2 *********************************************************************
4 * BY : C.L. Huang (ching@tekram.com.tw)
5 * Erich Chen (erich@tekram.com.tw)
6 * Description: Device Driver for the amd53c974 PCI Bus Master
7 * SCSI Host adapter found on cards such as
8 * the Tekram DC-390(T).
9 * (C)Copyright 1995-1999 Tekram Technology Co., Ltd.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *********************************************************************
33 * $FreeBSD: src/sys/pci/amd.c,v 1.3.2.2 2001/06/02 04:32:50 nyan Exp $
34 * $DragonFly: src/sys/dev/disk/amd/amd.c,v 1.3 2003/08/07 21:16:51 dillon Exp $
38 *********************************************************************
41 * REV# DATE NAME DESCRIPTION
42 * 1.00 07/02/96 CLH First release for RELEASE-2.1.0
43 * 1.01 08/20/96 CLH Update for RELEASE-2.1.5
44 * 1.02 11/06/96 CLH Fixed more than 1 LUN scanning
45 * 1.03 12/20/96 CLH Modify to support 2.2-ALPHA
46 * 1.04 12/26/97 CLH Modify to support RELEASE-2.2.5
47 * 1.05 01/01/99 ERICH CHEN Modify to support RELEASE-3.0.x (CAM)
48 *********************************************************************
51 /* #define AMD_DEBUG0 */
52 /* #define AMD_DEBUG_SCSI_PHASE */
54 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/malloc.h>
58 #include <sys/queue.h>
60 #include <sys/kernel.h>
65 #include <machine/bus_pio.h>
66 #include <machine/bus.h>
67 #include <machine/clock.h>
68 #include <machine/resource.h>
72 #include <bus/cam/cam.h>
73 #include <bus/cam/cam_ccb.h>
74 #include <bus/cam/cam_sim.h>
75 #include <bus/cam/cam_xpt_sim.h>
76 #include <bus/cam/cam_debug.h>
78 #include <bus/cam/scsi/scsi_all.h>
79 #include <bus/cam/scsi/scsi_message.h>
81 #include <bus/pci/pcivar.h>
82 #include <bus/pci/pcireg.h>
85 #define PCI_DEVICE_ID_AMD53C974 0x20201022ul
86 #define PCI_BASE_ADDR0 0x10
88 typedef u_int (phase_handler_t)(struct amd_softc *, struct amd_srb *, u_int);
89 typedef phase_handler_t *phase_handler_func_t;
91 static void amd_intr(void *vamd);
92 static int amdstart(struct amd_softc *amd, struct amd_srb * pSRB);
93 static phase_handler_t amd_NopPhase;
95 static phase_handler_t amd_DataOutPhase0;
96 static phase_handler_t amd_DataInPhase0;
97 #define amd_CommandPhase0 amd_NopPhase
98 static phase_handler_t amd_StatusPhase0;
99 static phase_handler_t amd_MsgOutPhase0;
100 static phase_handler_t amd_MsgInPhase0;
101 static phase_handler_t amd_DataOutPhase1;
102 static phase_handler_t amd_DataInPhase1;
103 static phase_handler_t amd_CommandPhase1;
104 static phase_handler_t amd_StatusPhase1;
105 static phase_handler_t amd_MsgOutPhase1;
106 static phase_handler_t amd_MsgInPhase1;
108 static void amdsetupcommand(struct amd_softc *amd, struct amd_srb *srb);
109 static int amdparsemsg(struct amd_softc *amd);
110 static int amdhandlemsgreject(struct amd_softc *amd);
111 static void amdconstructsdtr(struct amd_softc *amd,
112 u_int period, u_int offset);
113 static u_int amdfindclockrate(struct amd_softc *amd, u_int *period);
114 static int amdsentmsg(struct amd_softc *amd, u_int msgtype, int full);
116 static void DataIO_Comm(struct amd_softc *amd, struct amd_srb *pSRB, u_int dir);
117 static void amd_Disconnect(struct amd_softc *amd);
118 static void amd_Reselect(struct amd_softc *amd);
119 static void SRBdone(struct amd_softc *amd, struct amd_srb *pSRB);
120 static void amd_ScsiRstDetect(struct amd_softc *amd);
121 static void amd_ResetSCSIBus(struct amd_softc *amd);
122 static void RequestSense(struct amd_softc *amd, struct amd_srb *pSRB);
123 static void amd_InvalidCmd(struct amd_softc *amd);
126 static void amd_timeout(void *arg1);
127 static void amd_reset(struct amd_softc *amd);
129 static u_int8_t * phystovirt(struct amd_srb *pSRB, u_int32_t xferCnt);
131 void amd_linkSRB(struct amd_softc *amd);
132 static int amd_init(device_t);
133 static void amd_load_defaults(struct amd_softc *amd);
134 static void amd_load_eeprom_or_defaults(struct amd_softc *amd);
135 static int amd_EEpromInDO(struct amd_softc *amd);
136 static u_int16_t EEpromGetData1(struct amd_softc *amd);
137 static void amd_EnDisableCE(struct amd_softc *amd, int mode, int *regval);
138 static void amd_EEpromOutDI(struct amd_softc *amd, int *regval, int Carry);
139 static void amd_Prepare(struct amd_softc *amd, int *regval, u_int8_t EEpromCmd);
140 static void amd_ReadEEprom(struct amd_softc *amd);
142 static int amd_probe(device_t);
143 static int amd_attach(device_t);
144 static void amdcompletematch(struct amd_softc *amd, target_id_t target,
145 lun_id_t lun, u_int tag, struct srb_queue *queue,
147 static void amdsetsync(struct amd_softc *amd, u_int target, u_int clockrate,
148 u_int period, u_int offset, u_int type);
149 static void amdsettags(struct amd_softc *amd, u_int target, int tagenb);
151 static __inline void amd_clear_msg_state(struct amd_softc *amd);
154 amd_clear_msg_state(struct amd_softc *amd)
157 amd->msgout_index = 0;
158 amd->msgin_index = 0;
161 /* CAM SIM entry points */
162 #define ccb_srb_ptr spriv_ptr0
163 #define ccb_amd_ptr spriv_ptr1
164 static void amd_action(struct cam_sim *sim, union ccb *ccb);
165 static void amd_poll(struct cam_sim *sim);
168 * State engine function tables indexed by SCSI phase number
170 phase_handler_func_t amd_SCSI_phase0[] = {
181 phase_handler_func_t amd_SCSI_phase1[] = {
193 * EEProm/BIOS negotiation periods
195 u_int8_t eeprom_period[] = {
207 * chip clock setting to SCSI specified sync parameter table.
209 u_int8_t tinfo_sync_period[] = {
222 static __inline struct amd_srb *
223 amdgetsrb(struct amd_softc * amd)
226 struct amd_srb * pSRB;
229 pSRB = TAILQ_FIRST(&amd->free_srbs);
231 TAILQ_REMOVE(&amd->free_srbs, pSRB, links);
237 amdsetupcommand(struct amd_softc *amd, struct amd_srb *srb)
239 struct scsi_request_sense sense_cmd;
240 struct ccb_scsiio *csio;
244 csio = &srb->pccb->csio;
246 if (srb->SRBFlag & AUTO_REQSENSE) {
247 sense_cmd.opcode = REQUEST_SENSE;
248 sense_cmd.byte2 = srb->pccb->ccb_h.target_lun << 5;
249 sense_cmd.unused[0] = 0;
250 sense_cmd.unused[1] = 0;
251 sense_cmd.length = csio->sense_len;
252 sense_cmd.control = 0;
253 cdb = &sense_cmd.opcode;
254 cdb_len = sizeof(sense_cmd);
256 cdb = &srb->CmdBlock[0];
257 cdb_len = srb->ScsiCmdLen;
259 amd_write8_multi(amd, SCSIFIFOREG, cdb, cdb_len);
263 * Attempt to start a waiting transaction. Interrupts must be disabled
264 * upon entry to this function.
267 amdrunwaiting(struct amd_softc *amd) {
270 if (amd->last_phase != SCSI_BUS_FREE)
273 srb = TAILQ_FIRST(&amd->waiting_srbs);
277 if (amdstart(amd, srb) == 0) {
278 TAILQ_REMOVE(&amd->waiting_srbs, srb, links);
279 TAILQ_INSERT_HEAD(&amd->running_srbs, srb, links);
284 amdexecutesrb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
288 struct amd_softc *amd;
291 srb = (struct amd_srb *)arg;
293 amd = (struct amd_softc *)ccb->ccb_h.ccb_amd_ptr;
297 printf("amd%d: Unexepected error 0x%x returned from "
298 "bus_dmamap_load\n", amd->unit, error);
299 if (ccb->ccb_h.status == CAM_REQ_INPROG) {
300 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
301 ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN;
303 TAILQ_INSERT_HEAD(&amd->free_srbs, srb, links);
310 bus_dma_segment_t *end_seg;
313 end_seg = dm_segs + nseg;
315 /* Copy the segments into our SG list */
316 srb->pSGlist = &srb->SGsegment[0];
318 while (dm_segs < end_seg) {
319 sg->SGXLen = dm_segs->ds_len;
320 sg->SGXPtr = dm_segs->ds_addr;
325 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
326 op = BUS_DMASYNC_PREREAD;
328 op = BUS_DMASYNC_PREWRITE;
330 bus_dmamap_sync(amd->buffer_dmat, srb->dmamap, op);
335 srb->AdaptStatus = 0;
336 srb->TargetStatus = 0;
341 srb->TotalXferredLen = 0;
343 srb->SGToBeXferLen = 0;
349 * Last time we need to check if this CCB needs to
352 if (ccb->ccb_h.status != CAM_REQ_INPROG) {
354 bus_dmamap_unload(amd->buffer_dmat, srb->dmamap);
355 TAILQ_INSERT_HEAD(&amd->free_srbs, srb, links);
360 ccb->ccb_h.status |= CAM_SIM_QUEUED;
362 /* XXX Need a timeout handler */
363 ccb->ccb_h.timeout_ch =
364 timeout(amdtimeout, (caddr_t)srb,
365 (ccb->ccb_h.timeout * hz) / 1000);
367 TAILQ_INSERT_TAIL(&amd->waiting_srbs, srb, links);
373 amd_action(struct cam_sim * psim, union ccb * pccb)
375 struct amd_softc * amd;
376 u_int target_id, target_lun;
378 CAM_DEBUG(pccb->ccb_h.path, CAM_DEBUG_TRACE, ("amd_action\n"));
380 amd = (struct amd_softc *) cam_sim_softc(psim);
381 target_id = pccb->ccb_h.target_id;
382 target_lun = pccb->ccb_h.target_lun;
384 switch (pccb->ccb_h.func_code) {
387 struct amd_srb * pSRB;
388 struct ccb_scsiio *pcsio;
393 * Assign an SRB and connect it with this ccb.
395 pSRB = amdgetsrb(amd);
399 pccb->ccb_h.status = CAM_RESRC_UNAVAIL;
404 pccb->ccb_h.ccb_srb_ptr = pSRB;
405 pccb->ccb_h.ccb_amd_ptr = amd;
406 pSRB->ScsiCmdLen = pcsio->cdb_len;
407 bcopy(pcsio->cdb_io.cdb_bytes, pSRB->CmdBlock, pcsio->cdb_len);
408 if ((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
409 if ((pccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) {
411 * We've been given a pointer
412 * to a single buffer.
414 if ((pccb->ccb_h.flags & CAM_DATA_PHYS) == 0) {
420 bus_dmamap_load(amd->buffer_dmat,
426 if (error == EINPROGRESS) {
429 * ordering, freeze the
431 * until our mapping is
434 xpt_freeze_simq(amd->psim, 1);
435 pccb->ccb_h.status |=
440 struct bus_dma_segment seg;
442 /* Pointer to physical buffer */
444 (bus_addr_t)pcsio->data_ptr;
445 seg.ds_len = pcsio->dxfer_len;
446 amdexecutesrb(pSRB, &seg, 1, 0);
449 struct bus_dma_segment *segs;
451 if ((pccb->ccb_h.flags & CAM_SG_LIST_PHYS) == 0
452 || (pccb->ccb_h.flags & CAM_DATA_PHYS) != 0) {
453 TAILQ_INSERT_HEAD(&amd->free_srbs,
455 pccb->ccb_h.status = CAM_PROVIDE_FAIL;
460 /* Just use the segments provided */
462 (struct bus_dma_segment *)pcsio->data_ptr;
463 amdexecutesrb(pSRB, segs, pcsio->sglist_cnt, 0);
466 amdexecutesrb(pSRB, NULL, 0, 0);
471 struct ccb_pathinq *cpi = &pccb->cpi;
473 cpi->version_num = 1;
474 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE;
475 cpi->target_sprt = 0;
477 cpi->hba_eng_cnt = 0;
479 cpi->max_lun = amd->max_lun; /* 7 or 0 */
480 cpi->initiator_id = amd->AdaptSCSIID;
481 cpi->bus_id = cam_sim_bus(psim);
482 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
483 strncpy(cpi->hba_vid, "TRM-AMD", HBA_IDLEN);
484 strncpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN);
485 cpi->unit_number = cam_sim_unit(psim);
486 cpi->ccb_h.status = CAM_REQ_CMP;
491 pccb->ccb_h.status = CAM_REQ_INVALID;
499 amd_ResetSCSIBus(amd);
502 for (i = 0; i < 500; i++) {
503 DELAY(1000); /* Wait until our interrupt
507 pccb->ccb_h.status = CAM_REQ_CMP;
512 pccb->ccb_h.status = CAM_REQ_INVALID;
516 pccb->ccb_h.status = CAM_REQ_INVALID;
518 case XPT_GET_TRAN_SETTINGS:
520 struct ccb_trans_settings *cts;
521 struct amd_target_info *targ_info;
522 struct amd_transinfo *tinfo;
527 targ_info = &amd->tinfo[target_id];
528 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) {
529 /* current transfer settings */
530 if (targ_info->disc_tag & AMD_CUR_DISCENB) {
531 cts->flags = CCB_TRANS_DISC_ENB;
533 cts->flags = 0; /* no tag & disconnect */
535 if (targ_info->disc_tag & AMD_CUR_TAGENB) {
536 cts->flags |= CCB_TRANS_TAG_ENB;
538 tinfo = &targ_info->current;
540 /* default(user) transfer settings */
541 if (targ_info->disc_tag & AMD_USR_DISCENB) {
542 cts->flags = CCB_TRANS_DISC_ENB;
546 if (targ_info->disc_tag & AMD_USR_TAGENB) {
547 cts->flags |= CCB_TRANS_TAG_ENB;
549 tinfo = &targ_info->user;
552 cts->sync_period = tinfo->period;
553 cts->sync_offset = tinfo->offset;
554 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
556 cts->valid = CCB_TRANS_SYNC_RATE_VALID
557 | CCB_TRANS_SYNC_OFFSET_VALID
558 | CCB_TRANS_BUS_WIDTH_VALID
559 | CCB_TRANS_DISC_VALID
560 | CCB_TRANS_TQ_VALID;
561 pccb->ccb_h.status = CAM_REQ_CMP;
565 case XPT_SET_TRAN_SETTINGS:
567 struct ccb_trans_settings *cts;
568 struct amd_target_info *targ_info;
575 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) {
576 update_type |= AMD_TRANS_GOAL;
577 } else if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) {
578 update_type |= AMD_TRANS_USER;
581 || update_type == (AMD_TRANS_USER|AMD_TRANS_GOAL)) {
582 cts->ccb_h.status = CAM_REQ_INVALID;
587 targ_info = &amd->tinfo[target_id];
589 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) {
590 if (update_type & AMD_TRANS_GOAL) {
591 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) {
592 targ_info->disc_tag |= AMD_CUR_DISCENB;
594 targ_info->disc_tag &= ~AMD_CUR_DISCENB;
597 if (update_type & AMD_TRANS_USER) {
598 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) {
599 targ_info->disc_tag |= AMD_USR_DISCENB;
601 targ_info->disc_tag &= ~AMD_USR_DISCENB;
605 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) {
606 if (update_type & AMD_TRANS_GOAL) {
607 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) {
608 targ_info->disc_tag |= AMD_CUR_TAGENB;
610 targ_info->disc_tag &= ~AMD_CUR_TAGENB;
613 if (update_type & AMD_TRANS_USER) {
614 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) {
615 targ_info->disc_tag |= AMD_USR_TAGENB;
617 targ_info->disc_tag &= ~AMD_USR_TAGENB;
622 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) == 0) {
623 if (update_type & AMD_TRANS_GOAL)
624 cts->sync_offset = targ_info->goal.offset;
626 cts->sync_offset = targ_info->user.offset;
629 if (cts->sync_offset > AMD_MAX_SYNC_OFFSET)
630 cts->sync_offset = AMD_MAX_SYNC_OFFSET;
632 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) == 0) {
633 if (update_type & AMD_TRANS_GOAL)
634 cts->sync_period = targ_info->goal.period;
636 cts->sync_period = targ_info->user.period;
639 last_entry = sizeof(tinfo_sync_period) - 1;
640 if ((cts->sync_period != 0)
641 && (cts->sync_period < tinfo_sync_period[0]))
642 cts->sync_period = tinfo_sync_period[0];
643 if (cts->sync_period > tinfo_sync_period[last_entry])
644 cts->sync_period = 0;
645 if (cts->sync_offset == 0)
646 cts->sync_period = 0;
648 if ((update_type & AMD_TRANS_USER) != 0) {
649 targ_info->user.period = cts->sync_period;
650 targ_info->user.offset = cts->sync_offset;
652 if ((update_type & AMD_TRANS_GOAL) != 0) {
653 targ_info->goal.period = cts->sync_period;
654 targ_info->goal.offset = cts->sync_offset;
657 pccb->ccb_h.status = CAM_REQ_CMP;
661 case XPT_CALC_GEOMETRY:
663 struct ccb_calc_geometry *ccg;
665 u_int32_t secs_per_cylinder;
669 size_mb = ccg->volume_size/((1024L * 1024L)/ccg->block_size);
670 extended = (amd->eepromBuf[EE_MODE2] & GREATER_1G) != 0;
672 if (size_mb > 1024 && extended) {
674 ccg->secs_per_track = 63;
677 ccg->secs_per_track = 32;
679 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
680 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
681 pccb->ccb_h.status = CAM_REQ_CMP;
686 pccb->ccb_h.status = CAM_REQ_INVALID;
693 amd_poll(struct cam_sim * psim)
695 amd_intr(cam_sim_softc(psim));
699 phystovirt(struct amd_srb * pSRB, u_int32_t xferCnt)
702 struct ccb_scsiio *pcsio;
704 struct amd_sg * pseg;
707 pcsio = &pSRB->pccb->csio;
709 dataPtr = (int) pcsio->data_ptr;
710 pseg = pSRB->SGsegment;
711 for (i = 0; i < pSRB->SGIndex; i++) {
712 dataPtr += (int) pseg->SGXLen;
715 dataPtr += (int) xferCnt;
716 return ((u_int8_t *) dataPtr);
720 ResetDevParam(struct amd_softc * amd)
724 for (target = 0; target <= amd->max_id; target++) {
725 if (amd->AdaptSCSIID != target) {
726 amdsetsync(amd, target, /*clockrate*/0,
727 /*period*/0, /*offset*/0, AMD_TRANS_CUR);
733 amdcompletematch(struct amd_softc *amd, target_id_t target, lun_id_t lun,
734 u_int tag, struct srb_queue *queue, cam_status status)
737 struct amd_srb *next_srb;
739 for (srb = TAILQ_FIRST(queue); srb != NULL; srb = next_srb) {
742 next_srb = TAILQ_NEXT(srb, links);
743 if (srb->pccb->ccb_h.target_id != target
744 && target != CAM_TARGET_WILDCARD)
747 if (srb->pccb->ccb_h.target_lun != lun
748 && lun != CAM_LUN_WILDCARD)
751 if (srb->TagNumber != tag
752 && tag != AMD_TAG_WILDCARD)
756 TAILQ_REMOVE(queue, srb, links);
757 TAILQ_INSERT_HEAD(&amd->free_srbs, srb, links);
758 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0
759 && (status & CAM_DEV_QFRZN) != 0)
760 xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
761 ccb->ccb_h.status = status;
768 amdsetsync(struct amd_softc *amd, u_int target, u_int clockrate,
769 u_int period, u_int offset, u_int type)
771 struct amd_target_info *tinfo;
775 tinfo = &amd->tinfo[target];
776 old_period = tinfo->current.period;
777 old_offset = tinfo->current.offset;
778 if ((type & AMD_TRANS_CUR) != 0
779 && (old_period != period || old_offset != offset)) {
780 struct cam_path *path;
782 tinfo->current.period = period;
783 tinfo->current.offset = offset;
784 tinfo->sync_period_reg = clockrate;
785 tinfo->sync_offset_reg = offset;
786 tinfo->CtrlR3 &= ~FAST_SCSI;
787 tinfo->CtrlR4 &= ~EATER_25NS;
789 tinfo->CtrlR4 |= EATER_25NS;
791 tinfo->CtrlR3 |= FAST_SCSI;
793 if ((type & AMD_TRANS_ACTIVE) == AMD_TRANS_ACTIVE) {
794 amd_write8(amd, SYNCPERIOREG, tinfo->sync_period_reg);
795 amd_write8(amd, SYNCOFFREG, tinfo->sync_offset_reg);
796 amd_write8(amd, CNTLREG3, tinfo->CtrlR3);
797 amd_write8(amd, CNTLREG4, tinfo->CtrlR4);
799 /* If possible, update the XPT's notion of our transfer rate */
800 if (xpt_create_path(&path, /*periph*/NULL,
801 cam_sim_path(amd->psim), target,
802 CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
803 struct ccb_trans_settings neg;
805 xpt_setup_ccb(&neg.ccb_h, path, /*priority*/1);
806 neg.sync_period = period;
807 neg.sync_offset = offset;
808 neg.valid = CCB_TRANS_SYNC_RATE_VALID
809 | CCB_TRANS_SYNC_OFFSET_VALID;
810 xpt_async(AC_TRANSFER_NEG, path, &neg);
814 if ((type & AMD_TRANS_GOAL) != 0) {
815 tinfo->goal.period = period;
816 tinfo->goal.offset = offset;
819 if ((type & AMD_TRANS_USER) != 0) {
820 tinfo->user.period = period;
821 tinfo->user.offset = offset;
826 amdsettags(struct amd_softc *amd, u_int target, int tagenb)
828 panic("Implement me!\n");
834 **********************************************************************
835 * Function : amd_reset (struct amd_softc * amd)
836 * Purpose : perform a hard reset on the SCSI bus( and AMD chip).
837 * Inputs : cmd - command which caused the SCSI RESET
838 **********************************************************************
841 amd_reset(struct amd_softc * amd)
849 printf("DC390: RESET");
853 bval = amd_read8(amd, CNTLREG1);
854 bval |= DIS_INT_ON_SCSI_RST;
855 amd_write8(amd, CNTLREG1, bval); /* disable interrupt */
856 amd_ResetSCSIBus(amd);
858 for (i = 0; i < 500; i++) {
862 bval = amd_read8(amd, CNTLREG1);
863 bval &= ~DIS_INT_ON_SCSI_RST;
864 amd_write8(amd, CNTLREG1, bval); /* re-enable interrupt */
866 amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD);
867 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
870 amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD,
871 AMD_TAG_WILDCARD, &amd->running_srbs,
872 CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET);
873 amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD,
874 AMD_TAG_WILDCARD, &amd->waiting_srbs,
875 CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET);
876 amd->active_srb = NULL;
883 amd_timeout(void *arg1)
885 struct amd_srb * pSRB;
887 pSRB = (struct amd_srb *) arg1;
892 amdstart(struct amd_softc *amd, struct amd_srb *pSRB)
895 struct ccb_scsiio *pcsio;
896 struct amd_target_info *targ_info;
905 target = pccb->ccb_h.target_id;
906 lun = pccb->ccb_h.target_lun;
907 targ_info = &amd->tinfo[target];
909 amd_clear_msg_state(amd);
910 amd_write8(amd, SCSIDESTIDREG, target);
911 amd_write8(amd, SYNCPERIOREG, targ_info->sync_period_reg);
912 amd_write8(amd, SYNCOFFREG, targ_info->sync_offset_reg);
913 amd_write8(amd, CNTLREG1, targ_info->CtrlR1);
914 amd_write8(amd, CNTLREG3, targ_info->CtrlR3);
915 amd_write8(amd, CNTLREG4, targ_info->CtrlR4);
916 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
918 identify_msg = MSG_IDENTIFYFLAG | lun;
919 if ((targ_info->disc_tag & AMD_CUR_DISCENB) != 0
920 && (pccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0
921 && (pSRB->CmdBlock[0] != REQUEST_SENSE)
922 && (pSRB->SRBFlag & AUTO_REQSENSE) == 0)
923 identify_msg |= MSG_IDENTIFY_DISCFLAG;
925 amd_write8(amd, SCSIFIFOREG, identify_msg);
927 if ((targ_info->disc_tag & AMD_CUR_TAGENB) == 0
928 || (identify_msg & MSG_IDENTIFY_DISCFLAG) == 0)
929 pccb->ccb_h.flags &= ~CAM_TAG_ACTION_VALID;
930 if (targ_info->current.period != targ_info->goal.period
931 || targ_info->current.offset != targ_info->goal.offset) {
932 command = SEL_W_ATN_STOP;
933 amdconstructsdtr(amd, targ_info->goal.period,
934 targ_info->goal.offset);
935 } else if ((pccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) {
936 command = SEL_W_ATN2;
937 pSRB->SRBState = SRB_START;
938 amd_write8(amd, SCSIFIFOREG, pcsio->tag_action);
939 amd_write8(amd, SCSIFIFOREG, pSRB->TagNumber);
943 pSRB->SRBState = SRB_START;
945 if (command != SEL_W_ATN_STOP)
946 amdsetupcommand(amd, pSRB);
948 if (amd_read8(amd, SCSISTATREG) & INTERRUPT) {
949 pSRB->SRBState = SRB_READY;
952 amd->last_phase = SCSI_ARBITRATING;
953 amd_write8(amd, SCSICMDREG, command);
954 amd->active_srb = pSRB;
955 amd->cur_target = target;
962 * Catch an interrupt from the adapter.
963 * Process pending device interrupts.
968 struct amd_softc *amd;
969 struct amd_srb *pSRB;
970 u_int internstat = 0;
974 amd = (struct amd_softc *)arg;
978 printf("amd_intr: amd NULL return......");
983 scsistat = amd_read8(amd, SCSISTATREG);
984 if (!(scsistat & INTERRUPT)) {
986 printf("amd_intr: scsistat = NULL ,return......");
990 #ifdef AMD_DEBUG_SCSI_PHASE
991 printf("scsistat=%2x,", scsistat);
994 internstat = amd_read8(amd, INTERNSTATREG);
995 intstat = amd_read8(amd, INTSTATREG);
997 #ifdef AMD_DEBUG_SCSI_PHASE
998 printf("intstat=%2x,", intstat);
1001 if (intstat & DISCONNECTED) {
1002 amd_Disconnect(amd);
1005 if (intstat & RESELECTED) {
1009 if (intstat & INVALID_CMD) {
1010 amd_InvalidCmd(amd);
1013 if (intstat & SCSI_RESET_) {
1014 amd_ScsiRstDetect(amd);
1017 if (intstat & (SUCCESSFUL_OP + SERVICE_REQUEST)) {
1018 pSRB = amd->active_srb;
1020 * Run our state engine. First perform
1021 * post processing for the last phase we
1022 * were in, followed by any processing
1023 * required to handle the current phase.
1026 amd_SCSI_phase0[amd->last_phase](amd, pSRB, scsistat);
1027 amd->last_phase = scsistat & SCSI_PHASE_MASK;
1028 (void)amd_SCSI_phase1[amd->last_phase](amd, pSRB, scsistat);
1033 amd_DataOutPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1035 struct amd_sg *psgl;
1036 u_int32_t ResidCnt, xferCnt;
1038 if (!(pSRB->SRBState & SRB_XFERPAD)) {
1039 if (scsistat & PARITY_ERR) {
1040 pSRB->SRBStatus |= PARITY_ERROR;
1042 if (scsistat & COUNT_2_ZERO) {
1043 while ((amd_read8(amd, DMA_Status)&DMA_XFER_DONE) == 0)
1045 pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
1047 if (pSRB->SGIndex < pSRB->SGcount) {
1049 psgl = pSRB->pSGlist;
1050 pSRB->SGPhysAddr = psgl->SGXPtr;
1051 pSRB->SGToBeXferLen = psgl->SGXLen;
1053 pSRB->SGToBeXferLen = 0;
1056 ResidCnt = amd_read8(amd, CURRENTFIFOREG) & 0x1f;
1057 ResidCnt += amd_read8(amd, CTCREG_LOW)
1058 | (amd_read8(amd, CTCREG_MID) << 8)
1059 | (amd_read8(amd, CURTXTCNTREG) << 16);
1061 xferCnt = pSRB->SGToBeXferLen - ResidCnt;
1062 pSRB->SGPhysAddr += xferCnt;
1063 pSRB->TotalXferredLen += xferCnt;
1064 pSRB->SGToBeXferLen = ResidCnt;
1067 amd_write8(amd, DMA_Cmd, WRITE_DIRECTION | DMA_IDLE_CMD);
1072 amd_DataInPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1075 u_int16_t i, residual;
1076 struct amd_sg *psgl;
1077 u_int32_t ResidCnt, xferCnt;
1080 if (!(pSRB->SRBState & SRB_XFERPAD)) {
1081 if (scsistat & PARITY_ERR) {
1082 pSRB->SRBStatus |= PARITY_ERROR;
1084 if (scsistat & COUNT_2_ZERO) {
1086 bval = amd_read8(amd, DMA_Status);
1087 if ((bval & DMA_XFER_DONE) != 0)
1090 amd_write8(amd, DMA_Cmd, READ_DIRECTION|DMA_IDLE_CMD);
1092 pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
1094 if (pSRB->SGIndex < pSRB->SGcount) {
1096 psgl = pSRB->pSGlist;
1097 pSRB->SGPhysAddr = psgl->SGXPtr;
1098 pSRB->SGToBeXferLen = psgl->SGXLen;
1100 pSRB->SGToBeXferLen = 0;
1102 } else { /* phase changed */
1104 bval = amd_read8(amd, CURRENTFIFOREG);
1105 while (bval & 0x1f) {
1106 if ((bval & 0x1f) == 1) {
1107 for (i = 0; i < 0x100; i++) {
1108 bval = amd_read8(amd, CURRENTFIFOREG);
1109 if (!(bval & 0x1f)) {
1111 } else if (i == 0x0ff) {
1117 bval = amd_read8(amd, CURRENTFIFOREG);
1121 amd_write8(amd, DMA_Cmd, READ_DIRECTION|DMA_BLAST_CMD);
1122 for (i = 0; i < 0x8000; i++) {
1123 if ((amd_read8(amd, DMA_Status)&BLAST_COMPLETE))
1126 amd_write8(amd, DMA_Cmd, READ_DIRECTION|DMA_IDLE_CMD);
1128 ResidCnt = amd_read8(amd, CTCREG_LOW)
1129 | (amd_read8(amd, CTCREG_MID) << 8)
1130 | (amd_read8(amd, CURTXTCNTREG) << 16);
1131 xferCnt = pSRB->SGToBeXferLen - ResidCnt;
1132 pSRB->SGPhysAddr += xferCnt;
1133 pSRB->TotalXferredLen += xferCnt;
1134 pSRB->SGToBeXferLen = ResidCnt;
1136 /* get residual byte */
1137 bval = amd_read8(amd, SCSIFIFOREG);
1138 ptr = phystovirt(pSRB, xferCnt);
1141 pSRB->TotalXferredLen++;
1142 pSRB->SGToBeXferLen--;
1150 amd_StatusPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1152 pSRB->TargetStatus = amd_read8(amd, SCSIFIFOREG);
1154 pSRB->EndMessage = amd_read8(amd, SCSIFIFOREG);
1155 pSRB->SRBState = SRB_COMPLETED;
1156 amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD);
1161 amd_MsgOutPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1163 if (pSRB->SRBState & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT)) {
1164 scsistat = SCSI_NOP0;
1170 amd_MsgInPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1174 amd->msgin_buf[amd->msgin_index] = amd_read8(amd, SCSIFIFOREG);
1176 done = amdparsemsg(amd);
1178 amd->msgin_index = 0;
1185 amdparsemsg(struct amd_softc *amd)
1187 struct amd_target_info *targ_info;
1196 targ_info = &amd->tinfo[amd->cur_target];
1199 * Parse as much of the message as is availible,
1200 * rejecting it if we don't support it. When
1201 * the entire message is availible and has been
1202 * handled, return TRUE indicating that we have
1203 * parsed an entire message.
1205 switch (amd->msgin_buf[0]) {
1206 case MSG_DISCONNECT:
1207 amd->active_srb->SRBState = SRB_DISCONNECT;
1208 amd->disc_count[amd->cur_target][amd->cur_lun]++;
1211 case MSG_SIMPLE_Q_TAG:
1213 struct amd_srb *disc_srb;
1215 if (amd->msgin_index < 1)
1217 disc_srb = &amd->SRB_array[amd->msgin_buf[1]];
1218 if (amd->active_srb != NULL
1219 || disc_srb->SRBState != SRB_DISCONNECT
1220 || disc_srb->pccb->ccb_h.target_id != amd->cur_target
1221 || disc_srb->pccb->ccb_h.target_lun != amd->cur_lun) {
1222 printf("amd%d: Unexpected tagged reselection "
1223 "for target %d, Issuing Abort\n", amd->unit,
1225 amd->msgout_buf[0] = MSG_ABORT;
1226 amd->msgout_len = 1;
1230 amd->active_srb = disc_srb;
1231 amd->disc_count[amd->cur_target][amd->cur_lun]--;
1235 case MSG_MESSAGE_REJECT:
1236 response = amdhandlemsgreject(amd);
1237 if (response == FALSE)
1238 amd_write8(amd, SCSICMDREG, RESET_ATN_CMD);
1250 /* Wait for enough of the message to begin validation */
1251 if (amd->msgin_index < 1)
1253 if (amd->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
1258 /* Wait for opcode */
1259 if (amd->msgin_index < 2)
1262 if (amd->msgin_buf[2] != MSG_EXT_SDTR) {
1268 * Wait until we have both args before validating
1269 * and acting on this message.
1271 * Add one to MSG_EXT_SDTR_LEN to account for
1272 * the extended message preamble.
1274 if (amd->msgin_index < (MSG_EXT_SDTR_LEN + 1))
1277 period = amd->msgin_buf[3];
1278 saved_offset = offset = amd->msgin_buf[4];
1279 clockrate = amdfindclockrate(amd, &period);
1280 if (offset > AMD_MAX_SYNC_OFFSET)
1281 offset = AMD_MAX_SYNC_OFFSET;
1282 if (period == 0 || offset == 0) {
1287 amdsetsync(amd, amd->cur_target, clockrate, period, offset,
1288 AMD_TRANS_ACTIVE|AMD_TRANS_GOAL);
1291 * See if we initiated Sync Negotiation
1292 * and didn't have to fall down to async
1295 if (amdsentmsg(amd, MSG_EXT_SDTR, /*full*/TRUE)) {
1297 if (saved_offset != offset) {
1298 /* Went too low - force async */
1303 * Send our own SDTR in reply
1306 printf("Sending SDTR!\n");
1307 amd->msgout_index = 0;
1308 amd->msgout_len = 0;
1309 amdconstructsdtr(amd, period, offset);
1310 amd->msgout_index = 0;
1316 case MSG_SAVEDATAPOINTER:
1317 case MSG_RESTOREPOINTERS:
1318 /* XXX Implement!!! */
1327 amd->msgout_index = 0;
1328 amd->msgout_len = 1;
1329 amd->msgout_buf[0] = MSG_MESSAGE_REJECT;
1335 amd_write8(amd, SCSICMDREG, SET_ATN_CMD);
1337 if (done && !response)
1338 /* Clear the outgoing message buffer */
1339 amd->msgout_len = 0;
1342 amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD);
1348 amdfindclockrate(struct amd_softc *amd, u_int *period)
1353 for (i = 0; i < sizeof(tinfo_sync_period); i++) {
1354 u_int8_t *table_entry;
1356 table_entry = &tinfo_sync_period[i];
1357 if (*period <= *table_entry) {
1359 * When responding to a target that requests
1360 * sync, the requested rate may fall between
1361 * two rates that we can output, but still be
1362 * a rate that we can receive. Because of this,
1363 * we want to respond to the target with
1364 * the same rate that it sent to us even
1365 * if the period we use to send data to it
1366 * is lower. Only lower the response period
1370 *period = *table_entry;
1376 if (i == sizeof(tinfo_sync_period)) {
1377 /* Too slow for us. Use asnyc transfers. */
1387 * See if we sent a particular extended message to the target.
1388 * If "full" is true, the target saw the full message.
1389 * If "full" is false, the target saw at least the first
1390 * byte of the message.
1393 amdsentmsg(struct amd_softc *amd, u_int msgtype, int full)
1401 while (index < amd->msgout_len) {
1402 if ((amd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0
1403 || amd->msgout_buf[index] == MSG_MESSAGE_REJECT)
1405 else if (amd->msgout_buf[index] >= MSG_SIMPLE_Q_TAG
1406 && amd->msgout_buf[index] < MSG_IGN_WIDE_RESIDUE) {
1407 /* Skip tag type and tag id */
1409 } else if (amd->msgout_buf[index] == MSG_EXTENDED) {
1410 /* Found a candidate */
1411 if (amd->msgout_buf[index+2] == msgtype) {
1414 end_index = index + 1
1415 + amd->msgout_buf[index + 1];
1417 if (amd->msgout_index > end_index)
1419 } else if (amd->msgout_index > index)
1424 panic("amdsentmsg: Inconsistent msg buffer");
1431 amdconstructsdtr(struct amd_softc *amd, u_int period, u_int offset)
1433 amd->msgout_buf[amd->msgout_index++] = MSG_EXTENDED;
1434 amd->msgout_buf[amd->msgout_index++] = MSG_EXT_SDTR_LEN;
1435 amd->msgout_buf[amd->msgout_index++] = MSG_EXT_SDTR;
1436 amd->msgout_buf[amd->msgout_index++] = period;
1437 amd->msgout_buf[amd->msgout_index++] = offset;
1438 amd->msgout_len += 5;
1442 amdhandlemsgreject(struct amd_softc *amd)
1445 * If we had an outstanding SDTR for this
1446 * target, this is a signal that the target
1447 * is refusing negotiation. Also watch out
1448 * for rejected tag messages.
1450 struct amd_srb *srb;
1451 struct amd_target_info *targ_info;
1452 int response = FALSE;
1454 srb = amd->active_srb;
1455 targ_info = &amd->tinfo[amd->cur_target];
1456 if (amdsentmsg(amd, MSG_EXT_SDTR, /*full*/FALSE)) {
1457 /* note asynch xfers and clear flag */
1458 amdsetsync(amd, amd->cur_target, /*clockrate*/0,
1459 /*period*/0, /*offset*/0,
1460 AMD_TRANS_ACTIVE|AMD_TRANS_GOAL);
1461 printf("amd%d:%d: refuses synchronous negotiation. "
1462 "Using asynchronous transfers\n",
1463 amd->unit, amd->cur_target);
1464 } else if ((srb != NULL)
1465 && (srb->pccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) {
1466 struct ccb_trans_settings neg;
1468 printf("amd%d:%d: refuses tagged commands. Performing "
1469 "non-tagged I/O\n", amd->unit, amd->cur_target);
1471 amdsettags(amd, amd->cur_target, FALSE);
1473 neg.valid = CCB_TRANS_TQ_VALID;
1474 xpt_setup_ccb(&neg.ccb_h, srb->pccb->ccb_h.path, /*priority*/1);
1475 xpt_async(AC_TRANSFER_NEG, srb->pccb->ccb_h.path, &neg);
1478 * Resend the identify for this CCB as the target
1479 * may believe that the selection is invalid otherwise.
1481 if (amd->msgout_len != 0)
1482 bcopy(&amd->msgout_buf[0], &amd->msgout_buf[1],
1484 amd->msgout_buf[0] = MSG_IDENTIFYFLAG
1485 | srb->pccb->ccb_h.target_lun;
1487 if ((targ_info->disc_tag & AMD_CUR_DISCENB) != 0
1488 && (srb->pccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0)
1489 amd->msgout_buf[0] |= MSG_IDENTIFY_DISCFLAG;
1491 srb->pccb->ccb_h.flags &= ~CAM_TAG_ACTION_VALID;
1494 * Requeue all tagged commands for this target
1495 * currently in our posession so they can be
1496 * converted to untagged commands.
1498 amdcompletematch(amd, amd->cur_target, amd->cur_lun,
1499 AMD_TAG_WILDCARD, &amd->waiting_srbs,
1500 CAM_DEV_QFRZN|CAM_REQUEUE_REQ);
1503 * Otherwise, we ignore it.
1505 printf("amd%d:%d: Message reject received -- ignored\n",
1506 amd->unit, amd->cur_target);
1512 if (!(pSRB->SRBState & SRB_MSGIN_MULTI)) {
1513 if (bval == MSG_DISCONNECT) {
1514 pSRB->SRBState = SRB_DISCONNECT;
1515 } else if (bval == MSG_SAVEDATAPOINTER) {
1517 } else if ((bval == MSG_EXTENDED)
1518 || ((bval >= MSG_SIMPLE_Q_TAG)
1519 && (bval <= MSG_ORDERED_Q_TAG))) {
1520 pSRB->SRBState |= SRB_MSGIN_MULTI;
1521 pSRB->MsgInBuf[0] = bval;
1523 pSRB->pMsgPtr = &pSRB->MsgInBuf[1];
1524 } else if (bval == MSG_MESSAGE_REJECT) {
1525 amd_write8(amd, SCSICMDREG, RESET_ATN_CMD);
1527 if (pSRB->SRBState & DO_SYNC_NEGO) {
1530 } else if (bval == MSG_RESTOREPOINTERS) {
1535 } else { /* minx: */
1536 *pSRB->pMsgPtr = bval;
1539 if ((pSRB->MsgInBuf[0] >= MSG_SIMPLE_Q_TAG)
1540 && (pSRB->MsgInBuf[0] <= MSG_ORDERED_Q_TAG)) {
1541 if (pSRB->MsgCnt == 2) {
1543 pSRB = &amd->SRB_array[pSRB->MsgInBuf[1]];
1544 if (pSRB->SRBState & SRB_DISCONNECT) == 0) {
1545 pSRB = amd->pTmpSRB;
1546 pSRB->SRBState = SRB_UNEXPECT_RESEL;
1547 pDCB->pActiveSRB = pSRB;
1548 pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;
1549 EnableMsgOut2(amd, pSRB);
1551 if (pDCB->DCBFlag & ABORT_DEV_) {
1552 pSRB->SRBState = SRB_ABORT_SENT;
1553 EnableMsgOut1(amd, pSRB);
1555 pDCB->pActiveSRB = pSRB;
1556 pSRB->SRBState = SRB_DATA_XFER;
1559 } else if ((pSRB->MsgInBuf[0] == MSG_EXTENDED)
1560 && (pSRB->MsgCnt == 5)) {
1561 pSRB->SRBState &= ~(SRB_MSGIN_MULTI + DO_SYNC_NEGO);
1562 if ((pSRB->MsgInBuf[1] != 3)
1563 || (pSRB->MsgInBuf[2] != 1)) { /* reject_msg: */
1565 pSRB->MsgInBuf[0] = MSG_MESSAGE_REJECT;
1566 amd_write8(amd, SCSICMDREG, SET_ATN_CMD);
1567 } else if (!(pSRB->MsgInBuf[3])
1568 || !(pSRB->MsgInBuf[4])) {
1569 set_async: /* set async */
1571 pDCB = pSRB->pSRBDCB;
1572 /* disable sync & sync nego */
1573 pDCB->SyncMode &= ~(SYNC_ENABLE|SYNC_NEGO_DONE);
1574 pDCB->SyncPeriod = 0;
1575 pDCB->SyncOffset = 0;
1577 pDCB->tinfo.goal.period = 0;
1578 pDCB->tinfo.goal.offset = 0;
1580 pDCB->tinfo.current.period = 0;
1581 pDCB->tinfo.current.offset = 0;
1582 pDCB->tinfo.current.width =
1583 MSG_EXT_WDTR_BUS_8_BIT;
1585 pDCB->CtrlR3 = FAST_CLK; /* non_fast */
1586 pDCB->CtrlR4 &= 0x3f;
1587 pDCB->CtrlR4 |= EATER_25NS;
1589 } else {/* set sync */
1591 pDCB = pSRB->pSRBDCB;
1592 /* enable sync & sync nego */
1593 pDCB->SyncMode |= SYNC_ENABLE|SYNC_NEGO_DONE;
1595 /* set sync offset */
1596 pDCB->SyncOffset &= 0x0f0;
1597 pDCB->SyncOffset |= pSRB->MsgInBuf[4];
1599 /* set sync period */
1600 pDCB->MaxNegoPeriod = pSRB->MsgInBuf[3];
1602 wval = (u_int16_t) pSRB->MsgInBuf[3];
1606 if ((wval1 * 25) != wval) {
1609 bval = FAST_CLK|FAST_SCSI;
1610 pDCB->CtrlR4 &= 0x3f;
1615 pDCB->CtrlR4 |= EATER_25NS;
1617 pDCB->CtrlR3 = bval;
1618 pDCB->SyncPeriod = (u_int8_t) wval1;
1620 pDCB->tinfo.goal.period =
1621 tinfo_sync_period[pDCB->SyncPeriod - 4];
1622 pDCB->tinfo.goal.offset = pDCB->SyncOffset;
1623 pDCB->tinfo.current.period =
1624 tinfo_sync_period[pDCB->SyncPeriod - 4];;
1625 pDCB->tinfo.current.offset = pDCB->SyncOffset;
1628 * program SCSI control register
1631 amd_write8(amd, SYNCPERIOREG, pDCB->SyncPeriod);
1632 amd_write8(amd, SYNCOFFREG, pDCB->SyncOffset);
1633 amd_write8(amd, CNTLREG3, pDCB->CtrlR3);
1634 amd_write8(amd, CNTLREG4, pDCB->CtrlR4);
1639 amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD);
1645 amd_DataOutPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1647 DataIO_Comm(amd, pSRB, WRITE_DIRECTION);
1652 amd_DataInPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1654 DataIO_Comm(amd, pSRB, READ_DIRECTION);
1659 DataIO_Comm(struct amd_softc *amd, struct amd_srb *pSRB, u_int ioDir)
1661 struct amd_sg * psgl;
1664 if (pSRB->SGIndex < pSRB->SGcount) {
1665 amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD|ioDir);/* |EN_DMA_INT */
1667 if (!pSRB->SGToBeXferLen) {
1668 psgl = pSRB->pSGlist;
1669 pSRB->SGPhysAddr = psgl->SGXPtr;
1670 pSRB->SGToBeXferLen = psgl->SGXLen;
1672 lval = pSRB->SGToBeXferLen;
1673 amd_write8(amd, CTCREG_LOW, lval);
1674 amd_write8(amd, CTCREG_MID, lval >> 8);
1675 amd_write8(amd, CURTXTCNTREG, lval >> 16);
1677 amd_write32(amd, DMA_XferCnt, pSRB->SGToBeXferLen);
1679 amd_write32(amd, DMA_XferAddr, pSRB->SGPhysAddr);
1681 pSRB->SRBState = SRB_DATA_XFER;
1683 amd_write8(amd, SCSICMDREG, DMA_COMMAND|INFO_XFER_CMD);
1685 amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD|ioDir); /* |EN_DMA_INT */
1687 amd_write8(amd, DMA_Cmd, DMA_START_CMD|ioDir);/* |EN_DMA_INT */
1688 } else { /* xfer pad */
1689 if (pSRB->SGcount) {
1690 pSRB->AdaptStatus = H_OVER_UNDER_RUN;
1691 pSRB->SRBStatus |= OVER_RUN;
1693 amd_write8(amd, CTCREG_LOW, 0);
1694 amd_write8(amd, CTCREG_MID, 0);
1695 amd_write8(amd, CURTXTCNTREG, 0);
1697 pSRB->SRBState |= SRB_XFERPAD;
1698 amd_write8(amd, SCSICMDREG, DMA_COMMAND|XFER_PAD_BYTE);
1703 amd_CommandPhase1(struct amd_softc *amd, struct amd_srb *srb, u_int scsistat)
1705 amd_write8(amd, SCSICMDREG, RESET_ATN_CMD);
1706 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
1708 amdsetupcommand(amd, srb);
1710 srb->SRBState = SRB_COMMAND;
1711 amd_write8(amd, SCSICMDREG, INFO_XFER_CMD);
1716 amd_StatusPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1718 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
1719 pSRB->SRBState = SRB_STATUS;
1720 amd_write8(amd, SCSICMDREG, INITIATOR_CMD_CMPLTE);
1725 amd_MsgOutPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1727 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
1729 if (amd->msgout_len == 0) {
1730 amd->msgout_buf[0] = MSG_NOOP;
1731 amd->msgout_len = 1;
1733 amd_write8_multi(amd, SCSIFIFOREG, amd->msgout_buf, amd->msgout_len);
1734 amd_write8(amd, SCSICMDREG, INFO_XFER_CMD);
1739 amd_MsgInPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1741 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
1742 amd_write8(amd, SCSICMDREG, INFO_XFER_CMD);
1747 amd_NopPhase(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1753 amd_Disconnect(struct amd_softc * amd)
1755 struct amd_srb *srb;
1759 srb = amd->active_srb;
1760 amd->active_srb = NULL;
1761 amd->last_phase = SCSI_BUS_FREE;
1762 amd_write8(amd, SCSICMDREG, EN_SEL_RESEL);
1763 target = amd->cur_target;
1767 /* Invalid reselection */
1769 } else if (srb->SRBState & SRB_ABORT_SENT) {
1770 /* Clean up and done this srb */
1772 while (( = TAILQ_FIRST(&amd->running_srbs)) != NULL) {
1773 /* XXX What about "done'ing" these srbs??? */
1774 if (pSRB->pSRBDCB == pDCB) {
1775 TAILQ_REMOVE(&amd->running_srbs, pSRB, links);
1776 TAILQ_INSERT_HEAD(&amd->free_srbs, pSRB, links);
1782 if ((srb->SRBState & (SRB_START | SRB_MSGOUT))
1783 || !(srb->SRBState & (SRB_DISCONNECT | SRB_COMPLETED))) {
1784 srb->TargetStatus = AMD_SCSI_STAT_SEL_TIMEOUT;
1786 } else if (srb->SRBState & SRB_DISCONNECT) {
1787 if (!(srb->pccb->ccb_h.flags & CAM_TAG_ACTION_VALID))
1788 amd->untagged_srbs[target][lun] = srb;
1790 } else if (srb->SRBState & SRB_COMPLETED) {
1792 srb->SRBState = SRB_FREE;
1800 amd_Reselect(struct amd_softc *amd)
1802 struct amd_target_info *tinfo;
1803 u_int16_t disc_count;
1805 amd_clear_msg_state(amd);
1806 if (amd->active_srb != NULL) {
1807 /* Requeue the SRB for our attempted Selection */
1808 TAILQ_REMOVE(&amd->running_srbs, amd->active_srb, links);
1809 TAILQ_INSERT_HEAD(&amd->waiting_srbs, amd->active_srb, links);
1810 amd->active_srb = NULL;
1813 amd->cur_target = amd_read8(amd, SCSIFIFOREG);
1814 amd->cur_target ^= amd->HostID_Bit;
1815 amd->cur_target = ffs(amd->cur_target) - 1;
1816 amd->cur_lun = amd_read8(amd, SCSIFIFOREG) & 7;
1817 tinfo = &amd->tinfo[amd->cur_target];
1818 amd->active_srb = amd->untagged_srbs[amd->cur_target][amd->cur_lun];
1819 disc_count = amd->disc_count[amd->cur_target][amd->cur_lun];
1820 if (disc_count == 0) {
1821 printf("amd%d: Unexpected reselection for target %d, "
1822 "Issuing Abort\n", amd->unit, amd->cur_target);
1823 amd->msgout_buf[0] = MSG_ABORT;
1824 amd->msgout_len = 1;
1825 amd_write8(amd, SCSICMDREG, SET_ATN_CMD);
1827 if (amd->active_srb != NULL) {
1828 amd->disc_count[amd->cur_target][amd->cur_lun]--;
1829 amd->untagged_srbs[amd->cur_target][amd->cur_lun] = NULL;
1832 amd_write8(amd, SCSIDESTIDREG, amd->cur_target);
1833 amd_write8(amd, SYNCPERIOREG, tinfo->sync_period_reg);
1834 amd_write8(amd, SYNCOFFREG, tinfo->sync_offset_reg);
1835 amd_write8(amd, CNTLREG1, tinfo->CtrlR1);
1836 amd_write8(amd, CNTLREG3, tinfo->CtrlR3);
1837 amd_write8(amd, CNTLREG4, tinfo->CtrlR4);
1838 amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD);/* drop /ACK */
1839 amd->last_phase = SCSI_NOP0;
1843 SRBdone(struct amd_softc *amd, struct amd_srb *pSRB)
1845 u_int8_t bval, i, status;
1847 struct ccb_scsiio *pcsio;
1849 struct amd_sg *ptr2;
1851 u_int target_id, target_lun;
1854 pcsio = &pccb->csio;
1855 target_id = pSRB->pccb->ccb_h.target_id;
1856 target_lun = pSRB->pccb->ccb_h.target_lun;
1858 CAM_DEBUG(pccb->ccb_h.path, CAM_DEBUG_TRACE,
1859 ("SRBdone - TagNumber %d\n", pSRB->TagNumber));
1861 if ((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
1862 bus_dmasync_op_t op;
1864 if ((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
1865 op = BUS_DMASYNC_POSTREAD;
1867 op = BUS_DMASYNC_POSTWRITE;
1868 bus_dmamap_sync(amd->buffer_dmat, pSRB->dmamap, op);
1869 bus_dmamap_unload(amd->buffer_dmat, pSRB->dmamap);
1872 status = pSRB->TargetStatus;
1873 pccb->ccb_h.status = CAM_REQ_CMP;
1874 pccb->ccb_h.status = CAM_REQ_CMP;
1875 if (pSRB->SRBFlag & AUTO_REQSENSE) {
1876 pSRB->SRBFlag &= ~AUTO_REQSENSE;
1877 pSRB->AdaptStatus = 0;
1878 pSRB->TargetStatus = SCSI_STATUS_CHECK_COND;
1880 if (status == SCSI_STATUS_CHECK_COND) {
1881 pccb->ccb_h.status = CAM_SEL_TIMEOUT;
1884 *((u_int32_t *)&(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
1886 pcsio->sense_resid = pcsio->sense_len
1887 - pSRB->TotalXferredLen;
1888 pSRB->TotalXferredLen = pSRB->Segment1[1];
1889 if (pSRB->TotalXferredLen) {
1891 pcsio->resid = pcsio->dxfer_len
1892 - pSRB->TotalXferredLen;
1893 /* The resid field contains valid data */
1894 /* Flush resid bytes on complete */
1896 pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
1898 pccb->ccb_h.status = CAM_AUTOSNS_VALID|CAM_SCSI_STATUS_ERROR;
1902 if (status == SCSI_STATUS_CHECK_COND) {
1904 if ((pSRB->SGIndex < pSRB->SGcount)
1905 && (pSRB->SGcount) && (pSRB->SGToBeXferLen)) {
1906 bval = pSRB->SGcount;
1907 swlval = pSRB->SGToBeXferLen;
1908 ptr2 = pSRB->pSGlist;
1910 for (i = pSRB->SGIndex + 1; i < bval; i++) {
1911 swlval += ptr2->SGXLen;
1915 pcsio->resid = (u_int32_t) swlval;
1918 printf("XferredLen=%8x,NotYetXferLen=%8x,",
1919 pSRB->TotalXferredLen, swlval);
1922 if ((pcsio->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) {
1924 printf("RequestSense..................\n");
1926 RequestSense(amd, pSRB);
1929 pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
1930 pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
1932 } else if (status == SCSI_STATUS_QUEUE_FULL) {
1933 pSRB->AdaptStatus = 0;
1934 pSRB->TargetStatus = 0;
1935 pcsio->scsi_status = SCSI_STATUS_QUEUE_FULL;
1936 pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
1938 } else if (status == AMD_SCSI_STAT_SEL_TIMEOUT) {
1939 pSRB->AdaptStatus = H_SEL_TIMEOUT;
1940 pSRB->TargetStatus = 0;
1942 pcsio->scsi_status = AMD_SCSI_STAT_SEL_TIMEOUT;
1943 pccb->ccb_h.status = CAM_SEL_TIMEOUT;
1944 } else if (status == SCSI_STATUS_BUSY) {
1946 printf("DC390: target busy at %s %d\n",
1947 __FILE__, __LINE__);
1949 pcsio->scsi_status = SCSI_STATUS_BUSY;
1950 pccb->ccb_h.status = CAM_SCSI_BUSY;
1951 } else if (status == SCSI_STATUS_RESERV_CONFLICT) {
1953 printf("DC390: target reserved at %s %d\n",
1954 __FILE__, __LINE__);
1956 pcsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT;
1957 pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; /* XXX */
1959 pSRB->AdaptStatus = 0;
1961 printf("DC390: driver stuffup at %s %d\n",
1962 __FILE__, __LINE__);
1964 pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
1967 status = pSRB->AdaptStatus;
1968 if (status & H_OVER_UNDER_RUN) {
1969 pSRB->TargetStatus = 0;
1971 pccb->ccb_h.status = CAM_DATA_RUN_ERR;
1972 } else if (pSRB->SRBStatus & PARITY_ERROR) {
1974 printf("DC390: driver stuffup %s %d\n",
1975 __FILE__, __LINE__);
1977 /* Driver failed to perform operation */
1978 pccb->ccb_h.status = CAM_UNCOR_PARITY;
1979 } else { /* No error */
1980 pSRB->AdaptStatus = 0;
1981 pSRB->TargetStatus = 0;
1983 /* there is no error, (sense is invalid) */
1988 if ((pccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1989 /* CAM request not yet complete =>device_Q frozen */
1990 xpt_freeze_devq(pccb->ccb_h.path, 1);
1991 pccb->ccb_h.status |= CAM_DEV_QFRZN;
1993 TAILQ_REMOVE(&amd->running_srbs, pSRB, links);
1994 TAILQ_INSERT_HEAD(&amd->free_srbs, pSRB, links);
2002 amd_ResetSCSIBus(struct amd_softc * amd)
2007 amd->ACBFlag |= RESET_DEV;
2008 amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD);
2009 amd_write8(amd, SCSICMDREG, RST_SCSI_BUS_CMD);
2015 amd_ScsiRstDetect(struct amd_softc * amd)
2021 printf("amd_ScsiRstDetect \n");
2025 while (--wlval) { /* delay 1 sec */
2030 amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD);
2031 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
2033 if (amd->ACBFlag & RESET_DEV) {
2034 amd->ACBFlag |= RESET_DONE;
2036 amd->ACBFlag |= RESET_DETECT;
2038 amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD,
2039 AMD_TAG_WILDCARD, &amd->running_srbs,
2040 CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET);
2041 amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD,
2042 AMD_TAG_WILDCARD, &amd->waiting_srbs,
2043 CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET);
2044 amd->active_srb = NULL;
2053 RequestSense(struct amd_softc *amd, struct amd_srb *pSRB)
2056 struct ccb_scsiio *pcsio;
2059 pcsio = &pccb->csio;
2061 pSRB->SRBFlag |= AUTO_REQSENSE;
2062 pSRB->Segment0[0] = *((u_int32_t *) & (pSRB->CmdBlock[0]));
2063 pSRB->Segment0[1] = *((u_int32_t *) & (pSRB->CmdBlock[4]));
2064 pSRB->Segment1[0] = (pSRB->ScsiCmdLen << 8) + pSRB->SGcount;
2065 pSRB->Segment1[1] = pSRB->TotalXferredLen;
2067 pSRB->AdaptStatus = 0;
2068 pSRB->TargetStatus = 0;
2070 pSRB->Segmentx.SGXPtr = (u_int32_t) vtophys(&pcsio->sense_data);
2071 pSRB->Segmentx.SGXLen = (u_int32_t) pcsio->sense_len;
2073 pSRB->pSGlist = &pSRB->Segmentx;
2077 *((u_int32_t *) & (pSRB->CmdBlock[0])) = 0x00000003;
2078 pSRB->CmdBlock[1] = pSRB->pccb->ccb_h.target_lun << 5;
2079 *((u_int16_t *) & (pSRB->CmdBlock[4])) = pcsio->sense_len;
2080 pSRB->ScsiCmdLen = 6;
2082 pSRB->TotalXferredLen = 0;
2083 pSRB->SGToBeXferLen = 0;
2084 if (amdstart(amd, pSRB) != 0) {
2085 TAILQ_REMOVE(&amd->running_srbs, pSRB, links);
2086 TAILQ_INSERT_HEAD(&amd->waiting_srbs, pSRB, links);
2091 amd_InvalidCmd(struct amd_softc * amd)
2093 struct amd_srb *srb;
2095 srb = amd->active_srb;
2096 if (srb->SRBState & (SRB_START|SRB_MSGOUT))
2097 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
2101 amd_linkSRB(struct amd_softc *amd)
2104 struct amd_srb *psrb;
2106 count = amd->SRBCount;
2108 for (i = 0; i < count; i++) {
2109 psrb = (struct amd_srb *)&amd->SRB_array[i];
2110 psrb->TagNumber = i;
2111 TAILQ_INSERT_TAIL(&amd->free_srbs, psrb, links);
2116 amd_EnDisableCE(struct amd_softc *amd, int mode, int *regval)
2118 if (mode == ENABLE_CE) {
2123 pci_write_config(amd->dev, *regval, 0, /*bytes*/1);
2124 if (mode == DISABLE_CE) {
2125 pci_write_config(amd->dev, *regval, 0, /*bytes*/1);
2131 amd_EEpromOutDI(struct amd_softc *amd, int *regval, int Carry)
2139 pci_write_config(amd->dev, *regval, bval, /*bytes*/1);
2143 pci_write_config(amd->dev, *regval, bval, /*bytes*/1);
2145 pci_write_config(amd->dev, *regval, 0, /*bytes*/1);
2150 amd_EEpromInDO(struct amd_softc *amd)
2152 pci_write_config(amd->dev, 0x80, 0x80, /*bytes*/1);
2154 pci_write_config(amd->dev, 0x80, 0x40, /*bytes*/1);
2156 if (pci_read_config(amd->dev, 0, /*bytes*/1) == 0x22)
2162 EEpromGetData1(struct amd_softc *amd)
2169 for (i = 0; i < 16; i++) {
2171 carryFlag = amd_EEpromInDO(amd);
2178 amd_Prepare(struct amd_softc *amd, int *regval, u_int8_t EEpromCmd)
2185 for (i = 0; i < 9; i++) {
2186 amd_EEpromOutDI(amd, regval, carryFlag);
2187 carryFlag = (EEpromCmd & j) ? 1 : 0;
2193 amd_ReadEEprom(struct amd_softc *amd)
2200 ptr = (u_int16_t *)&amd->eepromBuf[0];
2202 for (i = 0; i < 0x40; i++) {
2203 amd_EnDisableCE(amd, ENABLE_CE, ®val);
2204 amd_Prepare(amd, ®val, cmd);
2205 *ptr = EEpromGetData1(amd);
2208 amd_EnDisableCE(amd, DISABLE_CE, ®val);
2213 amd_load_defaults(struct amd_softc *amd)
2217 bzero(&amd->eepromBuf, sizeof amd->eepromBuf);
2218 for (target = 0; target < MAX_SCSI_ID; target++)
2219 amd->eepromBuf[target << 2] =
2220 (TAG_QUEUING|EN_DISCONNECT|SYNC_NEGO|PARITY_CHK);
2221 amd->eepromBuf[EE_ADAPT_SCSI_ID] = 7;
2222 amd->eepromBuf[EE_MODE2] = ACTIVE_NEGATION|LUN_CHECK|GREATER_1G;
2223 amd->eepromBuf[EE_TAG_CMD_NUM] = 4;
2227 amd_load_eeprom_or_defaults(struct amd_softc *amd)
2229 u_int16_t wval, *ptr;
2232 amd_ReadEEprom(amd);
2234 ptr = (u_int16_t *) & amd->eepromBuf[0];
2235 for (i = 0; i < EE_DATA_SIZE; i += 2, ptr++)
2238 if (wval != EE_CHECKSUM) {
2240 printf("amd%d: SEEPROM data unavailable. "
2241 "Using default device parameters.\n",
2243 amd_load_defaults(amd);
2248 **********************************************************************
2249 * Function : static int amd_init (struct Scsi_Host *host)
2250 * Purpose : initialize the internal structures for a given SCSI host
2251 * Inputs : host - pointer to this host adapter's structure/
2252 **********************************************************************
2255 amd_init(device_t dev)
2257 struct amd_softc *amd = device_get_softc(dev);
2258 struct resource *iores;
2262 rid = PCI_BASE_ADDR0;
2263 iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
2265 if (iores == NULL) {
2267 printf("amd_init: bus_alloc_resource failure!\n");
2270 amd->tag = rman_get_bustag(iores);
2271 amd->bsh = rman_get_bushandle(iores);
2273 /* DMA tag for mapping buffers into device visible space. */
2274 if (bus_dma_tag_create(/*parent_dmat*/NULL, /*alignment*/1,
2276 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
2277 /*highaddr*/BUS_SPACE_MAXADDR,
2278 /*filter*/NULL, /*filterarg*/NULL,
2279 /*maxsize*/MAXBSIZE, /*nsegments*/AMD_NSEG,
2280 /*maxsegsz*/AMD_MAXTRANSFER_SIZE,
2281 /*flags*/BUS_DMA_ALLOCNOW,
2282 &amd->buffer_dmat) != 0) {
2284 printf("amd_init: bus_dma_tag_create failure!\n");
2287 TAILQ_INIT(&amd->free_srbs);
2288 TAILQ_INIT(&amd->running_srbs);
2289 TAILQ_INIT(&amd->waiting_srbs);
2290 amd->last_phase = SCSI_BUS_FREE;
2292 amd->unit = device_get_unit(dev);
2293 amd->SRBCount = MAX_SRB_CNT;
2295 amd_load_eeprom_or_defaults(amd);
2297 if (amd->eepromBuf[EE_MODE2] & LUN_CHECK) {
2302 amd->AdaptSCSIID = amd->eepromBuf[EE_ADAPT_SCSI_ID];
2303 amd->HostID_Bit = (1 << amd->AdaptSCSIID);
2304 amd->AdaptSCSILUN = 0;
2305 /* (eepromBuf[EE_TAG_CMD_NUM]) << 2; */
2307 amd->Gmode2 = amd->eepromBuf[EE_MODE2];
2309 for (i = 0; i <= amd->max_id; i++) {
2311 if (amd->AdaptSCSIID != i) {
2312 struct amd_target_info *tinfo;
2315 tinfo = &amd->tinfo[i];
2316 prom = (PEEprom)&amd->eepromBuf[i << 2];
2317 if ((prom->EE_MODE1 & EN_DISCONNECT) != 0) {
2318 tinfo->disc_tag |= AMD_USR_DISCENB;
2319 if ((prom->EE_MODE1 & TAG_QUEUING) != 0)
2320 tinfo->disc_tag |= AMD_USR_TAGENB;
2322 if ((prom->EE_MODE1 & SYNC_NEGO) != 0) {
2323 tinfo->user.period =
2324 eeprom_period[prom->EE_SPEED];
2325 tinfo->user.offset = AMD_MAX_SYNC_OFFSET;
2327 tinfo->CtrlR1 = amd->AdaptSCSIID;
2328 if ((prom->EE_MODE1 & PARITY_CHK) != 0)
2329 tinfo->CtrlR1 |= PARITY_ERR_REPO;
2330 tinfo->CtrlR3 = FAST_CLK;
2331 tinfo->CtrlR4 = EATER_25NS;
2332 if ((amd->eepromBuf[EE_MODE2] & ACTIVE_NEGATION) != 0)
2333 tinfo->CtrlR4 |= NEGATE_REQACKDATA;
2336 amd_write8(amd, SCSITIMEOUTREG, 153); /* 250ms selection timeout */
2337 /* Conversion factor = 0 , 40MHz clock */
2338 amd_write8(amd, CLKFACTREG, CLK_FREQ_40MHZ);
2339 /* NOP cmd - clear command register */
2340 amd_write8(amd, SCSICMDREG, NOP_CMD);
2341 amd_write8(amd, CNTLREG2, EN_FEATURE|EN_SCSI2_CMD);
2342 amd_write8(amd, CNTLREG3, FAST_CLK);
2344 if (amd->eepromBuf[EE_MODE2] & ACTIVE_NEGATION) {
2345 bval |= NEGATE_REQACKDATA;
2347 amd_write8(amd, CNTLREG4, bval);
2349 /* Disable SCSI bus reset interrupt */
2350 amd_write8(amd, CNTLREG1, DIS_INT_ON_SCSI_RST);
2356 * attach and init a host adapter
2359 amd_attach(device_t dev)
2361 struct cam_devq *devq; /* Device Queue to use for this SIM */
2363 struct amd_softc *amd = device_get_softc(dev);
2364 int unit = device_get_unit(dev);
2367 struct resource *irqres;
2369 if (amd_init(dev)) {
2371 printf("amd_attach: amd_init failure!\n");
2375 /* Reset Pending INT */
2376 intstat = amd_read8(amd, INTSTATREG);
2378 /* After setting up the adapter, map our interrupt */
2380 irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
2381 RF_SHAREABLE | RF_ACTIVE);
2382 if (irqres == NULL ||
2383 bus_setup_intr(dev, irqres, INTR_TYPE_CAM, amd_intr, amd, &ih)) {
2385 printf("amd%d: unable to register interrupt handler!\n",
2391 * Now let the CAM generic SCSI layer find the SCSI devices on
2392 * the bus * start queue to reset to the idle loop. *
2393 * Create device queue of SIM(s) * (MAX_START_JOB - 1) :
2394 * max_sim_transactions
2396 devq = cam_simq_alloc(MAX_START_JOB);
2399 printf("amd_attach: cam_simq_alloc failure!\n");
2403 amd->psim = cam_sim_alloc(amd_action, amd_poll, "amd",
2404 amd, amd->unit, 1, MAX_TAGS_CMD_QUEUE,
2406 if (amd->psim == NULL) {
2407 cam_simq_free(devq);
2409 printf("amd_attach: cam_sim_alloc failure!\n");
2413 if (xpt_bus_register(amd->psim, 0) != CAM_SUCCESS) {
2414 cam_sim_free(amd->psim, /*free_devq*/TRUE);
2416 printf("amd_attach: xpt_bus_register failure!\n");
2420 if (xpt_create_path(&amd->ppath, /* periph */ NULL,
2421 cam_sim_path(amd->psim), CAM_TARGET_WILDCARD,
2422 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2423 xpt_bus_deregister(cam_sim_path(amd->psim));
2424 cam_sim_free(amd->psim, /* free_simq */ TRUE);
2426 printf("amd_attach: xpt_create_path failure!\n");
2434 amd_probe(device_t dev)
2436 if (pci_get_devid(dev) == PCI_DEVICE_ID_AMD53C974) {
2437 device_set_desc(dev,
2438 "Tekram DC390(T)/AMD53c974 SCSI Host Adapter");
2444 static device_method_t amd_methods[] = {
2445 /* Device interface */
2446 DEVMETHOD(device_probe, amd_probe),
2447 DEVMETHOD(device_attach, amd_attach),
2451 static driver_t amd_driver = {
2452 "amd", amd_methods, sizeof(struct amd_softc)
2455 static devclass_t amd_devclass;
2456 DRIVER_MODULE(amd, pci, amd_driver, amd_devclass, 0, 0);