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