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 $ */
9 dc390_freetag (struct dc390_dcb
* pDCB
, struct dc390_srb
* pSRB
)
11 if (pSRB
->TagNumber
< 255) {
12 pDCB
->TagMask
&= ~(1 << pSRB
->TagNumber
); /* free tag mask */
13 pSRB
->TagNumber
= 255;
19 dc390_StartSCSI( struct dc390_acb
* pACB
, struct dc390_dcb
* pDCB
, struct dc390_srb
* pSRB
)
21 u8 cmd
; u8 disc_allowed
, try_sync_nego
;
23 pSRB
->ScsiPhase
= SCSI_NOP0
;
27 // Should not happen normally
28 printk (KERN_WARNING
"DC390: Can't select when connected! (%08x,%02x)\n",
29 pSRB
->SRBState
, pSRB
->SRBFlag
);
30 pSRB
->SRBState
= SRB_READY
;
34 if (time_before (jiffies
, pACB
->pScsiHost
->last_reset
))
36 DEBUG0(printk ("DC390: We were just reset and don't accept commands yet!\n"));
39 /* KG: Moved pci mapping here */
41 /* TODO: error handling */
42 DC390_write8 (Scsi_Dest_ID
, pDCB
->TargetID
);
43 DC390_write8 (Sync_Period
, pDCB
->SyncPeriod
);
44 DC390_write8 (Sync_Offset
, pDCB
->SyncOffset
);
45 DC390_write8 (CtrlReg1
, pDCB
->CtrlR1
);
46 DC390_write8 (CtrlReg3
, pDCB
->CtrlR3
);
47 DC390_write8 (CtrlReg4
, pDCB
->CtrlR4
);
48 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
); /* Flush FIFO */
49 DEBUG1(printk (KERN_INFO
"DC390: Start SCSI command: %02x (Sync:%02x)\n",\
50 pSRB
->pcmd
->cmnd
[0], pDCB
->SyncMode
));
51 disc_allowed
= pDCB
->DevMode
& EN_DISCONNECT_
;
53 /* Don't disconnect on AUTO_REQSENSE, cause it might be an
54 * Contingent Allegiance Condition (6.6), where no tags should be used.
55 * All other have to be allowed to disconnect to prevent Incorrect
56 * Initiator Connection (6.8.2/6.5.2) */
57 /* Changed KG, 99/06/06 */
58 if( /*(((pSRB->pcmd->cmnd[0] == INQUIRY) || (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) ||
59 * (pSRB->pcmd->cmnd[0] == TEST_UNIT_READY)) && pACB->scan_devices)
60 ||*/ (pSRB
->SRBFlag
& AUTO_REQSENSE
) )
62 if ( (pDCB
->SyncMode
& SYNC_ENABLE
) && (pDCB
->TargetLUN
== 0) && (pDCB
->Inquiry7
& 0x10) &&
63 ( ( ( (pSRB
->pcmd
->cmnd
[0] == REQUEST_SENSE
) || (pSRB
->SRBFlag
& AUTO_REQSENSE
) )
64 && !(pDCB
->SyncMode
& SYNC_NEGO_DONE
) ) || (pSRB
->pcmd
->cmnd
[0] == INQUIRY
) ) )
67 pSRB
->MsgCnt
= 0; cmd
= SEL_W_ATN
;
68 DC390_write8 (ScsiFifo
, IDENTIFY(disc_allowed
, pDCB
->TargetLUN
));
69 /* Change 99/05/31: Don't use tags when not disconnecting (BUSY) */
70 if ((pDCB
->SyncMode
& EN_TAG_QUEUEING
) && disc_allowed
)
73 while ((1 << tag_no
) & pDCB
->TagMask
) tag_no
++;
74 if (tag_no
>= sizeof (pDCB
->TagMask
)*8 || tag_no
>= pDCB
->MaxCommand
) {
75 printk (KERN_WARNING
"DC390: Out of tags for Dev. %02x %02x\n", pDCB
->TargetID
, pDCB
->TargetLUN
);
79 DC390_write8 (ScsiFifo
, SIMPLE_QUEUE_TAG
);
80 pDCB
->TagMask
|= (1 << tag_no
); pSRB
->TagNumber
= tag_no
;
81 DC390_write8 (ScsiFifo
, tag_no
);
82 DEBUG1(printk (KERN_DEBUG
"DC390: Select w/DisCn for Cmd %li (SRB %p), Using Tag %02x\n", pSRB
->pcmd
->pid
, pSRB
, tag_no
));
88 DEBUG1(printk (KERN_DEBUG
"DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", (disc_allowed
?"":"o"), pSRB
->pcmd
->pid
, pSRB
));
91 pSRB
->SRBState
= SRB_START_
;
95 u8 Sync_Off
= pDCB
->SyncOffset
;
96 DEBUG0(printk (KERN_INFO
"DC390: NEW Sync Nego code triggered (%i %i)\n", pDCB
->TargetID
, pDCB
->TargetLUN
));
97 pSRB
->MsgOutBuf
[0] = EXTENDED_MESSAGE
;
98 pSRB
->MsgOutBuf
[1] = 3;
99 pSRB
->MsgOutBuf
[2] = EXTENDED_SDTR
;
100 pSRB
->MsgOutBuf
[3] = pDCB
->NegoPeriod
;
101 if (!(Sync_Off
& 0x0f)) Sync_Off
= SYNC_NEGO_OFFSET
;
102 pSRB
->MsgOutBuf
[4] = Sync_Off
;
104 //pSRB->SRBState = SRB_MSGOUT_;
105 pSRB
->SRBState
|= DO_SYNC_NEGO
;
106 cmd
= SEL_W_ATN_STOP
;
109 /* Command is written in CommandPhase, if SEL_W_ATN_STOP ... */
110 if (cmd
!= SEL_W_ATN_STOP
)
112 if( pSRB
->SRBFlag
& AUTO_REQSENSE
)
114 DC390_write8 (ScsiFifo
, REQUEST_SENSE
);
115 DC390_write8 (ScsiFifo
, pDCB
->TargetLUN
<< 5);
116 DC390_write8 (ScsiFifo
, 0);
117 DC390_write8 (ScsiFifo
, 0);
118 DC390_write8 (ScsiFifo
, sizeof(pSRB
->pcmd
->sense_buffer
));
119 DC390_write8 (ScsiFifo
, 0);
120 DEBUG1(printk (KERN_DEBUG
"DC390: AutoReqSense !\n"));
122 else /* write cmnd to bus */
125 ptr
= (u8
*) pSRB
->pcmd
->cmnd
;
126 for (i
=0; i
<pSRB
->pcmd
->cmd_len
; i
++)
127 DC390_write8 (ScsiFifo
, *(ptr
++));
130 DEBUG0(if (pACB
->pActiveDCB
) \
131 printk (KERN_WARNING
"DC390: ActiveDCB != 0\n"));
132 DEBUG0(if (pDCB
->pActiveSRB
) \
133 printk (KERN_WARNING
"DC390: ActiveSRB != 0\n"));
134 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
135 if (DC390_read8 (Scsi_Status
) & INTERRUPT
)
137 dc390_freetag (pDCB
, pSRB
);
138 DEBUG0(printk ("DC390: Interrupt during Start SCSI (pid %li, target %02i-%02i)\n",
139 pSRB
->pcmd
->pid
, pSRB
->pcmd
->device
->id
, pSRB
->pcmd
->device
->lun
));
140 pSRB
->SRBState
= SRB_READY
;
141 //DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
145 DC390_write8 (ScsiCmd
, cmd
);
146 pACB
->pActiveDCB
= pDCB
; pDCB
->pActiveSRB
= pSRB
;
148 pSRB
->ScsiPhase
= SCSI_NOP1
;
152 //#define DMA_INT EN_DMA_INT /*| EN_PAGE_INT*/
156 /* This is similar to AM53C974.c ... */
158 dc390_dma_intr (struct dc390_acb
* pACB
)
160 struct dc390_srb
* pSRB
;
162 DEBUG0(u16 pstate
; struct pci_dev
*pdev
= pACB
->pdev
);
164 DEBUG0(pci_read_config_word(pdev
, PCI_STATUS
, &pstate
));
165 DEBUG0(if (pstate
& (PCI_STATUS_SIG_SYSTEM_ERROR
| PCI_STATUS_DETECTED_PARITY
))\
166 { printk(KERN_WARNING
"DC390: PCI state = %04x!\n", pstate
); \
167 pci_write_config_word(pdev
, PCI_STATUS
, (PCI_STATUS_SIG_SYSTEM_ERROR
| PCI_STATUS_DETECTED_PARITY
));});
169 dstate
= DC390_read8 (DMA_Status
);
171 if (! pACB
->pActiveDCB
|| ! pACB
->pActiveDCB
->pActiveSRB
) return dstate
;
172 else pSRB
= pACB
->pActiveDCB
->pActiveSRB
;
174 if (dstate
& (DMA_XFER_ABORT
| DMA_XFER_ERROR
| POWER_DOWN
| PCI_MS_ABORT
))
176 printk (KERN_ERR
"DC390: DMA error (%02x)!\n", dstate
);
179 if (dstate
& DMA_XFER_DONE
)
181 u32 residual
, xferCnt
; int ctr
= 6000000;
182 if (! (DC390_read8 (DMA_Cmd
) & READ_DIRECTION
))
186 DEBUG1(printk (KERN_DEBUG
"DC390: read residual bytes ... \n"));
187 dstate
= DC390_read8 (DMA_Status
);
188 residual
= DC390_read8 (CtcReg_Low
) | DC390_read8 (CtcReg_Mid
) << 8 |
189 DC390_read8 (CtcReg_High
) << 16;
190 residual
+= DC390_read8 (Current_Fifo
) & 0x1f;
191 } while (residual
&& ! (dstate
& SCSI_INTERRUPT
) && --ctr
);
192 if (!ctr
) printk (KERN_CRIT
"DC390: dma_intr: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr
));
200 xferCnt
= pSRB
->SGToBeXferLen
- residual
;
201 pSRB
->SGBusAddr
+= xferCnt
;
202 pSRB
->TotalXferredLen
+= xferCnt
;
203 pSRB
->SGToBeXferLen
= residual
;
205 printk (KERN_INFO
"DC390: DMA: residual = %i, xfer = %i\n",
206 (unsigned int)residual
, (unsigned int)xferCnt
);
209 DC390_write8 (DMA_Cmd
, DMA_IDLE_CMD
);
211 dc390_laststatus
&= ~0xff000000; dc390_laststatus
|= dstate
<< 24;
217 static void __inline__
218 dc390_InvalidCmd(struct dc390_acb
* pACB
)
220 if (pACB
->pActiveDCB
->pActiveSRB
->SRBState
& (SRB_START_
| SRB_MSGOUT
))
221 DC390_write8(ScsiCmd
, CLEAR_FIFO_CMD
);
225 static irqreturn_t __inline__
226 DC390_Interrupt(int irq
, void *dev_id
, struct pt_regs
*regs
)
228 struct dc390_acb
*pACB
, *pACB2
;
229 struct dc390_dcb
*pDCB
;
230 struct dc390_srb
*pSRB
;
233 void (*stateV
)( struct dc390_acb
*, struct dc390_srb
*, u8
*);
239 pACB
= (struct dc390_acb
*)dev_id
;
240 for (pACB2
= dc390_pACB_start
; (pACB2
&& pACB2
!= pACB
); pACB2
= pACB2
->pNextACB
);
243 printk ("DC390: IRQ called with foreign dev_id %p!\n", pACB
);
247 sstatus
= DC390_read8 (Scsi_Status
);
248 if( !(sstatus
& INTERRUPT
) )
251 DEBUG1(printk (KERN_DEBUG
"sstatus=%02x,", sstatus
));
254 spin_lock_irq(pACB
->pScsiHost
->host_lock
);
255 dstatus
= dc390_dma_intr (pACB
);
256 spin_unlock_irq(pACB
->pScsiHost
->host_lock
);
258 DEBUG1(printk (KERN_DEBUG
"dstatus=%02x,", dstatus
));
259 if (! (dstatus
& SCSI_INTERRUPT
))
261 DEBUG0(printk (KERN_WARNING
"DC390 Int w/o SCSI actions (only DMA?)\n"));
265 //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
266 //dstatus = DC390_read8 (DMA_Status);
267 //DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
270 spin_lock_irq(pACB
->pScsiHost
->host_lock
);
272 istate
= DC390_read8 (Intern_State
);
273 istatus
= DC390_read8 (INT_Status
); /* This clears Scsi_Status, Intern_State and INT_Status ! */
275 DEBUG1(printk (KERN_INFO
"Istatus(Res,Inv,Dis,Serv,Succ,ReS,SelA,Sel)=%02x,",istatus
));
276 dc390_laststatus
&= ~0x00ffffff;
277 dc390_laststatus
|= /* dstatus<<24 | */ sstatus
<<16 | istate
<<8 | istatus
;
279 if (sstatus
& ILLEGAL_OP_ERR
)
281 printk ("DC390: Illegal Operation detected (%08x)!\n", dc390_laststatus
);
282 dc390_dumpinfo (pACB
, pACB
->pActiveDCB
, pACB
->pActiveDCB
->pActiveSRB
);
285 else if (istatus
& INVALID_CMD
)
287 printk ("DC390: Invalid Command detected (%08x)!\n", dc390_laststatus
);
288 dc390_InvalidCmd( pACB
);
292 if (istatus
& SCSI_RESET
)
294 dc390_ScsiRstDetect( pACB
);
298 if (istatus
& DISCONNECTED
)
300 dc390_Disconnect( pACB
);
304 if (istatus
& RESELECTED
)
306 dc390_Reselect( pACB
);
310 else if (istatus
& (SELECTED
| SEL_ATTENTION
))
312 printk (KERN_ERR
"DC390: Target mode not supported!\n");
316 if (istatus
& (SUCCESSFUL_OP
|SERVICE_REQUEST
) )
318 pDCB
= pACB
->pActiveDCB
;
321 printk (KERN_ERR
"DC390: Suc. op/ Serv. req: pActiveDCB = 0!\n");
324 pSRB
= pDCB
->pActiveSRB
;
325 if( pDCB
->DCBFlag
& ABORT_DEV_
)
326 dc390_EnableMsgOut_Abort (pACB
, pSRB
);
328 phase
= pSRB
->ScsiPhase
;
329 DEBUG1(printk (KERN_INFO
"DC390: [%i]%s(0) (%02x)\n", phase
, dc390_p0_str
[phase
], sstatus
));
330 stateV
= (void *) dc390_phase0
[phase
];
331 ( *stateV
)( pACB
, pSRB
, &sstatus
);
333 pSRB
->ScsiPhase
= sstatus
& 7;
334 phase
= (u8
) sstatus
& 7;
335 DEBUG1(printk (KERN_INFO
"DC390: [%i]%s(1) (%02x)\n", phase
, dc390_p1_str
[phase
], sstatus
));
336 stateV
= (void *) dc390_phase1
[phase
];
337 ( *stateV
)( pACB
, pSRB
, &sstatus
);
341 spin_unlock_irq(pACB
->pScsiHost
->host_lock
);
345 static irqreturn_t
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 ret
= DC390_Interrupt(irq
, dev_id
, regs
);
351 DEBUG1(printk (".. IRQ returned\n"));
356 dc390_DataOut_0( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8
*psstatus
)
359 struct scatterlist
*psgl
;
360 u32 ResidCnt
, xferCnt
;
365 if( !(pSRB
->SRBState
& SRB_XFERPAD
) )
367 if( sstatus
& (PARITY_ERR
| ILLEGAL_OP_ERR
) )
368 pSRB
->SRBStatus
|= PARITY_ERROR
;
370 if( sstatus
& COUNT_2_ZERO
)
372 unsigned long timeout
= jiffies
+ HZ
;
374 /* Function called from the ISR with the host_lock held and interrupts disabled */
375 if (pSRB
->SGToBeXferLen
)
376 while (time_before(jiffies
, timeout
) && !((dstate
= DC390_read8 (DMA_Status
)) & DMA_XFER_DONE
)) {
377 spin_unlock_irq(pACB
->pScsiHost
->host_lock
);
379 spin_lock_irq(pACB
->pScsiHost
->host_lock
);
381 if (!time_before(jiffies
, timeout
))
382 printk (KERN_CRIT
"DC390: Deadlock in DataOut_0: DMA aborted unfinished: %06x bytes remain!!\n",
383 DC390_read32 (DMA_Wk_ByteCntr
));
384 dc390_laststatus
&= ~0xff000000;
385 dc390_laststatus
|= dstate
<< 24;
386 pSRB
->TotalXferredLen
+= pSRB
->SGToBeXferLen
;
388 if( pSRB
->SGIndex
< pSRB
->SGcount
)
390 pSRB
->pSegmentList
++;
391 psgl
= pSRB
->pSegmentList
;
393 pSRB
->SGBusAddr
= cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl
)));
394 pSRB
->SGToBeXferLen
= cpu_to_le32(sg_dma_len(psgl
));
397 pSRB
->SGToBeXferLen
= 0;
401 ResidCnt
= (u32
) DC390_read8 (Current_Fifo
) & 0x1f;
402 ResidCnt
|= (u32
) DC390_read8 (CtcReg_High
) << 16;
403 ResidCnt
|= (u32
) DC390_read8 (CtcReg_Mid
) << 8;
404 ResidCnt
+= (u32
) DC390_read8 (CtcReg_Low
);
406 xferCnt
= pSRB
->SGToBeXferLen
- ResidCnt
;
407 pSRB
->SGBusAddr
+= xferCnt
;
408 pSRB
->TotalXferredLen
+= xferCnt
;
409 pSRB
->SGToBeXferLen
= ResidCnt
;
412 if ((*psstatus
& 7) != SCSI_DATA_OUT
)
414 DC390_write8 (DMA_Cmd
, WRITE_DIRECTION
+DMA_IDLE_CMD
); /* | DMA_INT */
415 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
420 dc390_DataIn_0( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8
*psstatus
)
422 u8 sstatus
, residual
, bval
;
423 struct scatterlist
*psgl
;
425 unsigned long xferCnt
;
430 if( !(pSRB
->SRBState
& SRB_XFERPAD
) )
432 if( sstatus
& (PARITY_ERR
| ILLEGAL_OP_ERR
))
433 pSRB
->SRBStatus
|= PARITY_ERROR
;
435 if( sstatus
& COUNT_2_ZERO
)
438 unsigned long timeout
= jiffies
+ HZ
;
440 /* Function called from the ISR with the host_lock held and interrupts disabled */
441 if (pSRB
->SGToBeXferLen
)
442 while (time_before(jiffies
, timeout
) && !((dstate
= DC390_read8 (DMA_Status
)) & DMA_XFER_DONE
)) {
443 spin_unlock_irq(pACB
->pScsiHost
->host_lock
);
445 spin_lock_irq(pACB
->pScsiHost
->host_lock
);
447 if (!time_before(jiffies
, timeout
)) {
448 printk (KERN_CRIT
"DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!\n",
449 DC390_read32 (DMA_Wk_ByteCntr
));
450 printk (KERN_CRIT
"DC390: DataIn_0: DMA State: %i\n", dstate
);
452 dc390_laststatus
&= ~0xff000000;
453 dc390_laststatus
|= dstate
<< 24;
454 DEBUG1(ResidCnt
= ((unsigned long) DC390_read8 (CtcReg_High
) << 16) \
455 + ((unsigned long) DC390_read8 (CtcReg_Mid
) << 8) \
456 + ((unsigned long) DC390_read8 (CtcReg_Low
)));
457 DEBUG1(printk (KERN_DEBUG
"Count_2_Zero (ResidCnt=%i,ToBeXfer=%li),", ResidCnt
, pSRB
->SGToBeXferLen
));
459 DC390_write8 (DMA_Cmd
, READ_DIRECTION
+DMA_IDLE_CMD
); /* | DMA_INT */
461 pSRB
->TotalXferredLen
+= pSRB
->SGToBeXferLen
;
463 if( pSRB
->SGIndex
< pSRB
->SGcount
)
465 pSRB
->pSegmentList
++;
466 psgl
= pSRB
->pSegmentList
;
468 pSRB
->SGBusAddr
= cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl
)));
469 pSRB
->SGToBeXferLen
= cpu_to_le32(sg_dma_len(psgl
));
472 pSRB
->SGToBeXferLen
= 0;
474 else /* phase changed */
477 bval
= DC390_read8 (Current_Fifo
);
480 DEBUG1(printk (KERN_DEBUG
"Check for residuals,"));
481 if( (bval
& 0x1f) == 1 )
483 for(i
=0; i
< 0x100; i
++)
485 bval
= DC390_read8 (Current_Fifo
);
488 else if( i
== 0x0ff )
490 residual
= 1; /* ;1 residual byte */
496 bval
= DC390_read8 (Current_Fifo
);
499 DC390_write8 (DMA_Cmd
, READ_DIRECTION
+DMA_BLAST_CMD
);
500 for (i
= 0xa000; i
; i
--)
502 bval
= DC390_read8 (DMA_Status
);
503 if (bval
& BLAST_COMPLETE
)
506 /* It seems a DMA Blast abort isn't that bad ... */
507 if (!i
) printk (KERN_ERR
"DC390: DMA Blast aborted unfinished!\n");
508 //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
509 dc390_laststatus
&= ~0xff000000; dc390_laststatus
|= bval
<< 24;
511 DEBUG1(printk (KERN_DEBUG
"Blast: Read %i times DMA_Status %02x", 0xa000-i
, bval
));
512 ResidCnt
= (u32
) DC390_read8 (CtcReg_High
);
514 ResidCnt
|= (u32
) DC390_read8 (CtcReg_Mid
);
516 ResidCnt
|= (u32
) DC390_read8 (CtcReg_Low
);
518 xferCnt
= pSRB
->SGToBeXferLen
- ResidCnt
;
519 pSRB
->SGBusAddr
+= xferCnt
;
520 pSRB
->TotalXferredLen
+= xferCnt
;
521 pSRB
->SGToBeXferLen
= ResidCnt
;
525 bval
= DC390_read8 (ScsiFifo
); /* get one residual byte */
526 ptr
= (u8
*) bus_to_virt( pSRB
->SGBusAddr
);
528 pSRB
->SGBusAddr
++; xferCnt
++;
529 pSRB
->TotalXferredLen
++;
530 pSRB
->SGToBeXferLen
--;
532 DEBUG1(printk (KERN_DEBUG
"Xfered: %li, Total: %li, Remaining: %li\n", xferCnt
,\
533 pSRB
->TotalXferredLen
, pSRB
->SGToBeXferLen
));
537 if ((*psstatus
& 7) != SCSI_DATA_IN
)
539 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
540 DC390_write8 (DMA_Cmd
, READ_DIRECTION
+DMA_IDLE_CMD
); /* | DMA_INT */
545 dc390_Command_0( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8
*psstatus
)
550 dc390_Status_0( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8
*psstatus
)
553 pSRB
->TargetStatus
= DC390_read8 (ScsiFifo
);
555 pSRB
->EndMessage
= DC390_read8 (ScsiFifo
); /* get message */
557 *psstatus
= SCSI_NOP0
;
558 pSRB
->SRBState
= SRB_COMPLETED
;
559 DC390_write8 (ScsiCmd
, MSG_ACCEPTED_CMD
);
563 dc390_MsgOut_0( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8
*psstatus
)
565 if( pSRB
->SRBState
& (SRB_UNEXPECT_RESEL
+SRB_ABORT_SENT
) )
566 *psstatus
= SCSI_NOP0
;
567 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
571 static void __inline__
572 dc390_reprog (struct dc390_acb
* pACB
, struct dc390_dcb
* pDCB
)
574 DC390_write8 (Sync_Period
, pDCB
->SyncPeriod
);
575 DC390_write8 (Sync_Offset
, pDCB
->SyncOffset
);
576 DC390_write8 (CtrlReg3
, pDCB
->CtrlR3
);
577 DC390_write8 (CtrlReg4
, pDCB
->CtrlR4
);
578 dc390_SetXferRate (pACB
, pDCB
);
584 dc390_printMsg (u8
*MsgBuf
, u8 len
)
587 printk (" %02x", MsgBuf
[0]);
588 for (i
= 1; i
< len
; i
++)
589 printk (" %02x", MsgBuf
[i
]);
594 #define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD)
597 static void __inline__
598 dc390_MsgIn_reject (struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
)
600 pSRB
->MsgOutBuf
[0] = MESSAGE_REJECT
;
601 pSRB
->MsgCnt
= 1; DC390_ENABLE_MSGOUT
;
602 DEBUG0 (printk (KERN_INFO
"DC390: Reject message\n"));
607 dc390_EnableMsgOut_Abort ( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
)
609 pSRB
->MsgOutBuf
[0] = ABORT
;
610 pSRB
->MsgCnt
= 1; DC390_ENABLE_MSGOUT
;
611 pSRB
->pSRBDCB
->DCBFlag
&= ~ABORT_DEV_
;
614 static struct dc390_srb
*
615 dc390_MsgIn_QTag (struct dc390_acb
* pACB
, struct dc390_dcb
* pDCB
, u8 tag
)
617 struct dc390_srb
* lastSRB
= pDCB
->pGoingLast
;
618 struct dc390_srb
* pSRB
= pDCB
->pGoingSRB
;
624 if (pSRB
->TagNumber
== tag
) break;
625 if (pSRB
== lastSRB
) goto mingx0
;
626 pSRB
= pSRB
->pNextSRB
;
629 if( pDCB
->DCBFlag
& ABORT_DEV_
)
631 pSRB
->SRBState
= SRB_ABORT_SENT
;
632 dc390_EnableMsgOut_Abort( pACB
, pSRB
);
635 if( !(pSRB
->SRBState
& SRB_DISCONNECT
) )
638 pDCB
->pActiveSRB
= pSRB
;
639 pSRB
->SRBState
= SRB_DATA_XFER
;
644 pSRB
= pACB
->pTmpSRB
;
645 pSRB
->SRBState
= SRB_UNEXPECT_RESEL
;
646 pDCB
->pActiveSRB
= pSRB
;
647 pSRB
->MsgOutBuf
[0] = ABORT_TAG
;
648 pSRB
->MsgCnt
= 1; DC390_ENABLE_MSGOUT
;
654 /* set async transfer mode */
656 dc390_MsgIn_set_async (struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
)
658 struct dc390_dcb
* pDCB
= pSRB
->pSRBDCB
;
659 if (!(pSRB
->SRBState
& DO_SYNC_NEGO
))
660 printk (KERN_INFO
"DC390: Target %i initiates Non-Sync?\n", pDCB
->TargetID
);
661 pSRB
->SRBState
&= ~DO_SYNC_NEGO
;
662 pDCB
->SyncMode
&= ~(SYNC_ENABLE
+SYNC_NEGO_DONE
);
663 pDCB
->SyncPeriod
= 0;
664 pDCB
->SyncOffset
= 0;
665 //pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
666 pDCB
->CtrlR3
= FAST_CLK
; /* fast clock / normal scsi */
667 pDCB
->CtrlR4
&= 0x3f;
668 pDCB
->CtrlR4
|= pACB
->glitch_cfg
; /* glitch eater */
669 dc390_reprog (pACB
, pDCB
);
672 /* set sync transfer mode */
674 dc390_MsgIn_set_sync (struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
)
678 struct dc390_dcb
* pDCB
= pSRB
->pSRBDCB
;
679 u8 oldsyncperiod
= pDCB
->SyncPeriod
;
680 u8 oldsyncoffset
= pDCB
->SyncOffset
;
682 if (!(pSRB
->SRBState
& DO_SYNC_NEGO
))
684 printk (KERN_INFO
"DC390: Target %i initiates Sync: %ins %i ... answer ...\n",
685 pDCB
->TargetID
, pSRB
->MsgInBuf
[3]<<2, pSRB
->MsgInBuf
[4]);
688 //dc390_MsgIn_reject (pACB, pSRB);
689 //return dc390_MsgIn_set_async (pACB, pSRB);
691 /* Reply with corrected SDTR Message */
692 if (pSRB
->MsgInBuf
[4] > 15)
694 printk (KERN_INFO
"DC390: Lower Sync Offset to 15\n");
695 pSRB
->MsgInBuf
[4] = 15;
697 if (pSRB
->MsgInBuf
[3] < pDCB
->NegoPeriod
)
699 printk (KERN_INFO
"DC390: Set sync nego period to %ins\n", pDCB
->NegoPeriod
<< 2);
700 pSRB
->MsgInBuf
[3] = pDCB
->NegoPeriod
;
702 memcpy (pSRB
->MsgOutBuf
, pSRB
->MsgInBuf
, 5);
707 pSRB
->SRBState
&= ~DO_SYNC_NEGO
;
708 pDCB
->SyncMode
|= SYNC_ENABLE
+SYNC_NEGO_DONE
;
709 pDCB
->SyncOffset
&= 0x0f0;
710 pDCB
->SyncOffset
|= pSRB
->MsgInBuf
[4];
711 pDCB
->NegoPeriod
= pSRB
->MsgInBuf
[3];
713 wval
= (u16
) pSRB
->MsgInBuf
[3];
714 wval
= wval
<< 2; wval
-= 3; wval1
= wval
/ 25; /* compute speed */
715 if( (wval1
* 25) != wval
) wval1
++;
716 bval
= FAST_CLK
+FAST_SCSI
; /* fast clock / fast scsi */
718 pDCB
->CtrlR4
&= 0x3f; /* Glitch eater: 12ns less than normal */
719 if (pACB
->glitch_cfg
!= NS_TO_GLITCH(0))
720 pDCB
->CtrlR4
|= NS_TO_GLITCH(((GLITCH_TO_NS(pACB
->glitch_cfg
)) - 1));
722 pDCB
->CtrlR4
|= NS_TO_GLITCH(0);
723 if (wval1
< 4) pDCB
->CtrlR4
|= NS_TO_GLITCH(0); /* Ultra */
727 wval1
--; /* Timing computation differs by 1 from FAST_SCSI */
728 bval
= FAST_CLK
; /* fast clock / normal scsi */
729 pDCB
->CtrlR4
|= pACB
->glitch_cfg
; /* glitch eater */
733 pDCB
->SyncPeriod
= (u8
)wval1
;
735 if ((oldsyncperiod
!= wval1
|| oldsyncoffset
!= pDCB
->SyncOffset
) && pDCB
->TargetLUN
== 0)
737 if (! (bval
& FAST_SCSI
)) wval1
++;
738 printk (KERN_INFO
"DC390: Target %i: Sync transfer %i.%1i MHz, Offset %i\n", pDCB
->TargetID
,
739 40/wval1
, ((40%wval1
)*10+wval1
/2)/wval1
, pDCB
->SyncOffset
& 0x0f);
742 dc390_reprog (pACB
, pDCB
);
746 /* handle RESTORE_PTR */
747 /* I presume, this command is already mapped, so, have to remap. */
749 dc390_restore_ptr (struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
)
751 struct scsi_cmnd
*pcmd
= pSRB
->pcmd
;
752 struct scatterlist
*psgl
;
753 pSRB
->TotalXferredLen
= 0;
756 pSRB
->pSegmentList
= (struct scatterlist
*)pcmd
->request_buffer
;
757 psgl
= pSRB
->pSegmentList
;
758 //dc390_pci_sync(pSRB);
760 while (pSRB
->TotalXferredLen
+ (unsigned long) sg_dma_len(psgl
) < pSRB
->Saved_Ptr
)
762 pSRB
->TotalXferredLen
+= (unsigned long) sg_dma_len(psgl
);
764 if( pSRB
->SGIndex
< pSRB
->SGcount
)
766 pSRB
->pSegmentList
++;
767 psgl
= pSRB
->pSegmentList
;
768 pSRB
->SGBusAddr
= cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl
)));
769 pSRB
->SGToBeXferLen
= cpu_to_le32(sg_dma_len(psgl
));
772 pSRB
->SGToBeXferLen
= 0;
774 pSRB
->SGToBeXferLen
-= (pSRB
->Saved_Ptr
- pSRB
->TotalXferredLen
);
775 pSRB
->SGBusAddr
+= (pSRB
->Saved_Ptr
- pSRB
->TotalXferredLen
);
776 printk (KERN_INFO
"DC390: Pointer restored. Segment %i, Total %li, Bus %08lx\n",
777 pSRB
->SGIndex
, pSRB
->Saved_Ptr
, pSRB
->SGBusAddr
);
779 } else if(pcmd
->request_buffer
) {
780 //dc390_pci_sync(pSRB);
782 sg_dma_len(&pSRB
->Segmentx
) = pcmd
->request_bufflen
- pSRB
->Saved_Ptr
;
784 pSRB
->pSegmentList
= (struct scatterlist
*) &pSRB
->Segmentx
;
787 printk (KERN_INFO
"DC390: RESTORE_PTR message for Transfer without Scatter-Gather ??\n");
790 pSRB
->TotalXferredLen
= pSRB
->Saved_Ptr
;
794 /* According to the docs, the AM53C974 reads the message and
795 * generates a Successful Operation IRQ before asserting ACK for
796 * the last byte (how does it know whether it's the last ?) */
797 /* The old code handled it in another way, indicating, that on
798 * every message byte an IRQ is generated and every byte has to
799 * be manually ACKed. Hmmm ? (KG, 98/11/28) */
800 /* The old implementation was correct. Sigh! */
802 /* Check if the message is complete */
804 dc390_MsgIn_complete (u8
*msgbuf
, u32 len
)
806 if (*msgbuf
== EXTENDED_MESSAGE
)
808 if (len
< 2) return 0;
809 if (len
< msgbuf
[1] + 2) return 0;
811 else if (*msgbuf
>= 0x20 && *msgbuf
<= 0x2f) // two byte messages
812 if (len
< 2) return 0;
818 /* read and eval received messages */
820 dc390_MsgIn_0( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8
*psstatus
)
822 struct dc390_dcb
* pDCB
= pACB
->pActiveDCB
;
826 pSRB
->MsgInBuf
[pACB
->MsgLen
++] = DC390_read8 (ScsiFifo
);
827 //pSRB->SRBState = 0;
830 if (dc390_MsgIn_complete (pSRB
->MsgInBuf
, pACB
->MsgLen
))
832 DEBUG0 (printk (KERN_INFO
"DC390: MsgIn:"); dc390_printMsg (pSRB
->MsgInBuf
, pACB
->MsgLen
));
833 /* Now eval the msg */
834 switch (pSRB
->MsgInBuf
[0])
837 pSRB
->SRBState
= SRB_DISCONNECT
; break;
839 case SIMPLE_QUEUE_TAG
:
840 case HEAD_OF_QUEUE_TAG
:
841 case ORDERED_QUEUE_TAG
:
842 pSRB
= dc390_MsgIn_QTag (pACB
, pDCB
, pSRB
->MsgInBuf
[1]);
846 DC390_write8 (ScsiCmd
, RESET_ATN_CMD
);
847 pDCB
->NegoPeriod
= 50; /* 200ns <=> 5 MHz */
848 if( pSRB
->SRBState
& DO_SYNC_NEGO
)
849 dc390_MsgIn_set_async (pACB
, pSRB
);
852 case EXTENDED_MESSAGE
:
853 /* reject every extended msg but SDTR */
854 if (pSRB
->MsgInBuf
[1] != 3 || pSRB
->MsgInBuf
[2] != EXTENDED_SDTR
)
855 dc390_MsgIn_reject (pACB
, pSRB
);
858 if (pSRB
->MsgInBuf
[3] == 0 || pSRB
->MsgInBuf
[4] == 0)
859 dc390_MsgIn_set_async (pACB
, pSRB
);
861 dc390_MsgIn_set_sync (pACB
, pSRB
);
864 // nothing has to be done
865 case COMMAND_COMPLETE
: break;
867 // SAVE POINTER may be ignored as we have the struct dc390_srb* associated with the
868 // scsi command. Thanks, Gerard, for pointing it out.
870 pSRB
->Saved_Ptr
= pSRB
->TotalXferredLen
;
872 // The device might want to restart transfer with a RESTORE
873 case RESTORE_POINTERS
:
874 DEBUG0(printk ("DC390: RESTORE POINTER message received ... try to handle\n"));
875 dc390_restore_ptr (pACB
, pSRB
);
878 // reject unknown messages
879 default: dc390_MsgIn_reject (pACB
, pSRB
);
882 /* Clear counter and MsgIn state */
883 pSRB
->SRBState
&= ~SRB_MSGIN
;
887 *psstatus
= SCSI_NOP0
;
888 DC390_write8 (ScsiCmd
, MSG_ACCEPTED_CMD
);
889 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
894 dc390_DataIO_Comm( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8 ioDir
)
896 struct scatterlist
*psgl
;
898 struct dc390_dcb
* pDCB
= pACB
->pActiveDCB
;
900 if (pSRB
== pACB
->pTmpSRB
)
903 printk(KERN_ERR
"DC390: pSRB == pTmpSRB! (TagQ Error?) (%02i-%i)\n", pDCB
->TargetID
, pDCB
->TargetLUN
);
905 printk(KERN_ERR
"DC390: pSRB == pTmpSRB! (TagQ Error?) (DCB 0!)\n");
907 /* Try to recover - some broken disks react badly to tagged INQUIRY */
908 if (pDCB
&& pACB
->scan_devices
&& pDCB
->GoingSRBCnt
== 1) {
909 pSRB
= pDCB
->pGoingSRB
;
910 pDCB
->pActiveSRB
= pSRB
;
912 pSRB
->pSRBDCB
= pDCB
;
913 dc390_EnableMsgOut_Abort(pACB
, pSRB
);
915 pDCB
->DCBFlag
|= ABORT_DEV
;
920 if( pSRB
->SGIndex
< pSRB
->SGcount
)
922 DC390_write8 (DMA_Cmd
, DMA_IDLE_CMD
| ioDir
/* | DMA_INT */);
923 if( !pSRB
->SGToBeXferLen
)
925 psgl
= pSRB
->pSegmentList
;
926 pSRB
->SGBusAddr
= cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl
)));
927 pSRB
->SGToBeXferLen
= cpu_to_le32(sg_dma_len(psgl
));
928 DEBUG1(printk (KERN_DEBUG
" DC390: Next SG segment."));
930 lval
= pSRB
->SGToBeXferLen
;
931 DEBUG1(printk (KERN_DEBUG
" DC390: Start transfer: %li bytes (address %08lx)\n", lval
, pSRB
->SGBusAddr
));
932 DC390_write8 (CtcReg_Low
, (u8
) lval
);
934 DC390_write8 (CtcReg_Mid
, (u8
) lval
);
936 DC390_write8 (CtcReg_High
, (u8
) lval
);
938 DC390_write32 (DMA_XferCnt
, pSRB
->SGToBeXferLen
);
939 DC390_write32 (DMA_XferAddr
, pSRB
->SGBusAddr
);
941 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); /* | DMA_INT; */
942 pSRB
->SRBState
= SRB_DATA_XFER
;
944 DC390_write8 (ScsiCmd
, DMA_COMMAND
+INFO_XFER_CMD
);
946 DC390_write8 (DMA_Cmd
, DMA_START_CMD
| ioDir
| DMA_INT
);
947 //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT));
948 //DEBUG1(printk (KERN_DEBUG "DC390: DMA_Status: %02x\n", DC390_read8 (DMA_Status)));
949 //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT));
955 pSRB
->AdaptStatus
= H_OVER_UNDER_RUN
;
956 pSRB
->SRBStatus
|= OVER_RUN
;
957 DEBUG0(printk (KERN_WARNING
" DC390: Overrun -"));
959 DEBUG0(printk (KERN_WARNING
" Clear transfer pad \n"));
960 DC390_write8 (CtcReg_Low
, 0);
961 DC390_write8 (CtcReg_Mid
, 0);
962 DC390_write8 (CtcReg_High
, 0);
964 pSRB
->SRBState
|= SRB_XFERPAD
;
965 DC390_write8 (ScsiCmd
, DMA_COMMAND
+XFER_PAD_BYTE
);
967 DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); // | DMA_INT;
968 DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
975 dc390_DataOutPhase( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8
*psstatus
)
977 dc390_DataIO_Comm (pACB
, pSRB
, WRITE_DIRECTION
);
981 dc390_DataInPhase( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8
*psstatus
)
983 dc390_DataIO_Comm (pACB
, pSRB
, READ_DIRECTION
);
987 dc390_CommandPhase( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8
*psstatus
)
989 struct dc390_dcb
* pDCB
;
993 DC390_write8 (ScsiCmd
, RESET_ATN_CMD
);
994 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
995 if( !(pSRB
->SRBFlag
& AUTO_REQSENSE
) )
997 cnt
= (u8
) pSRB
->pcmd
->cmd_len
;
998 ptr
= (u8
*) pSRB
->pcmd
->cmnd
;
999 for(i
=0; i
< cnt
; i
++)
1000 DC390_write8 (ScsiFifo
, *(ptr
++));
1005 DC390_write8 (ScsiFifo
, REQUEST_SENSE
);
1006 pDCB
= pACB
->pActiveDCB
;
1007 DC390_write8 (ScsiFifo
, pDCB
->TargetLUN
<< 5);
1008 DC390_write8 (ScsiFifo
, bval
);
1009 DC390_write8 (ScsiFifo
, bval
);
1010 DC390_write8 (ScsiFifo
, sizeof(pSRB
->pcmd
->sense_buffer
));
1011 DC390_write8 (ScsiFifo
, bval
);
1012 DEBUG0(printk(KERN_DEBUG
"DC390: AutoReqSense (CmndPhase)!\n"));
1014 pSRB
->SRBState
= SRB_COMMAND
;
1015 DC390_write8 (ScsiCmd
, INFO_XFER_CMD
);
1019 dc390_StatusPhase( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8
*psstatus
)
1021 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
1022 pSRB
->SRBState
= SRB_STATUS
;
1023 DC390_write8 (ScsiCmd
, INITIATOR_CMD_CMPLTE
);
1024 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1028 dc390_MsgOutPhase( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8
*psstatus
)
1032 struct dc390_dcb
* pDCB
;
1034 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
1035 pDCB
= pACB
->pActiveDCB
;
1036 if( !(pSRB
->SRBState
& SRB_MSGOUT
) )
1041 ptr
= (u8
*) pSRB
->MsgOutBuf
;
1042 for(i
=0; i
< cnt
; i
++)
1043 DC390_write8 (ScsiFifo
, *(ptr
++));
1045 if( (pDCB
->DCBFlag
& ABORT_DEV_
) &&
1046 (pSRB
->MsgOutBuf
[0] == ABORT
) )
1047 pSRB
->SRBState
= SRB_ABORT_SENT
;
1051 bval
= ABORT
; /* ??? MSG_NOP */
1052 if( (pSRB
->pcmd
->cmnd
[0] == INQUIRY
) ||
1053 (pSRB
->pcmd
->cmnd
[0] == REQUEST_SENSE
) ||
1054 (pSRB
->SRBFlag
& AUTO_REQSENSE
) )
1056 if( pDCB
->SyncMode
& SYNC_ENABLE
)
1059 DC390_write8 (ScsiFifo
, bval
);
1061 DC390_write8 (ScsiCmd
, INFO_XFER_CMD
);
1066 printk (KERN_ERR
"DC390: OLD Sync Nego code triggered! (%i %i)\n", pDCB
->TargetID
, pDCB
->TargetLUN
);
1067 DC390_write8 (ScsiFifo
, EXTENDED_MESSAGE
);
1068 DC390_write8 (ScsiFifo
, 3); /* ;length of extended msg */
1069 DC390_write8 (ScsiFifo
, EXTENDED_SDTR
); /* ; sync nego */
1070 DC390_write8 (ScsiFifo
, pDCB
->NegoPeriod
);
1071 if (pDCB
->SyncOffset
& 0x0f)
1072 DC390_write8 (ScsiFifo
, pDCB
->SyncOffset
);
1074 DC390_write8 (ScsiFifo
, SYNC_NEGO_OFFSET
);
1075 pSRB
->SRBState
|= DO_SYNC_NEGO
;
1076 DC390_write8 (ScsiCmd
, INFO_XFER_CMD
);
1081 dc390_MsgInPhase( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8
*psstatus
)
1083 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
1084 if( !(pSRB
->SRBState
& SRB_MSGIN
) )
1086 pSRB
->SRBState
&= ~SRB_DISCONNECT
;
1087 pSRB
->SRBState
|= SRB_MSGIN
;
1089 DC390_write8 (ScsiCmd
, INFO_XFER_CMD
);
1090 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1094 dc390_Nop_0( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8
*psstatus
)
1099 dc390_Nop_1( struct dc390_acb
* pACB
, struct dc390_srb
* pSRB
, u8
*psstatus
)
1105 dc390_SetXferRate( struct dc390_acb
* pACB
, struct dc390_dcb
* pDCB
)
1108 struct dc390_dcb
* ptr
;
1110 if( !(pDCB
->TargetLUN
) )
1112 if( !pACB
->scan_devices
)
1114 ptr
= pACB
->pLinkDCB
;
1116 bval
= pDCB
->TargetID
;
1117 for(i
=0; i
<cnt
; i
++)
1119 if( ptr
->TargetID
== bval
)
1121 ptr
->SyncPeriod
= pDCB
->SyncPeriod
;
1122 ptr
->SyncOffset
= pDCB
->SyncOffset
;
1123 ptr
->CtrlR3
= pDCB
->CtrlR3
;
1124 ptr
->CtrlR4
= pDCB
->CtrlR4
;
1125 ptr
->SyncMode
= pDCB
->SyncMode
;
1127 ptr
= ptr
->pNextDCB
;
1136 dc390_Disconnect( struct dc390_acb
* pACB
)
1138 struct dc390_dcb
*pDCB
;
1139 struct dc390_srb
*pSRB
, *psrb
;
1142 DEBUG0(printk(KERN_INFO
"DISC,"));
1144 if (!pACB
->Connected
) printk(KERN_ERR
"DC390: Disconnect not-connected bus?\n");
1145 pACB
->Connected
= 0;
1146 pDCB
= pACB
->pActiveDCB
;
1149 DEBUG0(printk(KERN_ERR
"ACB:%p->ActiveDCB:%p IOPort:%04x IRQ:%02x !\n",\
1150 pACB
, pDCB
, pACB
->IOPortBase
, pACB
->IRQLevel
));
1152 DC390_read8 (INT_Status
); /* Reset Pending INT */
1153 DC390_write8 (ScsiCmd
, EN_SEL_RESEL
);
1156 DC390_write8 (ScsiCmd
, EN_SEL_RESEL
);
1157 pSRB
= pDCB
->pActiveSRB
;
1158 pACB
->pActiveDCB
= NULL
;
1159 pSRB
->ScsiPhase
= SCSI_NOP0
;
1160 if( pSRB
->SRBState
& SRB_UNEXPECT_RESEL
)
1163 dc390_Waiting_process ( pACB
);
1165 else if( pSRB
->SRBState
& SRB_ABORT_SENT
)
1169 cnt
= pDCB
->GoingSRBCnt
;
1170 pDCB
->GoingSRBCnt
= 0;
1171 pSRB
= pDCB
->pGoingSRB
;
1172 for( i
=0; i
< cnt
; i
++)
1174 psrb
= pSRB
->pNextSRB
;
1175 dc390_Free_insert (pACB
, pSRB
);
1178 pDCB
->pGoingSRB
= NULL
;
1179 dc390_Waiting_process (pACB
);
1183 if( (pSRB
->SRBState
& (SRB_START_
+SRB_MSGOUT
)) ||
1184 !(pSRB
->SRBState
& (SRB_DISCONNECT
+SRB_COMPLETED
)) )
1185 { /* Selection time out */
1186 if( !(1/*pACB->scan_devices*/) )
1188 pSRB
->SRBState
= SRB_READY
;
1189 dc390_freetag (pDCB
, pSRB
);
1190 dc390_Going_to_Waiting (pDCB
, pSRB
);
1191 dc390_waiting_timer (pACB
, HZ
/5);
1195 pSRB
->TargetStatus
= SCSI_STAT_SEL_TIMEOUT
;
1199 else if( pSRB
->SRBState
& SRB_DISCONNECT
)
1201 dc390_Waiting_process ( pACB
);
1203 else if( pSRB
->SRBState
& SRB_COMPLETED
)
1206 dc390_freetag (pDCB
, pSRB
);
1207 pDCB
->pActiveSRB
= NULL
;
1208 pSRB
->SRBState
= SRB_FREE
;
1209 dc390_SRBdone( pACB
, pDCB
, pSRB
);
1217 dc390_Reselect( struct dc390_acb
* pACB
)
1219 struct dc390_dcb
* pDCB
;
1220 struct dc390_srb
* pSRB
;
1223 DEBUG0(printk(KERN_INFO
"RSEL,"));
1224 pACB
->Connected
= 1;
1225 pDCB
= pACB
->pActiveDCB
;
1227 { /* Arbitration lost but Reselection won */
1228 DEBUG0(printk ("DC390: (ActiveDCB != 0: Arb. lost but resel. won)!\n"));
1229 pSRB
= pDCB
->pActiveSRB
;
1230 if( !( pACB
->scan_devices
) )
1232 pSRB
->SRBState
= SRB_READY
;
1233 dc390_freetag (pDCB
, pSRB
);
1234 dc390_Going_to_Waiting ( pDCB
, pSRB
);
1235 dc390_waiting_timer (pACB
, HZ
/5);
1239 lun
= DC390_read8 (ScsiFifo
);
1240 DEBUG0(printk ("Dev %02x,", lun
));
1241 if (!(lun
& (1 << pACB
->pScsiHost
->this_id
)))
1242 printk (KERN_ERR
"DC390: Reselection must select host adapter: %02x!\n", lun
);
1244 lun
^= 1 << pACB
->pScsiHost
->this_id
; /* Mask AdapterID */
1245 id
= 0; while (lun
>>= 1) id
++;
1247 lun
= DC390_read8 (ScsiFifo
);
1248 if (!(lun
& IDENTIFY_BASE
)) printk (KERN_ERR
"DC390: Resel: Expect identify message!\n");
1250 DEBUG0(printk ("(%02i-%i),", id
, lun
));
1251 pDCB
= dc390_findDCB (pACB
, id
, lun
);
1254 printk (KERN_ERR
"DC390: Reselect from non existing device (%02i-%i)\n",
1258 pACB
->pActiveDCB
= pDCB
;
1259 /* TagQ: We expect a message soon, so never mind the exact SRB */
1260 if( pDCB
->SyncMode
& EN_TAG_QUEUEING
)
1262 pSRB
= pACB
->pTmpSRB
;
1263 pDCB
->pActiveSRB
= pSRB
;
1267 pSRB
= pDCB
->pActiveSRB
;
1268 if( !pSRB
|| !(pSRB
->SRBState
& SRB_DISCONNECT
) )
1270 pSRB
= pACB
->pTmpSRB
;
1271 pSRB
->SRBState
= SRB_UNEXPECT_RESEL
;
1272 printk (KERN_ERR
"DC390: Reselect without outstanding cmnd (%02i-%i)\n",
1274 pDCB
->pActiveSRB
= pSRB
;
1275 dc390_EnableMsgOut_Abort ( pACB
, pSRB
);
1279 if( pDCB
->DCBFlag
& ABORT_DEV_
)
1281 pSRB
->SRBState
= SRB_ABORT_SENT
;
1282 printk (KERN_INFO
"DC390: Reselect: Abort (%02i-%i)\n",
1284 dc390_EnableMsgOut_Abort( pACB
, pSRB
);
1287 pSRB
->SRBState
= SRB_DATA_XFER
;
1291 DEBUG1(printk (KERN_DEBUG
"Resel SRB(%p): TagNum (%02x)\n", pSRB
, pSRB
->TagNumber
));
1292 pSRB
->ScsiPhase
= SCSI_NOP0
;
1293 DC390_write8 (Scsi_Dest_ID
, pDCB
->TargetID
);
1294 DC390_write8 (Sync_Period
, pDCB
->SyncPeriod
);
1295 DC390_write8 (Sync_Offset
, pDCB
->SyncOffset
);
1296 DC390_write8 (CtrlReg1
, pDCB
->CtrlR1
);
1297 DC390_write8 (CtrlReg3
, pDCB
->CtrlR3
);
1298 DC390_write8 (CtrlReg4
, pDCB
->CtrlR4
); /* ; Glitch eater */
1299 DC390_write8 (ScsiCmd
, MSG_ACCEPTED_CMD
); /* ;to release the /ACK signal */
1302 static u8 __inline__
1303 dc390_tagq_blacklist (char* name
)
1306 for(i
=0; i
<BADDEVCNT
; i
++)
1307 if (memcmp (name
, dc390_baddevname1
[i
], 28) == 0)
1314 dc390_disc_tagq_set (struct dc390_dcb
* pDCB
, PSCSI_INQDATA ptr
)
1316 /* Check for SCSI format (ANSI and Response data format) */
1317 if ( (ptr
->Vers
& 0x07) >= 2 || (ptr
->RDF
& 0x0F) == 2 )
1319 if ( (ptr
->Flags
& SCSI_INQ_CMDQUEUE
) &&
1320 (pDCB
->DevMode
& TAG_QUEUEING_
) &&
1321 /* ((pDCB->DevType == TYPE_DISK)
1322 || (pDCB->DevType == TYPE_MOD)) &&*/
1323 !dc390_tagq_blacklist (((char*)ptr
)+8) )
1325 if (pDCB
->MaxCommand
==1) pDCB
->MaxCommand
= pDCB
->pDCBACB
->TagMaxNum
;
1326 pDCB
->SyncMode
|= EN_TAG_QUEUEING
/* | EN_ATN_STOP */;
1327 //pDCB->TagMask = 0;
1330 pDCB
->MaxCommand
= 1;
1336 dc390_add_dev (struct dc390_acb
* pACB
, struct dc390_dcb
* pDCB
, PSCSI_INQDATA ptr
)
1338 u8 bval1
= ptr
->DevType
& SCSI_DEVTYPE
;
1339 pDCB
->DevType
= bval1
;
1340 /* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */
1341 dc390_disc_tagq_set (pDCB
, ptr
);
1345 static void __inline__
1346 dc390_RequestSense(struct dc390_acb
* pACB
, struct dc390_dcb
* pDCB
, struct dc390_srb
* pSRB
)
1348 struct scsi_cmnd
*pcmd
;
1352 REMOVABLEDEBUG(printk(KERN_INFO
"DC390: RequestSense(Cmd %02x, Id %02x, LUN %02x)\n",\
1353 pcmd
->cmnd
[0], pDCB
->TargetID
, pDCB
->TargetLUN
));
1355 pSRB
->SRBFlag
|= AUTO_REQSENSE
;
1356 pSRB
->SavedSGCount
= pcmd
->use_sg
;
1357 pSRB
->SavedTotXLen
= pSRB
->TotalXferredLen
;
1358 pSRB
->AdaptStatus
= 0;
1359 pSRB
->TargetStatus
= 0; /* CHECK_CONDITION<<1; */
1361 /* We are called from SRBdone, original PCI mapping has been removed
1362 * already, new one is set up from StartSCSI */
1365 pSRB
->TotalXferredLen
= 0;
1366 pSRB
->SGToBeXferLen
= 0;
1367 if (dc390_StartSCSI(pACB
, pDCB
, pSRB
)) {
1368 dc390_Going_to_Waiting(pDCB
, pSRB
);
1369 dc390_waiting_timer(pACB
, HZ
/5);
1375 dc390_SRBdone( struct dc390_acb
* pACB
, struct dc390_dcb
* pDCB
, struct dc390_srb
* pSRB
)
1378 struct scsi_cmnd
*pcmd
;
1380 struct scatterlist
*ptr2
;
1381 unsigned long swlval
;
1384 /* KG: Moved pci_unmap here */
1385 dc390_pci_unmap(pSRB
);
1387 status
= pSRB
->TargetStatus
;
1389 ptr2
= (struct scatterlist
*) (pcmd
->request_buffer
);
1390 ptr
= (PSCSI_INQDATA
) (page_address(ptr2
->page
) + ptr2
->offset
);
1392 ptr
= (PSCSI_INQDATA
) (pcmd
->request_buffer
);
1394 DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status
, pcmd
->result
,\
1396 if(pSRB
->SRBFlag
& AUTO_REQSENSE
)
1397 { /* Last command was a Request Sense */
1398 pSRB
->SRBFlag
&= ~AUTO_REQSENSE
;
1399 pSRB
->AdaptStatus
= 0;
1400 pSRB
->TargetStatus
= CHECK_CONDITION
<< 1;
1402 //pcmd->result = MK_RES(DRIVER_SENSE,DID_OK,0,status);
1403 if (status
== (CHECK_CONDITION
<< 1))
1405 pcmd
->result
= MK_RES_LNX(0,DID_BAD_TARGET
,0,/*CHECK_CONDITION*/0);
1408 if(pSRB
->RetryCnt
== 0)
1410 //(u32)(pSRB->pcmd->cmnd[0]) = pSRB->Segment0[0];
1411 pSRB
->TotalXferredLen
= pSRB
->SavedTotXLen
;
1412 if( (pSRB
->TotalXferredLen
) &&
1413 (pSRB
->TotalXferredLen
>= pcmd
->underflow
) )
1414 SET_RES_DID(pcmd
->result
,DID_OK
)
1416 pcmd
->result
= MK_RES_LNX(DRIVER_SENSE
,DID_OK
,0,CHECK_CONDITION
);
1417 REMOVABLEDEBUG(printk(KERN_INFO
"Cmd=%02x,Result=%08x,XferL=%08x\n",pSRB
->pcmd
->cmnd
[0],\
1418 (u32
) pcmd
->result
, (u32
) pSRB
->TotalXferredLen
));
1424 pSRB
->AdaptStatus
= 0;
1425 pSRB
->TargetStatus
= 0;
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 (u32
) pcmd
->result
, (u32
) pSRB
->TotalXferredLen
));
1434 SET_RES_DRV(pcmd
->result
,DRIVER_SENSE
);
1435 pcmd
->use_sg
= pSRB
->SavedSGCount
;
1436 //pSRB->ScsiCmdLen = (u8) (pSRB->Segment1[0] >> 8);
1437 DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd
->pid
, pcmd
->cmnd
[0], pcmd
->device
->id
, pcmd
->device
->lun
));
1439 pSRB
->TotalXferredLen
= 0;
1440 pSRB
->SGToBeXferLen
= 0;
1442 if( dc390_StartSCSI( pACB
, pDCB
, pSRB
) ) {
1443 dc390_Going_to_Waiting ( pDCB
, pSRB
);
1444 dc390_waiting_timer (pACB
, HZ
/5);
1451 if( status_byte(status
) == CHECK_CONDITION
)
1453 REMOVABLEDEBUG(printk (KERN_INFO
"DC390: Check_Condition (Cmd %02x, Id %02x, LUN %02x)\n",\
1454 pcmd
->cmnd
[0], pDCB
->TargetID
, pDCB
->TargetLUN
));
1455 if( (pSRB
->SGIndex
< pSRB
->SGcount
) && (pSRB
->SGcount
) && (pSRB
->SGToBeXferLen
) )
1457 bval
= pSRB
->SGcount
;
1459 ptr2
= pSRB
->pSegmentList
;
1460 for( i
=pSRB
->SGIndex
; i
< bval
; i
++)
1462 swlval
+= sg_dma_len(ptr2
);
1465 REMOVABLEDEBUG(printk(KERN_INFO
"XferredLen=%08x,NotXferLen=%08x\n",\
1466 (u32
) pSRB
->TotalXferredLen
, (u32
) swlval
));
1468 dc390_RequestSense( pACB
, pDCB
, pSRB
);
1471 else if( status_byte(status
) == QUEUE_FULL
)
1473 bval
= (u8
) pDCB
->GoingSRBCnt
;
1475 pDCB
->MaxCommand
= bval
;
1476 dc390_freetag (pDCB
, pSRB
);
1477 dc390_Going_to_Waiting ( pDCB
, pSRB
);
1478 dc390_waiting_timer (pACB
, HZ
/5);
1479 pSRB
->AdaptStatus
= 0;
1480 pSRB
->TargetStatus
= 0;
1483 else if(status
== SCSI_STAT_SEL_TIMEOUT
)
1485 pSRB
->AdaptStatus
= H_SEL_TIMEOUT
;
1486 pSRB
->TargetStatus
= 0;
1487 pcmd
->result
= MK_RES(0,DID_NO_CONNECT
,0,0);
1488 /* Devices are removed below ... */
1490 else if (status_byte(status
) == BUSY
&&
1491 (pcmd
->cmnd
[0] == TEST_UNIT_READY
|| pcmd
->cmnd
[0] == INQUIRY
) &&
1494 pSRB
->AdaptStatus
= 0;
1495 pSRB
->TargetStatus
= status
;
1496 pcmd
->result
= MK_RES(0,0,pSRB
->EndMessage
,/*status*/0);
1499 { /* Another error */
1500 pSRB
->AdaptStatus
= 0;
1501 if( pSRB
->RetryCnt
)
1503 //printk ("DC390: retry\n");
1505 pSRB
->TargetStatus
= 0;
1507 pSRB
->TotalXferredLen
= 0;
1508 pSRB
->SGToBeXferLen
= 0;
1509 if( dc390_StartSCSI( pACB
, pDCB
, pSRB
) ) {
1510 dc390_Going_to_Waiting ( pDCB
, pSRB
);
1511 dc390_waiting_timer (pACB
, HZ
/5);
1516 { /* Report error */
1517 //pcmd->result = MK_RES(0, DID_ERROR, pSRB->EndMessage, status);
1518 SET_RES_DID(pcmd
->result
,DID_ERROR
);
1519 SET_RES_MSG(pcmd
->result
,pSRB
->EndMessage
);
1520 SET_RES_TARGET(pcmd
->result
,status
);
1525 { /* Target status == 0 */
1526 status
= pSRB
->AdaptStatus
;
1527 if(status
& H_OVER_UNDER_RUN
)
1529 pSRB
->TargetStatus
= 0;
1530 SET_RES_DID(pcmd
->result
,DID_OK
);
1531 SET_RES_MSG(pcmd
->result
,pSRB
->EndMessage
);
1533 else if( pSRB
->SRBStatus
& PARITY_ERROR
)
1535 //pcmd->result = MK_RES(0,DID_PARITY,pSRB->EndMessage,0);
1536 SET_RES_DID(pcmd
->result
,DID_PARITY
);
1537 SET_RES_MSG(pcmd
->result
,pSRB
->EndMessage
);
1541 pSRB
->AdaptStatus
= 0;
1542 pSRB
->TargetStatus
= 0;
1543 SET_RES_DID(pcmd
->result
,DID_OK
);
1546 if ((pcmd
->result
& RES_DID
) == 0 &&
1547 pcmd
->cmnd
[0] == INQUIRY
&&
1548 pcmd
->cmnd
[2] == 0 &&
1549 pcmd
->request_bufflen
>= 8 &&
1551 (ptr
->Vers
& 0x07) >= 2)
1552 pDCB
->Inquiry7
= ptr
->Flags
;
1555 if( pcmd
->cmnd
[0] == INQUIRY
&&
1556 (pcmd
->result
== (DID_OK
<< 16) || status_byte(pcmd
->result
) & CHECK_CONDITION
) )
1558 if ((ptr
->DevType
& SCSI_DEVTYPE
) != TYPE_NODEV
)
1560 /* device found: add */
1561 dc390_add_dev (pACB
, pDCB
, ptr
);
1565 pcmd
->resid
= pcmd
->request_bufflen
- pSRB
->TotalXferredLen
;
1567 dc390_Going_remove (pDCB
, pSRB
);
1568 /* Add to free list */
1569 dc390_Free_insert (pACB
, pSRB
);
1571 DEBUG0(printk (KERN_DEBUG
"DC390: SRBdone: done pid %li\n", pcmd
->pid
));
1572 pcmd
->scsi_done (pcmd
);
1574 dc390_Waiting_process (pACB
);
1579 /* Remove all SRBs from Going list and inform midlevel */
1581 dc390_DoingSRB_Done(struct dc390_acb
* pACB
, struct scsi_cmnd
*cmd
)
1583 struct dc390_dcb
*pDCB
, *pdcb
;
1584 struct dc390_srb
*psrb
, *psrb2
;
1586 struct scsi_cmnd
*pcmd
;
1588 pDCB
= pACB
->pLinkDCB
;
1593 psrb
= pdcb
->pGoingSRB
;
1594 for( i
=0; i
<pdcb
->GoingSRBCnt
; i
++)
1596 psrb2
= psrb
->pNextSRB
;
1598 dc390_Free_insert (pACB
, psrb
);
1601 pdcb
->GoingSRBCnt
= 0;
1602 pdcb
->pGoingSRB
= NULL
;
1604 pdcb
= pdcb
->pNextDCB
;
1605 } while( pdcb
!= pDCB
);
1610 dc390_ResetSCSIBus( struct dc390_acb
* pACB
)
1612 //DC390_write8 (ScsiCmd, RST_DEVICE_CMD);
1614 //DC390_write8 (ScsiCmd, NOP_CMD);
1616 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
1617 DC390_write8 (DMA_Cmd
, DMA_IDLE_CMD
);
1618 DC390_write8 (ScsiCmd
, RST_SCSI_BUS_CMD
);
1619 pACB
->Connected
= 0;
1625 dc390_ScsiRstDetect( struct dc390_acb
* pACB
)
1627 printk ("DC390: Rst_Detect: laststat = %08x\n", dc390_laststatus
);
1628 //DEBUG0(printk(KERN_INFO "RST_DETECT,"));
1630 if (timer_pending (&pACB
->Waiting_Timer
)) del_timer (&pACB
->Waiting_Timer
);
1631 DC390_write8 (DMA_Cmd
, DMA_IDLE_CMD
);
1632 /* Unlock before ? */
1633 /* delay half a second */
1635 DC390_write8 (ScsiCmd
, CLEAR_FIFO_CMD
);
1636 pACB
->pScsiHost
->last_reset
= jiffies
+ 5*HZ
/2
1637 + HZ
* dc390_eepromBuf
[pACB
->AdapterIndex
][EE_DELAY
];
1638 pACB
->Connected
= 0;
1640 if( pACB
->ACBFlag
& RESET_DEV
)
1641 pACB
->ACBFlag
|= RESET_DONE
;
1643 { /* Reset was issued by sb else */
1644 pACB
->ACBFlag
|= RESET_DETECT
;
1646 dc390_ResetDevParam( pACB
);
1647 dc390_DoingSRB_Done( pACB
, NULL
);
1648 //dc390_RecoverSRB( pACB );
1649 pACB
->pActiveDCB
= NULL
;
1651 dc390_Waiting_process( pACB
);