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