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