* added 0.99 linux version
[mascara-docs.git] / i386 / linux / linux-2.3.21 / drivers / scsi / scsiiom.c
blob3923cb8e406f162af52635c0270c90936124a96d
1 /***********************************************************************
2 * FILE NAME : SCSIIOM.C *
3 * BY : C.L. Huang, ching@tekram.com.tw *
4 * Description: Device Driver for Tekram DC-390 (T) PCI SCSI *
5 * Bus Master Host Adapter *
6 ***********************************************************************/
7 /* $Id: scsiiom.c,v 2.15 1998/12/25 17:33:27 garloff Exp $ */
9 UCHAR
10 dc390_StartSCSI(PACB pACB, PDCB pDCB, PSRB pSRB)
12 USHORT wlval;
13 UCHAR bval, bval1;
15 pSRB->TagNumber = 31;
16 DC390_write8(Scsi_Dest_ID, pDCB->UnitSCSIID);
17 DC390_write8(Sync_Period, pDCB->SyncPeriod);
18 DC390_write8(Sync_Offset, pDCB->SyncOffset);
19 DC390_write8(CtrlReg1, pDCB->CtrlR1);
20 DC390_write8(CtrlReg3, pDCB->CtrlR3);
21 DC390_write8(CtrlReg4, pDCB->CtrlR4);
22 DC390_write8(ScsiCmd, CLEAR_FIFO_CMD); /* Flush FIFO */
23 DEBUG1(printk(KERN_INFO "DC390: Start SCSI command: %02x (Sync:%02x)\n", \
24 pSRB->CmdBlock[0], pDCB->SyncMode);
26 pSRB->ScsiPhase = SCSI_NOP0;
27 //pSRB->MsgOutBuf[0] = MSG_NOP;
28 //pSRB->MsgCnt = 0;
29 bval = pDCB->IdentifyMsg;
30 if (!(pDCB->SyncMode & EN_ATN_STOP)) { /* Don't always try send Extended messages on arbitration */
31 if ((pSRB->CmdBlock[0] == INQUIRY) ||
32 (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
33 (pSRB->SRBFlag & AUTO_REQSENSE)) {
34 bval &= 0xBF; /* No DisConn */
35 DC390_write8(ScsiFifo, bval);
36 bval1 = SEL_W_ATN;
37 pSRB->SRBState = SRB_START_;
38 DEBUG1(printk(KERN_DEBUG "DC390: No DisCn, No TagQ (%02x, %02x)\n", bval, bval1);
40 if (pDCB->SyncMode & SYNC_ENABLE) {
41 if (!(pDCB->IdentifyMsg & 7) || /* LUN == 0 || Cmd != INQUIRY */
42 (pSRB->CmdBlock[0] != INQUIRY)) {
43 bval1 = SEL_W_ATN_STOP; /* Try to establish SYNC nego */
44 pSRB->SRBState = SRB_MSGOUT;
47 } else { /* TagQ ? */
48 DC390_write8(ScsiFifo, bval);
49 if (pDCB->SyncMode & EN_TAG_QUEUEING) {
50 DC390_write8(ScsiFifo, MSG_SIMPLE_QTAG);
51 DEBUG1(printk(KERN_DEBUG "DC390: %sDisCn, TagQ (%02x, %02x, %08lx)\n", (bval & 0x40 ? "" : "No "), bval, SEL_W_ATN3, pDCB->TagMask);
53 bval = 0;
54 wlval = 1;
55 while (wlval & pDCB->TagMask) {
56 bval++;
57 wlval <<= 1;
59 pDCB->TagMask |= wlval;
60 DC390_write8(ScsiFifo, bval);
61 pSRB->TagNumber = bval;
62 DEBUG1(printk(KERN_DEBUG "DC390: SRB %p (Cmd %li), Tag %02x queued\n", pSRB, pSRB->pcmd->pid, bval);
64 bval1 = SEL_W_ATN3;
65 pSRB->SRBState = SRB_START_;
66 } else { /* No TagQ */
67 bval1 = SEL_W_ATN;
68 DEBUG1(printk(KERN_DEBUG "DC390: %sDisCn, No TagQ (%02x, %02x, %08lx)\n", (bval & 0x40 ? "" : "No "), bval, bval1, pDCB->TagMask);
70 pSRB->SRBState = SRB_START_;
74 } else { /* ATN_STOP: Always try to establish Sync nego */
75 if ((pSRB->CmdBlock[0] == INQUIRY) ||
76 (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
77 (pSRB->SRBFlag & AUTO_REQSENSE)) {
78 bval &= 0xBF; /* No DisConn */
79 DC390_write8(ScsiFifo, bval);
80 bval1 = SEL_W_ATN;
81 DEBUG1(printk(KERN_DEBUG "DC390: No DisCn, No TagQ (%02x, %02x)\n", bval, bval1);
83 pSRB->SRBState = SRB_START_;
84 /* ??? */
85 if (pDCB->SyncMode & SYNC_ENABLE) {
86 if (!(pDCB->IdentifyMsg & 7) || /* LUN == 0 || Cmd != INQUIRY */
87 (pSRB->CmdBlock[0] != INQUIRY)) {
88 bval1 = SEL_W_ATN_STOP; /* Try to establish Sync nego */
89 pSRB->SRBState = SRB_MSGOUT;
92 } else { /* TagQ ? */
93 DC390_write8(ScsiFifo, bval);
94 if (pDCB->SyncMode & EN_TAG_QUEUEING) {
95 pSRB->MsgOutBuf[0] = MSG_SIMPLE_QTAG;
96 DEBUG1(printk(KERN_DEBUG "DC390: %sDisCn, TagQ (%02x, %02x, %08lx)\n", (bval & 0x40 ? "" : "No "), bval, SEL_W_ATN_STOP, pDCB->TagMask);
98 bval = 0;
99 wlval = 1;
100 while (wlval & pDCB->TagMask) {
101 bval++;
102 wlval <<= 1;
104 pDCB->TagMask |= wlval;
105 pSRB->TagNumber = bval;
106 DEBUG1(printk(KERN_DEBUG "DC390: SRB %p (Cmd %li), Tag %02x queued\n", pSRB, pSRB->pcmd->pid, bval);
108 pSRB->MsgOutBuf[1] = bval;
109 pSRB->MsgCnt = 2;
110 bval1 = SEL_W_ATN_STOP;
111 pSRB->SRBState = SRB_START_; /* ?? */
112 } else { /* No TagQ */
113 pSRB->MsgOutBuf[0] = MSG_NOP;
114 pSRB->MsgCnt = 1;
115 pSRB->SRBState = SRB_START_;
116 bval1 = SEL_W_ATN_STOP;
117 DEBUG1(printk(KERN_DEBUG "DC390: %sDisCn, No TagQ (%02x, %02x, %08lx)\n", (bval & 0x40 ? "" : "No "), bval, bval1, pDCB->TagMask);
122 if (bval1 != SEL_W_ATN_STOP) { /* Command is written in CommandPhase, if SEL_W_ATN_STOP ... */
123 if (pSRB->SRBFlag & AUTO_REQSENSE) {
124 bval = 0;
125 DC390_write8(ScsiFifo, REQUEST_SENSE);
126 DC390_write8(ScsiFifo, pDCB->IdentifyMsg << 5);
127 DC390_write8(ScsiFifo, bval);
128 DC390_write8(ScsiFifo, bval);
129 DC390_write8(ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
130 DC390_write8(ScsiFifo, bval);
131 DEBUG1(printk(KERN_DEBUG "DC390: AutoReqSense !\n");
133 } else { /* write cmnd to bus */
134 PUCHAR ptr;
135 UCHAR i;
136 ptr = (PUCHAR) pSRB->CmdBlock;
137 for (i = 0; i < pSRB->ScsiCmdLen; i++)
138 DC390_write8(ScsiFifo, *(ptr++));
141 /* Check if we can't win arbitration */
142 if (DC390_read8(Scsi_Status) & INTERRUPT) {
143 pSRB->SRBState = SRB_READY;
144 pDCB->TagMask &= ~(1 << pSRB->TagNumber);
145 DEBUG0(printk(KERN_WARNING "DC390: Interrupt during StartSCSI!\n");
147 return 1;
148 } else {
149 pSRB->ScsiPhase = SCSI_NOP1;
150 DEBUG0(if (pACB->pActiveDCB) \
151 printk(KERN_WARNING "DC390: ActiveDCB != 0\n");)
152 DEBUG0(if (pDCB->pActiveSRB) \
153 printk(KERN_WARNING "DC390: ActiveSRB != 0\n");)
154 pACB->pActiveDCB = pDCB;
155 pDCB->pActiveSRB = pSRB;
156 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
157 DC390_write8(ScsiCmd, bval1);
158 return 0;
162 //#define DMA_INT EN_DMA_INT /*| EN_PAGE_INT*/
163 #define DMA_INT 0
165 #if DMA_INT
166 /* This is similar to AM53C974.c ... */
167 static UCHAR
168 dc390_dma_intr(PACB pACB)
170 PSRB pSRB;
171 UCHAR dstate;
172 DEBUG0(USHORT pstate;
173 PDEVDECL1;
175 DEBUG0(PDEVSET1;
177 DEBUG0(PCI_READ_CONFIG_WORD(PDEV, PCI_STATUS, &pstate);
179 DEBUG0(if (pstate & (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY)) \
181 printk(KERN_WARNING "DC390: PCI state = %04x!\n", pstate); \
182 PCI_WRITE_CONFIG_WORD(PDEV, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));
185 dstate = DC390_read8(DMA_Status);
187 if (!pACB->pActiveDCB || !pACB->pActiveDCB->pActiveSRB)
188 return dstate;
189 else
190 pSRB = pACB->pActiveDCB->pActiveSRB;
192 if (dstate & (DMA_XFER_ABORT | DMA_XFER_ERROR | POWER_DOWN | PCI_MS_ABORT)) {
193 printk(KERN_ERR "DC390: DMA error (%02x)!\n", dstate);
194 return dstate;
196 if (dstate & DMA_XFER_DONE) {
197 ULONG residual, xferCnt;
198 int ctr = 5000000;
199 if (!(DC390_read8(DMA_Cmd) & READ_DIRECTION)) {
200 do {
201 DEBUG1(printk(KERN_DEBUG "DC390: read residual bytes ... \n");
203 dstate = DC390_read8(DMA_Status);
204 residual = DC390_read8(CtcReg_Low) | DC390_read8(CtcReg_Mid) << 8 |
205 DC390_read8(CtcReg_High) << 16;
206 residual += DC390_read8(Current_Fifo) & 0x1f;
207 } while (residual && !(dstate & SCSI_INTERRUPT) && --ctr);
208 if (!ctr)
209 printk(KERN_CRIT "DC390: dma_intr: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32(DMA_Wk_ByteCntr));
210 /* residual = ... */
211 } else
212 residual = 0;
214 /* ??? */
216 xferCnt = pSRB->SGToBeXferLen - residual;
217 pSRB->SGBusAddr += xferCnt;
218 pSRB->TotalXferredLen += xferCnt;
219 pSRB->SGToBeXferLen = residual;
220 #ifdef DC390_DEBUG0
221 printk(KERN_INFO "DC390: DMA: residual = %i, xfer = %i\n",
222 (unsigned int) residual, (unsigned int) xferCnt);
223 #endif
225 DC390_write8(DMA_Cmd, DMA_IDLE_CMD);
227 dc390_laststatus &= ~0xff000000;
228 dc390_laststatus |= dstate << 24;
229 return dstate;
231 #endif
233 void __inline__
234 DC390_Interrupt(int irq, void *dev_id, struct pt_regs *regs)
236 PACB pACB;
237 PDCB pDCB;
238 PSRB pSRB;
239 UCHAR sstatus = 0;
240 UCHAR phase, i;
241 void (*stateV) (PACB, PSRB, PUCHAR);
242 UCHAR istate, istatus;
243 #if DMA_INT
244 UCHAR dstatus;
245 #endif
246 DC390_AFLAGS DC390_IFLAGS DC390_DFLAGS
248 pACB = dc390_pACB_start;
250 if (pACB == 0) {
251 printk(KERN_WARNING "DC390: Interrupt on uninitialized adapter!\n");
252 return;
254 DC390_LOCK_DRV;
256 for (i = 0; i < dc390_adapterCnt; i++) {
257 if (pACB->IRQLevel == (UCHAR) irq) {
258 sstatus = DC390_read8(Scsi_Status);
259 if (sstatus & INTERRUPT)
260 break;
261 else
262 pACB = pACB->pNextACB;
263 } else {
264 pACB = pACB->pNextACB;
268 DEBUG1(printk(KERN_DEBUG "sstatus=%02x,", sstatus);
270 if (!pACB) {
271 DC390_UNLOCK_DRV;
272 return;
275 #if DMA_INT
276 DC390_LOCK_IO;
277 DC390_LOCK_ACB;
278 dstatus = dc390_dma_intr(pACB);
279 DC390_UNLOCK_ACB;
280 DC390_UNLOCK_IO;
282 DEBUG1(printk(KERN_DEBUG "dstatus=%02x,", dstatus);
284 if (!(dstatus & SCSI_INTERRUPT)) {
285 DEBUG0(printk(KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n");
287 DC390_UNLOCK_DRV;
288 return;
290 #else
291 //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
292 //dstatus = DC390_read8 (DMA_Status);
293 //DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
294 #endif
296 DC390_LOCK_IO;
297 DC390_LOCK_ACB;
298 DC390_UNLOCK_DRV_NI; /* Allow _other_ CPUs to process IRQ (useful for shared IRQs) */
300 istate = DC390_read8(Intern_State);
301 istatus = DC390_read8(INT_Status); /* This clears Scsi_Status, Intern_State and INT_Status ! */
303 DEBUG1(printk(KERN_INFO "Istatus(Res,Inv,Dis,Serv,Succ,ReS,SelA,Sel)=%02x,", istatus);
305 dc390_laststatus &= ~0x00ffffff;
306 dc390_laststatus |= /* dstatus<<24 | */ sstatus << 16 | istate << 8 | istatus;
308 if (sstatus & ILLEGAL_OP_ERR) {
309 printk("DC390: Illegal Operation detected (%08lx)!\n", dc390_laststatus);
310 dc390_dumpinfo(pACB, pACB->pActiveDCB, pACB->pActiveDCB->pActiveSRB);
313 if (istatus & DISCONNECTED) {
314 dc390_Disconnect(pACB);
315 goto unlock;
317 if (istatus & RESELECTED) {
318 dc390_Reselect(pACB);
319 goto unlock;
321 if (istatus & (SUCCESSFUL_OP | SERVICE_REQUEST)) {
322 pDCB = pACB->pActiveDCB;
323 if (!pDCB) {
324 printk(KERN_ERR "DC390: Suc. op/ Serv. req: pActiveDCB = 0!\n");
325 goto unlock;
327 pSRB = pDCB->pActiveSRB;
328 if (pDCB->DCBFlag & ABORT_DEV_)
329 dc390_EnableMsgOut_Abort(pACB, pSRB);
331 phase = pSRB->ScsiPhase;
332 DEBUG1(printk(KERN_INFO "DC390: [%i]%s(0) (%02x)\n", phase, dc390_p0_str[phase], sstatus);
334 stateV = (void *) dc390_phase0[phase];
335 (*stateV) (pACB, pSRB, &sstatus);
337 pSRB->ScsiPhase = sstatus & 7;
338 phase = (UCHAR) sstatus & 7;
339 DEBUG1(printk(KERN_INFO "DC390: [%i]%s(1) (%02x)\n", phase, dc390_p1_str[phase], sstatus);
341 stateV = (void *) dc390_phase1[phase];
342 (*stateV) (pACB, pSRB, &sstatus);
343 goto unlock;
345 if (istatus & INVALID_CMD) {
346 dc390_InvalidCmd(pACB);
347 goto unlock;
349 if (istatus & SCSI_RESET) {
350 dc390_ScsiRstDetect(pACB);
351 goto unlock;
353 unlock:
354 DC390_LOCK_DRV_NI;
355 DC390_UNLOCK_ACB;
356 DC390_UNLOCK_IO;
357 DC390_UNLOCK_DRV; /* Restore initial flags */
360 void do_DC390_Interrupt(int irq, void *dev_id, struct pt_regs *regs)
362 DEBUG1(printk(KERN_INFO "DC390: Irq (%i) caught: ", irq);
364 /* Locking is done in DC390_Interrupt */
365 DC390_Interrupt(irq, dev_id, regs);
366 DEBUG1(printk(".. IRQ returned\n");
370 void dc390_DataOut_0(PACB pACB, PSRB pSRB, PUCHAR psstatus)
372 UCHAR sstatus;
373 PSGL psgl;
374 ULONG ResidCnt, xferCnt;
375 UCHAR dstate = 0;
377 sstatus = *psstatus;
379 if (!(pSRB->SRBState & SRB_XFERPAD)) {
380 if (sstatus & (PARITY_ERR | ILLEGAL_OP_ERR))
381 pSRB->SRBStatus |= PARITY_ERROR;
383 if (sstatus & COUNT_2_ZERO) {
384 int ctr = 5000000; /* only try for about a tenth of a second */
385 while (--ctr && !((dstate = DC390_read8(DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen);
386 if (!ctr)
387 printk(KERN_CRIT "DC390: Deadlock in DataOut_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32(DMA_Wk_ByteCntr));
388 dc390_laststatus &= ~0xff000000;
389 dc390_laststatus |= dstate << 24;
390 pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
391 pSRB->SGIndex++;
392 if (pSRB->SGIndex < pSRB->SGcount) {
393 pSRB->pSegmentList++;
394 psgl = pSRB->pSegmentList;
396 pSRB->SGBusAddr = virt_to_bus(psgl->address);
397 pSRB->SGToBeXferLen = (ULONG) psgl->length;
398 } else
399 pSRB->SGToBeXferLen = 0;
400 } else {
401 ResidCnt = (ULONG) DC390_read8(Current_Fifo) & 0x1f;
402 ResidCnt |= (ULONG) DC390_read8(CtcReg_High) << 16;
403 ResidCnt |= (ULONG) DC390_read8(CtcReg_Mid) << 8;
404 ResidCnt += (ULONG) DC390_read8(CtcReg_Low);
406 xferCnt = pSRB->SGToBeXferLen - ResidCnt;
407 pSRB->SGBusAddr += xferCnt;
408 pSRB->TotalXferredLen += xferCnt;
409 pSRB->SGToBeXferLen = ResidCnt;
412 DC390_write8(DMA_Cmd, WRITE_DIRECTION + DMA_IDLE_CMD); /* | DMA_INT */
415 void dc390_DataIn_0(PACB pACB, PSRB pSRB, PUCHAR psstatus)
417 UCHAR sstatus, residual, bval;
418 PSGL psgl;
419 ULONG ResidCnt, xferCnt, i;
420 PUCHAR ptr;
422 sstatus = *psstatus;
424 if (!(pSRB->SRBState & SRB_XFERPAD)) {
425 if (sstatus & (PARITY_ERR | ILLEGAL_OP_ERR))
426 pSRB->SRBStatus |= PARITY_ERROR;
428 if (sstatus & COUNT_2_ZERO) {
429 int ctr = 5000000; /* only try for about a tenth of a second */
430 int dstate = 0;
431 while (--ctr && !((dstate = DC390_read8(DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen);
432 if (!ctr)
433 printk(KERN_CRIT "DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32(DMA_Wk_ByteCntr));
434 if (!ctr)
435 printk(KERN_CRIT "DC390: DataIn_0: DMA State: %i\n", dstate);
436 dc390_laststatus &= ~0xff000000;
437 dc390_laststatus |= dstate << 24;
438 DEBUG1(ResidCnt = ((ULONG) DC390_read8(CtcReg_High) << 16) \
439 +((ULONG) DC390_read8(CtcReg_Mid) << 8) \
440 +((ULONG) DC390_read8(CtcReg_Low));
442 DEBUG1(printk(KERN_DEBUG "Count_2_Zero (ResidCnt=%li,ToBeXfer=%li),", ResidCnt, pSRB->SGToBeXferLen);
444 DC390_write8(DMA_Cmd, READ_DIRECTION + DMA_IDLE_CMD); /* | DMA_INT */
446 pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
447 pSRB->SGIndex++;
448 if (pSRB->SGIndex < pSRB->SGcount) {
449 pSRB->pSegmentList++;
450 psgl = pSRB->pSegmentList;
452 pSRB->SGBusAddr = virt_to_bus(psgl->address);
453 pSRB->SGToBeXferLen = (ULONG) psgl->length;
454 } else
455 pSRB->SGToBeXferLen = 0;
456 } else { /* phase changed */
457 residual = 0;
458 bval = DC390_read8(Current_Fifo);
459 while (bval & 0x1f) {
460 DEBUG1(printk(KERN_DEBUG "Check for residuals,");
462 if ((bval & 0x1f) == 1) {
463 for (i = 0; i < 0x100; i++) {
464 bval = DC390_read8(Current_Fifo);
465 if (!(bval & 0x1f))
466 goto din_1;
467 else if (i == 0x0ff) {
468 residual = 1; /* ;1 residual byte */
469 goto din_1;
472 } else
473 bval = DC390_read8(Current_Fifo);
475 din_1:
476 DC390_write8(DMA_Cmd, READ_DIRECTION + DMA_BLAST_CMD);
477 for (i = 0xa000; i; i--) {
478 bval = DC390_read8(DMA_Status);
479 if (bval & BLAST_COMPLETE)
480 break;
482 /* It seems a DMA Blast abort isn't that bad ... */
483 if (!i)
484 printk(KERN_ERR "DC390: DMA Blast aborted unfinished!\n");
485 //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
486 dc390_laststatus &= ~0xff000000;
487 dc390_laststatus |= bval << 24;
489 DEBUG1(printk(KERN_DEBUG "Blast: Read %li times DMA_Status %02x", 0xa000 - i, bval);
491 ResidCnt = (ULONG) DC390_read8(CtcReg_High);
492 ResidCnt <<= 8;
493 ResidCnt |= (ULONG) DC390_read8(CtcReg_Mid);
494 ResidCnt <<= 8;
495 ResidCnt |= (ULONG) DC390_read8(CtcReg_Low);
497 xferCnt = pSRB->SGToBeXferLen - ResidCnt;
498 pSRB->SGBusAddr += xferCnt;
499 pSRB->TotalXferredLen += xferCnt;
500 pSRB->SGToBeXferLen = ResidCnt;
502 if (residual) {
503 bval = DC390_read8(ScsiFifo); /* get one residual byte */
504 ptr = (PUCHAR) bus_to_virt(pSRB->SGBusAddr);
505 *ptr = bval;
506 pSRB->SGBusAddr++;
507 xferCnt++;
508 pSRB->TotalXferredLen++;
509 pSRB->SGToBeXferLen--;
511 DEBUG1(printk(KERN_DEBUG "Xfered: %li, Total: %li, Remaining: %li\n", xferCnt, \
512 pSRB->TotalXferredLen, pSRB->SGToBeXferLen);
518 static void dc390_Command_0(PACB pACB, PSRB pSRB, PUCHAR psstatus)
522 static void dc390_Status_0(PACB pACB, PSRB pSRB, PUCHAR psstatus)
525 pSRB->TargetStatus = DC390_read8(ScsiFifo);
526 //udelay (1);
527 pSRB->EndMessage = DC390_read8(ScsiFifo); /* get message */
529 *psstatus = SCSI_NOP0;
530 pSRB->SRBState = SRB_COMPLETED;
531 DC390_write8(ScsiCmd, MSG_ACCEPTED_CMD);
534 static void dc390_MsgOut_0(PACB pACB, PSRB pSRB, PUCHAR psstatus)
536 if (pSRB->SRBState & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT))
537 *psstatus = SCSI_NOP0;
538 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
542 static void __inline__
543 dc390_reprog(PACB pACB, PDCB pDCB)
545 DC390_write8(Sync_Period, pDCB->SyncPeriod);
546 DC390_write8(Sync_Offset, pDCB->SyncOffset);
547 DC390_write8(CtrlReg3, pDCB->CtrlR3);
548 DC390_write8(CtrlReg4, pDCB->CtrlR4);
549 dc390_SetXferRate(pACB, pDCB);
553 #ifdef DC390_DEBUG0
554 static void dc390_printMsg(UCHAR * MsgBuf, UCHAR len)
556 int i;
557 printk(" %02x", MsgBuf[0]);
558 for (i = 1; i < len; i++)
559 printk(" %02x", MsgBuf[i]);
560 printk("\n");
562 #endif
564 #define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD)
566 /* reject_msg */
567 static void __inline__
568 dc390_MsgIn_reject(PACB pACB, PSRB pSRB)
570 pSRB->MsgOutBuf[0] = MSG_REJECT_;
571 pSRB->MsgCnt = 1;
572 DC390_ENABLE_MSGOUT;
573 DEBUG0(printk(KERN_INFO "DC390: Reject message\n");
577 /* abort command */
578 static void __inline__
579 dc390_EnableMsgOut_Abort(PACB pACB, PSRB pSRB)
581 pSRB->MsgOutBuf[0] = MSG_ABORT;
582 pSRB->MsgCnt = 1;
583 DC390_ENABLE_MSGOUT;
584 pSRB->pSRBDCB->DCBFlag &= ~ABORT_DEV_;
587 static PSRB
588 dc390_MsgIn_QTag(PACB pACB, PDCB pDCB, UCHAR tag)
590 PSRB lastSRB = pDCB->pGoingLast;
591 PSRB pSRB = pDCB->pGoingSRB;
593 if (pSRB) {
594 for (; pSRB;) {
595 if (pSRB->TagNumber == tag)
596 break;
597 if (pSRB == lastSRB)
598 goto mingx0;
599 pSRB = pSRB->pNextSRB;
602 if (pDCB->DCBFlag & ABORT_DEV_) {
603 pSRB->SRBState = SRB_ABORT_SENT;
604 dc390_EnableMsgOut_Abort(pACB, pSRB);
606 if (!(pSRB->SRBState & SRB_DISCONNECT))
607 goto mingx0;
609 pDCB->pActiveSRB = pSRB;
610 pSRB->SRBState = SRB_DATA_XFER;
611 } else {
612 mingx0:
613 pSRB = pACB->pTmpSRB;
614 pSRB->SRBState = SRB_UNEXPECT_RESEL;
615 pDCB->pActiveSRB = pSRB;
616 pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;
617 pSRB->MsgCnt = 1;
618 DC390_ENABLE_MSGOUT;
620 return pSRB;
624 /* set async transfer mode */
625 static void dc390_MsgIn_set_async(PACB pACB, PSRB pSRB)
627 PDCB pDCB = pSRB->pSRBDCB;
628 if (!(pSRB->SRBState & DO_SYNC_NEGO))
629 printk("DC390: Target %i initiates Non-Sync?\n", pDCB->UnitSCSIID);
630 pSRB->SRBState &= ~DO_SYNC_NEGO;
631 pDCB->SyncMode &= ~(SYNC_ENABLE + SYNC_NEGO_DONE);
632 pDCB->SyncPeriod = 0;
633 pDCB->SyncOffset = 0;
634 //pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
635 pDCB->CtrlR3 = FAST_CLK; /* fast clock / normal scsi */
636 pDCB->CtrlR4 &= 0x3f;
637 pDCB->CtrlR4 |= pACB->glitch_cfg; /* glitch eater */
638 dc390_reprog(pACB, pDCB);
641 /* set sync transfer mode */
642 static void dc390_MsgIn_set_sync(PACB pACB, PSRB pSRB)
644 UCHAR bval;
645 USHORT wval, wval1;
646 PDCB pDCB = pSRB->pSRBDCB;
647 UCHAR oldsyncperiod = pDCB->SyncPeriod;
648 UCHAR oldsyncoffset = pDCB->SyncOffset;
650 if (!(pSRB->SRBState & DO_SYNC_NEGO)) {
651 printk("DC390: Target %i initiates Sync: %ins %i ... answer ...\n",
652 pDCB->UnitSCSIID, pSRB->MsgInBuf[3] << 2, pSRB->MsgInBuf[4]);
654 /* reject */
655 //dc390_MsgIn_reject (pACB, pSRB);
656 //return dc390_MsgIn_set_async (pACB, pSRB);
658 /* Reply with corrected SDTR Message */
659 if (pSRB->MsgInBuf[4] > 15) {
660 printk("DC390: Lower Sync Offset to 15\n");
661 pSRB->MsgInBuf[4] = 15;
663 if (pSRB->MsgInBuf[3] < pDCB->NegoPeriod) {
664 printk("DC390: Set sync nego period to %ins\n", pDCB->NegoPeriod << 2);
665 pSRB->MsgInBuf[3] = pDCB->NegoPeriod;
667 memcpy(pSRB->MsgOutBuf, pSRB->MsgInBuf, 5);
668 pSRB->MsgCnt = 5;
669 DC390_ENABLE_MSGOUT;
672 pSRB->SRBState &= ~DO_SYNC_NEGO;
673 pDCB->SyncMode |= SYNC_ENABLE + SYNC_NEGO_DONE;
674 pDCB->SyncOffset &= 0x0f0;
675 pDCB->SyncOffset |= pSRB->MsgInBuf[4];
676 pDCB->NegoPeriod = pSRB->MsgInBuf[3];
678 wval = (USHORT) pSRB->MsgInBuf[3];
679 wval = wval << 2;
680 wval -= 3;
681 wval1 = wval / 25; /* compute speed */
682 if ((wval1 * 25) != wval)
683 wval1++;
684 bval = FAST_CLK + FAST_SCSI; /* fast clock / fast scsi */
686 pDCB->CtrlR4 &= 0x3f; /* Glitch eater: 12ns less than normal */
687 if (pACB->glitch_cfg != NS_TO_GLITCH(0))
688 pDCB->CtrlR4 |= NS_TO_GLITCH(((GLITCH_TO_NS(pACB->glitch_cfg)) - 1));
689 else
690 pDCB->CtrlR4 |= NS_TO_GLITCH(0);
691 if (wval1 < 4)
692 pDCB->CtrlR4 |= NS_TO_GLITCH(0); /* Ultra */
694 if (wval1 >= 8) {
695 wval1--; /* Timing computation differs by 1 from FAST_SCSI */
696 bval = FAST_CLK; /* fast clock / normal scsi */
697 pDCB->CtrlR4 |= pACB->glitch_cfg; /* glitch eater */
699 pDCB->CtrlR3 = bval;
700 pDCB->SyncPeriod = (UCHAR) wval1;
702 if ((oldsyncperiod != wval1 || oldsyncoffset != pDCB->SyncOffset) && pDCB->UnitSCSILUN == 0) {
703 if (!(bval & FAST_SCSI))
704 wval1++;
705 printk("DC390: Target %i: Sync transfer %i.%1i MHz, Offset %i\n", pDCB->UnitSCSIID,
706 40 / wval1, ((40 % wval1) * 10 + wval1 / 2) / wval1, pDCB->SyncOffset & 0x0f);
708 dc390_reprog(pACB, pDCB);
712 /* According to the docs, the AM53C974 reads the message and
713 * generates a Succesful Operation IRQ before asserting ACK for
714 * the last byte (how does it know whether it's the last ?) */
715 /* The old code handled it in another way, indicating, that on
716 * every message byte an IRQ is generated and every byte has to
717 * be manually ACKed. Hmmm ? (KG, 98/11/28) */
718 /* The old implementation was correct. Sigh! */
720 /* Check if the message is complete */
721 static UCHAR __inline__
722 dc390_MsgIn_complete(UCHAR * msgbuf, ULONG len)
724 if (*msgbuf == MSG_EXTENDED) {
725 if (len < 2)
726 return 0;
727 if (len < msgbuf[1] + 2)
728 return 0;
729 } else if (*msgbuf >= 0x20 && *msgbuf <= 0x2f) // two byte messages
731 if (len < 2)
732 return 0;
733 return 1;
738 /* read and eval received messages */
739 void dc390_MsgIn_0(PACB pACB, PSRB pSRB, PUCHAR psstatus)
741 PDCB pDCB = pACB->pActiveDCB;
743 /* Read the msg */
745 pSRB->MsgInBuf[pACB->MsgLen++] = DC390_read8(ScsiFifo);
746 //pSRB->SRBState = 0;
748 /* Msg complete ? */
749 if (dc390_MsgIn_complete(pSRB->MsgInBuf, pACB->MsgLen)) {
750 DEBUG0(printk(KERN_INFO "DC390: MsgIn:");
751 dc390_printMsg(pSRB->MsgInBuf, pACB->MsgLen);
753 /* Now eval the msg */
754 switch (pSRB->MsgInBuf[0]) {
755 case MSG_DISCONNECT:
756 pSRB->SRBState = SRB_DISCONNECT;
757 break;
759 case MSG_SIMPLE_QTAG:
760 case MSG_HEAD_QTAG:
761 case MSG_ORDER_QTAG:
762 pSRB = dc390_MsgIn_QTag(pACB, pDCB, pSRB->MsgInBuf[1]);
763 break;
765 case MSG_REJECT_:
766 DC390_write8(ScsiCmd, RESET_ATN_CMD);
767 pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
768 if (pSRB->SRBState & DO_SYNC_NEGO)
769 dc390_MsgIn_set_async(pACB, pSRB);
770 break;
772 case MSG_EXTENDED:
773 /* reject every extended msg but SDTR */
774 if (pSRB->MsgInBuf[1] != 3 || pSRB->MsgInBuf[2] != EXTENDED_SDTR)
775 dc390_MsgIn_reject(pACB, pSRB);
776 else {
777 if (pSRB->MsgInBuf[3] == 0 || pSRB->MsgInBuf[4] == 0)
778 dc390_MsgIn_set_async(pACB, pSRB);
779 else
780 dc390_MsgIn_set_sync(pACB, pSRB);
783 // nothing has to be done
784 case MSG_COMPLETE:
785 break;
787 // SAVE POINTER my be ignored as we have the PSRB associated with the
788 // scsi command. Thanks, Gerard, for pointing it out.
789 case MSG_SAVE_PTR:
790 break;
791 // The device might want to restart transfer with a RESTORE
792 case MSG_RESTORE_PTR:
793 printk("DC390: RESTORE POINTER message received ... reject\n");
794 // fall through
796 // reject unknown messages
797 default:
798 dc390_MsgIn_reject(pACB, pSRB);
801 /* Clear counter and MsgIn state */
802 pSRB->SRBState &= ~SRB_MSGIN;
803 pACB->MsgLen = 0;
806 *psstatus = SCSI_NOP0;
807 DC390_write8(ScsiCmd, MSG_ACCEPTED_CMD);
808 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
812 void dc390_DataIO_Comm(PACB pACB, PSRB pSRB, UCHAR ioDir)
814 PSGL psgl;
815 ULONG lval;
817 if (pSRB->SGIndex < pSRB->SGcount) {
818 DC390_write8(DMA_Cmd, DMA_IDLE_CMD | ioDir /* | DMA_INT */ );
819 if (!pSRB->SGToBeXferLen) {
820 psgl = pSRB->pSegmentList;
821 pSRB->SGBusAddr = virt_to_bus(psgl->address);
822 pSRB->SGToBeXferLen = (ULONG) psgl->length;
823 DEBUG1(printk(KERN_DEBUG " DC390: Next SG segment.");
826 lval = pSRB->SGToBeXferLen;
827 DEBUG1(printk(KERN_DEBUG " DC390: Transfer %li bytes (address %08lx)\n", lval, pSRB->SGBusAddr);
829 DC390_write8(CtcReg_Low, (UCHAR) lval);
830 lval >>= 8;
831 DC390_write8(CtcReg_Mid, (UCHAR) lval);
832 lval >>= 8;
833 DC390_write8(CtcReg_High, (UCHAR) lval);
835 DC390_write32(DMA_XferCnt, pSRB->SGToBeXferLen);
836 DC390_write32(DMA_XferAddr, pSRB->SGBusAddr);
838 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); /* | DMA_INT; */
839 pSRB->SRBState = SRB_DATA_XFER;
841 DC390_write8(ScsiCmd, DMA_COMMAND + INFO_XFER_CMD);
843 DC390_write8(DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
844 //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);)
845 //DEBUG1(printk (KERN_DEBUG "DC390: DMA_Status: %02x\n", DC390_read8 (DMA_Status));)
846 //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);)
847 } else { /* xfer pad */
848 if (pSRB->SGcount) {
849 pSRB->AdaptStatus = H_OVER_UNDER_RUN;
850 pSRB->SRBStatus |= OVER_RUN;
851 DEBUG0(printk(KERN_WARNING " DC390: Overrun -");
854 DEBUG0(printk(KERN_WARNING " Clear transfer pad \n");
856 DC390_write8(CtcReg_Low, 0);
857 DC390_write8(CtcReg_Mid, 0);
858 DC390_write8(CtcReg_High, 0);
860 pSRB->SRBState |= SRB_XFERPAD;
861 DC390_write8(ScsiCmd, DMA_COMMAND + XFER_PAD_BYTE);
863 DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); // | DMA_INT;
864 DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
870 static void dc390_DataOutPhase(PACB pACB, PSRB pSRB, PUCHAR psstatus)
872 dc390_DataIO_Comm(pACB, pSRB, WRITE_DIRECTION);
875 static void dc390_DataInPhase(PACB pACB, PSRB pSRB, PUCHAR psstatus)
877 dc390_DataIO_Comm(pACB, pSRB, READ_DIRECTION);
880 void dc390_CommandPhase(PACB pACB, PSRB pSRB, PUCHAR psstatus)
882 PDCB pDCB;
883 UCHAR i, cnt;
884 PUCHAR ptr;
886 DC390_write8(ScsiCmd, RESET_ATN_CMD);
887 DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
888 if (!(pSRB->SRBFlag & AUTO_REQSENSE)) {
889 cnt = (UCHAR) pSRB->ScsiCmdLen;
890 ptr = (PUCHAR) pSRB->CmdBlock;
891 for (i = 0; i < cnt; i++)
892 DC390_write8(ScsiFifo, *(ptr++));
893 } else {
894 UCHAR bval = 0;
895 DC390_write8(ScsiFifo, REQUEST_SENSE);
896 pDCB = pACB->pActiveDCB;
897 DC390_write8(ScsiFifo, pDCB->IdentifyMsg << 5);
898 DC390_write8(ScsiFifo, bval);
899 DC390_write8(ScsiFifo, bval);
900 DC390_write8(ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
901 DC390_write8(ScsiFifo, bval);
903 pSRB->SRBState = SRB_COMMAND;
904 DC390_write8(ScsiCmd, INFO_XFER_CMD);
907 static void dc390_StatusPhase(PACB pACB, PSRB pSRB, PUCHAR psstatus)
909 DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
910 pSRB->SRBState = SRB_STATUS;
911 DC390_write8(ScsiCmd, INITIATOR_CMD_CMPLTE);
912 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
915 void dc390_MsgOutPhase(PACB pACB, PSRB pSRB, PUCHAR psstatus)
917 UCHAR bval, i, cnt;
918 PUCHAR ptr;
919 PDCB pDCB;
921 DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
922 pDCB = pACB->pActiveDCB;
923 if (!(pSRB->SRBState & SRB_MSGOUT)) {
924 cnt = pSRB->MsgCnt;
925 if (cnt) {
926 ptr = (PUCHAR) pSRB->MsgOutBuf;
927 for (i = 0; i < cnt; i++)
928 DC390_write8(ScsiFifo, *(ptr++));
929 pSRB->MsgCnt = 0;
930 if ((pDCB->DCBFlag & ABORT_DEV_) &&
931 (pSRB->MsgOutBuf[0] == MSG_ABORT))
932 pSRB->SRBState = SRB_ABORT_SENT;
933 } else {
934 bval = MSG_ABORT; /* ??? MSG_NOP */
935 if ((pSRB->CmdBlock[0] == INQUIRY) ||
936 (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
937 (pSRB->SRBFlag & AUTO_REQSENSE)) {
938 if (pDCB->SyncMode & SYNC_ENABLE)
939 goto mop1;
941 DC390_write8(ScsiFifo, bval);
943 DC390_write8(ScsiCmd, INFO_XFER_CMD);
944 } else {
945 mop1:
946 //printk ("DC390: Send SDTR message to %i %i ... \n", pDCB->UnitSCSIID, pDCB->UnitSCSILUN);
947 DC390_write8(ScsiFifo, MSG_EXTENDED);
948 DC390_write8(ScsiFifo, 3); /* ;length of extended msg */
949 DC390_write8(ScsiFifo, EXTENDED_SDTR); /* ; sync nego */
950 DC390_write8(ScsiFifo, pDCB->NegoPeriod);
951 if (pDCB->SyncOffset & 0x0f)
952 DC390_write8(ScsiFifo, pDCB->SyncOffset);
953 else
954 DC390_write8(ScsiFifo, SYNC_NEGO_OFFSET);
955 pSRB->SRBState |= DO_SYNC_NEGO;
956 DC390_write8(ScsiCmd, INFO_XFER_CMD);
960 static void dc390_MsgInPhase(PACB pACB, PSRB pSRB, PUCHAR psstatus)
962 DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
963 if (!(pSRB->SRBState & SRB_MSGIN)) {
964 pSRB->SRBState &= ~SRB_DISCONNECT;
965 pSRB->SRBState |= SRB_MSGIN;
967 DC390_write8(ScsiCmd, INFO_XFER_CMD);
968 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
971 static void dc390_Nop_0(PACB pACB, PSRB pSRB, PUCHAR psstatus)
975 static void dc390_Nop_1(PACB pACB, PSRB pSRB, PUCHAR psstatus)
980 static void dc390_SetXferRate(PACB pACB, PDCB pDCB)
982 UCHAR bval, i, cnt;
983 PDCB ptr;
985 if (!(pDCB->IdentifyMsg & 0x07)) {
986 if (pACB->scan_devices) {
987 dc390_CurrSyncOffset = pDCB->SyncOffset;
988 } else {
989 ptr = pACB->pLinkDCB;
990 cnt = pACB->DCBCnt;
991 bval = pDCB->UnitSCSIID;
992 for (i = 0; i < cnt; i++) {
993 if (ptr->UnitSCSIID == bval) {
994 ptr->SyncPeriod = pDCB->SyncPeriod;
995 ptr->SyncOffset = pDCB->SyncOffset;
996 ptr->CtrlR3 = pDCB->CtrlR3;
997 ptr->CtrlR4 = pDCB->CtrlR4;
998 ptr->SyncMode = pDCB->SyncMode;
1000 ptr = ptr->pNextDCB;
1004 return;
1008 void dc390_Disconnect(PACB pACB)
1010 PDCB pDCB;
1011 PSRB pSRB, psrb;
1012 UCHAR i, cnt;
1014 DEBUG0(printk(KERN_INFO "DISC,");
1016 pDCB = pACB->pActiveDCB;
1017 if (!pDCB) {
1018 int j = 400;
1019 DEBUG0(printk(KERN_WARNING "ACB:%08lx->ActiveDCB:%08lx IOPort:%04x IRQ:%02x !\n", \
1020 (ULONG) pACB, (ULONG) pDCB, pACB->IOPortBase, pACB->IRQLevel);
1022 while (--j)
1023 udelay(1000);
1024 DC390_read8(INT_Status); /* Reset Pending INT */
1025 DC390_write8(ScsiCmd, EN_SEL_RESEL);
1026 return;
1028 pSRB = pDCB->pActiveSRB;
1029 pACB->pActiveDCB = 0;
1030 pSRB->ScsiPhase = SCSI_NOP0;
1031 DC390_write8(ScsiCmd, EN_SEL_RESEL);
1032 if (pSRB->SRBState & SRB_UNEXPECT_RESEL) {
1033 pSRB->SRBState = 0;
1034 dc390_DoWaitingSRB(pACB);
1035 } else if (pSRB->SRBState & SRB_ABORT_SENT) {
1036 pDCB->TagMask = 0;
1037 pDCB->DCBFlag = 0;
1038 cnt = pDCB->GoingSRBCnt;
1039 pDCB->GoingSRBCnt = 0;
1040 pSRB = pDCB->pGoingSRB;
1041 for (i = 0; i < cnt; i++) {
1042 psrb = pSRB->pNextSRB;
1043 pSRB->pNextSRB = pACB->pFreeSRB;
1044 pACB->pFreeSRB = pSRB;
1045 pSRB = psrb;
1047 pDCB->pGoingSRB = 0;
1048 dc390_DoWaitingSRB(pACB);
1049 } else {
1050 if ((pSRB->SRBState & (SRB_START_ + SRB_MSGOUT)) ||
1051 !(pSRB->SRBState & (SRB_DISCONNECT + SRB_COMPLETED))) { /* Selection time out */
1052 if (!(pACB->scan_devices)) {
1053 pSRB->SRBState = SRB_READY;
1054 dc390_RewaitSRB(pDCB, pSRB);
1055 } else {
1056 pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT;
1057 goto disc1;
1059 } else if (pSRB->SRBState & SRB_DISCONNECT) {
1060 dc390_DoWaitingSRB(pACB);
1061 } else if (pSRB->SRBState & SRB_COMPLETED) {
1062 disc1:
1063 if (pDCB->MaxCommand > 1) {
1064 pDCB->TagMask &= (~(1 << pSRB->TagNumber)); /* free tag mask */
1066 pDCB->pActiveSRB = 0;
1067 pSRB->SRBState = SRB_FREE;
1068 dc390_SRBdone(pACB, pDCB, pSRB);
1071 pACB->MsgLen = 0;
1075 void dc390_Reselect(PACB pACB)
1077 PDCB pDCB;
1078 PSRB pSRB;
1079 USHORT wval;
1080 UCHAR bval;
1082 DEBUG0(printk(KERN_INFO "RSEL,");
1084 pDCB = pACB->pActiveDCB;
1085 if (pDCB) { /* Arbitration lost but Reselection won */
1086 DEBUG0(printk("(ActiveDCB != 0)");
1088 pSRB = pDCB->pActiveSRB;
1089 if (!(pACB->scan_devices)) {
1090 pSRB->SRBState = SRB_READY;
1091 dc390_RewaitSRB(pDCB, pSRB);
1094 bval = DC390_read8(ScsiFifo); /* get ID */
1095 DEBUG0(printk("Dev %02x,", bval);
1097 bval ^= 1 << pACB->pScsiHost->this_id; /* Mask AdapterID */
1098 wval = 0;
1099 while (bval >>= 1)
1100 wval++;
1101 wval |= ((USHORT) DC390_read8(ScsiFifo) & 7) << 8; /* get LUN */
1102 DEBUG0(printk("(ID %02x, LUN %02x),", wval & 0xff, (wval & 0xff00) >> 8);
1104 pDCB = pACB->pLinkDCB;
1105 while (wval != *((PUSHORT) & pDCB->UnitSCSIID)) {
1106 pDCB = pDCB->pNextDCB;
1107 if (pDCB == pACB->pLinkDCB) {
1108 printk(KERN_ERR "DC390: Reselect from non existing device (ID %02x, LUN %02x)\n",
1109 wval & 0xff, (wval & 0xff00) >> 8);
1110 return;
1113 pACB->pActiveDCB = pDCB;
1114 if (pDCB->SyncMode & EN_TAG_QUEUEING) {
1115 pSRB = pACB->pTmpSRB; /* ?? */
1116 pDCB->pActiveSRB = pSRB;
1117 } else {
1118 pSRB = pDCB->pActiveSRB;
1119 if (!pSRB || !(pSRB->SRBState & SRB_DISCONNECT)) {
1120 pSRB = pACB->pTmpSRB;
1121 pSRB->SRBState = SRB_UNEXPECT_RESEL;
1122 printk(KERN_ERR "DC390: Reselect without outstanding cmnd (ID %02x, LUN %02x)\n",
1123 wval & 0xff, (wval & 0xff00) >> 8);
1124 pDCB->pActiveSRB = pSRB;
1125 dc390_EnableMsgOut_Abort(pACB, pSRB);
1126 } else {
1127 if (pDCB->DCBFlag & ABORT_DEV_) {
1128 pSRB->SRBState = SRB_ABORT_SENT;
1129 printk(KERN_INFO "DC390: Reselect: Abort (ID %02x, LUN %02x)\n",
1130 wval & 0xff, (wval & 0xff00) >> 8);
1131 dc390_EnableMsgOut_Abort(pACB, pSRB);
1132 } else
1133 pSRB->SRBState = SRB_DATA_XFER;
1137 DEBUG1(printk(KERN_DEBUG "Resel SRB(%p): TagNum (%02x)\n", pSRB, pSRB->TagNumber);
1139 pSRB->ScsiPhase = SCSI_NOP0;
1140 DC390_write8(Scsi_Dest_ID, pDCB->UnitSCSIID);
1141 DC390_write8(Sync_Period, pDCB->SyncPeriod);
1142 DC390_write8(Sync_Offset, pDCB->SyncOffset);
1143 DC390_write8(CtrlReg1, pDCB->CtrlR1);
1144 DC390_write8(CtrlReg3, pDCB->CtrlR3);
1145 DC390_write8(CtrlReg4, pDCB->CtrlR4); /* ; Glitch eater */
1146 DC390_write8(ScsiCmd, MSG_ACCEPTED_CMD); /* ;to release the /ACK signal */
1150 static void dc390_remove_dev(PACB pACB, PDCB pDCB)
1152 PDCB pPrevDCB = pACB->pLinkDCB;
1154 pACB->DCBmap[pDCB->UnitSCSIID] &= ~(1 << pDCB->UnitSCSILUN);
1155 if (pDCB->GoingSRBCnt > 1) {
1156 DCBDEBUG(printk(KERN_INFO "DC390: Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %i\n", \
1157 pDCB->UnitSCSIID, pDCB->UnitSCSILUN, (int) pDCB, pDCB->GoingSRBCnt);
1159 return;
1162 if (pDCB == pACB->pLinkDCB) {
1163 if (pDCB->pNextDCB == pDCB)
1164 pDCB->pNextDCB = 0;
1165 pACB->pLinkDCB = pDCB->pNextDCB;
1166 pACB->pLastDCB->pNextDCB = pDCB->pNextDCB;
1167 } else {
1168 while (pPrevDCB->pNextDCB != pDCB)
1169 pPrevDCB = pPrevDCB->pNextDCB;
1170 pPrevDCB->pNextDCB = pDCB->pNextDCB;
1171 if (pDCB == pACB->pLastDCB)
1172 pACB->pLastDCB = pPrevDCB;
1175 DCBDEBUG(printk(KERN_INFO "DC390: Driver about to free DCB (ID %i, LUN %i): 0x%08x\n", \
1176 pDCB->UnitSCSIID, pDCB->UnitSCSILUN, (int) pDCB);
1178 kfree(pDCB);
1179 if (pDCB == pACB->pActiveDCB)
1180 pACB->pActiveDCB = 0;
1181 pACB->DCBCnt--;
1182 /* pACB->DeviceCnt--; */
1186 static UCHAR __inline__
1187 dc390_tagq_blacklist(char *name)
1189 UCHAR i;
1190 for (i = 0; i < BADDEVCNT; i++)
1191 if (memcmp(name, dc390_baddevname1[i], 28) == 0)
1192 return 1;
1193 return 0;
1197 static void dc390_disc_tagq_set(PDCB pDCB, PSCSI_INQDATA ptr)
1199 /* Check for SCSI format (ANSI and Response data format) */
1200 if ((ptr->Vers & 0x07) >= 2 || (ptr->RDF & 0x0F) == 2) {
1201 if ((ptr->Flags & SCSI_INQ_CMDQUEUE) &&
1202 (pDCB->DevMode & TAG_QUEUEING_) &&
1203 /* ((pDCB->DevType == TYPE_DISK)
1204 || (pDCB->DevType == TYPE_MOD)) && */
1205 !dc390_tagq_blacklist(((char *) ptr) + 8)) {
1206 pDCB->MaxCommand = pDCB->pDCBACB->TagMaxNum;
1207 pDCB->SyncMode |= EN_TAG_QUEUEING /* | EN_ATN_STOP */ ;
1208 pDCB->TagMask = 0;
1209 } else {
1210 /* Do we really need to check for DevType here ? */
1211 if (0 /*(pDCB->DevMode & EN_DISCONNECT_) */
1212 /* && ((pDCB->DevType == TYPE_DISK)
1213 || (pDCB->DevType == TYPE_MOD)) */ )
1214 pDCB->SyncMode |= EN_ATN_STOP;
1215 else
1216 //pDCB->SyncMode &= ~EN_ATN_STOP;
1217 pDCB->SyncMode &= ~0;
1223 static void dc390_add_dev(PACB pACB, PDCB pDCB, PSCSI_INQDATA ptr)
1225 UCHAR bval1 = ptr->DevType & SCSI_DEVTYPE;
1226 pDCB->DevType = bval1;
1227 /* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */
1228 dc390_disc_tagq_set(pDCB, ptr);
1232 void dc390_SRBdone(PACB pACB, PDCB pDCB, PSRB pSRB)
1234 PSRB psrb;
1235 UCHAR bval, status, i;
1236 PSCSICMD pcmd;
1237 PSCSI_INQDATA ptr;
1238 PSGL ptr2;
1239 ULONG swlval;
1241 pcmd = pSRB->pcmd;
1242 status = pSRB->TargetStatus;
1243 DEBUG0(printk(" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result, \
1244 pSRB, pcmd->pid);
1246 if (pSRB->SRBFlag & AUTO_REQSENSE) { /* Last command was a Request Sense */
1247 pSRB->SRBFlag &= ~AUTO_REQSENSE;
1248 pSRB->AdaptStatus = 0;
1249 pSRB->TargetStatus = SCSI_STAT_CHECKCOND;
1250 #ifdef DC390_REMOVABLEDEBUG
1251 switch (pcmd->sense_buffer[2] & 0x0f) {
1252 case NOT_READY:
1253 printk(KERN_INFO "DC390: ReqSense: NOT_READY (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1254 pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
1255 status, pACB->scan_devices);
1256 break;
1257 case UNIT_ATTENTION:
1258 printk(KERN_INFO "DC390: ReqSense: UNIT_ATTENTION (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1259 pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
1260 status, pACB->scan_devices);
1261 break;
1262 case ILLEGAL_REQUEST:
1263 printk(KERN_INFO "DC390: ReqSense: ILLEGAL_REQUEST (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1264 pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
1265 status, pACB->scan_devices);
1266 break;
1267 case MEDIUM_ERROR:
1268 printk(KERN_INFO "DC390: ReqSense: MEDIUM_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1269 pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
1270 status, pACB->scan_devices);
1271 break;
1272 case HARDWARE_ERROR:
1273 printk(KERN_INFO "DC390: ReqSense: HARDWARE_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1274 pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
1275 status, pACB->scan_devices);
1276 break;
1278 #endif
1279 //pcmd->result = DRIVER_SENSE << 24 | DID_OK << 16 | status;
1280 if (status == SCSI_STAT_CHECKCOND) {
1281 pcmd->result = DID_BAD_TARGET << 16;
1282 goto ckc_e;
1284 if (pSRB->RetryCnt == 0) {
1285 (ULONG) (pSRB->CmdBlock[0]) = pSRB->Segment0[0];
1286 pSRB->TotalXferredLen = pSRB->Segment1[1];
1287 if ((pSRB->TotalXferredLen) &&
1288 (pSRB->TotalXferredLen >= pcmd->underflow))
1289 pcmd->result |= (DID_OK << 16);
1290 else
1291 pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) |
1292 SCSI_STAT_CHECKCOND;
1293 REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x,Result=%08x,XferL=%08x\n", pSRB->CmdBlock[0], \
1294 (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);
1296 goto ckc_e;
1297 } else { /* Retry */
1298 pSRB->RetryCnt--;
1299 pSRB->AdaptStatus = 0;
1300 pSRB->TargetStatus = 0;
1301 *((PULONG) & (pSRB->CmdBlock[0])) = pSRB->Segment0[0];
1302 *((PULONG) & (pSRB->CmdBlock[4])) = pSRB->Segment0[1];
1303 /* Don't retry on TEST_UNIT_READY */
1304 if (pSRB->CmdBlock[0] == TEST_UNIT_READY /* || pSRB->CmdBlock[0] == START_STOP */ ) {
1305 pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16)
1306 | SCSI_STAT_CHECKCOND;
1307 REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n", pSRB->CmdBlock[0], \
1308 (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);
1310 goto ckc_e;
1312 pcmd->result |= (DRIVER_SENSE << 24);
1313 pSRB->SGcount = (UCHAR) pSRB->Segment1[0];
1314 pSRB->ScsiCmdLen = (UCHAR) (pSRB->Segment1[0] >> 8);
1315 pSRB->SGIndex = 0;
1316 pSRB->TotalXferredLen = 0;
1317 pSRB->SGToBeXferLen = 0;
1318 if (pcmd->use_sg)
1319 pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
1320 else if (pcmd->request_buffer) {
1321 pSRB->pSegmentList = (PSGL) & pSRB->Segmentx;
1322 pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
1323 pSRB->Segmentx.length = pcmd->request_bufflen;
1325 if (dc390_StartSCSI(pACB, pDCB, pSRB))
1326 dc390_RewaitSRB(pDCB, pSRB);
1327 return;
1330 if (status) {
1331 if (status == SCSI_STAT_CHECKCOND) {
1332 REMOVABLEDEBUG(printk(KERN_INFO "DC390: Scsi_Stat_CheckCond (Cmd %02x, Id %02x, LUN %02x)\n", \
1333 pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN);
1335 if ((pSRB->SGIndex < pSRB->SGcount) && (pSRB->SGcount) && (pSRB->SGToBeXferLen)) {
1336 bval = pSRB->SGcount;
1337 swlval = 0;
1338 ptr2 = pSRB->pSegmentList;
1339 for (i = pSRB->SGIndex; i < bval; i++) {
1340 swlval += ptr2->length;
1341 ptr2++;
1343 REMOVABLEDEBUG(printk(KERN_INFO "XferredLen=%08x,NotXferLen=%08x\n", \
1344 (UINT) pSRB->TotalXferredLen, (UINT) swlval);
1347 dc390_RequestSense(pACB, pDCB, pSRB);
1348 return;
1349 } else if (status == SCSI_STAT_QUEUEFULL) {
1350 bval = (UCHAR) pDCB->GoingSRBCnt;
1351 bval--;
1352 pDCB->MaxCommand = bval;
1353 dc390_RewaitSRB(pDCB, pSRB);
1354 pSRB->AdaptStatus = 0;
1355 pSRB->TargetStatus = 0;
1356 return;
1357 } else if (status == SCSI_STAT_SEL_TIMEOUT) {
1358 pSRB->AdaptStatus = H_SEL_TIMEOUT;
1359 pSRB->TargetStatus = 0;
1360 pcmd->result = DID_BAD_TARGET << 16;
1361 /* Devices are removed below ... */
1362 } else if (status == SCSI_STAT_BUSY &&
1363 (pSRB->CmdBlock[0] == TEST_UNIT_READY || pSRB->CmdBlock[0] == INQUIRY) &&
1364 pACB->scan_devices) {
1365 pSRB->AdaptStatus = 0;
1366 pSRB->TargetStatus = status;
1367 pcmd->result = (ULONG) (pSRB->EndMessage << 8)
1368 /* | (ULONG) status */ ;
1369 } else { /* Another error */
1370 pSRB->AdaptStatus = 0;
1371 if (pSRB->RetryCnt) { /* Retry */
1372 pSRB->RetryCnt--;
1373 pSRB->TargetStatus = 0;
1374 pSRB->SGIndex = 0;
1375 pSRB->TotalXferredLen = 0;
1376 pSRB->SGToBeXferLen = 0;
1377 if (pcmd->use_sg)
1378 pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
1379 else if (pcmd->request_buffer) {
1380 pSRB->pSegmentList = (PSGL) & pSRB->Segmentx;
1381 pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
1382 pSRB->Segmentx.length = pcmd->request_bufflen;
1384 if (dc390_StartSCSI(pACB, pDCB, pSRB))
1385 dc390_RewaitSRB(pDCB, pSRB);
1386 return;
1387 } else { /* Report error */
1388 pcmd->result |= (DID_ERROR << 16) | (ULONG) (pSRB->EndMessage << 8) |
1389 (ULONG) status;
1392 } else { /* Target status == 0 */
1393 status = pSRB->AdaptStatus;
1394 if (status & H_OVER_UNDER_RUN) {
1395 pSRB->TargetStatus = 0;
1396 pcmd->result |= (DID_OK << 16) | (pSRB->EndMessage << 8);
1397 } else if (pSRB->SRBStatus & PARITY_ERROR) {
1398 pcmd->result |= (DID_PARITY << 16) | (pSRB->EndMessage << 8);
1399 } else { /* No error */
1400 pSRB->AdaptStatus = 0;
1401 pSRB->TargetStatus = 0;
1402 pcmd->result |= (DID_OK << 16);
1406 ckc_e:
1407 if (pACB->scan_devices) {
1408 if (pSRB->CmdBlock[0] == TEST_UNIT_READY) {
1409 #ifdef DC390_DEBUG0
1410 printk(KERN_INFO "DC390: Test_Unit_Ready: result: %08x", pcmd->result);
1411 if (pcmd->result & DRIVER_SENSE << 24)
1412 printk(" (sense: %02x %02x %02x %02x)\n",
1413 pcmd->sense_buffer[0], pcmd->sense_buffer[1],
1414 pcmd->sense_buffer[2], pcmd->sense_buffer[3]);
1415 else
1416 printk("\n");
1417 #endif
1418 if ((pcmd->result != (DID_OK << 16) && !(pcmd->result & SCSI_STAT_CHECKCOND) && !(pcmd->result & SCSI_STAT_BUSY)) ||
1419 ((pcmd->result & DRIVER_SENSE << 24) && (pcmd->sense_buffer[0] & 0x70) == 0x70 &&
1420 (pcmd->sense_buffer[2] & 0xf) == ILLEGAL_REQUEST) || pcmd->result & DID_ERROR << 16) {
1421 /* device not present: remove */
1422 dc390_remove_dev(pACB, pDCB);
1424 if ((pcmd->target == pACB->pScsiHost->max_id - 1) &&
1425 ((pcmd->lun == 0) || (pcmd->lun == pACB->pScsiHost->max_lun - 1)))
1426 pACB->scan_devices = 0;
1427 } else {
1428 /* device present: add */
1429 if ((pcmd->target == pACB->pScsiHost->max_id - 1) &&
1430 (pcmd->lun == pACB->pScsiHost->max_lun - 1))
1431 pACB->scan_devices = END_SCAN;
1432 /* pACB->DeviceCnt++; *//* Dev is added on INQUIRY */
1436 if (pSRB->CmdBlock[0] == INQUIRY &&
1437 (pcmd->result == DID_OK << 16 || pcmd->result & SCSI_STAT_CHECKCOND)) {
1438 ptr = (PSCSI_INQDATA) (pcmd->request_buffer);
1439 if (pcmd->use_sg)
1440 ptr = (PSCSI_INQDATA) (((PSGL) ptr)->address);
1441 if ((ptr->DevType & SCSI_DEVTYPE) == TYPE_NODEV) {
1442 /* device not present: remove */
1443 dc390_remove_dev(pACB, pDCB);
1444 } else {
1445 /* device found: add */
1446 dc390_add_dev(pACB, pDCB, ptr);
1447 if (pACB->scan_devices)
1448 pACB->DeviceCnt++;
1450 if ((pcmd->target == pACB->pScsiHost->max_id - 1) &&
1451 (pcmd->lun == pACB->pScsiHost->max_lun - 1))
1452 pACB->scan_devices = 0;
1454 /* dc390_ReleaseSRB( pDCB, pSRB ); */
1456 if (pSRB == pDCB->pGoingSRB) {
1457 pDCB->pGoingSRB = pSRB->pNextSRB;
1458 } else {
1459 psrb = pDCB->pGoingSRB;
1460 while (psrb->pNextSRB != pSRB)
1461 psrb = psrb->pNextSRB;
1462 psrb->pNextSRB = pSRB->pNextSRB;
1463 if (pSRB == pDCB->pGoingLast)
1464 pDCB->pGoingLast = psrb;
1466 pSRB->pNextSRB = pACB->pFreeSRB;
1467 pACB->pFreeSRB = pSRB;
1468 pDCB->GoingSRBCnt--;
1470 dc390_DoWaitingSRB(pACB);
1472 DC390_UNLOCK_ACB_NI;
1473 pcmd->scsi_done(pcmd);
1474 DC390_LOCK_ACB_NI;
1476 if (pDCB->QIORBCnt)
1477 dc390_DoNextCmd(pACB, pDCB);
1478 return;
1482 /* Remove all SRBs and tell midlevel code DID_RESET */
1483 void dc390_DoingSRB_Done(PACB pACB)
1485 PDCB pDCB, pdcb;
1486 PSRB psrb, psrb2;
1487 UCHAR i;
1488 PSCSICMD pcmd;
1490 pDCB = pACB->pLinkDCB;
1491 pdcb = pDCB;
1492 if (!pdcb)
1493 return;
1494 do {
1495 psrb = pdcb->pGoingSRB;
1496 for (i = 0; i < pdcb->GoingSRBCnt; i++) {
1497 psrb2 = psrb->pNextSRB;
1498 pcmd = psrb->pcmd;
1499 pcmd->result = DID_RESET << 16;
1501 /* ReleaseSRB( pDCB, pSRB ); */
1503 psrb->pNextSRB = pACB->pFreeSRB;
1504 pACB->pFreeSRB = psrb;
1506 DC390_UNLOCK_ACB_NI;
1507 pcmd->scsi_done(pcmd);
1508 DC390_LOCK_ACB_NI;
1509 psrb = psrb2;
1511 pdcb->GoingSRBCnt = 0;;
1512 pdcb->pGoingSRB = NULL;
1513 pdcb->TagMask = 0;
1514 pdcb = pdcb->pNextDCB;
1515 } while (pdcb != pDCB);
1519 static void dc390_ResetSCSIBus(PACB pACB)
1521 pACB->ACBFlag |= RESET_DEV;
1523 DC390_write8(ScsiCmd, RST_DEVICE_CMD);
1524 udelay(250);
1525 DC390_write8(ScsiCmd, NOP_CMD);
1527 DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
1528 DC390_write8(DMA_Cmd, DMA_IDLE_CMD);
1529 DC390_write8(ScsiCmd, RST_SCSI_BUS_CMD);
1531 return;
1534 static void dc390_ScsiRstDetect(PACB pACB)
1536 printk("DC390: Rst_Detect: laststat = %08lx\n", dc390_laststatus);
1537 //DEBUG0(printk(KERN_INFO "RST_DETECT,");)
1539 DC390_write8(DMA_Cmd, DMA_IDLE_CMD);
1540 /* Unlock before ? */
1541 /* delay a second */
1543 unsigned int msec = 1 * 1000;
1544 while (--msec)
1545 udelay(1000);
1547 DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
1549 if (pACB->ACBFlag & RESET_DEV)
1550 pACB->ACBFlag |= RESET_DONE;
1551 else {
1552 pACB->ACBFlag |= RESET_DETECT;
1554 dc390_ResetDevParam(pACB);
1555 /* dc390_DoingSRB_Done( pACB ); ???? */
1556 dc390_RecoverSRB(pACB);
1557 pACB->pActiveDCB = NULL;
1558 pACB->ACBFlag = 0;
1559 dc390_DoWaitingSRB(pACB);
1561 return;
1565 static void __inline__
1566 dc390_RequestSense(PACB pACB, PDCB pDCB, PSRB pSRB)
1568 PSCSICMD pcmd;
1570 REMOVABLEDEBUG(printk(KERN_INFO "DC390: RequestSense (Cmd %02x, Id %02x, LUN %02x)\n", \
1571 pSRB->CmdBlock[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN);
1573 pSRB->SRBFlag |= AUTO_REQSENSE;
1574 pSRB->Segment0[0] = (ULONG) pSRB->CmdBlock[0];
1575 pSRB->Segment0[1] = (ULONG) pSRB->CmdBlock[4];
1576 pSRB->Segment1[0] = (ULONG) ((pSRB->ScsiCmdLen << 8) + pSRB->SGcount);
1577 pSRB->Segment1[1] = pSRB->TotalXferredLen;
1578 pSRB->AdaptStatus = 0;
1579 pSRB->TargetStatus = 0; /* SCSI_STAT_CHECKCOND; */
1581 pcmd = pSRB->pcmd;
1583 pSRB->Segmentx.address = (PUCHAR) & (pcmd->sense_buffer);
1584 pSRB->Segmentx.length = sizeof(pcmd->sense_buffer);
1585 pSRB->pSegmentList = &pSRB->Segmentx;
1586 pSRB->SGcount = 1;
1587 pSRB->SGIndex = 0;
1589 pSRB->CmdBlock[0] = REQUEST_SENSE;
1590 pSRB->CmdBlock[1] = pDCB->IdentifyMsg << 5;
1591 (USHORT) pSRB->CmdBlock[2] = 0;
1592 (USHORT) pSRB->CmdBlock[4] = sizeof(pcmd->sense_buffer);
1593 pSRB->ScsiCmdLen = 6;
1595 pSRB->TotalXferredLen = 0;
1596 pSRB->SGToBeXferLen = 0;
1597 if (dc390_StartSCSI(pACB, pDCB, pSRB))
1598 dc390_RewaitSRB(pDCB, pSRB);
1603 static void __inline__
1604 dc390_InvalidCmd(PACB pACB)
1606 if (pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_ + SRB_MSGOUT))
1607 DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);