Merge from vendor branch GROFF:
[dragonfly.git] / sys / dev / disk / trm / trm.c
1 /*
2  *       O.S   : FreeBSD CAM
3  *      FILE NAME  : trm.c                                            
4  *           BY    : C.L. Huang         (ching@tekram.com.tw)
5  *               Erich Chen     (erich@tekram.com.tw)
6  *      Description: Device Driver for Tekram DC395U/UW/F ,DC315/U 
7  *                       PCI SCSI Bus Master Host Adapter       
8  *               (SCSI chip set used Tekram ASIC TRM-S1040)
9  * (C)Copyright 1995-1999 Tekram Technology Co., Ltd.
10  */
11
12 /*
13  *      HISTORY:                                        
14  *                                              
15  *      REV#    DATE    NAME            DESCRIPTION     
16  *  1.05   05/01/1999  ERICH CHEN  First released for 3.x.x (CAM)
17  *  1.06   07/29/1999  ERICH CHEN  Modify for NEW PCI
18  *  1.07   12/12/1999  ERICH CHEN  Modify for 3.3.x ,DCB no free
19  *  1.08   06/12/2000  ERICH CHEN  Modify for 4.x.x 
20  */
21
22 /*
23  *
24  *
25  * Redistribution and use in source and binary forms, with or without
26  * modification, are permitted provided that the following conditions
27  * are met:
28  * 1. Redistributions of source code must retain the above copyright
29  *    notice, this list of conditions and the following disclaimer.
30  * 2. Redistributions in binary form must reproduce the above copyright
31  *    notice, this list of conditions and the following disclaimer in the
32  *    documentation and/or other materials provided with the distribution.
33  * 3. The name of the author may not be used to endorse or promote products
34  *    derived from this software without specific prior written permission.
35  *
36  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
37  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
39  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
40  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
45  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46  *
47  * $FreeBSD: src/sys/dev/trm/trm.c,v 1.2.2.2 2002/12/19 20:34:45 cognet Exp $
48  * $DragonFly: src/sys/dev/disk/trm/trm.c,v 1.8 2005/06/16 15:53:35 dillon Exp $
49  */
50
51 /*
52  * Imported into FreeBSD source repository, and updated to compile under  
53  * FreeBSD-3.0-DEVELOPMENT, by Stefan Esser <se@FreeBSD.Org>, 1996-12-17  
54  */
55
56 /*
57  * Updated to compile under FreeBSD 5.0-CURRENT by Olivier Houchard
58  * <doginou@ci0.org>, 2002-03-04
59  */
60
61 #include <sys/param.h>
62
63 #include <sys/systm.h>
64 #include <sys/malloc.h>
65 #include <sys/queue.h>
66 #if defined(__FreeBSD__) && __FreeBSD_version >= 500000
67 #include <sys/bio.h>
68 #endif
69 #include <sys/buf.h>
70 #include <sys/bus.h>
71 #include <sys/kernel.h>
72 #include <sys/thread2.h>
73
74 #include <vm/vm.h>
75 #include <vm/pmap.h>
76
77 #include <bus/pci/pcivar.h>
78 #include <bus/pci/pcireg.h>
79 #include <machine/resource.h>
80 #include <machine/bus_pio.h>
81 #include <machine/bus.h>
82 #include <machine/clock.h>
83 #include <sys/rman.h>
84
85 #include <bus/cam/cam.h>
86 #include <bus/cam/cam_ccb.h>
87 #include <bus/cam/cam_sim.h>
88 #include <bus/cam/cam_xpt_sim.h>
89 #include <bus/cam/cam_debug.h>
90
91 #include <bus/cam/scsi/scsi_all.h>
92
93 #include "trm.h"
94
95 #define trm_reg_read8(reg)      bus_space_read_1(pACB->tag, pACB->bsh, reg)
96 #define trm_reg_read16(reg)     bus_space_read_2(pACB->tag, pACB->bsh, reg)
97 #define trm_reg_read32(reg)     bus_space_read_4(pACB->tag, pACB->bsh, reg)
98 #define trm_reg_write8(value,reg)       bus_space_write_1(pACB->tag, pACB->bsh,\
99                 reg, value)
100 #define trm_reg_write16(value,reg)      bus_space_write_2(pACB->tag, pACB->bsh,\
101                 reg, value)
102 #define trm_reg_write32(value,reg)      bus_space_write_4(pACB->tag, pACB->bsh,\
103                 reg, value)
104
105 #define PCI_Vendor_ID_TEKRAM    0x1DE1
106 #define PCI_Device_ID_TRM_S1040 0x0391
107 #define PCI_DEVICEID_TRMS1040   0x03911DE1
108
109 #ifdef trm_DEBUG1
110 #define TRM_DPRINTF(fmt, arg...) printf("trm: " fmt, ##arg)
111 #else
112 #define TRM_DPRINTF(fmt, arg...) {}
113 #endif /* TRM_DEBUG */
114
115 static void     trm_check_eeprom(PNVRAMTYPE pEEpromBuf,PACB pACB);
116 static void     TRM_read_all(PNVRAMTYPE pEEpromBuf,PACB pACB);
117 static u_int8_t TRM_get_data(PACB pACB, u_int8_t bAddr);
118 static void     TRM_write_all(PNVRAMTYPE pEEpromBuf,PACB pACB);
119 static void     TRM_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData);
120 static void     TRM_write_cmd(PACB pACB, u_int8_t bCmd, u_int8_t bAddr);
121 static void     TRM_wait_30us(PACB pACB);
122
123 static void     trm_Interrupt(void *vpACB);
124 static void     trm_DataOutPhase0(PACB pACB, PSRB pSRB, 
125                                          u_int8_t * pscsi_status);
126 static void     trm_DataInPhase0(PACB pACB, PSRB pSRB, 
127                                         u_int8_t * pscsi_status);
128 static void     trm_CommandPhase0(PACB pACB, PSRB pSRB, 
129                                          u_int8_t * pscsi_status);
130 static void     trm_StatusPhase0(PACB pACB, PSRB pSRB, 
131                                         u_int8_t * pscsi_status);
132 static void     trm_MsgOutPhase0(PACB pACB, PSRB pSRB, 
133                                         u_int8_t * pscsi_status);
134 static void     trm_MsgInPhase0(PACB pACB, PSRB pSRB, 
135                                         u_int8_t * pscsi_status);
136 static void     trm_DataOutPhase1(PACB pACB, PSRB pSRB, 
137                                          u_int8_t * pscsi_status);
138 static void     trm_DataInPhase1(PACB pACB, PSRB pSRB, 
139                                         u_int8_t * pscsi_status);
140 static void     trm_CommandPhase1(PACB pACB, PSRB pSRB, 
141                                          u_int8_t * pscsi_status);
142 static void     trm_StatusPhase1(PACB pACB, PSRB pSRB, 
143                                         u_int8_t * pscsi_status);
144 static void     trm_MsgOutPhase1(PACB pACB, PSRB pSRB, 
145                                         u_int8_t * pscsi_status);
146 static void     trm_MsgInPhase1(PACB pACB, PSRB pSRB, 
147                                         u_int8_t * pscsi_status);
148 static void     trm_Nop0(PACB pACB, PSRB pSRB, u_int8_t * pscsi_status);
149 static void     trm_Nop1(PACB pACB, PSRB pSRB, u_int8_t * pscsi_status);
150 static void     trm_SetXferRate(PACB pACB, PSRB pSRB,PDCB pDCB);
151 static void     trm_DataIO_transfer(PACB pACB, PSRB pSRB, u_int16_t ioDir);
152 static void     trm_Disconnect(PACB pACB);
153 static void     trm_Reselect(PACB pACB);
154 static void     trm_SRBdone(PACB pACB, PDCB pDCB, PSRB pSRB);
155 static void     trm_DoingSRB_Done(PACB pACB);
156 static void     trm_ScsiRstDetect(PACB pACB);
157 static void     trm_ResetSCSIBus(PACB pACB);
158 static void     trm_RequestSense(PACB pACB, PDCB pDCB, PSRB pSRB);
159 static void     trm_EnableMsgOutAbort2(PACB pACB, PSRB pSRB);
160 static void     trm_EnableMsgOutAbort1(PACB pACB, PSRB pSRB);
161 static void     trm_SendSRB(PACB pACB, PSRB pSRB);
162 static int      trm_probe(device_t tag);
163 static int      trm_attach(device_t tag);
164 static void     trm_reset(PACB pACB);
165
166 static u_int16_t        trm_StartSCSI(PACB pACB, PDCB pDCB, PSRB pSRB);
167
168 static int      trm_initAdapter(PACB pACB, u_int16_t unit, 
169                                         device_t pci_config_id);
170 static void     trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit, 
171                                         u_int32_t i, u_int32_t j);
172 static void     trm_initSRB(PSRB psrb);
173 static void     trm_linkSRB(PACB pACB);
174 static void     trm_initACB(PACB pACB, u_int16_t unit);
175 /* CAM SIM entry points */
176 #define ccb_trmsrb_ptr spriv_ptr0
177 #define ccb_trmacb_ptr spriv_ptr1
178 static void     trm_action(struct cam_sim *psim, union ccb *pccb);
179 static void     trm_poll(struct cam_sim *psim);
180
181
182 static void * trm_SCSI_phase0[] = {
183         trm_DataOutPhase0,    /* phase:0 */
184         trm_DataInPhase0,     /* phase:1 */
185         trm_CommandPhase0,    /* phase:2 */
186         trm_StatusPhase0,     /* phase:3 */
187         trm_Nop0,             /* phase:4 */
188         trm_Nop1,             /* phase:5 */
189         trm_MsgOutPhase0,     /* phase:6 */
190         trm_MsgInPhase0,      /* phase:7 */
191 };
192
193 /*
194  *
195  *          stateV = (void *) trm_SCSI_phase1[phase]
196  *
197  */
198 static void * trm_SCSI_phase1[] = {
199         trm_DataOutPhase1,    /* phase:0 */
200         trm_DataInPhase1,     /* phase:1 */
201         trm_CommandPhase1,    /* phase:2 */
202         trm_StatusPhase1,     /* phase:3 */
203         trm_Nop0,             /* phase:4 */
204         trm_Nop1,             /* phase:5 */
205         trm_MsgOutPhase1,     /* phase:6 */
206         trm_MsgInPhase1,      /* phase:7 */
207 };
208
209
210 NVRAMTYPE trm_eepromBuf[MAX_ADAPTER_NUM];
211 /*
212  *Fast20:  000   50ns, 20.0 Mbytes/s
213  *             001       75ns, 13.3 Mbytes/s
214  *             010      100ns, 10.0 Mbytes/s
215  *             011      125ns,  8.0 Mbytes/s
216  *             100      150ns,  6.6 Mbytes/s
217  *             101      175ns,  5.7 Mbytes/s
218  *             110      200ns,  5.0 Mbytes/s
219  *             111      250ns,  4.0 Mbytes/s
220  *
221  *Fast40:  000   25ns, 40.0 Mbytes/s
222  *             001       50ns, 20.0 Mbytes/s
223  *             010       75ns, 13.3 Mbytes/s
224  *             011      100ns, 10.0 Mbytes/s
225  *             100      125ns,  8.0 Mbytes/s
226  *             101      150ns,  6.6 Mbytes/s
227  *             110      175ns,  5.7 Mbytes/s
228  *             111      200ns,  5.0 Mbytes/s
229  */
230                                              /* real period: */
231 u_int8_t dc395x_trm_clock_period[] = {
232         12,/*  48  ns 20   MB/sec */
233         18,/*  72  ns 13.3 MB/sec */
234         25,/* 100  ns 10.0 MB/sec */
235         31,/* 124  ns  8.0 MB/sec */
236         37,/* 148  ns  6.6 MB/sec */
237         43,/* 172  ns  5.7 MB/sec */
238         50,/* 200  ns  5.0 MB/sec */
239         62 /* 248  ns  4.0 MB/sec */
240 };
241
242 u_int8_t dc395x_trm_tinfo_sync_period[] = { 
243         12,/* 20.0 MB/sec */
244         18,/* 13.3 MB/sec */
245         25,/* 10.0 MB/sec */
246         31,/*  8.0 MB/sec */
247         37,/*  6.6 MB/sec */
248         43,/*  5.7 MB/sec */
249         50,/*  5.0 MB/sec */
250         62,/*  4.0 MB/sec */
251 };
252
253 static PSRB
254 trm_GetSRB(PACB pACB)
255 {
256         PSRB    pSRB;
257
258         crit_enter();
259         pSRB = pACB->pFreeSRB;
260         if (pSRB) {
261                 pACB->pFreeSRB = pSRB->pNextSRB;
262                 pSRB->pNextSRB = NULL;
263         }
264         crit_exit();
265         return (pSRB);
266 }
267
268 static void
269 trm_RewaitSRB0(PDCB pDCB, PSRB pSRB)
270 {
271         PSRB    psrb1;
272
273         crit_enter();
274         if ((psrb1 = pDCB->pWaitingSRB)) {
275                 pSRB->pNextSRB = psrb1;
276                 pDCB->pWaitingSRB = pSRB;
277         } else {
278                 pSRB->pNextSRB = NULL;
279                 pDCB->pWaitingSRB = pSRB;
280                 pDCB->pWaitLastSRB = pSRB;
281         }
282         crit_exit();
283 }
284
285 static void
286 trm_RewaitSRB(PDCB pDCB, PSRB pSRB)
287 {
288         PSRB    psrb1;
289         u_int8_t        bval;
290
291         crit_enter();
292         pDCB->GoingSRBCnt--;
293         psrb1 = pDCB->pGoingSRB;
294         if (pSRB == psrb1)
295                 pDCB->pGoingSRB = psrb1->pNextSRB;
296         else {
297                 while (pSRB != psrb1->pNextSRB)
298                         psrb1 = psrb1->pNextSRB;
299                 psrb1->pNextSRB = pSRB->pNextSRB;
300                 if (pSRB == pDCB->pGoingLastSRB)
301                         pDCB->pGoingLastSRB = psrb1;
302         }
303         if ((psrb1 = pDCB->pWaitingSRB)) {
304                 pSRB->pNextSRB = psrb1;
305                 pDCB->pWaitingSRB = pSRB;
306         } else {
307                 pSRB->pNextSRB = NULL;
308                 pDCB->pWaitingSRB = pSRB;
309                 pDCB->pWaitLastSRB = pSRB;
310         }
311         bval = pSRB->TagNumber;
312         pDCB->TagMask &= (~(1 << bval));          /* Free TAG number */
313         crit_exit();
314 }
315
316 static void
317 trm_DoWaitingSRB(PACB pACB)
318 {
319         PDCB    ptr, ptr1;
320         PSRB    pSRB;
321
322         crit_enter();
323         if (!(pACB->pActiveDCB) && 
324             !(pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV))) {
325                 ptr = pACB->pDCBRunRobin;
326                 if (!ptr) {
327                         ptr = pACB->pLinkDCB;
328                         pACB->pDCBRunRobin = ptr;
329                 }
330                 ptr1 = ptr;
331                 for (;ptr1 ;) {
332                         pACB->pDCBRunRobin = ptr1->pNextDCB;
333                         if (!(ptr1->MaxCommand > ptr1->GoingSRBCnt) 
334                             || !(pSRB = ptr1->pWaitingSRB)) {
335                                 if (pACB->pDCBRunRobin == ptr)
336                                         break;
337                                 ptr1 = ptr1->pNextDCB;
338                         } else {
339                                 if (!trm_StartSCSI(pACB, ptr1, pSRB)) {
340                                 /* 
341                                  * If trm_StartSCSI return 0 :
342                                  * current interrupt status is interrupt enable 
343                                  * It's said that SCSI processor is unoccupied 
344                                  */
345                                         ptr1->GoingSRBCnt++;
346                                         if (ptr1->pWaitLastSRB == pSRB) {
347                                                 ptr1->pWaitingSRB = NULL;
348                                                 ptr1->pWaitLastSRB = NULL;
349                                         } else
350                                                 ptr1->pWaitingSRB = pSRB->pNextSRB;
351                                         pSRB->pNextSRB = NULL;
352                                         if (ptr1->pGoingSRB) 
353                                                 ptr1->pGoingLastSRB->pNextSRB = pSRB;
354                                         else
355                                                 ptr1->pGoingSRB = pSRB;
356                                         ptr1->pGoingLastSRB = pSRB;
357                                 }
358                                 break;
359                         }
360                 }
361         }
362         crit_exit();
363         return;
364 }
365
366 static void
367 trm_SRBwaiting(PDCB pDCB, PSRB pSRB)
368 {
369   
370         if (pDCB->pWaitingSRB) {
371                 pDCB->pWaitLastSRB->pNextSRB = pSRB;
372                 pDCB->pWaitLastSRB = pSRB;
373                 pSRB->pNextSRB = NULL;
374         } else {
375                 pDCB->pWaitingSRB = pSRB;
376                 pDCB->pWaitLastSRB = pSRB;
377         }
378 }
379
380 static void
381 trm_ExecuteSRB(void *arg, bus_dma_segment_t *dm_segs, int nseg, int vp)
382 {
383         PACB            pACB;
384         PSRB            pSRB;
385         union ccb       *ccb;
386         u_long          totalxferlen=0;
387
388         pSRB = (PSRB)arg;
389         ccb = pSRB->pccb;
390         pACB = (PACB)ccb->ccb_h.ccb_trmacb_ptr;
391         TRM_DPRINTF("trm_ExecuteSRB..........\n");        
392         if (nseg != 0) {
393                 PSEG                    psg;
394                 bus_dma_segment_t       *end_seg;
395                 bus_dmasync_op_t        op;
396
397                 /* Copy the segments into our SG list */
398                 end_seg = dm_segs + nseg;
399                 psg = (PSEG) &pSRB->SegmentX[0];
400                 pSRB->SRBSGListPointer= psg;
401                 while (dm_segs < end_seg) {
402                         psg->address = vp?(u_long)vtophys(dm_segs->ds_addr)
403                           :(u_long)dm_segs->ds_addr;
404                         psg->length = (u_long)dm_segs->ds_len;
405                         totalxferlen += dm_segs->ds_len;
406                         psg++;
407                         dm_segs++;
408                 }
409                 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
410                         op = BUS_DMASYNC_PREREAD;
411                 } else {
412                         op = BUS_DMASYNC_PREWRITE;
413                 }
414                 bus_dmamap_sync(pACB->buffer_dmat, pSRB->dmamap, op);
415         }
416         pSRB->RetryCnt = 0;
417         pSRB->SRBTotalXferLength=totalxferlen;
418         pSRB->SRBSGCount = nseg;
419         pSRB->SRBSGIndex = 0;
420         pSRB->AdaptStatus = 0;
421         pSRB->TargetStatus = 0;
422         pSRB->MsgCnt = 0;
423         pSRB->SRBStatus = 0;
424         pSRB->SRBFlag = 0;
425         pSRB->SRBState = 0;
426         pSRB->ScsiPhase = PH_BUS_FREE; /* SCSI bus free Phase */
427
428         crit_enter();
429         if (ccb->ccb_h.status != CAM_REQ_INPROG) {
430                 if (nseg != 0)
431                         bus_dmamap_unload(pACB->buffer_dmat, pSRB->dmamap);
432                 pSRB->pNextSRB = pACB->pFreeSRB;
433                 pACB->pFreeSRB = pSRB;
434                 xpt_done(ccb);
435                 crit_exit();
436                 return;
437         }
438         ccb->ccb_h.status |= CAM_SIM_QUEUED;
439 #if 0
440         /* XXX Need a timeout handler */
441         callout_reset(&ccb->ccb_h.timeout_ch, (ccb->ccb_h.timeout * hz) / 1000,
442                       trmtimeout, srb);
443 #endif
444         trm_SendSRB(pACB, pSRB);
445         crit_exit();
446         return;
447 }
448
449 static void
450 trm_SendSRB(PACB pACB, PSRB pSRB)
451 {
452         PDCB    pDCB;
453
454         crit_enter();
455         pDCB = pSRB->pSRBDCB;
456         if (!(pDCB->MaxCommand > pDCB->GoingSRBCnt) || (pACB->pActiveDCB)
457             || (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV))) {
458                 TRM_DPRINTF("pDCB->MaxCommand=%d \n",pDCB->MaxCommand);        
459                 TRM_DPRINTF("pDCB->GoingSRBCnt=%d \n",pDCB->GoingSRBCnt);
460                 TRM_DPRINTF("pACB->pActiveDCB=%8x \n",(u_int)pACB->pActiveDCB);
461                 TRM_DPRINTF("pACB->ACBFlag=%x \n",pACB->ACBFlag);
462                 trm_SRBwaiting(pDCB, pSRB);
463                 goto SND_EXIT;
464         }
465
466         if (pDCB->pWaitingSRB) {
467                 trm_SRBwaiting(pDCB, pSRB);
468                 pSRB = pDCB->pWaitingSRB;
469                 pDCB->pWaitingSRB = pSRB->pNextSRB;
470                 pSRB->pNextSRB = NULL;
471         }
472
473         if (!trm_StartSCSI(pACB, pDCB, pSRB)) { 
474         /* 
475          * If trm_StartSCSI return 0 :
476          * current interrupt status is interrupt enable 
477          * It's said that SCSI processor is unoccupied 
478          */
479                 pDCB->GoingSRBCnt++; /* stack waiting SRB*/
480                 if (pDCB->pGoingSRB) {
481                         pDCB->pGoingLastSRB->pNextSRB = pSRB;
482                         pDCB->pGoingLastSRB = pSRB;
483                 } else {
484                         pDCB->pGoingSRB = pSRB;
485                         pDCB->pGoingLastSRB = pSRB;
486                 }
487         } else {
488         /* 
489          * If trm_StartSCSI return 1 :
490          * current interrupt status is interrupt disreenable 
491          * It's said that SCSI processor has more one SRB need to do
492          */
493                 trm_RewaitSRB0(pDCB, pSRB);
494         }
495 SND_EXIT:
496         crit_exit();
497         /*
498          *      enable interrupt
499          */
500         return;
501 }
502
503
504 static void
505 trm_action(struct cam_sim *psim, union ccb *pccb) 
506 {
507         PACB    pACB;
508         u_int   target_id,target_lun;
509
510         CAM_DEBUG(pccb->ccb_h.path, CAM_DEBUG_TRACE, ("trm_action\n"));
511
512         pACB = (PACB) cam_sim_softc(psim);
513         target_id  = pccb->ccb_h.target_id;
514         target_lun = pccb->ccb_h.target_lun;
515
516         switch (pccb->ccb_h.func_code) {
517                 case XPT_NOOP:                  
518                         TRM_DPRINTF(" XPT_NOOP \n");
519                         pccb->ccb_h.status = CAM_REQ_INVALID;
520                         xpt_done(pccb);
521                         break;
522                 /*
523                  * Execute the requested I/O operation 
524                  */
525                 case XPT_SCSI_IO: {
526                         PDCB                    pDCB = NULL;
527                         PSRB                    pSRB;
528                         struct ccb_scsiio       *pcsio;
529      
530                         pcsio = &pccb->csio;
531                         TRM_DPRINTF(" XPT_SCSI_IO \n");
532                         TRM_DPRINTF("trm: target_id= %d target_lun= %d \n"
533                              ,target_id, target_lun);
534                         TRM_DPRINTF(
535                             "pACB->scan_devices[target_id][target_lun]= %d \n"
536                             ,pACB->scan_devices[target_id][target_lun]);
537                         pDCB = pACB->pDCB[target_id][target_lun];
538                         /*
539                          * Assign an SRB and connect it with this ccb.
540                          */
541                         pSRB = trm_GetSRB(pACB);
542                         if (!pSRB) {
543                                 /* Freeze SIMQ */
544                                 pccb->ccb_h.status = CAM_RESRC_UNAVAIL;
545                                 xpt_done(pccb);
546                                 return;
547                         }
548                         pSRB->pSRBDCB = pDCB;
549                         pccb->ccb_h.ccb_trmsrb_ptr = pSRB;
550                         pccb->ccb_h.ccb_trmacb_ptr = pACB;
551                         pSRB->pccb = pccb;
552                         pSRB->ScsiCmdLen = pcsio->cdb_len;
553                         /* 
554                          * move layer of CAM command block to layer of SCSI
555                          * Request Block for SCSI processor command doing
556                          */
557                         bcopy(pcsio->cdb_io.cdb_bytes,pSRB->CmdBlock
558                             ,pcsio->cdb_len);
559                         if ((pccb->ccb_h.flags & CAM_DIR_MASK)
560                             != CAM_DIR_NONE) {
561                                 if ((pccb->ccb_h.flags &
562                                       CAM_SCATTER_VALID) == 0) {
563                                         if ((pccb->ccb_h.flags 
564                                               & CAM_DATA_PHYS) == 0) {
565                                                 int error;
566
567                                                 crit_enter();
568                                                 error = bus_dmamap_load(
569                                                     pACB->buffer_dmat,
570                                                     pSRB->dmamap,
571                                                     pcsio->data_ptr,
572                                                     pcsio->dxfer_len,
573                                                     trm_ExecuteSRB,
574                                                     pSRB,
575                                                     0);
576                                                 if (error == EINPROGRESS) {
577                                                         xpt_freeze_simq(
578                                                             pACB->psim,
579                                                             1);
580                                                         pccb->ccb_h.status |=
581                                                           CAM_RELEASE_SIMQ;
582                                                 }
583                                                 crit_exit();
584                                         } else {   
585                                                 struct bus_dma_segment seg;
586
587                                                 /* Pointer to physical buffer */
588                                                 seg.ds_addr = 
589                                                   (bus_addr_t)pcsio->data_ptr;
590                                                 seg.ds_len = pcsio->dxfer_len;
591                                                 trm_ExecuteSRB(pSRB, &seg, 1,
592                                                     0);
593                                         }
594                                 } else { 
595                                         /*  CAM_SCATTER_VALID */
596                                         struct bus_dma_segment *segs;
597
598                                         if ((pccb->ccb_h.flags &
599                                              CAM_SG_LIST_PHYS) == 0 ||
600                                              (pccb->ccb_h.flags 
601                                              & CAM_DATA_PHYS) != 0) {
602                                                 pSRB->pNextSRB = pACB->pFreeSRB;
603                                                 pACB->pFreeSRB = pSRB;
604                                                 pccb->ccb_h.status = 
605                                                   CAM_PROVIDE_FAIL;
606                                                 xpt_done(pccb);
607                                                 return;
608                                         }
609
610                                         /* cam SG list is physical,
611                                          *  cam data is virtual 
612                                          */
613                                         segs = (struct bus_dma_segment *)
614                                             pcsio->data_ptr;
615                                         trm_ExecuteSRB(pSRB, segs,
616                                             pcsio->sglist_cnt, 1);
617                                 }   /*  CAM_SCATTER_VALID */
618                         } else
619                                 trm_ExecuteSRB(pSRB, NULL, 0, 0);
620                                   }
621                         break;
622                 case XPT_GDEV_TYPE:                 
623                         TRM_DPRINTF(" XPT_GDEV_TYPE \n");
624                         pccb->ccb_h.status = CAM_REQ_INVALID;
625                         xpt_done(pccb);
626                         break;
627                 case XPT_GDEVLIST:                  
628                         TRM_DPRINTF(" XPT_GDEVLIST \n");
629                         pccb->ccb_h.status = CAM_REQ_INVALID;
630                         xpt_done(pccb);
631                         break;
632                 /*
633                  * Path routing inquiry 
634                  * Path Inquiry CCB 
635                  */
636                 case XPT_PATH_INQ: {
637                         struct ccb_pathinq *cpi = &pccb->cpi;
638
639                         TRM_DPRINTF(" XPT_PATH_INQ \n");
640                         cpi->version_num = 1; 
641                         cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
642                         cpi->target_sprt = 0;
643                         cpi->hba_misc = 0;
644                         cpi->hba_eng_cnt = 0;
645                         cpi->max_target = 15 ; 
646                         cpi->max_lun = pACB->max_lun;        /* 7 or 0 */
647                         cpi->initiator_id = pACB->AdaptSCSIID;
648                         cpi->bus_id = cam_sim_bus(psim);
649                         strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
650                         strncpy(cpi->hba_vid, "Tekram_TRM", HBA_IDLEN);
651                         strncpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN);
652                         cpi->unit_number = cam_sim_unit(psim);
653                         cpi->ccb_h.status = CAM_REQ_CMP;
654                         xpt_done(pccb);
655                                    }
656                         break;
657                 /*
658                  * Release a frozen SIM queue 
659                  * Release SIM Queue 
660                  */
661                 case XPT_REL_SIMQ:                  
662                         TRM_DPRINTF(" XPT_REL_SIMQ \n");
663                         pccb->ccb_h.status = CAM_REQ_INVALID;
664                         xpt_done(pccb);
665                         break;
666                 /*
667                  * Set Asynchronous Callback Parameters 
668                  * Set Asynchronous Callback CCB
669                  */
670                 case XPT_SASYNC_CB:                 
671                         TRM_DPRINTF(" XPT_SASYNC_CB \n");
672                         pccb->ccb_h.status = CAM_REQ_INVALID;
673                         xpt_done(pccb);
674                         break;
675                 /*
676                  * Set device type information 
677                  * Set Device Type CCB 
678                  */
679                 case XPT_SDEV_TYPE:                 
680                         TRM_DPRINTF(" XPT_SDEV_TYPE \n");
681                         pccb->ccb_h.status = CAM_REQ_INVALID;
682                         xpt_done(pccb);
683                         break;
684                 /*
685                  * (Re)Scan the SCSI Bus 
686                  * Rescan the given bus, or bus/target/lun
687                  */
688                 case XPT_SCAN_BUS:                  
689                         TRM_DPRINTF(" XPT_SCAN_BUS \n");
690                         pccb->ccb_h.status = CAM_REQ_INVALID;
691                         xpt_done(pccb);
692                         break;
693                 /*
694                  * Get EDT entries matching the given pattern 
695                  */
696                 case XPT_DEV_MATCH:             
697                         TRM_DPRINTF(" XPT_DEV_MATCH \n");
698                         pccb->ccb_h.status = CAM_REQ_INVALID;
699                         xpt_done(pccb);
700                         break;
701                 /*
702                  * Turn on debugging for a bus, target or lun 
703                  */
704                 case XPT_DEBUG:             
705                         TRM_DPRINTF(" XPT_DEBUG \n");
706                         pccb->ccb_h.status = CAM_REQ_INVALID;
707                         xpt_done(pccb);
708                         break;
709                         /*
710                          * XPT_ABORT = 0x10, Abort the specified CCB 
711                          * Abort XPT request CCB 
712                          */
713                 case XPT_ABORT:             
714                         TRM_DPRINTF(" XPT_ABORT \n");
715                         pccb->ccb_h.status = CAM_REQ_INVALID;
716                         xpt_done(pccb);
717                         break;
718                 /*
719                  * Reset the specified SCSI bus 
720                  * Reset SCSI Bus CCB 
721                  */
722                 case XPT_RESET_BUS: {           
723                         int i;
724
725                         TRM_DPRINTF(" XPT_RESET_BUS \n");
726                         trm_reset(pACB);
727                         pACB->ACBFlag=0;
728                         for (i=0; i<500; i++)
729                                 DELAY(1000);
730                         pccb->ccb_h.status = CAM_REQ_CMP;
731                         xpt_done(pccb);
732                                     }
733                         break;
734                 /*
735                  * Bus Device Reset the specified SCSI device 
736                  * Reset SCSI Device CCB 
737                  */
738                 case XPT_RESET_DEV:             
739                 /*
740                  * Don't (yet?) support vendor
741                  * specific commands.
742                  */
743                         TRM_DPRINTF(" XPT_RESET_DEV \n");
744                         pccb->ccb_h.status = CAM_REQ_INVALID;
745                         xpt_done(pccb);
746                         break;
747                 /*
748                  * Terminate the I/O process 
749                  * Terminate I/O Process Request CCB 
750                  */
751                 case XPT_TERM_IO:               
752                         TRM_DPRINTF(" XPT_TERM_IO \n");
753                         pccb->ccb_h.status = CAM_REQ_INVALID;
754                         xpt_done(pccb);
755                         break;
756                 /*
757                  * Scan Logical Unit 
758                  */
759                 case XPT_SCAN_LUN:                 
760                         TRM_DPRINTF(" XPT_SCAN_LUN \n");
761                         pccb->ccb_h.status = CAM_REQ_INVALID;
762                         xpt_done(pccb);
763                         break;
764
765                 /*
766                  * Get/Set transfer rate/width/disconnection/tag queueing 
767                  * settings 
768                  * (GET) default/user transfer settings for the target 
769                  */
770                 case XPT_GET_TRAN_SETTINGS: {
771                         struct  ccb_trans_settings *cts;        
772                         struct  trm_transinfo *tinfo;
773                         PDCB    pDCB;   
774                         
775                         TRM_DPRINTF(" XPT_GET_TRAN_SETTINGS \n");
776                         cts = &pccb->cts;
777                         pDCB = pACB->pDCB[target_id][target_lun];
778                         crit_enter();
779                         /*
780                          * disable interrupt
781                          */
782                         if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) {
783                                 /* current transfer settings */
784                                 if (pDCB->tinfo.disc_tag & TRM_CUR_DISCENB)
785                                         cts->flags = CCB_TRANS_DISC_ENB;
786                                 else
787                                         cts->flags = 0;/* no tag & disconnect */
788                                 if (pDCB->tinfo.disc_tag & TRM_CUR_TAGENB)
789                                         cts->flags |= CCB_TRANS_TAG_ENB;
790                                 tinfo = &pDCB->tinfo.current;
791                                 TRM_DPRINTF("CURRENT:  cts->flags= %2x \n",
792                                     cts->flags);
793                         } else {
794                           /* default(user) transfer settings */
795                                 if (pDCB->tinfo.disc_tag & TRM_USR_DISCENB)
796                                         cts->flags = CCB_TRANS_DISC_ENB;
797                                 else
798                                         cts->flags = 0;
799                                 if (pDCB->tinfo.disc_tag & TRM_USR_TAGENB)
800                                         cts->flags |= CCB_TRANS_TAG_ENB;
801                                 tinfo = &pDCB->tinfo.user;
802                                 TRM_DPRINTF("USER: cts->flags= %2x \n",
803                                         cts->flags);
804                         }
805                         cts->sync_period = tinfo->period;
806                         cts->sync_offset = tinfo->offset;
807                         cts->bus_width   = tinfo->width;
808                         TRM_DPRINTF("pDCB->SyncPeriod: %d  \n", 
809                                 pDCB->SyncPeriod);
810                         TRM_DPRINTF("period: %d  \n", tinfo->period);
811                         TRM_DPRINTF("offset: %d  \n", tinfo->offset);
812                         TRM_DPRINTF("width: %d  \n", tinfo->width);
813
814                         crit_exit();
815                         cts->valid = CCB_TRANS_SYNC_RATE_VALID | 
816                             CCB_TRANS_SYNC_OFFSET_VALID | 
817                             CCB_TRANS_BUS_WIDTH_VALID | 
818                             CCB_TRANS_DISC_VALID | 
819                             CCB_TRANS_TQ_VALID;
820                         pccb->ccb_h.status = CAM_REQ_CMP;
821                         xpt_done(pccb);
822                                             }
823                         break;
824                 /* 
825                  * Get/Set transfer rate/width/disconnection/tag queueing 
826                  * settings
827                  * (Set) transfer rate/width negotiation settings 
828                  */
829                 case XPT_SET_TRAN_SETTINGS: {
830                         struct  ccb_trans_settings *cts;
831                         u_int   update_type;
832                         PDCB    pDCB;
833
834                         TRM_DPRINTF(" XPT_SET_TRAN_SETTINGS \n");
835                         cts = &pccb->cts;
836                         update_type = 0;
837                         if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
838                                 update_type |= TRM_TRANS_GOAL;
839                         if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
840                                 update_type |= TRM_TRANS_USER;
841                         crit_enter();
842                         pDCB = pACB->pDCB[target_id][target_lun];
843
844                         if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) {
845                           /*ccb disc enables */
846                                 if (update_type & TRM_TRANS_GOAL) {
847                                         if ((cts->flags & CCB_TRANS_DISC_ENB)
848                                             != 0) 
849                                                 pDCB->tinfo.disc_tag 
850                                                     |= TRM_CUR_DISCENB;
851                                         else
852                                                 pDCB->tinfo.disc_tag &=
853                                                     ~TRM_CUR_DISCENB;
854                                 }
855                                 if (update_type & TRM_TRANS_USER) {
856                                         if ((cts->flags & CCB_TRANS_DISC_ENB)
857                                             != 0)
858                                                 pDCB->tinfo.disc_tag 
859                                                     |= TRM_USR_DISCENB;
860                                         else
861                                                 pDCB->tinfo.disc_tag &=
862                                                     ~TRM_USR_DISCENB;
863                                 }
864                         }
865                         if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) {
866                           /* if ccb tag q active */
867                                 if (update_type & TRM_TRANS_GOAL) {
868                                         if ((cts->flags & CCB_TRANS_TAG_ENB)
869                                             != 0)
870                                                 pDCB->tinfo.disc_tag |= 
871                                                     TRM_CUR_TAGENB;
872                                         else
873                                                 pDCB->tinfo.disc_tag &= 
874                                                     ~TRM_CUR_TAGENB;
875                                 }
876                                 if (update_type & TRM_TRANS_USER) {
877                                         if ((cts->flags & CCB_TRANS_TAG_ENB)
878                                             != 0)
879                                                 pDCB->tinfo.disc_tag |= 
880                                                     TRM_USR_TAGENB;
881                                         else
882                                                 pDCB->tinfo.disc_tag &= 
883                                                     ~TRM_USR_TAGENB;
884                                 }       
885                         }
886                         /* Minimum sync period factor   */
887
888                         if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
889                                 /* if ccb sync active */
890                                 /* TRM-S1040 MinSyncPeriod = 4 clocks/byte */
891                                 if ((cts->sync_period != 0) &&
892                                     (cts->sync_period < 125))
893                                         cts->sync_period = 125;
894                                 /* 1/(125*4) minsync 2 MByte/sec */
895                                 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID)
896                                     != 0) {
897                                         if (cts->sync_offset == 0)
898                                                 cts->sync_period = 0;
899                                         /* TRM-S1040 MaxSyncOffset = 15 bytes*/
900                                         if (cts->sync_offset > 15) 
901                                                 cts->sync_offset = 15;
902                                 }
903                         }
904                         if ((update_type & TRM_TRANS_USER) != 0) {
905                                 pDCB->tinfo.user.period = cts->sync_period;
906                                 pDCB->tinfo.user.offset = cts->sync_offset;
907                                 pDCB->tinfo.user.width  = cts->bus_width;
908                         }
909                         if ((update_type & TRM_TRANS_GOAL) != 0) {
910                                 pDCB->tinfo.goal.period = cts->sync_period;
911                                 pDCB->tinfo.goal.offset = cts->sync_offset;
912                                 pDCB->tinfo.goal.width  = cts->bus_width;
913                         }
914                         crit_exit();
915                         pccb->ccb_h.status = CAM_REQ_CMP;
916                         xpt_done(pccb);
917                         break;
918                                             }
919                 /*
920                  * Calculate the geometry parameters for a device give
921                  * the sector size and volume size. 
922                  */
923                 case XPT_CALC_GEOMETRY: {
924                         struct          ccb_calc_geometry *ccg;
925                         u_int32_t       size_mb;
926                         u_int32_t       secs_per_cylinder;
927                         int             extended;
928
929                         TRM_DPRINTF(" XPT_CALC_GEOMETRY \n");
930                         ccg = &pccb->ccg;
931                         size_mb = ccg->volume_size / 
932                             ((1024L * 1024L) / ccg->block_size);
933                         extended =  1;          
934                         if (size_mb > 1024 && extended) {
935                                 ccg->heads = 255;
936                                 ccg->secs_per_track = 63;
937                         } else {
938                                 ccg->heads = 64;
939                                 ccg->secs_per_track = 32;
940                         }
941                         secs_per_cylinder = ccg->heads * ccg->secs_per_track;
942                         ccg->cylinders = ccg->volume_size / secs_per_cylinder;
943                         pccb->ccb_h.status = CAM_REQ_CMP;
944                         xpt_done(pccb);
945                                         }
946                         break;
947                 case XPT_ENG_INQ:           
948                         TRM_DPRINTF(" XPT_ENG_INQ \n");
949                         pccb->ccb_h.status = CAM_REQ_INVALID;
950                         xpt_done(pccb);
951                         break;
952                 /*
953                  * HBA execute engine request 
954                  * This structure must match SCSIIO size 
955                  */
956                 case XPT_ENG_EXEC:                  
957                         TRM_DPRINTF(" XPT_ENG_EXEC \n");
958                         pccb->ccb_h.status = CAM_REQ_INVALID;
959                         xpt_done(pccb);
960                         break;
961                 /*
962                  * XPT_EN_LUN = 0x30, Enable LUN as a target 
963                  * Target mode structures. 
964                  */
965                 case XPT_EN_LUN:            
966                 /*
967                  * Don't (yet?) support vendor
968                  * specific commands.
969                  */
970                         TRM_DPRINTF(" XPT_EN_LUN \n");
971                         pccb->ccb_h.status = CAM_REQ_INVALID;
972                         xpt_done(pccb);
973                         break;
974                 /*
975                 * Execute target I/O request 
976                 */
977                 case XPT_TARGET_IO:                 
978                 /*
979                  * Don't (yet?) support vendor
980                  * specific commands.
981                  */
982                         TRM_DPRINTF(" XPT_TARGET_IO \n");
983                         pccb->ccb_h.status = CAM_REQ_INVALID;
984                         xpt_done(pccb);
985                         break;
986                 /*
987                  * Accept Host Target Mode CDB 
988                  */
989                 case XPT_ACCEPT_TARGET_IO:      
990                 /*
991                  * Don't (yet?) support vendor
992                  * specific commands.
993                  */
994                         TRM_DPRINTF(" XPT_ACCEPT_TARGET_IO \n");
995                         pccb->ccb_h.status = CAM_REQ_INVALID;
996                         xpt_done(pccb);
997                         break;
998                 /*
999                  * Continue Host Target I/O Connection 
1000                  */
1001                 case XPT_CONT_TARGET_IO:        
1002                 /*
1003                  * Don't (yet?) support vendor
1004                  * specific commands.
1005                  */
1006                         TRM_DPRINTF(" XPT_CONT_TARGET_IO \n");
1007                         pccb->ccb_h.status = CAM_REQ_INVALID;
1008                         xpt_done(pccb);
1009                         break;
1010                 /*
1011                  * Notify Host Target driver of event 
1012                  */
1013                 case XPT_IMMED_NOTIFY:      
1014                         TRM_DPRINTF(" XPT_IMMED_NOTIFY \n");
1015                         pccb->ccb_h.status = CAM_REQ_INVALID;
1016                         xpt_done(pccb);
1017                         break;
1018                 /*
1019                  * Acknowledgement of event
1020                  */
1021                 case XPT_NOTIFY_ACK:        
1022                         TRM_DPRINTF(" XPT_NOTIFY_ACK \n");
1023                         pccb->ccb_h.status = CAM_REQ_INVALID;
1024                         xpt_done(pccb);
1025                         break;
1026                 /*
1027                  * XPT_VUNIQUE = 0x80
1028                  */
1029                 case XPT_VUNIQUE:   
1030                         pccb->ccb_h.status = CAM_REQ_INVALID;
1031                         xpt_done(pccb);
1032                         break;
1033                 default:
1034                         pccb->ccb_h.status = CAM_REQ_INVALID;
1035                         xpt_done(pccb);
1036                         break;
1037         }
1038 }
1039
1040 static void 
1041 trm_poll(struct cam_sim *psim)
1042 {       
1043   
1044 }
1045
1046 static void
1047 trm_ResetDevParam(PACB pACB)
1048 {
1049         PDCB            pDCB, pdcb;
1050         PNVRAMTYPE      pEEpromBuf;
1051         u_int8_t        PeriodIndex;
1052
1053         pDCB = pACB->pLinkDCB;
1054         if (pDCB == NULL)
1055                 return;
1056         pdcb = pDCB;
1057         do {
1058                 pDCB->SyncMode  &= ~(SYNC_NEGO_DONE+ WIDE_NEGO_DONE);
1059                 pDCB->SyncPeriod = 0;
1060                 pDCB->SyncOffset = 0;
1061                 pEEpromBuf = &trm_eepromBuf[pACB->AdapterUnit];
1062                 pDCB->DevMode = 
1063                   pEEpromBuf->NvramTarget[pDCB->TargetID].NvmTarCfg0;
1064                 pDCB->AdpMode = pEEpromBuf->NvramChannelCfg;
1065                 PeriodIndex =
1066                    pEEpromBuf->NvramTarget[pDCB->TargetID].NvmTarPeriod & 0x07;
1067                 pDCB->MaxNegoPeriod = dc395x_trm_clock_period[PeriodIndex];
1068                 if ((pDCB->DevMode & NTC_DO_WIDE_NEGO) && 
1069                     (pACB->Config & HCC_WIDE_CARD))
1070                         pDCB->SyncMode |= WIDE_NEGO_ENABLE;
1071                 pDCB = pDCB->pNextDCB;
1072         }
1073         while (pdcb != pDCB);
1074 }
1075
1076 static void
1077 trm_RecoverSRB(PACB pACB)
1078 {
1079         PDCB            pDCB, pdcb;
1080         PSRB            psrb, psrb2;
1081         u_int16_t       cnt, i;
1082
1083         pDCB = pACB->pLinkDCB;
1084         if (pDCB == NULL)
1085                 return;
1086         pdcb = pDCB;
1087         do {
1088                 cnt = pdcb->GoingSRBCnt;
1089                 psrb = pdcb->pGoingSRB;
1090                 for (i = 0; i < cnt; i++) {
1091                         psrb2 = psrb;
1092                         psrb = psrb->pNextSRB;
1093                         if (pdcb->pWaitingSRB) {
1094                                 psrb2->pNextSRB = pdcb->pWaitingSRB;
1095                                 pdcb->pWaitingSRB = psrb2;
1096                         } else {
1097                                 pdcb->pWaitingSRB = psrb2;
1098                                 pdcb->pWaitLastSRB = psrb2;
1099                                 psrb2->pNextSRB = NULL;
1100                         }
1101                 }
1102                 pdcb->GoingSRBCnt = 0;
1103                 pdcb->pGoingSRB = NULL;
1104                 pdcb->TagMask = 0;
1105                 pdcb = pdcb->pNextDCB;
1106         }
1107         while (pdcb != pDCB);
1108 }
1109
1110 static void
1111 trm_reset(PACB pACB)
1112 {
1113         u_int16_t       i;
1114
1115         TRM_DPRINTF("trm: RESET");
1116         crit_enter();
1117         trm_reg_write8(0x00, TRMREG_DMA_INTEN);
1118         trm_reg_write8(0x00, TRMREG_SCSI_INTEN);
1119
1120         trm_ResetSCSIBus(pACB);
1121         for (i = 0; i < 500; i++)
1122                 DELAY(1000);
1123         trm_reg_write8(0x7F, TRMREG_SCSI_INTEN); 
1124         /* Enable DMA interrupt */
1125         trm_reg_write8(EN_SCSIINTR, TRMREG_DMA_INTEN);
1126         /* Clear DMA FIFO */
1127         trm_reg_write8(CLRXFIFO, TRMREG_DMA_CONTROL);
1128         /* Clear SCSI FIFO */
1129         trm_reg_write16(DO_CLRFIFO,TRMREG_SCSI_CONTROL);
1130         trm_ResetDevParam(pACB);
1131         trm_DoingSRB_Done(pACB);
1132         pACB->pActiveDCB = NULL;
1133         pACB->ACBFlag = 0;/* RESET_DETECT, RESET_DONE ,RESET_DEV */
1134         trm_DoWaitingSRB(pACB);
1135         /* Tell the XPT layer that a bus reset occured    */
1136         if (pACB->ppath != NULL)
1137                 xpt_async(AC_BUS_RESET, pACB->ppath, NULL);
1138         crit_exit();
1139         return;
1140 }
1141
1142 static u_int16_t
1143 trm_StartSCSI(PACB pACB, PDCB pDCB, PSRB pSRB)
1144 {
1145         u_int16_t       return_code;
1146         u_int8_t        tag_number, scsicommand, i,command,identify_message;
1147         u_int8_t *      ptr;
1148         u_long          tag_mask;
1149         union  ccb      *pccb;
1150         struct ccb_scsiio *pcsio;
1151
1152         pccb  = pSRB->pccb;
1153         pcsio = &pccb->csio;
1154         pSRB->TagNumber = 31;
1155
1156         trm_reg_write8(pACB->AdaptSCSIID, TRMREG_SCSI_HOSTID);
1157         trm_reg_write8(pDCB->TargetID, TRMREG_SCSI_TARGETID);
1158         trm_reg_write8(pDCB->SyncPeriod, TRMREG_SCSI_SYNC);
1159         trm_reg_write8(pDCB->SyncOffset, TRMREG_SCSI_OFFSET);
1160         pSRB->ScsiPhase = PH_BUS_FREE;/* initial phase */
1161         /* Flush FIFO */
1162         trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
1163
1164         identify_message = pDCB->IdentifyMsg;
1165
1166         if ((pSRB->CmdBlock[0] == INQUIRY) ||
1167             (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
1168             (pSRB->SRBFlag & AUTO_REQSENSE)) {
1169                 if (((pDCB->SyncMode & WIDE_NEGO_ENABLE) &&
1170                       !(pDCB->SyncMode & WIDE_NEGO_DONE)) \
1171                 || ((pDCB->SyncMode & SYNC_NEGO_ENABLE) &&
1172                   !(pDCB->SyncMode & SYNC_NEGO_DONE))) {
1173                         if (!(pDCB->IdentifyMsg & 7) ||
1174                             (pSRB->CmdBlock[0] != INQUIRY)) {
1175                                 scsicommand = SCMD_SEL_ATNSTOP;
1176                                 pSRB->SRBState = SRB_MSGOUT;
1177                                 goto polling;
1178                         }
1179                 }
1180         /* 
1181         * Send identify message 
1182         */
1183                 trm_reg_write8((identify_message & 0xBF) ,TRMREG_SCSI_FIFO); 
1184                 scsicommand = SCMD_SEL_ATN;
1185                 pSRB->SRBState = SRB_START_;
1186         } else {
1187                 /* not inquiry,request sense,auto request sense */
1188                 /* 
1189                  * Send identify message        
1190                  */
1191                 trm_reg_write8(identify_message,TRMREG_SCSI_FIFO);
1192                 scsicommand = SCMD_SEL_ATN;
1193                 pSRB->SRBState = SRB_START_;
1194                 if (pDCB->SyncMode & EN_TAG_QUEUING) {
1195                   /* Send Tag message */
1196                   /* 
1197                    * Get tag id
1198                    */
1199                         tag_mask = 1;
1200                         tag_number = 0;
1201                         while (tag_mask & pDCB->TagMask) {
1202                                 tag_mask = tag_mask << 1;
1203                                 tag_number++;
1204                         }
1205                         /* 
1206                          * Send Tag id
1207                          */
1208                         trm_reg_write8(MSG_SIMPLE_QTAG, TRMREG_SCSI_FIFO);
1209                         trm_reg_write8(tag_number, TRMREG_SCSI_FIFO);
1210                         pDCB->TagMask |= tag_mask;
1211                         pSRB->TagNumber = tag_number;
1212                         scsicommand = SCMD_SEL_ATN3;
1213                         pSRB->SRBState = SRB_START_;
1214                 }
1215         }
1216 polling:
1217         /*
1218          *       Send CDB ..command block .........                     
1219          */
1220         if (pSRB->SRBFlag & AUTO_REQSENSE) {
1221                 trm_reg_write8(REQUEST_SENSE, TRMREG_SCSI_FIFO);
1222                 trm_reg_write8((pDCB->IdentifyMsg << 5), TRMREG_SCSI_FIFO);
1223                 trm_reg_write8(0, TRMREG_SCSI_FIFO);
1224                 trm_reg_write8(0, TRMREG_SCSI_FIFO);
1225                 trm_reg_write8(pcsio->sense_len, TRMREG_SCSI_FIFO);
1226                 trm_reg_write8(0, TRMREG_SCSI_FIFO);
1227         } else {
1228                 ptr = (u_int8_t *) pSRB->CmdBlock;
1229                 for (i = 0; i < pSRB->ScsiCmdLen ; i++) {
1230                         command = *ptr++;
1231                         trm_reg_write8(command,TRMREG_SCSI_FIFO);
1232                 }
1233         }
1234         if (trm_reg_read16(TRMREG_SCSI_STATUS) & SCSIINTERRUPT) { 
1235             /* 
1236              * If trm_StartSCSI return 1 :
1237              * current interrupt status is interrupt disreenable 
1238              * It's said that SCSI processor has more one SRB need to do,
1239              * SCSI processor has been occupied by one SRB.
1240              */
1241                 pSRB->SRBState = SRB_READY;
1242                 pDCB->TagMask &= ~(1 << pSRB->TagNumber);
1243                 return_code = 1;
1244         } else { 
1245           /* 
1246            * If trm_StartSCSI return 0 :
1247            * current interrupt status is interrupt enable 
1248            * It's said that SCSI processor is unoccupied 
1249            */
1250                 pSRB->ScsiPhase  = SCSI_NOP1; /* SCSI bus free Phase */
1251                 pACB->pActiveDCB = pDCB;
1252                 pDCB->pActiveSRB = pSRB;
1253                 return_code = 0;
1254                 trm_reg_write16(DO_DATALATCH | DO_HWRESELECT, 
1255                     TRMREG_SCSI_CONTROL);/* it's important for atn stop*/
1256                 /*
1257                  * SCSI cammand 
1258                  */
1259                 trm_reg_write8(scsicommand,TRMREG_SCSI_COMMAND);
1260         }
1261         return (return_code);   
1262 }
1263
1264 static void 
1265 trm_Interrupt(vpACB)
1266 void *vpACB;
1267 {
1268         PACB            pACB;
1269         PDCB            pDCB;
1270         PSRB            pSRB;
1271         u_int16_t       phase;
1272         void            (*stateV)(PACB, PSRB, u_int8_t *);
1273         u_int8_t        scsi_status=0, scsi_intstatus;
1274
1275         pACB = vpACB;
1276
1277         if (pACB == NULL) {
1278                 TRM_DPRINTF("trm_Interrupt: pACB NULL return......");
1279                 return;
1280         }
1281
1282         scsi_status = trm_reg_read16(TRMREG_SCSI_STATUS);
1283         if (!(scsi_status & SCSIINTERRUPT)) {
1284                 TRM_DPRINTF("trm_Interrupt: TRMREG_SCSI_STATUS scsi_status = NULL ,return......");
1285                 return;
1286         }
1287         TRM_DPRINTF("scsi_status=%2x,",scsi_status);
1288
1289         scsi_intstatus = trm_reg_read8(TRMREG_SCSI_INTSTATUS);
1290
1291         TRM_DPRINTF("scsi_intstatus=%2x,",scsi_intstatus);
1292
1293         if (scsi_intstatus & (INT_SELTIMEOUT | INT_DISCONNECT)) {
1294                 trm_Disconnect(pACB);
1295                 return;
1296         }
1297
1298         if (scsi_intstatus & INT_RESELECTED) {
1299                 trm_Reselect(pACB);
1300                 return;
1301         }
1302         if (scsi_intstatus & INT_SCSIRESET) {
1303                 trm_ScsiRstDetect(pACB);
1304                 return;
1305         }
1306
1307         if (scsi_intstatus & (INT_BUSSERVICE | INT_CMDDONE)) {
1308                 pDCB = pACB->pActiveDCB;
1309                 pSRB = pDCB->pActiveSRB;
1310                 if (pDCB) {
1311                         if (pDCB->DCBFlag & ABORT_DEV_)
1312                                 trm_EnableMsgOutAbort1(pACB, pSRB);
1313                 }
1314                 phase = (u_int16_t) pSRB->ScsiPhase;  /* phase: */
1315                 stateV = (void *) trm_SCSI_phase0[phase];
1316                 stateV(pACB, pSRB, &scsi_status);
1317                 pSRB->ScsiPhase = scsi_status & PHASEMASK; 
1318                 /* phase:0,1,2,3,4,5,6,7 */
1319                 phase = (u_int16_t) scsi_status & PHASEMASK;       
1320                 stateV = (void *) trm_SCSI_phase1[phase];
1321                 stateV(pACB, pSRB, &scsi_status);  
1322         }
1323 }
1324
1325 static void
1326 trm_MsgOutPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1327 {
1328
1329         if (pSRB->SRBState & (SRB_UNEXPECT_RESEL+SRB_ABORT_SENT))
1330                 *pscsi_status = PH_BUS_FREE;
1331         /*.. initial phase*/
1332 }
1333
1334 static void
1335 trm_MsgOutPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1336 {
1337         u_int8_t        bval;
1338         u_int16_t       i, cnt;
1339         u_int8_t *      ptr;
1340         PDCB            pDCB;
1341
1342         trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
1343         pDCB = pACB->pActiveDCB;
1344         if (!(pSRB->SRBState & SRB_MSGOUT)) {
1345                 cnt = pSRB->MsgCnt;
1346                 if (cnt) {
1347                         ptr = (u_int8_t *) pSRB->MsgOutBuf;
1348                         for (i = 0; i < cnt; i++) {
1349                                 trm_reg_write8(*ptr, TRMREG_SCSI_FIFO);
1350                                 ptr++;
1351                         }
1352                         pSRB->MsgCnt = 0;
1353                         if ((pDCB->DCBFlag & ABORT_DEV_) &&
1354                             (pSRB->MsgOutBuf[0] == MSG_ABORT)) {
1355                                 pSRB->SRBState = SRB_ABORT_SENT;
1356                         }
1357                 } else {
1358                         bval = MSG_ABORT;       
1359                         if ((pSRB->CmdBlock[0] == INQUIRY) ||
1360                                         (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
1361                                         (pSRB->SRBFlag & AUTO_REQSENSE)) {
1362                                 if (pDCB->SyncMode & SYNC_NEGO_ENABLE) {
1363                                         goto  mop1;
1364                                 }
1365                         }
1366                         trm_reg_write8(bval, TRMREG_SCSI_FIFO);
1367                 }
1368         } else {
1369 mop1:   /* message out phase */
1370                 if (!(pSRB->SRBState & SRB_DO_WIDE_NEGO)
1371                     && (pDCB->SyncMode & WIDE_NEGO_ENABLE)) {
1372                   /*
1373                    * WIDE DATA TRANSFER REQUEST code (03h)
1374                    */
1375                         pDCB->SyncMode &= ~(SYNC_NEGO_DONE | EN_ATN_STOP);
1376                         trm_reg_write8((pDCB->IdentifyMsg & 0xBF),
1377                             TRMREG_SCSI_FIFO); 
1378                         trm_reg_write8(MSG_EXTENDED,TRMREG_SCSI_FIFO);
1379                         /* (01h) */
1380                         trm_reg_write8(2,TRMREG_SCSI_FIFO);     
1381                         /* Message length (02h) */
1382                         trm_reg_write8(3,TRMREG_SCSI_FIFO);
1383                         /* wide data xfer (03h) */
1384                         trm_reg_write8(1,TRMREG_SCSI_FIFO);
1385                         /* width:0(8bit),1(16bit),2(32bit) */
1386                         pSRB->SRBState |= SRB_DO_WIDE_NEGO; 
1387                 } else if (!(pSRB->SRBState & SRB_DO_SYNC_NEGO) 
1388                     && (pDCB->SyncMode & SYNC_NEGO_ENABLE)) {
1389                   /*
1390                    * SYNCHRONOUS DATA TRANSFER REQUEST code (01h)
1391                    */
1392                         if (!(pDCB->SyncMode & WIDE_NEGO_DONE))
1393                                 trm_reg_write8((pDCB->IdentifyMsg & 0xBF),
1394                                                 TRMREG_SCSI_FIFO);
1395                         trm_reg_write8(MSG_EXTENDED,TRMREG_SCSI_FIFO);
1396                   /* (01h) */
1397                         trm_reg_write8(3,TRMREG_SCSI_FIFO); 
1398                   /* Message length (03h) */
1399                         trm_reg_write8(1,TRMREG_SCSI_FIFO);
1400                   /* SYNCHRONOUS DATA TRANSFER REQUEST code (01h) */
1401                         trm_reg_write8(pDCB->MaxNegoPeriod,TRMREG_SCSI_FIFO);
1402                   /* Transfer peeriod factor */
1403                         trm_reg_write8(SYNC_NEGO_OFFSET,TRMREG_SCSI_FIFO); 
1404                   /* REQ/ACK offset */
1405                         pSRB->SRBState |= SRB_DO_SYNC_NEGO;
1406                 }
1407         }
1408         trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
1409         /* it's important for atn stop */
1410         /*
1411          * SCSI cammand 
1412          */
1413         trm_reg_write8(SCMD_FIFO_OUT, TRMREG_SCSI_COMMAND);
1414 }
1415
1416 static void 
1417 trm_CommandPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1418 {
1419
1420 }
1421
1422 static void 
1423 trm_CommandPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1424 {
1425         PDCB                    pDCB;
1426         u_int8_t *              ptr;
1427         u_int16_t               i, cnt;
1428         union  ccb              *pccb;
1429         struct ccb_scsiio       *pcsio;
1430
1431         pccb  = pSRB->pccb;
1432         pcsio = &pccb->csio;
1433
1434         trm_reg_write16(DO_CLRATN | DO_CLRFIFO , TRMREG_SCSI_CONTROL);
1435         if (!(pSRB->SRBFlag & AUTO_REQSENSE)) {
1436                 cnt = (u_int16_t) pSRB->ScsiCmdLen;
1437                 ptr = (u_int8_t *) pSRB->CmdBlock;
1438                 for (i = 0; i < cnt; i++) {
1439                         trm_reg_write8(*ptr, TRMREG_SCSI_FIFO);
1440                         ptr++;
1441                 }
1442         } else {
1443                 trm_reg_write8(REQUEST_SENSE, TRMREG_SCSI_FIFO);
1444                 pDCB = pACB->pActiveDCB;
1445                 /* target id */
1446                 trm_reg_write8((pDCB->IdentifyMsg << 5), TRMREG_SCSI_FIFO);
1447                 trm_reg_write8(0, TRMREG_SCSI_FIFO);
1448                 trm_reg_write8(0, TRMREG_SCSI_FIFO);
1449                 /* sizeof(struct scsi_sense_data) */
1450                 trm_reg_write8(pcsio->sense_len, TRMREG_SCSI_FIFO);
1451                 trm_reg_write8(0, TRMREG_SCSI_FIFO);
1452         }
1453         pSRB->SRBState = SRB_COMMAND;
1454         trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
1455         /* it's important for atn stop*/
1456         /*
1457          * SCSI cammand 
1458          */
1459         trm_reg_write8(SCMD_FIFO_OUT, TRMREG_SCSI_COMMAND);
1460 }
1461
1462 static void
1463 trm_DataOutPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1464 {
1465         PDCB            pDCB;
1466         u_int8_t        TempDMAstatus,SGIndexTemp;
1467         u_int16_t       scsi_status;
1468         PSEG            pseg;
1469         u_long          TempSRBXferredLength,dLeftCounter=0;
1470
1471         pDCB = pSRB->pSRBDCB;
1472         scsi_status = *pscsi_status;
1473
1474         if (!(pSRB->SRBState & SRB_XFERPAD)) {
1475                 if (scsi_status & PARITYERROR)
1476                         pSRB->SRBStatus |= PARITY_ERROR;
1477                 if (!(scsi_status & SCSIXFERDONE)) {
1478                   /*
1479                    * when data transfer from DMA FIFO to SCSI FIFO
1480                    * if there was some data left in SCSI FIFO
1481                    */
1482                         dLeftCounter = (u_long) 
1483                           (trm_reg_read8(TRMREG_SCSI_FIFOCNT) & 0x1F);
1484                         if (pDCB->SyncPeriod & WIDE_SYNC) {
1485                           /*
1486                            * if WIDE scsi SCSI FIFOCNT unit is word
1487                            * so need to * 2
1488                            */
1489                                 dLeftCounter <<= 1;
1490                         }
1491                 }
1492                 /*
1493                  * caculate all the residue data that not yet tranfered
1494                  * SCSI transfer counter + left in SCSI FIFO data
1495                  *
1496                  * .....TRM_SCSI_COUNTER (24bits)
1497                  * The counter always decrement by one for every SCSI byte 
1498                  *transfer.
1499                  * .....TRM_SCSI_FIFOCNT (5bits)
1500                  * The counter is SCSI FIFO offset counter
1501                  */
1502                 dLeftCounter += trm_reg_read32(TRMREG_SCSI_COUNTER);
1503                 if (dLeftCounter == 1) {
1504                         dLeftCounter = 0;
1505                         trm_reg_write16(DO_CLRFIFO,TRMREG_SCSI_CONTROL);
1506                 }
1507                 if ((dLeftCounter == 0) || 
1508                     (scsi_status & SCSIXFERCNT_2_ZERO)) {   
1509                         TempDMAstatus = trm_reg_read8(TRMREG_DMA_STATUS);
1510                         while (!(TempDMAstatus & DMAXFERCOMP)) {
1511                                 TempDMAstatus = 
1512                                   trm_reg_read8(TRMREG_DMA_STATUS);
1513                         }
1514                         pSRB->SRBTotalXferLength = 0;
1515                 } else {
1516                   /* Update SG list             */
1517                   /*
1518                    * if transfer not yet complete
1519                    * there were some data residue in SCSI FIFO or
1520                    * SCSI transfer counter not empty
1521                    */
1522                         if (pSRB->SRBTotalXferLength != dLeftCounter) {
1523                           /*
1524                            * data that had transferred length
1525                            */
1526                                 TempSRBXferredLength = 
1527                                   pSRB->SRBTotalXferLength - dLeftCounter;
1528                                 /*
1529                                  * next time to be transferred length
1530                                  */
1531                                 pSRB->SRBTotalXferLength = dLeftCounter;
1532                                 /*
1533                                  * parsing from last time disconnect SRBSGIndex
1534                                  */
1535                                 pseg = 
1536                                   pSRB->SRBSGListPointer + pSRB->SRBSGIndex;
1537                                 for (SGIndexTemp = pSRB->SRBSGIndex;
1538                                     SGIndexTemp < pSRB->SRBSGCount; 
1539                                     SGIndexTemp++) {
1540                                         /* 
1541                                          * find last time which SG transfer be 
1542                                          * disconnect 
1543                                          */
1544                                         if (TempSRBXferredLength >= 
1545                                             pseg->length) 
1546                                                 TempSRBXferredLength -= 
1547                                                   pseg->length;
1548                                         else {
1549                                           /*
1550                                            * update last time disconnected SG 
1551                                            * list
1552                                            */
1553                                                 pseg->length -= 
1554                                                   TempSRBXferredLength; 
1555                                                 /* residue data length  */
1556                                                 pseg->address += 
1557                                                   TempSRBXferredLength;
1558                                                 /* residue data pointer */
1559                                                 pSRB->SRBSGIndex = SGIndexTemp;
1560                                                 break;
1561                                         }
1562                                         pseg++;
1563                                 }
1564                         }
1565                 }
1566         }
1567         trm_reg_write8(STOPDMAXFER ,TRMREG_DMA_CONTROL);
1568 }
1569
1570
1571 static void
1572 trm_DataOutPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1573 {
1574         u_int16_t       ioDir;
1575         /*
1576          * do prepare befor transfer when data out phase
1577          */
1578
1579         ioDir = XFERDATAOUT;
1580         trm_DataIO_transfer(pACB, pSRB, ioDir);
1581 }
1582
1583 static void 
1584 trm_DataInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1585 {
1586         u_int8_t        bval,SGIndexTemp;
1587         u_int16_t       scsi_status;
1588         PSEG            pseg;
1589         u_long          TempSRBXferredLength,dLeftCounter = 0;
1590
1591         scsi_status = *pscsi_status;
1592         if (!(pSRB->SRBState & SRB_XFERPAD)) {
1593                 if (scsi_status & PARITYERROR)
1594                         pSRB->SRBStatus |= PARITY_ERROR;
1595                 dLeftCounter += trm_reg_read32(TRMREG_SCSI_COUNTER);
1596                 if ((dLeftCounter == 0) || (scsi_status & SCSIXFERCNT_2_ZERO)) {
1597                         bval = trm_reg_read8(TRMREG_DMA_STATUS);
1598                         while (!(bval & DMAXFERCOMP))
1599                                 bval = trm_reg_read8(TRMREG_DMA_STATUS);
1600                         pSRB->SRBTotalXferLength = 0;
1601                 } else {  
1602                   /*
1603                    * parsing the case:
1604                    * when a transfer not yet complete 
1605                    * but be disconnected by uper layer
1606                    * if transfer not yet complete
1607                    * there were some data residue in SCSI FIFO or
1608                    * SCSI transfer counter not empty
1609                    */
1610                   if (pSRB->SRBTotalXferLength != dLeftCounter) {
1611                                 /*
1612                                  * data that had transferred length
1613                                  */
1614                         TempSRBXferredLength = 
1615                           pSRB->SRBTotalXferLength - dLeftCounter;
1616                                 /*
1617                                  * next time to be transferred length
1618                                  */
1619                         pSRB->SRBTotalXferLength = dLeftCounter;
1620                                 /*
1621                                  * parsing from last time disconnect SRBSGIndex
1622                                  */
1623                         pseg = pSRB->SRBSGListPointer + pSRB->SRBSGIndex;
1624                         for (SGIndexTemp = pSRB->SRBSGIndex; 
1625                             SGIndexTemp < pSRB->SRBSGCount;
1626                             SGIndexTemp++) {
1627                           /* 
1628                            * find last time which SG transfer be disconnect 
1629                            */
1630                                 if (TempSRBXferredLength >= pseg->length)
1631                                         TempSRBXferredLength -= pseg->length;
1632                                 else {
1633                                   /*
1634                                    * update last time disconnected SG list
1635                                    */
1636                                         pseg->length -= TempSRBXferredLength;
1637                                         /* residue data length  */
1638                                         pseg->address += TempSRBXferredLength;
1639                                         /* residue data pointer */
1640                                         pSRB->SRBSGIndex = SGIndexTemp;
1641                                         break;
1642                                 } 
1643                                 pseg++;
1644                         }
1645                   }
1646                 }
1647         }
1648 }
1649
1650 static void
1651 trm_DataInPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1652 {
1653         u_int16_t       ioDir;
1654         /*
1655          * do prepare befor transfer when data in phase
1656          */
1657         
1658         ioDir = XFERDATAIN;
1659         trm_DataIO_transfer(pACB, pSRB, ioDir);
1660 }
1661
1662 static void
1663 trm_DataIO_transfer(PACB pACB, PSRB pSRB, u_int16_t ioDir)
1664 {
1665         u_int8_t        bval;
1666         PDCB            pDCB;
1667
1668         pDCB = pSRB->pSRBDCB;
1669         if (pSRB->SRBSGIndex < pSRB->SRBSGCount) {
1670                 if (pSRB->SRBTotalXferLength != 0) {
1671                         pSRB->SRBSGPhyAddr = vtophys(pSRB->SRBSGListPointer);
1672                         /* 
1673                          * load what physical address of Scatter/Gather list 
1674                          table want to be transfer
1675                          */
1676                         pSRB->SRBState = SRB_DATA_XFER;
1677                         trm_reg_write32(0, TRMREG_DMA_XHIGHADDR);
1678                         trm_reg_write32(
1679                             (pSRB->SRBSGPhyAddr + 
1680                              ((u_long)pSRB->SRBSGIndex << 3)),
1681                             TRMREG_DMA_XLOWADDR);
1682                         /*
1683                          * load how many bytes in the Scatter/Gather 
1684                          * list table 
1685                          */
1686                         trm_reg_write32(
1687                             ((u_long)(pSRB->SRBSGCount - pSRB->SRBSGIndex) << 3),
1688                             TRMREG_DMA_XCNT);                   
1689                         /*
1690                          * load total transfer length (24bits) max value
1691                          * 16Mbyte 
1692                          */
1693                         trm_reg_write32(pSRB->SRBTotalXferLength,
1694                             TRMREG_SCSI_COUNTER);
1695                         /* Start DMA transfer */
1696                         trm_reg_write16(ioDir, TRMREG_DMA_COMMAND);
1697                         /* Start SCSI transfer */
1698                         trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
1699                         /* it's important for atn stop */
1700                         /*
1701                          * SCSI cammand 
1702                          */
1703                         bval = (ioDir == XFERDATAOUT) ?
1704                           SCMD_DMA_OUT : SCMD_DMA_IN;
1705                         trm_reg_write8(bval, TRMREG_SCSI_COMMAND);
1706                 } else {
1707                   /* xfer pad */
1708                         if (pSRB->SRBSGCount) {
1709                                 pSRB->AdaptStatus = H_OVER_UNDER_RUN;
1710                                 pSRB->SRBStatus |= OVER_RUN;
1711                         }
1712                         if (pDCB->SyncPeriod & WIDE_SYNC)
1713                                 trm_reg_write32(2,TRMREG_SCSI_COUNTER);
1714                         else
1715                                 trm_reg_write32(1,TRMREG_SCSI_COUNTER);
1716                         if (ioDir == XFERDATAOUT)
1717                                 trm_reg_write16(0, TRMREG_SCSI_FIFO);
1718                         else
1719                                 trm_reg_read16(TRMREG_SCSI_FIFO);
1720                         pSRB->SRBState |= SRB_XFERPAD;
1721                         trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
1722                         /* it's important for atn stop */
1723                         /*
1724                          * SCSI cammand 
1725                          */
1726                         bval = (ioDir == XFERDATAOUT) ? 
1727                           SCMD_FIFO_OUT : SCMD_FIFO_IN;
1728                         trm_reg_write8(bval, TRMREG_SCSI_COMMAND);
1729                 }
1730         }
1731 }
1732
1733 static void
1734 trm_StatusPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1735 {
1736
1737         pSRB->TargetStatus = trm_reg_read8(TRMREG_SCSI_FIFO);
1738         pSRB->SRBState = SRB_COMPLETED;
1739         *pscsi_status = PH_BUS_FREE;  
1740         /*.. initial phase*/
1741         trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
1742         /* it's important for atn stop */
1743         /*
1744          * SCSI cammand 
1745          */
1746         trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
1747 }
1748
1749
1750
1751 static void
1752 trm_StatusPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1753 {
1754
1755         if (trm_reg_read16(TRMREG_DMA_COMMAND) & 0x0001) {
1756                 if (!(trm_reg_read8(TRMREG_SCSI_FIFOCNT) & 0x40))
1757                         trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
1758                 if (!(trm_reg_read16(TRMREG_DMA_FIFOCNT) & 0x8000))
1759                         trm_reg_write8(CLRXFIFO, TRMREG_DMA_CONTROL);
1760         } else {
1761                 if (!(trm_reg_read16(TRMREG_DMA_FIFOCNT) & 0x8000))
1762                         trm_reg_write8(CLRXFIFO, TRMREG_DMA_CONTROL);
1763                 if (!(trm_reg_read8(TRMREG_SCSI_FIFOCNT) & 0x40))
1764                         trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
1765         }
1766         pSRB->SRBState = SRB_STATUS;
1767         trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
1768         /* it's important for atn stop */
1769         /*
1770          * SCSI cammand 
1771          */
1772         trm_reg_write8(SCMD_COMP, TRMREG_SCSI_COMMAND);
1773 }
1774
1775 /*
1776  *scsiiom                
1777  *       trm_MsgInPhase0: one of trm_SCSI_phase0[] vectors
1778  *            stateV = (void *) trm_SCSI_phase0[phase]
1779  *                         if phase =7    
1780  * extended message codes:
1781  *
1782  *   code        description
1783  *
1784  *    02h        Reserved
1785  *    00h        MODIFY DATA  POINTER
1786  *    01h        SYNCHRONOUS DATA TRANSFER REQUEST
1787  *    03h        WIDE DATA TRANSFER REQUEST
1788  * 04h - 7Fh     Reserved
1789  * 80h - FFh     Vendor specific  
1790  *                      
1791  */
1792
1793 static void
1794 trm_MsgInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1795 {
1796         u_int8_t        message_in_code,bIndex,message_in_tag_id;
1797         PDCB            pDCB;
1798         PSRB            pSRBTemp;
1799
1800         pDCB = pACB->pActiveDCB;
1801
1802         message_in_code = trm_reg_read8(TRMREG_SCSI_FIFO);
1803         if (!(pSRB->SRBState & SRB_EXTEND_MSGIN)) {
1804                 if (message_in_code == MSG_DISCONNECT) {
1805                         pSRB->SRBState = SRB_DISCONNECT;
1806                         goto  min6;
1807                 } else if (message_in_code == MSG_SAVE_PTR) {
1808                         goto  min6;
1809                 } else if ((message_in_code == MSG_EXTENDED) ||
1810                     ((message_in_code >= MSG_SIMPLE_QTAG) &&
1811                      (message_in_code <= MSG_ORDER_QTAG))) {
1812                         pSRB->SRBState |= SRB_EXTEND_MSGIN;
1813                         pSRB->MsgInBuf[0] = message_in_code;
1814                         /* extended message      (01h) */
1815                         pSRB->MsgCnt = 1;
1816                         pSRB->pMsgPtr = &pSRB->MsgInBuf[1];
1817                         /* extended message length (n) */
1818                         goto  min6;
1819                 } else if (message_in_code == MSG_REJECT_) {
1820                         /* Reject message */
1821                         if (pDCB->SyncMode & WIDE_NEGO_ENABLE) {
1822                           /* do wide nego reject */
1823                                 pDCB = pSRB->pSRBDCB;
1824                                 pDCB->SyncMode |= WIDE_NEGO_DONE;
1825                                 pDCB->SyncMode &= ~(SYNC_NEGO_DONE | 
1826                                     EN_ATN_STOP | WIDE_NEGO_ENABLE);
1827                                 pSRB->SRBState &= ~(SRB_DO_WIDE_NEGO+SRB_MSGIN);
1828                                 if ((pDCB->SyncMode & SYNC_NEGO_ENABLE) 
1829                                     && !(pDCB->SyncMode & SYNC_NEGO_DONE)) {   
1830                                   /* Set ATN, in case ATN was clear */
1831                                         pSRB->SRBState |= SRB_MSGOUT;
1832                                         trm_reg_write16(
1833                                             DO_SETATN,
1834                                             TRMREG_SCSI_CONTROL);
1835                                 } else {   
1836                                   /* Clear ATN */
1837                                         trm_reg_write16(
1838                                             DO_CLRATN,
1839                                             TRMREG_SCSI_CONTROL);
1840                                 }
1841                         } else if (pDCB->SyncMode & SYNC_NEGO_ENABLE) { 
1842                           /* do sync nego reject */
1843                                 trm_reg_write16(DO_CLRATN,TRMREG_SCSI_CONTROL);
1844                                 if (pSRB->SRBState & SRB_DO_SYNC_NEGO) {
1845                                         pDCB = pSRB->pSRBDCB;
1846                                         pDCB->SyncMode &= 
1847                                           ~(SYNC_NEGO_ENABLE+SYNC_NEGO_DONE); 
1848                                         pDCB->SyncPeriod = 0;
1849                                         pDCB->SyncOffset = 0;
1850                                         goto  re_prog;
1851                                 }
1852                         }
1853                         goto  min6;
1854                 } else if (message_in_code == MSG_IGNOREWIDE) {
1855                         trm_reg_write32(1, TRMREG_SCSI_COUNTER);
1856                         trm_reg_read8(TRMREG_SCSI_FIFO);
1857                         goto  min6;
1858                 } else {
1859                   /* Restore data pointer message */
1860                   /* Save data pointer message    */
1861                   /* Completion message           */
1862                   /* NOP message                  */
1863                         goto  min6;
1864                 }
1865         } else {        
1866           /* 
1867            * Parsing incomming extented messages 
1868            */
1869                 *pSRB->pMsgPtr = message_in_code;
1870                 pSRB->MsgCnt++;
1871                 pSRB->pMsgPtr++;
1872                 TRM_DPRINTF("pSRB->MsgInBuf[0]=%2x \n ",pSRB->MsgInBuf[0]);
1873                 TRM_DPRINTF("pSRB->MsgInBuf[1]=%2x \n ",pSRB->MsgInBuf[1]);
1874                 TRM_DPRINTF("pSRB->MsgInBuf[2]=%2x \n ",pSRB->MsgInBuf[2]);
1875                 TRM_DPRINTF("pSRB->MsgInBuf[3]=%2x \n ",pSRB->MsgInBuf[3]);
1876                 TRM_DPRINTF("pSRB->MsgInBuf[4]=%2x \n ",pSRB->MsgInBuf[4]);
1877                 if ((pSRB->MsgInBuf[0] >= MSG_SIMPLE_QTAG)
1878                     && (pSRB->MsgInBuf[0] <= MSG_ORDER_QTAG)) {
1879                   /*
1880                    * is QUEUE tag message :
1881                    *
1882                    * byte 0:
1883                    * HEAD    QUEUE TAG (20h)
1884                    * ORDERED QUEUE TAG (21h)
1885                    * SIMPLE  QUEUE TAG (22h)
1886                    * byte 1:
1887                    * Queue tag (00h - FFh)
1888                    */
1889                         if (pSRB->MsgCnt == 2) {
1890                                 pSRB->SRBState = 0;
1891                                 message_in_tag_id = pSRB->MsgInBuf[1];
1892                                 pSRB = pDCB->pGoingSRB;
1893                                 pSRBTemp = pDCB->pGoingLastSRB;
1894                                 if (pSRB) {
1895                                         for (;;) {
1896                                                 if (pSRB->TagNumber != 
1897                                                     message_in_tag_id) {
1898                                                         if (pSRB == pSRBTemp) {
1899                                                                 goto  mingx0;
1900                                                         }
1901                                                         pSRB = pSRB->pNextSRB;
1902                                                 } else
1903                                                         break;
1904                                         }
1905                                         if (pDCB->DCBFlag & ABORT_DEV_) {
1906                                                 pSRB->SRBState = SRB_ABORT_SENT;
1907                                                 trm_EnableMsgOutAbort1(
1908                                                     pACB, pSRB);
1909                                         }
1910                                         if (!(pSRB->SRBState & SRB_DISCONNECT))
1911                                                 goto  mingx0;
1912                                         pDCB->pActiveSRB = pSRB;
1913                                         pSRB->SRBState = SRB_DATA_XFER;
1914                                 } else {
1915 mingx0:
1916                                         pSRB = pACB->pTmpSRB;
1917                                         pSRB->SRBState = SRB_UNEXPECT_RESEL;
1918                                         pDCB->pActiveSRB = pSRB;
1919                                         pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;
1920                                         trm_EnableMsgOutAbort2(
1921                                             pACB,
1922                                             pSRB);
1923                                 }
1924                         }
1925                 } else if ((pSRB->MsgInBuf[0] == MSG_EXTENDED) &&
1926                     (pSRB->MsgInBuf[2] == 3) && (pSRB->MsgCnt == 4)) {
1927                   /*
1928                    * is Wide data xfer Extended message :
1929                    * ======================================
1930                    * WIDE DATA TRANSFER REQUEST
1931                    * ======================================
1932                    * byte 0 :  Extended message (01h)
1933                    * byte 1 :  Extended message length (02h)
1934                    * byte 2 :  WIDE DATA TRANSFER code (03h)
1935                    * byte 3 :  Transfer width exponent 
1936                    */
1937                         pDCB = pSRB->pSRBDCB;
1938                         pSRB->SRBState &= ~(SRB_EXTEND_MSGIN+SRB_DO_WIDE_NEGO);
1939                         if ((pSRB->MsgInBuf[1] != 2)) {
1940                           /* Length is wrong, reject it  */
1941                                 pDCB->SyncMode &=
1942                                   ~(WIDE_NEGO_ENABLE+WIDE_NEGO_DONE); 
1943                                 pSRB->MsgCnt = 1;
1944                                 pSRB->MsgInBuf[0] = MSG_REJECT_;
1945                                 trm_reg_write16(DO_SETATN, TRMREG_SCSI_CONTROL);
1946                                 goto  min6;
1947                         }
1948                         if (pDCB->SyncMode & WIDE_NEGO_ENABLE) {                
1949                           /* Do wide negoniation */
1950                                 if (pSRB->MsgInBuf[3] > 2) {
1951                                   /* > 32 bit   */
1952                                   /* reject_msg: */
1953                                         pDCB->SyncMode &= 
1954                                           ~(WIDE_NEGO_ENABLE+WIDE_NEGO_DONE); 
1955                                         pSRB->MsgCnt = 1;
1956                                         pSRB->MsgInBuf[0] = MSG_REJECT_;
1957                                         trm_reg_write16(DO_SETATN,
1958                                             TRMREG_SCSI_CONTROL);
1959                                         goto  min6;
1960                                 }
1961                                 if (pSRB->MsgInBuf[3] == 2) {
1962                                         pSRB->MsgInBuf[3] = 1;
1963                                         /* do 16 bits   */
1964                                 } else {
1965                                         if (!(pDCB->SyncMode 
1966                                               & WIDE_NEGO_DONE)) {
1967                                                 pSRB->SRBState &=
1968                                                   ~(SRB_DO_WIDE_NEGO+SRB_MSGIN);
1969                                                 pDCB->SyncMode |= 
1970                                                   WIDE_NEGO_DONE;
1971                                                 pDCB->SyncMode &=
1972                                                   ~(SYNC_NEGO_DONE |
1973                                                       EN_ATN_STOP |
1974                                                       WIDE_NEGO_ENABLE);
1975                                                 if (pSRB->MsgInBuf[3] != 0) {
1976                                                   /* is Wide data xfer */
1977                                                         pDCB->SyncPeriod |=
1978                                                           WIDE_SYNC;
1979                                                         pDCB->tinfo.current.width 
1980                                                           = MSG_EXT_WDTR_BUS_16_BIT;
1981                                                         pDCB->tinfo.goal.width
1982                                                           = MSG_EXT_WDTR_BUS_16_BIT;
1983                                                 }
1984                                         }
1985                                 }
1986                         } else
1987                                 pSRB->MsgInBuf[3] = 0;
1988                         pSRB->SRBState |= SRB_MSGOUT;
1989                         trm_reg_write16(DO_SETATN,TRMREG_SCSI_CONTROL);
1990                         goto  min6;
1991                 } else if ((pSRB->MsgInBuf[0] == MSG_EXTENDED) &&
1992                     (pSRB->MsgInBuf[2] == 1) && (pSRB->MsgCnt == 5)) {
1993                         /*
1994                          * is 8bit transfer Extended message :
1995                          * =================================
1996                          * SYNCHRONOUS DATA TRANSFER REQUEST
1997                          * =================================
1998                          * byte 0 :  Extended message (01h)
1999                          * byte 1 :  Extended message length (03)
2000                          * byte 2 :  SYNCHRONOUS DATA TRANSFER code (01h)
2001                          * byte 3 :  Transfer period factor 
2002                          * byte 4 :  REQ/ACK offset  
2003                          */
2004                         pSRB->SRBState &= ~(SRB_EXTEND_MSGIN+SRB_DO_SYNC_NEGO);
2005                         if ((pSRB->MsgInBuf[1] != 3) ||
2006                             (pSRB->MsgInBuf[2] != 1)) {
2007                           /* reject_msg: */
2008                                 pSRB->MsgCnt = 1;
2009                                 pSRB->MsgInBuf[0] = MSG_REJECT_;
2010                                 trm_reg_write16(DO_SETATN, TRMREG_SCSI_CONTROL);
2011                         } else if (!(pSRB->MsgInBuf[3]) || !(pSRB->MsgInBuf[4])) {
2012                                 /* set async */
2013                                 pDCB = pSRB->pSRBDCB;
2014                                 /* disable sync & sync nego */
2015                                 pDCB->SyncMode &= 
2016                                   ~(SYNC_NEGO_ENABLE+SYNC_NEGO_DONE);
2017                                 pDCB->SyncPeriod = 0;
2018                                 pDCB->SyncOffset = 0;
2019                                 pDCB->tinfo.goal.period = 0;
2020                                 pDCB->tinfo.goal.offset = 0;
2021                                 pDCB->tinfo.current.period = 0;
2022                                 pDCB->tinfo.current.offset = 0;
2023                                 pDCB->tinfo.current.width = 
2024                                   MSG_EXT_WDTR_BUS_8_BIT;
2025                                 goto  re_prog;
2026                         } else {
2027                                 /* set sync */
2028                                 pDCB = pSRB->pSRBDCB;
2029                                 pDCB->SyncMode |= 
2030                                   SYNC_NEGO_ENABLE+SYNC_NEGO_DONE;
2031                                 pDCB->MaxNegoPeriod = pSRB->MsgInBuf[3];
2032                                 /* Transfer period factor */
2033                                 pDCB->SyncOffset = pSRB->MsgInBuf[4]; 
2034                                 /* REQ/ACK offset */
2035                                 for (bIndex = 0; bIndex < 7; bIndex++) {
2036                                   if (pSRB->MsgInBuf[3] <=
2037                                       dc395x_trm_clock_period[bIndex]) {
2038                                         break;
2039                                   }
2040                                 }
2041                                 pDCB->tinfo.goal.period =
2042                                   dc395x_trm_tinfo_sync_period[bIndex];
2043                                 pDCB->tinfo.current.period = 
2044                                   dc395x_trm_tinfo_sync_period[bIndex];
2045                                 pDCB->tinfo.goal.offset = pDCB->SyncOffset;
2046                                 pDCB->tinfo.current.offset = pDCB->SyncOffset;
2047                                 pDCB->SyncPeriod |= (bIndex | ALT_SYNC);
2048 re_prog:
2049                                 /*               
2050                                  *
2051                                  *   program SCSI control register
2052                                  *
2053                                  */
2054                                 trm_reg_write8(pDCB->SyncPeriod,
2055                                     TRMREG_SCSI_SYNC);
2056                                 trm_reg_write8(pDCB->SyncOffset,
2057                                     TRMREG_SCSI_OFFSET);
2058                                 trm_SetXferRate(pACB,pSRB,pDCB);
2059                         }
2060                 }
2061         }
2062 min6:
2063         *pscsi_status = PH_BUS_FREE;
2064         /* .. initial phase */
2065         trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
2066         /* it's important for atn stop */
2067         /*
2068          * SCSI cammand 
2069          */
2070         trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
2071 }
2072
2073 static void
2074 trm_MsgInPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
2075 {
2076
2077         trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
2078         trm_reg_write32(1,TRMREG_SCSI_COUNTER);
2079         if (!(pSRB->SRBState & SRB_MSGIN)) {
2080                 pSRB->SRBState &= SRB_DISCONNECT;
2081                 pSRB->SRBState |= SRB_MSGIN;
2082         }
2083         trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
2084         /* it's important for atn stop*/
2085         /*
2086          * SCSI cammand 
2087          */
2088         trm_reg_write8(SCMD_FIFO_IN, TRMREG_SCSI_COMMAND);
2089 }
2090
2091 static void
2092 trm_Nop0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
2093 {
2094
2095 }
2096
2097 static void
2098 trm_Nop1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
2099 {
2100
2101 }
2102
2103 static void
2104 trm_SetXferRate(PACB pACB,PSRB pSRB, PDCB pDCB)
2105 {
2106         u_int16_t       cnt, i;
2107         u_int8_t        bval;
2108         PDCB            pDCBTemp;
2109         u_int           target_id,target_lun;
2110
2111         /*
2112          * set all lun device's  period , offset
2113          */
2114         target_id  = pSRB->pccb->ccb_h.target_id;
2115         target_lun = pSRB->pccb->ccb_h.target_lun;
2116         TRM_DPRINTF("trm_SetXferRate:target_id= %d ,target_lun= %d \n"
2117             ,target_id,target_lun);
2118         if (!(pDCB->IdentifyMsg & 0x07)) {
2119                 if (!pACB->scan_devices[target_id][target_lun]) {
2120                         pDCBTemp = pACB->pLinkDCB;
2121                         cnt = pACB->DeviceCnt;
2122                         bval = pDCB->TargetID;
2123                         for (i = 0; i < cnt; i++) {
2124                                 if (pDCBTemp->TargetID == bval) {
2125                                         pDCBTemp->SyncPeriod = pDCB->SyncPeriod;
2126                                         pDCBTemp->SyncOffset = pDCB->SyncOffset;
2127                                         pDCBTemp->SyncMode = pDCB->SyncMode;
2128                                 }
2129                                 pDCBTemp = pDCBTemp->pNextDCB;
2130                         }
2131                 }
2132         }
2133         return;
2134 }
2135
2136 /*
2137  * scsiiom              
2138  *            trm_Interrupt       
2139  *                      
2140  *
2141  *    ---SCSI bus phase
2142  *
2143  *      PH_DATA_OUT             0x00     Data out phase               
2144  *      PH_DATA_IN              0x01     Data in phase              
2145  *      PH_COMMAND              0x02     Command phase   
2146  *      PH_STATUS               0x03     Status phase
2147  *      PH_BUS_FREE             0x04     Invalid phase used as bus free 
2148  *      PH_BUS_FREE             0x05     Invalid phase used as bus free 
2149  *      PH_MSG_OUT              0x06     Message out phase
2150  *      PH_MSG_IN               0x07     Message in phase
2151  *
2152  */
2153 static void 
2154 trm_Disconnect(PACB pACB)
2155 {
2156         PDCB            pDCB;
2157         PSRB            pSRB, psrb;
2158         u_int16_t       i,j, cnt;
2159         u_int8_t        bval;
2160         u_int           target_id,target_lun;
2161         
2162         TRM_DPRINTF("trm_Disconnect...............\n ");
2163         
2164         crit_enter();
2165         pDCB = pACB->pActiveDCB;
2166         if (!pDCB) {
2167                 TRM_DPRINTF(" Exception Disconnect DCB=NULL..............\n ");
2168                 j = 400;
2169                 while (--j) 
2170                         DELAY(1);
2171                 /* 1 msec */
2172                 trm_reg_write16((DO_CLRFIFO | DO_HWRESELECT),
2173                     TRMREG_SCSI_CONTROL);
2174                 crit_exit();
2175                 return;
2176         }
2177         pSRB = pDCB->pActiveSRB; 
2178         /* bug pSRB=0 */
2179         target_id  = pSRB->pccb->ccb_h.target_id;
2180         target_lun = pSRB->pccb->ccb_h.target_lun;
2181         TRM_DPRINTF(":pDCB->pActiveSRB= %8x \n ",(u_int) pDCB->pActiveSRB);
2182         pACB->pActiveDCB = 0;
2183         pSRB->ScsiPhase = PH_BUS_FREE; 
2184         /* SCSI bus free Phase */
2185         trm_reg_write16((DO_CLRFIFO | DO_HWRESELECT), TRMREG_SCSI_CONTROL);
2186         if (pSRB->SRBState & SRB_UNEXPECT_RESEL) {
2187                 pSRB->SRBState = 0;
2188                 trm_DoWaitingSRB(pACB);
2189         } else if (pSRB->SRBState & SRB_ABORT_SENT) {
2190                 pDCB->TagMask = 0;
2191                 pDCB->DCBFlag = 0;
2192                 cnt = pDCB->GoingSRBCnt;
2193                 pDCB->GoingSRBCnt = 0;
2194                 pSRB = pDCB->pGoingSRB;
2195                 for (i = 0; i < cnt; i++) {
2196                         psrb = pSRB->pNextSRB;
2197                         pSRB->pNextSRB = pACB->pFreeSRB;
2198                         pACB->pFreeSRB = pSRB;
2199                         pSRB = psrb;
2200                 }
2201                 pDCB->pGoingSRB = 0;
2202                 trm_DoWaitingSRB(pACB);
2203         } else {
2204                 if ((pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) || 
2205                     !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED))) {
2206                   /* Selection time out */
2207                         if (!(pACB->scan_devices[target_id][target_lun])) {
2208                                 pSRB->SRBState = SRB_READY;
2209                                 trm_RewaitSRB(pDCB, pSRB);
2210                         } else {
2211                                 pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT;
2212                                 goto  disc1;
2213                         }
2214                 } else if (pSRB->SRBState & SRB_DISCONNECT) {
2215                         /*
2216                          * SRB_DISCONNECT
2217                          */
2218                         trm_DoWaitingSRB(pACB);
2219                 } else if (pSRB->SRBState & SRB_COMPLETED) {
2220 disc1:
2221                   /*
2222                    * SRB_COMPLETED
2223                    */
2224                         if (pDCB->MaxCommand > 1) {
2225                                 bval = pSRB->TagNumber;
2226                                 pDCB->TagMask &= (~(1 << bval));
2227                                 /* free tag mask */
2228                         }
2229                         pDCB->pActiveSRB = 0;
2230                         pSRB->SRBState = SRB_FREE;
2231                         trm_SRBdone(pACB, pDCB, pSRB);
2232                 }
2233         }
2234         crit_exit();
2235         return;
2236 }
2237
2238 static void
2239 trm_Reselect(PACB pACB)
2240 {
2241         PDCB            pDCB;
2242         PSRB            pSRB;
2243         u_int16_t       RselTarLunId;
2244
2245         TRM_DPRINTF("trm_Reselect................. \n");
2246         pDCB = pACB->pActiveDCB;
2247         if (pDCB) {
2248           /* Arbitration lost but Reselection win */
2249                 pSRB = pDCB->pActiveSRB;
2250                 pSRB->SRBState = SRB_READY;
2251                 trm_RewaitSRB(pDCB, pSRB);
2252         }
2253         /* Read Reselected Target Id and LUN */
2254         RselTarLunId = trm_reg_read16(TRMREG_SCSI_TARGETID) & 0x1FFF;
2255         pDCB = pACB->pLinkDCB;
2256         while (RselTarLunId != *((u_int16_t *) &pDCB->TargetID)) {
2257           /* get pDCB of the reselect id */
2258                 pDCB = pDCB->pNextDCB;
2259         }
2260
2261         pACB->pActiveDCB = pDCB;
2262         if (pDCB->SyncMode & EN_TAG_QUEUING) {
2263                 pSRB = pACB->pTmpSRB;
2264                 pDCB->pActiveSRB = pSRB;
2265         } else {
2266                 pSRB = pDCB->pActiveSRB;
2267                 if (!pSRB || !(pSRB->SRBState & SRB_DISCONNECT)) {
2268                   /*
2269                    * abort command
2270                    */
2271                         pSRB = pACB->pTmpSRB;
2272                         pSRB->SRBState = SRB_UNEXPECT_RESEL;
2273                         pDCB->pActiveSRB = pSRB;
2274                         trm_EnableMsgOutAbort1(pACB, pSRB);
2275                 } else {
2276                         if (pDCB->DCBFlag & ABORT_DEV_) {
2277                                 pSRB->SRBState = SRB_ABORT_SENT;
2278                                 trm_EnableMsgOutAbort1(pACB, pSRB);
2279                         } else 
2280                                 pSRB->SRBState = SRB_DATA_XFER;
2281                 }
2282         }
2283         pSRB->ScsiPhase = PH_BUS_FREE;
2284         /* SCSI bus free Phase */
2285         /* 
2286          * Program HA ID, target ID, period and offset
2287          */
2288         trm_reg_write8((u_int8_t) RselTarLunId,TRMREG_SCSI_TARGETID);
2289         /* target ID */
2290         trm_reg_write8(pACB->AdaptSCSIID,TRMREG_SCSI_HOSTID);
2291         /* host   ID */
2292         trm_reg_write8(pDCB->SyncPeriod,TRMREG_SCSI_SYNC);
2293         /* period    */
2294         trm_reg_write8(pDCB->SyncOffset,TRMREG_SCSI_OFFSET); 
2295         /* offset    */
2296         trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
2297         /* it's important for atn stop*/
2298         /*
2299          * SCSI cammand 
2300          */
2301         trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
2302         /* to rls the /ACK signal */
2303 }
2304
2305 static void
2306 trm_SRBdone(PACB pACB, PDCB pDCB, PSRB pSRB)
2307 {
2308         PSRB                    psrb;
2309         u_int8_t                bval, bval1,status;
2310         union ccb               *pccb;
2311         struct ccb_scsiio       *pcsio;
2312         PSCSI_INQDATA           ptr;
2313         u_int                   target_id,target_lun;
2314         PDCB                    pTempDCB;
2315
2316         pccb  = pSRB->pccb;
2317         if (pccb == NULL)
2318                 return;
2319         pcsio = &pccb->csio;
2320         target_id  = pSRB->pccb->ccb_h.target_id;
2321         target_lun = pSRB->pccb->ccb_h.target_lun;
2322         if ((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
2323                 bus_dmasync_op_t op;
2324                 if ((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
2325                         op = BUS_DMASYNC_POSTREAD;
2326                 else
2327                         op = BUS_DMASYNC_POSTWRITE;
2328                 bus_dmamap_sync(pACB->buffer_dmat, pSRB->dmamap, op);
2329                 bus_dmamap_unload(pACB->buffer_dmat, pSRB->dmamap);
2330         }
2331         /*
2332          *
2333          * target status
2334          *
2335          */
2336         status = pSRB->TargetStatus;
2337         pcsio->scsi_status=SCSI_STAT_GOOD;
2338         pccb->ccb_h.status = CAM_REQ_CMP;
2339         if (pSRB->SRBFlag & AUTO_REQSENSE) {
2340           /* 
2341            * status of auto request sense 
2342            */
2343                 pSRB->SRBFlag &= ~AUTO_REQSENSE;
2344                 pSRB->AdaptStatus = 0;
2345                 pSRB->TargetStatus = SCSI_STATUS_CHECK_COND;
2346                 
2347                 if (status == SCSI_STATUS_CHECK_COND) {
2348                         pccb->ccb_h.status = CAM_SEL_TIMEOUT;
2349                         goto ckc_e;
2350                 }
2351                 *((u_long *) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
2352                 *((u_long *) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1];
2353                 pSRB->SRBTotalXferLength = pSRB->Segment1[1];
2354                 pSRB->SegmentX[0].address = pSRB->SgSenseTemp.address;
2355                 pSRB->SegmentX[0].length = pSRB->SgSenseTemp.length;
2356                 pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
2357                 pccb->ccb_h.status = CAM_AUTOSNS_VALID;
2358                 goto ckc_e;
2359         }
2360         /*
2361          * target status
2362          */
2363         if (status) {
2364                 if (status == SCSI_STATUS_CHECK_COND) {
2365                         if ((pcsio->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) {
2366                           TRM_DPRINTF("trm_RequestSense..................\n");
2367                           trm_RequestSense(pACB, pDCB, pSRB);
2368                           return;
2369                         }
2370                         pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
2371                         pccb->ccb_h.status = CAM_AUTOSNS_VALID |
2372                           CAM_SCSI_STATUS_ERROR;
2373                         goto ckc_e;
2374                 } else if (status == SCSI_STAT_QUEUEFULL) {
2375                         bval = (u_int8_t) pDCB->GoingSRBCnt;
2376                         bval--;
2377                         pDCB->MaxCommand = bval;
2378                         trm_RewaitSRB(pDCB, pSRB);
2379                         pSRB->AdaptStatus = 0;
2380                         pSRB->TargetStatus = 0;
2381                         pcsio->scsi_status = SCSI_STAT_QUEUEFULL;
2382                         pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
2383                         goto ckc_e;
2384                 } else if (status == SCSI_STAT_SEL_TIMEOUT) {
2385                         pSRB->AdaptStatus  = H_SEL_TIMEOUT;
2386                         pSRB->TargetStatus = 0;
2387                         pcsio->scsi_status = SCSI_STAT_SEL_TIMEOUT;
2388                         pccb->ccb_h.status = CAM_SEL_TIMEOUT;
2389                 } else if (status == SCSI_STAT_BUSY) {
2390                         TRM_DPRINTF("trm: target busy at %s %d\n",
2391                                 __FILE__, __LINE__);
2392                         pcsio->scsi_status = SCSI_STAT_BUSY;
2393                         pccb->ccb_h.status = CAM_SCSI_BUSY;
2394                   /* The device busy, try again later?    */
2395                 } else if (status == SCSI_STAT_RESCONFLICT) {
2396                         TRM_DPRINTF("trm: target reserved at %s %d\n",
2397                                 __FILE__, __LINE__);
2398                         pcsio->scsi_status = SCSI_STAT_RESCONFLICT;
2399                         pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;     /*XXX*/
2400                 } else {
2401                         pSRB->AdaptStatus = 0;
2402                         if (pSRB->RetryCnt) {
2403                                 pSRB->RetryCnt--;
2404                                 pSRB->TargetStatus = 0;
2405                                 pSRB->SRBSGIndex = 0;
2406                                 pSRB->SRBSGListPointer = (PSEG)
2407                                   &pSRB->SegmentX[0];
2408                                 if (trm_StartSCSI(pACB, pDCB, pSRB)) {
2409                                   /* 
2410                                    * If trm_StartSCSI return 1 :
2411                                    * current interrupt status is interrupt 
2412                                    * disreenable 
2413                                    * It's said that SCSI processor has more 
2414                                    * one SRB need to do
2415                                    */
2416                                         trm_RewaitSRB(pDCB, pSRB);
2417                                 }
2418                                 return;
2419                         } else {
2420                                 TRM_DPRINTF("trm: driver stuffup at %s %d\n",
2421                                         __FILE__, __LINE__);
2422                                 pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
2423                         }
2424                 }
2425         } else {
2426         /* 
2427          * process initiator status..........................
2428          * Adapter (initiator) status
2429          */
2430                 status = pSRB->AdaptStatus;
2431                 if (status & H_OVER_UNDER_RUN) {
2432                         pSRB->TargetStatus = 0;
2433                         pccb->ccb_h.status = CAM_DATA_RUN_ERR;
2434                         /* Illegal length (over/under run) */
2435                 } else if (pSRB->SRBStatus & PARITY_ERROR) {
2436                         TRM_DPRINTF("trm: driver stuffup %s %d\n",
2437                                 __FILE__, __LINE__);
2438                         pDCB->tinfo.goal.period = 0;
2439                         pDCB->tinfo.goal.offset = 0;
2440                         /* Driver failed to perform operation */
2441                         pccb->ccb_h.status = CAM_UNCOR_PARITY;
2442                 } else {
2443                   /* no error */
2444                         pSRB->AdaptStatus = 0;
2445                         pSRB->TargetStatus = 0;
2446                         pccb->ccb_h.status = CAM_REQ_CMP;
2447                         /* there is no error, (sense is invalid) */
2448                 }
2449         }
2450 ckc_e:
2451         if (pACB->scan_devices[target_id][target_lun]) {
2452           /*
2453            *   if SCSI command in "scan devices" duty
2454            */
2455                 if (pSRB->CmdBlock[0] == TEST_UNIT_READY) 
2456                         pACB->scan_devices[target_id][target_lun] = 0;
2457                 /* SCSI command phase :test unit ready */
2458                 else if (pSRB->CmdBlock[0] == INQUIRY) {
2459                   /* 
2460                    * SCSI command phase :inquiry scsi device data 
2461                    * (type,capacity,manufacture.... 
2462                    */
2463                         if (pccb->ccb_h.status == CAM_SEL_TIMEOUT)
2464                                 goto NO_DEV;
2465                         ptr = (PSCSI_INQDATA) pcsio->data_ptr;
2466                         /* page fault */
2467                         TRM_DPRINTF("trm_SRBdone..PSCSI_INQDATA:%2x \n",
2468                             ptr->DevType);
2469                         bval1 = ptr->DevType & SCSI_DEVTYPE; 
2470                         if (bval1 == SCSI_NODEV) {
2471 NO_DEV:
2472                                 TRM_DPRINTF("trm_SRBdone NO Device:target_id= %d ,target_lun= %d \n",
2473                                     target_id,
2474                                     target_lun);
2475                                 crit_enter();
2476                                 pACB->scan_devices[target_id][target_lun] = 0;
2477                                 /* no device set scan device flag =0*/
2478                                 /* pDCB Q link */
2479                                 /* move the head of DCB to tempDCB*/
2480                                 pTempDCB=pACB->pLinkDCB;  
2481                                 /* search current DCB for pass link */
2482                                 while (pTempDCB->pNextDCB != pDCB) {
2483                                         pTempDCB = pTempDCB->pNextDCB;
2484                                 }
2485                                 /*
2486                                  * when the current DCB found than connect 
2487                                  * current DCB tail 
2488                                  */
2489                                 /* to the DCB tail that before current DCB */
2490                                 pTempDCB->pNextDCB = pDCB->pNextDCB;
2491                                 /*
2492                                  * if there was only one DCB ,connect his tail
2493                                  * to his head 
2494                                  */
2495                                 if (pACB->pLinkDCB == pDCB)
2496                                         pACB->pLinkDCB = pTempDCB->pNextDCB;
2497                                 if (pACB->pDCBRunRobin == pDCB)
2498                                         pACB->pDCBRunRobin = pTempDCB->pNextDCB;
2499                                 pACB->DeviceCnt--;
2500                                 if (pACB->DeviceCnt == 0) {
2501                                         pACB->pLinkDCB = NULL;
2502                                         pACB->pDCBRunRobin = NULL;
2503                                 }
2504                                 crit_exit();
2505                         } else { 
2506 #ifdef trm_DEBUG1
2507                                 int j;
2508                                 for (j = 0; j < 28; j++) {
2509                                         TRM_DPRINTF("ptr=%2x ", 
2510                                                 ((u_int8_t *)ptr)[j]);
2511                                 }
2512 #endif
2513                                 pDCB->DevType = bval1;
2514                                 if (bval1 == SCSI_DASD ||
2515                                     bval1 == SCSI_OPTICAL) {
2516                                         if ((((ptr->Vers & 0x07) >= 2) ||
2517                                               ((ptr->RDF & 0x0F) == 2)) && 
2518                                             (ptr->Flags & SCSI_INQ_CMDQUEUE) &&
2519                                             (pDCB->DevMode & TAG_QUEUING_) &&
2520                                             (pDCB->DevMode & EN_DISCONNECT_)) {
2521                                                 if (pDCB->DevMode &
2522                                                     TAG_QUEUING_) {
2523                                                         pDCB->MaxCommand = 
2524                                                           pACB->TagMaxNum;
2525                                                         pDCB->SyncMode |= 
2526                                                           EN_TAG_QUEUING;
2527                                                         pDCB->TagMask = 0;
2528                                                         pDCB->tinfo.disc_tag |=
2529                                                           TRM_CUR_TAGENB;
2530                                                 } else {
2531                                                         pDCB->SyncMode |= 
2532                                                           EN_ATN_STOP;
2533                                                         pDCB->tinfo.disc_tag &=
2534                                                           ~TRM_CUR_TAGENB;
2535                                                 }
2536                                         }
2537                                 }
2538                         }
2539                         /* pSRB->CmdBlock[0] == INQUIRY */
2540                 }
2541                 /* pACB->scan_devices[target_id][target_lun] */
2542         }
2543         crit_enter();
2544         /*  ReleaseSRB(pDCB, pSRB); */
2545         if (pSRB == pDCB->pGoingSRB)
2546                 pDCB->pGoingSRB = pSRB->pNextSRB;
2547         else {
2548                 psrb = pDCB->pGoingSRB;
2549                 while (psrb->pNextSRB != pSRB) {
2550                         psrb = psrb->pNextSRB;
2551                 }
2552                 psrb->pNextSRB = pSRB->pNextSRB;
2553                 if (pSRB == pDCB->pGoingLastSRB) {
2554                         pDCB->pGoingLastSRB = psrb;
2555                 }
2556         }
2557         pSRB->pNextSRB = pACB->pFreeSRB;
2558         pACB->pFreeSRB = pSRB;
2559         pDCB->GoingSRBCnt--;
2560         trm_DoWaitingSRB(pACB);
2561
2562         crit_exit();
2563         /*  Notify cmd done */
2564         xpt_done (pccb);
2565 }
2566
2567 static void
2568 trm_DoingSRB_Done(PACB pACB)
2569 {
2570         PDCB            pDCB, pdcb;
2571         PSRB            psrb, psrb2;
2572         u_int16_t       cnt, i;
2573         union ccb       *pccb;
2574
2575         pDCB = pACB->pLinkDCB;
2576         if (pDCB == NULL) 
2577                 return;
2578         pdcb = pDCB;
2579         do {
2580                 cnt = pdcb->GoingSRBCnt;
2581                 psrb = pdcb->pGoingSRB;
2582                 for (i = 0; i < cnt; i++) {
2583                         psrb2 = psrb->pNextSRB;
2584                         pccb = psrb->pccb;
2585                         pccb->ccb_h.status = CAM_SEL_TIMEOUT;
2586                         /*  ReleaseSRB(pDCB, pSRB); */
2587                         psrb->pNextSRB = pACB->pFreeSRB;
2588                         pACB->pFreeSRB = psrb;
2589                         xpt_done(pccb);
2590                         psrb  = psrb2;
2591                 }
2592                 pdcb->GoingSRBCnt = 0;;
2593                 pdcb->pGoingSRB = NULL;
2594                 pdcb->TagMask = 0;
2595                 pdcb = pdcb->pNextDCB;
2596         }
2597         while (pdcb != pDCB);
2598 }
2599
2600 static void 
2601 trm_ResetSCSIBus(PACB pACB)
2602 {
2603         crit_enter();
2604         pACB->ACBFlag |= RESET_DEV;
2605
2606         trm_reg_write16(DO_RSTSCSI,TRMREG_SCSI_CONTROL);
2607         while (!(trm_reg_read16(TRMREG_SCSI_INTSTATUS) & INT_SCSIRESET));
2608         crit_exit();
2609         return;
2610 }
2611
2612 static void 
2613 trm_ScsiRstDetect(PACB pACB)
2614 {
2615         u_long  wlval;
2616
2617         TRM_DPRINTF("trm_ScsiRstDetect \n");
2618         wlval = 1000;
2619         while (--wlval)
2620                 DELAY(1000);
2621         crit_enter();
2622         trm_reg_write8(STOPDMAXFER,TRMREG_DMA_CONTROL);
2623
2624         trm_reg_write16(DO_CLRFIFO,TRMREG_SCSI_CONTROL);
2625
2626         if (pACB->ACBFlag & RESET_DEV)
2627                 pACB->ACBFlag |= RESET_DONE;
2628         else {
2629                 pACB->ACBFlag |= RESET_DETECT;
2630                 trm_ResetDevParam(pACB);
2631                 /*      trm_DoingSRB_Done(pACB); ???? */
2632                 trm_RecoverSRB(pACB);
2633                 pACB->pActiveDCB = NULL;
2634                 pACB->ACBFlag = 0;
2635                 trm_DoWaitingSRB(pACB);
2636         }
2637         crit_exit();
2638         return;
2639 }
2640
2641 static void
2642 trm_RequestSense(PACB pACB, PDCB pDCB, PSRB pSRB)       
2643 {
2644         union ccb               *pccb;
2645         struct ccb_scsiio       *pcsio;
2646
2647         pccb  = pSRB->pccb;
2648         pcsio = &pccb->csio;
2649
2650         pSRB->SRBFlag |= AUTO_REQSENSE;
2651         pSRB->Segment0[0] = *((u_long *) &(pSRB->CmdBlock[0]));
2652         pSRB->Segment0[1] = *((u_long *) &(pSRB->CmdBlock[4]));
2653         pSRB->Segment1[0] = (u_long) ((pSRB->ScsiCmdLen << 8) + 
2654             pSRB->SRBSGCount);
2655         pSRB->Segment1[1] = pSRB->SRBTotalXferLength; /* ?????????? */
2656
2657         /* $$$$$$ Status of initiator/target $$$$$$$$ */
2658         pSRB->AdaptStatus = 0;
2659         pSRB->TargetStatus = 0;
2660         /* $$$$$$ Status of initiator/target $$$$$$$$ */
2661         
2662         pSRB->SRBTotalXferLength = sizeof(pcsio->sense_data);
2663         pSRB->SgSenseTemp.address = pSRB->SegmentX[0].address;
2664         pSRB->SgSenseTemp.length  = pSRB->SegmentX[0].length;
2665         pSRB->SegmentX[0].address = (u_long) vtophys(&pcsio->sense_data);
2666         pSRB->SegmentX[0].length = (u_long) pcsio->sense_len;
2667         pSRB->SRBSGListPointer = &pSRB->SegmentX[0];
2668         pSRB->SRBSGCount = 1;
2669         pSRB->SRBSGIndex = 0;
2670         
2671         *((u_long *) &(pSRB->CmdBlock[0])) = 0x00000003;
2672         pSRB->CmdBlock[1] = pDCB->IdentifyMsg << 5;
2673         *((u_int16_t *) &(pSRB->CmdBlock[4])) = pcsio->sense_len;
2674         pSRB->ScsiCmdLen = 6;
2675         
2676         if (trm_StartSCSI(pACB, pDCB, pSRB))
2677            /* 
2678             * If trm_StartSCSI return 1 :
2679             * current interrupt status is interrupt disreenable 
2680             * It's said that SCSI processor has more one SRB need to do
2681             */
2682                 trm_RewaitSRB(pDCB, pSRB);
2683 }
2684
2685 static void 
2686 trm_EnableMsgOutAbort2(PACB pACB, PSRB pSRB)
2687 {
2688
2689         pSRB->MsgCnt = 1;
2690         trm_reg_write16(DO_SETATN, TRMREG_SCSI_CONTROL);
2691 }
2692
2693 static void
2694 trm_EnableMsgOutAbort1(PACB pACB, PSRB pSRB)
2695 {
2696   
2697         pSRB->MsgOutBuf[0] = MSG_ABORT;
2698         trm_EnableMsgOutAbort2(pACB, pSRB);
2699 }
2700
2701 static void
2702 trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit,u_int32_t i,u_int32_t j)
2703 {
2704         PNVRAMTYPE      pEEpromBuf;
2705         u_int8_t        bval,PeriodIndex;
2706         u_int           target_id,target_lun;
2707         PDCB            pTempDCB;
2708     
2709         target_id  = i;
2710         target_lun = j;
2711
2712         crit_enter();
2713         if (pACB->pLinkDCB == 0) {
2714                 pACB->pLinkDCB = pDCB;
2715                 /* 
2716                  * RunRobin impersonate the role 
2717                  * that let each device had good proportion 
2718                  * about SCSI command proceeding 
2719                  */
2720                 pACB->pDCBRunRobin = pDCB;
2721                 pDCB->pNextDCB = pDCB;
2722         } else {
2723                 pTempDCB=pACB->pLinkDCB;
2724                 /* search the last nod of DCB link */
2725                 while (pTempDCB->pNextDCB != pACB->pLinkDCB)
2726                         pTempDCB = pTempDCB->pNextDCB;
2727                 /* connect current DCB with last DCB tail */
2728                 pTempDCB->pNextDCB = pDCB;
2729                 /* connect current DCB tail to this DCB Q head */
2730                 pDCB->pNextDCB=pACB->pLinkDCB;
2731         }
2732         crit_exit();
2733
2734         pACB->DeviceCnt++;
2735         pDCB->pDCBACB = pACB;
2736         pDCB->TargetID = target_id;
2737         pDCB->TargetLUN =  target_lun;
2738         pDCB->pWaitingSRB = NULL;
2739         pDCB->pGoingSRB = NULL;
2740         pDCB->GoingSRBCnt = 0;
2741         pDCB->pActiveSRB = NULL;
2742         pDCB->TagMask = 0;
2743         pDCB->MaxCommand = 1;
2744         pDCB->DCBFlag = 0;
2745         /* $$$$$$$ */
2746         pEEpromBuf = &trm_eepromBuf[unit];
2747         pDCB->DevMode = pEEpromBuf->NvramTarget[target_id].NvmTarCfg0;
2748         pDCB->AdpMode = pEEpromBuf->NvramChannelCfg;
2749         /* $$$$$$$ */
2750         /* 
2751          * disconnect enable ?
2752          */
2753         if (pDCB->DevMode & NTC_DO_DISCONNECT) {
2754                 bval = 0xC0;
2755                 pDCB->tinfo.disc_tag |= TRM_USR_DISCENB ;
2756         } else {
2757                 bval = 0x80;
2758                 pDCB->tinfo.disc_tag &= ~(TRM_USR_DISCENB);
2759         }
2760         bval |= target_lun;
2761         pDCB->IdentifyMsg = bval;
2762         /* $$$$$$$ */
2763         /*
2764          * tag Qing enable ?
2765          */
2766         if (pDCB->DevMode & TAG_QUEUING_) {
2767                 pDCB->tinfo.disc_tag |= TRM_USR_TAGENB ;
2768         } else
2769                 pDCB->tinfo.disc_tag &= ~(TRM_USR_TAGENB);
2770         /* $$$$$$$ */
2771         /*
2772          * wide nego ,sync nego enable ?
2773          */
2774         pDCB->SyncPeriod = 0;
2775         pDCB->SyncOffset = 0;
2776         PeriodIndex = pEEpromBuf->NvramTarget[target_id].NvmTarPeriod & 0x07;
2777         pDCB->MaxNegoPeriod = dc395x_trm_clock_period[ PeriodIndex ] ;
2778         pDCB->SyncMode = 0;
2779         if ((pDCB->DevMode & NTC_DO_WIDE_NEGO) && 
2780             (pACB->Config & HCC_WIDE_CARD))
2781                 pDCB->SyncMode |= WIDE_NEGO_ENABLE;
2782         /* enable wide nego */
2783         if (pDCB->DevMode & NTC_DO_SYNC_NEGO)
2784                 pDCB->SyncMode |= SYNC_NEGO_ENABLE;
2785         /* enable sync nego */
2786         /* $$$$$$$ */
2787         /*
2788          *      Fill in tinfo structure.
2789          */
2790         pDCB->tinfo.user.period = pDCB->MaxNegoPeriod;
2791         pDCB->tinfo.user.offset = (pDCB->SyncMode & SYNC_NEGO_ENABLE) ? 15 : 0;
2792         pDCB->tinfo.user.width  = (pDCB->SyncMode & WIDE_NEGO_ENABLE) ? 
2793           MSG_EXT_WDTR_BUS_16_BIT : MSG_EXT_WDTR_BUS_8_BIT;
2794
2795         pDCB->tinfo.current.period = 0;
2796         pDCB->tinfo.current.offset = 0;
2797         pDCB->tinfo.current.width = MSG_EXT_WDTR_BUS_8_BIT;
2798 }
2799
2800 static void 
2801 trm_initSRB(PSRB psrb)
2802 {
2803   
2804         psrb->PhysSRB = vtophys(psrb);
2805 }
2806
2807 static void
2808 trm_linkSRB(PACB pACB)
2809 {
2810         u_int16_t       i;
2811
2812         for (i = 0; i < MAX_SRB_CNT; i++) {
2813                 if (i != MAX_SRB_CNT - 1)
2814                         /*
2815                          * link all SRB 
2816                          */
2817                         pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[i+1];
2818         else
2819                         /*
2820                          * load NULL to NextSRB of the last SRB
2821                          */
2822                 pACB->SRB_array[i].pNextSRB = NULL;
2823         /*
2824          * convert and save physical address of SRB to pSRB->PhysSRB
2825          */
2826         trm_initSRB((PSRB) &pACB->SRB_array[i]);
2827         }
2828 }
2829
2830
2831 static void
2832 trm_initACB(PACB pACB, u_int16_t unit)
2833 {
2834         PNVRAMTYPE      pEEpromBuf;
2835         u_int16_t               i,j;
2836     
2837         pEEpromBuf = &trm_eepromBuf[unit];
2838         pACB->max_id = 15;
2839         
2840         if (pEEpromBuf->NvramChannelCfg & NAC_SCANLUN)
2841                 pACB->max_lun = 7;
2842         else
2843                 pACB->max_lun = 0;
2844
2845         TRM_DPRINTF("trm: pACB->max_id= %d pACB->max_lun= %d \n",
2846             pACB->max_id, pACB->max_lun);
2847
2848         pACB->pLinkDCB = NULL;
2849         pACB->pDCBRunRobin = NULL;
2850         pACB->pActiveDCB = NULL;
2851         pACB->pFreeSRB = pACB->SRB_array;
2852         pACB->AdapterUnit = unit;
2853         pACB->AdaptSCSIID = pEEpromBuf->NvramScsiId;
2854         pACB->AdaptSCSILUN = 0;
2855         pACB->DeviceCnt = 0;
2856         pACB->TagMaxNum = 2 << pEEpromBuf->NvramMaxTag ;
2857         pACB->ACBFlag = 0;
2858         /* 
2859          * link all device's SRB Q of this adapter 
2860          */
2861         trm_linkSRB(pACB);
2862         /* 
2863          * temp SRB for Q tag used or abord command used 
2864          */
2865         pACB->pTmpSRB = &pACB->TmpSRB;
2866         /*
2867          * convert and save physical address of SRB to pSRB->PhysSRB
2868          */
2869         trm_initSRB(pACB->pTmpSRB);
2870         /* allocate DCB array for scan device */
2871         for (i = 0; i < (pACB->max_id +1); i++) {   
2872                 if (pACB->AdaptSCSIID != i) {
2873                         for (j = 0; j < (pACB->max_lun +1); j++) {
2874                                 pACB->scan_devices[i][j] = 1;
2875                                 pACB->pDCB[i][j]= (PDCB) malloc (
2876                                     sizeof (struct _DCB), M_DEVBUF, M_WAITOK);
2877                                 trm_initDCB(pACB,
2878                                     pACB->pDCB[i][j], unit, i, j);
2879                                 TRM_DPRINTF("pDCB= %8x \n",
2880                                         (u_int)pACB->pDCB[i][j]);
2881                         }
2882                 }
2883         }
2884         TRM_DPRINTF("sizeof(struct _DCB)= %8x \n",sizeof(struct _DCB));
2885         TRM_DPRINTF("sizeof(struct _ACB)= %8x \n",sizeof(struct _ACB));
2886         TRM_DPRINTF("sizeof(struct _SRB)= %8x \n",sizeof(struct _SRB));
2887 }
2888
2889 static void
2890 TRM_write_all(PNVRAMTYPE pEEpromBuf,PACB pACB)
2891 {
2892         u_int8_t        *bpEeprom = (u_int8_t *) pEEpromBuf;
2893         u_int8_t        bAddr;
2894
2895         /* Enable SEEPROM */
2896         trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) | EN_EEPROM),
2897             TRMREG_GEN_CONTROL);
2898         /*
2899          * Write enable
2900          */
2901         TRM_write_cmd(pACB, 0x04, 0xFF);
2902         trm_reg_write8(0, TRMREG_GEN_NVRAM);
2903         TRM_wait_30us(pACB);
2904         for (bAddr = 0; bAddr < 128; bAddr++, bpEeprom++) { 
2905                 TRM_set_data(pACB, bAddr, *bpEeprom);
2906         }
2907         /* 
2908          * Write disable
2909          */
2910         TRM_write_cmd(pACB, 0x04, 0x00);
2911         trm_reg_write8(0 , TRMREG_GEN_NVRAM);
2912         TRM_wait_30us(pACB);
2913         /* Disable SEEPROM */
2914         trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) & ~EN_EEPROM),
2915             TRMREG_GEN_CONTROL);
2916         return;
2917 }
2918
2919 static void
2920 TRM_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData)
2921 {
2922         int             i;
2923         u_int8_t        bSendData;
2924         /* 
2925          * Send write command & address 
2926          */
2927         
2928         TRM_write_cmd(pACB, 0x05, bAddr);
2929         /* 
2930          * Write data 
2931          */
2932         for (i = 0; i < 8; i++, bData <<= 1) {
2933                 bSendData = NVR_SELECT;
2934                 if (bData & 0x80)
2935                   /* Start from bit 7   */
2936                         bSendData |= NVR_BITOUT;
2937                 trm_reg_write8(bSendData , TRMREG_GEN_NVRAM);
2938                 TRM_wait_30us(pACB);
2939                 trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM);
2940                 TRM_wait_30us(pACB);
2941         }
2942         trm_reg_write8(NVR_SELECT , TRMREG_GEN_NVRAM);
2943         TRM_wait_30us(pACB);
2944         /*
2945          * Disable chip select 
2946          */
2947         trm_reg_write8(0 , TRMREG_GEN_NVRAM);
2948         TRM_wait_30us(pACB);
2949         trm_reg_write8(NVR_SELECT ,TRMREG_GEN_NVRAM);
2950         TRM_wait_30us(pACB);
2951         /* 
2952          * Wait for write ready 
2953          */
2954         while (1) {
2955                 trm_reg_write8((NVR_SELECT | NVR_CLOCK), TRMREG_GEN_NVRAM);
2956                 TRM_wait_30us(pACB);
2957                 trm_reg_write8(NVR_SELECT, TRMREG_GEN_NVRAM);
2958                 TRM_wait_30us(pACB);
2959                 if (trm_reg_read8(TRMREG_GEN_NVRAM) & NVR_BITIN) {
2960                         break;
2961                 }
2962         }
2963         /* 
2964          * Disable chip select 
2965          */
2966         trm_reg_write8(0, TRMREG_GEN_NVRAM);
2967         return;
2968 }
2969
2970 static void 
2971 TRM_read_all(PNVRAMTYPE pEEpromBuf, PACB pACB)
2972 {
2973         u_int8_t        *bpEeprom = (u_int8_t*) pEEpromBuf;
2974         u_int8_t        bAddr;
2975     
2976         /*
2977          * Enable SEEPROM 
2978          */
2979         trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) | EN_EEPROM),
2980             TRMREG_GEN_CONTROL);
2981         for (bAddr = 0; bAddr < 128; bAddr++, bpEeprom++)
2982                 *bpEeprom = TRM_get_data(pACB, bAddr);
2983         /* 
2984          * Disable SEEPROM 
2985          */
2986         trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) & ~EN_EEPROM),
2987             TRMREG_GEN_CONTROL);
2988         return;
2989 }
2990
2991 static u_int8_t
2992 TRM_get_data(PACB pACB, u_int8_t bAddr)
2993 {
2994         int             i;
2995         u_int8_t        bReadData, bData = 0;
2996         /* 
2997         * Send read command & address
2998         */
2999         
3000         TRM_write_cmd(pACB, 0x06, bAddr);
3001                                 
3002         for (i = 0; i < 8; i++) {
3003           /* 
3004            * Read data
3005            */
3006                 trm_reg_write8((NVR_SELECT | NVR_CLOCK) , TRMREG_GEN_NVRAM);
3007                 TRM_wait_30us(pACB);
3008                 trm_reg_write8(NVR_SELECT , TRMREG_GEN_NVRAM);
3009                 /* 
3010                  * Get data bit while falling edge 
3011                  */
3012                 bReadData = trm_reg_read8(TRMREG_GEN_NVRAM);
3013                 bData <<= 1;
3014                 if (bReadData & NVR_BITIN) {
3015                         bData |= 1;
3016                 }
3017                 TRM_wait_30us(pACB);
3018         }
3019         /* 
3020          * Disable chip select 
3021          */
3022         trm_reg_write8(0, TRMREG_GEN_NVRAM);
3023         return (bData);
3024 }
3025
3026 static void
3027 TRM_wait_30us(PACB pACB)
3028 {
3029   
3030         /*    ScsiPortStallExecution(30);        wait 30 us     */
3031         trm_reg_write8(5, TRMREG_GEN_TIMER);
3032         while (!(trm_reg_read8(TRMREG_GEN_STATUS) & GTIMEOUT));
3033         return;
3034 }
3035
3036 static void
3037 TRM_write_cmd(PACB pACB, u_int8_t bCmd, u_int8_t bAddr)
3038 {
3039         int             i;
3040         u_int8_t        bSendData;
3041                                         
3042         for (i = 0; i < 3; i++, bCmd <<= 1) {
3043           /* 
3044            * Program SB+OP code         
3045            */
3046                 bSendData = NVR_SELECT;
3047                 if (bCmd & 0x04)        
3048                         bSendData |= NVR_BITOUT;
3049                 /* start from bit 2 */
3050                 trm_reg_write8(bSendData, TRMREG_GEN_NVRAM);
3051                 TRM_wait_30us(pACB);
3052                 trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM);
3053                 TRM_wait_30us(pACB);
3054         }       
3055         for (i = 0; i < 7; i++, bAddr <<= 1) {
3056           /* 
3057            * Program address            
3058            */
3059                 bSendData = NVR_SELECT;
3060                 if (bAddr & 0x40)       
3061                   /* Start from bit 6   */
3062                         bSendData |= NVR_BITOUT;
3063                 trm_reg_write8(bSendData , TRMREG_GEN_NVRAM);
3064                 TRM_wait_30us(pACB);
3065                 trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM);
3066                 TRM_wait_30us(pACB);
3067         }
3068         trm_reg_write8(NVR_SELECT, TRMREG_GEN_NVRAM);
3069         TRM_wait_30us(pACB);
3070 }
3071
3072 static void
3073 trm_check_eeprom(PNVRAMTYPE pEEpromBuf, PACB pACB)
3074 {
3075         u_int16_t       *wpEeprom = (u_int16_t *) pEEpromBuf;
3076         u_int16_t       wAddr, wCheckSum;
3077         u_long  dAddr, *dpEeprom;
3078
3079         TRM_read_all(pEEpromBuf,pACB);
3080         wCheckSum = 0;
3081         for (wAddr = 0, wpEeprom = (u_int16_t *) pEEpromBuf;
3082             wAddr < 64; wAddr++, wpEeprom++) {
3083                 wCheckSum += *wpEeprom;
3084         }
3085         if (wCheckSum != 0x1234) {
3086           /* 
3087            * Checksum error, load default       
3088            */
3089                 pEEpromBuf->NvramSubVendorID[0] = (u_int8_t) PCI_Vendor_ID_TEKRAM;
3090                 pEEpromBuf->NvramSubVendorID[1] =
3091                   (u_int8_t) (PCI_Vendor_ID_TEKRAM >> 8);
3092                 pEEpromBuf->NvramSubSysID[0] = (u_int8_t) PCI_Device_ID_TRM_S1040;
3093                 pEEpromBuf->NvramSubSysID[1] = 
3094                   (u_int8_t) (PCI_Device_ID_TRM_S1040 >> 8);
3095                 pEEpromBuf->NvramSubClass = 0x00;
3096                 pEEpromBuf->NvramVendorID[0] = (u_int8_t) PCI_Vendor_ID_TEKRAM;
3097                 pEEpromBuf->NvramVendorID[1] =
3098                   (u_int8_t) (PCI_Vendor_ID_TEKRAM >> 8);
3099                 pEEpromBuf->NvramDeviceID[0] = (u_int8_t) PCI_Device_ID_TRM_S1040;
3100                 pEEpromBuf->NvramDeviceID[1] = 
3101                   (u_int8_t) (PCI_Device_ID_TRM_S1040 >> 8);
3102                 pEEpromBuf->NvramReserved = 0x00;
3103
3104                 for (dAddr = 0, dpEeprom = (u_long *) pEEpromBuf->NvramTarget;
3105                     dAddr < 16; dAddr++, dpEeprom++) {
3106                         *dpEeprom = 0x00000077;
3107                         /* NvmTarCfg3,NvmTarCfg2,NvmTarPeriod,NvmTarCfg0 */
3108                 }
3109
3110                 *dpEeprom++ = 0x04000F07;
3111                 /* NvramMaxTag,NvramDelayTime,NvramChannelCfg,NvramScsiId */
3112                 *dpEeprom++ = 0x00000015;
3113                 /* NvramReserved1,NvramBootLun,NvramBootTarget,NvramReserved0 */
3114                 for (dAddr = 0; dAddr < 12; dAddr++, dpEeprom++)
3115                         *dpEeprom = 0x00;
3116                 pEEpromBuf->NvramCheckSum = 0x00;
3117                 for (wAddr = 0, wCheckSum = 0, wpEeprom = (u_int16_t *) pEEpromBuf;
3118                     wAddr < 63; wAddr++, wpEeprom++)
3119                         wCheckSum += *wpEeprom;
3120                 *wpEeprom = 0x1234 - wCheckSum;
3121                 TRM_write_all(pEEpromBuf,pACB);
3122         }
3123         return;
3124 }
3125 static int
3126 trm_initAdapter(PACB pACB, u_int16_t unit, device_t pci_config_id)
3127 {
3128         PNVRAMTYPE      pEEpromBuf;
3129         u_int16_t       wval;
3130         u_int8_t        bval;
3131
3132         pEEpromBuf = &trm_eepromBuf[unit];
3133
3134         /* 250ms selection timeout */
3135         trm_reg_write8(SEL_TIMEOUT, TRMREG_SCSI_TIMEOUT);
3136         /* Mask all the interrupt */
3137         trm_reg_write8(0x00, TRMREG_DMA_INTEN);    
3138         trm_reg_write8(0x00, TRMREG_SCSI_INTEN);     
3139         /* Reset SCSI module */
3140         trm_reg_write16(DO_RSTMODULE, TRMREG_SCSI_CONTROL); 
3141         /* program configuration 0 */
3142         pACB->Config = HCC_AUTOTERM | HCC_PARITY;
3143         if (trm_reg_read8(TRMREG_GEN_STATUS) & WIDESCSI)
3144                 pACB->Config |= HCC_WIDE_CARD;
3145         if (pEEpromBuf->NvramChannelCfg & NAC_POWERON_SCSI_RESET)
3146                 pACB->Config |= HCC_SCSI_RESET;
3147         if (pACB->Config & HCC_PARITY)
3148                 bval = PHASELATCH | INITIATOR | BLOCKRST | PARITYCHECK;
3149         else
3150                 bval = PHASELATCH | INITIATOR | BLOCKRST ;
3151         trm_reg_write8(bval,TRMREG_SCSI_CONFIG0); 
3152         /* program configuration 1 */
3153         trm_reg_write8(0x13, TRMREG_SCSI_CONFIG1); 
3154         /* program Host ID */
3155         bval = pEEpromBuf->NvramScsiId;
3156         trm_reg_write8(bval, TRMREG_SCSI_HOSTID); 
3157         /* set ansynchronous transfer */
3158         trm_reg_write8(0x00, TRMREG_SCSI_OFFSET); 
3159         /* Trun LED control off*/
3160         wval = trm_reg_read16(TRMREG_GEN_CONTROL) & 0x7F;
3161         trm_reg_write16(wval, TRMREG_GEN_CONTROL); 
3162         /* DMA config */
3163         wval = trm_reg_read16(TRMREG_DMA_CONFIG) | DMA_ENHANCE;
3164         trm_reg_write16(wval, TRMREG_DMA_CONFIG); 
3165         /* Clear pending interrupt status */
3166         trm_reg_read8(TRMREG_SCSI_INTSTATUS);
3167         /* Enable SCSI interrupt */
3168         trm_reg_write8(0x7F, TRMREG_SCSI_INTEN); 
3169         trm_reg_write8(EN_SCSIINTR, TRMREG_DMA_INTEN); 
3170         return (0);
3171 }
3172
3173 static PACB
3174 trm_init(u_int16_t unit, device_t pci_config_id)
3175 {
3176         PACB            pACB;
3177         int             rid = PCIR_MAPS;
3178     
3179         pACB = (PACB) device_get_softc(pci_config_id);
3180         if (!pACB) {
3181                 printf("trm%d: cannot allocate ACB !\n", unit);
3182                 return (NULL);
3183         }
3184         bzero (pACB, sizeof (struct _ACB));
3185         pACB->iores = bus_alloc_resource(pci_config_id, SYS_RES_IOPORT, 
3186             &rid, 0, ~0, 1, RF_ACTIVE);
3187         if (pACB->iores == NULL) {
3188                 printf("trm_init: bus_alloc_resource failed!\n");
3189                 return (NULL);
3190         }
3191         pACB->tag = rman_get_bustag(pACB->iores);
3192         pACB->bsh = rman_get_bushandle(pACB->iores);
3193         if (bus_dma_tag_create(/*parent_dmat*/                 NULL, 
3194               /*alignment*/                      1,
3195               /*boundary*/                       0,
3196               /*lowaddr*/  BUS_SPACE_MAXADDR_32BIT,
3197               /*highaddr*/       BUS_SPACE_MAXADDR,
3198               /*filter*/                      NULL, 
3199               /*filterarg*/                   NULL,
3200               /*maxsize*/                 MAXBSIZE,
3201               /*nsegments*/               TRM_NSEG,
3202               /*maxsegsz*/    TRM_MAXTRANSFER_SIZE,
3203               /*flags*/           BUS_DMA_ALLOCNOW,
3204               &pACB->buffer_dmat) != 0) 
3205                 goto bad;
3206         trm_check_eeprom(&trm_eepromBuf[unit],pACB);
3207         trm_initACB(pACB, unit);
3208         if (trm_initAdapter(pACB, unit, pci_config_id)) {
3209                 printf("trm_initAdapter: initial ERROR\n");
3210                 goto bad;
3211         }
3212         return (pACB);
3213 bad:
3214         if (pACB->iores)
3215                 bus_release_resource(pci_config_id, SYS_RES_IOPORT, PCIR_MAPS,
3216                     pACB->iores);
3217         if (pACB->buffer_dmat)
3218                 bus_dma_tag_destroy(pACB->buffer_dmat);
3219         return (NULL);
3220 }
3221
3222 static int
3223 trm_attach(device_t pci_config_id)
3224 {
3225         struct  cam_devq *device_Q;
3226         u_long  device_id;
3227         PACB    pACB = 0;
3228         int     rid = 0;
3229         int unit = device_get_unit(pci_config_id);
3230         
3231         device_id = pci_get_devid(pci_config_id);
3232         /*
3233          * These cards do not allow memory mapped accesses
3234          */
3235         if (device_id == PCI_DEVICEID_TRMS1040) {
3236                 if ((pACB=trm_init((u_int16_t) unit,
3237                         pci_config_id)) == NULL) {
3238                         printf("trm%d: trm_init error!\n",unit);
3239                         return (ENXIO);
3240                 }
3241         } else
3242                 return (ENXIO);
3243         /* After setting up the adapter, map our interrupt */
3244         /*  
3245          * Now let the CAM generic SCSI layer find the SCSI devices on the bus
3246          * start queue to reset to the idle loop.
3247          * Create device queue of SIM(s)
3248          * (MAX_START_JOB - 1) : max_sim_transactions
3249          */
3250         pACB->irq = bus_alloc_resource(pci_config_id, SYS_RES_IRQ, &rid, 0,
3251             ~0, 1, RF_SHAREABLE | RF_ACTIVE);
3252         if (pACB->irq == NULL ||
3253             bus_setup_intr(pci_config_id, pACB->irq, 
3254                            INTR_TYPE_CAM, trm_Interrupt, pACB,
3255                            &pACB->ih, NULL)) {
3256                 printf("trm%d: register Interrupt handler error!\n", unit);
3257                 goto bad;
3258         }
3259         device_Q = cam_simq_alloc(MAX_START_JOB);
3260         if (device_Q == NULL){ 
3261                 printf("trm%d: device_Q == NULL !\n",unit);
3262                 goto bad;
3263         }
3264         /*
3265          * Now tell the generic SCSI layer
3266          * about our bus.
3267          * If this is the xpt layer creating a sim, then it's OK
3268          * to wait for an allocation.
3269          * XXX Should we pass in a flag to indicate that wait is OK?
3270          *
3271          *                    SIM allocation
3272          *
3273          *                 SCSI Interface Modules
3274          * The sim driver creates a sim for each controller.  The sim device
3275          * queue is separately created in order to allow resource sharing betwee
3276          * sims.  For instance, a driver may create one sim for each channel of
3277          * a multi-channel controller and use the same queue for each channel.
3278          * In this way, the queue resources are shared across all the channels
3279          * of the multi-channel controller.
3280          * trm_action     : sim_action_func
3281          * trm_poll       : sim_poll_func
3282          * "trm"        : sim_name ,if sim_name =  "xpt" ..M_DEVBUF,M_WAITOK
3283          * pACB         : *softc    if sim_name <> "xpt" ..M_DEVBUF,M_NOWAIT
3284          * pACB->unit   : unit
3285          * 1            : max_dev_transactions
3286          * MAX_TAGS     : max_tagged_dev_transactions
3287          *
3288          *  *******Construct our first channel SIM entry
3289          */
3290         pACB->psim = cam_sim_alloc(trm_action,
3291             trm_poll,
3292             "trm",
3293             pACB,
3294             unit,
3295             1,
3296             MAX_TAGS_CMD_QUEUE,
3297             device_Q);
3298         cam_simq_release(device_Q);  /* SIM allocate fault*/
3299         if (pACB->psim == NULL) {
3300                 printf("trm%d: SIM allocate fault !\n",unit);
3301                 goto bad;
3302         }
3303         if (xpt_bus_register(pACB->psim, 0) != CAM_SUCCESS)  {
3304                 printf("trm%d: xpt_bus_register fault !\n",unit);
3305                 goto bad;
3306         }
3307         if (xpt_create_path(&pACB->ppath,
3308               NULL,
3309               cam_sim_path(pACB->psim),
3310               CAM_TARGET_WILDCARD,
3311               CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
3312                 printf("trm%d: xpt_create_path fault !\n",unit);
3313                 xpt_bus_deregister(cam_sim_path(pACB->psim));
3314                 goto bad;
3315                 /* 
3316                  * cam_sim_free(pACB->psim, TRUE);  free_devq 
3317                  * pACB->psim = NULL;
3318                  */
3319                 return (ENXIO);
3320         }
3321         return (0);
3322 bad:
3323         if (pACB->iores)
3324                 bus_release_resource(pci_config_id, SYS_RES_IOPORT, PCIR_MAPS,
3325                     pACB->iores);
3326         if (pACB->buffer_dmat)
3327                 bus_dma_tag_destroy(pACB->buffer_dmat);
3328         if (pACB->ih)
3329                 bus_teardown_intr(pci_config_id, pACB->irq, pACB->ih);
3330         if (pACB->irq)
3331                 bus_release_resource(pci_config_id, SYS_RES_IRQ, 0, pACB->irq);
3332         if (pACB->psim)
3333                 cam_sim_free(pACB->psim);
3334         
3335         return (ENXIO);
3336         
3337 }
3338
3339 /*
3340 *                  pci_device
3341 *         trm_probe (device_t tag, pcidi_t type)
3342 *
3343 */
3344 static int
3345 trm_probe(device_t tag)
3346 {
3347   
3348         if (pci_get_devid(tag) == PCI_DEVICEID_TRMS1040) { 
3349                 device_set_desc(tag,
3350                     "Tekram DC395U/UW/F DC315/U Fast20 Wide SCSI Adapter");
3351                 return (0);
3352         } else
3353                 return (ENXIO);
3354 }
3355
3356 static int
3357 trm_detach(device_t dev)
3358 {
3359         PACB pACB = device_get_softc(dev);
3360
3361         bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS, pACB->iores);
3362         bus_dma_tag_destroy(pACB->buffer_dmat); 
3363         bus_teardown_intr(dev, pACB->irq, pACB->ih);
3364         bus_release_resource(dev, SYS_RES_IRQ, 0, pACB->irq);
3365         xpt_async(AC_LOST_DEVICE, pACB->ppath, NULL);
3366         xpt_free_path(pACB->ppath);
3367         xpt_bus_deregister(cam_sim_path(pACB->psim));
3368         cam_sim_free(pACB->psim);
3369         return (0);
3370 }
3371 static device_method_t trm_methods[] = {
3372         /* Device interface */
3373         DEVMETHOD(device_probe,         trm_probe),
3374         DEVMETHOD(device_attach,        trm_attach),
3375         DEVMETHOD(device_detach,        trm_detach),
3376         { 0, 0 }
3377 };
3378
3379 static driver_t trm_driver = {
3380         "trm", trm_methods, sizeof(struct _ACB)
3381 };
3382
3383 static devclass_t trm_devclass;
3384 DRIVER_MODULE(trm, pci, trm_driver, trm_devclass, 0, 0);