patch-2.3.17 linux/drivers/scsi/scsiiom.c
Next file: linux/drivers/scsi/sd.c
Previous file: linux/drivers/scsi/scsicam.c
Back to the patch index
Back to the overall index
- Lines: 3093
- Date:
Sat Sep 4 10:48:46 1999
- Orig file:
v2.3.16/linux/drivers/scsi/scsiiom.c
- Orig date:
Fri Dec 25 16:41:39 1998
diff -u --recursive --new-file v2.3.16/linux/drivers/scsi/scsiiom.c linux/drivers/scsi/scsiiom.c
@@ -7,165 +7,156 @@
/* $Id: scsiiom.c,v 2.15 1998/12/25 17:33:27 garloff Exp $ */
UCHAR
-dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
+dc390_StartSCSI(PACB pACB, PDCB pDCB, PSRB pSRB)
{
- USHORT wlval;
- UCHAR bval, bval1;
+ USHORT wlval;
+ UCHAR bval, bval1;
- pSRB->TagNumber = 31;
- DC390_write8 (Scsi_Dest_ID, pDCB->UnitSCSIID);
- DC390_write8 (Sync_Period, pDCB->SyncPeriod);
- DC390_write8 (Sync_Offset, pDCB->SyncOffset);
- DC390_write8 (CtrlReg1, pDCB->CtrlR1);
- DC390_write8 (CtrlReg3, pDCB->CtrlR3);
- DC390_write8 (CtrlReg4, pDCB->CtrlR4);
- DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); /* Flush FIFO */
- DEBUG1(printk (KERN_INFO "DC390: Start SCSI command: %02x (Sync:%02x)\n",\
- pSRB->CmdBlock[0], pDCB->SyncMode);)
- pSRB->ScsiPhase = SCSI_NOP0;
- //pSRB->MsgOutBuf[0] = MSG_NOP;
- //pSRB->MsgCnt = 0;
- bval = pDCB->IdentifyMsg;
- if( !(pDCB->SyncMode & EN_ATN_STOP) ) /* Don't always try send Extended messages on arbitration */
- {
- if( (pSRB->CmdBlock[0] == INQUIRY) ||
- (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
- (pSRB->SRBFlag & AUTO_REQSENSE) )
- {
- bval &= 0xBF; /* No DisConn */
- DC390_write8 (ScsiFifo, bval);
- bval1 = SEL_W_ATN;
- pSRB->SRBState = SRB_START_;
- DEBUG1(printk (KERN_DEBUG "DC390: No DisCn, No TagQ (%02x, %02x)\n", bval, bval1);)
- if( pDCB->SyncMode & SYNC_ENABLE )
- {
- if( !(pDCB->IdentifyMsg & 7) || /* LUN == 0 || Cmd != INQUIRY */
- (pSRB->CmdBlock[0] != INQUIRY) )
- {
- bval1 = SEL_W_ATN_STOP; /* Try to establish SYNC nego */
- pSRB->SRBState = SRB_MSGOUT;
+ pSRB->TagNumber = 31;
+ DC390_write8(Scsi_Dest_ID, pDCB->UnitSCSIID);
+ DC390_write8(Sync_Period, pDCB->SyncPeriod);
+ DC390_write8(Sync_Offset, pDCB->SyncOffset);
+ DC390_write8(CtrlReg1, pDCB->CtrlR1);
+ DC390_write8(CtrlReg3, pDCB->CtrlR3);
+ DC390_write8(CtrlReg4, pDCB->CtrlR4);
+ DC390_write8(ScsiCmd, CLEAR_FIFO_CMD); /* Flush FIFO */
+ DEBUG1(printk(KERN_INFO "DC390: Start SCSI command: %02x (Sync:%02x)\n", \
+ pSRB->CmdBlock[0], pDCB->SyncMode);
+ )
+ pSRB->ScsiPhase = SCSI_NOP0;
+ //pSRB->MsgOutBuf[0] = MSG_NOP;
+ //pSRB->MsgCnt = 0;
+ bval = pDCB->IdentifyMsg;
+ if (!(pDCB->SyncMode & EN_ATN_STOP)) { /* Don't always try send Extended messages on arbitration */
+ if ((pSRB->CmdBlock[0] == INQUIRY) ||
+ (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
+ (pSRB->SRBFlag & AUTO_REQSENSE)) {
+ bval &= 0xBF; /* No DisConn */
+ DC390_write8(ScsiFifo, bval);
+ bval1 = SEL_W_ATN;
+ pSRB->SRBState = SRB_START_;
+ DEBUG1(printk(KERN_DEBUG "DC390: No DisCn, No TagQ (%02x, %02x)\n", bval, bval1);
+ )
+ if (pDCB->SyncMode & SYNC_ENABLE) {
+ if (!(pDCB->IdentifyMsg & 7) || /* LUN == 0 || Cmd != INQUIRY */
+ (pSRB->CmdBlock[0] != INQUIRY)) {
+ bval1 = SEL_W_ATN_STOP; /* Try to establish SYNC nego */
+ pSRB->SRBState = SRB_MSGOUT;
+ }
+ }
+ } else { /* TagQ ? */
+ DC390_write8(ScsiFifo, bval);
+ if (pDCB->SyncMode & EN_TAG_QUEUEING) {
+ DC390_write8(ScsiFifo, MSG_SIMPLE_QTAG);
+ DEBUG1(printk(KERN_DEBUG "DC390: %sDisCn, TagQ (%02x, %02x, %08lx)\n", (bval & 0x40 ? "" : "No "), bval, SEL_W_ATN3, pDCB->TagMask);
+ )
+ bval = 0;
+ wlval = 1;
+ while (wlval & pDCB->TagMask) {
+ bval++;
+ wlval <<= 1;
+ };
+ pDCB->TagMask |= wlval;
+ DC390_write8(ScsiFifo, bval);
+ pSRB->TagNumber = bval;
+ DEBUG1(printk(KERN_DEBUG "DC390: SRB %p (Cmd %li), Tag %02x queued\n", pSRB, pSRB->pcmd->pid, bval);
+ )
+ bval1 = SEL_W_ATN3;
+ pSRB->SRBState = SRB_START_;
+ } else { /* No TagQ */
+ bval1 = SEL_W_ATN;
+ DEBUG1(printk(KERN_DEBUG "DC390: %sDisCn, No TagQ (%02x, %02x, %08lx)\n", (bval & 0x40 ? "" : "No "), bval, bval1, pDCB->TagMask);
+ )
+ pSRB->SRBState = SRB_START_;
+ }
}
- }
- }
- else /* TagQ ? */
- {
- DC390_write8 (ScsiFifo, bval);
- if(pDCB->SyncMode & EN_TAG_QUEUEING)
- {
- DC390_write8 (ScsiFifo, MSG_SIMPLE_QTAG);
- DEBUG1(printk (KERN_DEBUG "DC390: %sDisCn, TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, SEL_W_ATN3, pDCB->TagMask);)
- bval = 0; wlval = 1;
- while (wlval & pDCB->TagMask)
- { bval++; wlval <<= 1; };
- pDCB->TagMask |= wlval;
- DC390_write8 (ScsiFifo, bval);
- pSRB->TagNumber = bval;
- DEBUG1(printk (KERN_DEBUG "DC390: SRB %p (Cmd %li), Tag %02x queued\n", pSRB, pSRB->pcmd->pid, bval);)
- bval1 = SEL_W_ATN3;
- pSRB->SRBState = SRB_START_;
- }
- else /* No TagQ */
- {
- bval1 = SEL_W_ATN;
- DEBUG1(printk (KERN_DEBUG "DC390: %sDisCn, No TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, bval1, pDCB->TagMask);)
- pSRB->SRBState = SRB_START_;
- }
- }
-
- }
- else /* ATN_STOP: Always try to establish Sync nego */
- {
- if( (pSRB->CmdBlock[0] == INQUIRY) ||
- (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
- (pSRB->SRBFlag & AUTO_REQSENSE) )
- {
- bval &= 0xBF; /* No DisConn */
- DC390_write8 (ScsiFifo, bval);
- bval1 = SEL_W_ATN;
- DEBUG1(printk (KERN_DEBUG "DC390: No DisCn, No TagQ (%02x, %02x)\n", bval, bval1);)
- pSRB->SRBState = SRB_START_;
- /* ??? */
- if( pDCB->SyncMode & SYNC_ENABLE )
- {
- if( !(pDCB->IdentifyMsg & 7) || /* LUN == 0 || Cmd != INQUIRY */
- (pSRB->CmdBlock[0] != INQUIRY) )
- {
- bval1 = SEL_W_ATN_STOP; /* Try to establish Sync nego */
- pSRB->SRBState = SRB_MSGOUT;
+
+ } else { /* ATN_STOP: Always try to establish Sync nego */
+ if ((pSRB->CmdBlock[0] == INQUIRY) ||
+ (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
+ (pSRB->SRBFlag & AUTO_REQSENSE)) {
+ bval &= 0xBF; /* No DisConn */
+ DC390_write8(ScsiFifo, bval);
+ bval1 = SEL_W_ATN;
+ DEBUG1(printk(KERN_DEBUG "DC390: No DisCn, No TagQ (%02x, %02x)\n", bval, bval1);
+ )
+ pSRB->SRBState = SRB_START_;
+ /* ??? */
+ if (pDCB->SyncMode & SYNC_ENABLE) {
+ if (!(pDCB->IdentifyMsg & 7) || /* LUN == 0 || Cmd != INQUIRY */
+ (pSRB->CmdBlock[0] != INQUIRY)) {
+ bval1 = SEL_W_ATN_STOP; /* Try to establish Sync nego */
+ pSRB->SRBState = SRB_MSGOUT;
+ }
+ }
+ } else { /* TagQ ? */
+ DC390_write8(ScsiFifo, bval);
+ if (pDCB->SyncMode & EN_TAG_QUEUEING) {
+ pSRB->MsgOutBuf[0] = MSG_SIMPLE_QTAG;
+ DEBUG1(printk(KERN_DEBUG "DC390: %sDisCn, TagQ (%02x, %02x, %08lx)\n", (bval & 0x40 ? "" : "No "), bval, SEL_W_ATN_STOP, pDCB->TagMask);
+ )
+ bval = 0;
+ wlval = 1;
+ while (wlval & pDCB->TagMask) {
+ bval++;
+ wlval <<= 1;
+ };
+ pDCB->TagMask |= wlval;
+ pSRB->TagNumber = bval;
+ DEBUG1(printk(KERN_DEBUG "DC390: SRB %p (Cmd %li), Tag %02x queued\n", pSRB, pSRB->pcmd->pid, bval);
+ )
+ pSRB->MsgOutBuf[1] = bval;
+ pSRB->MsgCnt = 2;
+ bval1 = SEL_W_ATN_STOP;
+ pSRB->SRBState = SRB_START_; /* ?? */
+ } else { /* No TagQ */
+ pSRB->MsgOutBuf[0] = MSG_NOP;
+ pSRB->MsgCnt = 1;
+ pSRB->SRBState = SRB_START_;
+ bval1 = SEL_W_ATN_STOP;
+ DEBUG1(printk(KERN_DEBUG "DC390: %sDisCn, No TagQ (%02x, %02x, %08lx)\n", (bval & 0x40 ? "" : "No "), bval, bval1, pDCB->TagMask);
+ )
+ };
}
- }
}
- else /* TagQ ? */
- {
- DC390_write8 (ScsiFifo, bval);
- if(pDCB->SyncMode & EN_TAG_QUEUEING)
- {
- pSRB->MsgOutBuf[0] = MSG_SIMPLE_QTAG;
- DEBUG1(printk (KERN_DEBUG "DC390: %sDisCn, TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, SEL_W_ATN_STOP, pDCB->TagMask);)
- bval = 0; wlval = 1;
- while (wlval & pDCB->TagMask)
- { bval++; wlval <<= 1; };
- pDCB->TagMask |= wlval;
- pSRB->TagNumber = bval;
- DEBUG1(printk (KERN_DEBUG "DC390: SRB %p (Cmd %li), Tag %02x queued\n", pSRB, pSRB->pcmd->pid, bval);)
- pSRB->MsgOutBuf[1] = bval;
- pSRB->MsgCnt = 2;
- bval1 = SEL_W_ATN_STOP;
- pSRB->SRBState = SRB_START_; /* ?? */
- }
- else /* No TagQ */
- {
- pSRB->MsgOutBuf[0] = MSG_NOP;
- pSRB->MsgCnt = 1;
- pSRB->SRBState = SRB_START_;
- bval1 = SEL_W_ATN_STOP;
- DEBUG1(printk (KERN_DEBUG "DC390: %sDisCn, No TagQ (%02x, %02x, %08lx)\n", (bval&0x40?"":"No "), bval, bval1, pDCB->TagMask);)
- };
- }
- }
- if (bval1 != SEL_W_ATN_STOP)
- { /* Command is written in CommandPhase, if SEL_W_ATN_STOP ... */
- if( pSRB->SRBFlag & AUTO_REQSENSE )
- {
- bval = 0;
- DC390_write8 (ScsiFifo, REQUEST_SENSE);
- DC390_write8 (ScsiFifo, pDCB->IdentifyMsg << 5);
- DC390_write8 (ScsiFifo, bval);
- DC390_write8 (ScsiFifo, bval);
- DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
- DC390_write8 (ScsiFifo, bval);
- DEBUG1(printk (KERN_DEBUG "DC390: AutoReqSense !\n");)
- }
- else /* write cmnd to bus */
- {
- PUCHAR ptr; UCHAR i;
- ptr = (PUCHAR) pSRB->CmdBlock;
- for (i=0; i<pSRB->ScsiCmdLen; i++)
- DC390_write8 (ScsiFifo, *(ptr++));
- };
- }
-
- /* Check if we can't win arbitration */
- if (DC390_read8 (Scsi_Status) & INTERRUPT)
- {
- pSRB->SRBState = SRB_READY;
- pDCB->TagMask &= ~( 1 << pSRB->TagNumber );
- DEBUG0(printk (KERN_WARNING "DC390: Interrupt during StartSCSI!\n");)
- return 1;
- }
- else
- {
- pSRB->ScsiPhase = SCSI_NOP1;
- DEBUG0(if (pACB->pActiveDCB) \
- printk (KERN_WARNING "DC390: ActiveDCB != 0\n");)
- DEBUG0(if (pDCB->pActiveSRB) \
- printk (KERN_WARNING "DC390: ActiveSRB != 0\n");)
- pACB->pActiveDCB = pDCB;
- pDCB->pActiveSRB = pSRB;
- //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
- DC390_write8 (ScsiCmd, bval1);
- return 0;
- }
+ if (bval1 != SEL_W_ATN_STOP) { /* Command is written in CommandPhase, if SEL_W_ATN_STOP ... */
+ if (pSRB->SRBFlag & AUTO_REQSENSE) {
+ bval = 0;
+ DC390_write8(ScsiFifo, REQUEST_SENSE);
+ DC390_write8(ScsiFifo, pDCB->IdentifyMsg << 5);
+ DC390_write8(ScsiFifo, bval);
+ DC390_write8(ScsiFifo, bval);
+ DC390_write8(ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
+ DC390_write8(ScsiFifo, bval);
+ DEBUG1(printk(KERN_DEBUG "DC390: AutoReqSense !\n");
+ )
+ } else { /* write cmnd to bus */
+ PUCHAR ptr;
+ UCHAR i;
+ ptr = (PUCHAR) pSRB->CmdBlock;
+ for (i = 0; i < pSRB->ScsiCmdLen; i++)
+ DC390_write8(ScsiFifo, *(ptr++));
+ };
+ }
+ /* Check if we can't win arbitration */
+ if (DC390_read8(Scsi_Status) & INTERRUPT) {
+ pSRB->SRBState = SRB_READY;
+ pDCB->TagMask &= ~(1 << pSRB->TagNumber);
+ DEBUG0(printk(KERN_WARNING "DC390: Interrupt during StartSCSI!\n");
+ )
+ return 1;
+ } else {
+ pSRB->ScsiPhase = SCSI_NOP1;
+ DEBUG0(if (pACB->pActiveDCB) \
+ printk(KERN_WARNING "DC390: ActiveDCB != 0\n");)
+ DEBUG0(if (pDCB->pActiveSRB) \
+ printk(KERN_WARNING "DC390: ActiveSRB != 0\n");)
+ pACB->pActiveDCB = pDCB;
+ pDCB->pActiveSRB = pSRB;
+ //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
+ DC390_write8(ScsiCmd, bval1);
+ return 0;
+ }
}
//#define DMA_INT EN_DMA_INT /*| EN_PAGE_INT*/
@@ -173,417 +164,400 @@
#if DMA_INT
/* This is similar to AM53C974.c ... */
-static UCHAR
-dc390_dma_intr (PACB pACB)
+static UCHAR
+ dc390_dma_intr(PACB pACB)
{
- PSRB pSRB;
- UCHAR dstate;
- DEBUG0(USHORT pstate;PDEVDECL1;)
-
- DEBUG0(PDEVSET1;)
- DEBUG0(PCI_READ_CONFIG_WORD (PDEV, PCI_STATUS, &pstate);)
- DEBUG0(if (pstate & (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY))\
- { printk(KERN_WARNING "DC390: PCI state = %04x!\n", pstate); \
- PCI_WRITE_CONFIG_WORD (PDEV, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));};)
-
- dstate = DC390_read8 (DMA_Status);
-
- if (! pACB->pActiveDCB || ! pACB->pActiveDCB->pActiveSRB) return dstate;
- else pSRB = pACB->pActiveDCB->pActiveSRB;
-
- if (dstate & (DMA_XFER_ABORT | DMA_XFER_ERROR | POWER_DOWN | PCI_MS_ABORT))
- {
- printk (KERN_ERR "DC390: DMA error (%02x)!\n", dstate);
- return dstate;
- };
- if (dstate & DMA_XFER_DONE)
- {
- ULONG residual, xferCnt; int ctr = 5000000;
- if (! (DC390_read8 (DMA_Cmd) & READ_DIRECTION))
- {
- do
- {
- DEBUG1(printk (KERN_DEBUG "DC390: read residual bytes ... \n");)
- dstate = DC390_read8 (DMA_Status);
- residual = DC390_read8 (CtcReg_Low) | DC390_read8 (CtcReg_Mid) << 8 |
- DC390_read8 (CtcReg_High) << 16;
- residual += DC390_read8 (Current_Fifo) & 0x1f;
- } while (residual && ! (dstate & SCSI_INTERRUPT) && --ctr);
- if (!ctr) printk (KERN_CRIT "DC390: dma_intr: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr));
- /* residual = ... */
- }
+ PSRB pSRB;
+ UCHAR dstate;
+ DEBUG0(USHORT pstate;
+ PDEVDECL1;
+ )
+ DEBUG0(PDEVSET1;
+ )
+ DEBUG0(PCI_READ_CONFIG_WORD(PDEV, PCI_STATUS, &pstate);
+ )
+ DEBUG0(if (pstate & (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY)) \
+ {
+ printk(KERN_WARNING "DC390: PCI state = %04x!\n", pstate); \
+ PCI_WRITE_CONFIG_WORD(PDEV, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));
+ };
+ )
+ dstate = DC390_read8(DMA_Status);
+
+ if (!pACB->pActiveDCB || !pACB->pActiveDCB->pActiveSRB)
+ return dstate;
else
- residual = 0;
-
- /* ??? */
-
- xferCnt = pSRB->SGToBeXferLen - residual;
- pSRB->SGBusAddr += xferCnt;
- pSRB->TotalXferredLen += xferCnt;
- pSRB->SGToBeXferLen = residual;
-# ifdef DC390_DEBUG0
- printk (KERN_INFO "DC390: DMA: residual = %i, xfer = %i\n",
- (unsigned int)residual, (unsigned int)xferCnt);
-# endif
-
- DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
- }
- dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24;
- return dstate;
+ pSRB = pACB->pActiveDCB->pActiveSRB;
+
+ if (dstate & (DMA_XFER_ABORT | DMA_XFER_ERROR | POWER_DOWN | PCI_MS_ABORT)) {
+ printk(KERN_ERR "DC390: DMA error (%02x)!\n", dstate);
+ return dstate;
+ };
+ if (dstate & DMA_XFER_DONE) {
+ ULONG residual, xferCnt;
+ int ctr = 5000000;
+ if (!(DC390_read8(DMA_Cmd) & READ_DIRECTION)) {
+ do {
+ DEBUG1(printk(KERN_DEBUG "DC390: read residual bytes ... \n");
+ )
+ dstate = DC390_read8(DMA_Status);
+ residual = DC390_read8(CtcReg_Low) | DC390_read8(CtcReg_Mid) << 8 |
+ DC390_read8(CtcReg_High) << 16;
+ residual += DC390_read8(Current_Fifo) & 0x1f;
+ } while (residual && !(dstate & SCSI_INTERRUPT) && --ctr);
+ if (!ctr)
+ printk(KERN_CRIT "DC390: dma_intr: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32(DMA_Wk_ByteCntr));
+ /* residual = ... */
+ } else
+ residual = 0;
+
+ /* ??? */
+
+ xferCnt = pSRB->SGToBeXferLen - residual;
+ pSRB->SGBusAddr += xferCnt;
+ pSRB->TotalXferredLen += xferCnt;
+ pSRB->SGToBeXferLen = residual;
+#ifdef DC390_DEBUG0
+ printk(KERN_INFO "DC390: DMA: residual = %i, xfer = %i\n",
+ (unsigned int) residual, (unsigned int) xferCnt);
+#endif
+
+ DC390_write8(DMA_Cmd, DMA_IDLE_CMD);
+ }
+ dc390_laststatus &= ~0xff000000;
+ dc390_laststatus |= dstate << 24;
+ return dstate;
};
#endif
void __inline__
-DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
+ DC390_Interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- PACB pACB;
- PDCB pDCB;
- PSRB pSRB;
- UCHAR sstatus=0;
- UCHAR phase, i;
- void (*stateV)( PACB, PSRB, PUCHAR );
- UCHAR istate, istatus;
+ PACB pACB;
+ PDCB pDCB;
+ PSRB pSRB;
+ UCHAR sstatus = 0;
+ UCHAR phase, i;
+ void (*stateV) (PACB, PSRB, PUCHAR);
+ UCHAR istate, istatus;
#if DMA_INT
- UCHAR dstatus;
+ UCHAR dstatus;
#endif
- DC390_AFLAGS DC390_IFLAGS DC390_DFLAGS
-
- pACB = dc390_pACB_start;
+ DC390_AFLAGS DC390_IFLAGS DC390_DFLAGS
- if (pACB == 0)
- {
- printk(KERN_WARNING "DC390: Interrupt on uninitialized adapter!\n");
- return;
- }
- DC390_LOCK_DRV;
+ pACB = dc390_pACB_start;
- for( i=0; i < dc390_adapterCnt; i++ )
- {
- if( pACB->IRQLevel == (UCHAR) irq )
- {
- sstatus = DC390_read8 (Scsi_Status);
- if( sstatus & INTERRUPT )
- break;
- else
- pACB = pACB->pNextACB;
- }
- else
- {
- pACB = pACB->pNextACB;
+ if (pACB == 0) {
+ printk(KERN_WARNING "DC390: Interrupt on uninitialized adapter!\n");
+ return;
}
- }
+ DC390_LOCK_DRV;
- DEBUG1(printk (KERN_DEBUG "sstatus=%02x,", sstatus);)
+ for (i = 0; i < dc390_adapterCnt; i++) {
+ if (pACB->IRQLevel == (UCHAR) irq) {
+ sstatus = DC390_read8(Scsi_Status);
+ if (sstatus & INTERRUPT)
+ break;
+ else
+ pACB = pACB->pNextACB;
+ } else {
+ pACB = pACB->pNextACB;
+ }
+ }
- if( !pACB ) { DC390_UNLOCK_DRV; return; };
+ DEBUG1(printk(KERN_DEBUG "sstatus=%02x,", sstatus);
+ )
+ if (!pACB) {
+ DC390_UNLOCK_DRV;
+ return;
+ };
#if DMA_INT
- DC390_LOCK_IO;
- DC390_LOCK_ACB;
- dstatus = dc390_dma_intr (pACB);
- DC390_UNLOCK_ACB;
- DC390_UNLOCK_IO;
-
- DEBUG1(printk (KERN_DEBUG "dstatus=%02x,", dstatus);)
- if (! (dstatus & SCSI_INTERRUPT))
- {
- DEBUG0(printk (KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n");)
- DC390_UNLOCK_DRV;
- return;
- };
+ DC390_LOCK_IO;
+ DC390_LOCK_ACB;
+ dstatus = dc390_dma_intr(pACB);
+ DC390_UNLOCK_ACB;
+ DC390_UNLOCK_IO;
+
+ DEBUG1(printk(KERN_DEBUG "dstatus=%02x,", dstatus);
+ )
+ if (!(dstatus & SCSI_INTERRUPT)) {
+ DEBUG0(printk(KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n");
+ )
+ DC390_UNLOCK_DRV;
+ return;
+ };
#else
- //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
- //dstatus = DC390_read8 (DMA_Status);
- //DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
+ //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
+ //dstatus = DC390_read8 (DMA_Status);
+ //DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
#endif
- DC390_LOCK_IO;
- DC390_LOCK_ACB;
- DC390_UNLOCK_DRV_NI; /* Allow _other_ CPUs to process IRQ (useful for shared IRQs) */
-
- istate = DC390_read8 (Intern_State);
- istatus = DC390_read8 (INT_Status); /* This clears Scsi_Status, Intern_State and INT_Status ! */
-
- DEBUG1(printk (KERN_INFO "Istatus(Res,Inv,Dis,Serv,Succ,ReS,SelA,Sel)=%02x,",istatus);)
- dc390_laststatus &= ~0x00ffffff;
- dc390_laststatus |= /* dstatus<<24 | */ sstatus<<16 | istate<<8 | istatus;
-
- if (sstatus & ILLEGAL_OP_ERR)
- {
- printk ("DC390: Illegal Operation detected (%08lx)!\n", dc390_laststatus);
- dc390_dumpinfo (pACB, pACB->pActiveDCB, pACB->pActiveDCB->pActiveSRB);
- };
-
- if(istatus & DISCONNECTED)
- {
- dc390_Disconnect( pACB );
- goto unlock;
- }
-
- if(istatus & RESELECTED)
- {
- dc390_Reselect( pACB );
- goto unlock;
- }
-
- if( istatus & (SUCCESSFUL_OP|SERVICE_REQUEST) )
- {
- pDCB = pACB->pActiveDCB;
- if (!pDCB)
- {
- printk (KERN_ERR "DC390: Suc. op/ Serv. req: pActiveDCB = 0!\n");
- goto unlock;
+ DC390_LOCK_IO;
+ DC390_LOCK_ACB;
+ DC390_UNLOCK_DRV_NI; /* Allow _other_ CPUs to process IRQ (useful for shared IRQs) */
+
+ istate = DC390_read8(Intern_State);
+ istatus = DC390_read8(INT_Status); /* This clears Scsi_Status, Intern_State and INT_Status ! */
+
+ DEBUG1(printk(KERN_INFO "Istatus(Res,Inv,Dis,Serv,Succ,ReS,SelA,Sel)=%02x,", istatus);
+ )
+ dc390_laststatus &= ~0x00ffffff;
+ dc390_laststatus |= /* dstatus<<24 | */ sstatus << 16 | istate << 8 | istatus;
+
+ if (sstatus & ILLEGAL_OP_ERR) {
+ printk("DC390: Illegal Operation detected (%08lx)!\n", dc390_laststatus);
+ dc390_dumpinfo(pACB, pACB->pActiveDCB, pACB->pActiveDCB->pActiveSRB);
};
- pSRB = pDCB->pActiveSRB;
- if( pDCB->DCBFlag & ABORT_DEV_ )
- dc390_EnableMsgOut_Abort (pACB, pSRB);
-
- phase = pSRB->ScsiPhase;
- DEBUG1(printk (KERN_INFO "DC390: [%i]%s(0) (%02x)\n", phase, dc390_p0_str[phase], sstatus);)
- stateV = (void *) dc390_phase0[phase];
- ( *stateV )( pACB, pSRB, &sstatus );
-
- pSRB->ScsiPhase = sstatus & 7;
- phase = (UCHAR) sstatus & 7;
- DEBUG1(printk (KERN_INFO "DC390: [%i]%s(1) (%02x)\n", phase, dc390_p1_str[phase], sstatus);)
- stateV = (void *) dc390_phase1[phase];
- ( *stateV )( pACB, pSRB, &sstatus );
- goto unlock;
- }
-
- if(istatus & INVALID_CMD)
- {
- dc390_InvalidCmd( pACB );
- goto unlock;
- }
-
- if(istatus & SCSI_RESET)
- {
- dc390_ScsiRstDetect( pACB );
- goto unlock;
- }
-
- unlock:
- DC390_LOCK_DRV_NI;
- DC390_UNLOCK_ACB;
- DC390_UNLOCK_IO;
- DC390_UNLOCK_DRV; /* Restore initial flags */
-}
-
-void
-do_DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
-{
- DEBUG1(printk (KERN_INFO "DC390: Irq (%i) caught: ", irq);)
- /* Locking is done in DC390_Interrupt */
- DC390_Interrupt(irq, dev_id, regs);
- DEBUG1(printk (".. IRQ returned\n");)
-}
-
-void
-dc390_DataOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
-{
- UCHAR sstatus;
- PSGL psgl;
- ULONG ResidCnt, xferCnt;
- UCHAR dstate = 0;
-
- sstatus = *psstatus;
-
- if( !(pSRB->SRBState & SRB_XFERPAD) )
- {
- if( sstatus & (PARITY_ERR | ILLEGAL_OP_ERR) )
- pSRB->SRBStatus |= PARITY_ERROR;
- if( sstatus & COUNT_2_ZERO )
- {
- int ctr = 5000000; /* only try for about a tenth of a second */
- while( --ctr && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen );
- if (!ctr) printk (KERN_CRIT "DC390: Deadlock in DataOut_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr));
- dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24;
- pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
- pSRB->SGIndex++;
- if( pSRB->SGIndex < pSRB->SGcount )
- {
- pSRB->pSegmentList++;
- psgl = pSRB->pSegmentList;
-
- pSRB->SGBusAddr = virt_to_bus( psgl->address );
- pSRB->SGToBeXferLen = (ULONG) psgl->length;
- }
- else
- pSRB->SGToBeXferLen = 0;
+ if (istatus & DISCONNECTED) {
+ dc390_Disconnect(pACB);
+ goto unlock;
}
- else
- {
- ResidCnt = (ULONG) DC390_read8 (Current_Fifo) & 0x1f;
- ResidCnt |= (ULONG) DC390_read8 (CtcReg_High) << 16;
- ResidCnt |= (ULONG) DC390_read8 (CtcReg_Mid) << 8;
- ResidCnt += (ULONG) DC390_read8 (CtcReg_Low);
+ if (istatus & RESELECTED) {
+ dc390_Reselect(pACB);
+ goto unlock;
+ }
+ if (istatus & (SUCCESSFUL_OP | SERVICE_REQUEST)) {
+ pDCB = pACB->pActiveDCB;
+ if (!pDCB) {
+ printk(KERN_ERR "DC390: Suc. op/ Serv. req: pActiveDCB = 0!\n");
+ goto unlock;
+ };
+ pSRB = pDCB->pActiveSRB;
+ if (pDCB->DCBFlag & ABORT_DEV_)
+ dc390_EnableMsgOut_Abort(pACB, pSRB);
+
+ phase = pSRB->ScsiPhase;
+ DEBUG1(printk(KERN_INFO "DC390: [%i]%s(0) (%02x)\n", phase, dc390_p0_str[phase], sstatus);
+ )
+ stateV = (void *) dc390_phase0[phase];
+ (*stateV) (pACB, pSRB, &sstatus);
+
+ pSRB->ScsiPhase = sstatus & 7;
+ phase = (UCHAR) sstatus & 7;
+ DEBUG1(printk(KERN_INFO "DC390: [%i]%s(1) (%02x)\n", phase, dc390_p1_str[phase], sstatus);
+ )
+ stateV = (void *) dc390_phase1[phase];
+ (*stateV) (pACB, pSRB, &sstatus);
+ goto unlock;
+ }
+ if (istatus & INVALID_CMD) {
+ dc390_InvalidCmd(pACB);
+ goto unlock;
+ }
+ if (istatus & SCSI_RESET) {
+ dc390_ScsiRstDetect(pACB);
+ goto unlock;
+ }
+ unlock:
+ DC390_LOCK_DRV_NI;
+ DC390_UNLOCK_ACB;
+ DC390_UNLOCK_IO;
+ DC390_UNLOCK_DRV; /* Restore initial flags */
+}
+
+void do_DC390_Interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ DEBUG1(printk(KERN_INFO "DC390: Irq (%i) caught: ", irq);
+ )
+ /* Locking is done in DC390_Interrupt */
+ DC390_Interrupt(irq, dev_id, regs);
+ DEBUG1(printk(".. IRQ returned\n");
+ )
+}
+
+void dc390_DataOut_0(PACB pACB, PSRB pSRB, PUCHAR psstatus)
+{
+ UCHAR sstatus;
+ PSGL psgl;
+ ULONG ResidCnt, xferCnt;
+ UCHAR dstate = 0;
+
+ sstatus = *psstatus;
+
+ if (!(pSRB->SRBState & SRB_XFERPAD)) {
+ if (sstatus & (PARITY_ERR | ILLEGAL_OP_ERR))
+ pSRB->SRBStatus |= PARITY_ERROR;
+
+ if (sstatus & COUNT_2_ZERO) {
+ int ctr = 5000000; /* only try for about a tenth of a second */
+ while (--ctr && !((dstate = DC390_read8(DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen);
+ if (!ctr)
+ printk(KERN_CRIT "DC390: Deadlock in DataOut_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32(DMA_Wk_ByteCntr));
+ dc390_laststatus &= ~0xff000000;
+ dc390_laststatus |= dstate << 24;
+ pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
+ pSRB->SGIndex++;
+ if (pSRB->SGIndex < pSRB->SGcount) {
+ pSRB->pSegmentList++;
+ psgl = pSRB->pSegmentList;
+
+ pSRB->SGBusAddr = virt_to_bus(psgl->address);
+ pSRB->SGToBeXferLen = (ULONG) psgl->length;
+ } else
+ pSRB->SGToBeXferLen = 0;
+ } else {
+ ResidCnt = (ULONG) DC390_read8(Current_Fifo) & 0x1f;
+ ResidCnt |= (ULONG) DC390_read8(CtcReg_High) << 16;
+ ResidCnt |= (ULONG) DC390_read8(CtcReg_Mid) << 8;
+ ResidCnt += (ULONG) DC390_read8(CtcReg_Low);
+
+ xferCnt = pSRB->SGToBeXferLen - ResidCnt;
+ pSRB->SGBusAddr += xferCnt;
+ pSRB->TotalXferredLen += xferCnt;
+ pSRB->SGToBeXferLen = ResidCnt;
+ }
+ }
+ DC390_write8(DMA_Cmd, WRITE_DIRECTION + DMA_IDLE_CMD); /* | DMA_INT */
+}
- xferCnt = pSRB->SGToBeXferLen - ResidCnt;
- pSRB->SGBusAddr += xferCnt;
- pSRB->TotalXferredLen += xferCnt;
- pSRB->SGToBeXferLen = ResidCnt;
+void dc390_DataIn_0(PACB pACB, PSRB pSRB, PUCHAR psstatus)
+{
+ UCHAR sstatus, residual, bval;
+ PSGL psgl;
+ ULONG ResidCnt, xferCnt, i;
+ PUCHAR ptr;
+
+ sstatus = *psstatus;
+
+ if (!(pSRB->SRBState & SRB_XFERPAD)) {
+ if (sstatus & (PARITY_ERR | ILLEGAL_OP_ERR))
+ pSRB->SRBStatus |= PARITY_ERROR;
+
+ if (sstatus & COUNT_2_ZERO) {
+ int ctr = 5000000; /* only try for about a tenth of a second */
+ int dstate = 0;
+ while (--ctr && !((dstate = DC390_read8(DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen);
+ if (!ctr)
+ printk(KERN_CRIT "DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32(DMA_Wk_ByteCntr));
+ if (!ctr)
+ printk(KERN_CRIT "DC390: DataIn_0: DMA State: %i\n", dstate);
+ dc390_laststatus &= ~0xff000000;
+ dc390_laststatus |= dstate << 24;
+ DEBUG1(ResidCnt = ((ULONG) DC390_read8(CtcReg_High) << 16) \
+ +((ULONG) DC390_read8(CtcReg_Mid) << 8) \
+ +((ULONG) DC390_read8(CtcReg_Low));
+ )
+ DEBUG1(printk(KERN_DEBUG "Count_2_Zero (ResidCnt=%li,ToBeXfer=%li),", ResidCnt, pSRB->SGToBeXferLen);
+ )
+ DC390_write8(DMA_Cmd, READ_DIRECTION + DMA_IDLE_CMD); /* | DMA_INT */
+
+ pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
+ pSRB->SGIndex++;
+ if (pSRB->SGIndex < pSRB->SGcount) {
+ pSRB->pSegmentList++;
+ psgl = pSRB->pSegmentList;
+
+ pSRB->SGBusAddr = virt_to_bus(psgl->address);
+ pSRB->SGToBeXferLen = (ULONG) psgl->length;
+ } else
+ pSRB->SGToBeXferLen = 0;
+ } else { /* phase changed */
+ residual = 0;
+ bval = DC390_read8(Current_Fifo);
+ while (bval & 0x1f) {
+ DEBUG1(printk(KERN_DEBUG "Check for residuals,");
+ )
+ if ((bval & 0x1f) == 1) {
+ for (i = 0; i < 0x100; i++) {
+ bval = DC390_read8(Current_Fifo);
+ if (!(bval & 0x1f))
+ goto din_1;
+ else if (i == 0x0ff) {
+ residual = 1; /* ;1 residual byte */
+ goto din_1;
+ }
+ }
+ } else
+ bval = DC390_read8(Current_Fifo);
+ }
+ din_1:
+ DC390_write8(DMA_Cmd, READ_DIRECTION + DMA_BLAST_CMD);
+ for (i = 0xa000; i; i--) {
+ bval = DC390_read8(DMA_Status);
+ if (bval & BLAST_COMPLETE)
+ break;
+ }
+ /* It seems a DMA Blast abort isn't that bad ... */
+ if (!i)
+ printk(KERN_ERR "DC390: DMA Blast aborted unfinished!\n");
+ //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
+ dc390_laststatus &= ~0xff000000;
+ dc390_laststatus |= bval << 24;
+
+ DEBUG1(printk(KERN_DEBUG "Blast: Read %li times DMA_Status %02x", 0xa000 - i, bval);
+ )
+ ResidCnt = (ULONG) DC390_read8(CtcReg_High);
+ ResidCnt <<= 8;
+ ResidCnt |= (ULONG) DC390_read8(CtcReg_Mid);
+ ResidCnt <<= 8;
+ ResidCnt |= (ULONG) DC390_read8(CtcReg_Low);
+
+ xferCnt = pSRB->SGToBeXferLen - ResidCnt;
+ pSRB->SGBusAddr += xferCnt;
+ pSRB->TotalXferredLen += xferCnt;
+ pSRB->SGToBeXferLen = ResidCnt;
+
+ if (residual) {
+ bval = DC390_read8(ScsiFifo); /* get one residual byte */
+ ptr = (PUCHAR) bus_to_virt(pSRB->SGBusAddr);
+ *ptr = bval;
+ pSRB->SGBusAddr++;
+ xferCnt++;
+ pSRB->TotalXferredLen++;
+ pSRB->SGToBeXferLen--;
+ }
+ DEBUG1(printk(KERN_DEBUG "Xfered: %li, Total: %li, Remaining: %li\n", xferCnt, \
+ pSRB->TotalXferredLen, pSRB->SGToBeXferLen);
+ )
+ }
}
- }
- DC390_write8 (DMA_Cmd, WRITE_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
}
-void
-dc390_DataIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
+static void dc390_Command_0(PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
- UCHAR sstatus, residual, bval;
- PSGL psgl;
- ULONG ResidCnt, xferCnt, i;
- PUCHAR ptr;
+}
- sstatus = *psstatus;
+static void dc390_Status_0(PACB pACB, PSRB pSRB, PUCHAR psstatus)
+{
- if( !(pSRB->SRBState & SRB_XFERPAD) )
- {
- if( sstatus & (PARITY_ERR | ILLEGAL_OP_ERR))
- pSRB->SRBStatus |= PARITY_ERROR;
+ pSRB->TargetStatus = DC390_read8(ScsiFifo);
+ //udelay (1);
+ pSRB->EndMessage = DC390_read8(ScsiFifo); /* get message */
- if( sstatus & COUNT_2_ZERO )
- {
- int ctr = 5000000; /* only try for about a tenth of a second */
- int dstate = 0;
- while( --ctr && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen );
- if (!ctr) printk (KERN_CRIT "DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr));
- if (!ctr) printk (KERN_CRIT "DC390: DataIn_0: DMA State: %i\n", dstate);
- dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24;
- DEBUG1(ResidCnt = ((ULONG) DC390_read8 (CtcReg_High) << 16) \
- + ((ULONG) DC390_read8 (CtcReg_Mid) << 8) \
- + ((ULONG) DC390_read8 (CtcReg_Low));)
- DEBUG1(printk (KERN_DEBUG "Count_2_Zero (ResidCnt=%li,ToBeXfer=%li),", ResidCnt, pSRB->SGToBeXferLen);)
-
- DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
-
- pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
- pSRB->SGIndex++;
- if( pSRB->SGIndex < pSRB->SGcount )
- {
- pSRB->pSegmentList++;
- psgl = pSRB->pSegmentList;
-
- pSRB->SGBusAddr = virt_to_bus( psgl->address );
- pSRB->SGToBeXferLen = (ULONG) psgl->length;
- }
- else
- pSRB->SGToBeXferLen = 0;
- }
- else /* phase changed */
- {
- residual = 0;
- bval = DC390_read8 (Current_Fifo);
- while( bval & 0x1f )
- {
- DEBUG1(printk (KERN_DEBUG "Check for residuals,");)
- if( (bval & 0x1f) == 1 )
- {
- for(i=0; i < 0x100; i++)
- {
- bval = DC390_read8 (Current_Fifo);
- if( !(bval & 0x1f) )
- goto din_1;
- else if( i == 0x0ff )
- {
- residual = 1; /* ;1 residual byte */
- goto din_1;
- }
- }
- }
- else
- bval = DC390_read8 (Current_Fifo);
- }
-din_1:
- DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_BLAST_CMD);
- for (i = 0xa000; i; i--)
- {
- bval = DC390_read8 (DMA_Status);
- if (bval & BLAST_COMPLETE)
- break;
- }
- /* It seems a DMA Blast abort isn't that bad ... */
- if (!i) printk (KERN_ERR "DC390: DMA Blast aborted unfinished!\n");
- //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
- dc390_laststatus &= ~0xff000000; dc390_laststatus |= bval << 24;
-
- DEBUG1(printk (KERN_DEBUG "Blast: Read %li times DMA_Status %02x", 0xa000-i, bval);)
- ResidCnt = (ULONG) DC390_read8 (CtcReg_High);
- ResidCnt <<= 8;
- ResidCnt |= (ULONG) DC390_read8 (CtcReg_Mid);
- ResidCnt <<= 8;
- ResidCnt |= (ULONG) DC390_read8 (CtcReg_Low);
-
- xferCnt = pSRB->SGToBeXferLen - ResidCnt;
- pSRB->SGBusAddr += xferCnt;
- pSRB->TotalXferredLen += xferCnt;
- pSRB->SGToBeXferLen = ResidCnt;
-
- if( residual )
- {
- bval = DC390_read8 (ScsiFifo); /* get one residual byte */
- ptr = (PUCHAR) bus_to_virt( pSRB->SGBusAddr );
- *ptr = bval;
- pSRB->SGBusAddr++; xferCnt++;
- pSRB->TotalXferredLen++;
- pSRB->SGToBeXferLen--;
- }
- DEBUG1(printk (KERN_DEBUG "Xfered: %li, Total: %li, Remaining: %li\n", xferCnt,\
- pSRB->TotalXferredLen, pSRB->SGToBeXferLen);)
-
- }
- }
-}
-
-static void
-dc390_Command_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
-{
-}
-
-static void
-dc390_Status_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
-{
-
- pSRB->TargetStatus = DC390_read8 (ScsiFifo);
- //udelay (1);
- pSRB->EndMessage = DC390_read8 (ScsiFifo); /* get message */
-
- *psstatus = SCSI_NOP0;
- pSRB->SRBState = SRB_COMPLETED;
- DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);
+ *psstatus = SCSI_NOP0;
+ pSRB->SRBState = SRB_COMPLETED;
+ DC390_write8(ScsiCmd, MSG_ACCEPTED_CMD);
}
-static void
-dc390_MsgOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
+static void dc390_MsgOut_0(PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
- if( pSRB->SRBState & (SRB_UNEXPECT_RESEL+SRB_ABORT_SENT) )
- *psstatus = SCSI_NOP0;
- //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
+ if (pSRB->SRBState & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT))
+ *psstatus = SCSI_NOP0;
+ //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
}
static void __inline__
-dc390_reprog (PACB pACB, PDCB pDCB)
+ dc390_reprog(PACB pACB, PDCB pDCB)
{
- DC390_write8 (Sync_Period, pDCB->SyncPeriod);
- DC390_write8 (Sync_Offset, pDCB->SyncOffset);
- DC390_write8 (CtrlReg3, pDCB->CtrlR3);
- DC390_write8 (CtrlReg4, pDCB->CtrlR4);
- dc390_SetXferRate (pACB, pDCB);
+ DC390_write8(Sync_Period, pDCB->SyncPeriod);
+ DC390_write8(Sync_Offset, pDCB->SyncOffset);
+ DC390_write8(CtrlReg3, pDCB->CtrlR3);
+ DC390_write8(CtrlReg4, pDCB->CtrlR4);
+ dc390_SetXferRate(pACB, pDCB);
};
#ifdef DC390_DEBUG0
-static void
-dc390_printMsg (UCHAR *MsgBuf, UCHAR len)
+static void dc390_printMsg(UCHAR * MsgBuf, UCHAR len)
{
- int i;
- printk (" %02x", MsgBuf[0]);
- for (i = 1; i < len; i++)
- printk (" %02x", MsgBuf[i]);
- printk ("\n");
+ int i;
+ printk(" %02x", MsgBuf[0]);
+ for (i = 1; i < len; i++)
+ printk(" %02x", MsgBuf[i]);
+ printk("\n");
};
#endif
@@ -591,151 +565,147 @@
/* reject_msg */
static void __inline__
-dc390_MsgIn_reject (PACB pACB, PSRB pSRB)
+ dc390_MsgIn_reject(PACB pACB, PSRB pSRB)
{
- pSRB->MsgOutBuf[0] = MSG_REJECT_;
- pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
- DEBUG0 (printk (KERN_INFO "DC390: Reject message\n");)
+ pSRB->MsgOutBuf[0] = MSG_REJECT_;
+ pSRB->MsgCnt = 1;
+ DC390_ENABLE_MSGOUT;
+ DEBUG0(printk(KERN_INFO "DC390: Reject message\n");
+ )
}
/* abort command */
static void __inline__
-dc390_EnableMsgOut_Abort ( PACB pACB, PSRB pSRB )
+ dc390_EnableMsgOut_Abort(PACB pACB, PSRB pSRB)
{
- pSRB->MsgOutBuf[0] = MSG_ABORT;
- pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
- pSRB->pSRBDCB->DCBFlag &= ~ABORT_DEV_;
+ pSRB->MsgOutBuf[0] = MSG_ABORT;
+ pSRB->MsgCnt = 1;
+ DC390_ENABLE_MSGOUT;
+ pSRB->pSRBDCB->DCBFlag &= ~ABORT_DEV_;
}
static PSRB
-dc390_MsgIn_QTag (PACB pACB, PDCB pDCB, UCHAR tag)
+ dc390_MsgIn_QTag(PACB pACB, PDCB pDCB, UCHAR tag)
{
- PSRB lastSRB = pDCB->pGoingLast;
- PSRB pSRB = pDCB->pGoingSRB;
+ PSRB lastSRB = pDCB->pGoingLast;
+ PSRB pSRB = pDCB->pGoingSRB;
- if (pSRB)
- {
- for( ;pSRB ; )
- {
- if (pSRB->TagNumber == tag) break;
- if (pSRB == lastSRB) goto mingx0;
- pSRB = pSRB->pNextSRB;
- }
-
- if( pDCB->DCBFlag & ABORT_DEV_ )
- {
- pSRB->SRBState = SRB_ABORT_SENT;
- dc390_EnableMsgOut_Abort( pACB, pSRB );
- }
+ if (pSRB) {
+ for (; pSRB;) {
+ if (pSRB->TagNumber == tag)
+ break;
+ if (pSRB == lastSRB)
+ goto mingx0;
+ pSRB = pSRB->pNextSRB;
+ }
- if( !(pSRB->SRBState & SRB_DISCONNECT) )
- goto mingx0;
+ if (pDCB->DCBFlag & ABORT_DEV_) {
+ pSRB->SRBState = SRB_ABORT_SENT;
+ dc390_EnableMsgOut_Abort(pACB, pSRB);
+ }
+ if (!(pSRB->SRBState & SRB_DISCONNECT))
+ goto mingx0;
- pDCB->pActiveSRB = pSRB;
- pSRB->SRBState = SRB_DATA_XFER;
- }
- else
- {
- mingx0:
- pSRB = pACB->pTmpSRB;
- pSRB->SRBState = SRB_UNEXPECT_RESEL;
- pDCB->pActiveSRB = pSRB;
- pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;
- pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
- }
- return pSRB;
+ pDCB->pActiveSRB = pSRB;
+ pSRB->SRBState = SRB_DATA_XFER;
+ } else {
+ mingx0:
+ pSRB = pACB->pTmpSRB;
+ pSRB->SRBState = SRB_UNEXPECT_RESEL;
+ pDCB->pActiveSRB = pSRB;
+ pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;
+ pSRB->MsgCnt = 1;
+ DC390_ENABLE_MSGOUT;
+ }
+ return pSRB;
}
/* set async transfer mode */
-static void
-dc390_MsgIn_set_async (PACB pACB, PSRB pSRB)
+static void dc390_MsgIn_set_async(PACB pACB, PSRB pSRB)
{
- PDCB pDCB = pSRB->pSRBDCB;
- if (!(pSRB->SRBState & DO_SYNC_NEGO))
- printk ("DC390: Target %i initiates Non-Sync?\n", pDCB->UnitSCSIID);
- pSRB->SRBState &= ~DO_SYNC_NEGO;
- pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE);
- pDCB->SyncPeriod = 0;
- pDCB->SyncOffset = 0;
- //pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
- pDCB->CtrlR3 = FAST_CLK; /* fast clock / normal scsi */
- pDCB->CtrlR4 &= 0x3f;
- pDCB->CtrlR4 |= pACB->glitch_cfg; /* glitch eater */
- dc390_reprog (pACB, pDCB);
+ PDCB pDCB = pSRB->pSRBDCB;
+ if (!(pSRB->SRBState & DO_SYNC_NEGO))
+ printk("DC390: Target %i initiates Non-Sync?\n", pDCB->UnitSCSIID);
+ pSRB->SRBState &= ~DO_SYNC_NEGO;
+ pDCB->SyncMode &= ~(SYNC_ENABLE + SYNC_NEGO_DONE);
+ pDCB->SyncPeriod = 0;
+ pDCB->SyncOffset = 0;
+ //pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
+ pDCB->CtrlR3 = FAST_CLK; /* fast clock / normal scsi */
+ pDCB->CtrlR4 &= 0x3f;
+ pDCB->CtrlR4 |= pACB->glitch_cfg; /* glitch eater */
+ dc390_reprog(pACB, pDCB);
}
/* set sync transfer mode */
-static void
-dc390_MsgIn_set_sync (PACB pACB, PSRB pSRB)
+static void dc390_MsgIn_set_sync(PACB pACB, PSRB pSRB)
{
- UCHAR bval;
- USHORT wval, wval1;
- PDCB pDCB = pSRB->pSRBDCB;
- UCHAR oldsyncperiod = pDCB->SyncPeriod;
- UCHAR oldsyncoffset = pDCB->SyncOffset;
-
- if (!(pSRB->SRBState & DO_SYNC_NEGO))
- {
- printk ("DC390: Target %i initiates Sync: %ins %i ... answer ...\n",
- pDCB->UnitSCSIID, pSRB->MsgInBuf[3]<<2, pSRB->MsgInBuf[4]);
-
- /* reject */
- //dc390_MsgIn_reject (pACB, pSRB);
- //return dc390_MsgIn_set_async (pACB, pSRB);
-
- /* Reply with corrected SDTR Message */
- if (pSRB->MsgInBuf[4] > 15)
- {
- printk ("DC390: Lower Sync Offset to 15\n");
- pSRB->MsgInBuf[4] = 15;
- }
- if (pSRB->MsgInBuf[3] < pDCB->NegoPeriod)
- {
- printk ("DC390: Set sync nego period to %ins\n", pDCB->NegoPeriod << 2);
- pSRB->MsgInBuf[3] = pDCB->NegoPeriod;
+ UCHAR bval;
+ USHORT wval, wval1;
+ PDCB pDCB = pSRB->pSRBDCB;
+ UCHAR oldsyncperiod = pDCB->SyncPeriod;
+ UCHAR oldsyncoffset = pDCB->SyncOffset;
+
+ if (!(pSRB->SRBState & DO_SYNC_NEGO)) {
+ printk("DC390: Target %i initiates Sync: %ins %i ... answer ...\n",
+ pDCB->UnitSCSIID, pSRB->MsgInBuf[3] << 2, pSRB->MsgInBuf[4]);
+
+ /* reject */
+ //dc390_MsgIn_reject (pACB, pSRB);
+ //return dc390_MsgIn_set_async (pACB, pSRB);
+
+ /* Reply with corrected SDTR Message */
+ if (pSRB->MsgInBuf[4] > 15) {
+ printk("DC390: Lower Sync Offset to 15\n");
+ pSRB->MsgInBuf[4] = 15;
+ }
+ if (pSRB->MsgInBuf[3] < pDCB->NegoPeriod) {
+ printk("DC390: Set sync nego period to %ins\n", pDCB->NegoPeriod << 2);
+ pSRB->MsgInBuf[3] = pDCB->NegoPeriod;
+ };
+ memcpy(pSRB->MsgOutBuf, pSRB->MsgInBuf, 5);
+ pSRB->MsgCnt = 5;
+ DC390_ENABLE_MSGOUT;
};
- memcpy (pSRB->MsgOutBuf, pSRB->MsgInBuf, 5);
- pSRB->MsgCnt = 5;
- DC390_ENABLE_MSGOUT;
- };
-
- pSRB->SRBState &= ~DO_SYNC_NEGO;
- pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE;
- pDCB->SyncOffset &= 0x0f0;
- pDCB->SyncOffset |= pSRB->MsgInBuf[4];
- pDCB->NegoPeriod = pSRB->MsgInBuf[3];
-
- wval = (USHORT) pSRB->MsgInBuf[3];
- wval = wval << 2; wval -= 3; wval1 = wval / 25; /* compute speed */
- if( (wval1 * 25) != wval) wval1++;
- bval = FAST_CLK+FAST_SCSI; /* fast clock / fast scsi */
-
- pDCB->CtrlR4 &= 0x3f; /* Glitch eater: 12ns less than normal */
- if (pACB->glitch_cfg != NS_TO_GLITCH(0))
- pDCB->CtrlR4 |= NS_TO_GLITCH(((GLITCH_TO_NS(pACB->glitch_cfg)) - 1));
- else
- pDCB->CtrlR4 |= NS_TO_GLITCH(0);
- if (wval1 < 4) pDCB->CtrlR4 |= NS_TO_GLITCH(0); /* Ultra */
-
- if (wval1 >= 8)
- {
- wval1--; /* Timing computation differs by 1 from FAST_SCSI */
- bval = FAST_CLK; /* fast clock / normal scsi */
- pDCB->CtrlR4 |= pACB->glitch_cfg; /* glitch eater */
- }
-
- pDCB->CtrlR3 = bval;
- pDCB->SyncPeriod = (UCHAR)wval1;
-
- if ((oldsyncperiod != wval1 || oldsyncoffset != pDCB->SyncOffset) && pDCB->UnitSCSILUN == 0)
- {
- if (! (bval & FAST_SCSI)) wval1++;
- printk ("DC390: Target %i: Sync transfer %i.%1i MHz, Offset %i\n", pDCB->UnitSCSIID,
- 40/wval1, ((40%wval1)*10+wval1/2)/wval1, pDCB->SyncOffset & 0x0f);
- }
-
- dc390_reprog (pACB, pDCB);
+
+ pSRB->SRBState &= ~DO_SYNC_NEGO;
+ pDCB->SyncMode |= SYNC_ENABLE + SYNC_NEGO_DONE;
+ pDCB->SyncOffset &= 0x0f0;
+ pDCB->SyncOffset |= pSRB->MsgInBuf[4];
+ pDCB->NegoPeriod = pSRB->MsgInBuf[3];
+
+ wval = (USHORT) pSRB->MsgInBuf[3];
+ wval = wval << 2;
+ wval -= 3;
+ wval1 = wval / 25; /* compute speed */
+ if ((wval1 * 25) != wval)
+ wval1++;
+ bval = FAST_CLK + FAST_SCSI; /* fast clock / fast scsi */
+
+ pDCB->CtrlR4 &= 0x3f; /* Glitch eater: 12ns less than normal */
+ if (pACB->glitch_cfg != NS_TO_GLITCH(0))
+ pDCB->CtrlR4 |= NS_TO_GLITCH(((GLITCH_TO_NS(pACB->glitch_cfg)) - 1));
+ else
+ pDCB->CtrlR4 |= NS_TO_GLITCH(0);
+ if (wval1 < 4)
+ pDCB->CtrlR4 |= NS_TO_GLITCH(0); /* Ultra */
+
+ if (wval1 >= 8) {
+ wval1--; /* Timing computation differs by 1 from FAST_SCSI */
+ bval = FAST_CLK; /* fast clock / normal scsi */
+ pDCB->CtrlR4 |= pACB->glitch_cfg; /* glitch eater */
+ }
+ pDCB->CtrlR3 = bval;
+ pDCB->SyncPeriod = (UCHAR) wval1;
+
+ if ((oldsyncperiod != wval1 || oldsyncoffset != pDCB->SyncOffset) && pDCB->UnitSCSILUN == 0) {
+ if (!(bval & FAST_SCSI))
+ wval1++;
+ printk("DC390: Target %i: Sync transfer %i.%1i MHz, Offset %i\n", pDCB->UnitSCSIID,
+ 40 / wval1, ((40 % wval1) * 10 + wval1 / 2) / wval1, pDCB->SyncOffset & 0x0f);
+ }
+ dc390_reprog(pACB, pDCB);
};
@@ -749,969 +719,890 @@
/* Check if the message is complete */
static UCHAR __inline__
-dc390_MsgIn_complete (UCHAR *msgbuf, ULONG len)
-{
- if (*msgbuf == MSG_EXTENDED)
- {
- if (len < 2) return 0;
- if (len < msgbuf[1] + 2) return 0;
- }
- else if (*msgbuf >= 0x20 && *msgbuf <= 0x2f) // two byte messages
- if (len < 2) return 0;
- return 1;
+ dc390_MsgIn_complete(UCHAR * msgbuf, ULONG len)
+{
+ if (*msgbuf == MSG_EXTENDED) {
+ if (len < 2)
+ return 0;
+ if (len < msgbuf[1] + 2)
+ return 0;
+ } else if (*msgbuf >= 0x20 && *msgbuf <= 0x2f) // two byte messages
+
+ if (len < 2)
+ return 0;
+ return 1;
}
/* read and eval received messages */
-void
-dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
+void dc390_MsgIn_0(PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
- PDCB pDCB = pACB->pActiveDCB;
+ PDCB pDCB = pACB->pActiveDCB;
- /* Read the msg */
+ /* Read the msg */
- pSRB->MsgInBuf[pACB->MsgLen++] = DC390_read8 (ScsiFifo);
- //pSRB->SRBState = 0;
-
- /* Msg complete ? */
- if (dc390_MsgIn_complete (pSRB->MsgInBuf, pACB->MsgLen))
- {
- DEBUG0 (printk (KERN_INFO "DC390: MsgIn:"); dc390_printMsg (pSRB->MsgInBuf, pACB->MsgLen);)
- /* Now eval the msg */
- switch (pSRB->MsgInBuf[0])
- {
- case MSG_DISCONNECT:
- pSRB->SRBState = SRB_DISCONNECT; break;
-
- case MSG_SIMPLE_QTAG:
- case MSG_HEAD_QTAG:
- case MSG_ORDER_QTAG:
- pSRB = dc390_MsgIn_QTag (pACB, pDCB, pSRB->MsgInBuf[1]);
- break;
-
- case MSG_REJECT_:
- DC390_write8 (ScsiCmd, RESET_ATN_CMD);
- pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
- if( pSRB->SRBState & DO_SYNC_NEGO)
- dc390_MsgIn_set_async (pACB, pSRB);
- break;
-
- case MSG_EXTENDED:
- /* reject every extended msg but SDTR */
- if (pSRB->MsgInBuf[1] != 3 || pSRB->MsgInBuf[2] != EXTENDED_SDTR)
- dc390_MsgIn_reject (pACB, pSRB);
- else
- {
- if (pSRB->MsgInBuf[3] == 0 || pSRB->MsgInBuf[4] == 0)
- dc390_MsgIn_set_async (pACB, pSRB);
- else
- dc390_MsgIn_set_sync (pACB, pSRB);
- };
-
- // nothing has to be done
- case MSG_COMPLETE: break;
-
- // SAVE POINTER my be ignored as we have the PSRB associated with the
- // scsi command. Thanks, Gerard, for pointing it out.
- case MSG_SAVE_PTR: break;
- // The device might want to restart transfer with a RESTORE
- case MSG_RESTORE_PTR:
- printk ("DC390: RESTORE POINTER message received ... reject\n");
- // fall through
-
- // reject unknown messages
- default: dc390_MsgIn_reject (pACB, pSRB);
- }
-
- /* Clear counter and MsgIn state */
- pSRB->SRBState &= ~SRB_MSGIN;
- pACB->MsgLen = 0;
- };
+ pSRB->MsgInBuf[pACB->MsgLen++] = DC390_read8(ScsiFifo);
+ //pSRB->SRBState = 0;
- *psstatus = SCSI_NOP0;
- DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);
- //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
+ /* Msg complete ? */
+ if (dc390_MsgIn_complete(pSRB->MsgInBuf, pACB->MsgLen)) {
+ DEBUG0(printk(KERN_INFO "DC390: MsgIn:");
+ dc390_printMsg(pSRB->MsgInBuf, pACB->MsgLen);
+ )
+ /* Now eval the msg */
+ switch (pSRB->MsgInBuf[0]) {
+ case MSG_DISCONNECT:
+ pSRB->SRBState = SRB_DISCONNECT;
+ break;
+
+ case MSG_SIMPLE_QTAG:
+ case MSG_HEAD_QTAG:
+ case MSG_ORDER_QTAG:
+ pSRB = dc390_MsgIn_QTag(pACB, pDCB, pSRB->MsgInBuf[1]);
+ break;
+
+ case MSG_REJECT_:
+ DC390_write8(ScsiCmd, RESET_ATN_CMD);
+ pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
+ if (pSRB->SRBState & DO_SYNC_NEGO)
+ dc390_MsgIn_set_async(pACB, pSRB);
+ break;
+
+ case MSG_EXTENDED:
+ /* reject every extended msg but SDTR */
+ if (pSRB->MsgInBuf[1] != 3 || pSRB->MsgInBuf[2] != EXTENDED_SDTR)
+ dc390_MsgIn_reject(pACB, pSRB);
+ else {
+ if (pSRB->MsgInBuf[3] == 0 || pSRB->MsgInBuf[4] == 0)
+ dc390_MsgIn_set_async(pACB, pSRB);
+ else
+ dc390_MsgIn_set_sync(pACB, pSRB);
+ };
+
+ // nothing has to be done
+ case MSG_COMPLETE:
+ break;
+
+ // SAVE POINTER my be ignored as we have the PSRB associated with the
+ // scsi command. Thanks, Gerard, for pointing it out.
+ case MSG_SAVE_PTR:
+ break;
+ // The device might want to restart transfer with a RESTORE
+ case MSG_RESTORE_PTR:
+ printk("DC390: RESTORE POINTER message received ... reject\n");
+ // fall through
+
+ // reject unknown messages
+ default:
+ dc390_MsgIn_reject(pACB, pSRB);
+ }
+
+ /* Clear counter and MsgIn state */
+ pSRB->SRBState &= ~SRB_MSGIN;
+ pACB->MsgLen = 0;
+ };
+
+ *psstatus = SCSI_NOP0;
+ DC390_write8(ScsiCmd, MSG_ACCEPTED_CMD);
+ //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
}
-void
-dc390_DataIO_Comm( PACB pACB, PSRB pSRB, UCHAR ioDir)
+void dc390_DataIO_Comm(PACB pACB, PSRB pSRB, UCHAR ioDir)
{
- PSGL psgl;
- ULONG lval;
+ PSGL psgl;
+ ULONG lval;
- if( pSRB->SGIndex < pSRB->SGcount )
- {
- DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir /* | DMA_INT */);
- if( !pSRB->SGToBeXferLen )
- {
- psgl = pSRB->pSegmentList;
- pSRB->SGBusAddr = virt_to_bus( psgl->address );
- pSRB->SGToBeXferLen = (ULONG) psgl->length;
- DEBUG1(printk (KERN_DEBUG " DC390: Next SG segment.");)
- }
- lval = pSRB->SGToBeXferLen;
- DEBUG1(printk (KERN_DEBUG " DC390: Transfer %li bytes (address %08lx)\n", lval, pSRB->SGBusAddr);)
- DC390_write8 (CtcReg_Low, (UCHAR) lval);
- lval >>= 8;
- DC390_write8 (CtcReg_Mid, (UCHAR) lval);
- lval >>= 8;
- DC390_write8 (CtcReg_High, (UCHAR) lval);
-
- DC390_write32 (DMA_XferCnt, pSRB->SGToBeXferLen);
- DC390_write32 (DMA_XferAddr, pSRB->SGBusAddr);
-
- //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); /* | DMA_INT; */
- pSRB->SRBState = SRB_DATA_XFER;
-
- DC390_write8 (ScsiCmd, DMA_COMMAND+INFO_XFER_CMD);
-
- DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
- //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);)
- //DEBUG1(printk (KERN_DEBUG "DC390: DMA_Status: %02x\n", DC390_read8 (DMA_Status));)
- //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);)
- }
- else /* xfer pad */
- {
- if( pSRB->SGcount )
- {
- pSRB->AdaptStatus = H_OVER_UNDER_RUN;
- pSRB->SRBStatus |= OVER_RUN;
- DEBUG0(printk (KERN_WARNING " DC390: Overrun -");)
- }
- DEBUG0(printk (KERN_WARNING " Clear transfer pad \n");)
- DC390_write8 (CtcReg_Low, 0);
- DC390_write8 (CtcReg_Mid, 0);
- DC390_write8 (CtcReg_High, 0);
+ if (pSRB->SGIndex < pSRB->SGcount) {
+ DC390_write8(DMA_Cmd, DMA_IDLE_CMD | ioDir /* | DMA_INT */ );
+ if (!pSRB->SGToBeXferLen) {
+ psgl = pSRB->pSegmentList;
+ pSRB->SGBusAddr = virt_to_bus(psgl->address);
+ pSRB->SGToBeXferLen = (ULONG) psgl->length;
+ DEBUG1(printk(KERN_DEBUG " DC390: Next SG segment.");
+ )
+ }
+ lval = pSRB->SGToBeXferLen;
+ DEBUG1(printk(KERN_DEBUG " DC390: Transfer %li bytes (address %08lx)\n", lval, pSRB->SGBusAddr);
+ )
+ DC390_write8(CtcReg_Low, (UCHAR) lval);
+ lval >>= 8;
+ DC390_write8(CtcReg_Mid, (UCHAR) lval);
+ lval >>= 8;
+ DC390_write8(CtcReg_High, (UCHAR) lval);
+
+ DC390_write32(DMA_XferCnt, pSRB->SGToBeXferLen);
+ DC390_write32(DMA_XferAddr, pSRB->SGBusAddr);
+
+ //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); /* | DMA_INT; */
+ pSRB->SRBState = SRB_DATA_XFER;
+
+ DC390_write8(ScsiCmd, DMA_COMMAND + INFO_XFER_CMD);
+
+ DC390_write8(DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
+ //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);)
+ //DEBUG1(printk (KERN_DEBUG "DC390: DMA_Status: %02x\n", DC390_read8 (DMA_Status));)
+ //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);)
+ } else { /* xfer pad */
+ if (pSRB->SGcount) {
+ pSRB->AdaptStatus = H_OVER_UNDER_RUN;
+ pSRB->SRBStatus |= OVER_RUN;
+ DEBUG0(printk(KERN_WARNING " DC390: Overrun -");
+ )
+ }
+ DEBUG0(printk(KERN_WARNING " Clear transfer pad \n");
+ )
+ DC390_write8(CtcReg_Low, 0);
+ DC390_write8(CtcReg_Mid, 0);
+ DC390_write8(CtcReg_High, 0);
- pSRB->SRBState |= SRB_XFERPAD;
- DC390_write8 (ScsiCmd, DMA_COMMAND+XFER_PAD_BYTE);
+ pSRB->SRBState |= SRB_XFERPAD;
+ DC390_write8(ScsiCmd, DMA_COMMAND + XFER_PAD_BYTE);
/*
- DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); // | DMA_INT;
- DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
-*/
- }
+ DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); // | DMA_INT;
+ DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
+ */
+ }
}
-static void
-dc390_DataOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
+static void dc390_DataOutPhase(PACB pACB, PSRB pSRB, PUCHAR psstatus)
+{
+ dc390_DataIO_Comm(pACB, pSRB, WRITE_DIRECTION);
+}
+
+static void dc390_DataInPhase(PACB pACB, PSRB pSRB, PUCHAR psstatus)
+{
+ dc390_DataIO_Comm(pACB, pSRB, READ_DIRECTION);
+}
+
+void dc390_CommandPhase(PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
- dc390_DataIO_Comm (pACB, pSRB, WRITE_DIRECTION);
+ PDCB pDCB;
+ UCHAR i, cnt;
+ PUCHAR ptr;
+
+ DC390_write8(ScsiCmd, RESET_ATN_CMD);
+ DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
+ if (!(pSRB->SRBFlag & AUTO_REQSENSE)) {
+ cnt = (UCHAR) pSRB->ScsiCmdLen;
+ ptr = (PUCHAR) pSRB->CmdBlock;
+ for (i = 0; i < cnt; i++)
+ DC390_write8(ScsiFifo, *(ptr++));
+ } else {
+ UCHAR bval = 0;
+ DC390_write8(ScsiFifo, REQUEST_SENSE);
+ pDCB = pACB->pActiveDCB;
+ DC390_write8(ScsiFifo, pDCB->IdentifyMsg << 5);
+ DC390_write8(ScsiFifo, bval);
+ DC390_write8(ScsiFifo, bval);
+ DC390_write8(ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
+ DC390_write8(ScsiFifo, bval);
+ }
+ pSRB->SRBState = SRB_COMMAND;
+ DC390_write8(ScsiCmd, INFO_XFER_CMD);
}
-static void
-dc390_DataInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
+static void dc390_StatusPhase(PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
- dc390_DataIO_Comm (pACB, pSRB, READ_DIRECTION);
+ DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
+ pSRB->SRBState = SRB_STATUS;
+ DC390_write8(ScsiCmd, INITIATOR_CMD_CMPLTE);
+ //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
}
-void
-dc390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
+void dc390_MsgOutPhase(PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
- PDCB pDCB;
- UCHAR i, cnt;
- PUCHAR ptr;
+ UCHAR bval, i, cnt;
+ PUCHAR ptr;
+ PDCB pDCB;
- DC390_write8 (ScsiCmd, RESET_ATN_CMD);
- DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
- if( !(pSRB->SRBFlag & AUTO_REQSENSE) )
- {
- cnt = (UCHAR) pSRB->ScsiCmdLen;
- ptr = (PUCHAR) pSRB->CmdBlock;
- for(i=0; i < cnt; i++)
- DC390_write8 (ScsiFifo, *(ptr++));
- }
- else
- {
- UCHAR bval = 0;
- DC390_write8 (ScsiFifo, REQUEST_SENSE);
+ DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
pDCB = pACB->pActiveDCB;
- DC390_write8 (ScsiFifo, pDCB->IdentifyMsg << 5);
- DC390_write8 (ScsiFifo, bval);
- DC390_write8 (ScsiFifo, bval);
- DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
- DC390_write8 (ScsiFifo, bval);
- }
- pSRB->SRBState = SRB_COMMAND;
- DC390_write8 (ScsiCmd, INFO_XFER_CMD);
-}
-
-static void
-dc390_StatusPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
-{
- DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
- pSRB->SRBState = SRB_STATUS;
- DC390_write8 (ScsiCmd, INITIATOR_CMD_CMPLTE);
- //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
-}
-
-void
-dc390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
-{
- UCHAR bval, i, cnt;
- PUCHAR ptr;
- PDCB pDCB;
-
- DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
- pDCB = pACB->pActiveDCB;
- if( !(pSRB->SRBState & SRB_MSGOUT) )
- {
- cnt = pSRB->MsgCnt;
- if( cnt )
- {
- ptr = (PUCHAR) pSRB->MsgOutBuf;
- for(i=0; i < cnt; i++)
- DC390_write8 (ScsiFifo, *(ptr++));
- pSRB->MsgCnt = 0;
- if( (pDCB->DCBFlag & ABORT_DEV_) &&
- (pSRB->MsgOutBuf[0] == MSG_ABORT) )
- pSRB->SRBState = SRB_ABORT_SENT;
+ if (!(pSRB->SRBState & SRB_MSGOUT)) {
+ cnt = pSRB->MsgCnt;
+ if (cnt) {
+ ptr = (PUCHAR) pSRB->MsgOutBuf;
+ for (i = 0; i < cnt; i++)
+ DC390_write8(ScsiFifo, *(ptr++));
+ pSRB->MsgCnt = 0;
+ if ((pDCB->DCBFlag & ABORT_DEV_) &&
+ (pSRB->MsgOutBuf[0] == MSG_ABORT))
+ pSRB->SRBState = SRB_ABORT_SENT;
+ } else {
+ bval = MSG_ABORT; /* ??? MSG_NOP */
+ if ((pSRB->CmdBlock[0] == INQUIRY) ||
+ (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
+ (pSRB->SRBFlag & AUTO_REQSENSE)) {
+ if (pDCB->SyncMode & SYNC_ENABLE)
+ goto mop1;
+ }
+ DC390_write8(ScsiFifo, bval);
+ }
+ DC390_write8(ScsiCmd, INFO_XFER_CMD);
+ } else {
+ mop1:
+ //printk ("DC390: Send SDTR message to %i %i ... \n", pDCB->UnitSCSIID, pDCB->UnitSCSILUN);
+ DC390_write8(ScsiFifo, MSG_EXTENDED);
+ DC390_write8(ScsiFifo, 3); /* ;length of extended msg */
+ DC390_write8(ScsiFifo, EXTENDED_SDTR); /* ; sync nego */
+ DC390_write8(ScsiFifo, pDCB->NegoPeriod);
+ if (pDCB->SyncOffset & 0x0f)
+ DC390_write8(ScsiFifo, pDCB->SyncOffset);
+ else
+ DC390_write8(ScsiFifo, SYNC_NEGO_OFFSET);
+ pSRB->SRBState |= DO_SYNC_NEGO;
+ DC390_write8(ScsiCmd, INFO_XFER_CMD);
}
- else
- {
- bval = MSG_ABORT; /* ??? MSG_NOP */
- if( (pSRB->CmdBlock[0] == INQUIRY ) ||
- (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
- (pSRB->SRBFlag & AUTO_REQSENSE) )
- {
- if( pDCB->SyncMode & SYNC_ENABLE )
- goto mop1;
- }
- DC390_write8 (ScsiFifo, bval);
- }
- DC390_write8 (ScsiCmd, INFO_XFER_CMD);
- }
- else
- {
-mop1:
- //printk ("DC390: Send SDTR message to %i %i ... \n", pDCB->UnitSCSIID, pDCB->UnitSCSILUN);
- DC390_write8 (ScsiFifo, MSG_EXTENDED);
- DC390_write8 (ScsiFifo, 3); /* ;length of extended msg */
- DC390_write8 (ScsiFifo, EXTENDED_SDTR); /* ; sync nego */
- DC390_write8 (ScsiFifo, pDCB->NegoPeriod);
- if (pDCB->SyncOffset & 0x0f)
- DC390_write8 (ScsiFifo, pDCB->SyncOffset);
- else
- DC390_write8 (ScsiFifo, SYNC_NEGO_OFFSET);
- pSRB->SRBState |= DO_SYNC_NEGO;
- DC390_write8 (ScsiCmd, INFO_XFER_CMD);
- }
}
-static void
-dc390_MsgInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
+static void dc390_MsgInPhase(PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
- DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
- if( !(pSRB->SRBState & SRB_MSGIN) )
- {
- pSRB->SRBState &= ~SRB_DISCONNECT;
- pSRB->SRBState |= SRB_MSGIN;
- }
- DC390_write8 (ScsiCmd, INFO_XFER_CMD);
- //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
+ DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
+ if (!(pSRB->SRBState & SRB_MSGIN)) {
+ pSRB->SRBState &= ~SRB_DISCONNECT;
+ pSRB->SRBState |= SRB_MSGIN;
+ }
+ DC390_write8(ScsiCmd, INFO_XFER_CMD);
+ //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
}
-static void
-dc390_Nop_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
+static void dc390_Nop_0(PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
}
-static void
-dc390_Nop_1( PACB pACB, PSRB pSRB, PUCHAR psstatus)
+static void dc390_Nop_1(PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
}
-static void
-dc390_SetXferRate( PACB pACB, PDCB pDCB )
+static void dc390_SetXferRate(PACB pACB, PDCB pDCB)
{
- UCHAR bval, i, cnt;
- PDCB ptr;
+ UCHAR bval, i, cnt;
+ PDCB ptr;
- if( !(pDCB->IdentifyMsg & 0x07) )
- {
- if( pACB->scan_devices )
- {
- dc390_CurrSyncOffset = pDCB->SyncOffset;
+ if (!(pDCB->IdentifyMsg & 0x07)) {
+ if (pACB->scan_devices) {
+ dc390_CurrSyncOffset = pDCB->SyncOffset;
+ } else {
+ ptr = pACB->pLinkDCB;
+ cnt = pACB->DCBCnt;
+ bval = pDCB->UnitSCSIID;
+ for (i = 0; i < cnt; i++) {
+ if (ptr->UnitSCSIID == bval) {
+ ptr->SyncPeriod = pDCB->SyncPeriod;
+ ptr->SyncOffset = pDCB->SyncOffset;
+ ptr->CtrlR3 = pDCB->CtrlR3;
+ ptr->CtrlR4 = pDCB->CtrlR4;
+ ptr->SyncMode = pDCB->SyncMode;
+ }
+ ptr = ptr->pNextDCB;
+ }
+ }
}
- else
- {
- ptr = pACB->pLinkDCB;
- cnt = pACB->DCBCnt;
- bval = pDCB->UnitSCSIID;
- for(i=0; i<cnt; i++)
- {
- if( ptr->UnitSCSIID == bval )
- {
- ptr->SyncPeriod = pDCB->SyncPeriod;
- ptr->SyncOffset = pDCB->SyncOffset;
- ptr->CtrlR3 = pDCB->CtrlR3;
- ptr->CtrlR4 = pDCB->CtrlR4;
- ptr->SyncMode = pDCB->SyncMode;
- }
- ptr = ptr->pNextDCB;
- }
- }
- }
- return;
+ return;
}
-void
-dc390_Disconnect( PACB pACB )
-{
- PDCB pDCB;
- PSRB pSRB, psrb;
- UCHAR i, cnt;
-
- DEBUG0(printk(KERN_INFO "DISC,");)
-
- pDCB = pACB->pActiveDCB;
- if (!pDCB)
- {
- int j = 400;
- DEBUG0(printk(KERN_WARNING "ACB:%08lx->ActiveDCB:%08lx IOPort:%04x IRQ:%02x !\n",\
- (ULONG)pACB,(ULONG)pDCB,pACB->IOPortBase,pACB->IRQLevel);)
- while (--j) udelay (1000);
- DC390_read8 (INT_Status); /* Reset Pending INT */
- DC390_write8 (ScsiCmd, EN_SEL_RESEL);
- return;
- }
- pSRB = pDCB->pActiveSRB;
- pACB->pActiveDCB = 0;
- pSRB->ScsiPhase = SCSI_NOP0;
- DC390_write8 (ScsiCmd, EN_SEL_RESEL);
- if( pSRB->SRBState & SRB_UNEXPECT_RESEL )
- {
- pSRB->SRBState = 0;
- dc390_DoWaitingSRB( pACB );
- }
- else if( pSRB->SRBState & SRB_ABORT_SENT )
- {
- pDCB->TagMask = 0;
- pDCB->DCBFlag = 0;
- cnt = pDCB->GoingSRBCnt;
- pDCB->GoingSRBCnt = 0;
- pSRB = pDCB->pGoingSRB;
- for( i=0; i < cnt; i++)
- {
- psrb = pSRB->pNextSRB;
- pSRB->pNextSRB = pACB->pFreeSRB;
- pACB->pFreeSRB = pSRB;
- pSRB = psrb;
- }
- pDCB->pGoingSRB = 0;
- dc390_DoWaitingSRB( pACB );
- }
- else
- {
- if( (pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) ||
- !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED)) )
- { /* Selection time out */
- if( !(pACB->scan_devices) )
- {
- pSRB->SRBState = SRB_READY;
- dc390_RewaitSRB( pDCB, pSRB);
- }
- else
- {
- pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT;
- goto disc1;
- }
+void dc390_Disconnect(PACB pACB)
+{
+ PDCB pDCB;
+ PSRB pSRB, psrb;
+ UCHAR i, cnt;
+
+ DEBUG0(printk(KERN_INFO "DISC,");
+ )
+ pDCB = pACB->pActiveDCB;
+ if (!pDCB) {
+ int j = 400;
+ DEBUG0(printk(KERN_WARNING "ACB:%08lx->ActiveDCB:%08lx IOPort:%04x IRQ:%02x !\n", \
+ (ULONG) pACB, (ULONG) pDCB, pACB->IOPortBase, pACB->IRQLevel);
+ )
+ while (--j)
+ udelay(1000);
+ DC390_read8(INT_Status); /* Reset Pending INT */
+ DC390_write8(ScsiCmd, EN_SEL_RESEL);
+ return;
}
- else if( pSRB->SRBState & SRB_DISCONNECT )
- {
- dc390_DoWaitingSRB( pACB );
+ pSRB = pDCB->pActiveSRB;
+ pACB->pActiveDCB = 0;
+ pSRB->ScsiPhase = SCSI_NOP0;
+ DC390_write8(ScsiCmd, EN_SEL_RESEL);
+ if (pSRB->SRBState & SRB_UNEXPECT_RESEL) {
+ pSRB->SRBState = 0;
+ dc390_DoWaitingSRB(pACB);
+ } else if (pSRB->SRBState & SRB_ABORT_SENT) {
+ pDCB->TagMask = 0;
+ pDCB->DCBFlag = 0;
+ cnt = pDCB->GoingSRBCnt;
+ pDCB->GoingSRBCnt = 0;
+ pSRB = pDCB->pGoingSRB;
+ for (i = 0; i < cnt; i++) {
+ psrb = pSRB->pNextSRB;
+ pSRB->pNextSRB = pACB->pFreeSRB;
+ pACB->pFreeSRB = pSRB;
+ pSRB = psrb;
+ }
+ pDCB->pGoingSRB = 0;
+ dc390_DoWaitingSRB(pACB);
+ } else {
+ if ((pSRB->SRBState & (SRB_START_ + SRB_MSGOUT)) ||
+ !(pSRB->SRBState & (SRB_DISCONNECT + SRB_COMPLETED))) { /* Selection time out */
+ if (!(pACB->scan_devices)) {
+ pSRB->SRBState = SRB_READY;
+ dc390_RewaitSRB(pDCB, pSRB);
+ } else {
+ pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT;
+ goto disc1;
+ }
+ } else if (pSRB->SRBState & SRB_DISCONNECT) {
+ dc390_DoWaitingSRB(pACB);
+ } else if (pSRB->SRBState & SRB_COMPLETED) {
+ disc1:
+ if (pDCB->MaxCommand > 1) {
+ pDCB->TagMask &= (~(1 << pSRB->TagNumber)); /* free tag mask */
+ }
+ pDCB->pActiveSRB = 0;
+ pSRB->SRBState = SRB_FREE;
+ dc390_SRBdone(pACB, pDCB, pSRB);
+ }
}
- else if( pSRB->SRBState & SRB_COMPLETED )
- {
-disc1:
- if(pDCB->MaxCommand > 1)
- {
- pDCB->TagMask &= (~(1 << pSRB->TagNumber)); /* free tag mask */
- }
- pDCB->pActiveSRB = 0;
- pSRB->SRBState = SRB_FREE;
- dc390_SRBdone( pACB, pDCB, pSRB);
- }
- }
- pACB->MsgLen = 0;
+ pACB->MsgLen = 0;
}
-void
-dc390_Reselect( PACB pACB )
-{
- PDCB pDCB;
- PSRB pSRB;
- USHORT wval;
- UCHAR bval;
-
- DEBUG0(printk(KERN_INFO "RSEL,");)
- pDCB = pACB->pActiveDCB;
- if( pDCB )
- { /* Arbitration lost but Reselection won */
- DEBUG0(printk ("(ActiveDCB != 0)");)
- pSRB = pDCB->pActiveSRB;
- if( !( pACB->scan_devices ) )
- {
- pSRB->SRBState = SRB_READY;
- dc390_RewaitSRB( pDCB, pSRB);
+void dc390_Reselect(PACB pACB)
+{
+ PDCB pDCB;
+ PSRB pSRB;
+ USHORT wval;
+ UCHAR bval;
+
+ DEBUG0(printk(KERN_INFO "RSEL,");
+ )
+ pDCB = pACB->pActiveDCB;
+ if (pDCB) { /* Arbitration lost but Reselection won */
+ DEBUG0(printk("(ActiveDCB != 0)");
+ )
+ pSRB = pDCB->pActiveSRB;
+ if (!(pACB->scan_devices)) {
+ pSRB->SRBState = SRB_READY;
+ dc390_RewaitSRB(pDCB, pSRB);
+ }
}
- }
- bval = DC390_read8 (ScsiFifo); /* get ID */
- DEBUG0(printk ("Dev %02x,", bval);)
- bval ^= 1 << pACB->pScsiHost->this_id; /* Mask AdapterID */
- wval = 0;
- while (bval >>= 1) wval++;
- wval |= ( (USHORT) DC390_read8 (ScsiFifo) & 7) << 8; /* get LUN */
- DEBUG0(printk ("(ID %02x, LUN %02x),", wval & 0xff, (wval & 0xff00) >> 8);)
- pDCB = pACB->pLinkDCB;
- while( wval != *((PUSHORT) &pDCB->UnitSCSIID) )
- {
- pDCB = pDCB->pNextDCB;
- if( pDCB == pACB->pLinkDCB )
- {
- printk (KERN_ERR "DC390: Reselect from non existing device (ID %02x, LUN %02x)\n",
- wval & 0xff, (wval & 0xff00) >> 8);
- return;
- }
- }
- pACB->pActiveDCB = pDCB;
- if( pDCB->SyncMode & EN_TAG_QUEUEING )
- {
- pSRB = pACB->pTmpSRB; /* ?? */
- pDCB->pActiveSRB = pSRB;
- }
- else
- {
- pSRB = pDCB->pActiveSRB;
- if( !pSRB || !(pSRB->SRBState & SRB_DISCONNECT) )
- {
- pSRB= pACB->pTmpSRB;
- pSRB->SRBState = SRB_UNEXPECT_RESEL;
- printk (KERN_ERR "DC390: Reselect without outstanding cmnd (ID %02x, LUN %02x)\n",
- wval & 0xff, (wval & 0xff00) >> 8);
- pDCB->pActiveSRB = pSRB;
- dc390_EnableMsgOut_Abort ( pACB, pSRB );
+ bval = DC390_read8(ScsiFifo); /* get ID */
+ DEBUG0(printk("Dev %02x,", bval);
+ )
+ bval ^= 1 << pACB->pScsiHost->this_id; /* Mask AdapterID */
+ wval = 0;
+ while (bval >>= 1)
+ wval++;
+ wval |= ((USHORT) DC390_read8(ScsiFifo) & 7) << 8; /* get LUN */
+ DEBUG0(printk("(ID %02x, LUN %02x),", wval & 0xff, (wval & 0xff00) >> 8);
+ )
+ pDCB = pACB->pLinkDCB;
+ while (wval != *((PUSHORT) & pDCB->UnitSCSIID)) {
+ pDCB = pDCB->pNextDCB;
+ if (pDCB == pACB->pLinkDCB) {
+ printk(KERN_ERR "DC390: Reselect from non existing device (ID %02x, LUN %02x)\n",
+ wval & 0xff, (wval & 0xff00) >> 8);
+ return;
+ }
}
- else
- {
- if( pDCB->DCBFlag & ABORT_DEV_ )
- {
- pSRB->SRBState = SRB_ABORT_SENT;
- printk (KERN_INFO "DC390: Reselect: Abort (ID %02x, LUN %02x)\n",
- wval & 0xff, (wval & 0xff00) >> 8);
- dc390_EnableMsgOut_Abort( pACB, pSRB );
- }
- else
- pSRB->SRBState = SRB_DATA_XFER;
+ pACB->pActiveDCB = pDCB;
+ if (pDCB->SyncMode & EN_TAG_QUEUEING) {
+ pSRB = pACB->pTmpSRB; /* ?? */
+ pDCB->pActiveSRB = pSRB;
+ } else {
+ pSRB = pDCB->pActiveSRB;
+ if (!pSRB || !(pSRB->SRBState & SRB_DISCONNECT)) {
+ pSRB = pACB->pTmpSRB;
+ pSRB->SRBState = SRB_UNEXPECT_RESEL;
+ printk(KERN_ERR "DC390: Reselect without outstanding cmnd (ID %02x, LUN %02x)\n",
+ wval & 0xff, (wval & 0xff00) >> 8);
+ pDCB->pActiveSRB = pSRB;
+ dc390_EnableMsgOut_Abort(pACB, pSRB);
+ } else {
+ if (pDCB->DCBFlag & ABORT_DEV_) {
+ pSRB->SRBState = SRB_ABORT_SENT;
+ printk(KERN_INFO "DC390: Reselect: Abort (ID %02x, LUN %02x)\n",
+ wval & 0xff, (wval & 0xff00) >> 8);
+ dc390_EnableMsgOut_Abort(pACB, pSRB);
+ } else
+ pSRB->SRBState = SRB_DATA_XFER;
+ }
}
- }
- DEBUG1(printk (KERN_DEBUG "Resel SRB(%p): TagNum (%02x)\n", pSRB, pSRB->TagNumber);)
- pSRB->ScsiPhase = SCSI_NOP0;
- DC390_write8 (Scsi_Dest_ID, pDCB->UnitSCSIID);
- DC390_write8 (Sync_Period, pDCB->SyncPeriod);
- DC390_write8 (Sync_Offset, pDCB->SyncOffset);
- DC390_write8 (CtrlReg1, pDCB->CtrlR1);
- DC390_write8 (CtrlReg3, pDCB->CtrlR3);
- DC390_write8 (CtrlReg4, pDCB->CtrlR4); /* ; Glitch eater */
- DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD); /* ;to release the /ACK signal */
+ DEBUG1(printk(KERN_DEBUG "Resel SRB(%p): TagNum (%02x)\n", pSRB, pSRB->TagNumber);
+ )
+ pSRB->ScsiPhase = SCSI_NOP0;
+ DC390_write8(Scsi_Dest_ID, pDCB->UnitSCSIID);
+ DC390_write8(Sync_Period, pDCB->SyncPeriod);
+ DC390_write8(Sync_Offset, pDCB->SyncOffset);
+ DC390_write8(CtrlReg1, pDCB->CtrlR1);
+ DC390_write8(CtrlReg3, pDCB->CtrlR3);
+ DC390_write8(CtrlReg4, pDCB->CtrlR4); /* ; Glitch eater */
+ DC390_write8(ScsiCmd, MSG_ACCEPTED_CMD); /* ;to release the /ACK signal */
}
-static void
-dc390_remove_dev (PACB pACB, PDCB pDCB)
-{
- PDCB pPrevDCB = pACB->pLinkDCB;
-
- pACB->DCBmap[pDCB->UnitSCSIID] &= ~(1 << pDCB->UnitSCSILUN);
- if (pDCB->GoingSRBCnt > 1)
- {
- DCBDEBUG(printk (KERN_INFO "DC390: Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %i\n",\
- pDCB->UnitSCSIID, pDCB->UnitSCSILUN, (int)pDCB, pDCB->GoingSRBCnt);)
- return;
- };
-
- if (pDCB == pACB->pLinkDCB)
- {
- if (pDCB->pNextDCB == pDCB) pDCB->pNextDCB = 0;
- pACB->pLinkDCB = pDCB->pNextDCB;
- pACB->pLastDCB->pNextDCB = pDCB->pNextDCB;
- }
- else
- {
- while (pPrevDCB->pNextDCB != pDCB) pPrevDCB = pPrevDCB->pNextDCB;
- pPrevDCB->pNextDCB = pDCB->pNextDCB;
- if (pDCB == pACB->pLastDCB) pACB->pLastDCB = pPrevDCB;
- }
-
- DCBDEBUG(printk (KERN_INFO "DC390: Driver about to free DCB (ID %i, LUN %i): 0x%08x\n",\
- pDCB->UnitSCSIID, pDCB->UnitSCSILUN, (int)pDCB);)
- kfree (pDCB); if (pDCB == pACB->pActiveDCB) pACB->pActiveDCB = 0;
- pACB->DCBCnt--;
- /* pACB->DeviceCnt--; */
+static void dc390_remove_dev(PACB pACB, PDCB pDCB)
+{
+ PDCB pPrevDCB = pACB->pLinkDCB;
+
+ pACB->DCBmap[pDCB->UnitSCSIID] &= ~(1 << pDCB->UnitSCSILUN);
+ if (pDCB->GoingSRBCnt > 1) {
+ DCBDEBUG(printk(KERN_INFO "DC390: Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %i\n", \
+ pDCB->UnitSCSIID, pDCB->UnitSCSILUN, (int) pDCB, pDCB->GoingSRBCnt);
+ )
+ return;
+ };
+
+ if (pDCB == pACB->pLinkDCB) {
+ if (pDCB->pNextDCB == pDCB)
+ pDCB->pNextDCB = 0;
+ pACB->pLinkDCB = pDCB->pNextDCB;
+ pACB->pLastDCB->pNextDCB = pDCB->pNextDCB;
+ } else {
+ while (pPrevDCB->pNextDCB != pDCB)
+ pPrevDCB = pPrevDCB->pNextDCB;
+ pPrevDCB->pNextDCB = pDCB->pNextDCB;
+ if (pDCB == pACB->pLastDCB)
+ pACB->pLastDCB = pPrevDCB;
+ }
+
+ DCBDEBUG(printk(KERN_INFO "DC390: Driver about to free DCB (ID %i, LUN %i): 0x%08x\n", \
+ pDCB->UnitSCSIID, pDCB->UnitSCSILUN, (int) pDCB);
+ )
+ kfree(pDCB);
+ if (pDCB == pACB->pActiveDCB)
+ pACB->pActiveDCB = 0;
+ pACB->DCBCnt--;
+ /* pACB->DeviceCnt--; */
};
static UCHAR __inline__
-dc390_tagq_blacklist (char* name)
+ dc390_tagq_blacklist(char *name)
{
- UCHAR i;
- for(i=0; i<BADDEVCNT; i++)
- if (memcmp (name, dc390_baddevname1[i], 28) == 0)
- return 1;
- return 0;
+ UCHAR i;
+ for (i = 0; i < BADDEVCNT; i++)
+ if (memcmp(name, dc390_baddevname1[i], 28) == 0)
+ return 1;
+ return 0;
};
-
-static void
-dc390_disc_tagq_set (PDCB pDCB, PSCSI_INQDATA ptr)
+
+static void dc390_disc_tagq_set(PDCB pDCB, PSCSI_INQDATA ptr)
{
- /* Check for SCSI format (ANSI and Response data format) */
- if ( (ptr->Vers & 0x07) >= 2 || (ptr->RDF & 0x0F) == 2 )
- {
- if ( (ptr->Flags & SCSI_INQ_CMDQUEUE) &&
- (pDCB->DevMode & TAG_QUEUEING_) &&
- /* ((pDCB->DevType == TYPE_DISK)
- || (pDCB->DevType == TYPE_MOD)) &&*/
- !dc390_tagq_blacklist (((char*)ptr)+8) )
- {
- pDCB->MaxCommand = pDCB->pDCBACB->TagMaxNum;
- pDCB->SyncMode |= EN_TAG_QUEUEING /* | EN_ATN_STOP */;
- pDCB->TagMask = 0;
- }
- else
- {
- /* Do we really need to check for DevType here ? */
- if ( 0 /*(pDCB->DevMode & EN_DISCONNECT_)*/
- /* && ((pDCB->DevType == TYPE_DISK)
- || (pDCB->DevType == TYPE_MOD))*/ )
- pDCB->SyncMode |= EN_ATN_STOP;
- else
- //pDCB->SyncMode &= ~EN_ATN_STOP;
- pDCB->SyncMode &= ~0;
- }
- }
+ /* Check for SCSI format (ANSI and Response data format) */
+ if ((ptr->Vers & 0x07) >= 2 || (ptr->RDF & 0x0F) == 2) {
+ if ((ptr->Flags & SCSI_INQ_CMDQUEUE) &&
+ (pDCB->DevMode & TAG_QUEUEING_) &&
+ /* ((pDCB->DevType == TYPE_DISK)
+ || (pDCB->DevType == TYPE_MOD)) && */
+ !dc390_tagq_blacklist(((char *) ptr) + 8)) {
+ pDCB->MaxCommand = pDCB->pDCBACB->TagMaxNum;
+ pDCB->SyncMode |= EN_TAG_QUEUEING /* | EN_ATN_STOP */ ;
+ pDCB->TagMask = 0;
+ } else {
+ /* Do we really need to check for DevType here ? */
+ if (0 /*(pDCB->DevMode & EN_DISCONNECT_) */
+ /* && ((pDCB->DevType == TYPE_DISK)
+ || (pDCB->DevType == TYPE_MOD)) */ )
+ pDCB->SyncMode |= EN_ATN_STOP;
+ else
+ //pDCB->SyncMode &= ~EN_ATN_STOP;
+ pDCB->SyncMode &= ~0;
+ }
+ }
};
-static void
-dc390_add_dev (PACB pACB, PDCB pDCB, PSCSI_INQDATA ptr)
+static void dc390_add_dev(PACB pACB, PDCB pDCB, PSCSI_INQDATA ptr)
{
- UCHAR bval1 = ptr->DevType & SCSI_DEVTYPE;
- pDCB->DevType = bval1;
- /* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */
- dc390_disc_tagq_set (pDCB, ptr);
+ UCHAR bval1 = ptr->DevType & SCSI_DEVTYPE;
+ pDCB->DevType = bval1;
+ /* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */
+ dc390_disc_tagq_set(pDCB, ptr);
};
-void
-dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
+void dc390_SRBdone(PACB pACB, PDCB pDCB, PSRB pSRB)
{
- PSRB psrb;
- UCHAR bval, status, i;
- PSCSICMD pcmd;
- PSCSI_INQDATA ptr;
- PSGL ptr2;
- ULONG swlval;
-
- pcmd = pSRB->pcmd;
- status = pSRB->TargetStatus;
- DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result,\
- pSRB, pcmd->pid);)
- if(pSRB->SRBFlag & AUTO_REQSENSE)
- { /* Last command was a Request Sense */
- pSRB->SRBFlag &= ~AUTO_REQSENSE;
- pSRB->AdaptStatus = 0;
- pSRB->TargetStatus = SCSI_STAT_CHECKCOND;
+ PSRB psrb;
+ UCHAR bval, status, i;
+ PSCSICMD pcmd;
+ PSCSI_INQDATA ptr;
+ PSGL ptr2;
+ ULONG swlval;
+
+ pcmd = pSRB->pcmd;
+ status = pSRB->TargetStatus;
+ DEBUG0(printk(" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result, \
+ pSRB, pcmd->pid);
+ )
+ if (pSRB->SRBFlag & AUTO_REQSENSE) { /* Last command was a Request Sense */
+ pSRB->SRBFlag &= ~AUTO_REQSENSE;
+ pSRB->AdaptStatus = 0;
+ pSRB->TargetStatus = SCSI_STAT_CHECKCOND;
#ifdef DC390_REMOVABLEDEBUG
- switch (pcmd->sense_buffer[2] & 0x0f)
- {
- case NOT_READY: printk (KERN_INFO "DC390: ReqSense: NOT_READY (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
- pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
- status, pACB->scan_devices); break;
- case UNIT_ATTENTION: printk (KERN_INFO "DC390: ReqSense: UNIT_ATTENTION (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
- pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
- status, pACB->scan_devices); break;
- case ILLEGAL_REQUEST: printk (KERN_INFO "DC390: ReqSense: ILLEGAL_REQUEST (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
- pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
- status, pACB->scan_devices); break;
- case MEDIUM_ERROR: printk (KERN_INFO "DC390: ReqSense: MEDIUM_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
- pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
- status, pACB->scan_devices); break;
- case HARDWARE_ERROR: printk (KERN_INFO "DC390: ReqSense: HARDWARE_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
- pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
- status, pACB->scan_devices); break;
- }
+ switch (pcmd->sense_buffer[2] & 0x0f) {
+ case NOT_READY:
+ printk(KERN_INFO "DC390: ReqSense: NOT_READY (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
+ pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
+ status, pACB->scan_devices);
+ break;
+ case UNIT_ATTENTION:
+ printk(KERN_INFO "DC390: ReqSense: UNIT_ATTENTION (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
+ pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
+ status, pACB->scan_devices);
+ break;
+ case ILLEGAL_REQUEST:
+ printk(KERN_INFO "DC390: ReqSense: ILLEGAL_REQUEST (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
+ pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
+ status, pACB->scan_devices);
+ break;
+ case MEDIUM_ERROR:
+ printk(KERN_INFO "DC390: ReqSense: MEDIUM_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
+ pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
+ status, pACB->scan_devices);
+ break;
+ case HARDWARE_ERROR:
+ printk(KERN_INFO "DC390: ReqSense: HARDWARE_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)\n",
+ pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN,
+ status, pACB->scan_devices);
+ break;
+ }
#endif
- //pcmd->result = DRIVER_SENSE << 24 | DID_OK << 16 | status;
- if(status == SCSI_STAT_CHECKCOND)
- {
- pcmd->result = DID_BAD_TARGET << 16;
- goto ckc_e;
- }
- if(pSRB->RetryCnt == 0)
- {
- (ULONG)(pSRB->CmdBlock[0]) = pSRB->Segment0[0];
- pSRB->TotalXferredLen = pSRB->Segment1[1];
- if( (pSRB->TotalXferredLen) &&
- (pSRB->TotalXferredLen >= pcmd->underflow) )
- pcmd->result |= (DID_OK << 16);
- else
- pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) |
- SCSI_STAT_CHECKCOND;
- REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x,Result=%08x,XferL=%08x\n",pSRB->CmdBlock[0],\
- (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);)
- goto ckc_e;
- }
- else /* Retry */
- {
- pSRB->RetryCnt--;
- pSRB->AdaptStatus = 0;
- pSRB->TargetStatus = 0;
- *((PULONG) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
- *((PULONG) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1];
- /* Don't retry on TEST_UNIT_READY */
- if( pSRB->CmdBlock[0] == TEST_UNIT_READY /* || pSRB->CmdBlock[0] == START_STOP */)
- {
- pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16)
- | SCSI_STAT_CHECKCOND;
- REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->CmdBlock[0],\
- (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);)
- goto ckc_e;
- }
- pcmd->result |= (DRIVER_SENSE << 24);
- pSRB->SGcount = (UCHAR) pSRB->Segment1[0];
- pSRB->ScsiCmdLen = (UCHAR) (pSRB->Segment1[0] >> 8);
- pSRB->SGIndex = 0;
- pSRB->TotalXferredLen = 0;
- pSRB->SGToBeXferLen = 0;
- if( pcmd->use_sg )
- pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
- else if( pcmd->request_buffer )
- {
- pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
- pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
- pSRB->Segmentx.length = pcmd->request_bufflen;
- }
- if( dc390_StartSCSI( pACB, pDCB, pSRB ) )
- dc390_RewaitSRB( pDCB, pSRB );
- return;
- }
- }
- if( status )
- {
- if( status == SCSI_STAT_CHECKCOND)
- {
- REMOVABLEDEBUG(printk (KERN_INFO "DC390: Scsi_Stat_CheckCond (Cmd %02x, Id %02x, LUN %02x)\n",\
- pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN);)
- if( (pSRB->SGIndex < pSRB->SGcount) && (pSRB->SGcount) && (pSRB->SGToBeXferLen) )
- {
- bval = pSRB->SGcount;
- swlval = 0;
- ptr2 = pSRB->pSegmentList;
- for( i=pSRB->SGIndex; i < bval; i++)
- {
- swlval += ptr2->length;
- ptr2++;
- }
- REMOVABLEDEBUG(printk(KERN_INFO "XferredLen=%08x,NotXferLen=%08x\n",\
- (UINT) pSRB->TotalXferredLen, (UINT) swlval);)
- }
- dc390_RequestSense( pACB, pDCB, pSRB );
- return;
- }
- else if( status == SCSI_STAT_QUEUEFULL )
- {
- bval = (UCHAR) pDCB->GoingSRBCnt;
- bval--;
- pDCB->MaxCommand = bval;
- dc390_RewaitSRB( pDCB, pSRB );
- pSRB->AdaptStatus = 0;
- pSRB->TargetStatus = 0;
- return;
- }
- else if(status == SCSI_STAT_SEL_TIMEOUT)
- {
- pSRB->AdaptStatus = H_SEL_TIMEOUT;
- pSRB->TargetStatus = 0;
- pcmd->result = DID_BAD_TARGET << 16;
- /* Devices are removed below ... */
- }
- else if (status == SCSI_STAT_BUSY &&
- (pSRB->CmdBlock[0] == TEST_UNIT_READY || pSRB->CmdBlock[0] == INQUIRY) &&
- pACB->scan_devices)
- {
- pSRB->AdaptStatus = 0;
- pSRB->TargetStatus = status;
- pcmd->result = (ULONG) (pSRB->EndMessage << 8)
- /* | (ULONG) status */;
- }
- else
- { /* Another error */
- pSRB->AdaptStatus = 0;
- if( pSRB->RetryCnt )
- { /* Retry */
- pSRB->RetryCnt--;
- pSRB->TargetStatus = 0;
- pSRB->SGIndex = 0;
- pSRB->TotalXferredLen = 0;
- pSRB->SGToBeXferLen = 0;
- if( pcmd->use_sg )
- pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
- else if( pcmd->request_buffer )
- {
- pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
- pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
- pSRB->Segmentx.length = pcmd->request_bufflen;
+ //pcmd->result = DRIVER_SENSE << 24 | DID_OK << 16 | status;
+ if (status == SCSI_STAT_CHECKCOND) {
+ pcmd->result = DID_BAD_TARGET << 16;
+ goto ckc_e;
+ }
+ if (pSRB->RetryCnt == 0) {
+ (ULONG) (pSRB->CmdBlock[0]) = pSRB->Segment0[0];
+ pSRB->TotalXferredLen = pSRB->Segment1[1];
+ if ((pSRB->TotalXferredLen) &&
+ (pSRB->TotalXferredLen >= pcmd->underflow))
+ pcmd->result |= (DID_OK << 16);
+ else
+ pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16) |
+ SCSI_STAT_CHECKCOND;
+ REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x,Result=%08x,XferL=%08x\n", pSRB->CmdBlock[0], \
+ (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);
+ )
+ goto ckc_e;
+ } else { /* Retry */
+ pSRB->RetryCnt--;
+ pSRB->AdaptStatus = 0;
+ pSRB->TargetStatus = 0;
+ *((PULONG) & (pSRB->CmdBlock[0])) = pSRB->Segment0[0];
+ *((PULONG) & (pSRB->CmdBlock[4])) = pSRB->Segment0[1];
+ /* Don't retry on TEST_UNIT_READY */
+ if (pSRB->CmdBlock[0] == TEST_UNIT_READY /* || pSRB->CmdBlock[0] == START_STOP */ ) {
+ pcmd->result = (DRIVER_SENSE << 24) | (DRIVER_OK << 16)
+ | SCSI_STAT_CHECKCOND;
+ REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n", pSRB->CmdBlock[0], \
+ (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);
+ )
+ goto ckc_e;
+ }
+ pcmd->result |= (DRIVER_SENSE << 24);
+ pSRB->SGcount = (UCHAR) pSRB->Segment1[0];
+ pSRB->ScsiCmdLen = (UCHAR) (pSRB->Segment1[0] >> 8);
+ pSRB->SGIndex = 0;
+ pSRB->TotalXferredLen = 0;
+ pSRB->SGToBeXferLen = 0;
+ if (pcmd->use_sg)
+ pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
+ else if (pcmd->request_buffer) {
+ pSRB->pSegmentList = (PSGL) & pSRB->Segmentx;
+ pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
+ pSRB->Segmentx.length = pcmd->request_bufflen;
+ }
+ if (dc390_StartSCSI(pACB, pDCB, pSRB))
+ dc390_RewaitSRB(pDCB, pSRB);
+ return;
}
- if( dc390_StartSCSI( pACB, pDCB, pSRB ) )
- dc390_RewaitSRB( pDCB, pSRB );
- return;
- }
- else
- { /* Report error */
- pcmd->result |= (DID_ERROR << 16) | (ULONG) (pSRB->EndMessage << 8) |
- (ULONG) status;
- }
- }
- }
- else
- { /* Target status == 0 */
- status = pSRB->AdaptStatus;
- if(status & H_OVER_UNDER_RUN)
- {
- pSRB->TargetStatus = 0;
- pcmd->result |= (DID_OK << 16) | (pSRB->EndMessage << 8);
}
- else if( pSRB->SRBStatus & PARITY_ERROR)
- {
- pcmd->result |= (DID_PARITY << 16) | (pSRB->EndMessage << 8);
+ if (status) {
+ if (status == SCSI_STAT_CHECKCOND) {
+ REMOVABLEDEBUG(printk(KERN_INFO "DC390: Scsi_Stat_CheckCond (Cmd %02x, Id %02x, LUN %02x)\n", \
+ pcmd->cmnd[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN);
+ )
+ if ((pSRB->SGIndex < pSRB->SGcount) && (pSRB->SGcount) && (pSRB->SGToBeXferLen)) {
+ bval = pSRB->SGcount;
+ swlval = 0;
+ ptr2 = pSRB->pSegmentList;
+ for (i = pSRB->SGIndex; i < bval; i++) {
+ swlval += ptr2->length;
+ ptr2++;
+ }
+ REMOVABLEDEBUG(printk(KERN_INFO "XferredLen=%08x,NotXferLen=%08x\n", \
+ (UINT) pSRB->TotalXferredLen, (UINT) swlval);
+ )
+ }
+ dc390_RequestSense(pACB, pDCB, pSRB);
+ return;
+ } else if (status == SCSI_STAT_QUEUEFULL) {
+ bval = (UCHAR) pDCB->GoingSRBCnt;
+ bval--;
+ pDCB->MaxCommand = bval;
+ dc390_RewaitSRB(pDCB, pSRB);
+ pSRB->AdaptStatus = 0;
+ pSRB->TargetStatus = 0;
+ return;
+ } else if (status == SCSI_STAT_SEL_TIMEOUT) {
+ pSRB->AdaptStatus = H_SEL_TIMEOUT;
+ pSRB->TargetStatus = 0;
+ pcmd->result = DID_BAD_TARGET << 16;
+ /* Devices are removed below ... */
+ } else if (status == SCSI_STAT_BUSY &&
+ (pSRB->CmdBlock[0] == TEST_UNIT_READY || pSRB->CmdBlock[0] == INQUIRY) &&
+ pACB->scan_devices) {
+ pSRB->AdaptStatus = 0;
+ pSRB->TargetStatus = status;
+ pcmd->result = (ULONG) (pSRB->EndMessage << 8)
+ /* | (ULONG) status */ ;
+ } else { /* Another error */
+ pSRB->AdaptStatus = 0;
+ if (pSRB->RetryCnt) { /* Retry */
+ pSRB->RetryCnt--;
+ pSRB->TargetStatus = 0;
+ pSRB->SGIndex = 0;
+ pSRB->TotalXferredLen = 0;
+ pSRB->SGToBeXferLen = 0;
+ if (pcmd->use_sg)
+ pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
+ else if (pcmd->request_buffer) {
+ pSRB->pSegmentList = (PSGL) & pSRB->Segmentx;
+ pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
+ pSRB->Segmentx.length = pcmd->request_bufflen;
+ }
+ if (dc390_StartSCSI(pACB, pDCB, pSRB))
+ dc390_RewaitSRB(pDCB, pSRB);
+ return;
+ } else { /* Report error */
+ pcmd->result |= (DID_ERROR << 16) | (ULONG) (pSRB->EndMessage << 8) |
+ (ULONG) status;
+ }
+ }
+ } else { /* Target status == 0 */
+ status = pSRB->AdaptStatus;
+ if (status & H_OVER_UNDER_RUN) {
+ pSRB->TargetStatus = 0;
+ pcmd->result |= (DID_OK << 16) | (pSRB->EndMessage << 8);
+ } else if (pSRB->SRBStatus & PARITY_ERROR) {
+ pcmd->result |= (DID_PARITY << 16) | (pSRB->EndMessage << 8);
+ } else { /* No error */
+ pSRB->AdaptStatus = 0;
+ pSRB->TargetStatus = 0;
+ pcmd->result |= (DID_OK << 16);
+ }
}
- else /* No error */
- {
- pSRB->AdaptStatus = 0;
- pSRB->TargetStatus = 0;
- pcmd->result |= (DID_OK << 16);
- }
- }
-
-ckc_e:
- if( pACB->scan_devices )
- {
- if( pSRB->CmdBlock[0] == TEST_UNIT_READY )
- {
+
+ ckc_e:
+ if (pACB->scan_devices) {
+ if (pSRB->CmdBlock[0] == TEST_UNIT_READY) {
#ifdef DC390_DEBUG0
- printk (KERN_INFO "DC390: Test_Unit_Ready: result: %08x", pcmd->result);
- if (pcmd->result & DRIVER_SENSE << 24) printk (" (sense: %02x %02x %02x %02x)\n",
- pcmd->sense_buffer[0], pcmd->sense_buffer[1],
- pcmd->sense_buffer[2], pcmd->sense_buffer[3]);
- else printk ("\n");
+ printk(KERN_INFO "DC390: Test_Unit_Ready: result: %08x", pcmd->result);
+ if (pcmd->result & DRIVER_SENSE << 24)
+ printk(" (sense: %02x %02x %02x %02x)\n",
+ pcmd->sense_buffer[0], pcmd->sense_buffer[1],
+ pcmd->sense_buffer[2], pcmd->sense_buffer[3]);
+ else
+ printk("\n");
#endif
- if((pcmd->result != (DID_OK << 16) && !(pcmd->result & SCSI_STAT_CHECKCOND) && !(pcmd->result & SCSI_STAT_BUSY)) ||
- ((pcmd->result & DRIVER_SENSE << 24) && (pcmd->sense_buffer[0] & 0x70) == 0x70 &&
- (pcmd->sense_buffer[2] & 0xf) == ILLEGAL_REQUEST) || pcmd->result & DID_ERROR << 16)
- {
- /* device not present: remove */
- dc390_remove_dev (pACB, pDCB);
-
- if( (pcmd->target == pACB->pScsiHost->max_id - 1) &&
- ((pcmd->lun == 0) || (pcmd->lun == pACB->pScsiHost->max_lun - 1)) )
- pACB->scan_devices = 0;
- }
- else
- {
- /* device present: add */
- if( (pcmd->target == pACB->pScsiHost->max_id - 1) &&
- (pcmd->lun == pACB->pScsiHost->max_lun - 1) )
- pACB->scan_devices = END_SCAN ;
- /* pACB->DeviceCnt++; */ /* Dev is added on INQUIRY */
- }
- }
- }
-
- if( pSRB->CmdBlock[0] == INQUIRY &&
- (pcmd->result == DID_OK << 16 || pcmd->result & SCSI_STAT_CHECKCOND) )
- {
- ptr = (PSCSI_INQDATA) (pcmd->request_buffer);
- if( pcmd->use_sg )
- ptr = (PSCSI_INQDATA) (((PSGL) ptr)->address);
- if ((ptr->DevType & SCSI_DEVTYPE) == TYPE_NODEV)
- {
- /* device not present: remove */
- dc390_remove_dev (pACB, pDCB);
- }
- else
- {
- /* device found: add */
- dc390_add_dev (pACB, pDCB, ptr);
- if (pACB->scan_devices) pACB->DeviceCnt++;
- }
- if( (pcmd->target == pACB->pScsiHost->max_id - 1) &&
- (pcmd->lun == pACB->pScsiHost->max_lun - 1) )
- pACB->scan_devices = 0;
- };
+ if ((pcmd->result != (DID_OK << 16) && !(pcmd->result & SCSI_STAT_CHECKCOND) && !(pcmd->result & SCSI_STAT_BUSY)) ||
+ ((pcmd->result & DRIVER_SENSE << 24) && (pcmd->sense_buffer[0] & 0x70) == 0x70 &&
+ (pcmd->sense_buffer[2] & 0xf) == ILLEGAL_REQUEST) || pcmd->result & DID_ERROR << 16) {
+ /* device not present: remove */
+ dc390_remove_dev(pACB, pDCB);
+
+ if ((pcmd->target == pACB->pScsiHost->max_id - 1) &&
+ ((pcmd->lun == 0) || (pcmd->lun == pACB->pScsiHost->max_lun - 1)))
+ pACB->scan_devices = 0;
+ } else {
+ /* device present: add */
+ if ((pcmd->target == pACB->pScsiHost->max_id - 1) &&
+ (pcmd->lun == pACB->pScsiHost->max_lun - 1))
+ pACB->scan_devices = END_SCAN;
+ /* pACB->DeviceCnt++; *//* Dev is added on INQUIRY */
+ }
+ }
+ }
+ if (pSRB->CmdBlock[0] == INQUIRY &&
+ (pcmd->result == DID_OK << 16 || pcmd->result & SCSI_STAT_CHECKCOND)) {
+ ptr = (PSCSI_INQDATA) (pcmd->request_buffer);
+ if (pcmd->use_sg)
+ ptr = (PSCSI_INQDATA) (((PSGL) ptr)->address);
+ if ((ptr->DevType & SCSI_DEVTYPE) == TYPE_NODEV) {
+ /* device not present: remove */
+ dc390_remove_dev(pACB, pDCB);
+ } else {
+ /* device found: add */
+ dc390_add_dev(pACB, pDCB, ptr);
+ if (pACB->scan_devices)
+ pACB->DeviceCnt++;
+ }
+ if ((pcmd->target == pACB->pScsiHost->max_id - 1) &&
+ (pcmd->lun == pACB->pScsiHost->max_lun - 1))
+ pACB->scan_devices = 0;
+ };
/* dc390_ReleaseSRB( pDCB, pSRB ); */
- if(pSRB == pDCB->pGoingSRB )
- {
- pDCB->pGoingSRB = pSRB->pNextSRB;
- }
- else
- {
- psrb = pDCB->pGoingSRB;
- while( psrb->pNextSRB != pSRB )
- psrb = psrb->pNextSRB;
- psrb->pNextSRB = pSRB->pNextSRB;
- if( pSRB == pDCB->pGoingLast )
- pDCB->pGoingLast = psrb;
- }
- pSRB->pNextSRB = pACB->pFreeSRB;
- pACB->pFreeSRB = pSRB;
- pDCB->GoingSRBCnt--;
-
- dc390_DoWaitingSRB( pACB );
-
- DC390_UNLOCK_ACB_NI;
- pcmd->scsi_done( pcmd );
- DC390_LOCK_ACB_NI;
-
- if( pDCB->QIORBCnt )
- dc390_DoNextCmd( pACB, pDCB );
- return;
+ if (pSRB == pDCB->pGoingSRB) {
+ pDCB->pGoingSRB = pSRB->pNextSRB;
+ } else {
+ psrb = pDCB->pGoingSRB;
+ while (psrb->pNextSRB != pSRB)
+ psrb = psrb->pNextSRB;
+ psrb->pNextSRB = pSRB->pNextSRB;
+ if (pSRB == pDCB->pGoingLast)
+ pDCB->pGoingLast = psrb;
+ }
+ pSRB->pNextSRB = pACB->pFreeSRB;
+ pACB->pFreeSRB = pSRB;
+ pDCB->GoingSRBCnt--;
+
+ dc390_DoWaitingSRB(pACB);
+
+ DC390_UNLOCK_ACB_NI;
+ pcmd->scsi_done(pcmd);
+ DC390_LOCK_ACB_NI;
+
+ if (pDCB->QIORBCnt)
+ dc390_DoNextCmd(pACB, pDCB);
+ return;
}
/* Remove all SRBs and tell midlevel code DID_RESET */
-void
-dc390_DoingSRB_Done( PACB pACB )
+void dc390_DoingSRB_Done(PACB pACB)
{
- PDCB pDCB, pdcb;
- PSRB psrb, psrb2;
- UCHAR i;
- PSCSICMD pcmd;
-
- pDCB = pACB->pLinkDCB;
- pdcb = pDCB;
- if (! pdcb) return;
- do
- {
- psrb = pdcb->pGoingSRB;
- for( i=0; i<pdcb->GoingSRBCnt; i++)
- {
- psrb2 = psrb->pNextSRB;
- pcmd = psrb->pcmd;
- pcmd->result = DID_RESET << 16;
-
-/* ReleaseSRB( pDCB, pSRB ); */
-
- psrb->pNextSRB = pACB->pFreeSRB;
- pACB->pFreeSRB = psrb;
-
- DC390_UNLOCK_ACB_NI;
- pcmd->scsi_done( pcmd );
- DC390_LOCK_ACB_NI;
- psrb = psrb2;
- }
- pdcb->GoingSRBCnt = 0;;
- pdcb->pGoingSRB = NULL;
- pdcb->TagMask = 0;
- pdcb = pdcb->pNextDCB;
- } while( pdcb != pDCB );
+ PDCB pDCB, pdcb;
+ PSRB psrb, psrb2;
+ UCHAR i;
+ PSCSICMD pcmd;
+
+ pDCB = pACB->pLinkDCB;
+ pdcb = pDCB;
+ if (!pdcb)
+ return;
+ do {
+ psrb = pdcb->pGoingSRB;
+ for (i = 0; i < pdcb->GoingSRBCnt; i++) {
+ psrb2 = psrb->pNextSRB;
+ pcmd = psrb->pcmd;
+ pcmd->result = DID_RESET << 16;
+
+/* ReleaseSRB( pDCB, pSRB ); */
+
+ psrb->pNextSRB = pACB->pFreeSRB;
+ pACB->pFreeSRB = psrb;
+
+ DC390_UNLOCK_ACB_NI;
+ pcmd->scsi_done(pcmd);
+ DC390_LOCK_ACB_NI;
+ psrb = psrb2;
+ }
+ pdcb->GoingSRBCnt = 0;;
+ pdcb->pGoingSRB = NULL;
+ pdcb->TagMask = 0;
+ pdcb = pdcb->pNextDCB;
+ } while (pdcb != pDCB);
}
-static void
-dc390_ResetSCSIBus( PACB pACB )
+static void dc390_ResetSCSIBus(PACB pACB)
{
- pACB->ACBFlag |= RESET_DEV;
+ pACB->ACBFlag |= RESET_DEV;
- DC390_write8 (ScsiCmd, RST_DEVICE_CMD);
- udelay (250);
- DC390_write8 (ScsiCmd, NOP_CMD);
+ DC390_write8(ScsiCmd, RST_DEVICE_CMD);
+ udelay(250);
+ DC390_write8(ScsiCmd, NOP_CMD);
- DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
- DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
- DC390_write8 (ScsiCmd, RST_SCSI_BUS_CMD);
+ DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
+ DC390_write8(DMA_Cmd, DMA_IDLE_CMD);
+ DC390_write8(ScsiCmd, RST_SCSI_BUS_CMD);
- return;
+ return;
}
-static void
-dc390_ScsiRstDetect( PACB pACB )
+static void dc390_ScsiRstDetect(PACB pACB)
{
- printk ("DC390: Rst_Detect: laststat = %08lx\n", dc390_laststatus);
- //DEBUG0(printk(KERN_INFO "RST_DETECT,");)
+ printk("DC390: Rst_Detect: laststat = %08lx\n", dc390_laststatus);
+ //DEBUG0(printk(KERN_INFO "RST_DETECT,");)
- DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
- /* Unlock before ? */
- /* delay a second */
- { unsigned int msec = 1*1000; while (--msec) udelay(1000); }
- DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
-
- if( pACB->ACBFlag & RESET_DEV )
- pACB->ACBFlag |= RESET_DONE;
- else
- {
- pACB->ACBFlag |= RESET_DETECT;
-
- dc390_ResetDevParam( pACB );
-/* dc390_DoingSRB_Done( pACB ); ???? */
- dc390_RecoverSRB( pACB );
- pACB->pActiveDCB = NULL;
- pACB->ACBFlag = 0;
- dc390_DoWaitingSRB( pACB );
- }
- return;
+ DC390_write8(DMA_Cmd, DMA_IDLE_CMD);
+ /* Unlock before ? */
+ /* delay a second */
+ {
+ unsigned int msec = 1 * 1000;
+ while (--msec)
+ udelay(1000);
+ }
+ DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
+
+ if (pACB->ACBFlag & RESET_DEV)
+ pACB->ACBFlag |= RESET_DONE;
+ else {
+ pACB->ACBFlag |= RESET_DETECT;
+
+ dc390_ResetDevParam(pACB);
+/* dc390_DoingSRB_Done( pACB ); ???? */
+ dc390_RecoverSRB(pACB);
+ pACB->pActiveDCB = NULL;
+ pACB->ACBFlag = 0;
+ dc390_DoWaitingSRB(pACB);
+ }
+ return;
}
static void __inline__
-dc390_RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB )
+ dc390_RequestSense(PACB pACB, PDCB pDCB, PSRB pSRB)
{
- PSCSICMD pcmd;
+ PSCSICMD pcmd;
- REMOVABLEDEBUG(printk (KERN_INFO "DC390: RequestSense (Cmd %02x, Id %02x, LUN %02x)\n",\
- pSRB->CmdBlock[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN);)
+ REMOVABLEDEBUG(printk(KERN_INFO "DC390: RequestSense (Cmd %02x, Id %02x, LUN %02x)\n", \
+ pSRB->CmdBlock[0], pDCB->UnitSCSIID, pDCB->UnitSCSILUN);
+ )
+ pSRB->SRBFlag |= AUTO_REQSENSE;
+ pSRB->Segment0[0] = (ULONG) pSRB->CmdBlock[0];
+ pSRB->Segment0[1] = (ULONG) pSRB->CmdBlock[4];
+ pSRB->Segment1[0] = (ULONG) ((pSRB->ScsiCmdLen << 8) + pSRB->SGcount);
+ pSRB->Segment1[1] = pSRB->TotalXferredLen;
+ pSRB->AdaptStatus = 0;
+ pSRB->TargetStatus = 0; /* SCSI_STAT_CHECKCOND; */
+
+ pcmd = pSRB->pcmd;
- pSRB->SRBFlag |= AUTO_REQSENSE;
- pSRB->Segment0[0] = (ULONG) pSRB->CmdBlock[0];
- pSRB->Segment0[1] = (ULONG) pSRB->CmdBlock[4];
- pSRB->Segment1[0] = (ULONG) ((pSRB->ScsiCmdLen << 8) + pSRB->SGcount);
- pSRB->Segment1[1] = pSRB->TotalXferredLen;
- pSRB->AdaptStatus = 0;
- pSRB->TargetStatus = 0; /* SCSI_STAT_CHECKCOND; */
-
- pcmd = pSRB->pcmd;
-
- pSRB->Segmentx.address = (PUCHAR) &(pcmd->sense_buffer);
- pSRB->Segmentx.length = sizeof(pcmd->sense_buffer);
- pSRB->pSegmentList = &pSRB->Segmentx;
- pSRB->SGcount = 1;
- pSRB->SGIndex = 0;
-
- pSRB->CmdBlock[0] = REQUEST_SENSE;
- pSRB->CmdBlock[1] = pDCB->IdentifyMsg << 5;
- (USHORT) pSRB->CmdBlock[2] = 0;
- (USHORT) pSRB->CmdBlock[4] = sizeof(pcmd->sense_buffer);
- pSRB->ScsiCmdLen = 6;
-
- pSRB->TotalXferredLen = 0;
- pSRB->SGToBeXferLen = 0;
- if( dc390_StartSCSI( pACB, pDCB, pSRB ) )
- dc390_RewaitSRB( pDCB, pSRB );
+ pSRB->Segmentx.address = (PUCHAR) & (pcmd->sense_buffer);
+ pSRB->Segmentx.length = sizeof(pcmd->sense_buffer);
+ pSRB->pSegmentList = &pSRB->Segmentx;
+ pSRB->SGcount = 1;
+ pSRB->SGIndex = 0;
+
+ pSRB->CmdBlock[0] = REQUEST_SENSE;
+ pSRB->CmdBlock[1] = pDCB->IdentifyMsg << 5;
+ (USHORT) pSRB->CmdBlock[2] = 0;
+ (USHORT) pSRB->CmdBlock[4] = sizeof(pcmd->sense_buffer);
+ pSRB->ScsiCmdLen = 6;
+
+ pSRB->TotalXferredLen = 0;
+ pSRB->SGToBeXferLen = 0;
+ if (dc390_StartSCSI(pACB, pDCB, pSRB))
+ dc390_RewaitSRB(pDCB, pSRB);
}
static void __inline__
-dc390_InvalidCmd( PACB pACB )
+ dc390_InvalidCmd(PACB pACB)
{
- if( pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_+SRB_MSGOUT) )
- DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
+ if (pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_ + SRB_MSGOUT))
+ DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
}
-
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)