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;
216 static irqreturn_t __inline__
217 DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
219 struct dc390_acb *pACB, *pACB2;
220 struct dc390_dcb *pDCB;
221 struct dc390_srb *pSRB;
224 void (*stateV)( struct dc390_acb*, struct dc390_srb*, u8 *);
230 pACB = (struct dc390_acb*)dev_id;
231 for (pACB2 = dc390_pACB_start; (pACB2 && pACB2 != pACB); pACB2 = pACB2->pNextACB);
234 printk ("DC390: IRQ called with foreign dev_id %p!\n", pACB);
238 sstatus = DC390_read8 (Scsi_Status);
239 if( !(sstatus & INTERRUPT) )
242 DEBUG1(printk (KERN_DEBUG "sstatus=%02x,", sstatus));
245 spin_lock_irq(pACB->pScsiHost->host_lock);
246 dstatus = dc390_dma_intr (pACB);
247 spin_unlock_irq(pACB->pScsiHost->host_lock);
249 DEBUG1(printk (KERN_DEBUG "dstatus=%02x,", dstatus));
250 if (! (dstatus & SCSI_INTERRUPT))
252 DEBUG0(printk (KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n"));
256 //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
257 //dstatus = DC390_read8 (DMA_Status);
258 //DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
261 spin_lock_irq(pACB->pScsiHost->host_lock);
263 istate = DC390_read8 (Intern_State);
264 istatus = DC390_read8 (INT_Status); /* This clears Scsi_Status, Intern_State and INT_Status ! */
266 DEBUG1(printk (KERN_INFO "Istatus(Res,Inv,Dis,Serv,Succ,ReS,SelA,Sel)=%02x,",istatus));
267 dc390_laststatus &= ~0x00ffffff;
268 dc390_laststatus |= /* dstatus<<24 | */ sstatus<<16 | istate<<8 | istatus;
270 if (sstatus & ILLEGAL_OP_ERR)
272 printk ("DC390: Illegal Operation detected (%08x)!\n", dc390_laststatus);
273 dc390_dumpinfo (pACB, pACB->pActiveDCB, pACB->pActiveDCB->pActiveSRB);
276 else if (istatus & INVALID_CMD)
278 printk ("DC390: Invalid Command detected (%08x)!\n", dc390_laststatus);
279 dc390_InvalidCmd( pACB );
283 if (istatus & SCSI_RESET)
285 dc390_ScsiRstDetect( pACB );
289 if (istatus & DISCONNECTED)
291 dc390_Disconnect( pACB );
295 if (istatus & RESELECTED)
297 dc390_Reselect( pACB );
301 else if (istatus & (SELECTED | SEL_ATTENTION))
303 printk (KERN_ERR "DC390: Target mode not supported!\n");
307 if (istatus & (SUCCESSFUL_OP|SERVICE_REQUEST) )
309 pDCB = pACB->pActiveDCB;
312 printk (KERN_ERR "DC390: Suc. op/ Serv. req: pActiveDCB = 0!\n");
315 pSRB = pDCB->pActiveSRB;
316 if( pDCB->DCBFlag & ABORT_DEV_ )
317 dc390_EnableMsgOut_Abort (pACB, pSRB);
319 phase = pSRB->ScsiPhase;
320 DEBUG1(printk (KERN_INFO "DC390: [%i]%s(0) (%02x)\n", phase, dc390_p0_str[phase], sstatus));
321 stateV = (void *) dc390_phase0[phase];
322 ( *stateV )( pACB, pSRB, &sstatus );
324 pSRB->ScsiPhase = sstatus & 7;
325 phase = (u8) sstatus & 7;
326 DEBUG1(printk (KERN_INFO "DC390: [%i]%s(1) (%02x)\n", phase, dc390_p1_str[phase], sstatus));
327 stateV = (void *) dc390_phase1[phase];
328 ( *stateV )( pACB, pSRB, &sstatus );
332 spin_unlock_irq(pACB->pScsiHost->host_lock);
336 static irqreturn_t do_DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
339 DEBUG1(printk (KERN_INFO "DC390: Irq (%i) caught: ", irq));
340 /* Locking is done in DC390_Interrupt */
341 ret = DC390_Interrupt(irq, dev_id, regs);
342 DEBUG1(printk (".. IRQ returned\n"));
347 dc390_DataOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
350 struct scatterlist *psgl;
351 u32 ResidCnt, xferCnt;
356 if( !(pSRB->SRBState & SRB_XFERPAD) )
358 if( sstatus & (PARITY_ERR | ILLEGAL_OP_ERR) )
359 pSRB->SRBStatus |= PARITY_ERROR;
361 if( sstatus & COUNT_2_ZERO )
363 unsigned long timeout = jiffies + HZ;
365 /* Function called from the ISR with the host_lock held and interrupts disabled */
366 if (pSRB->SGToBeXferLen)
367 while (time_before(jiffies, timeout) && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE)) {
368 spin_unlock_irq(pACB->pScsiHost->host_lock);
370 spin_lock_irq(pACB->pScsiHost->host_lock);
372 if (!time_before(jiffies, timeout))
373 printk (KERN_CRIT "DC390: Deadlock in DataOut_0: DMA aborted unfinished: %06x bytes remain!!\n",
374 DC390_read32 (DMA_Wk_ByteCntr));
375 dc390_laststatus &= ~0xff000000;
376 dc390_laststatus |= dstate << 24;
377 pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
379 if( pSRB->SGIndex < pSRB->SGcount )
381 pSRB->pSegmentList++;
382 psgl = pSRB->pSegmentList;
384 pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
385 pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
388 pSRB->SGToBeXferLen = 0;
392 ResidCnt = (u32) DC390_read8 (Current_Fifo) & 0x1f;
393 ResidCnt |= (u32) DC390_read8 (CtcReg_High) << 16;
394 ResidCnt |= (u32) DC390_read8 (CtcReg_Mid) << 8;
395 ResidCnt += (u32) DC390_read8 (CtcReg_Low);
397 xferCnt = pSRB->SGToBeXferLen - ResidCnt;
398 pSRB->SGBusAddr += xferCnt;
399 pSRB->TotalXferredLen += xferCnt;
400 pSRB->SGToBeXferLen = ResidCnt;
403 if ((*psstatus & 7) != SCSI_DATA_OUT)
405 DC390_write8 (DMA_Cmd, WRITE_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
406 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
411 dc390_DataIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
413 u8 sstatus, residual, bval;
414 struct scatterlist *psgl;
416 unsigned long xferCnt;
421 if( !(pSRB->SRBState & SRB_XFERPAD) )
423 if( sstatus & (PARITY_ERR | ILLEGAL_OP_ERR))
424 pSRB->SRBStatus |= PARITY_ERROR;
426 if( sstatus & COUNT_2_ZERO )
429 unsigned long timeout = jiffies + HZ;
431 /* Function called from the ISR with the host_lock held and interrupts disabled */
432 if (pSRB->SGToBeXferLen)
433 while (time_before(jiffies, timeout) && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE)) {
434 spin_unlock_irq(pACB->pScsiHost->host_lock);
436 spin_lock_irq(pACB->pScsiHost->host_lock);
438 if (!time_before(jiffies, timeout)) {
439 printk (KERN_CRIT "DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!\n",
440 DC390_read32 (DMA_Wk_ByteCntr));
441 printk (KERN_CRIT "DC390: DataIn_0: DMA State: %i\n", dstate);
443 dc390_laststatus &= ~0xff000000;
444 dc390_laststatus |= dstate << 24;
445 DEBUG1(ResidCnt = ((unsigned long) DC390_read8 (CtcReg_High) << 16) \
446 + ((unsigned long) DC390_read8 (CtcReg_Mid) << 8) \
447 + ((unsigned long) DC390_read8 (CtcReg_Low)));
448 DEBUG1(printk (KERN_DEBUG "Count_2_Zero (ResidCnt=%i,ToBeXfer=%li),", ResidCnt, pSRB->SGToBeXferLen));
450 DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
452 pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
454 if( pSRB->SGIndex < pSRB->SGcount )
456 pSRB->pSegmentList++;
457 psgl = pSRB->pSegmentList;
459 pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
460 pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
463 pSRB->SGToBeXferLen = 0;
465 else /* phase changed */
468 bval = DC390_read8 (Current_Fifo);
471 DEBUG1(printk (KERN_DEBUG "Check for residuals,"));
472 if( (bval & 0x1f) == 1 )
474 for(i=0; i < 0x100; i++)
476 bval = DC390_read8 (Current_Fifo);
479 else if( i == 0x0ff )
481 residual = 1; /* ;1 residual byte */
487 bval = DC390_read8 (Current_Fifo);
490 DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_BLAST_CMD);
491 for (i = 0xa000; i; i--)
493 bval = DC390_read8 (DMA_Status);
494 if (bval & BLAST_COMPLETE)
497 /* It seems a DMA Blast abort isn't that bad ... */
498 if (!i) printk (KERN_ERR "DC390: DMA Blast aborted unfinished!\n");
499 //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
500 dc390_laststatus &= ~0xff000000; dc390_laststatus |= bval << 24;
502 DEBUG1(printk (KERN_DEBUG "Blast: Read %i times DMA_Status %02x", 0xa000-i, bval));
503 ResidCnt = (u32) DC390_read8 (CtcReg_High);
505 ResidCnt |= (u32) DC390_read8 (CtcReg_Mid);
507 ResidCnt |= (u32) DC390_read8 (CtcReg_Low);
509 xferCnt = pSRB->SGToBeXferLen - ResidCnt;
510 pSRB->SGBusAddr += xferCnt;
511 pSRB->TotalXferredLen += xferCnt;
512 pSRB->SGToBeXferLen = ResidCnt;
516 bval = DC390_read8 (ScsiFifo); /* get one residual byte */
517 ptr = (u8 *) bus_to_virt( pSRB->SGBusAddr );
519 pSRB->SGBusAddr++; xferCnt++;
520 pSRB->TotalXferredLen++;
521 pSRB->SGToBeXferLen--;
523 DEBUG1(printk (KERN_DEBUG "Xfered: %li, Total: %li, Remaining: %li\n", xferCnt,\
524 pSRB->TotalXferredLen, pSRB->SGToBeXferLen));
528 if ((*psstatus & 7) != SCSI_DATA_IN)
530 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
531 DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
536 dc390_Command_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
541 dc390_Status_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
544 pSRB->TargetStatus = DC390_read8 (ScsiFifo);
546 pSRB->EndMessage = DC390_read8 (ScsiFifo); /* get message */
548 *psstatus = SCSI_NOP0;
549 pSRB->SRBState = SRB_COMPLETED;
550 DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);
554 dc390_MsgOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
556 if( pSRB->SRBState & (SRB_UNEXPECT_RESEL+SRB_ABORT_SENT) )
557 *psstatus = SCSI_NOP0;
558 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
562 static void __inline__
563 dc390_reprog (struct dc390_acb* pACB, struct dc390_dcb* pDCB)
565 DC390_write8 (Sync_Period, pDCB->SyncPeriod);
566 DC390_write8 (Sync_Offset, pDCB->SyncOffset);
567 DC390_write8 (CtrlReg3, pDCB->CtrlR3);
568 DC390_write8 (CtrlReg4, pDCB->CtrlR4);
569 dc390_SetXferRate (pACB, pDCB);
575 dc390_printMsg (u8 *MsgBuf, u8 len)
578 printk (" %02x", MsgBuf[0]);
579 for (i = 1; i < len; i++)
580 printk (" %02x", MsgBuf[i]);
585 #define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD)
588 static void __inline__
589 dc390_MsgIn_reject (struct dc390_acb* pACB, struct dc390_srb* pSRB)
591 pSRB->MsgOutBuf[0] = MESSAGE_REJECT;
592 pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
593 DEBUG0 (printk (KERN_INFO "DC390: Reject message\n"));
597 static void __inline__
598 dc390_EnableMsgOut_Abort ( struct dc390_acb* pACB, struct dc390_srb* pSRB )
600 pSRB->MsgOutBuf[0] = ABORT;
601 pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
602 pSRB->pSRBDCB->DCBFlag &= ~ABORT_DEV_;
605 static struct dc390_srb*
606 dc390_MsgIn_QTag (struct dc390_acb* pACB, struct dc390_dcb* pDCB, u8 tag)
608 struct dc390_srb* lastSRB = pDCB->pGoingLast;
609 struct dc390_srb* pSRB = pDCB->pGoingSRB;
615 if (pSRB->TagNumber == tag) break;
616 if (pSRB == lastSRB) goto mingx0;
617 pSRB = pSRB->pNextSRB;
620 if( pDCB->DCBFlag & ABORT_DEV_ )
622 pSRB->SRBState = SRB_ABORT_SENT;
623 dc390_EnableMsgOut_Abort( pACB, pSRB );
626 if( !(pSRB->SRBState & SRB_DISCONNECT) )
629 pDCB->pActiveSRB = pSRB;
630 pSRB->SRBState = SRB_DATA_XFER;
635 pSRB = pACB->pTmpSRB;
636 pSRB->SRBState = SRB_UNEXPECT_RESEL;
637 pDCB->pActiveSRB = pSRB;
638 pSRB->MsgOutBuf[0] = ABORT_TAG;
639 pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
645 /* set async transfer mode */
647 dc390_MsgIn_set_async (struct dc390_acb* pACB, struct dc390_srb* pSRB)
649 struct dc390_dcb* pDCB = pSRB->pSRBDCB;
650 if (!(pSRB->SRBState & DO_SYNC_NEGO))
651 printk (KERN_INFO "DC390: Target %i initiates Non-Sync?\n", pDCB->TargetID);
652 pSRB->SRBState &= ~DO_SYNC_NEGO;
653 pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE);
654 pDCB->SyncPeriod = 0;
655 pDCB->SyncOffset = 0;
656 //pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
657 pDCB->CtrlR3 = FAST_CLK; /* fast clock / normal scsi */
658 pDCB->CtrlR4 &= 0x3f;
659 pDCB->CtrlR4 |= pACB->glitch_cfg; /* glitch eater */
660 dc390_reprog (pACB, pDCB);
663 /* set sync transfer mode */
665 dc390_MsgIn_set_sync (struct dc390_acb* pACB, struct dc390_srb* pSRB)
669 struct dc390_dcb* pDCB = pSRB->pSRBDCB;
670 u8 oldsyncperiod = pDCB->SyncPeriod;
671 u8 oldsyncoffset = pDCB->SyncOffset;
673 if (!(pSRB->SRBState & DO_SYNC_NEGO))
675 printk (KERN_INFO "DC390: Target %i initiates Sync: %ins %i ... answer ...\n",
676 pDCB->TargetID, pSRB->MsgInBuf[3]<<2, pSRB->MsgInBuf[4]);
679 //dc390_MsgIn_reject (pACB, pSRB);
680 //return dc390_MsgIn_set_async (pACB, pSRB);
682 /* Reply with corrected SDTR Message */
683 if (pSRB->MsgInBuf[4] > 15)
685 printk (KERN_INFO "DC390: Lower Sync Offset to 15\n");
686 pSRB->MsgInBuf[4] = 15;
688 if (pSRB->MsgInBuf[3] < pDCB->NegoPeriod)
690 printk (KERN_INFO "DC390: Set sync nego period to %ins\n", pDCB->NegoPeriod << 2);
691 pSRB->MsgInBuf[3] = pDCB->NegoPeriod;
693 memcpy (pSRB->MsgOutBuf, pSRB->MsgInBuf, 5);
698 pSRB->SRBState &= ~DO_SYNC_NEGO;
699 pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE;
700 pDCB->SyncOffset &= 0x0f0;
701 pDCB->SyncOffset |= pSRB->MsgInBuf[4];
702 pDCB->NegoPeriod = pSRB->MsgInBuf[3];
704 wval = (u16) pSRB->MsgInBuf[3];
705 wval = wval << 2; wval -= 3; wval1 = wval / 25; /* compute speed */
706 if( (wval1 * 25) != wval) wval1++;
707 bval = FAST_CLK+FAST_SCSI; /* fast clock / fast scsi */
709 pDCB->CtrlR4 &= 0x3f; /* Glitch eater: 12ns less than normal */
710 if (pACB->glitch_cfg != NS_TO_GLITCH(0))
711 pDCB->CtrlR4 |= NS_TO_GLITCH(((GLITCH_TO_NS(pACB->glitch_cfg)) - 1));
713 pDCB->CtrlR4 |= NS_TO_GLITCH(0);
714 if (wval1 < 4) pDCB->CtrlR4 |= NS_TO_GLITCH(0); /* Ultra */
718 wval1--; /* Timing computation differs by 1 from FAST_SCSI */
719 bval = FAST_CLK; /* fast clock / normal scsi */
720 pDCB->CtrlR4 |= pACB->glitch_cfg; /* glitch eater */
724 pDCB->SyncPeriod = (u8)wval1;
726 if ((oldsyncperiod != wval1 || oldsyncoffset != pDCB->SyncOffset) && pDCB->TargetLUN == 0)
728 if (! (bval & FAST_SCSI)) wval1++;
729 printk (KERN_INFO "DC390: Target %i: Sync transfer %i.%1i MHz, Offset %i\n", pDCB->TargetID,
730 40/wval1, ((40%wval1)*10+wval1/2)/wval1, pDCB->SyncOffset & 0x0f);
733 dc390_reprog (pACB, pDCB);
737 /* handle RESTORE_PTR */
738 /* I presume, this command is already mapped, so, have to remap. */
740 dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB)
742 struct scsi_cmnd *pcmd = pSRB->pcmd;
743 struct scatterlist *psgl;
744 pSRB->TotalXferredLen = 0;
747 pSRB->pSegmentList = (struct scatterlist *)pcmd->request_buffer;
748 psgl = pSRB->pSegmentList;
749 //dc390_pci_sync(pSRB);
751 while (pSRB->TotalXferredLen + (unsigned long) sg_dma_len(psgl) < pSRB->Saved_Ptr)
753 pSRB->TotalXferredLen += (unsigned long) sg_dma_len(psgl);
755 if( pSRB->SGIndex < pSRB->SGcount )
757 pSRB->pSegmentList++;
758 psgl = pSRB->pSegmentList;
759 pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
760 pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
763 pSRB->SGToBeXferLen = 0;
765 pSRB->SGToBeXferLen -= (pSRB->Saved_Ptr - pSRB->TotalXferredLen);
766 pSRB->SGBusAddr += (pSRB->Saved_Ptr - pSRB->TotalXferredLen);
767 printk (KERN_INFO "DC390: Pointer restored. Segment %i, Total %li, Bus %08lx\n",
768 pSRB->SGIndex, pSRB->Saved_Ptr, pSRB->SGBusAddr);
770 } else if(pcmd->request_buffer) {
771 //dc390_pci_sync(pSRB);
773 sg_dma_len(&pSRB->Segmentx) = pcmd->request_bufflen - pSRB->Saved_Ptr;
775 pSRB->pSegmentList = (struct scatterlist *) &pSRB->Segmentx;
778 printk (KERN_INFO "DC390: RESTORE_PTR message for Transfer without Scatter-Gather ??\n");
781 pSRB->TotalXferredLen = pSRB->Saved_Ptr;
785 /* According to the docs, the AM53C974 reads the message and
786 * generates a Successful Operation IRQ before asserting ACK for
787 * the last byte (how does it know whether it's the last ?) */
788 /* The old code handled it in another way, indicating, that on
789 * every message byte an IRQ is generated and every byte has to
790 * be manually ACKed. Hmmm ? (KG, 98/11/28) */
791 /* The old implementation was correct. Sigh! */
793 /* Check if the message is complete */
795 dc390_MsgIn_complete (u8 *msgbuf, u32 len)
797 if (*msgbuf == EXTENDED_MESSAGE)
799 if (len < 2) return 0;
800 if (len < msgbuf[1] + 2) return 0;
802 else if (*msgbuf >= 0x20 && *msgbuf <= 0x2f) // two byte messages
803 if (len < 2) return 0;
809 /* read and eval received messages */
811 dc390_MsgIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
813 struct dc390_dcb* pDCB = pACB->pActiveDCB;
817 pSRB->MsgInBuf[pACB->MsgLen++] = DC390_read8 (ScsiFifo);
818 //pSRB->SRBState = 0;
821 if (dc390_MsgIn_complete (pSRB->MsgInBuf, pACB->MsgLen))
823 DEBUG0 (printk (KERN_INFO "DC390: MsgIn:"); dc390_printMsg (pSRB->MsgInBuf, pACB->MsgLen));
824 /* Now eval the msg */
825 switch (pSRB->MsgInBuf[0])
828 pSRB->SRBState = SRB_DISCONNECT; break;
830 case SIMPLE_QUEUE_TAG:
831 case HEAD_OF_QUEUE_TAG:
832 case ORDERED_QUEUE_TAG:
833 pSRB = dc390_MsgIn_QTag (pACB, pDCB, pSRB->MsgInBuf[1]);
837 DC390_write8 (ScsiCmd, RESET_ATN_CMD);
838 pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
839 if( pSRB->SRBState & DO_SYNC_NEGO)
840 dc390_MsgIn_set_async (pACB, pSRB);
843 case EXTENDED_MESSAGE:
844 /* reject every extended msg but SDTR */
845 if (pSRB->MsgInBuf[1] != 3 || pSRB->MsgInBuf[2] != EXTENDED_SDTR)
846 dc390_MsgIn_reject (pACB, pSRB);
849 if (pSRB->MsgInBuf[3] == 0 || pSRB->MsgInBuf[4] == 0)
850 dc390_MsgIn_set_async (pACB, pSRB);
852 dc390_MsgIn_set_sync (pACB, pSRB);
855 // nothing has to be done
856 case COMMAND_COMPLETE: break;
858 // SAVE POINTER may be ignored as we have the struct dc390_srb* associated with the
859 // scsi command. Thanks, Gerard, for pointing it out.
861 pSRB->Saved_Ptr = pSRB->TotalXferredLen;
863 // The device might want to restart transfer with a RESTORE
864 case RESTORE_POINTERS:
865 DEBUG0(printk ("DC390: RESTORE POINTER message received ... try to handle\n"));
866 dc390_restore_ptr (pACB, pSRB);
869 // reject unknown messages
870 default: dc390_MsgIn_reject (pACB, pSRB);
873 /* Clear counter and MsgIn state */
874 pSRB->SRBState &= ~SRB_MSGIN;
878 *psstatus = SCSI_NOP0;
879 DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);
880 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
885 dc390_DataIO_Comm( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 ioDir)
887 struct scatterlist *psgl;
889 struct dc390_dcb* pDCB = pACB->pActiveDCB;
891 if (pSRB == pACB->pTmpSRB)
893 if (pDCB) printk (KERN_ERR "DC390: pSRB == pTmpSRB! (TagQ Error?) (%02i-%i)\n",
894 pDCB->TargetID, pDCB->TargetLUN);
895 else printk (KERN_ERR "DC390: pSRB == pTmpSRB! (TagQ Error?) (DCB 0!)\n");
897 pSRB->pSRBDCB = pDCB;
898 dc390_EnableMsgOut_Abort (pACB, pSRB);
899 if (pDCB) pDCB->DCBFlag |= ABORT_DEV;
903 if( pSRB->SGIndex < pSRB->SGcount )
905 DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir /* | DMA_INT */);
906 if( !pSRB->SGToBeXferLen )
908 psgl = pSRB->pSegmentList;
909 pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
910 pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
911 DEBUG1(printk (KERN_DEBUG " DC390: Next SG segment."));
913 lval = pSRB->SGToBeXferLen;
914 DEBUG1(printk (KERN_DEBUG " DC390: Start transfer: %li bytes (address %08lx)\n", lval, pSRB->SGBusAddr));
915 DC390_write8 (CtcReg_Low, (u8) lval);
917 DC390_write8 (CtcReg_Mid, (u8) lval);
919 DC390_write8 (CtcReg_High, (u8) lval);
921 DC390_write32 (DMA_XferCnt, pSRB->SGToBeXferLen);
922 DC390_write32 (DMA_XferAddr, pSRB->SGBusAddr);
924 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); /* | DMA_INT; */
925 pSRB->SRBState = SRB_DATA_XFER;
927 DC390_write8 (ScsiCmd, DMA_COMMAND+INFO_XFER_CMD);
929 DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
930 //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT));
931 //DEBUG1(printk (KERN_DEBUG "DC390: DMA_Status: %02x\n", DC390_read8 (DMA_Status)));
932 //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT));
938 pSRB->AdaptStatus = H_OVER_UNDER_RUN;
939 pSRB->SRBStatus |= OVER_RUN;
940 DEBUG0(printk (KERN_WARNING " DC390: Overrun -"));
942 DEBUG0(printk (KERN_WARNING " Clear transfer pad \n"));
943 DC390_write8 (CtcReg_Low, 0);
944 DC390_write8 (CtcReg_Mid, 0);
945 DC390_write8 (CtcReg_High, 0);
947 pSRB->SRBState |= SRB_XFERPAD;
948 DC390_write8 (ScsiCmd, DMA_COMMAND+XFER_PAD_BYTE);
950 DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); // | DMA_INT;
951 DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
958 dc390_DataOutPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
960 dc390_DataIO_Comm (pACB, pSRB, WRITE_DIRECTION);
964 dc390_DataInPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
966 dc390_DataIO_Comm (pACB, pSRB, READ_DIRECTION);
970 dc390_CommandPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
972 struct dc390_dcb* pDCB;
976 DC390_write8 (ScsiCmd, RESET_ATN_CMD);
977 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
978 if( !(pSRB->SRBFlag & AUTO_REQSENSE) )
980 cnt = (u8) pSRB->pcmd->cmd_len;
981 ptr = (u8 *) pSRB->pcmd->cmnd;
982 for(i=0; i < cnt; i++)
983 DC390_write8 (ScsiFifo, *(ptr++));
988 DC390_write8 (ScsiFifo, REQUEST_SENSE);
989 pDCB = pACB->pActiveDCB;
990 DC390_write8 (ScsiFifo, pDCB->TargetLUN << 5);
991 DC390_write8 (ScsiFifo, bval);
992 DC390_write8 (ScsiFifo, bval);
993 DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
994 DC390_write8 (ScsiFifo, bval);
995 DEBUG0(printk(KERN_DEBUG "DC390: AutoReqSense (CmndPhase)!\n"));
997 pSRB->SRBState = SRB_COMMAND;
998 DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1002 dc390_StatusPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1004 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1005 pSRB->SRBState = SRB_STATUS;
1006 DC390_write8 (ScsiCmd, INITIATOR_CMD_CMPLTE);
1007 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1011 dc390_MsgOutPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1015 struct dc390_dcb* pDCB;
1017 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1018 pDCB = pACB->pActiveDCB;
1019 if( !(pSRB->SRBState & SRB_MSGOUT) )
1024 ptr = (u8 *) pSRB->MsgOutBuf;
1025 for(i=0; i < cnt; i++)
1026 DC390_write8 (ScsiFifo, *(ptr++));
1028 if( (pDCB->DCBFlag & ABORT_DEV_) &&
1029 (pSRB->MsgOutBuf[0] == ABORT) )
1030 pSRB->SRBState = SRB_ABORT_SENT;
1034 bval = ABORT; /* ??? MSG_NOP */
1035 if( (pSRB->pcmd->cmnd[0] == INQUIRY ) ||
1036 (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) ||
1037 (pSRB->SRBFlag & AUTO_REQSENSE) )
1039 if( pDCB->SyncMode & SYNC_ENABLE )
1042 DC390_write8 (ScsiFifo, bval);
1044 DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1049 printk (KERN_ERR "DC390: OLD Sync Nego code triggered! (%i %i)\n", pDCB->TargetID, pDCB->TargetLUN);
1050 DC390_write8 (ScsiFifo, EXTENDED_MESSAGE);
1051 DC390_write8 (ScsiFifo, 3); /* ;length of extended msg */
1052 DC390_write8 (ScsiFifo, EXTENDED_SDTR); /* ; sync nego */
1053 DC390_write8 (ScsiFifo, pDCB->NegoPeriod);
1054 if (pDCB->SyncOffset & 0x0f)
1055 DC390_write8 (ScsiFifo, pDCB->SyncOffset);
1057 DC390_write8 (ScsiFifo, SYNC_NEGO_OFFSET);
1058 pSRB->SRBState |= DO_SYNC_NEGO;
1059 DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1064 dc390_MsgInPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1066 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1067 if( !(pSRB->SRBState & SRB_MSGIN) )
1069 pSRB->SRBState &= ~SRB_DISCONNECT;
1070 pSRB->SRBState |= SRB_MSGIN;
1072 DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1073 //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1077 dc390_Nop_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1082 dc390_Nop_1( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1088 dc390_SetXferRate( struct dc390_acb* pACB, struct dc390_dcb* pDCB )
1091 struct dc390_dcb* ptr;
1093 if( !(pDCB->TargetLUN) )
1095 if( !pACB->scan_devices )
1097 ptr = pACB->pLinkDCB;
1099 bval = pDCB->TargetID;
1100 for(i=0; i<cnt; i++)
1102 if( ptr->TargetID == bval )
1104 ptr->SyncPeriod = pDCB->SyncPeriod;
1105 ptr->SyncOffset = pDCB->SyncOffset;
1106 ptr->CtrlR3 = pDCB->CtrlR3;
1107 ptr->CtrlR4 = pDCB->CtrlR4;
1108 ptr->SyncMode = pDCB->SyncMode;
1110 ptr = ptr->pNextDCB;
1119 dc390_Disconnect( struct dc390_acb* pACB )
1121 struct dc390_dcb *pDCB;
1122 struct dc390_srb *pSRB, *psrb;
1125 DEBUG0(printk(KERN_INFO "DISC,"));
1127 if (!pACB->Connected) printk(KERN_ERR "DC390: Disconnect not-connected bus?\n");
1128 pACB->Connected = 0;
1129 pDCB = pACB->pActiveDCB;
1132 DEBUG0(printk(KERN_ERR "ACB:%p->ActiveDCB:%p IOPort:%04x IRQ:%02x !\n",\
1133 pACB, pDCB, pACB->IOPortBase, pACB->IRQLevel));
1135 DC390_read8 (INT_Status); /* Reset Pending INT */
1136 DC390_write8 (ScsiCmd, EN_SEL_RESEL);
1139 DC390_write8 (ScsiCmd, EN_SEL_RESEL);
1140 pSRB = pDCB->pActiveSRB;
1141 pACB->pActiveDCB = 0;
1142 pSRB->ScsiPhase = SCSI_NOP0;
1143 if( pSRB->SRBState & SRB_UNEXPECT_RESEL )
1146 dc390_Waiting_process ( pACB );
1148 else if( pSRB->SRBState & SRB_ABORT_SENT )
1152 cnt = pDCB->GoingSRBCnt;
1153 pDCB->GoingSRBCnt = 0;
1154 pSRB = pDCB->pGoingSRB;
1155 for( i=0; i < cnt; i++)
1157 psrb = pSRB->pNextSRB;
1158 dc390_Free_insert (pACB, pSRB);
1161 pDCB->pGoingSRB = 0;
1162 dc390_Waiting_process (pACB);
1166 if( (pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) ||
1167 !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED)) )
1168 { /* Selection time out */
1169 if( !(1/*pACB->scan_devices*/) )
1171 pSRB->SRBState = SRB_READY;
1172 dc390_freetag (pDCB, pSRB);
1173 dc390_Going_to_Waiting (pDCB, pSRB);
1174 dc390_waiting_timer (pACB, HZ/5);
1178 pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT;
1182 else if( pSRB->SRBState & SRB_DISCONNECT )
1184 dc390_Waiting_process ( pACB );
1186 else if( pSRB->SRBState & SRB_COMPLETED )
1189 dc390_freetag (pDCB, pSRB);
1190 pDCB->pActiveSRB = 0;
1191 pSRB->SRBState = SRB_FREE;
1192 dc390_SRBdone( pACB, pDCB, pSRB);
1200 dc390_Reselect( struct dc390_acb* pACB )
1202 struct dc390_dcb* pDCB;
1203 struct dc390_srb* pSRB;
1206 DEBUG0(printk(KERN_INFO "RSEL,"));
1207 pACB->Connected = 1;
1208 pDCB = pACB->pActiveDCB;
1210 { /* Arbitration lost but Reselection won */
1211 DEBUG0(printk ("DC390: (ActiveDCB != 0: Arb. lost but resel. won)!\n"));
1212 pSRB = pDCB->pActiveSRB;
1213 if( !( pACB->scan_devices ) )
1215 pSRB->SRBState = SRB_READY;
1216 dc390_freetag (pDCB, pSRB);
1217 dc390_Going_to_Waiting ( pDCB, pSRB);
1218 dc390_waiting_timer (pACB, HZ/5);
1222 lun = DC390_read8 (ScsiFifo);
1223 DEBUG0(printk ("Dev %02x,", lun));
1224 if (!(lun & (1 << pACB->pScsiHost->this_id)))
1225 printk (KERN_ERR "DC390: Reselection must select host adapter: %02x!\n", lun);
1227 lun ^= 1 << pACB->pScsiHost->this_id; /* Mask AdapterID */
1228 id = 0; while (lun >>= 1) id++;
1230 lun = DC390_read8 (ScsiFifo);
1231 if (!(lun & IDENTIFY_BASE)) printk (KERN_ERR "DC390: Resel: Expect identify message!\n");
1233 DEBUG0(printk ("(%02i-%i),", id, lun));
1234 pDCB = dc390_findDCB (pACB, id, lun);
1237 printk (KERN_ERR "DC390: Reselect from non existing device (%02i-%i)\n",
1241 pACB->pActiveDCB = pDCB;
1242 /* TagQ: We expect a message soon, so never mind the exact SRB */
1243 if( pDCB->SyncMode & EN_TAG_QUEUEING )
1245 pSRB = pACB->pTmpSRB;
1246 pDCB->pActiveSRB = pSRB;
1250 pSRB = pDCB->pActiveSRB;
1251 if( !pSRB || !(pSRB->SRBState & SRB_DISCONNECT) )
1253 pSRB= pACB->pTmpSRB;
1254 pSRB->SRBState = SRB_UNEXPECT_RESEL;
1255 printk (KERN_ERR "DC390: Reselect without outstanding cmnd (%02i-%i)\n",
1257 pDCB->pActiveSRB = pSRB;
1258 dc390_EnableMsgOut_Abort ( pACB, pSRB );
1262 if( pDCB->DCBFlag & ABORT_DEV_ )
1264 pSRB->SRBState = SRB_ABORT_SENT;
1265 printk (KERN_INFO "DC390: Reselect: Abort (%02i-%i)\n",
1267 dc390_EnableMsgOut_Abort( pACB, pSRB );
1270 pSRB->SRBState = SRB_DATA_XFER;
1274 DEBUG1(printk (KERN_DEBUG "Resel SRB(%p): TagNum (%02x)\n", pSRB, pSRB->TagNumber));
1275 pSRB->ScsiPhase = SCSI_NOP0;
1276 DC390_write8 (Scsi_Dest_ID, pDCB->TargetID);
1277 DC390_write8 (Sync_Period, pDCB->SyncPeriod);
1278 DC390_write8 (Sync_Offset, pDCB->SyncOffset);
1279 DC390_write8 (CtrlReg1, pDCB->CtrlR1);
1280 DC390_write8 (CtrlReg3, pDCB->CtrlR3);
1281 DC390_write8 (CtrlReg4, pDCB->CtrlR4); /* ; Glitch eater */
1282 DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD); /* ;to release the /ACK signal */
1285 static u8 __inline__
1286 dc390_tagq_blacklist (char* name)
1289 for(i=0; i<BADDEVCNT; i++)
1290 if (memcmp (name, dc390_baddevname1[i], 28) == 0)
1297 dc390_disc_tagq_set (struct dc390_dcb* pDCB, PSCSI_INQDATA ptr)
1299 /* Check for SCSI format (ANSI and Response data format) */
1300 if ( (ptr->Vers & 0x07) >= 2 || (ptr->RDF & 0x0F) == 2 )
1302 if ( (ptr->Flags & SCSI_INQ_CMDQUEUE) &&
1303 (pDCB->DevMode & TAG_QUEUEING_) &&
1304 /* ((pDCB->DevType == TYPE_DISK)
1305 || (pDCB->DevType == TYPE_MOD)) &&*/
1306 !dc390_tagq_blacklist (((char*)ptr)+8) )
1308 if (pDCB->MaxCommand ==1) pDCB->MaxCommand = pDCB->pDCBACB->TagMaxNum;
1309 pDCB->SyncMode |= EN_TAG_QUEUEING /* | EN_ATN_STOP */;
1310 //pDCB->TagMask = 0;
1313 pDCB->MaxCommand = 1;
1319 dc390_add_dev (struct dc390_acb* pACB, struct dc390_dcb* pDCB, PSCSI_INQDATA ptr)
1321 u8 bval1 = ptr->DevType & SCSI_DEVTYPE;
1322 pDCB->DevType = bval1;
1323 /* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */
1324 dc390_disc_tagq_set (pDCB, ptr);
1329 dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB )
1332 struct scsi_cmnd *pcmd;
1334 struct scatterlist *ptr2;
1335 unsigned long swlval;
1338 /* KG: Moved pci_unmap here */
1339 dc390_pci_unmap(pSRB);
1341 status = pSRB->TargetStatus;
1343 ptr2 = (struct scatterlist *) (pcmd->request_buffer);
1344 ptr = (PSCSI_INQDATA) (page_address(ptr2->page) + ptr2->offset);
1346 ptr = (PSCSI_INQDATA) (pcmd->request_buffer);
1348 DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result,\
1350 if(pSRB->SRBFlag & AUTO_REQSENSE)
1351 { /* Last command was a Request Sense */
1352 pSRB->SRBFlag &= ~AUTO_REQSENSE;
1353 pSRB->AdaptStatus = 0;
1354 pSRB->TargetStatus = CHECK_CONDITION << 1;
1355 #ifdef DC390_REMOVABLEDEBUG
1356 switch (pcmd->sense_buffer[2] & 0x0f)
1358 case NOT_READY: printk (KERN_INFO "DC390: ReqSense: NOT_READY (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1359 pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
1360 status, pACB->scan_devices); break;
1361 case UNIT_ATTENTION: printk (KERN_INFO "DC390: ReqSense: UNIT_ATTENTION (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1362 pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
1363 status, pACB->scan_devices); break;
1364 case ILLEGAL_REQUEST: printk (KERN_INFO "DC390: ReqSense: ILLEGAL_REQUEST (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1365 pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
1366 status, pACB->scan_devices); break;
1367 case MEDIUM_ERROR: printk (KERN_INFO "DC390: ReqSense: MEDIUM_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1368 pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
1369 status, pACB->scan_devices); break;
1370 case HARDWARE_ERROR: printk (KERN_INFO "DC390: ReqSense: HARDWARE_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
1371 pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
1372 status, pACB->scan_devices); break;
1375 //pcmd->result = MK_RES(DRIVER_SENSE,DID_OK,0,status);
1376 if (status == (CHECK_CONDITION << 1))
1378 pcmd->result = MK_RES_LNX(0,DID_BAD_TARGET,0,/*CHECK_CONDITION*/0);
1381 if(pSRB->RetryCnt == 0)
1383 //(u32)(pSRB->pcmd->cmnd[0]) = pSRB->Segment0[0];
1384 pSRB->TotalXferredLen = pSRB->SavedTotXLen;
1385 if( (pSRB->TotalXferredLen) &&
1386 (pSRB->TotalXferredLen >= pcmd->underflow) )
1387 SET_RES_DID(pcmd->result,DID_OK)
1389 pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION);
1390 REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x,Result=%08x,XferL=%08x\n",pSRB->pcmd->cmnd[0],\
1391 (u32) pcmd->result, (u32) pSRB->TotalXferredLen));
1397 pSRB->AdaptStatus = 0;
1398 pSRB->TargetStatus = 0;
1399 /* Don't retry on TEST_UNIT_READY */
1400 if( pSRB->pcmd->cmnd[0] == TEST_UNIT_READY /* || pSRB->pcmd->cmnd[0] == START_STOP */)
1402 pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION);
1403 REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->pcmd->cmnd[0],\
1404 (u32) pcmd->result, (u32) pSRB->TotalXferredLen));
1407 SET_RES_DRV(pcmd->result,DRIVER_SENSE);
1408 pcmd->use_sg = pSRB->SavedSGCount;
1409 //pSRB->ScsiCmdLen = (u8) (pSRB->Segment1[0] >> 8);
1410 DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
1412 pSRB->TotalXferredLen = 0;
1413 pSRB->SGToBeXferLen = 0;
1415 if( dc390_StartSCSI( pACB, pDCB, pSRB ) ) {
1416 dc390_Going_to_Waiting ( pDCB, pSRB );
1417 dc390_waiting_timer (pACB, HZ/5);
1424 if( status_byte(status) == CHECK_CONDITION )
1426 REMOVABLEDEBUG(printk (KERN_INFO "DC390: Check_Condition (Cmd %02x, Id %02x, LUN %02x)\n",\
1427 pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN));
1428 if( (pSRB->SGIndex < pSRB->SGcount) && (pSRB->SGcount) && (pSRB->SGToBeXferLen) )
1430 bval = pSRB->SGcount;
1432 ptr2 = pSRB->pSegmentList;
1433 for( i=pSRB->SGIndex; i < bval; i++)
1435 swlval += sg_dma_len(ptr2);
1438 REMOVABLEDEBUG(printk(KERN_INFO "XferredLen=%08x,NotXferLen=%08x\n",\
1439 (u32) pSRB->TotalXferredLen, (u32) swlval));
1441 dc390_RequestSense( pACB, pDCB, pSRB );
1444 else if( status_byte(status) == QUEUE_FULL )
1446 bval = (u8) pDCB->GoingSRBCnt;
1448 pDCB->MaxCommand = bval;
1449 dc390_freetag (pDCB, pSRB);
1450 dc390_Going_to_Waiting ( pDCB, pSRB );
1451 dc390_waiting_timer (pACB, HZ/5);
1452 pSRB->AdaptStatus = 0;
1453 pSRB->TargetStatus = 0;
1456 else if(status == SCSI_STAT_SEL_TIMEOUT)
1458 pSRB->AdaptStatus = H_SEL_TIMEOUT;
1459 pSRB->TargetStatus = 0;
1460 pcmd->result = MK_RES(0,DID_NO_CONNECT,0,0);
1461 /* Devices are removed below ... */
1463 else if (status_byte(status) == BUSY &&
1464 (pcmd->cmnd[0] == TEST_UNIT_READY || pcmd->cmnd[0] == INQUIRY) &&
1467 pSRB->AdaptStatus = 0;
1468 pSRB->TargetStatus = status;
1469 pcmd->result = MK_RES(0,0,pSRB->EndMessage,/*status*/0);
1472 { /* Another error */
1473 pSRB->AdaptStatus = 0;
1474 if( pSRB->RetryCnt )
1476 //printk ("DC390: retry\n");
1478 pSRB->TargetStatus = 0;
1480 pSRB->TotalXferredLen = 0;
1481 pSRB->SGToBeXferLen = 0;
1482 if( dc390_StartSCSI( pACB, pDCB, pSRB ) ) {
1483 dc390_Going_to_Waiting ( pDCB, pSRB );
1484 dc390_waiting_timer (pACB, HZ/5);
1489 { /* Report error */
1490 //pcmd->result = MK_RES(0, DID_ERROR, pSRB->EndMessage, status);
1491 SET_RES_DID(pcmd->result,DID_ERROR);
1492 SET_RES_MSG(pcmd->result,pSRB->EndMessage);
1493 SET_RES_TARGET(pcmd->result,status);
1498 { /* Target status == 0 */
1499 status = pSRB->AdaptStatus;
1500 if(status & H_OVER_UNDER_RUN)
1502 pSRB->TargetStatus = 0;
1503 SET_RES_DID(pcmd->result,DID_OK);
1504 SET_RES_MSG(pcmd->result,pSRB->EndMessage);
1506 else if( pSRB->SRBStatus & PARITY_ERROR)
1508 //pcmd->result = MK_RES(0,DID_PARITY,pSRB->EndMessage,0);
1509 SET_RES_DID(pcmd->result,DID_PARITY);
1510 SET_RES_MSG(pcmd->result,pSRB->EndMessage);
1514 pSRB->AdaptStatus = 0;
1515 pSRB->TargetStatus = 0;
1516 SET_RES_DID(pcmd->result,DID_OK);
1519 if ((pcmd->result & RES_DID) == 0 &&
1520 pcmd->cmnd[0] == INQUIRY &&
1521 pcmd->cmnd[2] == 0 &&
1522 pcmd->request_bufflen >= 8 &&
1524 (ptr->Vers & 0x07) >= 2)
1525 pDCB->Inquiry7 = ptr->Flags;
1528 if( pACB->scan_devices )
1530 if( pcmd->cmnd[0] == TEST_UNIT_READY ||
1531 pcmd->cmnd[0] == INQUIRY)
1534 printk (KERN_INFO "DC390: %s: result: %08x",
1535 (pcmd->cmnd[0] == INQUIRY? "INQUIRY": "TEST_UNIT_READY"),
1537 if (pcmd->result & (DRIVER_SENSE << 24)) printk (" (sense: %02x %02x %02x %02x)\n",
1538 pcmd->sense_buffer[0], pcmd->sense_buffer[1],
1539 pcmd->sense_buffer[2], pcmd->sense_buffer[3]);
1545 if( pcmd->cmnd[0] == INQUIRY &&
1546 (pcmd->result == (DID_OK << 16) || status_byte(pcmd->result) & CHECK_CONDITION) )
1548 if ((ptr->DevType & SCSI_DEVTYPE) != TYPE_NODEV)
1550 /* device found: add */
1551 dc390_add_dev (pACB, pDCB, ptr);
1555 pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen;
1557 dc390_Going_remove (pDCB, pSRB);
1558 /* Add to free list */
1559 dc390_Free_insert (pACB, pSRB);
1561 DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done pid %li\n", pcmd->pid));
1562 pcmd->scsi_done (pcmd);
1564 dc390_Waiting_process (pACB);
1569 /* Remove all SRBs from Going list and inform midlevel */
1571 dc390_DoingSRB_Done(struct dc390_acb* pACB, struct scsi_cmnd *cmd)
1573 struct dc390_dcb *pDCB, *pdcb;
1574 struct dc390_srb *psrb, *psrb2;
1576 struct scsi_cmnd *pcmd;
1578 pDCB = pACB->pLinkDCB;
1583 psrb = pdcb->pGoingSRB;
1584 for( i=0; i<pdcb->GoingSRBCnt; i++)
1586 psrb2 = psrb->pNextSRB;
1588 dc390_Free_insert (pACB, psrb);
1590 /* New EH will crash on being given timed out cmnds */
1592 pcmd->result = MK_RES(0,DID_ABORT,0,0);
1594 pcmd->result = MK_RES(0,DID_RESET,0,0);
1596 /* ReleaseSRB( pDCB, pSRB ); */
1598 DEBUG0(printk (KERN_DEBUG "DC390: DoingSRB_Done: done pid %li\n", pcmd->pid));
1599 pcmd->scsi_done( pcmd );
1603 pdcb->GoingSRBCnt = 0;
1604 pdcb->pGoingSRB = NULL;
1606 pdcb = pdcb->pNextDCB;
1607 } while( pdcb != pDCB );
1612 dc390_ResetSCSIBus( struct dc390_acb* pACB )
1614 //DC390_write8 (ScsiCmd, RST_DEVICE_CMD);
1616 //DC390_write8 (ScsiCmd, NOP_CMD);
1618 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1619 DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1620 DC390_write8 (ScsiCmd, RST_SCSI_BUS_CMD);
1621 pACB->Connected = 0;
1627 dc390_ScsiRstDetect( struct dc390_acb* pACB )
1629 printk ("DC390: Rst_Detect: laststat = %08x\n", dc390_laststatus);
1630 //DEBUG0(printk(KERN_INFO "RST_DETECT,"));
1632 if (timer_pending (&pACB->Waiting_Timer)) del_timer (&pACB->Waiting_Timer);
1633 DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1634 /* Unlock before ? */
1635 /* delay half a second */
1637 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1638 pACB->pScsiHost->last_reset = jiffies + 5*HZ/2
1639 + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
1640 pACB->Connected = 0;
1642 if( pACB->ACBFlag & RESET_DEV )
1643 pACB->ACBFlag |= RESET_DONE;
1645 { /* Reset was issued by sb else */
1646 pACB->ACBFlag |= RESET_DETECT;
1648 dc390_ResetDevParam( pACB );
1649 dc390_DoingSRB_Done( pACB, 0 );
1650 //dc390_RecoverSRB( pACB );
1651 pACB->pActiveDCB = NULL;
1653 dc390_Waiting_process( pACB );
1659 static void __inline__
1660 dc390_RequestSense( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB )
1662 struct scsi_cmnd *pcmd;
1666 REMOVABLEDEBUG(printk (KERN_INFO "DC390: RequestSense (Cmd %02x, Id %02x, LUN %02x)\n",\
1667 pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN));
1669 pSRB->SRBFlag |= AUTO_REQSENSE;
1670 //pSRB->Segment0[0] = (u32) pSRB->CmdBlock[0];
1671 //pSRB->Segment0[1] = (u32) pSRB->CmdBlock[4];
1672 //pSRB->Segment1[0] = ((u32)(pcmd->cmd_len) << 8) + pSRB->SGcount;
1673 //pSRB->Segment1[1] = pSRB->TotalXferredLen;
1674 pSRB->SavedSGCount = pcmd->use_sg;
1675 pSRB->SavedTotXLen = pSRB->TotalXferredLen;
1676 pSRB->AdaptStatus = 0;
1677 pSRB->TargetStatus = 0; /* CHECK_CONDITION<<1; */
1679 /* We are called from SRBdone, original PCI mapping has been removed
1680 * already, new one is set up from StartSCSI */
1683 //pSRB->CmdBlock[0] = REQUEST_SENSE;
1684 //pSRB->CmdBlock[1] = pDCB->TargetLUN << 5;
1685 //(u16) pSRB->CmdBlock[2] = 0;
1686 //(u16) pSRB->CmdBlock[4] = sizeof(pcmd->sense_buffer);
1687 //pSRB->ScsiCmdLen = 6;
1689 pSRB->TotalXferredLen = 0;
1690 pSRB->SGToBeXferLen = 0;
1691 if( dc390_StartSCSI( pACB, pDCB, pSRB ) ) {
1692 dc390_Going_to_Waiting ( pDCB, pSRB );
1693 dc390_waiting_timer (pACB, HZ/5);
1699 static void __inline__
1700 dc390_InvalidCmd( struct dc390_acb* pACB )
1702 if( pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_+SRB_MSGOUT) )
1703 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);