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