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.55.2.17 2000/12/20 00:39:37 garloff Exp $ */
10 dc390_freetag (PDCB pDCB
, PSRB pSRB
)
12 if (pSRB
->TagNumber
< 255) {
13 pDCB
->TagMask
&= ~(1 << pSRB
->TagNumber
); /* free tag mask */
14 pSRB
->TagNumber
= 255;
20 dc390_StartSCSI( PACB pACB
, PDCB pDCB
, PSRB pSRB
)
22 UCHAR cmd
; UCHAR disc_allowed
, try_sync_nego
;
24 pSRB
->ScsiPhase
= SCSI_NOP0
;
28 // Should not happen normally
29 printk (KERN_WARNING
"DC390: Can't select when connected! (%08x,%02x)\n",
30 pSRB
->SRBState
, pSRB
->SRBFlag
);
31 pSRB
->SRBState
= SRB_READY
;
35 if (time_before (jiffies
, pACB
->pScsiHost
->last_reset
))
37 DEBUG0(printk ("DC390: We were just reset and don't accept commands yet!\n");)
40 DC390_write8 (Scsi_Dest_ID
, pDCB
->TargetID
);
41 DC390_write8 (Sync_Period
, pDCB
->SyncPeriod
);
42 DC390_write8 (Sync_Offset
, pDCB
->SyncOffset
);
43 DC390_write8 (CtrlReg1
, pDCB
->CtrlR1
);
44 DC390_write8 (CtrlReg3
, pDCB
->CtrlR3
);
45 DC390_write8 (CtrlReg4
, pDCB
->CtrlR4
);
46 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
); /* Flush FIFO */
47 DEBUG1(printk (KERN_INFO
"DC390: Start SCSI command: %02x (Sync:%02x)\n",\
48 pSRB
->pcmd
->cmnd
[0], pDCB
->SyncMode
);)
49 disc_allowed
= pDCB
->DevMode
& EN_DISCONNECT_
; try_sync_nego
= 0;
50 /* Don't disconnect on AUTO_REQSENSE, cause it might be an
51 * Contingent Allegiance Condition (6.6), where no tags should be used.
52 * All other have to be allowed to disconnect to prevent Incorrect
53 * Initiator Connection (6.8.2/6.5.2) */
54 /* Changed KG, 99/06/06 */
55 if( /*(((pSRB->pcmd->cmnd[0] == INQUIRY) || (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) ||
56 * (pSRB->pcmd->cmnd[0] == TEST_UNIT_READY)) && pACB->scan_devices)
57 ||*/ (pSRB
->SRBFlag
& AUTO_REQSENSE
) )
59 if ( (pDCB
->SyncMode
& SYNC_ENABLE
) && (pDCB
->TargetLUN
== 0) && (pDCB
->Inquiry7
& 0x10) &&
60 ( ( ( (pSRB
->pcmd
->cmnd
[0] == REQUEST_SENSE
) || (pSRB
->SRBFlag
& AUTO_REQSENSE
) )
61 && !(pDCB
->SyncMode
& SYNC_NEGO_DONE
) ) || (pSRB
->pcmd
->cmnd
[0] == INQUIRY
) ) )
64 pSRB
->MsgCnt
= 0; cmd
= SEL_W_ATN
;
65 DC390_write8 (ScsiFifo
, IDENTIFY(disc_allowed
, pDCB
->TargetLUN
));
66 /* Change 99/05/31: Don't use tags when not disconnecting (BUSY) */
67 if ((pDCB
->SyncMode
& EN_TAG_QUEUEING
) && disc_allowed
)
70 while ((1 << tag_no
) & pDCB
->TagMask
) tag_no
++;
71 if (tag_no
>= sizeof (pDCB
->TagMask
)*8 || tag_no
>= pDCB
->MaxCommand
) {
72 printk (KERN_WARNING
"DC390: Out of tags for Dev. %02x %02x\n", pDCB
->TargetID
, pDCB
->TargetLUN
);
76 DC390_write8 (ScsiFifo
, SIMPLE_QUEUE_TAG
);
77 pDCB
->TagMask
|= (1 << tag_no
); pSRB
->TagNumber
= tag_no
;
78 DC390_write8 (ScsiFifo
, tag_no
);
79 DEBUG1(printk (KERN_DEBUG
"DC390: Select w/DisCn for Cmd %li (SRB %p), Using Tag %02x\n", pSRB
->pcmd
->pid
, pSRB
, tag_no
);)
85 DEBUG1(printk (KERN_DEBUG
"DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", (disc_allowed
?"":"o"), pSRB
->pcmd
->pid
, pSRB
);)
88 pSRB
->SRBState
= SRB_START_
;
92 UCHAR Sync_Off
= pDCB
->SyncOffset
;
93 DEBUG0(printk (KERN_INFO
"DC390: NEW Sync Nego code triggered (%i %i)\n", pDCB
->TargetID
, pDCB
->TargetLUN
);)
94 pSRB
->MsgOutBuf
[0] = EXTENDED_MESSAGE
;
95 pSRB
->MsgOutBuf
[1] = 3;
96 pSRB
->MsgOutBuf
[2] = EXTENDED_SDTR
;
97 pSRB
->MsgOutBuf
[3] = pDCB
->NegoPeriod
;
98 if (!(Sync_Off
& 0x0f)) Sync_Off
= SYNC_NEGO_OFFSET
;
99 pSRB
->MsgOutBuf
[4] = Sync_Off
;
101 //pSRB->SRBState = SRB_MSGOUT_;
102 pSRB
->SRBState
|= DO_SYNC_NEGO
;
103 cmd
= SEL_W_ATN_STOP
;
106 /* Command is written in CommandPhase, if SEL_W_ATN_STOP ... */
107 if (cmd
!= SEL_W_ATN_STOP
)
109 if( pSRB
->SRBFlag
& AUTO_REQSENSE
)
111 DC390_write8 (ScsiFifo
, REQUEST_SENSE
);
112 DC390_write8 (ScsiFifo
, pDCB
->TargetLUN
<< 5);
113 DC390_write8 (ScsiFifo
, 0);
114 DC390_write8 (ScsiFifo
, 0);
115 DC390_write8 (ScsiFifo
, sizeof(pSRB
->pcmd
->sense_buffer
));
116 DC390_write8 (ScsiFifo
, 0);
117 DEBUG1(printk (KERN_DEBUG
"DC390: AutoReqSense !\n");)
119 else /* write cmnd to bus */
122 ptr
= (PUCHAR
) pSRB
->pcmd
->cmnd
;
123 for (i
=0; i
<pSRB
->pcmd
->cmd_len
; i
++)
124 DC390_write8 (ScsiFifo
, *(ptr
++));
127 DEBUG0(if (pACB
->pActiveDCB
) \
128 printk (KERN_WARNING
"DC390: ActiveDCB != 0\n");)
129 DEBUG0(if (pDCB
->pActiveSRB
) \
130 printk (KERN_WARNING
"DC390: ActiveSRB != 0\n");)
131 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
132 if (DC390_read8 (Scsi_Status
) & INTERRUPT
)
134 dc390_freetag (pDCB
, pSRB
);
135 DEBUG0(printk ("DC390: Interrupt during Start SCSI (pid %li, target %02i-%02i)\n",
136 pSRB
->pcmd
->pid
, pSRB
->pcmd
->target
, pSRB
->pcmd
->lun
);)
137 pSRB
->SRBState
= SRB_READY
;
138 //DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
142 DC390_write8 (ScsiCmd
, cmd
);
143 pACB
->pActiveDCB
= pDCB
; pDCB
->pActiveSRB
= pSRB
;
145 pSRB
->ScsiPhase
= SCSI_NOP1
;
149 //#define DMA_INT EN_DMA_INT /*| EN_PAGE_INT*/
153 /* This is similar to AM53C974.c ... */
155 dc390_dma_intr (PACB pACB
)
159 DEBUG0(USHORT pstate
;PDEVDECL1
;)
162 DEBUG0(PCI_READ_CONFIG_WORD (PDEV
, PCI_STATUS
, &pstate
);)
163 DEBUG0(if (pstate
& (PCI_STATUS_SIG_SYSTEM_ERROR
| PCI_STATUS_DETECTED_PARITY
))\
164 { printk(KERN_WARNING
"DC390: PCI state = %04x!\n", pstate
); \
165 PCI_WRITE_CONFIG_WORD (PDEV
, PCI_STATUS
, (PCI_STATUS_SIG_SYSTEM_ERROR
| PCI_STATUS_DETECTED_PARITY
));};)
167 dstate
= DC390_read8 (DMA_Status
);
169 if (! pACB
->pActiveDCB
|| ! pACB
->pActiveDCB
->pActiveSRB
) return dstate
;
170 else pSRB
= pACB
->pActiveDCB
->pActiveSRB
;
172 if (dstate
& (DMA_XFER_ABORT
| DMA_XFER_ERROR
| POWER_DOWN
| PCI_MS_ABORT
))
174 printk (KERN_ERR
"DC390: DMA error (%02x)!\n", dstate
);
177 if (dstate
& DMA_XFER_DONE
)
179 UINT residual
, xferCnt
; int ctr
= 6000000;
180 if (! (DC390_read8 (DMA_Cmd
) & READ_DIRECTION
))
184 DEBUG1(printk (KERN_DEBUG
"DC390: read residual bytes ... \n");)
185 dstate
= DC390_read8 (DMA_Status
);
186 residual
= DC390_read8 (CtcReg_Low
) | DC390_read8 (CtcReg_Mid
) << 8 |
187 DC390_read8 (CtcReg_High
) << 16;
188 residual
+= DC390_read8 (Current_Fifo
) & 0x1f;
189 } while (residual
&& ! (dstate
& SCSI_INTERRUPT
) && --ctr
);
190 if (!ctr
) printk (KERN_CRIT
"DC390: dma_intr: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr
));
198 xferCnt
= pSRB
->SGToBeXferLen
- residual
;
199 pSRB
->SGBusAddr
+= xferCnt
;
200 pSRB
->TotalXferredLen
+= xferCnt
;
201 pSRB
->SGToBeXferLen
= residual
;
203 printk (KERN_INFO
"DC390: DMA: residual = %i, xfer = %i\n",
204 (unsigned int)residual
, (unsigned int)xferCnt
);
207 DC390_write8 (DMA_Cmd
, DMA_IDLE_CMD
);
209 dc390_laststatus
&= ~0xff000000; dc390_laststatus
|= dstate
<< 24;
215 DC390_Interrupt( int irq
, void *dev_id
, struct pt_regs
*regs
)
222 void (*stateV
)( PACB
, PSRB
, PUCHAR
);
223 UCHAR istate
, istatus
;
227 DC390_AFLAGS DC390_IFLAGS
//DC390_DFLAGS
230 for (pACB2
= dc390_pACB_start
; (pACB2
&& pACB2
!= pACB
); pACB2
= pACB2
->pNextACB
);
233 printk ("DC390: IRQ called with foreign dev_id %p!\n", pACB
);
239 sstatus
= DC390_read8 (Scsi_Status
);
240 if( !(sstatus
& INTERRUPT
) )
241 { /*DC390_UNLOCK_DRV;*/ return; };
243 DEBUG1(printk (KERN_DEBUG
"sstatus=%02x,", sstatus
);)
248 dstatus
= dc390_dma_intr (pACB
);
252 DEBUG1(printk (KERN_DEBUG
"dstatus=%02x,", dstatus
);)
253 if (! (dstatus
& SCSI_INTERRUPT
))
255 DEBUG0(printk (KERN_WARNING
"DC390 Int w/o SCSI actions (only DMA?)\n");)
260 //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
261 //dstatus = DC390_read8 (DMA_Status);
262 //DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
267 //DC390_UNLOCK_DRV_NI; /* Allow _other_ CPUs to process IRQ (useful for shared IRQs) */
269 istate
= DC390_read8 (Intern_State
);
270 istatus
= DC390_read8 (INT_Status
); /* This clears Scsi_Status, Intern_State and INT_Status ! */
272 DEBUG1(printk (KERN_INFO
"Istatus(Res,Inv,Dis,Serv,Succ,ReS,SelA,Sel)=%02x,",istatus
);)
273 dc390_laststatus
&= ~0x00ffffff;
274 dc390_laststatus
|= /* dstatus<<24 | */ sstatus
<<16 | istate
<<8 | istatus
;
276 if (sstatus
& ILLEGAL_OP_ERR
)
278 printk ("DC390: Illegal Operation detected (%08x)!\n", dc390_laststatus
);
279 dc390_dumpinfo (pACB
, pACB
->pActiveDCB
, pACB
->pActiveDCB
->pActiveSRB
);
282 else if (istatus
& INVALID_CMD
)
284 printk ("DC390: Invalid Command detected (%08x)!\n", dc390_laststatus
);
285 dc390_InvalidCmd( pACB
);
289 if (istatus
& SCSI_RESET
)
291 dc390_ScsiRstDetect( pACB
);
295 if (istatus
& DISCONNECTED
)
297 dc390_Disconnect( pACB
);
301 if (istatus
& RESELECTED
)
303 dc390_Reselect( pACB
);
307 else if (istatus
& (SELECTED
| SEL_ATTENTION
))
309 printk (KERN_ERR
"DC390: Target mode not supported!\n");
313 if (istatus
& (SUCCESSFUL_OP
|SERVICE_REQUEST
) )
315 pDCB
= pACB
->pActiveDCB
;
318 printk (KERN_ERR
"DC390: Suc. op/ Serv. req: pActiveDCB = 0!\n");
321 pSRB
= pDCB
->pActiveSRB
;
322 if( pDCB
->DCBFlag
& ABORT_DEV_
)
323 dc390_EnableMsgOut_Abort (pACB
, pSRB
);
325 phase
= pSRB
->ScsiPhase
;
326 DEBUG1(printk (KERN_INFO
"DC390: [%i]%s(0) (%02x)\n", phase
, dc390_p0_str
[phase
], sstatus
);)
327 stateV
= (void *) dc390_phase0
[phase
];
328 ( *stateV
)( pACB
, pSRB
, &sstatus
);
330 pSRB
->ScsiPhase
= sstatus
& 7;
331 phase
= (UCHAR
) sstatus
& 7;
332 DEBUG1(printk (KERN_INFO
"DC390: [%i]%s(1) (%02x)\n", phase
, dc390_p1_str
[phase
], sstatus
);)
333 stateV
= (void *) dc390_phase1
[phase
];
334 ( *stateV
)( pACB
, pSRB
, &sstatus
);
342 //DC390_UNLOCK_DRV; /* Restore initial flags */
346 do_DC390_Interrupt( int irq
, void *dev_id
, struct pt_regs
*regs
)
348 DEBUG1(printk (KERN_INFO
"DC390: Irq (%i) caught: ", irq
);)
349 /* Locking is done in DC390_Interrupt */
350 DC390_Interrupt(irq
, dev_id
, regs
);
351 DEBUG1(printk (".. IRQ returned\n");)
355 dc390_DataOut_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
)
359 UINT ResidCnt
, xferCnt
;
364 if( !(pSRB
->SRBState
& SRB_XFERPAD
) )
366 if( sstatus
& (PARITY_ERR
| ILLEGAL_OP_ERR
) )
367 pSRB
->SRBStatus
|= PARITY_ERROR
;
369 if( sstatus
& COUNT_2_ZERO
)
371 int ctr
= 6000000; /* only try for about a second */
372 while( --ctr
&& !((dstate
= DC390_read8 (DMA_Status
)) & DMA_XFER_DONE
) && pSRB
->SGToBeXferLen
);
373 if (!ctr
) printk (KERN_CRIT
"DC390: Deadlock in DataOut_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr
));
374 dc390_laststatus
&= ~0xff000000; dc390_laststatus
|= dstate
<< 24;
375 pSRB
->TotalXferredLen
+= pSRB
->SGToBeXferLen
;
377 if( pSRB
->SGIndex
< pSRB
->SGcount
)
379 pSRB
->pSegmentList
++;
380 psgl
= pSRB
->pSegmentList
;
382 pSRB
->SGBusAddr
= virt_to_bus( psgl
->address
);
383 pSRB
->SGToBeXferLen
= (ULONG
) psgl
->length
;
386 pSRB
->SGToBeXferLen
= 0;
390 ResidCnt
= (UINT
) DC390_read8 (Current_Fifo
) & 0x1f;
391 ResidCnt
|= (UINT
) DC390_read8 (CtcReg_High
) << 16;
392 ResidCnt
|= (UINT
) DC390_read8 (CtcReg_Mid
) << 8;
393 ResidCnt
+= (UINT
) DC390_read8 (CtcReg_Low
);
395 xferCnt
= pSRB
->SGToBeXferLen
- ResidCnt
;
396 pSRB
->SGBusAddr
+= xferCnt
;
397 pSRB
->TotalXferredLen
+= xferCnt
;
398 pSRB
->SGToBeXferLen
= ResidCnt
;
401 if ((*psstatus
& 7) != SCSI_DATA_OUT
)
403 DC390_write8 (DMA_Cmd
, WRITE_DIRECTION
+DMA_IDLE_CMD
); /* | DMA_INT */
404 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
409 dc390_DataIn_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
)
411 UCHAR sstatus
, residual
, bval
;
419 if( !(pSRB
->SRBState
& SRB_XFERPAD
) )
421 if( sstatus
& (PARITY_ERR
| ILLEGAL_OP_ERR
))
422 pSRB
->SRBStatus
|= PARITY_ERROR
;
424 if( sstatus
& COUNT_2_ZERO
)
426 int ctr
= 6000000; /* only try for about a second */
428 while( --ctr
&& !((dstate
= DC390_read8 (DMA_Status
)) & DMA_XFER_DONE
) && pSRB
->SGToBeXferLen
);
429 if (!ctr
) printk (KERN_CRIT
"DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr
));
430 if (!ctr
) printk (KERN_CRIT
"DC390: DataIn_0: DMA State: %i\n", dstate
);
431 dc390_laststatus
&= ~0xff000000; dc390_laststatus
|= dstate
<< 24;
432 DEBUG1(ResidCnt
= ((ULONG
) DC390_read8 (CtcReg_High
) << 16) \
433 + ((ULONG
) DC390_read8 (CtcReg_Mid
) << 8) \
434 + ((ULONG
) DC390_read8 (CtcReg_Low
));)
435 DEBUG1(printk (KERN_DEBUG
"Count_2_Zero (ResidCnt=%i,ToBeXfer=%li),", ResidCnt
, pSRB
->SGToBeXferLen
);)
437 DC390_write8 (DMA_Cmd
, READ_DIRECTION
+DMA_IDLE_CMD
); /* | DMA_INT */
439 pSRB
->TotalXferredLen
+= pSRB
->SGToBeXferLen
;
441 if( pSRB
->SGIndex
< pSRB
->SGcount
)
443 pSRB
->pSegmentList
++;
444 psgl
= pSRB
->pSegmentList
;
446 pSRB
->SGBusAddr
= virt_to_bus( psgl
->address
);
447 pSRB
->SGToBeXferLen
= (ULONG
) psgl
->length
;
450 pSRB
->SGToBeXferLen
= 0;
452 else /* phase changed */
455 bval
= DC390_read8 (Current_Fifo
);
458 DEBUG1(printk (KERN_DEBUG
"Check for residuals,");)
459 if( (bval
& 0x1f) == 1 )
461 for(i
=0; i
< 0x100; i
++)
463 bval
= DC390_read8 (Current_Fifo
);
466 else if( i
== 0x0ff )
468 residual
= 1; /* ;1 residual byte */
474 bval
= DC390_read8 (Current_Fifo
);
477 DC390_write8 (DMA_Cmd
, READ_DIRECTION
+DMA_BLAST_CMD
);
478 for (i
= 0xa000; i
; i
--)
480 bval
= DC390_read8 (DMA_Status
);
481 if (bval
& BLAST_COMPLETE
)
484 /* It seems a DMA Blast abort isn't that bad ... */
485 if (!i
) printk (KERN_ERR
"DC390: DMA Blast aborted unfinished!\n");
486 //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
487 dc390_laststatus
&= ~0xff000000; dc390_laststatus
|= bval
<< 24;
489 DEBUG1(printk (KERN_DEBUG
"Blast: Read %i times DMA_Status %02x", 0xa000-i
, bval
);)
490 ResidCnt
= (UINT
) DC390_read8 (CtcReg_High
);
492 ResidCnt
|= (UINT
) DC390_read8 (CtcReg_Mid
);
494 ResidCnt
|= (UINT
) DC390_read8 (CtcReg_Low
);
496 xferCnt
= pSRB
->SGToBeXferLen
- ResidCnt
;
497 pSRB
->SGBusAddr
+= xferCnt
;
498 pSRB
->TotalXferredLen
+= xferCnt
;
499 pSRB
->SGToBeXferLen
= ResidCnt
;
503 bval
= DC390_read8 (ScsiFifo
); /* get one residual byte */
504 ptr
= (PUCHAR
) bus_to_virt( pSRB
->SGBusAddr
);
506 pSRB
->SGBusAddr
++; xferCnt
++;
507 pSRB
->TotalXferredLen
++;
508 pSRB
->SGToBeXferLen
--;
510 DEBUG1(printk (KERN_DEBUG
"Xfered: %li, Total: %li, Remaining: %li\n", xferCnt
,\
511 pSRB
->TotalXferredLen
, pSRB
->SGToBeXferLen
);)
515 if ((*psstatus
& 7) != SCSI_DATA_IN
)
517 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
518 DC390_write8 (DMA_Cmd
, READ_DIRECTION
+DMA_IDLE_CMD
); /* | DMA_INT */
523 dc390_Command_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
)
528 dc390_Status_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
)
531 pSRB
->TargetStatus
= DC390_read8 (ScsiFifo
);
533 pSRB
->EndMessage
= DC390_read8 (ScsiFifo
); /* get message */
535 *psstatus
= SCSI_NOP0
;
536 pSRB
->SRBState
= SRB_COMPLETED
;
537 DC390_write8 (ScsiCmd
, MSG_ACCEPTED_CMD
);
541 dc390_MsgOut_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
)
543 if( pSRB
->SRBState
& (SRB_UNEXPECT_RESEL
+SRB_ABORT_SENT
) )
544 *psstatus
= SCSI_NOP0
;
545 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
549 static void __inline__
550 dc390_reprog (PACB pACB
, PDCB pDCB
)
552 DC390_write8 (Sync_Period
, pDCB
->SyncPeriod
);
553 DC390_write8 (Sync_Offset
, pDCB
->SyncOffset
);
554 DC390_write8 (CtrlReg3
, pDCB
->CtrlR3
);
555 DC390_write8 (CtrlReg4
, pDCB
->CtrlR4
);
556 dc390_SetXferRate (pACB
, pDCB
);
562 dc390_printMsg (UCHAR
*MsgBuf
, UCHAR len
)
565 printk (" %02x", MsgBuf
[0]);
566 for (i
= 1; i
< len
; i
++)
567 printk (" %02x", MsgBuf
[i
]);
572 #define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD)
575 static void __inline__
576 dc390_MsgIn_reject (PACB pACB
, PSRB pSRB
)
578 pSRB
->MsgOutBuf
[0] = MESSAGE_REJECT
;
579 pSRB
->MsgCnt
= 1; DC390_ENABLE_MSGOUT
;
580 DEBUG0 (printk (KERN_INFO
"DC390: Reject message\n");)
584 static void __inline__
585 dc390_EnableMsgOut_Abort ( PACB pACB
, PSRB pSRB
)
587 pSRB
->MsgOutBuf
[0] = ABORT
;
588 pSRB
->MsgCnt
= 1; DC390_ENABLE_MSGOUT
;
589 pSRB
->pSRBDCB
->DCBFlag
&= ~ABORT_DEV_
;
593 dc390_MsgIn_QTag (PACB pACB
, PDCB pDCB
, UCHAR tag
)
595 PSRB lastSRB
= pDCB
->pGoingLast
;
596 PSRB pSRB
= pDCB
->pGoingSRB
;
602 if (pSRB
->TagNumber
== tag
) break;
603 if (pSRB
== lastSRB
) goto mingx0
;
604 pSRB
= pSRB
->pNextSRB
;
607 if( pDCB
->DCBFlag
& ABORT_DEV_
)
609 pSRB
->SRBState
= SRB_ABORT_SENT
;
610 dc390_EnableMsgOut_Abort( pACB
, pSRB
);
613 if( !(pSRB
->SRBState
& SRB_DISCONNECT
) )
616 pDCB
->pActiveSRB
= pSRB
;
617 pSRB
->SRBState
= SRB_DATA_XFER
;
622 pSRB
= pACB
->pTmpSRB
;
623 pSRB
->SRBState
= SRB_UNEXPECT_RESEL
;
624 pDCB
->pActiveSRB
= pSRB
;
625 pSRB
->MsgOutBuf
[0] = ABORT_TAG
;
626 pSRB
->MsgCnt
= 1; DC390_ENABLE_MSGOUT
;
632 /* set async transfer mode */
634 dc390_MsgIn_set_async (PACB pACB
, PSRB pSRB
)
636 PDCB pDCB
= pSRB
->pSRBDCB
;
637 if (!(pSRB
->SRBState
& DO_SYNC_NEGO
))
638 printk (KERN_INFO
"DC390: Target %i initiates Non-Sync?\n", pDCB
->TargetID
);
639 pSRB
->SRBState
&= ~DO_SYNC_NEGO
;
640 pDCB
->SyncMode
&= ~(SYNC_ENABLE
+SYNC_NEGO_DONE
);
641 pDCB
->SyncPeriod
= 0;
642 pDCB
->SyncOffset
= 0;
643 //pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
644 pDCB
->CtrlR3
= FAST_CLK
; /* fast clock / normal scsi */
645 pDCB
->CtrlR4
&= 0x3f;
646 pDCB
->CtrlR4
|= pACB
->glitch_cfg
; /* glitch eater */
647 dc390_reprog (pACB
, pDCB
);
650 /* set sync transfer mode */
652 dc390_MsgIn_set_sync (PACB pACB
, PSRB pSRB
)
656 PDCB pDCB
= pSRB
->pSRBDCB
;
657 UCHAR oldsyncperiod
= pDCB
->SyncPeriod
;
658 UCHAR oldsyncoffset
= pDCB
->SyncOffset
;
660 if (!(pSRB
->SRBState
& DO_SYNC_NEGO
))
662 printk (KERN_INFO
"DC390: Target %i initiates Sync: %ins %i ... answer ...\n",
663 pDCB
->TargetID
, pSRB
->MsgInBuf
[3]<<2, pSRB
->MsgInBuf
[4]);
666 //dc390_MsgIn_reject (pACB, pSRB);
667 //return dc390_MsgIn_set_async (pACB, pSRB);
669 /* Reply with corrected SDTR Message */
670 if (pSRB
->MsgInBuf
[4] > 15)
672 printk (KERN_INFO
"DC390: Lower Sync Offset to 15\n");
673 pSRB
->MsgInBuf
[4] = 15;
675 if (pSRB
->MsgInBuf
[3] < pDCB
->NegoPeriod
)
677 printk (KERN_INFO
"DC390: Set sync nego period to %ins\n", pDCB
->NegoPeriod
<< 2);
678 pSRB
->MsgInBuf
[3] = pDCB
->NegoPeriod
;
680 memcpy (pSRB
->MsgOutBuf
, pSRB
->MsgInBuf
, 5);
685 pSRB
->SRBState
&= ~DO_SYNC_NEGO
;
686 pDCB
->SyncMode
|= SYNC_ENABLE
+SYNC_NEGO_DONE
;
687 pDCB
->SyncOffset
&= 0x0f0;
688 pDCB
->SyncOffset
|= pSRB
->MsgInBuf
[4];
689 pDCB
->NegoPeriod
= pSRB
->MsgInBuf
[3];
691 wval
= (USHORT
) pSRB
->MsgInBuf
[3];
692 wval
= wval
<< 2; wval
-= 3; wval1
= wval
/ 25; /* compute speed */
693 if( (wval1
* 25) != wval
) wval1
++;
694 bval
= FAST_CLK
+FAST_SCSI
; /* fast clock / fast scsi */
696 pDCB
->CtrlR4
&= 0x3f; /* Glitch eater: 12ns less than normal */
697 if (pACB
->glitch_cfg
!= NS_TO_GLITCH(0))
698 pDCB
->CtrlR4
|= NS_TO_GLITCH(((GLITCH_TO_NS(pACB
->glitch_cfg
)) - 1));
700 pDCB
->CtrlR4
|= NS_TO_GLITCH(0);
701 if (wval1
< 4) pDCB
->CtrlR4
|= NS_TO_GLITCH(0); /* Ultra */
705 wval1
--; /* Timing computation differs by 1 from FAST_SCSI */
706 bval
= FAST_CLK
; /* fast clock / normal scsi */
707 pDCB
->CtrlR4
|= pACB
->glitch_cfg
; /* glitch eater */
711 pDCB
->SyncPeriod
= (UCHAR
)wval1
;
713 if ((oldsyncperiod
!= wval1
|| oldsyncoffset
!= pDCB
->SyncOffset
) && pDCB
->TargetLUN
== 0)
715 if (! (bval
& FAST_SCSI
)) wval1
++;
716 printk (KERN_INFO
"DC390: Target %i: Sync transfer %i.%1i MHz, Offset %i\n", pDCB
->TargetID
,
717 40/wval1
, ((40%wval1
)*10+wval1
/2)/wval1
, pDCB
->SyncOffset
& 0x0f);
720 dc390_reprog (pACB
, pDCB
);
724 /* handle RESTORE_PTR */
726 dc390_restore_ptr (PACB pACB
, PSRB pSRB
)
729 pSRB
->TotalXferredLen
= 0;
731 if( pSRB
->pcmd
->use_sg
)
733 pSRB
->SGcount
= (UCHAR
) pSRB
->pcmd
->use_sg
;
734 pSRB
->pSegmentList
= (PSGL
) pSRB
->pcmd
->request_buffer
;
735 psgl
= pSRB
->pSegmentList
;
736 while (pSRB
->TotalXferredLen
+ (ULONG
) psgl
->length
< pSRB
->Saved_Ptr
)
738 pSRB
->TotalXferredLen
+= (ULONG
) psgl
->length
;
740 if( pSRB
->SGIndex
< pSRB
->SGcount
)
742 pSRB
->pSegmentList
++;
743 psgl
= pSRB
->pSegmentList
;
745 pSRB
->SGBusAddr
= virt_to_bus( psgl
->address
);
746 pSRB
->SGToBeXferLen
= (ULONG
) psgl
->length
;
749 pSRB
->SGToBeXferLen
= 0;
751 pSRB
->SGToBeXferLen
-= (pSRB
->Saved_Ptr
- pSRB
->TotalXferredLen
);
752 pSRB
->SGBusAddr
+= (pSRB
->Saved_Ptr
- pSRB
->TotalXferredLen
);
753 printk (KERN_INFO
"DC390: Pointer restored. Segment %i, Total %li, Bus %08lx\n", pSRB
->SGIndex
, pSRB
->Saved_Ptr
, pSRB
->SGBusAddr
);
755 else if( pSRB
->pcmd
->request_buffer
)
758 pSRB
->pSegmentList
= (PSGL
) &pSRB
->Segmentx
;
759 pSRB
->Segmentx
.address
= (PUCHAR
) pSRB
->pcmd
->request_buffer
+ pSRB
->Saved_Ptr
;
760 pSRB
->Segmentx
.length
= pSRB
->pcmd
->request_bufflen
- pSRB
->Saved_Ptr
;
761 printk (KERN_INFO
"DC390: Pointer restored. Total %li, Bus %p\n",
762 pSRB
->Saved_Ptr
, pSRB
->Segmentx
.address
);
767 printk (KERN_INFO
"DC390: RESTORE_PTR message for Transfer without Scatter-Gather ??\n");
770 pSRB
->TotalXferredLen
= pSRB
->Saved_Ptr
;
774 /* According to the docs, the AM53C974 reads the message and
775 * generates a Succesful Operation IRQ before asserting ACK for
776 * the last byte (how does it know whether it's the last ?) */
777 /* The old code handled it in another way, indicating, that on
778 * every message byte an IRQ is generated and every byte has to
779 * be manually ACKed. Hmmm ? (KG, 98/11/28) */
780 /* The old implementation was correct. Sigh! */
782 /* Check if the message is complete */
783 static UCHAR __inline__
784 dc390_MsgIn_complete (UCHAR
*msgbuf
, UINT len
)
786 if (*msgbuf
== EXTENDED_MESSAGE
)
788 if (len
< 2) return 0;
789 if (len
< msgbuf
[1] + 2) return 0;
791 else if (*msgbuf
>= 0x20 && *msgbuf
<= 0x2f) // two byte messages
792 if (len
< 2) return 0;
798 /* read and eval received messages */
800 dc390_MsgIn_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
)
802 PDCB pDCB
= pACB
->pActiveDCB
;
806 pSRB
->MsgInBuf
[pACB
->MsgLen
++] = DC390_read8 (ScsiFifo
);
807 //pSRB->SRBState = 0;
810 if (dc390_MsgIn_complete (pSRB
->MsgInBuf
, pACB
->MsgLen
))
812 DEBUG0 (printk (KERN_INFO
"DC390: MsgIn:"); dc390_printMsg (pSRB
->MsgInBuf
, pACB
->MsgLen
);)
813 /* Now eval the msg */
814 switch (pSRB
->MsgInBuf
[0])
817 pSRB
->SRBState
= SRB_DISCONNECT
; break;
819 case SIMPLE_QUEUE_TAG
:
820 case HEAD_OF_QUEUE_TAG
:
821 case ORDERED_QUEUE_TAG
:
822 pSRB
= dc390_MsgIn_QTag (pACB
, pDCB
, pSRB
->MsgInBuf
[1]);
826 DC390_write8 (ScsiCmd
, RESET_ATN_CMD
);
827 pDCB
->NegoPeriod
= 50; /* 200ns <=> 5 MHz */
828 if( pSRB
->SRBState
& DO_SYNC_NEGO
)
829 dc390_MsgIn_set_async (pACB
, pSRB
);
832 case EXTENDED_MESSAGE
:
833 /* reject every extended msg but SDTR */
834 if (pSRB
->MsgInBuf
[1] != 3 || pSRB
->MsgInBuf
[2] != EXTENDED_SDTR
)
835 dc390_MsgIn_reject (pACB
, pSRB
);
838 if (pSRB
->MsgInBuf
[3] == 0 || pSRB
->MsgInBuf
[4] == 0)
839 dc390_MsgIn_set_async (pACB
, pSRB
);
841 dc390_MsgIn_set_sync (pACB
, pSRB
);
844 // nothing has to be done
845 case COMMAND_COMPLETE
: break;
847 // SAVE POINTER may be ignored as we have the PSRB associated with the
848 // scsi command. Thanks, Gerard, for pointing it out.
850 pSRB
->Saved_Ptr
= pSRB
->TotalXferredLen
;
852 // The device might want to restart transfer with a RESTORE
853 case RESTORE_POINTERS
:
854 DEBUG0(printk ("DC390: RESTORE POINTER message received ... try to handle\n");)
855 dc390_restore_ptr (pACB
, pSRB
);
858 // reject unknown messages
859 default: dc390_MsgIn_reject (pACB
, pSRB
);
862 /* Clear counter and MsgIn state */
863 pSRB
->SRBState
&= ~SRB_MSGIN
;
867 *psstatus
= SCSI_NOP0
;
868 DC390_write8 (ScsiCmd
, MSG_ACCEPTED_CMD
);
869 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
874 dc390_DataIO_Comm( PACB pACB
, PSRB pSRB
, UCHAR ioDir
)
878 PDCB pDCB
= pACB
->pActiveDCB
;
880 if (pSRB
== pACB
->pTmpSRB
)
882 if (pDCB
) printk (KERN_ERR
"DC390: pSRB == pTmpSRB! (TagQ Error?) (%02i-%i)\n",
883 pDCB
->TargetID
, pDCB
->TargetLUN
);
884 else printk (KERN_ERR
"DC390: pSRB == pTmpSRB! (TagQ Error?) (DCB 0!)\n");
885 dc390_EnableMsgOut_Abort (pACB
, pSRB
);
886 if (pDCB
) pDCB
->DCBFlag
|= ABORT_DEV
;
890 if( pSRB
->SGIndex
< pSRB
->SGcount
)
892 DC390_write8 (DMA_Cmd
, DMA_IDLE_CMD
| ioDir
/* | DMA_INT */);
893 if( !pSRB
->SGToBeXferLen
)
895 psgl
= pSRB
->pSegmentList
;
896 pSRB
->SGBusAddr
= virt_to_bus( psgl
->address
);
897 pSRB
->SGToBeXferLen
= (ULONG
) psgl
->length
;
898 DEBUG1(printk (KERN_DEBUG
" DC390: Next SG segment.");)
900 lval
= pSRB
->SGToBeXferLen
;
901 DEBUG1(printk (KERN_DEBUG
" DC390: Start transfer: %li bytes (address %08lx)\n", lval
, pSRB
->SGBusAddr
);)
902 DC390_write8 (CtcReg_Low
, (UCHAR
) lval
);
904 DC390_write8 (CtcReg_Mid
, (UCHAR
) lval
);
906 DC390_write8 (CtcReg_High
, (UCHAR
) lval
);
908 DC390_write32 (DMA_XferCnt
, pSRB
->SGToBeXferLen
);
909 DC390_write32 (DMA_XferAddr
, pSRB
->SGBusAddr
);
911 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); /* | DMA_INT; */
912 pSRB
->SRBState
= SRB_DATA_XFER
;
914 DC390_write8 (ScsiCmd
, DMA_COMMAND
+INFO_XFER_CMD
);
916 DC390_write8 (DMA_Cmd
, DMA_START_CMD
| ioDir
| DMA_INT
);
917 //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);)
918 //DEBUG1(printk (KERN_DEBUG "DC390: DMA_Status: %02x\n", DC390_read8 (DMA_Status));)
919 //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);)
925 pSRB
->AdaptStatus
= H_OVER_UNDER_RUN
;
926 pSRB
->SRBStatus
|= OVER_RUN
;
927 DEBUG0(printk (KERN_WARNING
" DC390: Overrun -");)
929 DEBUG0(printk (KERN_WARNING
" Clear transfer pad \n");)
930 DC390_write8 (CtcReg_Low
, 0);
931 DC390_write8 (CtcReg_Mid
, 0);
932 DC390_write8 (CtcReg_High
, 0);
934 pSRB
->SRBState
|= SRB_XFERPAD
;
935 DC390_write8 (ScsiCmd
, DMA_COMMAND
+XFER_PAD_BYTE
);
937 DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); // | DMA_INT;
938 DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
945 dc390_DataOutPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
)
947 dc390_DataIO_Comm (pACB
, pSRB
, WRITE_DIRECTION
);
951 dc390_DataInPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
)
953 dc390_DataIO_Comm (pACB
, pSRB
, READ_DIRECTION
);
957 dc390_CommandPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
)
963 DC390_write8 (ScsiCmd
, RESET_ATN_CMD
);
964 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
965 if( !(pSRB
->SRBFlag
& AUTO_REQSENSE
) )
967 cnt
= (UCHAR
) pSRB
->pcmd
->cmd_len
;
968 ptr
= (PUCHAR
) pSRB
->pcmd
->cmnd
;
969 for(i
=0; i
< cnt
; i
++)
970 DC390_write8 (ScsiFifo
, *(ptr
++));
975 DC390_write8 (ScsiFifo
, REQUEST_SENSE
);
976 pDCB
= pACB
->pActiveDCB
;
977 DC390_write8 (ScsiFifo
, pDCB
->TargetLUN
<< 5);
978 DC390_write8 (ScsiFifo
, bval
);
979 DC390_write8 (ScsiFifo
, bval
);
980 DC390_write8 (ScsiFifo
, sizeof(pSRB
->pcmd
->sense_buffer
));
981 DC390_write8 (ScsiFifo
, bval
);
982 DEBUG0(printk(KERN_DEBUG
"DC390: AutoReqSense (CmndPhase)!\n");)
984 pSRB
->SRBState
= SRB_COMMAND
;
985 DC390_write8 (ScsiCmd
, INFO_XFER_CMD
);
989 dc390_StatusPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
)
991 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
992 pSRB
->SRBState
= SRB_STATUS
;
993 DC390_write8 (ScsiCmd
, INITIATOR_CMD_CMPLTE
);
994 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
998 dc390_MsgOutPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
)
1004 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
1005 pDCB
= pACB
->pActiveDCB
;
1006 if( !(pSRB
->SRBState
& SRB_MSGOUT
) )
1011 ptr
= (PUCHAR
) pSRB
->MsgOutBuf
;
1012 for(i
=0; i
< cnt
; i
++)
1013 DC390_write8 (ScsiFifo
, *(ptr
++));
1015 if( (pDCB
->DCBFlag
& ABORT_DEV_
) &&
1016 (pSRB
->MsgOutBuf
[0] == ABORT
) )
1017 pSRB
->SRBState
= SRB_ABORT_SENT
;
1021 bval
= ABORT
; /* ??? MSG_NOP */
1022 if( (pSRB
->pcmd
->cmnd
[0] == INQUIRY
) ||
1023 (pSRB
->pcmd
->cmnd
[0] == REQUEST_SENSE
) ||
1024 (pSRB
->SRBFlag
& AUTO_REQSENSE
) )
1026 if( pDCB
->SyncMode
& SYNC_ENABLE
)
1029 DC390_write8 (ScsiFifo
, bval
);
1031 DC390_write8 (ScsiCmd
, INFO_XFER_CMD
);
1036 printk (KERN_ERR
"DC390: OLD Sync Nego code triggered! (%i %i)\n", pDCB
->TargetID
, pDCB
->TargetLUN
);
1037 DC390_write8 (ScsiFifo
, EXTENDED_MESSAGE
);
1038 DC390_write8 (ScsiFifo
, 3); /* ;length of extended msg */
1039 DC390_write8 (ScsiFifo
, EXTENDED_SDTR
); /* ; sync nego */
1040 DC390_write8 (ScsiFifo
, pDCB
->NegoPeriod
);
1041 if (pDCB
->SyncOffset
& 0x0f)
1042 DC390_write8 (ScsiFifo
, pDCB
->SyncOffset
);
1044 DC390_write8 (ScsiFifo
, SYNC_NEGO_OFFSET
);
1045 pSRB
->SRBState
|= DO_SYNC_NEGO
;
1046 DC390_write8 (ScsiCmd
, INFO_XFER_CMD
);
1051 dc390_MsgInPhase( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
)
1053 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
1054 if( !(pSRB
->SRBState
& SRB_MSGIN
) )
1056 pSRB
->SRBState
&= ~SRB_DISCONNECT
;
1057 pSRB
->SRBState
|= SRB_MSGIN
;
1059 DC390_write8 (ScsiCmd
, INFO_XFER_CMD
);
1060 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1064 dc390_Nop_0( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
)
1069 dc390_Nop_1( PACB pACB
, PSRB pSRB
, PUCHAR psstatus
)
1075 dc390_SetXferRate( PACB pACB
, PDCB pDCB
)
1080 if( !(pDCB
->TargetLUN
) )
1082 if( !pACB
->scan_devices
)
1084 ptr
= pACB
->pLinkDCB
;
1086 bval
= pDCB
->TargetID
;
1087 for(i
=0; i
<cnt
; i
++)
1089 if( ptr
->TargetID
== bval
)
1091 ptr
->SyncPeriod
= pDCB
->SyncPeriod
;
1092 ptr
->SyncOffset
= pDCB
->SyncOffset
;
1093 ptr
->CtrlR3
= pDCB
->CtrlR3
;
1094 ptr
->CtrlR4
= pDCB
->CtrlR4
;
1095 ptr
->SyncMode
= pDCB
->SyncMode
;
1097 ptr
= ptr
->pNextDCB
;
1106 dc390_Disconnect( PACB pACB
)
1112 DEBUG0(printk(KERN_INFO
"DISC,");)
1114 if (!pACB
->Connected
) printk(KERN_ERR
"DC390: Disconnect not-connected bus?\n");
1115 pACB
->Connected
= 0;
1116 pDCB
= pACB
->pActiveDCB
;
1120 DEBUG0(printk(KERN_ERR
"ACB:%p->ActiveDCB:%p IOPort:%04x IRQ:%02x !\n",\
1121 pACB
, pDCB
, pACB
->IOPortBase
, pACB
->IRQLevel
);)
1122 while (--j
) udelay (1000);
1123 DC390_read8 (INT_Status
); /* Reset Pending INT */
1124 DC390_write8 (ScsiCmd
, EN_SEL_RESEL
);
1127 DC390_write8 (ScsiCmd
, EN_SEL_RESEL
);
1128 pSRB
= pDCB
->pActiveSRB
;
1129 pACB
->pActiveDCB
= 0;
1130 pSRB
->ScsiPhase
= SCSI_NOP0
;
1131 if( pSRB
->SRBState
& SRB_UNEXPECT_RESEL
)
1134 dc390_Waiting_process ( pACB
);
1136 else if( pSRB
->SRBState
& SRB_ABORT_SENT
)
1140 cnt
= pDCB
->GoingSRBCnt
;
1141 pDCB
->GoingSRBCnt
= 0;
1142 pSRB
= pDCB
->pGoingSRB
;
1143 for( i
=0; i
< cnt
; i
++)
1145 psrb
= pSRB
->pNextSRB
;
1146 dc390_Free_insert (pACB
, pSRB
);
1149 pDCB
->pGoingSRB
= 0;
1150 dc390_Query_to_Waiting (pACB
);
1151 dc390_Waiting_process (pACB
);
1155 if( (pSRB
->SRBState
& (SRB_START_
+SRB_MSGOUT
)) ||
1156 !(pSRB
->SRBState
& (SRB_DISCONNECT
+SRB_COMPLETED
)) )
1157 { /* Selection time out */
1158 if( !(1/*pACB->scan_devices*/) )
1160 pSRB
->SRBState
= SRB_READY
;
1161 dc390_freetag (pDCB
, pSRB
);
1162 dc390_Going_to_Waiting (pDCB
, pSRB
);
1163 dc390_waiting_timer (pACB
, HZ
/5);
1167 pSRB
->TargetStatus
= SCSI_STAT_SEL_TIMEOUT
;
1171 else if( pSRB
->SRBState
& SRB_DISCONNECT
)
1173 dc390_Waiting_process ( pACB
);
1175 else if( pSRB
->SRBState
& SRB_COMPLETED
)
1178 dc390_freetag (pDCB
, pSRB
);
1179 pDCB
->pActiveSRB
= 0;
1180 pSRB
->SRBState
= SRB_FREE
;
1181 dc390_SRBdone( pACB
, pDCB
, pSRB
);
1189 dc390_Reselect( PACB pACB
)
1195 DEBUG0(printk(KERN_INFO
"RSEL,");)
1196 pACB
->Connected
= 1;
1197 pDCB
= pACB
->pActiveDCB
;
1199 { /* Arbitration lost but Reselection won */
1200 DEBUG0(printk ("DC390: (ActiveDCB != 0: Arb. lost but resel. won)!\n");)
1201 pSRB
= pDCB
->pActiveSRB
;
1202 if( !( pACB
->scan_devices
) )
1204 pSRB
->SRBState
= SRB_READY
;
1205 dc390_freetag (pDCB
, pSRB
);
1206 dc390_Going_to_Waiting ( pDCB
, pSRB
);
1207 dc390_waiting_timer (pACB
, HZ
/5);
1211 lun
= DC390_read8 (ScsiFifo
);
1212 DEBUG0(printk ("Dev %02x,", lun
);)
1213 if (!(lun
& (1 << pACB
->pScsiHost
->this_id
)))
1214 printk (KERN_ERR
"DC390: Reselection must select host adapter: %02x!\n", lun
);
1216 lun
^= 1 << pACB
->pScsiHost
->this_id
; /* Mask AdapterID */
1217 id
= 0; while (lun
>>= 1) id
++;
1219 lun
= DC390_read8 (ScsiFifo
);
1220 if (!(lun
& IDENTIFY_BASE
)) printk (KERN_ERR
"DC390: Resel: Expect identify message!\n");
1222 DEBUG0(printk ("(%02i-%i),", id
, lun
);)
1223 pDCB
= dc390_findDCB (pACB
, id
, lun
);
1226 printk (KERN_ERR
"DC390: Reselect from non existing device (%02i-%i)\n",
1230 pACB
->pActiveDCB
= pDCB
;
1231 /* TagQ: We expect a message soon, so never mind the exact SRB */
1232 if( pDCB
->SyncMode
& EN_TAG_QUEUEING
)
1234 pSRB
= pACB
->pTmpSRB
;
1235 pDCB
->pActiveSRB
= pSRB
;
1239 pSRB
= pDCB
->pActiveSRB
;
1240 if( !pSRB
|| !(pSRB
->SRBState
& SRB_DISCONNECT
) )
1242 pSRB
= pACB
->pTmpSRB
;
1243 pSRB
->SRBState
= SRB_UNEXPECT_RESEL
;
1244 printk (KERN_ERR
"DC390: Reselect without outstanding cmnd (%02i-%i)\n",
1246 pDCB
->pActiveSRB
= pSRB
;
1247 dc390_EnableMsgOut_Abort ( pACB
, pSRB
);
1251 if( pDCB
->DCBFlag
& ABORT_DEV_
)
1253 pSRB
->SRBState
= SRB_ABORT_SENT
;
1254 printk (KERN_INFO
"DC390: Reselect: Abort (%02i-%i)\n",
1256 dc390_EnableMsgOut_Abort( pACB
, pSRB
);
1259 pSRB
->SRBState
= SRB_DATA_XFER
;
1263 DEBUG1(printk (KERN_DEBUG
"Resel SRB(%p): TagNum (%02x)\n", pSRB
, pSRB
->TagNumber
);)
1264 pSRB
->ScsiPhase
= SCSI_NOP0
;
1265 DC390_write8 (Scsi_Dest_ID
, pDCB
->TargetID
);
1266 DC390_write8 (Sync_Period
, pDCB
->SyncPeriod
);
1267 DC390_write8 (Sync_Offset
, pDCB
->SyncOffset
);
1268 DC390_write8 (CtrlReg1
, pDCB
->CtrlR1
);
1269 DC390_write8 (CtrlReg3
, pDCB
->CtrlR3
);
1270 DC390_write8 (CtrlReg4
, pDCB
->CtrlR4
); /* ; Glitch eater */
1271 DC390_write8 (ScsiCmd
, MSG_ACCEPTED_CMD
); /* ;to release the /ACK signal */
1276 dc390_remove_dev (PACB pACB
, PDCB pDCB
)
1278 PDCB pPrevDCB
= pACB
->pLinkDCB
;
1280 if (pDCB
->GoingSRBCnt
> 1)
1282 DCBDEBUG(printk (KERN_INFO
"DC390: Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %i\n",\
1283 pDCB
->TargetID
, pDCB
->TargetLUN
, (int)pDCB
, pDCB
->GoingSRBCnt
);)
1286 pACB
->DCBmap
[pDCB
->TargetID
] &= ~(1 << pDCB
->TargetLUN
);
1289 if (pDCB
== pACB
->pLinkDCB
)
1292 if (pACB
->pLastDCB
== pDCB
) {
1293 pDCB
->pNextDCB
= 0; pACB
->pLastDCB
= 0;
1295 pACB
->pLinkDCB
= pDCB
->pNextDCB
;
1299 while (pPrevDCB
->pNextDCB
!= pDCB
) pPrevDCB
= pPrevDCB
->pNextDCB
;
1300 pPrevDCB
->pNextDCB
= pDCB
->pNextDCB
;
1301 if (pDCB
== pACB
->pLastDCB
) pACB
->pLastDCB
= pPrevDCB
;
1304 DCBDEBUG(printk (KERN_INFO
"DC390: Driver about to free DCB (ID %i, LUN %i): %p\n",\
1305 pDCB
->TargetID
, pDCB
->TargetLUN
, pDCB
);)
1306 if (pDCB
== pACB
->pActiveDCB
) pACB
->pActiveDCB
= 0;
1307 if (pDCB
== pACB
->pLinkDCB
) pACB
->pLinkDCB
= pDCB
->pNextDCB
;
1308 if (pDCB
== pACB
->pDCBRunRobin
) pACB
->pDCBRunRobin
= pDCB
->pNextDCB
;
1311 /* pACB->DeviceCnt--; */
1315 static UCHAR __inline__
1316 dc390_tagq_blacklist (char* name
)
1319 for(i
=0; i
<BADDEVCNT
; i
++)
1320 if (memcmp (name
, dc390_baddevname1
[i
], 28) == 0)
1327 dc390_disc_tagq_set (PDCB pDCB
, PSCSI_INQDATA ptr
)
1329 /* Check for SCSI format (ANSI and Response data format) */
1330 if ( (ptr
->Vers
& 0x07) >= 2 || (ptr
->RDF
& 0x0F) == 2 )
1332 if ( (ptr
->Flags
& SCSI_INQ_CMDQUEUE
) &&
1333 (pDCB
->DevMode
& TAG_QUEUEING_
) &&
1334 /* ((pDCB->DevType == TYPE_DISK)
1335 || (pDCB->DevType == TYPE_MOD)) &&*/
1336 !dc390_tagq_blacklist (((char*)ptr
)+8) )
1338 if (pDCB
->MaxCommand
==1) pDCB
->MaxCommand
= pDCB
->pDCBACB
->TagMaxNum
;
1339 pDCB
->SyncMode
|= EN_TAG_QUEUEING
/* | EN_ATN_STOP */;
1340 //pDCB->TagMask = 0;
1343 pDCB
->MaxCommand
= 1;
1349 dc390_add_dev (PACB pACB
, PDCB pDCB
, PSCSI_INQDATA ptr
)
1351 UCHAR bval1
= ptr
->DevType
& SCSI_DEVTYPE
;
1352 pDCB
->DevType
= bval1
;
1353 /* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */
1354 dc390_disc_tagq_set (pDCB
, ptr
);
1359 dc390_SRBdone( PACB pACB
, PDCB pDCB
, PSRB pSRB
)
1361 UCHAR bval
, status
, i
, DCB_removed
;
1367 pcmd
= pSRB
->pcmd
; DCB_removed
= 0;
1368 status
= pSRB
->TargetStatus
;
1369 ptr
= (PSCSI_INQDATA
) (pcmd
->request_buffer
);
1371 ptr
= (PSCSI_INQDATA
) (((PSGL
) ptr
)->address
);
1373 DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status
, pcmd
->result
,\
1375 if(pSRB
->SRBFlag
& AUTO_REQSENSE
)
1376 { /* Last command was a Request Sense */
1377 pSRB
->SRBFlag
&= ~AUTO_REQSENSE
;
1378 pSRB
->AdaptStatus
= 0;
1379 pSRB
->TargetStatus
= CHECK_CONDITION
<< 1;
1380 #ifdef DC390_REMOVABLEDEBUG
1381 switch (pcmd
->sense_buffer
[2] & 0x0f)
1383 case NOT_READY
: printk (KERN_INFO
"DC390: ReqSense: NOT_READY (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1384 pcmd
->cmnd
[0], pDCB
->TargetID
, pDCB
->TargetLUN
,
1385 status
, pACB
->scan_devices
); break;
1386 case UNIT_ATTENTION
: printk (KERN_INFO
"DC390: ReqSense: UNIT_ATTENTION (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1387 pcmd
->cmnd
[0], pDCB
->TargetID
, pDCB
->TargetLUN
,
1388 status
, pACB
->scan_devices
); break;
1389 case ILLEGAL_REQUEST
: printk (KERN_INFO
"DC390: ReqSense: ILLEGAL_REQUEST (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1390 pcmd
->cmnd
[0], pDCB
->TargetID
, pDCB
->TargetLUN
,
1391 status
, pACB
->scan_devices
); break;
1392 case MEDIUM_ERROR
: printk (KERN_INFO
"DC390: ReqSense: MEDIUM_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1393 pcmd
->cmnd
[0], pDCB
->TargetID
, pDCB
->TargetLUN
,
1394 status
, pACB
->scan_devices
); break;
1395 case HARDWARE_ERROR
: printk (KERN_INFO
"DC390: ReqSense: HARDWARE_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1396 pcmd
->cmnd
[0], pDCB
->TargetID
, pDCB
->TargetLUN
,
1397 status
, pACB
->scan_devices
); break;
1400 //pcmd->result = MK_RES(DRIVER_SENSE,DID_OK,0,status);
1401 if (status
== (CHECK_CONDITION
<< 1))
1403 pcmd
->result
= MK_RES_LNX(0,DID_BAD_TARGET
,0,/*CHECK_CONDITION*/0);
1406 if(pSRB
->RetryCnt
== 0)
1408 //(UINT)(pSRB->pcmd->cmnd[0]) = pSRB->Segment0[0];
1409 pSRB
->TotalXferredLen
= pSRB
->SavedTotXLen
;
1410 if( (pSRB
->TotalXferredLen
) &&
1411 (pSRB
->TotalXferredLen
>= pcmd
->underflow
) )
1412 SET_RES_DID(pcmd
->result
,DID_OK
)
1414 pcmd
->result
= MK_RES_LNX(DRIVER_SENSE
,DID_OK
,0,CHECK_CONDITION
);
1415 REMOVABLEDEBUG(printk(KERN_INFO
"Cmd=%02x,Result=%08x,XferL=%08x\n",pSRB
->pcmd
->cmnd
[0],\
1416 (UINT
) pcmd
->result
, (UINT
) pSRB
->TotalXferredLen
);)
1422 pSRB
->AdaptStatus
= 0;
1423 pSRB
->TargetStatus
= 0;
1424 //*((PUINT) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
1425 //*((PUINT) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1];
1426 /* Don't retry on TEST_UNIT_READY */
1427 if( pSRB
->pcmd
->cmnd
[0] == TEST_UNIT_READY
/* || pSRB->pcmd->cmnd[0] == START_STOP */)
1429 pcmd
->result
= MK_RES_LNX(DRIVER_SENSE
,DID_OK
,0,CHECK_CONDITION
);
1430 REMOVABLEDEBUG(printk(KERN_INFO
"Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB
->pcmd
->cmnd
[0],\
1431 (UINT
) pcmd
->result
, (UINT
) pSRB
->TotalXferredLen
);)
1434 SET_RES_DRV(pcmd
->result
,DRIVER_SENSE
);
1435 pSRB
->SGcount
= (UCHAR
) pSRB
->SavedSGCount
;
1436 //pSRB->ScsiCmdLen = (UCHAR) (pSRB->Segment1[0] >> 8);
1437 DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd
->pid
, pcmd
->cmnd
[0], pcmd
->target
, pcmd
->lun
);)
1439 pSRB
->TotalXferredLen
= 0;
1440 pSRB
->SGToBeXferLen
= 0;
1442 pSRB
->pSegmentList
= (PSGL
) pcmd
->request_buffer
;
1443 else if( pcmd
->request_buffer
)
1445 pSRB
->pSegmentList
= (PSGL
) &pSRB
->Segmentx
;
1446 pSRB
->Segmentx
.address
= (PUCHAR
) pcmd
->request_buffer
;
1447 pSRB
->Segmentx
.length
= pcmd
->request_bufflen
;
1449 if( dc390_StartSCSI( pACB
, pDCB
, pSRB
) ) {
1450 dc390_Going_to_Waiting ( pDCB
, pSRB
);
1451 dc390_waiting_timer (pACB
, HZ
/5);
1458 if( status_byte(status
) == CHECK_CONDITION
)
1460 REMOVABLEDEBUG(printk (KERN_INFO
"DC390: Check_Condition (Cmd %02x, Id %02x, LUN %02x)\n",\
1461 pcmd
->cmnd
[0], pDCB
->TargetID
, pDCB
->TargetLUN
);)
1462 if( (pSRB
->SGIndex
< pSRB
->SGcount
) && (pSRB
->SGcount
) && (pSRB
->SGToBeXferLen
) )
1464 bval
= pSRB
->SGcount
;
1466 ptr2
= pSRB
->pSegmentList
;
1467 for( i
=pSRB
->SGIndex
; i
< bval
; i
++)
1469 swlval
+= ptr2
->length
;
1472 REMOVABLEDEBUG(printk(KERN_INFO
"XferredLen=%08x,NotXferLen=%08x\n",\
1473 (UINT
) pSRB
->TotalXferredLen
, (UINT
) swlval
);)
1475 dc390_RequestSense( pACB
, pDCB
, pSRB
);
1478 else if( status_byte(status
) == QUEUE_FULL
)
1480 bval
= (UCHAR
) pDCB
->GoingSRBCnt
;
1482 pDCB
->MaxCommand
= bval
;
1483 dc390_freetag (pDCB
, pSRB
);
1484 dc390_Going_to_Waiting ( pDCB
, pSRB
);
1485 dc390_waiting_timer (pACB
, HZ
/5);
1486 pSRB
->AdaptStatus
= 0;
1487 pSRB
->TargetStatus
= 0;
1490 else if(status
== SCSI_STAT_SEL_TIMEOUT
)
1492 pSRB
->AdaptStatus
= H_SEL_TIMEOUT
;
1493 pSRB
->TargetStatus
= 0;
1494 pcmd
->result
= MK_RES(0,DID_NO_CONNECT
,0,0);
1495 /* Devices are removed below ... */
1497 else if (status_byte(status
) == BUSY
&&
1498 (pcmd
->cmnd
[0] == TEST_UNIT_READY
|| pcmd
->cmnd
[0] == INQUIRY
) &&
1501 pSRB
->AdaptStatus
= 0;
1502 pSRB
->TargetStatus
= status
;
1503 pcmd
->result
= MK_RES(0,0,pSRB
->EndMessage
,/*status*/0);
1506 { /* Another error */
1507 pSRB
->AdaptStatus
= 0;
1508 if( pSRB
->RetryCnt
)
1510 //printk ("DC390: retry\n");
1512 pSRB
->TargetStatus
= 0;
1514 pSRB
->TotalXferredLen
= 0;
1515 pSRB
->SGToBeXferLen
= 0;
1517 pSRB
->pSegmentList
= (PSGL
) pcmd
->request_buffer
;
1518 else if( pcmd
->request_buffer
)
1520 pSRB
->pSegmentList
= (PSGL
) &pSRB
->Segmentx
;
1521 pSRB
->Segmentx
.address
= (PUCHAR
) pcmd
->request_buffer
;
1522 pSRB
->Segmentx
.length
= pcmd
->request_bufflen
;
1524 if( dc390_StartSCSI( pACB
, pDCB
, pSRB
) ) {
1525 dc390_Going_to_Waiting ( pDCB
, pSRB
);
1526 dc390_waiting_timer (pACB
, HZ
/5);
1531 { /* Report error */
1532 //pcmd->result = MK_RES(0, DID_ERROR, pSRB->EndMessage, status);
1533 SET_RES_DID(pcmd
->result
,DID_ERROR
);
1534 SET_RES_MSG(pcmd
->result
,pSRB
->EndMessage
);
1535 SET_RES_TARGET(pcmd
->result
,status
);
1540 { /* Target status == 0 */
1541 status
= pSRB
->AdaptStatus
;
1542 if(status
& H_OVER_UNDER_RUN
)
1544 pSRB
->TargetStatus
= 0;
1545 SET_RES_DID(pcmd
->result
,DID_OK
);
1546 SET_RES_MSG(pcmd
->result
,pSRB
->EndMessage
);
1548 else if( pSRB
->SRBStatus
& PARITY_ERROR
)
1550 //pcmd->result = MK_RES(0,DID_PARITY,pSRB->EndMessage,0);
1551 SET_RES_DID(pcmd
->result
,DID_PARITY
);
1552 SET_RES_MSG(pcmd
->result
,pSRB
->EndMessage
);
1556 pSRB
->AdaptStatus
= 0;
1557 pSRB
->TargetStatus
= 0;
1558 SET_RES_DID(pcmd
->result
,DID_OK
);
1561 if ((pcmd
->result
& RES_DID
) == 0 &&
1562 pcmd
->cmnd
[0] == INQUIRY
&&
1563 pcmd
->cmnd
[2] == 0 &&
1564 pcmd
->request_bufflen
>= 8 &&
1566 (ptr
->Vers
& 0x07) >= 2)
1567 pDCB
->Inquiry7
= ptr
->Flags
;
1570 if( pACB
->scan_devices
)
1572 if( pcmd
->cmnd
[0] == TEST_UNIT_READY
||
1573 pcmd
->cmnd
[0] == INQUIRY
)
1576 printk (KERN_INFO
"DC390: %s: result: %08x",
1577 (pcmd
->cmnd
[0] == INQUIRY
? "INQUIRY": "TEST_UNIT_READY"),
1579 if (pcmd
->result
& (DRIVER_SENSE
<< 24)) printk (" (sense: %02x %02x %02x %02x)\n",
1580 pcmd
->sense_buffer
[0], pcmd
->sense_buffer
[1],
1581 pcmd
->sense_buffer
[2], pcmd
->sense_buffer
[3]);
1584 if( (host_byte(pcmd
->result
) != DID_OK
&& !(status_byte(pcmd
->result
) & CHECK_CONDITION
) && !(status_byte(pcmd
->result
) & BUSY
)) ||
1585 ((driver_byte(pcmd
->result
) & DRIVER_SENSE
) && (pcmd
->sense_buffer
[0] & 0x70) == 0x70 &&
1586 (pcmd
->sense_buffer
[2] & 0xf) == ILLEGAL_REQUEST
) || host_byte(pcmd
->result
) & DID_ERROR
)
1588 /* device not present: remove */
1589 //dc390_Going_remove (pDCB, pSRB);
1590 dc390_remove_dev (pACB
, pDCB
); DCB_removed
= 1;
1592 if( (pcmd
->target
== pACB
->pScsiHost
->max_id
- 1) &&
1593 ((pcmd
->lun
== 0) || (pcmd
->lun
== pACB
->pScsiHost
->max_lun
- 1)) )
1594 pACB
->scan_devices
= 0;
1598 /* device present: add */
1599 if( (pcmd
->target
== pACB
->pScsiHost
->max_id
- 1) &&
1600 (pcmd
->lun
== pACB
->pScsiHost
->max_lun
- 1) )
1601 pACB
->scan_devices
= END_SCAN
;
1602 /* pACB->DeviceCnt++; */ /* Dev is added on INQUIRY */
1607 //if( pSRB->pcmd->cmnd[0] == INQUIRY &&
1608 // (host_byte(pcmd->result) == DID_OK || status_byte(pcmd->result) & CHECK_CONDITION) )
1609 if( pcmd
->cmnd
[0] == INQUIRY
&&
1610 (pcmd
->result
== (DID_OK
<< 16) || status_byte(pcmd
->result
) & CHECK_CONDITION
) )
1612 if ((ptr
->DevType
& SCSI_DEVTYPE
) == TYPE_NODEV
&& !DCB_removed
)
1614 //printk ("DC390: Type = nodev! (%02i-%i)\n", pcmd->target, pcmd->lun);
1615 /* device not present: remove */
1616 //dc390_Going_remove (pDCB, pSRB);
1617 dc390_remove_dev (pACB
, pDCB
); DCB_removed
= 1;
1621 /* device found: add */
1622 dc390_add_dev (pACB
, pDCB
, ptr
);
1623 if (pACB
->scan_devices
) pACB
->DeviceCnt
++;
1625 if( (pcmd
->target
== pACB
->pScsiHost
->max_id
- 1) &&
1626 (pcmd
->lun
== pACB
->pScsiHost
->max_lun
- 1) )
1627 pACB
->scan_devices
= 0;
1630 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,30)
1631 pcmd
->resid
= pcmd
->request_bufflen
- pSRB
->TotalXferredLen
;
1634 if (!DCB_removed
) dc390_Going_remove (pDCB
, pSRB
);
1635 /* Add to free list */
1636 dc390_Free_insert (pACB
, pSRB
);
1638 DEBUG0(printk (KERN_DEBUG
"DC390: SRBdone: done pid %li\n", pcmd
->pid
);)
1639 DC390_UNLOCK_ACB_NI
;
1640 pcmd
->scsi_done (pcmd
);
1643 dc390_Query_to_Waiting (pACB
);
1644 dc390_Waiting_process (pACB
);
1649 /* Remove all SRBs from Going list and inform midlevel */
1651 dc390_DoingSRB_Done( PACB pACB
, PSCSICMD cmd
)
1658 pDCB
= pACB
->pLinkDCB
;
1663 psrb
= pdcb
->pGoingSRB
;
1664 for( i
=0; i
<pdcb
->GoingSRBCnt
; i
++)
1666 psrb2
= psrb
->pNextSRB
;
1668 dc390_Free_insert (pACB
, psrb
);
1670 /* New EH will crash on being given timed out cmnds */
1672 pcmd
->result
= MK_RES(0,DID_ABORT
,0,0);
1674 pcmd
->result
= MK_RES(0,DID_RESET
,0,0);
1676 /* ReleaseSRB( pDCB, pSRB ); */
1678 DEBUG0(printk (KERN_DEBUG
"DC390: DoingSRB_Done: done pid %li\n", pcmd
->pid
);)
1679 DC390_UNLOCK_ACB_NI
;
1680 pcmd
->scsi_done( pcmd
);
1685 pdcb
->GoingSRBCnt
= 0;;
1686 pdcb
->pGoingSRB
= NULL
;
1688 pdcb
= pdcb
->pNextDCB
;
1689 } while( pdcb
!= pDCB
);
1690 dc390_Query_to_Waiting (pACB
);
1695 dc390_ResetSCSIBus( PACB pACB
)
1697 //DC390_write8 (ScsiCmd, RST_DEVICE_CMD);
1699 //DC390_write8 (ScsiCmd, NOP_CMD);
1701 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
1702 DC390_write8 (DMA_Cmd
, DMA_IDLE_CMD
);
1703 DC390_write8 (ScsiCmd
, RST_SCSI_BUS_CMD
);
1704 pACB
->Connected
= 0;
1710 dc390_ScsiRstDetect( PACB pACB
)
1712 printk ("DC390: Rst_Detect: laststat = %08x\n", dc390_laststatus
);
1713 //DEBUG0(printk(KERN_INFO "RST_DETECT,");)
1715 if (timer_pending (&pACB
->Waiting_Timer
)) del_timer (&pACB
->Waiting_Timer
);
1716 DC390_write8 (DMA_Cmd
, DMA_IDLE_CMD
);
1717 /* Unlock before ? */
1718 /* delay half a second */
1720 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
1721 pACB
->pScsiHost
->last_reset
= jiffies
+ 5*HZ
/2
1722 + HZ
* dc390_eepromBuf
[pACB
->AdapterIndex
][EE_DELAY
];
1723 pACB
->Connected
= 0;
1725 if( pACB
->ACBFlag
& RESET_DEV
)
1726 pACB
->ACBFlag
|= RESET_DONE
;
1728 { /* Reset was issued by sb else */
1729 pACB
->ACBFlag
|= RESET_DETECT
;
1731 dc390_ResetDevParam( pACB
);
1732 dc390_DoingSRB_Done( pACB
, 0 );
1733 //dc390_RecoverSRB( pACB );
1734 pACB
->pActiveDCB
= NULL
;
1736 dc390_Waiting_process( pACB
);
1742 static void __inline__
1743 dc390_RequestSense( PACB pACB
, PDCB pDCB
, PSRB pSRB
)
1747 REMOVABLEDEBUG(printk (KERN_INFO
"DC390: RequestSense (Cmd %02x, Id %02x, LUN %02x)\n",\
1748 pSRB
->pcmd
->cmnd
[0], pDCB
->TargetID
, pDCB
->TargetLUN
);)
1750 pSRB
->SRBFlag
|= AUTO_REQSENSE
;
1751 //pSRB->Segment0[0] = (UINT) pSRB->CmdBlock[0];
1752 //pSRB->Segment0[1] = (UINT) pSRB->CmdBlock[4];
1753 //pSRB->Segment1[0] = ((UINT)(pSRB->pcmd->cmd_len) << 8) + pSRB->SGcount;
1754 //pSRB->Segment1[1] = pSRB->TotalXferredLen;
1755 pSRB
->SavedSGCount
= pSRB
->SGcount
;
1756 pSRB
->SavedTotXLen
= pSRB
->TotalXferredLen
;
1757 pSRB
->AdaptStatus
= 0;
1758 pSRB
->TargetStatus
= 0; /* CHECK_CONDITION<<1; */
1762 pSRB
->Segmentx
.address
= (PUCHAR
) &(pcmd
->sense_buffer
);
1763 pSRB
->Segmentx
.length
= sizeof(pcmd
->sense_buffer
);
1764 pSRB
->pSegmentList
= &pSRB
->Segmentx
;
1768 //pSRB->CmdBlock[0] = REQUEST_SENSE;
1769 //pSRB->CmdBlock[1] = pDCB->TargetLUN << 5;
1770 //(USHORT) pSRB->CmdBlock[2] = 0;
1771 //(USHORT) pSRB->CmdBlock[4] = sizeof(pcmd->sense_buffer);
1772 //pSRB->ScsiCmdLen = 6;
1774 pSRB
->TotalXferredLen
= 0;
1775 pSRB
->SGToBeXferLen
= 0;
1776 if( dc390_StartSCSI( pACB
, pDCB
, pSRB
) ) {
1777 dc390_Going_to_Waiting ( pDCB
, pSRB
);
1778 dc390_waiting_timer (pACB
, HZ
/5);
1784 static void __inline__
1785 dc390_InvalidCmd( PACB pACB
)
1787 if( pACB
->pActiveDCB
->pActiveSRB
->SRBState
& (SRB_START_
+SRB_MSGOUT
) )
1788 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);