timeout/untimeout ==> callout_*
[dragonfly.git] / sys / dev / disk / amd / amd.c
1 /*
2  *********************************************************************
3  *      FILE NAME  : amd.c
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.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
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.
21  *
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.5 2004/09/17 03:39:39 joerg Exp $
35  */
36
37 /*
38  *********************************************************************
39  *      HISTORY:
40  *
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  *********************************************************************
49  */
50
51 /* #define AMD_DEBUG0           */
52 /* #define AMD_DEBUG_SCSI_PHASE */
53
54 #include <sys/param.h>
55
56 #include <sys/systm.h>
57 #include <sys/malloc.h>
58 #include <sys/queue.h>
59 #include <sys/buf.h>
60 #include <sys/kernel.h>
61
62 #include <vm/vm.h>
63 #include <vm/pmap.h>
64
65 #include <machine/bus_pio.h>
66 #include <machine/bus.h>
67 #include <machine/clock.h>
68 #include <machine/resource.h>
69 #include <sys/bus.h>
70 #include <sys/rman.h>
71
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>
77
78 #include <bus/cam/scsi/scsi_all.h>
79 #include <bus/cam/scsi/scsi_message.h>
80
81 #include <bus/pci/pcivar.h>
82 #include <bus/pci/pcireg.h>
83 #include "amd.h"
84
85 #define PCI_DEVICE_ID_AMD53C974         0x20201022ul
86 #define PCI_BASE_ADDR0                  0x10
87
88 typedef u_int (phase_handler_t)(struct amd_softc *, struct amd_srb *, u_int);
89 typedef phase_handler_t *phase_handler_func_t;
90
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;
94
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;
107
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);
115
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);
124
125 #if 0
126 static void amd_timeout(void *arg1);
127 static void amd_reset(struct amd_softc *amd);
128 #endif
129 static u_int8_t * phystovirt(struct amd_srb *pSRB, u_int32_t xferCnt);
130
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);
141
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,
146                              cam_status status);
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);
150
151 static __inline void amd_clear_msg_state(struct amd_softc *amd);
152
153 static __inline void
154 amd_clear_msg_state(struct amd_softc *amd)
155 {
156         amd->msgout_len = 0;
157         amd->msgout_index = 0;
158         amd->msgin_index = 0;
159 }
160
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);
166
167 /*
168  * State engine function tables indexed by SCSI phase number
169  */
170 phase_handler_func_t amd_SCSI_phase0[] = {
171         amd_DataOutPhase0,
172         amd_DataInPhase0,
173         amd_CommandPhase0,
174         amd_StatusPhase0,
175         amd_NopPhase,
176         amd_NopPhase,
177         amd_MsgOutPhase0,
178         amd_MsgInPhase0
179 };
180
181 phase_handler_func_t amd_SCSI_phase1[] = {
182         amd_DataOutPhase1,
183         amd_DataInPhase1,
184         amd_CommandPhase1,
185         amd_StatusPhase1,
186         amd_NopPhase,
187         amd_NopPhase,
188         amd_MsgOutPhase1,
189         amd_MsgInPhase1
190 };
191
192 /*
193  * EEProm/BIOS negotiation periods
194  */
195 u_int8_t   eeprom_period[] = {
196          25,    /* 10.0MHz */
197          32,    /*  8.0MHz */
198          38,    /*  6.6MHz */
199          44,    /*  5.7MHz */
200          50,    /*  5.0MHz */
201          63,    /*  4.0MHz */
202          83,    /*  3.0MHz */
203         125     /*  2.0MHz */
204 };
205
206 /*
207  * chip clock setting to SCSI specified sync parameter table.
208  */
209 u_int8_t tinfo_sync_period[] = {
210         25,     /* 10.0 */
211         32,     /* 8.0 */
212         38,     /* 6.6 */
213         44,     /* 5.7 */
214         50,     /* 5.0 */
215         57,     /* 4.4 */
216         63,     /* 4.0 */
217         70,     /* 3.6 */
218         76,     /* 3.3 */
219         83      /* 3.0 */
220 };
221
222 static __inline struct amd_srb *
223 amdgetsrb(struct amd_softc * amd)
224 {
225         int     intflag;
226         struct amd_srb *    pSRB;
227
228         intflag = splcam();
229         pSRB = TAILQ_FIRST(&amd->free_srbs);
230         if (pSRB)
231                 TAILQ_REMOVE(&amd->free_srbs, pSRB, links);
232         splx(intflag);
233         return (pSRB);
234 }
235
236 static void
237 amdsetupcommand(struct amd_softc *amd, struct amd_srb *srb)
238 {
239         struct scsi_request_sense sense_cmd;
240         struct ccb_scsiio *csio;
241         u_int8_t *cdb;
242         u_int cdb_len;
243
244         csio = &srb->pccb->csio;
245
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);
255         } else {
256                 cdb = &srb->CmdBlock[0];
257                 cdb_len = srb->ScsiCmdLen;
258         }
259         amd_write8_multi(amd, SCSIFIFOREG, cdb, cdb_len);
260 }
261
262 /*
263  * Attempt to start a waiting transaction.  Interrupts must be disabled
264  * upon entry to this function.
265  */
266 static void
267 amdrunwaiting(struct amd_softc *amd) {
268         struct amd_srb *srb;
269
270         if (amd->last_phase != SCSI_BUS_FREE)
271                 return;
272
273         srb = TAILQ_FIRST(&amd->waiting_srbs);
274         if (srb == NULL)
275                 return;
276         
277         if (amdstart(amd, srb) == 0) {
278                 TAILQ_REMOVE(&amd->waiting_srbs, srb, links);
279                 TAILQ_INSERT_HEAD(&amd->running_srbs, srb, links);
280         }
281 }
282
283 static void
284 amdexecutesrb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
285 {
286         struct   amd_srb *srb;
287         union    ccb *ccb;
288         struct   amd_softc *amd;
289         int      s;
290
291         srb = (struct amd_srb *)arg;
292         ccb = srb->pccb;
293         amd = (struct amd_softc *)ccb->ccb_h.ccb_amd_ptr;
294
295         if (error != 0) {
296                 if (error != EFBIG)
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;
302                 }
303                 TAILQ_INSERT_HEAD(&amd->free_srbs, srb, links);
304                 xpt_done(ccb);
305                 return;
306         }
307
308         if (nseg != 0) {
309                 struct amd_sg *sg;
310                 bus_dma_segment_t *end_seg;
311                 bus_dmasync_op_t op;
312
313                 end_seg = dm_segs + nseg;
314
315                 /* Copy the segments into our SG list */
316                 srb->pSGlist = &srb->SGsegment[0];
317                 sg = srb->pSGlist;
318                 while (dm_segs < end_seg) {
319                         sg->SGXLen = dm_segs->ds_len;
320                         sg->SGXPtr = dm_segs->ds_addr;
321                         sg++;
322                         dm_segs++;
323                 }
324
325                 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
326                         op = BUS_DMASYNC_PREREAD;
327                 else
328                         op = BUS_DMASYNC_PREWRITE;
329
330                 bus_dmamap_sync(amd->buffer_dmat, srb->dmamap, op);
331
332         }
333         srb->SGcount = nseg;
334         srb->SGIndex = 0;
335         srb->AdaptStatus = 0;
336         srb->TargetStatus = 0;
337         srb->MsgCnt = 0;
338         srb->SRBStatus = 0;
339         srb->SRBFlag = 0;
340         srb->SRBState = 0;
341         srb->TotalXferredLen = 0;
342         srb->SGPhysAddr = 0;
343         srb->SGToBeXferLen = 0;
344         srb->EndMessage = 0;
345
346         s = splcam();
347
348         /*
349          * Last time we need to check if this CCB needs to
350          * be aborted.
351          */
352         if (ccb->ccb_h.status != CAM_REQ_INPROG) {
353                 if (nseg != 0)
354                         bus_dmamap_unload(amd->buffer_dmat, srb->dmamap);
355                 TAILQ_INSERT_HEAD(&amd->free_srbs, srb, links);
356                 xpt_done(ccb);
357                 splx(s);
358                 return;
359         }
360         ccb->ccb_h.status |= CAM_SIM_QUEUED;
361 #if 0
362         /* XXX Need a timeout handler */
363         callout_reset(&ccb->ccb_h.timeout_ch, (ccb->ccb_h.timeout * hz) / 1000,
364             amdtimeout, srb);
365 #endif
366         TAILQ_INSERT_TAIL(&amd->waiting_srbs, srb, links);
367         amdrunwaiting(amd);
368         splx(s);
369 }
370
371 static void
372 amd_action(struct cam_sim * psim, union ccb * pccb)
373 {
374         struct amd_softc *    amd;
375         u_int   target_id, target_lun;
376
377         CAM_DEBUG(pccb->ccb_h.path, CAM_DEBUG_TRACE, ("amd_action\n"));
378
379         amd = (struct amd_softc *) cam_sim_softc(psim);
380         target_id = pccb->ccb_h.target_id;
381         target_lun = pccb->ccb_h.target_lun;
382
383         switch (pccb->ccb_h.func_code) {
384         case XPT_SCSI_IO:
385         {
386                 struct amd_srb *    pSRB;
387                 struct ccb_scsiio *pcsio;
388
389                 pcsio = &pccb->csio;
390
391                 /*
392                  * Assign an SRB and connect it with this ccb.
393                  */
394                 pSRB = amdgetsrb(amd);
395
396                 if (!pSRB) {
397                         /* Freeze SIMQ */
398                         pccb->ccb_h.status = CAM_RESRC_UNAVAIL;
399                         xpt_done(pccb);
400                         return;
401                 }
402                 pSRB->pccb = pccb;
403                 pccb->ccb_h.ccb_srb_ptr = pSRB;
404                 pccb->ccb_h.ccb_amd_ptr = amd;
405                 pSRB->ScsiCmdLen = pcsio->cdb_len;
406                 bcopy(pcsio->cdb_io.cdb_bytes, pSRB->CmdBlock, pcsio->cdb_len);
407                 if ((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
408                         if ((pccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) {
409                                 /*
410                                  * We've been given a pointer
411                                  * to a single buffer.
412                                  */
413                                 if ((pccb->ccb_h.flags & CAM_DATA_PHYS) == 0) {
414                                         int s;
415                                         int error;
416
417                                         s = splsoftvm();
418                                         error =
419                                             bus_dmamap_load(amd->buffer_dmat,
420                                                             pSRB->dmamap,
421                                                             pcsio->data_ptr,
422                                                             pcsio->dxfer_len,
423                                                             amdexecutesrb,
424                                                             pSRB, /*flags*/0);
425                                         if (error == EINPROGRESS) {
426                                                 /*
427                                                  * So as to maintain
428                                                  * ordering, freeze the
429                                                  * controller queue
430                                                  * until our mapping is
431                                                  * returned.
432                                                  */
433                                                 xpt_freeze_simq(amd->psim, 1);
434                                                 pccb->ccb_h.status |=
435                                                     CAM_RELEASE_SIMQ;
436                                         }
437                                         splx(s);
438                                 } else {
439                                         struct bus_dma_segment seg;
440
441                                         /* Pointer to physical buffer */
442                                         seg.ds_addr =
443                                             (bus_addr_t)pcsio->data_ptr;
444                                         seg.ds_len = pcsio->dxfer_len;
445                                         amdexecutesrb(pSRB, &seg, 1, 0);
446                                 }
447                         } else {
448                                 struct bus_dma_segment *segs;
449
450                                 if ((pccb->ccb_h.flags & CAM_SG_LIST_PHYS) == 0
451                                  || (pccb->ccb_h.flags & CAM_DATA_PHYS) != 0) {
452                                         TAILQ_INSERT_HEAD(&amd->free_srbs,
453                                                           pSRB, links);
454                                         pccb->ccb_h.status = CAM_PROVIDE_FAIL;
455                                         xpt_done(pccb);
456                                         return;
457                                 }
458
459                                 /* Just use the segments provided */
460                                 segs =
461                                     (struct bus_dma_segment *)pcsio->data_ptr;
462                                 amdexecutesrb(pSRB, segs, pcsio->sglist_cnt, 0);
463                         }
464                 } else
465                         amdexecutesrb(pSRB, NULL, 0, 0);
466                 break;
467         }
468         case XPT_PATH_INQ:
469         {
470                 struct ccb_pathinq *cpi = &pccb->cpi;
471
472                 cpi->version_num = 1;
473                 cpi->hba_inquiry = PI_SDTR_ABLE | PI_TAG_ABLE;
474                 cpi->target_sprt = 0;
475                 cpi->hba_misc = 0;
476                 cpi->hba_eng_cnt = 0;
477                 cpi->max_target = 7;
478                 cpi->max_lun = amd->max_lun;    /* 7 or 0 */
479                 cpi->initiator_id = amd->AdaptSCSIID;
480                 cpi->bus_id = cam_sim_bus(psim);
481                 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
482                 strncpy(cpi->hba_vid, "TRM-AMD", HBA_IDLEN);
483                 strncpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN);
484                 cpi->unit_number = cam_sim_unit(psim);
485                 cpi->ccb_h.status = CAM_REQ_CMP;
486                 xpt_done(pccb);
487                 break;
488         }
489         case XPT_ABORT:
490                 pccb->ccb_h.status = CAM_REQ_INVALID;
491                 xpt_done(pccb);
492                 break;
493         case XPT_RESET_BUS:
494         {
495
496                 int     i;
497
498                 amd_ResetSCSIBus(amd);
499                 amd->ACBFlag = 0;
500
501                 for (i = 0; i < 500; i++) {
502                         DELAY(1000);    /* Wait until our interrupt
503                                          * handler sees it */
504                 }
505
506                 pccb->ccb_h.status = CAM_REQ_CMP;
507                 xpt_done(pccb);
508                 break;
509         }
510         case XPT_RESET_DEV:
511                 pccb->ccb_h.status = CAM_REQ_INVALID;
512                 xpt_done(pccb);
513                 break;
514         case XPT_TERM_IO:
515                 pccb->ccb_h.status = CAM_REQ_INVALID;
516                 xpt_done(pccb);
517         case XPT_GET_TRAN_SETTINGS:
518         {
519                 struct ccb_trans_settings *cts;
520                 struct amd_target_info *targ_info;
521                 struct amd_transinfo *tinfo;
522                 int     intflag;
523
524                 cts = &pccb->cts;
525                 intflag = splcam();
526                 targ_info = &amd->tinfo[target_id];
527                 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) {
528                         /* current transfer settings */
529                         if (targ_info->disc_tag & AMD_CUR_DISCENB) {
530                                 cts->flags = CCB_TRANS_DISC_ENB;
531                         } else {
532                                 cts->flags = 0; /* no tag & disconnect */
533                         }
534                         if (targ_info->disc_tag & AMD_CUR_TAGENB) {
535                                 cts->flags |= CCB_TRANS_TAG_ENB;
536                         }
537                         tinfo = &targ_info->current;
538                 } else {
539                         /* default(user) transfer settings */
540                         if (targ_info->disc_tag & AMD_USR_DISCENB) {
541                                 cts->flags = CCB_TRANS_DISC_ENB;
542                         } else {
543                                 cts->flags = 0;
544                         }
545                         if (targ_info->disc_tag & AMD_USR_TAGENB) {
546                                 cts->flags |= CCB_TRANS_TAG_ENB;
547                         }
548                         tinfo = &targ_info->user;
549                 }
550
551                 cts->sync_period = tinfo->period;
552                 cts->sync_offset = tinfo->offset;
553                 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
554                 splx(intflag);
555                 cts->valid = CCB_TRANS_SYNC_RATE_VALID
556                            | CCB_TRANS_SYNC_OFFSET_VALID
557                            | CCB_TRANS_BUS_WIDTH_VALID
558                            | CCB_TRANS_DISC_VALID
559                            | CCB_TRANS_TQ_VALID;
560                 pccb->ccb_h.status = CAM_REQ_CMP;
561                 xpt_done(pccb);
562                 break;
563         }
564         case XPT_SET_TRAN_SETTINGS:
565         {
566                 struct ccb_trans_settings *cts;
567                 struct amd_target_info *targ_info;
568                 u_int  update_type;
569                 int    intflag;
570                 int    last_entry;
571
572                 cts = &pccb->cts;
573                 update_type = 0;
574                 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) {
575                         update_type |= AMD_TRANS_GOAL;
576                 } else if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) {
577                         update_type |= AMD_TRANS_USER;
578                 }
579                 if (update_type == 0
580                  || update_type == (AMD_TRANS_USER|AMD_TRANS_GOAL)) {
581                         cts->ccb_h.status = CAM_REQ_INVALID;
582                         xpt_done(pccb);
583                 }
584
585                 intflag = splcam();
586                 targ_info = &amd->tinfo[target_id];
587
588                 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) {
589                         if (update_type & AMD_TRANS_GOAL) {
590                                 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) {
591                                         targ_info->disc_tag |= AMD_CUR_DISCENB;
592                                 } else {
593                                         targ_info->disc_tag &= ~AMD_CUR_DISCENB;
594                                 }
595                         }
596                         if (update_type & AMD_TRANS_USER) {
597                                 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) {
598                                         targ_info->disc_tag |= AMD_USR_DISCENB;
599                                 } else {
600                                         targ_info->disc_tag &= ~AMD_USR_DISCENB;
601                                 }
602                         }
603                 }
604                 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) {
605                         if (update_type & AMD_TRANS_GOAL) {
606                                 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) {
607                                         targ_info->disc_tag |= AMD_CUR_TAGENB;
608                                 } else {
609                                         targ_info->disc_tag &= ~AMD_CUR_TAGENB;
610                                 }
611                         }
612                         if (update_type & AMD_TRANS_USER) {
613                                 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) {
614                                         targ_info->disc_tag |= AMD_USR_TAGENB;
615                                 } else {
616                                         targ_info->disc_tag &= ~AMD_USR_TAGENB;
617                                 }
618                         }
619                 }
620
621                 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) == 0) {
622                         if (update_type & AMD_TRANS_GOAL)
623                                 cts->sync_offset = targ_info->goal.offset;
624                         else
625                                 cts->sync_offset = targ_info->user.offset;
626                 }
627
628                 if (cts->sync_offset > AMD_MAX_SYNC_OFFSET)
629                         cts->sync_offset = AMD_MAX_SYNC_OFFSET;
630
631                 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) == 0) {
632                         if (update_type & AMD_TRANS_GOAL)
633                                 cts->sync_period = targ_info->goal.period;
634                         else
635                                 cts->sync_period = targ_info->user.period;
636                 }
637
638                 last_entry = sizeof(tinfo_sync_period) - 1;
639                 if ((cts->sync_period != 0)
640                  && (cts->sync_period < tinfo_sync_period[0]))
641                         cts->sync_period = tinfo_sync_period[0];
642                 if (cts->sync_period > tinfo_sync_period[last_entry])
643                         cts->sync_period = 0;
644                 if (cts->sync_offset == 0)
645                         cts->sync_period = 0;
646
647                 if ((update_type & AMD_TRANS_USER) != 0) {
648                         targ_info->user.period = cts->sync_period;
649                         targ_info->user.offset = cts->sync_offset;
650                 }
651                 if ((update_type & AMD_TRANS_GOAL) != 0) {
652                         targ_info->goal.period = cts->sync_period;
653                         targ_info->goal.offset = cts->sync_offset;
654                 }
655                 splx(intflag);
656                 pccb->ccb_h.status = CAM_REQ_CMP;
657                 xpt_done(pccb);
658                 break;
659         }
660         case XPT_CALC_GEOMETRY:
661         {
662                 struct ccb_calc_geometry *ccg;
663                 u_int32_t size_mb;
664                 u_int32_t secs_per_cylinder;
665                 int     extended;
666
667                 ccg = &pccb->ccg;
668                 size_mb = ccg->volume_size/((1024L * 1024L)/ccg->block_size);
669                 extended = (amd->eepromBuf[EE_MODE2] & GREATER_1G) != 0;
670
671                 if (size_mb > 1024 && extended) {
672                         ccg->heads = 255;
673                         ccg->secs_per_track = 63;
674                 } else {
675                         ccg->heads = 64;
676                         ccg->secs_per_track = 32;
677                 }
678                 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
679                 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
680                 pccb->ccb_h.status = CAM_REQ_CMP;
681                 xpt_done(pccb);
682                 break;
683         }
684         default:
685                 pccb->ccb_h.status = CAM_REQ_INVALID;
686                 xpt_done(pccb);
687                 break;
688         }
689 }
690
691 static void
692 amd_poll(struct cam_sim * psim)
693 {
694         amd_intr(cam_sim_softc(psim));
695 }
696
697 static u_int8_t * 
698 phystovirt(struct amd_srb * pSRB, u_int32_t xferCnt)
699 {
700         int     dataPtr;
701         struct ccb_scsiio *pcsio;
702         u_int8_t   i;
703         struct amd_sg *    pseg;
704
705         dataPtr = 0;
706         pcsio = &pSRB->pccb->csio;
707
708         dataPtr = (int) pcsio->data_ptr;
709         pseg = pSRB->SGsegment;
710         for (i = 0; i < pSRB->SGIndex; i++) {
711                 dataPtr += (int) pseg->SGXLen;
712                 pseg++;
713         }
714         dataPtr += (int) xferCnt;
715         return ((u_int8_t *) dataPtr);
716 }
717
718 static void
719 ResetDevParam(struct amd_softc * amd)
720 {
721         u_int target;
722
723         for (target = 0; target <= amd->max_id; target++) {
724                 if (amd->AdaptSCSIID != target) {
725                         amdsetsync(amd, target, /*clockrate*/0,
726                                    /*period*/0, /*offset*/0, AMD_TRANS_CUR);
727                 }
728         }
729 }
730
731 static void
732 amdcompletematch(struct amd_softc *amd, target_id_t target, lun_id_t lun,
733                  u_int tag, struct srb_queue *queue, cam_status status)
734 {
735         struct amd_srb *srb;
736         struct amd_srb *next_srb;
737
738         for (srb = TAILQ_FIRST(queue); srb != NULL; srb = next_srb) {
739                 union ccb *ccb;
740
741                 next_srb = TAILQ_NEXT(srb, links);
742                 if (srb->pccb->ccb_h.target_id != target
743                  && target != CAM_TARGET_WILDCARD)
744                         continue;
745
746                 if (srb->pccb->ccb_h.target_lun != lun
747                  && lun != CAM_LUN_WILDCARD)
748                         continue;
749
750                 if (srb->TagNumber != tag
751                  && tag != AMD_TAG_WILDCARD)
752                         continue;
753                 
754                 ccb = srb->pccb;
755                 TAILQ_REMOVE(queue, srb, links);
756                 TAILQ_INSERT_HEAD(&amd->free_srbs, srb, links);
757                 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0
758                  && (status & CAM_DEV_QFRZN) != 0)
759                         xpt_freeze_devq(ccb->ccb_h.path, /*count*/1);
760                 ccb->ccb_h.status = status;
761                 xpt_done(ccb);
762         }
763
764 }
765
766 static void
767 amdsetsync(struct amd_softc *amd, u_int target, u_int clockrate,
768            u_int period, u_int offset, u_int type)
769 {
770         struct amd_target_info *tinfo;
771         u_int old_period;
772         u_int old_offset;
773
774         tinfo = &amd->tinfo[target];
775         old_period = tinfo->current.period;
776         old_offset = tinfo->current.offset;
777         if ((type & AMD_TRANS_CUR) != 0
778          && (old_period != period || old_offset != offset)) {
779                 struct cam_path *path;
780
781                 tinfo->current.period = period;
782                 tinfo->current.offset = offset;
783                 tinfo->sync_period_reg = clockrate;
784                 tinfo->sync_offset_reg = offset;
785                 tinfo->CtrlR3 &= ~FAST_SCSI;
786                 tinfo->CtrlR4 &= ~EATER_25NS;
787                 if (clockrate > 7)
788                         tinfo->CtrlR4 |= EATER_25NS;
789                 else
790                         tinfo->CtrlR3 |= FAST_SCSI;
791
792                 if ((type & AMD_TRANS_ACTIVE) == AMD_TRANS_ACTIVE) {
793                         amd_write8(amd, SYNCPERIOREG, tinfo->sync_period_reg);
794                         amd_write8(amd, SYNCOFFREG, tinfo->sync_offset_reg);
795                         amd_write8(amd, CNTLREG3, tinfo->CtrlR3);
796                         amd_write8(amd, CNTLREG4, tinfo->CtrlR4);
797                 }
798                 /* If possible, update the XPT's notion of our transfer rate */
799                 if (xpt_create_path(&path, /*periph*/NULL,
800                                     cam_sim_path(amd->psim), target,
801                                     CAM_LUN_WILDCARD) == CAM_REQ_CMP) {
802                         struct ccb_trans_settings neg;
803
804                         xpt_setup_ccb(&neg.ccb_h, path, /*priority*/1);
805                         neg.sync_period = period;
806                         neg.sync_offset = offset;
807                         neg.valid = CCB_TRANS_SYNC_RATE_VALID
808                                   | CCB_TRANS_SYNC_OFFSET_VALID;
809                         xpt_async(AC_TRANSFER_NEG, path, &neg);
810                         xpt_free_path(path);    
811                 }
812         }
813         if ((type & AMD_TRANS_GOAL) != 0) {
814                 tinfo->goal.period = period;
815                 tinfo->goal.offset = offset;
816         }
817
818         if ((type & AMD_TRANS_USER) != 0) {
819                 tinfo->user.period = period;
820                 tinfo->user.offset = offset;
821         }
822 }
823
824 static void
825 amdsettags(struct amd_softc *amd, u_int target, int tagenb)
826 {
827         panic("Implement me!\n");
828 }
829
830
831 #if 0
832 /*
833  **********************************************************************
834  * Function : amd_reset (struct amd_softc * amd)
835  * Purpose  : perform a hard reset on the SCSI bus( and AMD chip).
836  * Inputs   : cmd - command which caused the SCSI RESET
837  **********************************************************************
838  */
839 static void
840 amd_reset(struct amd_softc * amd)
841 {
842         int        intflag;
843         u_int8_t   bval;
844         u_int16_t  i;
845
846
847 #ifdef AMD_DEBUG0
848         printf("DC390: RESET");
849 #endif
850
851         intflag = splcam();
852         bval = amd_read8(amd, CNTLREG1);
853         bval |= DIS_INT_ON_SCSI_RST;
854         amd_write8(amd, CNTLREG1, bval);        /* disable interrupt */
855         amd_ResetSCSIBus(amd);
856
857         for (i = 0; i < 500; i++) {
858                 DELAY(1000);
859         }
860
861         bval = amd_read8(amd, CNTLREG1);
862         bval &= ~DIS_INT_ON_SCSI_RST;
863         amd_write8(amd, CNTLREG1, bval);        /* re-enable interrupt */
864
865         amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD);
866         amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
867
868         ResetDevParam(amd);
869         amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD,
870                          AMD_TAG_WILDCARD, &amd->running_srbs,
871                          CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET);
872         amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD,
873                          AMD_TAG_WILDCARD, &amd->waiting_srbs,
874                          CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET);
875         amd->active_srb = NULL;
876         amd->ACBFlag = 0;
877         splx(intflag);
878         return;
879 }
880
881 void
882 amd_timeout(void *arg1)
883 {
884         struct amd_srb *    pSRB;
885
886         pSRB = (struct amd_srb *) arg1;
887 }
888 #endif
889
890 static int
891 amdstart(struct amd_softc *amd, struct amd_srb *pSRB)
892 {
893         union ccb *pccb;
894         struct ccb_scsiio *pcsio;
895         struct amd_target_info *targ_info;
896         u_int identify_msg;
897         u_int command;
898         u_int target;
899         u_int lun;
900         int tagged;
901
902         pccb = pSRB->pccb;
903         pcsio = &pccb->csio;
904         target = pccb->ccb_h.target_id;
905         lun = pccb->ccb_h.target_lun;
906         targ_info = &amd->tinfo[target];
907
908         amd_clear_msg_state(amd);
909         amd_write8(amd, SCSIDESTIDREG, target);
910         amd_write8(amd, SYNCPERIOREG, targ_info->sync_period_reg);
911         amd_write8(amd, SYNCOFFREG, targ_info->sync_offset_reg);
912         amd_write8(amd, CNTLREG1, targ_info->CtrlR1);
913         amd_write8(amd, CNTLREG3, targ_info->CtrlR3);
914         amd_write8(amd, CNTLREG4, targ_info->CtrlR4);
915         amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
916
917         identify_msg = MSG_IDENTIFYFLAG | lun;
918         if ((targ_info->disc_tag & AMD_CUR_DISCENB) != 0
919           && (pccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0
920           && (pSRB->CmdBlock[0] != REQUEST_SENSE)
921           && (pSRB->SRBFlag & AUTO_REQSENSE) == 0)
922                 identify_msg |= MSG_IDENTIFY_DISCFLAG;
923
924         amd_write8(amd, SCSIFIFOREG, identify_msg);
925         tagged = 0;
926         if ((targ_info->disc_tag & AMD_CUR_TAGENB) == 0
927           || (identify_msg & MSG_IDENTIFY_DISCFLAG) == 0)
928                 pccb->ccb_h.flags &= ~CAM_TAG_ACTION_VALID;
929         if (targ_info->current.period != targ_info->goal.period
930          || targ_info->current.offset != targ_info->goal.offset) {
931                 command = SEL_W_ATN_STOP;
932                 amdconstructsdtr(amd, targ_info->goal.period,
933                                  targ_info->goal.offset);
934         } else if ((pccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) {
935                 command = SEL_W_ATN2;
936                 pSRB->SRBState = SRB_START;
937                 amd_write8(amd, SCSIFIFOREG, pcsio->tag_action);
938                 amd_write8(amd, SCSIFIFOREG, pSRB->TagNumber);
939                 tagged++;
940         } else {
941                 command = SEL_W_ATN;
942                 pSRB->SRBState = SRB_START;
943         }
944         if (command != SEL_W_ATN_STOP)
945                 amdsetupcommand(amd, pSRB);
946
947         if (amd_read8(amd, SCSISTATREG) & INTERRUPT) {
948                 pSRB->SRBState = SRB_READY;
949                 return (1);
950         } else {
951                 amd->last_phase = SCSI_ARBITRATING;
952                 amd_write8(amd, SCSICMDREG, command);
953                 amd->active_srb = pSRB;
954                 amd->cur_target = target;
955                 amd->cur_lun = lun;
956                 return (0);
957         }
958 }
959
960 /*
961  *  Catch an interrupt from the adapter.
962  *  Process pending device interrupts.
963  */
964 static void 
965 amd_intr(void   *arg)
966 {
967         struct amd_softc *amd;
968         struct amd_srb *pSRB;
969         u_int  internstat = 0;
970         u_int  scsistat;
971         u_int  intstat;
972
973         amd = (struct amd_softc *)arg;
974
975         if (amd == NULL) {
976 #ifdef AMD_DEBUG0
977                 printf("amd_intr: amd NULL return......");
978 #endif
979                 return;
980         }
981
982         scsistat = amd_read8(amd, SCSISTATREG);
983         if (!(scsistat & INTERRUPT)) {
984 #ifdef AMD_DEBUG0
985                 printf("amd_intr: scsistat = NULL ,return......");
986 #endif
987                 return;
988         }
989 #ifdef AMD_DEBUG_SCSI_PHASE
990         printf("scsistat=%2x,", scsistat);
991 #endif
992
993         internstat = amd_read8(amd, INTERNSTATREG);
994         intstat = amd_read8(amd, INTSTATREG);
995
996 #ifdef AMD_DEBUG_SCSI_PHASE
997         printf("intstat=%2x,", intstat);
998 #endif
999
1000         if (intstat & DISCONNECTED) {
1001                 amd_Disconnect(amd);
1002                 return;
1003         }
1004         if (intstat & RESELECTED) {
1005                 amd_Reselect(amd);
1006                 return;
1007         }
1008         if (intstat & INVALID_CMD) {
1009                 amd_InvalidCmd(amd);
1010                 return;
1011         }
1012         if (intstat & SCSI_RESET_) {
1013                 amd_ScsiRstDetect(amd);
1014                 return;
1015         }
1016         if (intstat & (SUCCESSFUL_OP + SERVICE_REQUEST)) {
1017                 pSRB = amd->active_srb;
1018                 /*
1019                  * Run our state engine.  First perform
1020                  * post processing for the last phase we
1021                  * were in, followed by any processing
1022                  * required to handle the current phase.
1023                  */
1024                 scsistat =
1025                     amd_SCSI_phase0[amd->last_phase](amd, pSRB, scsistat);
1026                 amd->last_phase = scsistat & SCSI_PHASE_MASK;
1027                 (void)amd_SCSI_phase1[amd->last_phase](amd, pSRB, scsistat);
1028         }
1029 }
1030
1031 static u_int
1032 amd_DataOutPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1033 {
1034         struct amd_sg *psgl;
1035         u_int32_t   ResidCnt, xferCnt;
1036
1037         if (!(pSRB->SRBState & SRB_XFERPAD)) {
1038                 if (scsistat & PARITY_ERR) {
1039                         pSRB->SRBStatus |= PARITY_ERROR;
1040                 }
1041                 if (scsistat & COUNT_2_ZERO) {
1042                         while ((amd_read8(amd, DMA_Status)&DMA_XFER_DONE) == 0)
1043                                 ;
1044                         pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
1045                         pSRB->SGIndex++;
1046                         if (pSRB->SGIndex < pSRB->SGcount) {
1047                                 pSRB->pSGlist++;
1048                                 psgl = pSRB->pSGlist;
1049                                 pSRB->SGPhysAddr = psgl->SGXPtr;
1050                                 pSRB->SGToBeXferLen = psgl->SGXLen;
1051                         } else {
1052                                 pSRB->SGToBeXferLen = 0;
1053                         }
1054                 } else {
1055                         ResidCnt = amd_read8(amd, CURRENTFIFOREG) & 0x1f;
1056                         ResidCnt += amd_read8(amd, CTCREG_LOW)
1057                                   | (amd_read8(amd, CTCREG_MID) << 8)
1058                                   | (amd_read8(amd, CURTXTCNTREG) << 16);
1059
1060                         xferCnt = pSRB->SGToBeXferLen - ResidCnt;
1061                         pSRB->SGPhysAddr += xferCnt;
1062                         pSRB->TotalXferredLen += xferCnt;
1063                         pSRB->SGToBeXferLen = ResidCnt;
1064                 }
1065         }
1066         amd_write8(amd, DMA_Cmd, WRITE_DIRECTION | DMA_IDLE_CMD);
1067         return (scsistat);
1068 }
1069
1070 static u_int
1071 amd_DataInPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1072 {
1073         u_int8_t bval;
1074         u_int16_t  i, residual;
1075         struct amd_sg *psgl;
1076         u_int32_t   ResidCnt, xferCnt;
1077         u_int8_t *  ptr;
1078
1079         if (!(pSRB->SRBState & SRB_XFERPAD)) {
1080                 if (scsistat & PARITY_ERR) {
1081                         pSRB->SRBStatus |= PARITY_ERROR;
1082                 }
1083                 if (scsistat & COUNT_2_ZERO) {
1084                         while (1) {
1085                                 bval = amd_read8(amd, DMA_Status);
1086                                 if ((bval & DMA_XFER_DONE) != 0)
1087                                         break;
1088                         }
1089                         amd_write8(amd, DMA_Cmd, READ_DIRECTION|DMA_IDLE_CMD);
1090
1091                         pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
1092                         pSRB->SGIndex++;
1093                         if (pSRB->SGIndex < pSRB->SGcount) {
1094                                 pSRB->pSGlist++;
1095                                 psgl = pSRB->pSGlist;
1096                                 pSRB->SGPhysAddr = psgl->SGXPtr;
1097                                 pSRB->SGToBeXferLen = psgl->SGXLen;
1098                         } else {
1099                                 pSRB->SGToBeXferLen = 0;
1100                         }
1101                 } else {        /* phase changed */
1102                         residual = 0;
1103                         bval = amd_read8(amd, CURRENTFIFOREG);
1104                         while (bval & 0x1f) {
1105                                 if ((bval & 0x1f) == 1) {
1106                                         for (i = 0; i < 0x100; i++) {
1107                                                 bval = amd_read8(amd, CURRENTFIFOREG);
1108                                                 if (!(bval & 0x1f)) {
1109                                                         goto din_1;
1110                                                 } else if (i == 0x0ff) {
1111                                                         residual = 1;
1112                                                         goto din_1;
1113                                                 }
1114                                         }
1115                                 } else {
1116                                         bval = amd_read8(amd, CURRENTFIFOREG);
1117                                 }
1118                         }
1119         din_1:
1120                         amd_write8(amd, DMA_Cmd, READ_DIRECTION|DMA_BLAST_CMD);
1121                         for (i = 0; i < 0x8000; i++) {
1122                                 if ((amd_read8(amd, DMA_Status)&BLAST_COMPLETE))
1123                                         break;
1124                         }
1125                         amd_write8(amd, DMA_Cmd, READ_DIRECTION|DMA_IDLE_CMD);
1126
1127                         ResidCnt = amd_read8(amd, CTCREG_LOW)
1128                                  | (amd_read8(amd, CTCREG_MID) << 8)
1129                                  | (amd_read8(amd, CURTXTCNTREG) << 16);
1130                         xferCnt = pSRB->SGToBeXferLen - ResidCnt;
1131                         pSRB->SGPhysAddr += xferCnt;
1132                         pSRB->TotalXferredLen += xferCnt;
1133                         pSRB->SGToBeXferLen = ResidCnt;
1134                         if (residual) {
1135                                 /* get residual byte */ 
1136                                 bval = amd_read8(amd, SCSIFIFOREG);
1137                                 ptr = phystovirt(pSRB, xferCnt);
1138                                 *ptr = bval;
1139                                 pSRB->SGPhysAddr++;
1140                                 pSRB->TotalXferredLen++;
1141                                 pSRB->SGToBeXferLen--;
1142                         }
1143                 }
1144         }
1145         return (scsistat);
1146 }
1147
1148 static u_int
1149 amd_StatusPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1150 {
1151         pSRB->TargetStatus = amd_read8(amd, SCSIFIFOREG);
1152         /* get message */
1153         pSRB->EndMessage = amd_read8(amd, SCSIFIFOREG);
1154         pSRB->SRBState = SRB_COMPLETED;
1155         amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD);
1156         return (SCSI_NOP0);
1157 }
1158
1159 static u_int
1160 amd_MsgOutPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1161 {
1162         if (pSRB->SRBState & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT)) {
1163                 scsistat = SCSI_NOP0;
1164         }
1165         return (scsistat);
1166 }
1167
1168 static u_int
1169 amd_MsgInPhase0(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1170 {
1171         int done;
1172         
1173         amd->msgin_buf[amd->msgin_index]  = amd_read8(amd, SCSIFIFOREG);
1174
1175         done = amdparsemsg(amd);
1176         if (done)
1177                 amd->msgin_index = 0;
1178         else 
1179                 amd->msgin_index++;
1180         return (SCSI_NOP0);
1181 }
1182
1183 static int
1184 amdparsemsg(struct amd_softc *amd)
1185 {
1186         struct  amd_target_info *targ_info;
1187         int     reject;
1188         int     done;
1189         int     response;
1190
1191         done = FALSE;
1192         response = FALSE;
1193         reject = FALSE;
1194
1195         targ_info = &amd->tinfo[amd->cur_target];
1196
1197         /*
1198          * Parse as much of the message as is availible,
1199          * rejecting it if we don't support it.  When
1200          * the entire message is availible and has been
1201          * handled, return TRUE indicating that we have
1202          * parsed an entire message.
1203          */
1204         switch (amd->msgin_buf[0]) {
1205         case MSG_DISCONNECT:
1206                 amd->active_srb->SRBState = SRB_DISCONNECT;
1207                 amd->disc_count[amd->cur_target][amd->cur_lun]++;
1208                 done = TRUE;
1209                 break;
1210         case MSG_SIMPLE_Q_TAG:
1211         {
1212                 struct amd_srb *disc_srb;
1213
1214                 if (amd->msgin_index < 1)
1215                         break;          
1216                 disc_srb = &amd->SRB_array[amd->msgin_buf[1]];
1217                 if (amd->active_srb != NULL
1218                  || disc_srb->SRBState != SRB_DISCONNECT
1219                  || disc_srb->pccb->ccb_h.target_id != amd->cur_target
1220                  || disc_srb->pccb->ccb_h.target_lun != amd->cur_lun) {
1221                         printf("amd%d: Unexpected tagged reselection "
1222                                "for target %d, Issuing Abort\n", amd->unit,
1223                                amd->cur_target);
1224                         amd->msgout_buf[0] = MSG_ABORT;
1225                         amd->msgout_len = 1;
1226                         response = TRUE;
1227                         break;
1228                 }
1229                 amd->active_srb = disc_srb;
1230                 amd->disc_count[amd->cur_target][amd->cur_lun]--;
1231                 done = TRUE;
1232                 break;
1233         }
1234         case MSG_MESSAGE_REJECT:
1235                 response = amdhandlemsgreject(amd);
1236                 if (response == FALSE)
1237                         amd_write8(amd, SCSICMDREG, RESET_ATN_CMD);
1238                 /* FALLTHROUGH */
1239         case MSG_NOOP:
1240                 done = TRUE;
1241                 break;
1242         case MSG_EXTENDED:
1243         {
1244                 u_int clockrate;
1245                 u_int period;
1246                 u_int offset;
1247                 u_int saved_offset;
1248
1249                 /* Wait for enough of the message to begin validation */
1250                 if (amd->msgin_index < 1)
1251                         break;
1252                 if (amd->msgin_buf[1] != MSG_EXT_SDTR_LEN) {
1253                         reject = TRUE;
1254                         break;
1255                 }
1256
1257                 /* Wait for opcode */
1258                 if (amd->msgin_index < 2)
1259                         break;
1260
1261                 if (amd->msgin_buf[2] != MSG_EXT_SDTR) {
1262                         reject = TRUE;
1263                         break;
1264                 }
1265
1266                 /*
1267                  * Wait until we have both args before validating
1268                  * and acting on this message.
1269                  *
1270                  * Add one to MSG_EXT_SDTR_LEN to account for
1271                  * the extended message preamble.
1272                  */
1273                 if (amd->msgin_index < (MSG_EXT_SDTR_LEN + 1))
1274                         break;
1275
1276                 period = amd->msgin_buf[3];
1277                 saved_offset = offset = amd->msgin_buf[4];
1278                 clockrate = amdfindclockrate(amd, &period);
1279                 if (offset > AMD_MAX_SYNC_OFFSET)
1280                         offset = AMD_MAX_SYNC_OFFSET;
1281                 if (period == 0 || offset == 0) {
1282                         offset = 0;
1283                         period = 0;
1284                         clockrate = 0;
1285                 }
1286                 amdsetsync(amd, amd->cur_target, clockrate, period, offset,
1287                            AMD_TRANS_ACTIVE|AMD_TRANS_GOAL);
1288
1289                 /*
1290                  * See if we initiated Sync Negotiation
1291                  * and didn't have to fall down to async
1292                  * transfers.
1293                  */
1294                 if (amdsentmsg(amd, MSG_EXT_SDTR, /*full*/TRUE)) {
1295                         /* We started it */
1296                         if (saved_offset != offset) {
1297                                 /* Went too low - force async */
1298                                 reject = TRUE;
1299                         }
1300                 } else {
1301                         /*
1302                          * Send our own SDTR in reply
1303                          */
1304                         if (bootverbose)
1305                                 printf("Sending SDTR!\n");
1306                         amd->msgout_index = 0;
1307                         amd->msgout_len = 0;
1308                         amdconstructsdtr(amd, period, offset);
1309                         amd->msgout_index = 0;
1310                         response = TRUE;
1311                 }
1312                 done = TRUE;
1313                 break;
1314         }
1315         case MSG_SAVEDATAPOINTER:
1316         case MSG_RESTOREPOINTERS:
1317                 /* XXX Implement!!! */
1318                 done = TRUE;
1319                 break;
1320         default:
1321                 reject = TRUE;
1322                 break;
1323         }
1324
1325         if (reject) {
1326                 amd->msgout_index = 0;
1327                 amd->msgout_len = 1;
1328                 amd->msgout_buf[0] = MSG_MESSAGE_REJECT;
1329                 done = TRUE;
1330                 response = TRUE;
1331         }
1332
1333         if (response)
1334                 amd_write8(amd, SCSICMDREG, SET_ATN_CMD);
1335
1336         if (done && !response)
1337                 /* Clear the outgoing message buffer */
1338                 amd->msgout_len = 0;
1339
1340         /* Drop Ack */
1341         amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD);
1342
1343         return (done);
1344 }
1345
1346 static u_int
1347 amdfindclockrate(struct amd_softc *amd, u_int *period)
1348 {
1349         u_int i;
1350         u_int clockrate;
1351
1352         for (i = 0; i < sizeof(tinfo_sync_period); i++) {
1353                 u_int8_t *table_entry;
1354
1355                 table_entry = &tinfo_sync_period[i];
1356                 if (*period <= *table_entry) {
1357                         /*
1358                          * When responding to a target that requests
1359                          * sync, the requested rate may fall between
1360                          * two rates that we can output, but still be
1361                          * a rate that we can receive.  Because of this,
1362                          * we want to respond to the target with
1363                          * the same rate that it sent to us even
1364                          * if the period we use to send data to it
1365                          * is lower.  Only lower the response period
1366                          * if we must.
1367                          */ 
1368                         if (i == 0) {
1369                                 *period = *table_entry;
1370                         }
1371                         break;
1372                 }
1373         }
1374
1375         if (i == sizeof(tinfo_sync_period)) {
1376                 /* Too slow for us.  Use asnyc transfers. */
1377                 *period = 0;
1378                 clockrate = 0;
1379         } else
1380                 clockrate = i + 4;
1381
1382         return (clockrate);
1383 }
1384
1385 /*
1386  * See if we sent a particular extended message to the target.
1387  * If "full" is true, the target saw the full message.
1388  * If "full" is false, the target saw at least the first
1389  * byte of the message.
1390  */
1391 static int
1392 amdsentmsg(struct amd_softc *amd, u_int msgtype, int full)
1393 {
1394         int found;
1395         int index;
1396
1397         found = FALSE;
1398         index = 0;
1399
1400         while (index < amd->msgout_len) {
1401                 if ((amd->msgout_buf[index] & MSG_IDENTIFYFLAG) != 0
1402                  || amd->msgout_buf[index] == MSG_MESSAGE_REJECT)
1403                         index++;
1404                 else if (amd->msgout_buf[index] >= MSG_SIMPLE_Q_TAG
1405                       && amd->msgout_buf[index] < MSG_IGN_WIDE_RESIDUE) {
1406                         /* Skip tag type and tag id */
1407                         index += 2;
1408                 } else if (amd->msgout_buf[index] == MSG_EXTENDED) {
1409                         /* Found a candidate */
1410                         if (amd->msgout_buf[index+2] == msgtype) {
1411                                 u_int end_index;
1412
1413                                 end_index = index + 1
1414                                           + amd->msgout_buf[index + 1];
1415                                 if (full) {
1416                                         if (amd->msgout_index > end_index)
1417                                                 found = TRUE;
1418                                 } else if (amd->msgout_index > index)
1419                                         found = TRUE;
1420                         }
1421                         break;
1422                 } else {
1423                         panic("amdsentmsg: Inconsistent msg buffer");
1424                 }
1425         }
1426         return (found);
1427 }
1428
1429 static void
1430 amdconstructsdtr(struct amd_softc *amd, u_int period, u_int offset)
1431 {
1432         amd->msgout_buf[amd->msgout_index++] = MSG_EXTENDED;
1433         amd->msgout_buf[amd->msgout_index++] = MSG_EXT_SDTR_LEN;
1434         amd->msgout_buf[amd->msgout_index++] = MSG_EXT_SDTR;
1435         amd->msgout_buf[amd->msgout_index++] = period;
1436         amd->msgout_buf[amd->msgout_index++] = offset;
1437         amd->msgout_len += 5;
1438 }
1439
1440 static int
1441 amdhandlemsgreject(struct amd_softc *amd)
1442 {
1443         /*
1444          * If we had an outstanding SDTR for this
1445          * target, this is a signal that the target
1446          * is refusing negotiation.  Also watch out
1447          * for rejected tag messages.
1448          */
1449         struct  amd_srb *srb;
1450         struct  amd_target_info *targ_info;
1451         int     response = FALSE;
1452
1453         srb = amd->active_srb;
1454         targ_info = &amd->tinfo[amd->cur_target];
1455         if (amdsentmsg(amd, MSG_EXT_SDTR, /*full*/FALSE)) {
1456                 /* note asynch xfers and clear flag */
1457                 amdsetsync(amd, amd->cur_target, /*clockrate*/0,
1458                            /*period*/0, /*offset*/0,
1459                            AMD_TRANS_ACTIVE|AMD_TRANS_GOAL);
1460                 printf("amd%d:%d: refuses synchronous negotiation. "
1461                        "Using asynchronous transfers\n",
1462                        amd->unit, amd->cur_target);
1463         } else if ((srb != NULL)
1464                 && (srb->pccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) {
1465                 struct  ccb_trans_settings neg;
1466
1467                 printf("amd%d:%d: refuses tagged commands.  Performing "
1468                        "non-tagged I/O\n", amd->unit, amd->cur_target);
1469
1470                 amdsettags(amd, amd->cur_target, FALSE);
1471                 neg.flags = 0;
1472                 neg.valid = CCB_TRANS_TQ_VALID;
1473                 xpt_setup_ccb(&neg.ccb_h, srb->pccb->ccb_h.path, /*priority*/1);
1474                 xpt_async(AC_TRANSFER_NEG, srb->pccb->ccb_h.path, &neg);
1475
1476                 /*
1477                  * Resend the identify for this CCB as the target
1478                  * may believe that the selection is invalid otherwise.
1479                  */
1480                 if (amd->msgout_len != 0)
1481                         bcopy(&amd->msgout_buf[0], &amd->msgout_buf[1],
1482                               amd->msgout_len);
1483                 amd->msgout_buf[0] = MSG_IDENTIFYFLAG
1484                                     | srb->pccb->ccb_h.target_lun;
1485                 amd->msgout_len++;
1486                 if ((targ_info->disc_tag & AMD_CUR_DISCENB) != 0
1487                   && (srb->pccb->ccb_h.flags & CAM_DIS_DISCONNECT) == 0)
1488                         amd->msgout_buf[0] |= MSG_IDENTIFY_DISCFLAG;
1489
1490                 srb->pccb->ccb_h.flags &= ~CAM_TAG_ACTION_VALID;
1491
1492                 /*
1493                  * Requeue all tagged commands for this target
1494                  * currently in our posession so they can be
1495                  * converted to untagged commands.
1496                  */
1497                 amdcompletematch(amd, amd->cur_target, amd->cur_lun,
1498                                  AMD_TAG_WILDCARD, &amd->waiting_srbs,
1499                                  CAM_DEV_QFRZN|CAM_REQUEUE_REQ);
1500         } else {
1501                 /*
1502                  * Otherwise, we ignore it.
1503                  */
1504                 printf("amd%d:%d: Message reject received -- ignored\n",
1505                        amd->unit, amd->cur_target);
1506         }
1507         return (response);
1508 }
1509
1510 #if 0
1511         if (!(pSRB->SRBState & SRB_MSGIN_MULTI)) {
1512                 if (bval == MSG_DISCONNECT) {
1513                         pSRB->SRBState = SRB_DISCONNECT;
1514                 } else if (bval == MSG_SAVEDATAPOINTER) {
1515                         goto min6;
1516                 } else if ((bval == MSG_EXTENDED)
1517                         || ((bval >= MSG_SIMPLE_Q_TAG)
1518                          && (bval <= MSG_ORDERED_Q_TAG))) {
1519                         pSRB->SRBState |= SRB_MSGIN_MULTI;
1520                         pSRB->MsgInBuf[0] = bval;
1521                         pSRB->MsgCnt = 1;
1522                         pSRB->pMsgPtr = &pSRB->MsgInBuf[1];
1523                 } else if (bval == MSG_MESSAGE_REJECT) {
1524                         amd_write8(amd, SCSICMDREG, RESET_ATN_CMD);
1525
1526                         if (pSRB->SRBState & DO_SYNC_NEGO) {
1527                                 goto set_async;
1528                         }
1529                 } else if (bval == MSG_RESTOREPOINTERS) {
1530                         goto min6;
1531                 } else {
1532                         goto min6;
1533                 }
1534         } else {                /* minx: */
1535                 *pSRB->pMsgPtr = bval;
1536                 pSRB->MsgCnt++;
1537                 pSRB->pMsgPtr++;
1538                 if ((pSRB->MsgInBuf[0] >= MSG_SIMPLE_Q_TAG)
1539                  && (pSRB->MsgInBuf[0] <= MSG_ORDERED_Q_TAG)) {
1540                         if (pSRB->MsgCnt == 2) {
1541                                 pSRB->SRBState = 0;
1542                                 pSRB = &amd->SRB_array[pSRB->MsgInBuf[1]];
1543                                 if (pSRB->SRBState & SRB_DISCONNECT) == 0) {
1544                                         pSRB = amd->pTmpSRB;
1545                                         pSRB->SRBState = SRB_UNEXPECT_RESEL;
1546                                         pDCB->pActiveSRB = pSRB;
1547                                         pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;
1548                                         EnableMsgOut2(amd, pSRB);
1549                                 } else {
1550                                         if (pDCB->DCBFlag & ABORT_DEV_) {
1551                                                 pSRB->SRBState = SRB_ABORT_SENT;
1552                                                 EnableMsgOut1(amd, pSRB);
1553                                         }
1554                                         pDCB->pActiveSRB = pSRB;
1555                                         pSRB->SRBState = SRB_DATA_XFER;
1556                                 }
1557                         }
1558                 } else if ((pSRB->MsgInBuf[0] == MSG_EXTENDED)
1559                         && (pSRB->MsgCnt == 5)) {
1560                         pSRB->SRBState &= ~(SRB_MSGIN_MULTI + DO_SYNC_NEGO);
1561                         if ((pSRB->MsgInBuf[1] != 3)
1562                          || (pSRB->MsgInBuf[2] != 1)) { /* reject_msg: */
1563                                 pSRB->MsgCnt = 1;
1564                                 pSRB->MsgInBuf[0] = MSG_MESSAGE_REJECT;
1565                                 amd_write8(amd, SCSICMDREG, SET_ATN_CMD);
1566                         } else if (!(pSRB->MsgInBuf[3])
1567                                 || !(pSRB->MsgInBuf[4])) {
1568                 set_async:      /* set async */
1569
1570                                 pDCB = pSRB->pSRBDCB;
1571                                 /* disable sync & sync nego */
1572                                 pDCB->SyncMode &= ~(SYNC_ENABLE|SYNC_NEGO_DONE);
1573                                 pDCB->SyncPeriod = 0;
1574                                 pDCB->SyncOffset = 0;
1575
1576                                 pDCB->tinfo.goal.period = 0;
1577                                 pDCB->tinfo.goal.offset = 0;
1578
1579                                 pDCB->tinfo.current.period = 0;
1580                                 pDCB->tinfo.current.offset = 0;
1581                                 pDCB->tinfo.current.width =
1582                                     MSG_EXT_WDTR_BUS_8_BIT;
1583
1584                                 pDCB->CtrlR3 = FAST_CLK; /* non_fast */
1585                                 pDCB->CtrlR4 &= 0x3f;
1586                                 pDCB->CtrlR4 |= EATER_25NS; 
1587                                 goto re_prog;
1588                         } else {/* set sync */
1589
1590                                 pDCB = pSRB->pSRBDCB;
1591                                 /* enable sync & sync nego */
1592                                 pDCB->SyncMode |= SYNC_ENABLE|SYNC_NEGO_DONE;
1593
1594                                 /* set sync offset */
1595                                 pDCB->SyncOffset &= 0x0f0;
1596                                 pDCB->SyncOffset |= pSRB->MsgInBuf[4];
1597
1598                                 /* set sync period */
1599                                 pDCB->MaxNegoPeriod = pSRB->MsgInBuf[3];
1600
1601                                 wval = (u_int16_t) pSRB->MsgInBuf[3];
1602                                 wval = wval << 2;
1603                                 wval--;
1604                                 wval1 = wval / 25;
1605                                 if ((wval1 * 25) != wval) {
1606                                         wval1++;
1607                                 }
1608                                 bval = FAST_CLK|FAST_SCSI;
1609                                 pDCB->CtrlR4 &= 0x3f;
1610                                 if (wval1 >= 8) {
1611                                         /* Fast SCSI */
1612                                         wval1--;
1613                                         bval = FAST_CLK;
1614                                         pDCB->CtrlR4 |= EATER_25NS;
1615                                 }
1616                                 pDCB->CtrlR3 = bval;
1617                                 pDCB->SyncPeriod = (u_int8_t) wval1;
1618
1619                                 pDCB->tinfo.goal.period =
1620                                     tinfo_sync_period[pDCB->SyncPeriod - 4];
1621                                 pDCB->tinfo.goal.offset = pDCB->SyncOffset;
1622                                 pDCB->tinfo.current.period =
1623                                     tinfo_sync_period[pDCB->SyncPeriod - 4];;
1624                                 pDCB->tinfo.current.offset = pDCB->SyncOffset;
1625
1626                                 /*
1627                                  * program SCSI control register
1628                                  */
1629                 re_prog:
1630                                 amd_write8(amd, SYNCPERIOREG, pDCB->SyncPeriod);
1631                                 amd_write8(amd, SYNCOFFREG, pDCB->SyncOffset);
1632                                 amd_write8(amd, CNTLREG3, pDCB->CtrlR3);
1633                                 amd_write8(amd, CNTLREG4, pDCB->CtrlR4);
1634                         }
1635                 }
1636         }
1637 min6:
1638         amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD);
1639         return (SCSI_NOP0);
1640 }
1641 #endif
1642
1643 static u_int
1644 amd_DataOutPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1645 {
1646         DataIO_Comm(amd, pSRB, WRITE_DIRECTION);
1647         return (scsistat);
1648 }
1649
1650 static u_int 
1651 amd_DataInPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1652 {
1653         DataIO_Comm(amd, pSRB, READ_DIRECTION);
1654         return (scsistat);
1655 }
1656
1657 static void
1658 DataIO_Comm(struct amd_softc *amd, struct amd_srb *pSRB, u_int ioDir)
1659 {
1660         struct amd_sg *    psgl;
1661         u_int32_t   lval;
1662
1663         if (pSRB->SGIndex < pSRB->SGcount) {
1664                 amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD|ioDir);/* |EN_DMA_INT */
1665
1666                 if (!pSRB->SGToBeXferLen) {
1667                         psgl = pSRB->pSGlist;
1668                         pSRB->SGPhysAddr = psgl->SGXPtr;
1669                         pSRB->SGToBeXferLen = psgl->SGXLen;
1670                 }
1671                 lval = pSRB->SGToBeXferLen;
1672                 amd_write8(amd, CTCREG_LOW, lval);
1673                 amd_write8(amd, CTCREG_MID, lval >> 8);
1674                 amd_write8(amd, CURTXTCNTREG, lval >> 16);
1675
1676                 amd_write32(amd, DMA_XferCnt, pSRB->SGToBeXferLen);
1677
1678                 amd_write32(amd, DMA_XferAddr, pSRB->SGPhysAddr);
1679
1680                 pSRB->SRBState = SRB_DATA_XFER;
1681
1682                 amd_write8(amd, SCSICMDREG, DMA_COMMAND|INFO_XFER_CMD);
1683
1684                 amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD|ioDir); /* |EN_DMA_INT */
1685
1686                 amd_write8(amd, DMA_Cmd, DMA_START_CMD|ioDir);/* |EN_DMA_INT */
1687         } else {                /* xfer pad */
1688                 if (pSRB->SGcount) {
1689                         pSRB->AdaptStatus = H_OVER_UNDER_RUN;
1690                         pSRB->SRBStatus |= OVER_RUN;
1691                 }
1692                 amd_write8(amd, CTCREG_LOW, 0);
1693                 amd_write8(amd, CTCREG_MID, 0);
1694                 amd_write8(amd, CURTXTCNTREG, 0);
1695
1696                 pSRB->SRBState |= SRB_XFERPAD;
1697                 amd_write8(amd, SCSICMDREG, DMA_COMMAND|XFER_PAD_BYTE);
1698         }
1699 }
1700
1701 static u_int
1702 amd_CommandPhase1(struct amd_softc *amd, struct amd_srb *srb, u_int scsistat)
1703 {
1704         amd_write8(amd, SCSICMDREG, RESET_ATN_CMD);
1705         amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
1706
1707         amdsetupcommand(amd, srb);
1708
1709         srb->SRBState = SRB_COMMAND;
1710         amd_write8(amd, SCSICMDREG, INFO_XFER_CMD);
1711         return (scsistat);
1712 }
1713
1714 static u_int
1715 amd_StatusPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1716 {
1717         amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
1718         pSRB->SRBState = SRB_STATUS;
1719         amd_write8(amd, SCSICMDREG, INITIATOR_CMD_CMPLTE);
1720         return (scsistat);
1721 }
1722
1723 static u_int
1724 amd_MsgOutPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1725 {
1726         amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
1727
1728         if (amd->msgout_len == 0) {
1729                 amd->msgout_buf[0] = MSG_NOOP;
1730                 amd->msgout_len = 1;
1731         }
1732         amd_write8_multi(amd, SCSIFIFOREG, amd->msgout_buf, amd->msgout_len);
1733         amd_write8(amd, SCSICMDREG, INFO_XFER_CMD);
1734         return (scsistat);
1735 }
1736
1737 static u_int
1738 amd_MsgInPhase1(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1739 {
1740         amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
1741         amd_write8(amd, SCSICMDREG, INFO_XFER_CMD);
1742         return (scsistat);
1743 }
1744
1745 static u_int
1746 amd_NopPhase(struct amd_softc *amd, struct amd_srb *pSRB, u_int scsistat)
1747 {
1748         return (scsistat);
1749 }
1750
1751 static void
1752 amd_Disconnect(struct amd_softc * amd)
1753 {
1754         struct  amd_srb *srb;
1755         int     target;
1756         int     lun;
1757
1758         srb = amd->active_srb;
1759         amd->active_srb = NULL;
1760         amd->last_phase = SCSI_BUS_FREE;
1761         amd_write8(amd, SCSICMDREG, EN_SEL_RESEL);
1762         target = amd->cur_target;
1763         lun = amd->cur_lun;
1764
1765         if (srb == NULL) {
1766                 /* Invalid reselection */
1767                 amdrunwaiting(amd);
1768         } else if (srb->SRBState & SRB_ABORT_SENT) {
1769                 /* Clean up and done this srb */
1770 #if 0
1771                 while (( = TAILQ_FIRST(&amd->running_srbs)) != NULL) {
1772                         /* XXX What about "done'ing" these srbs??? */
1773                         if (pSRB->pSRBDCB == pDCB) {
1774                                 TAILQ_REMOVE(&amd->running_srbs, pSRB, links);
1775                                 TAILQ_INSERT_HEAD(&amd->free_srbs, pSRB, links);
1776                         }
1777                 }
1778                 amdrunwaiting(amd);
1779 #endif
1780         } else {
1781                 if ((srb->SRBState & (SRB_START | SRB_MSGOUT))
1782                  || !(srb->SRBState & (SRB_DISCONNECT | SRB_COMPLETED))) {
1783                         srb->TargetStatus = AMD_SCSI_STAT_SEL_TIMEOUT;
1784                         goto disc1;
1785                 } else if (srb->SRBState & SRB_DISCONNECT) {
1786                         if (!(srb->pccb->ccb_h.flags & CAM_TAG_ACTION_VALID))
1787                                 amd->untagged_srbs[target][lun] = srb;
1788                         amdrunwaiting(amd);
1789                 } else if (srb->SRBState & SRB_COMPLETED) {
1790         disc1:
1791                         srb->SRBState = SRB_FREE;
1792                         SRBdone(amd, srb);
1793                 }
1794         }
1795         return;
1796 }
1797
1798 static void
1799 amd_Reselect(struct amd_softc *amd)
1800 {
1801         struct amd_target_info *tinfo;
1802         u_int16_t disc_count;
1803
1804         amd_clear_msg_state(amd);
1805         if (amd->active_srb != NULL) {
1806                 /* Requeue the SRB for our attempted Selection */
1807                 TAILQ_REMOVE(&amd->running_srbs, amd->active_srb, links);
1808                 TAILQ_INSERT_HEAD(&amd->waiting_srbs, amd->active_srb, links);
1809                 amd->active_srb = NULL;
1810         }
1811         /* get ID */
1812         amd->cur_target = amd_read8(amd, SCSIFIFOREG);
1813         amd->cur_target ^= amd->HostID_Bit;
1814         amd->cur_target = ffs(amd->cur_target) - 1;
1815         amd->cur_lun = amd_read8(amd, SCSIFIFOREG) & 7;
1816         tinfo = &amd->tinfo[amd->cur_target];
1817         amd->active_srb = amd->untagged_srbs[amd->cur_target][amd->cur_lun];
1818         disc_count = amd->disc_count[amd->cur_target][amd->cur_lun];
1819         if (disc_count == 0) {
1820                 printf("amd%d: Unexpected reselection for target %d, "
1821                        "Issuing Abort\n", amd->unit, amd->cur_target);
1822                 amd->msgout_buf[0] = MSG_ABORT;
1823                 amd->msgout_len = 1;
1824                 amd_write8(amd, SCSICMDREG, SET_ATN_CMD);
1825         }
1826         if (amd->active_srb != NULL) {
1827                 amd->disc_count[amd->cur_target][amd->cur_lun]--;
1828                 amd->untagged_srbs[amd->cur_target][amd->cur_lun] = NULL;
1829         }
1830         
1831         amd_write8(amd, SCSIDESTIDREG, amd->cur_target);
1832         amd_write8(amd, SYNCPERIOREG, tinfo->sync_period_reg);
1833         amd_write8(amd, SYNCOFFREG, tinfo->sync_offset_reg);
1834         amd_write8(amd, CNTLREG1, tinfo->CtrlR1);
1835         amd_write8(amd, CNTLREG3, tinfo->CtrlR3);
1836         amd_write8(amd, CNTLREG4, tinfo->CtrlR4);
1837         amd_write8(amd, SCSICMDREG, MSG_ACCEPTED_CMD);/* drop /ACK */
1838         amd->last_phase = SCSI_NOP0;
1839 }
1840
1841 static void
1842 SRBdone(struct amd_softc *amd, struct amd_srb *pSRB)
1843 {
1844         u_int8_t   bval, i, status;
1845         union ccb *pccb;
1846         struct ccb_scsiio *pcsio;
1847         int        intflag;
1848         struct amd_sg *ptr2;
1849         u_int32_t   swlval;
1850         u_int   target_id, target_lun;
1851
1852         pccb = pSRB->pccb;
1853         pcsio = &pccb->csio;
1854         target_id = pSRB->pccb->ccb_h.target_id;
1855         target_lun = pSRB->pccb->ccb_h.target_lun;
1856
1857         CAM_DEBUG(pccb->ccb_h.path, CAM_DEBUG_TRACE,
1858                   ("SRBdone - TagNumber %d\n", pSRB->TagNumber));
1859
1860         if ((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
1861                 bus_dmasync_op_t op;
1862
1863                 if ((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
1864                         op = BUS_DMASYNC_POSTREAD;
1865                 else
1866                         op = BUS_DMASYNC_POSTWRITE;
1867                 bus_dmamap_sync(amd->buffer_dmat, pSRB->dmamap, op);
1868                 bus_dmamap_unload(amd->buffer_dmat, pSRB->dmamap);
1869         }
1870
1871         status = pSRB->TargetStatus;
1872         pccb->ccb_h.status = CAM_REQ_CMP;
1873         pccb->ccb_h.status = CAM_REQ_CMP;
1874         if (pSRB->SRBFlag & AUTO_REQSENSE) {
1875                 pSRB->SRBFlag &= ~AUTO_REQSENSE;
1876                 pSRB->AdaptStatus = 0;
1877                 pSRB->TargetStatus = SCSI_STATUS_CHECK_COND;
1878
1879                 if (status == SCSI_STATUS_CHECK_COND) {
1880                         pccb->ccb_h.status = CAM_SEL_TIMEOUT;
1881                         goto ckc_e;
1882                 }
1883                 *((u_int32_t *)&(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
1884
1885                 pcsio->sense_resid = pcsio->sense_len
1886                                    - pSRB->TotalXferredLen;
1887                 pSRB->TotalXferredLen = pSRB->Segment1[1];
1888                 if (pSRB->TotalXferredLen) {
1889                         /* ???? */
1890                         pcsio->resid = pcsio->dxfer_len
1891                                      - pSRB->TotalXferredLen;
1892                         /* The resid field contains valid data   */
1893                         /* Flush resid bytes on complete        */
1894                 } else {
1895                         pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
1896                 }
1897                 pccb->ccb_h.status = CAM_AUTOSNS_VALID|CAM_SCSI_STATUS_ERROR;
1898                 goto ckc_e;
1899         }
1900         if (status) {
1901                 if (status == SCSI_STATUS_CHECK_COND) {
1902
1903                         if ((pSRB->SGIndex < pSRB->SGcount)
1904                          && (pSRB->SGcount) && (pSRB->SGToBeXferLen)) {
1905                                 bval = pSRB->SGcount;
1906                                 swlval = pSRB->SGToBeXferLen;
1907                                 ptr2 = pSRB->pSGlist;
1908                                 ptr2++;
1909                                 for (i = pSRB->SGIndex + 1; i < bval; i++) {
1910                                         swlval += ptr2->SGXLen;
1911                                         ptr2++;
1912                                 }
1913                                 /* ??????? */
1914                                 pcsio->resid = (u_int32_t) swlval;
1915
1916 #ifdef  AMD_DEBUG0
1917                                 printf("XferredLen=%8x,NotYetXferLen=%8x,",
1918                                         pSRB->TotalXferredLen, swlval);
1919 #endif
1920                         }
1921                         if ((pcsio->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) {
1922 #ifdef  AMD_DEBUG0
1923                                 printf("RequestSense..................\n");
1924 #endif
1925                                 RequestSense(amd, pSRB);
1926                                 return;
1927                         }
1928                         pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
1929                         pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
1930                         goto ckc_e;
1931                 } else if (status == SCSI_STATUS_QUEUE_FULL) {
1932                         pSRB->AdaptStatus = 0;
1933                         pSRB->TargetStatus = 0;
1934                         pcsio->scsi_status = SCSI_STATUS_QUEUE_FULL;
1935                         pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
1936                         goto ckc_e;
1937                 } else if (status == AMD_SCSI_STAT_SEL_TIMEOUT) {
1938                         pSRB->AdaptStatus = H_SEL_TIMEOUT;
1939                         pSRB->TargetStatus = 0;
1940
1941                         pcsio->scsi_status = AMD_SCSI_STAT_SEL_TIMEOUT;
1942                         pccb->ccb_h.status = CAM_SEL_TIMEOUT;
1943                 } else if (status == SCSI_STATUS_BUSY) {
1944 #ifdef AMD_DEBUG0
1945                         printf("DC390: target busy at %s %d\n",
1946                                __FILE__, __LINE__);
1947 #endif
1948                         pcsio->scsi_status = SCSI_STATUS_BUSY;
1949                         pccb->ccb_h.status = CAM_SCSI_BUSY;
1950                 } else if (status == SCSI_STATUS_RESERV_CONFLICT) {
1951 #ifdef AMD_DEBUG0
1952                         printf("DC390: target reserved at %s %d\n",
1953                                __FILE__, __LINE__);
1954 #endif
1955                         pcsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT;
1956                         pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; /* XXX */
1957                 } else {
1958                         pSRB->AdaptStatus = 0;
1959 #ifdef AMD_DEBUG0
1960                         printf("DC390: driver stuffup at %s %d\n",
1961                                __FILE__, __LINE__);
1962 #endif
1963                         pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
1964                 }
1965         } else {
1966                 status = pSRB->AdaptStatus;
1967                 if (status & H_OVER_UNDER_RUN) {
1968                         pSRB->TargetStatus = 0;
1969
1970                         pccb->ccb_h.status = CAM_DATA_RUN_ERR;  
1971                 } else if (pSRB->SRBStatus & PARITY_ERROR) {
1972 #ifdef AMD_DEBUG0
1973                         printf("DC390: driver stuffup %s %d\n",
1974                                __FILE__, __LINE__);
1975 #endif
1976                         /* Driver failed to perform operation     */
1977                         pccb->ccb_h.status = CAM_UNCOR_PARITY;
1978                 } else {        /* No error */
1979                         pSRB->AdaptStatus = 0;
1980                         pSRB->TargetStatus = 0;
1981                         pcsio->resid = 0;
1982                         /* there is no error, (sense is invalid)  */
1983                 }
1984         }
1985 ckc_e:
1986         intflag = splcam();
1987         if ((pccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1988                 /* CAM request not yet complete =>device_Q frozen */
1989                 xpt_freeze_devq(pccb->ccb_h.path, 1);
1990                 pccb->ccb_h.status |= CAM_DEV_QFRZN;
1991         }
1992         TAILQ_REMOVE(&amd->running_srbs, pSRB, links);
1993         TAILQ_INSERT_HEAD(&amd->free_srbs, pSRB, links);
1994         amdrunwaiting(amd);
1995         splx(intflag);
1996         xpt_done(pccb);
1997
1998 }
1999
2000 static void
2001 amd_ResetSCSIBus(struct amd_softc * amd)
2002 {
2003         int     intflag;
2004
2005         intflag = splcam();
2006         amd->ACBFlag |= RESET_DEV;
2007         amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD);
2008         amd_write8(amd, SCSICMDREG, RST_SCSI_BUS_CMD);
2009         splx(intflag);
2010         return;
2011 }
2012
2013 static void
2014 amd_ScsiRstDetect(struct amd_softc * amd)
2015 {
2016         int     intflag;
2017         u_int32_t   wlval;
2018
2019 #ifdef AMD_DEBUG0
2020         printf("amd_ScsiRstDetect \n");
2021 #endif
2022
2023         wlval = 1000;
2024         while (--wlval) {       /* delay 1 sec */
2025                 DELAY(1000);
2026         }
2027         intflag = splcam();
2028
2029         amd_write8(amd, DMA_Cmd, DMA_IDLE_CMD);
2030         amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
2031
2032         if (amd->ACBFlag & RESET_DEV) {
2033                 amd->ACBFlag |= RESET_DONE;
2034         } else {
2035                 amd->ACBFlag |= RESET_DETECT;
2036                 ResetDevParam(amd);
2037                 amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD,
2038                                  AMD_TAG_WILDCARD, &amd->running_srbs,
2039                                  CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET);
2040                 amdcompletematch(amd, CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD,
2041                                  AMD_TAG_WILDCARD, &amd->waiting_srbs,
2042                                  CAM_DEV_QFRZN|CAM_SCSI_BUS_RESET);
2043                 amd->active_srb = NULL;
2044                 amd->ACBFlag = 0;
2045                 amdrunwaiting(amd);
2046         }
2047         splx(intflag);
2048         return;
2049 }
2050
2051 static void
2052 RequestSense(struct amd_softc *amd, struct amd_srb *pSRB)
2053 {
2054         union ccb *pccb;
2055         struct ccb_scsiio *pcsio;
2056
2057         pccb = pSRB->pccb;
2058         pcsio = &pccb->csio;
2059
2060         pSRB->SRBFlag |= AUTO_REQSENSE;
2061         pSRB->Segment0[0] = *((u_int32_t *) & (pSRB->CmdBlock[0]));
2062         pSRB->Segment0[1] = *((u_int32_t *) & (pSRB->CmdBlock[4]));
2063         pSRB->Segment1[0] = (pSRB->ScsiCmdLen << 8) + pSRB->SGcount;
2064         pSRB->Segment1[1] = pSRB->TotalXferredLen;
2065
2066         pSRB->AdaptStatus = 0;
2067         pSRB->TargetStatus = 0;
2068
2069         pSRB->Segmentx.SGXPtr = (u_int32_t) vtophys(&pcsio->sense_data);
2070         pSRB->Segmentx.SGXLen = (u_int32_t) pcsio->sense_len;
2071
2072         pSRB->pSGlist = &pSRB->Segmentx;
2073         pSRB->SGcount = 1;
2074         pSRB->SGIndex = 0;
2075
2076         *((u_int32_t *) & (pSRB->CmdBlock[0])) = 0x00000003;
2077         pSRB->CmdBlock[1] = pSRB->pccb->ccb_h.target_lun << 5;
2078         *((u_int16_t *) & (pSRB->CmdBlock[4])) = pcsio->sense_len;
2079         pSRB->ScsiCmdLen = 6;
2080
2081         pSRB->TotalXferredLen = 0;
2082         pSRB->SGToBeXferLen = 0;
2083         if (amdstart(amd, pSRB) != 0) {
2084                 TAILQ_REMOVE(&amd->running_srbs, pSRB, links);
2085                 TAILQ_INSERT_HEAD(&amd->waiting_srbs, pSRB, links);
2086         }
2087 }
2088
2089 static void
2090 amd_InvalidCmd(struct amd_softc * amd)
2091 {
2092         struct amd_srb *srb;
2093
2094         srb = amd->active_srb;
2095         if (srb->SRBState & (SRB_START|SRB_MSGOUT))
2096                 amd_write8(amd, SCSICMDREG, CLEAR_FIFO_CMD);
2097 }
2098
2099 void 
2100 amd_linkSRB(struct amd_softc *amd)
2101 {
2102         u_int16_t  count, i;
2103         struct amd_srb *psrb;
2104
2105         count = amd->SRBCount;
2106
2107         for (i = 0; i < count; i++) {
2108                 psrb = (struct amd_srb *)&amd->SRB_array[i];
2109                 psrb->TagNumber = i;
2110                 TAILQ_INSERT_TAIL(&amd->free_srbs, psrb, links);
2111         }
2112 }
2113
2114 void
2115 amd_EnDisableCE(struct amd_softc *amd, int mode, int *regval)
2116 {
2117         if (mode == ENABLE_CE) {
2118                 *regval = 0xc0;
2119         } else {
2120                 *regval = 0x80;
2121         }
2122         pci_write_config(amd->dev, *regval, 0, /*bytes*/1);
2123         if (mode == DISABLE_CE) {
2124                 pci_write_config(amd->dev, *regval, 0, /*bytes*/1);
2125         }
2126         DELAY(160);
2127 }
2128
2129 void
2130 amd_EEpromOutDI(struct amd_softc *amd, int *regval, int Carry)
2131 {
2132         u_int bval;
2133
2134         bval = 0;
2135         if (Carry) {
2136                 bval = 0x40;
2137                 *regval = 0x80;
2138                 pci_write_config(amd->dev, *regval, bval, /*bytes*/1);
2139         }
2140         DELAY(160);
2141         bval |= 0x80;
2142         pci_write_config(amd->dev, *regval, bval, /*bytes*/1);
2143         DELAY(160);
2144         pci_write_config(amd->dev, *regval, 0, /*bytes*/1);
2145         DELAY(160);
2146 }
2147
2148 static int
2149 amd_EEpromInDO(struct amd_softc *amd)
2150 {
2151         pci_write_config(amd->dev, 0x80, 0x80, /*bytes*/1);
2152         DELAY(160);
2153         pci_write_config(amd->dev, 0x80, 0x40, /*bytes*/1);
2154         DELAY(160);
2155         if (pci_read_config(amd->dev, 0, /*bytes*/1) == 0x22)
2156                 return (1);
2157         return (0);
2158 }
2159
2160 static u_int16_t
2161 EEpromGetData1(struct amd_softc *amd)
2162 {
2163         u_int     i;
2164         u_int     carryFlag;
2165         u_int16_t wval;
2166
2167         wval = 0;
2168         for (i = 0; i < 16; i++) {
2169                 wval <<= 1;
2170                 carryFlag = amd_EEpromInDO(amd);
2171                 wval |= carryFlag;
2172         }
2173         return (wval);
2174 }
2175
2176 static void
2177 amd_Prepare(struct amd_softc *amd, int *regval, u_int8_t EEpromCmd)
2178 {
2179         u_int i, j;
2180         int carryFlag;
2181
2182         carryFlag = 1;
2183         j = 0x80;
2184         for (i = 0; i < 9; i++) {
2185                 amd_EEpromOutDI(amd, regval, carryFlag);
2186                 carryFlag = (EEpromCmd & j) ? 1 : 0;
2187                 j >>= 1;
2188         }
2189 }
2190
2191 static void
2192 amd_ReadEEprom(struct amd_softc *amd)
2193 {
2194         int        regval;
2195         u_int      i;
2196         u_int16_t *ptr;
2197         u_int8_t   cmd;
2198
2199         ptr = (u_int16_t *)&amd->eepromBuf[0];
2200         cmd = EEPROM_READ;
2201         for (i = 0; i < 0x40; i++) {
2202                 amd_EnDisableCE(amd, ENABLE_CE, &regval);
2203                 amd_Prepare(amd, &regval, cmd);
2204                 *ptr = EEpromGetData1(amd);
2205                 ptr++;
2206                 cmd++;
2207                 amd_EnDisableCE(amd, DISABLE_CE, &regval);
2208         }
2209 }
2210
2211 static void
2212 amd_load_defaults(struct amd_softc *amd)
2213 {
2214         int target;
2215
2216         bzero(&amd->eepromBuf, sizeof amd->eepromBuf);
2217         for (target = 0; target < MAX_SCSI_ID; target++)
2218                 amd->eepromBuf[target << 2] =
2219                     (TAG_QUEUING|EN_DISCONNECT|SYNC_NEGO|PARITY_CHK);
2220         amd->eepromBuf[EE_ADAPT_SCSI_ID] = 7;
2221         amd->eepromBuf[EE_MODE2] = ACTIVE_NEGATION|LUN_CHECK|GREATER_1G;
2222         amd->eepromBuf[EE_TAG_CMD_NUM] = 4;
2223 }
2224
2225 static void
2226 amd_load_eeprom_or_defaults(struct amd_softc *amd)
2227 {
2228         u_int16_t  wval, *ptr;
2229         u_int8_t   i;
2230
2231         amd_ReadEEprom(amd);
2232         wval = 0;
2233         ptr = (u_int16_t *) & amd->eepromBuf[0];
2234         for (i = 0; i < EE_DATA_SIZE; i += 2, ptr++)
2235                 wval += *ptr;
2236
2237         if (wval != EE_CHECKSUM) {
2238                 if (bootverbose)
2239                         printf("amd%d: SEEPROM data unavailable.  "
2240                                "Using default device parameters.\n",
2241                                amd->unit);
2242                 amd_load_defaults(amd);
2243         }
2244 }
2245
2246 /*
2247  **********************************************************************
2248  * Function      : static int amd_init (struct Scsi_Host *host)
2249  * Purpose       : initialize the internal structures for a given SCSI host
2250  * Inputs        : host - pointer to this host adapter's structure/
2251  **********************************************************************
2252  */
2253 static int
2254 amd_init(device_t dev)
2255 {
2256         struct amd_softc *amd = device_get_softc(dev);
2257         struct resource *iores;
2258         int     i, rid;
2259         u_int   bval;
2260
2261         rid = PCI_BASE_ADDR0;
2262         iores = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1,
2263                                    RF_ACTIVE);
2264         if (iores == NULL) {
2265                 if (bootverbose)
2266                         printf("amd_init: bus_alloc_resource failure!\n");
2267                 return ENXIO;
2268         }
2269         amd->tag = rman_get_bustag(iores);
2270         amd->bsh = rman_get_bushandle(iores);
2271
2272         /* DMA tag for mapping buffers into device visible space. */
2273         if (bus_dma_tag_create(/*parent_dmat*/NULL, /*alignment*/1,
2274                                /*boundary*/0,
2275                                /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
2276                                /*highaddr*/BUS_SPACE_MAXADDR,
2277                                /*filter*/NULL, /*filterarg*/NULL,
2278                                /*maxsize*/MAXBSIZE, /*nsegments*/AMD_NSEG,
2279                                /*maxsegsz*/AMD_MAXTRANSFER_SIZE,
2280                                /*flags*/BUS_DMA_ALLOCNOW,
2281                                &amd->buffer_dmat) != 0) {
2282                 if (bootverbose)
2283                         printf("amd_init: bus_dma_tag_create failure!\n");
2284                 return ENXIO;
2285         }
2286         TAILQ_INIT(&amd->free_srbs);
2287         TAILQ_INIT(&amd->running_srbs);
2288         TAILQ_INIT(&amd->waiting_srbs);
2289         amd->last_phase = SCSI_BUS_FREE;
2290         amd->dev = dev;
2291         amd->unit = device_get_unit(dev);
2292         amd->SRBCount = MAX_SRB_CNT;
2293         amd->status = 0;
2294         amd_load_eeprom_or_defaults(amd);
2295         amd->max_id = 7;
2296         if (amd->eepromBuf[EE_MODE2] & LUN_CHECK) {
2297                 amd->max_lun = 7;
2298         } else {
2299                 amd->max_lun = 0;
2300         }
2301         amd->AdaptSCSIID = amd->eepromBuf[EE_ADAPT_SCSI_ID];
2302         amd->HostID_Bit = (1 << amd->AdaptSCSIID);
2303         amd->AdaptSCSILUN = 0;
2304         /* (eepromBuf[EE_TAG_CMD_NUM]) << 2; */
2305         amd->ACBFlag = 0;
2306         amd->Gmode2 = amd->eepromBuf[EE_MODE2];
2307         amd_linkSRB(amd);
2308         for (i = 0; i <= amd->max_id; i++) {
2309
2310                 if (amd->AdaptSCSIID != i) {
2311                         struct amd_target_info *tinfo;
2312                         PEEprom prom;
2313
2314                         tinfo = &amd->tinfo[i];
2315                         prom = (PEEprom)&amd->eepromBuf[i << 2];
2316                         if ((prom->EE_MODE1 & EN_DISCONNECT) != 0) {
2317                                 tinfo->disc_tag |= AMD_USR_DISCENB;
2318                                 if ((prom->EE_MODE1 & TAG_QUEUING) != 0)
2319                                         tinfo->disc_tag |= AMD_USR_TAGENB;
2320                         }
2321                         if ((prom->EE_MODE1 & SYNC_NEGO) != 0) {
2322                                 tinfo->user.period =
2323                                     eeprom_period[prom->EE_SPEED];
2324                                 tinfo->user.offset = AMD_MAX_SYNC_OFFSET;
2325                         }
2326                         tinfo->CtrlR1 = amd->AdaptSCSIID;
2327                         if ((prom->EE_MODE1 & PARITY_CHK) != 0)
2328                                 tinfo->CtrlR1 |= PARITY_ERR_REPO;
2329                         tinfo->CtrlR3 = FAST_CLK;
2330                         tinfo->CtrlR4 = EATER_25NS;
2331                         if ((amd->eepromBuf[EE_MODE2] & ACTIVE_NEGATION) != 0)
2332                                 tinfo->CtrlR4 |= NEGATE_REQACKDATA;
2333                 }
2334         }
2335         amd_write8(amd, SCSITIMEOUTREG, 153); /* 250ms selection timeout */
2336         /* Conversion factor = 0 , 40MHz clock */
2337         amd_write8(amd, CLKFACTREG, CLK_FREQ_40MHZ);
2338         /* NOP cmd - clear command register */
2339         amd_write8(amd, SCSICMDREG, NOP_CMD);   
2340         amd_write8(amd, CNTLREG2, EN_FEATURE|EN_SCSI2_CMD);
2341         amd_write8(amd, CNTLREG3, FAST_CLK);
2342         bval = EATER_25NS;
2343         if (amd->eepromBuf[EE_MODE2] & ACTIVE_NEGATION) {
2344                 bval |= NEGATE_REQACKDATA;
2345         }
2346         amd_write8(amd, CNTLREG4, bval);
2347
2348         /* Disable SCSI bus reset interrupt */
2349         amd_write8(amd, CNTLREG1, DIS_INT_ON_SCSI_RST);
2350
2351         return 0;
2352 }
2353
2354 /*
2355  * attach and init a host adapter
2356  */
2357 static int
2358 amd_attach(device_t dev)
2359 {
2360         struct cam_devq *devq;  /* Device Queue to use for this SIM */
2361         u_int8_t        intstat;
2362         struct amd_softc *amd = device_get_softc(dev);
2363         int             unit = device_get_unit(dev);
2364         int             rid;
2365         void            *ih;
2366         struct resource *irqres;
2367
2368         if (amd_init(dev)) {
2369                 if (bootverbose)
2370                         printf("amd_attach: amd_init failure!\n");
2371                 return ENXIO;
2372         }
2373
2374         /* Reset Pending INT */
2375         intstat = amd_read8(amd, INTSTATREG);
2376
2377         /* After setting up the adapter, map our interrupt */
2378         rid = 0;
2379         irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
2380                                     RF_SHAREABLE | RF_ACTIVE);
2381         if (irqres == NULL ||
2382             bus_setup_intr(dev, irqres, INTR_TYPE_CAM, amd_intr, amd, &ih)) {
2383                 if (bootverbose)
2384                         printf("amd%d: unable to register interrupt handler!\n",
2385                                unit);
2386                 return ENXIO;
2387         }
2388
2389         /*
2390          * Now let the CAM generic SCSI layer find the SCSI devices on
2391          * the bus *  start queue to reset to the idle loop. *
2392          * Create device queue of SIM(s) *  (MAX_START_JOB - 1) :
2393          * max_sim_transactions
2394          */
2395         devq = cam_simq_alloc(MAX_START_JOB);
2396         if (devq == NULL) {
2397                 if (bootverbose)
2398                         printf("amd_attach: cam_simq_alloc failure!\n");
2399                 return ENXIO;
2400         }
2401
2402         amd->psim = cam_sim_alloc(amd_action, amd_poll, "amd",
2403                                   amd, amd->unit, 1, MAX_TAGS_CMD_QUEUE,
2404                                   devq);
2405         cam_simq_release(devq);
2406         if (amd->psim == NULL) {
2407                 if (bootverbose)
2408                         printf("amd_attach: cam_sim_alloc failure!\n");
2409                 return ENXIO;
2410         }
2411
2412         if (xpt_bus_register(amd->psim, 0) != CAM_SUCCESS) {
2413                 cam_sim_free(amd->psim);
2414                 if (bootverbose)
2415                         printf("amd_attach: xpt_bus_register failure!\n");
2416                 return ENXIO;
2417         }
2418
2419         if (xpt_create_path(&amd->ppath, /* periph */ NULL,
2420                             cam_sim_path(amd->psim), CAM_TARGET_WILDCARD,
2421                             CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2422                 xpt_bus_deregister(cam_sim_path(amd->psim));
2423                 cam_sim_free(amd->psim);
2424                 if (bootverbose)
2425                         printf("amd_attach: xpt_create_path failure!\n");
2426                 return ENXIO;
2427         }
2428
2429         return 0;
2430 }
2431
2432 static int
2433 amd_probe(device_t dev)
2434 {
2435         if (pci_get_devid(dev) == PCI_DEVICE_ID_AMD53C974) {
2436                 device_set_desc(dev,
2437                         "Tekram DC390(T)/AMD53c974 SCSI Host Adapter");
2438                 return 0;
2439         }
2440         return ENXIO;
2441 }
2442
2443 static device_method_t amd_methods[] = {
2444         /* Device interface */
2445         DEVMETHOD(device_probe,         amd_probe),
2446         DEVMETHOD(device_attach,        amd_attach),
2447         { 0, 0 }
2448 };
2449
2450 static driver_t amd_driver = {
2451         "amd", amd_methods, sizeof(struct amd_softc)
2452 };
2453
2454 static devclass_t amd_devclass;
2455 DRIVER_MODULE(amd, pci, amd_driver, amd_devclass, 0, 0);