All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] merge scsiiom.c into tmscsim.c
@ 2004-10-03 13:47 Christoph Hellwig
  2004-10-03 20:42 ` Guennadi Liakhovetski
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Christoph Hellwig @ 2004-10-03 13:47 UTC (permalink / raw)
  To: g.liakhovetski, jejb; +Cc: linux-scsi

might be a good time to get rid of that clumsy include .c file into
another one thing.  (Also please bk rm scsiiom.c afterwards)


--- 1.56/drivers/scsi/tmscsim.c	2004-10-03 15:43:04 +02:00
+++ edited/drivers/scsi/tmscsim.c	2004-10-03 15:48:31 +02:00
@@ -252,7 +252,7 @@
 
 #include "tmscsim.h"
 
-static int dc390_StartSCSI( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB );
+
 static void dc390_DataOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 static void dc390_DataIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
 static void dc390_Command_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
@@ -272,11 +272,10 @@
 static void dc390_Disconnect( struct dc390_acb* pACB );
 static void dc390_Reselect( struct dc390_acb* pACB );
 static void dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB );
-static void dc390_DoingSRB_Done( struct dc390_acb* pACB, struct scsi_cmnd * cmd);
 static void dc390_ScsiRstDetect( struct dc390_acb* pACB );
-static void dc390_ResetSCSIBus( struct dc390_acb* pACB );
 static void dc390_EnableMsgOut_Abort(struct dc390_acb*, struct dc390_srb*);
-static irqreturn_t do_DC390_Interrupt( int, void *, struct pt_regs *);
+static void dc390_dumpinfo(struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB);
+static void dc390_ResetDevParam(struct dc390_acb* pACB);
 
 static u32	dc390_laststatus = 0;
 static u8	dc390_adapterCnt = 0;
@@ -482,6 +481,1500 @@
 	}
 }
 
+static void __inline__
+dc390_freetag (struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
+{
+	if (pSRB->TagNumber != SCSI_NO_TAG) {
+		pDCB->TagMask &= ~(1 << pSRB->TagNumber);   /* free tag mask */
+		pSRB->TagNumber = SCSI_NO_TAG;
+	}
+}
+
+
+static int
+dc390_StartSCSI( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB )
+{
+    struct scsi_device *sdev = pSRB->pcmd->device;
+    u8 cmd; u8  disc_allowed, try_sync_nego;
+
+    pSRB->ScsiPhase = SCSI_NOP0;
+
+    if (pACB->Connected)
+    {
+	// Should not happen normally
+	printk (KERN_WARNING "DC390: Can't select when connected! (%08x,%02x)\n",
+		pSRB->SRBState, pSRB->SRBFlag);
+	pSRB->SRBState = SRB_READY;
+	pACB->SelConn++;
+	return 1;
+    }
+    if (time_before (jiffies, pACB->pScsiHost->last_reset))
+    {
+	DEBUG0(printk ("DC390: We were just reset and don't accept commands yet!\n"));
+	return 1;
+    }
+    /* KG: Moved pci mapping here */
+    dc390_pci_map(pSRB);
+    /* TODO: error handling */
+    DC390_write8 (Scsi_Dest_ID, pDCB->TargetID);
+    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->pcmd->cmnd[0], pDCB->SyncMode));
+    disc_allowed = pDCB->DevMode & EN_DISCONNECT_;
+    try_sync_nego = 0;
+    /* Don't disconnect on AUTO_REQSENSE, cause it might be an
+     * Contingent Allegiance Condition (6.6), where no tags should be used.
+     * All other have to be allowed to disconnect to prevent Incorrect 
+     * Initiator Connection (6.8.2/6.5.2) */
+    /* Changed KG, 99/06/06 */
+    if( /*(((pSRB->pcmd->cmnd[0] == INQUIRY) || (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) ||
+	 * (pSRB->pcmd->cmnd[0] == TEST_UNIT_READY)) && pACB->scan_devices)
+		||*/ (pSRB->SRBFlag & AUTO_REQSENSE) ) 
+      disc_allowed = 0;
+    if ( (pDCB->SyncMode & SYNC_ENABLE) && (pDCB->TargetLUN == 0) && sdev->sdtr &&
+	( ( ( (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) || (pSRB->SRBFlag & AUTO_REQSENSE) )
+	  && !(pDCB->SyncMode & SYNC_NEGO_DONE) ) || (pSRB->pcmd->cmnd[0] == INQUIRY) ) )
+      try_sync_nego = 1;
+
+    pSRB->MsgCnt = 0; cmd = SEL_W_ATN;
+    DC390_write8 (ScsiFifo, IDENTIFY(disc_allowed, pDCB->TargetLUN));
+    /* Change 99/05/31: Don't use tags when not disconnecting (BUSY) */
+    if ((pDCB->SyncMode & EN_TAG_QUEUEING) && disc_allowed)
+      {
+	s8 tag_no = 0;
+	while ((1 << tag_no) & pDCB->TagMask) tag_no++;
+	if (tag_no >= sizeof (pDCB->TagMask)*8 || tag_no >= pDCB->MaxCommand) { 
+		printk (KERN_WARNING "DC390: Out of tags for Dev. %02x %02x\n", pDCB->TargetID, pDCB->TargetLUN); 
+		return 1;
+		//goto no_tag;
+	}
+	DC390_write8 (ScsiFifo, SIMPLE_QUEUE_TAG);
+	pDCB->TagMask |= (1 << tag_no); pSRB->TagNumber = tag_no;
+	DC390_write8 (ScsiFifo, tag_no);
+	DEBUG1(printk (KERN_DEBUG "DC390: Select w/DisCn for Cmd %li (SRB %p), Using Tag %02x\n", pSRB->pcmd->pid, pSRB, tag_no));
+	cmd = SEL_W_ATN3;
+      }
+    else	/* No TagQ */
+      {
+//      no_tag:
+	DEBUG1(printk (KERN_DEBUG "DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", (disc_allowed?"":"o"), pSRB->pcmd->pid, pSRB));
+      }
+
+    pSRB->SRBState = SRB_START_;
+
+    if (try_sync_nego)
+      { 
+	u8 Sync_Off = pDCB->SyncOffset;
+        DEBUG0(printk (KERN_INFO "DC390: NEW Sync Nego code triggered (%i %i)\n", pDCB->TargetID, pDCB->TargetLUN));
+	pSRB->MsgOutBuf[0] = EXTENDED_MESSAGE;
+	pSRB->MsgOutBuf[1] = 3;
+	pSRB->MsgOutBuf[2] = EXTENDED_SDTR;
+	pSRB->MsgOutBuf[3] = pDCB->NegoPeriod;
+	if (!(Sync_Off & 0x0f)) Sync_Off = SYNC_NEGO_OFFSET;
+	pSRB->MsgOutBuf[4] = Sync_Off;
+	pSRB->MsgCnt = 5;
+	//pSRB->SRBState = SRB_MSGOUT_;
+	pSRB->SRBState |= DO_SYNC_NEGO;
+	cmd = SEL_W_ATN_STOP;
+      }
+
+    /* Command is written in CommandPhase, if SEL_W_ATN_STOP ... */
+    if (cmd != SEL_W_ATN_STOP)
+      {
+	if( pSRB->SRBFlag & AUTO_REQSENSE )
+	  {
+	    DC390_write8 (ScsiFifo, REQUEST_SENSE);
+	    DC390_write8 (ScsiFifo, pDCB->TargetLUN << 5);
+	    DC390_write8 (ScsiFifo, 0);
+	    DC390_write8 (ScsiFifo, 0);
+	    DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
+	    DC390_write8 (ScsiFifo, 0);
+	    DEBUG1(printk (KERN_DEBUG "DC390: AutoReqSense !\n"));
+	  }
+	else	/* write cmnd to bus */ 
+	  {
+	    u8 *ptr; u8 i;
+	    ptr = (u8 *) pSRB->pcmd->cmnd;
+	    for (i=0; i<pSRB->pcmd->cmd_len; i++)
+	      DC390_write8 (ScsiFifo, *(ptr++));
+	  }
+      }
+    DEBUG0(if (pACB->pActiveDCB)	\
+	   printk (KERN_WARNING "DC390: ActiveDCB != 0\n"));
+    DEBUG0(if (pDCB->pActiveSRB)	\
+	   printk (KERN_WARNING "DC390: ActiveSRB != 0\n"));
+    //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
+    if (DC390_read8 (Scsi_Status) & INTERRUPT)
+    {
+	dc390_freetag (pDCB, pSRB);
+	DEBUG0(printk ("DC390: Interrupt during Start SCSI (pid %li, target %02i-%02i)\n",
+		pSRB->pcmd->pid, pSRB->pcmd->device->id, pSRB->pcmd->device->lun));
+	pSRB->SRBState = SRB_READY;
+	//DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
+	pACB->SelLost++;
+	return 1;
+    }
+    DC390_write8 (ScsiCmd, cmd);
+    pACB->pActiveDCB = pDCB; pDCB->pActiveSRB = pSRB;
+    pACB->Connected = 1;
+    pSRB->ScsiPhase = SCSI_NOP1;
+    return 0;
+}
+
+//#define DMA_INT EN_DMA_INT /*| EN_PAGE_INT*/
+#define DMA_INT 0
+
+#if DMA_INT
+/* This is similar to AM53C974.c ... */
+static u8 
+dc390_dma_intr (struct dc390_acb* pACB)
+{
+  struct dc390_srb* pSRB;
+  u8 dstate;
+  DEBUG0(u16 pstate; struct pci_dev *pdev = pACB->pdev);
+  
+  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)
+    {
+	u32 residual, xferCnt; int ctr = 6000000;
+	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
+
+
+static void __inline__
+dc390_InvalidCmd(struct dc390_acb* pACB)
+{
+	if (pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_ | SRB_MSGOUT))
+		DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
+}
+
+
+static irqreturn_t __inline__
+DC390_Interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+    struct dc390_acb *pACB = (struct dc390_acb*)dev_id;
+    struct dc390_dcb *pDCB;
+    struct dc390_srb *pSRB;
+    u8  sstatus=0;
+    u8  phase;
+    void   (*stateV)( struct dc390_acb*, struct dc390_srb*, u8 *);
+    u8  istate, istatus;
+#if DMA_INT
+    u8  dstatus;
+#endif
+
+    sstatus = DC390_read8 (Scsi_Status);
+    if( !(sstatus & INTERRUPT) )
+	return IRQ_NONE;
+
+    DEBUG1(printk (KERN_DEBUG "sstatus=%02x,", sstatus));
+
+#if DMA_INT
+    spin_lock_irq(pACB->pScsiHost->host_lock);
+    dstatus = dc390_dma_intr (pACB);
+    spin_unlock_irq(pACB->pScsiHost->host_lock);
+
+    DEBUG1(printk (KERN_DEBUG "dstatus=%02x,", dstatus));
+    if (! (dstatus & SCSI_INTERRUPT))
+      {
+	DEBUG0(printk (KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n"));
+	return IRQ_NONE;
+      }
+#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);
+#endif
+
+    spin_lock_irq(pACB->pScsiHost->host_lock);
+
+    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 (%08x)!\n", dc390_laststatus);
+	dc390_dumpinfo (pACB, pACB->pActiveDCB, pACB->pActiveDCB->pActiveSRB);
+    }
+	
+    else if (istatus &  INVALID_CMD)
+    {
+	printk ("DC390: Invalid Command detected (%08x)!\n", dc390_laststatus);
+	dc390_InvalidCmd( pACB );
+	goto unlock;
+    }
+
+    if (istatus &  SCSI_RESET)
+    {
+	dc390_ScsiRstDetect( pACB );
+	goto unlock;
+    }
+
+    if (istatus &  DISCONNECTED)
+    {
+	dc390_Disconnect( pACB );
+	goto unlock;
+    }
+
+    if (istatus &  RESELECTED)
+    {
+	dc390_Reselect( pACB );
+	goto unlock;
+    }
+
+    else if (istatus & (SELECTED | SEL_ATTENTION))
+    {
+	printk (KERN_ERR "DC390: Target mode not supported!\n");
+	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 = (u8) 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 );
+    }
+
+ unlock:
+    spin_unlock_irq(pACB->pScsiHost->host_lock);
+    return IRQ_HANDLED;
+}
+
+static irqreturn_t do_DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
+{
+    irqreturn_t ret;
+    DEBUG1(printk (KERN_INFO "DC390: Irq (%i) caught: ", irq));
+    /* Locking is done in DC390_Interrupt */
+    ret = DC390_Interrupt(irq, dev_id, regs);
+    DEBUG1(printk (".. IRQ returned\n"));
+    return ret;
+}
+
+static void
+dc390_DataOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
+{
+    u8   sstatus;
+    struct scatterlist *psgl;
+    u32    ResidCnt, xferCnt;
+    u8   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 )
+	{
+	    unsigned long timeout = jiffies + HZ;
+
+	    /* Function called from the ISR with the host_lock held and interrupts disabled */
+	    if (pSRB->SGToBeXferLen)
+		while (time_before(jiffies, timeout) && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE)) {
+		    spin_unlock_irq(pACB->pScsiHost->host_lock);
+		    udelay(50);
+		    spin_lock_irq(pACB->pScsiHost->host_lock);
+		}
+	    if (!time_before(jiffies, timeout))
+		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 = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
+		pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
+	    }
+	    else
+		pSRB->SGToBeXferLen = 0;
+	}
+	else
+	{
+	    ResidCnt  = (u32) DC390_read8 (Current_Fifo) & 0x1f;
+	    ResidCnt |= (u32) DC390_read8 (CtcReg_High) << 16;
+	    ResidCnt |= (u32) DC390_read8 (CtcReg_Mid) << 8; 
+	    ResidCnt += (u32) DC390_read8 (CtcReg_Low);
+
+	    xferCnt = pSRB->SGToBeXferLen - ResidCnt;
+	    pSRB->SGBusAddr += xferCnt;
+	    pSRB->TotalXferredLen += xferCnt;
+	    pSRB->SGToBeXferLen = ResidCnt;
+	}
+    }
+    if ((*psstatus & 7) != SCSI_DATA_OUT)
+    {
+	    DC390_write8 (DMA_Cmd, WRITE_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
+	    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
+    }	    
+}
+
+static void
+dc390_DataIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
+{
+    u8   sstatus, residual, bval;
+    struct scatterlist *psgl;
+    u32    ResidCnt, i;
+    unsigned long   xferCnt;
+    u8      *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 dstate = 0;
+	    unsigned long timeout = jiffies + HZ;
+
+	    /* Function called from the ISR with the host_lock held and interrupts disabled */
+	    if (pSRB->SGToBeXferLen)
+		while (time_before(jiffies, timeout) && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE)) {
+		    spin_unlock_irq(pACB->pScsiHost->host_lock);
+		    udelay(50);
+		    spin_lock_irq(pACB->pScsiHost->host_lock);
+		}
+	    if (!time_before(jiffies, timeout)) {
+		printk (KERN_CRIT "DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!\n",
+			DC390_read32 (DMA_Wk_ByteCntr));
+		printk (KERN_CRIT "DC390: DataIn_0: DMA State: %i\n", dstate);
+	    }
+	    dc390_laststatus &= ~0xff000000;
+	    dc390_laststatus |= dstate << 24;
+	    DEBUG1(ResidCnt = ((unsigned long) DC390_read8 (CtcReg_High) << 16)	\
+		+ ((unsigned long) DC390_read8 (CtcReg_Mid) << 8)		\
+		+ ((unsigned long) DC390_read8 (CtcReg_Low)));
+	    DEBUG1(printk (KERN_DEBUG "Count_2_Zero (ResidCnt=%i,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 = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
+		pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
+	    }
+	    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 %i times DMA_Status %02x", 0xa000-i, bval));
+	    ResidCnt = (u32) DC390_read8 (CtcReg_High);
+	    ResidCnt <<= 8;
+	    ResidCnt |= (u32) DC390_read8 (CtcReg_Mid);
+	    ResidCnt <<= 8;
+	    ResidCnt |= (u32) 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 = (u8 *) 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));
+
+	}
+    }
+    if ((*psstatus & 7) != SCSI_DATA_IN)
+    {
+	    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
+	    DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
+    }
+}
+
+static void
+dc390_Command_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
+{
+}
+
+static void
+dc390_Status_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *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);
+}
+
+static void
+dc390_MsgOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
+{
+    if( pSRB->SRBState & (SRB_UNEXPECT_RESEL+SRB_ABORT_SENT) )
+	*psstatus = SCSI_NOP0;
+    //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
+}
+
+
+static void __inline__
+dc390_reprog (struct dc390_acb* pACB, struct dc390_dcb* 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 (u8 *MsgBuf, u8 len)
+{
+  int i;
+  printk (" %02x", MsgBuf[0]);
+  for (i = 1; i < len; i++)
+    printk (" %02x", MsgBuf[i]);
+  printk ("\n");
+}
+#endif
+
+#define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD)
+
+/* reject_msg */
+static void __inline__
+dc390_MsgIn_reject (struct dc390_acb* pACB, struct dc390_srb* pSRB)
+{
+  pSRB->MsgOutBuf[0] = MESSAGE_REJECT;
+  pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
+  DEBUG0 (printk (KERN_INFO "DC390: Reject message\n"));
+}
+
+/* abort command */
+static void
+dc390_EnableMsgOut_Abort ( struct dc390_acb* pACB, struct dc390_srb* pSRB )
+{
+    pSRB->MsgOutBuf[0] = ABORT; 
+    pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
+    pSRB->pSRBDCB->DCBFlag &= ~ABORT_DEV_;
+}
+
+static struct dc390_srb*
+dc390_MsgIn_QTag (struct dc390_acb* pACB, struct dc390_dcb* pDCB, s8 tag)
+{
+  struct dc390_srb* lastSRB = pDCB->pGoingLast;
+  struct dc390_srb* 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->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] = ABORT_TAG;
+      pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
+    }
+  return pSRB;
+}
+
+
+/* set async transfer mode */
+static void 
+dc390_MsgIn_set_async (struct dc390_acb* pACB, struct dc390_srb* pSRB)
+{
+  struct dc390_dcb* pDCB = pSRB->pSRBDCB;
+  if (!(pSRB->SRBState & DO_SYNC_NEGO)) 
+    printk (KERN_INFO "DC390: Target %i initiates Non-Sync?\n", pDCB->TargetID);
+  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 (struct dc390_acb* pACB, struct dc390_srb* pSRB)
+{
+  u8 bval;
+  u16 wval, wval1;
+  struct dc390_dcb* pDCB = pSRB->pSRBDCB;
+  u8 oldsyncperiod = pDCB->SyncPeriod;
+  u8 oldsyncoffset = pDCB->SyncOffset;
+  
+  if (!(pSRB->SRBState & DO_SYNC_NEGO))
+    {
+      printk (KERN_INFO "DC390: Target %i initiates Sync: %ins %i ... answer ...\n", 
+	      pDCB->TargetID, 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 (KERN_INFO "DC390: Lower Sync Offset to 15\n");
+	  pSRB->MsgInBuf[4] = 15;
+	}
+      if (pSRB->MsgInBuf[3] < pDCB->NegoPeriod)
+	{
+	  printk (KERN_INFO "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;
+    }
+
+  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 = (u16) 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 = (u8)wval1;
+  
+  if ((oldsyncperiod != wval1 || oldsyncoffset != pDCB->SyncOffset) && pDCB->TargetLUN == 0)
+    {
+      if (! (bval & FAST_SCSI)) wval1++;
+      printk (KERN_INFO "DC390: Target %i: Sync transfer %i.%1i MHz, Offset %i\n", pDCB->TargetID, 
+	      40/wval1, ((40%wval1)*10+wval1/2)/wval1, pDCB->SyncOffset & 0x0f);
+    }
+  
+  dc390_reprog (pACB, pDCB);
+}
+
+
+/* handle RESTORE_PTR */
+/* I presume, this command is already mapped, so, have to remap. */
+static void 
+dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB)
+{
+    struct scsi_cmnd *pcmd = pSRB->pcmd;
+    struct scatterlist *psgl;
+    pSRB->TotalXferredLen = 0;
+    pSRB->SGIndex = 0;
+    if (pcmd->use_sg) {
+	pSRB->pSegmentList = (struct scatterlist *)pcmd->request_buffer;
+	psgl = pSRB->pSegmentList;
+	//dc390_pci_sync(pSRB);
+
+	while (pSRB->TotalXferredLen + (unsigned long) sg_dma_len(psgl) < pSRB->Saved_Ptr)
+	{
+	    pSRB->TotalXferredLen += (unsigned long) sg_dma_len(psgl);
+	    pSRB->SGIndex++;
+	    if( pSRB->SGIndex < pSRB->SGcount )
+	    {
+		pSRB->pSegmentList++;
+		psgl = pSRB->pSegmentList;
+		pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
+		pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
+	    }
+	    else
+		pSRB->SGToBeXferLen = 0;
+	}
+	pSRB->SGToBeXferLen -= (pSRB->Saved_Ptr - pSRB->TotalXferredLen);
+	pSRB->SGBusAddr += (pSRB->Saved_Ptr - pSRB->TotalXferredLen);
+	printk (KERN_INFO "DC390: Pointer restored. Segment %i, Total %li, Bus %08lx\n",
+		pSRB->SGIndex, pSRB->Saved_Ptr, pSRB->SGBusAddr);
+
+    } else if(pcmd->request_buffer) {
+	//dc390_pci_sync(pSRB);
+
+	sg_dma_len(&pSRB->Segmentx) = pcmd->request_bufflen - pSRB->Saved_Ptr;
+	pSRB->SGcount = 1;
+	pSRB->pSegmentList = (struct scatterlist *) &pSRB->Segmentx;
+    } else {
+	 pSRB->SGcount = 0;
+	 printk (KERN_INFO "DC390: RESTORE_PTR message for Transfer without Scatter-Gather ??\n");
+    }
+
+  pSRB->TotalXferredLen = pSRB->Saved_Ptr;
+}
+
+
+/* According to the docs, the AM53C974 reads the message and 
+ * generates a Successful Operation IRQ before asserting ACK for
+ * the last byte (how does it know whether it's the last ?) */
+/* The old code handled it in another way, indicating, that on
+ * every message byte an IRQ is generated and every byte has to
+ * be manually ACKed. Hmmm ?  (KG, 98/11/28) */
+/* The old implementation was correct. Sigh! */
+
+/* Check if the message is complete */
+static u8 __inline__
+dc390_MsgIn_complete (u8 *msgbuf, u32 len)
+{ 
+  if (*msgbuf == EXTENDED_MESSAGE)
+  {
+	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 */
+static void
+dc390_MsgIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
+{
+    struct dc390_dcb*   pDCB = pACB->pActiveDCB;
+
+    /* 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 DISCONNECT: 
+	    pSRB->SRBState = SRB_DISCONNECT; break;
+	    
+	  case SIMPLE_QUEUE_TAG:
+	  case HEAD_OF_QUEUE_TAG:
+	  case ORDERED_QUEUE_TAG:
+	    pSRB = dc390_MsgIn_QTag (pACB, pDCB, pSRB->MsgInBuf[1]);
+	    break;
+	    
+	  case MESSAGE_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 EXTENDED_MESSAGE:
+	    /* 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 COMMAND_COMPLETE: break;
+	    
+	    // SAVE POINTER may be ignored as we have the struct dc390_srb* associated with the
+	    // scsi command. Thanks, Gerard, for pointing it out.
+	  case SAVE_POINTERS: 
+	    pSRB->Saved_Ptr = pSRB->TotalXferredLen;
+	    break;
+	    // The device might want to restart transfer with a RESTORE
+	  case RESTORE_POINTERS:
+	    DEBUG0(printk ("DC390: RESTORE POINTER message received ... try to handle\n"));
+	    dc390_restore_ptr (pACB, pSRB);
+	    break;
+
+	    // 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);
+}
+
+
+static void
+dc390_DataIO_Comm( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 ioDir)
+{
+    struct scatterlist *psgl;
+    unsigned long  lval;
+    struct dc390_dcb*   pDCB = pACB->pActiveDCB;
+
+    if (pSRB == pACB->pTmpSRB)
+    {
+	if (pDCB)
+		printk(KERN_ERR "DC390: pSRB == pTmpSRB! (TagQ Error?) (%02i-%i)\n", pDCB->TargetID, pDCB->TargetLUN);
+	else
+		printk(KERN_ERR "DC390: pSRB == pTmpSRB! (TagQ Error?) (DCB 0!)\n");
+
+	/* Try to recover - some broken disks react badly to tagged INQUIRY */
+	if (pDCB && pACB->scan_devices && pDCB->GoingSRBCnt == 1) {
+		pSRB = pDCB->pGoingSRB;
+		pDCB->pActiveSRB = pSRB;
+	} else {
+		pSRB->pSRBDCB = pDCB;
+		dc390_EnableMsgOut_Abort(pACB, pSRB);
+		if (pDCB)
+			pDCB->DCBFlag |= ABORT_DEV;
+		return;
+	}
+    }
+
+    if( pSRB->SGIndex < pSRB->SGcount )
+    {
+	DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir /* | DMA_INT */);
+	if( !pSRB->SGToBeXferLen )
+	{
+	    psgl = pSRB->pSegmentList;
+	    pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
+	    pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
+	    DEBUG1(printk (KERN_DEBUG " DC390: Next SG segment."));
+	}
+	lval = pSRB->SGToBeXferLen;
+	DEBUG1(printk (KERN_DEBUG " DC390: Start transfer: %li bytes (address %08lx)\n", lval, pSRB->SGBusAddr));
+	DC390_write8 (CtcReg_Low, (u8) lval);
+	lval >>= 8;
+	DC390_write8 (CtcReg_Mid, (u8) lval);
+	lval >>= 8;
+	DC390_write8 (CtcReg_High, (u8) 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);
+/*
+	DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); // | DMA_INT;
+	DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
+*/
+    }
+}
+
+
+static void
+dc390_DataOutPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
+{
+    dc390_DataIO_Comm (pACB, pSRB, WRITE_DIRECTION);
+}
+
+static void
+dc390_DataInPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
+{
+    dc390_DataIO_Comm (pACB, pSRB, READ_DIRECTION);
+}
+
+static void
+dc390_CommandPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
+{
+    struct dc390_dcb*   pDCB;
+    u8  i, cnt;
+    u8     *ptr;
+
+    DC390_write8 (ScsiCmd, RESET_ATN_CMD);
+    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
+    if( !(pSRB->SRBFlag & AUTO_REQSENSE) )
+    {
+	cnt = (u8) pSRB->pcmd->cmd_len;
+	ptr = (u8 *) pSRB->pcmd->cmnd;
+	for(i=0; i < cnt; i++)
+	    DC390_write8 (ScsiFifo, *(ptr++));
+    }
+    else
+    {
+	u8 bval = 0;
+	DC390_write8 (ScsiFifo, REQUEST_SENSE);
+	pDCB = pACB->pActiveDCB;
+	DC390_write8 (ScsiFifo, pDCB->TargetLUN << 5);
+	DC390_write8 (ScsiFifo, bval);
+	DC390_write8 (ScsiFifo, bval);
+	DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
+	DC390_write8 (ScsiFifo, bval);
+	DEBUG0(printk(KERN_DEBUG "DC390: AutoReqSense (CmndPhase)!\n"));
+    }
+    pSRB->SRBState = SRB_COMMAND;
+    DC390_write8 (ScsiCmd, INFO_XFER_CMD);
+}
+
+static void
+dc390_StatusPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
+{
+    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
+    pSRB->SRBState = SRB_STATUS;
+    DC390_write8 (ScsiCmd, INITIATOR_CMD_CMPLTE);
+    //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
+}
+
+static void
+dc390_MsgOutPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
+{
+    u8   bval, i, cnt;
+    u8     *ptr;
+    struct dc390_dcb*    pDCB;
+
+    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
+    pDCB = pACB->pActiveDCB;
+    if( !(pSRB->SRBState & SRB_MSGOUT) )
+    {
+	cnt = pSRB->MsgCnt;
+	if( cnt )
+	{
+	    ptr = (u8 *) pSRB->MsgOutBuf;
+	    for(i=0; i < cnt; i++)
+		DC390_write8 (ScsiFifo, *(ptr++));
+	    pSRB->MsgCnt = 0;
+	    if( (pDCB->DCBFlag & ABORT_DEV_) &&
+		(pSRB->MsgOutBuf[0] == ABORT) )
+		pSRB->SRBState = SRB_ABORT_SENT;
+	}
+	else
+	{
+	    bval = ABORT;	/* ??? MSG_NOP */
+	    if( (pSRB->pcmd->cmnd[0] == INQUIRY ) ||
+		(pSRB->pcmd->cmnd[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 (KERN_ERR "DC390: OLD Sync Nego code triggered! (%i %i)\n", pDCB->TargetID, pDCB->TargetLUN);
+	DC390_write8 (ScsiFifo, EXTENDED_MESSAGE);
+	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( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *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);
+}
+
+static void
+dc390_Nop_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
+{
+}
+
+static void
+dc390_Nop_1( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
+{
+}
+
+
+static void
+dc390_SetXferRate( struct dc390_acb* pACB, struct dc390_dcb* pDCB )
+{
+    u8  bval, i, cnt;
+    struct dc390_dcb*   ptr;
+
+    if( !(pDCB->TargetLUN) )
+    {
+	if( !pACB->scan_devices )
+	{
+	    ptr = pACB->pLinkDCB;
+	    cnt = pACB->DCBCnt;
+	    bval = pDCB->TargetID;
+	    for(i=0; i<cnt; i++)
+	    {
+		if( ptr->TargetID == 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;
+}
+
+
+static void
+dc390_Disconnect( struct dc390_acb* pACB )
+{
+    struct dc390_dcb *pDCB;
+    struct dc390_srb *pSRB, *psrb;
+    u8  i, cnt;
+
+    DEBUG0(printk(KERN_INFO "DISC,"));
+
+    if (!pACB->Connected) printk(KERN_ERR "DC390: Disconnect not-connected bus?\n");
+    pACB->Connected = 0;
+    pDCB = pACB->pActiveDCB;
+    if (!pDCB)
+     {
+	DEBUG0(printk(KERN_ERR "ACB:%p->ActiveDCB:%p IOPort:%04x IRQ:%02x !\n",\
+	       pACB, pDCB, pACB->IOPortBase, pACB->IRQLevel));
+	mdelay(400);
+	DC390_read8 (INT_Status);	/* Reset Pending INT */
+	DC390_write8 (ScsiCmd, EN_SEL_RESEL);
+	return;
+     }
+    DC390_write8 (ScsiCmd, EN_SEL_RESEL);
+    pSRB = pDCB->pActiveSRB;
+    pACB->pActiveDCB = 0;
+    pSRB->ScsiPhase = SCSI_NOP0;
+    if( pSRB->SRBState & SRB_UNEXPECT_RESEL )
+	pSRB->SRBState = 0;
+    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;
+	    dc390_Free_insert (pACB, pSRB);
+	    pSRB = psrb;
+	}
+	pDCB->pGoingSRB = 0;
+    }
+    else
+    {
+	if( (pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) ||
+	   !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED)) )
+	{	/* Selection time out */
+		pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT;
+		goto  disc1;
+	}
+	else if (!(pSRB->SRBState & SRB_DISCONNECT) && (pSRB->SRBState & SRB_COMPLETED))
+	{
+disc1:
+	    dc390_freetag (pDCB, pSRB);
+	    pDCB->pActiveSRB = 0;
+	    pSRB->SRBState = SRB_FREE;
+	    dc390_SRBdone( pACB, pDCB, pSRB);
+	}
+    }
+    pACB->MsgLen = 0;
+}
+
+
+static void
+dc390_Reselect( struct dc390_acb* pACB )
+{
+    struct dc390_dcb*   pDCB;
+    struct dc390_srb*   pSRB;
+    u8  id, lun;
+
+    DEBUG0(printk(KERN_INFO "RSEL,"));
+    pACB->Connected = 1;
+    pDCB = pACB->pActiveDCB;
+    if( pDCB )
+    {	/* Arbitration lost but Reselection won */
+	DEBUG0(printk ("DC390: (ActiveDCB != 0: Arb. lost but resel. won)!\n"));
+	pSRB = pDCB->pActiveSRB;
+	if( !( pACB->scan_devices ) )
+	{
+	    struct scsi_cmnd *pcmd = pSRB->pcmd;
+	    pcmd->resid = pcmd->request_bufflen;
+	    SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
+	    dc390_Going_remove(pDCB, pSRB);
+	    dc390_Free_insert(pACB, pSRB);
+	    pcmd->scsi_done (pcmd);
+	    DEBUG0(printk(KERN_DEBUG"DC390: Return SRB %p to free\n", pSRB));
+	}
+    }
+    /* Get ID */
+    lun = DC390_read8 (ScsiFifo);
+    DEBUG0(printk ("Dev %02x,", lun));
+    if (!(lun & (1 << pACB->pScsiHost->this_id)))
+      printk (KERN_ERR "DC390: Reselection must select host adapter: %02x!\n", lun);
+    else
+      lun ^= 1 << pACB->pScsiHost->this_id; /* Mask AdapterID */
+    id = 0; while (lun >>= 1) id++;
+    /* Get LUN */
+    lun = DC390_read8 (ScsiFifo);
+    if (!(lun & IDENTIFY_BASE)) printk (KERN_ERR "DC390: Resel: Expect identify message!\n");
+    lun &= 7;
+    DEBUG0(printk ("(%02i-%i),", id, lun));
+    pDCB = dc390_findDCB (pACB, id, lun);
+    if (!pDCB)
+    {
+	printk (KERN_ERR "DC390: Reselect from non existing device (%02i-%i)\n",
+		    id, lun);
+	return;
+    }
+    pACB->pActiveDCB = pDCB;
+    /* TagQ: We expect a message soon, so never mind the exact SRB */
+    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 (%02i-%i)\n",
+		    id, lun);
+	    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 (%02i-%i)\n",
+			id, lun);
+		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->TargetID);
+    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 int __inline__
+dc390_RequestSense(struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
+{
+	struct scsi_cmnd *pcmd;
+
+	pcmd = pSRB->pcmd;
+
+	REMOVABLEDEBUG(printk(KERN_INFO "DC390: RequestSense(Cmd %02x, Id %02x, LUN %02x)\n",\
+			      pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN));
+
+	pSRB->SRBFlag |= AUTO_REQSENSE;
+	pSRB->SavedSGCount = pcmd->use_sg;
+	pSRB->SavedTotXLen = pSRB->TotalXferredLen;
+	pSRB->AdaptStatus = 0;
+	pSRB->TargetStatus = 0; /* CHECK_CONDITION<<1; */
+
+	/* We are called from SRBdone, original PCI mapping has been removed
+	 * already, new one is set up from StartSCSI */
+	pSRB->SGIndex = 0;
+
+	pSRB->TotalXferredLen = 0;
+	pSRB->SGToBeXferLen = 0;
+	return dc390_StartSCSI(pACB, pDCB, pSRB);
+}
+
+
+static void
+dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB )
+{
+    u8  bval, status;
+    struct scsi_cmnd *pcmd;
+
+    pcmd = pSRB->pcmd;
+    /* KG: Moved pci_unmap here */
+    dc390_pci_unmap(pSRB);
+
+    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 = CHECK_CONDITION << 1;
+
+	//pcmd->result = MK_RES(DRIVER_SENSE,DID_OK,0,status);
+	if (status == (CHECK_CONDITION << 1))
+	    pcmd->result = MK_RES_LNX(0, DID_BAD_TARGET, 0, /*CHECK_CONDITION*/0);
+	else /* Retry */
+	{
+	    if( pSRB->pcmd->cmnd[0] == TEST_UNIT_READY /* || pSRB->pcmd->cmnd[0] == START_STOP */)
+	    {
+		/* Don't retry on TEST_UNIT_READY */
+		pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION);
+		REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->pcmd->cmnd[0],\
+		       (u32) pcmd->result, (u32) pSRB->TotalXferredLen));
+	    } else {
+		SET_RES_DRV(pcmd->result, DRIVER_SENSE);
+		pcmd->use_sg = pSRB->SavedSGCount;
+		//pSRB->ScsiCmdLen	 = (u8) (pSRB->Segment1[0] >> 8);
+		DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
+		pSRB->TotalXferredLen = 0;
+		SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
+	    }
+	}
+	goto cmd_done;
+    }
+    if( status )
+    {
+	if( status_byte(status) == CHECK_CONDITION )
+	{
+	    if (dc390_RequestSense(pACB, pDCB, pSRB)) {
+		SET_RES_DID(pcmd->result, DID_ERROR);
+		goto cmd_done;
+	    }
+	    return;
+	}
+	else if( status_byte(status) == QUEUE_FULL )
+	{
+	    bval = (u8) pDCB->GoingSRBCnt;
+	    bval--;
+	    pDCB->MaxCommand = bval;
+	    pcmd->use_sg = pSRB->SavedSGCount;
+	    DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
+	    pSRB->TotalXferredLen = 0;
+	    SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
+	}
+	else if(status == SCSI_STAT_SEL_TIMEOUT)
+	{
+	    pSRB->AdaptStatus = H_SEL_TIMEOUT;
+	    pSRB->TargetStatus = 0;
+	    pcmd->result = MK_RES(0,DID_NO_CONNECT,0,0);
+	    /* Devices are removed below ... */
+	}
+	else if (status_byte(status) == BUSY && 
+		 (pcmd->cmnd[0] == TEST_UNIT_READY || pcmd->cmnd[0] == INQUIRY) &&
+		 pACB->scan_devices)
+	{
+	    pSRB->AdaptStatus = 0;
+	    pSRB->TargetStatus = status;
+	    pcmd->result = MK_RES(0,0,pSRB->EndMessage,/*status*/0);
+	}
+	else
+	{   /* Another error */
+	    pSRB->TotalXferredLen = 0;
+	    SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
+	    goto cmd_done;
+	}
+    }
+    else
+    {	/*  Target status == 0 */
+	status = pSRB->AdaptStatus;
+	if(status & H_OVER_UNDER_RUN)
+	{
+	    pSRB->TargetStatus = 0;
+	    SET_RES_DID(pcmd->result,DID_OK);
+	    SET_RES_MSG(pcmd->result,pSRB->EndMessage);
+	}
+	else if( pSRB->SRBStatus & PARITY_ERROR)
+	{
+	    //pcmd->result = MK_RES(0,DID_PARITY,pSRB->EndMessage,0);
+	    SET_RES_DID(pcmd->result,DID_PARITY);
+	    SET_RES_MSG(pcmd->result,pSRB->EndMessage);
+	}
+	else		       /* No error */
+	{
+	    pSRB->AdaptStatus = 0;
+	    pSRB->TargetStatus = 0;
+	    SET_RES_DID(pcmd->result,DID_OK);
+	}
+    }
+
+cmd_done:
+    pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen;
+
+    dc390_Going_remove (pDCB, pSRB);
+    /* Add to free list */
+    dc390_Free_insert (pACB, pSRB);
+
+    DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done pid %li\n", pcmd->pid));
+    pcmd->scsi_done (pcmd);
+
+    return;
+}
+
+
+/* Remove all SRBs from Going list and inform midlevel */
+static void
+dc390_DoingSRB_Done(struct dc390_acb* pACB, struct scsi_cmnd *cmd)
+{
+    struct dc390_dcb *pDCB, *pdcb;
+    struct dc390_srb *psrb, *psrb2;
+    u8  i;
+    struct scsi_cmnd *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;
+	    dc390_Free_insert (pACB, psrb);
+	    psrb  = psrb2;
+	}
+	pdcb->GoingSRBCnt = 0;
+	pdcb->pGoingSRB = NULL;
+	pdcb->TagMask = 0;
+	pdcb = pdcb->pNextDCB;
+    } while( pdcb != pDCB );
+}
+
+
+static void
+dc390_ResetSCSIBus( struct dc390_acb* pACB )
+{
+    //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);
+    pACB->Connected = 0;
+
+    return;
+}
+
+static void
+dc390_ScsiRstDetect( struct dc390_acb* pACB )
+{
+    printk ("DC390: Rst_Detect: laststat = %08x\n", dc390_laststatus);
+    //DEBUG0(printk(KERN_INFO "RST_DETECT,"));
+
+    DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
+    /* Unlock before ? */
+    /* delay half a second */
+    udelay (1000);
+    DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
+    pACB->pScsiHost->last_reset = jiffies + 5*HZ/2
+		    + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
+    pACB->Connected = 0;
+
+    if( pACB->ACBFlag & RESET_DEV )
+	pACB->ACBFlag |= RESET_DONE;
+    else
+    {   /* Reset was issued by sb else */
+	pACB->ACBFlag |= RESET_DETECT;
+
+	dc390_ResetDevParam( pACB );
+	dc390_DoingSRB_Done( pACB, 0 );
+	//dc390_RecoverSRB( pACB );
+	pACB->pActiveDCB = NULL;
+	pACB->ACBFlag = 0;
+    }
+    return;
+}
+
 static int DC390_queuecommand(struct scsi_cmnd *cmd,
 		void (*done)(struct scsi_cmnd *))
 {
@@ -660,9 +2153,6 @@
 
 	return SUCCESS;
 }
-
-#include "scsiiom.c"
-
 
 /**
  * dc390_slave_alloc - Called by the scsi mid layer to tell us about a new

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] merge scsiiom.c into tmscsim.c
  2004-10-03 13:47 [PATCH] merge scsiiom.c into tmscsim.c Christoph Hellwig
@ 2004-10-03 20:42 ` Guennadi Liakhovetski
  2004-10-09 12:29 ` Christoph Hellwig
  2007-06-17 15:09 ` Guennadi Liakhovetski
  2 siblings, 0 replies; 8+ messages in thread
From: Guennadi Liakhovetski @ 2004-10-03 20:42 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: jejb, linux-scsi

On Sun, 3 Oct 2004, Christoph Hellwig wrote:

> might be a good time to get rid of that clumsy include .c file into
> another one thing.  (Also please bk rm scsiiom.c afterwards)

Accepted:-)

Thanks
Guennadi
---
Guennadi Liakhovetski


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] merge scsiiom.c into tmscsim.c
  2004-10-03 13:47 [PATCH] merge scsiiom.c into tmscsim.c Christoph Hellwig
  2004-10-03 20:42 ` Guennadi Liakhovetski
@ 2004-10-09 12:29 ` Christoph Hellwig
  2004-10-09 13:02   ` James Bottomley
  2007-06-17 15:09 ` Guennadi Liakhovetski
  2 siblings, 1 reply; 8+ messages in thread
From: Christoph Hellwig @ 2004-10-09 12:29 UTC (permalink / raw)
  To: g.liakhovetski, jejb; +Cc: linux-scsi

On Sun, Oct 03, 2004 at 03:47:14PM +0200, Christoph Hellwig wrote:
> might be a good time to get rid of that clumsy include .c file into
> another one thing.  (Also please bk rm scsiiom.c afterwards)

And here's a patch ontop that restores's Al's sparse fixes done in
scsiiom.c (the old patch still applies and works without this one,
but without it you get a few more sparse warnings):


--- linux/drivers/scsi/tmscsim.c~	2004-10-09 14:29:45.772931256 +0200
+++ linux/drivers/scsi/tmscsim.c	2004-10-09 14:30:45.486905632 +0200
@@ -1624,7 +1624,7 @@
      }
     DC390_write8 (ScsiCmd, EN_SEL_RESEL);
     pSRB = pDCB->pActiveSRB;
-    pACB->pActiveDCB = 0;
+    pACB->pActiveDCB = NULL;
     pSRB->ScsiPhase = SCSI_NOP0;
     if( pSRB->SRBState & SRB_UNEXPECT_RESEL )
 	pSRB->SRBState = 0;
@@ -1641,7 +1641,7 @@
 	    dc390_Free_insert (pACB, pSRB);
 	    pSRB = psrb;
 	}
-	pDCB->pGoingSRB = 0;
+	pDCB->pGoingSRB = NULL;
     }
     else
     {
@@ -1655,7 +1655,7 @@
 	{
 disc1:
 	    dc390_freetag (pDCB, pSRB);
-	    pDCB->pActiveSRB = 0;
+	    pDCB->pActiveSRB = NULL;
 	    pSRB->SRBState = SRB_FREE;
 	    dc390_SRBdone( pACB, pDCB, pSRB);
 	}
@@ -1967,7 +1967,7 @@
 	pACB->ACBFlag |= RESET_DETECT;
 
 	dc390_ResetDevParam( pACB );
-	dc390_DoingSRB_Done( pACB, 0 );
+	dc390_DoingSRB_Done( pACB, NULL);
 	//dc390_RecoverSRB( pACB );
 	pACB->pActiveDCB = NULL;
 	pACB->ACBFlag = 0;

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] merge scsiiom.c into tmscsim.c
  2004-10-09 12:29 ` Christoph Hellwig
@ 2004-10-09 13:02   ` James Bottomley
  2004-10-09 19:18     ` Guennadi Liakhovetski
  0 siblings, 1 reply; 8+ messages in thread
From: James Bottomley @ 2004-10-09 13:02 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: g.liakhovetski, SCSI Mailing List

On Sat, 2004-10-09 at 07:29, Christoph Hellwig wrote:
> On Sun, Oct 03, 2004 at 03:47:14PM +0200, Christoph Hellwig wrote:
> > might be a good time to get rid of that clumsy include .c file into
> > another one thing.  (Also please bk rm scsiiom.c afterwards)
> 
> And here's a patch ontop that restores's Al's sparse fixes done in
> scsiiom.c (the old patch still applies and works without this one,
> but without it you get a few more sparse warnings):

I can't apply this patch without previously applying the tmscsim: remove
remaining INQUIRY sniffing.  In reply to that patch Guennadi said:

    So, I just wanted to let the so far submitted patches settle down a
    bit, at least hear some reaction to them, and then submit this one.
    But yours looks a bit better: I overlooked the possibility to do
    srb->pcmd->device, and added a dcb->sdev pointer to get to sdtr. So,
    be it yours.
    
Which I interpreted to mean wait a while before applying.

So, I can either apply both or neither.  Which is it to be?

James



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] merge scsiiom.c into tmscsim.c
  2004-10-09 13:02   ` James Bottomley
@ 2004-10-09 19:18     ` Guennadi Liakhovetski
  0 siblings, 0 replies; 8+ messages in thread
From: Guennadi Liakhovetski @ 2004-10-09 19:18 UTC (permalink / raw)
  To: James Bottomley; +Cc: Christoph Hellwig, SCSI Mailing List

On Sat, 9 Oct 2004, James Bottomley wrote:

> On Sat, 2004-10-09 at 07:29, Christoph Hellwig wrote:
> 
> I can't apply this patch without previously applying the tmscsim: remove
> remaining INQUIRY sniffing.  In reply to that patch Guennadi said:
> 
>     So, I just wanted to let the so far submitted patches settle down a
>     bit, at least hear some reaction to them, and then submit this one.
>     But yours looks a bit better: I overlooked the possibility to do
>     srb->pcmd->device, and added a dcb->sdev pointer to get to sdtr. So,
>     be it yours.
>     
> Which I interpreted to mean wait a while before applying.
> 
> So, I can either apply both or neither.  Which is it to be?

Sorry, James, Christoph. I wasn't clear enough in that my email. I just 
explained that I also had a patch to address the same problem, and just 
was waiting for some reaction to the previous pretty risky patch before 
submitting further ones. And I did say that Christoph's patch was a bit 
better. So, if you and Christoph have nothing against my "remove internal 
command queueing" patch, then we can move further, so, please, apply all 
(3 so far, I think?) Christoph's patches too.

Thanks
Guennadi
---
Guennadi Liakhovetski


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] merge scsiiom.c into tmscsim.c
  2004-10-03 13:47 [PATCH] merge scsiiom.c into tmscsim.c Christoph Hellwig
  2004-10-03 20:42 ` Guennadi Liakhovetski
  2004-10-09 12:29 ` Christoph Hellwig
@ 2007-06-17 15:09 ` Guennadi Liakhovetski
  2007-06-17 16:25   ` Boaz Harrosh
  2 siblings, 1 reply; 8+ messages in thread
From: Guennadi Liakhovetski @ 2007-06-17 15:09 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-scsi

Hi Christoph,

On Sun, 3 Oct 2004, Christoph Hellwig wrote:

> might be a good time to get rid of that clumsy include .c file into
> another one thing.  (Also please bk rm scsiiom.c afterwards)

You certainly will have no problem at all remembering this patch, will 
you?:-) It's only less than 3 years ago... Sure, you'll also have no 
problem answering a couple of my simple questions to this patch... 
Specifically, this place in it:

> --- 1.56/drivers/scsi/tmscsim.c	2004-10-03 15:43:04 +02:00
> +++ edited/drivers/scsi/tmscsim.c	2004-10-03 15:48:31 +02:00
> @@ -252,7 +252,7 @@

[snip]

> +static int __inline__
> +dc390_RequestSense(struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
> +{
> +	struct scsi_cmnd *pcmd;
> +
> +	pcmd = pSRB->pcmd;
> +
> +	REMOVABLEDEBUG(printk(KERN_INFO "DC390: RequestSense(Cmd %02x, Id %02x, LUN %02x)\n",\
> +			      pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN));
> +
> +	pSRB->SRBFlag |= AUTO_REQSENSE;
> +	pSRB->SavedSGCount = pcmd->use_sg;
> +	pSRB->SavedTotXLen = pSRB->TotalXferredLen;
> +	pSRB->AdaptStatus = 0;
> +	pSRB->TargetStatus = 0; /* CHECK_CONDITION<<1; */
> +
> +	/* We are called from SRBdone, original PCI mapping has been removed
> +	 * already, new one is set up from StartSCSI */
> +	pSRB->SGIndex = 0;
> +
> +	pSRB->TotalXferredLen = 0;
> +	pSRB->SGToBeXferLen = 0;
> +	return dc390_StartSCSI(pACB, pDCB, pSRB);
> +}
> +
> +
> +static void
> +dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB )
> +{
> +    u8  bval, status;
> +    struct scsi_cmnd *pcmd;
> +
> +    pcmd = pSRB->pcmd;
> +    /* KG: Moved pci_unmap here */
> +    dc390_pci_unmap(pSRB);
> +
> +    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 */

Here we come in after Request Sense above.

> +	pSRB->SRBFlag &= ~AUTO_REQSENSE;
> +	pSRB->AdaptStatus = 0;
> +	pSRB->TargetStatus = CHECK_CONDITION << 1;
> +
> +	//pcmd->result = MK_RES(DRIVER_SENSE,DID_OK,0,status);
> +	if (status == (CHECK_CONDITION << 1))
> +	    pcmd->result = MK_RES_LNX(0, DID_BAD_TARGET, 0, /*CHECK_CONDITION*/0);
> +	else /* Retry */
> +	{
> +	    if( pSRB->pcmd->cmnd[0] == TEST_UNIT_READY /* || pSRB->pcmd->cmnd[0] == START_STOP */)
> +	    {
> +		/* Don't retry on TEST_UNIT_READY */
> +		pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION);
> +		REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->pcmd->cmnd[0],\
> +		       (u32) pcmd->result, (u32) pSRB->TotalXferredLen));
> +	    } else {
> +		SET_RES_DRV(pcmd->result, DRIVER_SENSE);
> +		pcmd->use_sg = pSRB->SavedSGCount;
> +		//pSRB->ScsiCmdLen	 = (u8) (pSRB->Segment1[0] >> 8);
> +		DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
> +		pSRB->TotalXferredLen = 0;
> +		SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
> +	    }
> +	}
> +	goto cmd_done;

And here we jump out.

> +    }
> +    if( status )
> +    {

Therefore here we come only if we didn't request sense before.

> +	if( status_byte(status) == CHECK_CONDITION )
> +	{
> +	    if (dc390_RequestSense(pACB, pDCB, pSRB)) {
> +		SET_RES_DID(pcmd->result, DID_ERROR);
> +		goto cmd_done;
> +	    }
> +	    return;
> +	}
> +	else if( status_byte(status) == QUEUE_FULL )
> +	{
> +	    bval = (u8) pDCB->GoingSRBCnt;
> +	    bval--;
> +	    pDCB->MaxCommand = bval;
> +	    pcmd->use_sg = pSRB->SavedSGCount;

Now, this I don't understand. If we didn't request sense, SavedSGCount is 
not defined, is it?...

Thanks and sorry for taking you on a time-travel
Guennadi
---
Guennadi Liakhovetski

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] merge scsiiom.c into tmscsim.c
  2007-06-17 15:09 ` Guennadi Liakhovetski
@ 2007-06-17 16:25   ` Boaz Harrosh
  2007-06-17 18:09     ` Guennadi Liakhovetski
  0 siblings, 1 reply; 8+ messages in thread
From: Boaz Harrosh @ 2007-06-17 16:25 UTC (permalink / raw)
  To: Guennadi Liakhovetski; +Cc: Christoph Hellwig, linux-scsi

Guennadi Liakhovetski wrote:
> Hi Christoph,
> 
> On Sun, 3 Oct 2004, Christoph Hellwig wrote:
> 
>> might be a good time to get rid of that clumsy include .c file into
>> another one thing.  (Also please bk rm scsiiom.c afterwards)
> 
> You certainly will have no problem at all remembering this patch, will 
> you?:-) It's only less than 3 years ago... Sure, you'll also have no 
> problem answering a couple of my simple questions to this patch... 
> Specifically, this place in it:
> 
>> --- 1.56/drivers/scsi/tmscsim.c	2004-10-03 15:43:04 +02:00
>> +++ edited/drivers/scsi/tmscsim.c	2004-10-03 15:48:31 +02:00
>> @@ -252,7 +252,7 @@
> 
> [snip]
> 
>> +static int __inline__
>> +dc390_RequestSense(struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
>> +{
>> +	struct scsi_cmnd *pcmd;
>> +
>> +	pcmd = pSRB->pcmd;
>> +
>> +	REMOVABLEDEBUG(printk(KERN_INFO "DC390: RequestSense(Cmd %02x, Id %02x, LUN %02x)\n",\
>> +			      pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN));
>> +
>> +	pSRB->SRBFlag |= AUTO_REQSENSE;
>> +	pSRB->SavedSGCount = pcmd->use_sg;
>> +	pSRB->SavedTotXLen = pSRB->TotalXferredLen;
>> +	pSRB->AdaptStatus = 0;
>> +	pSRB->TargetStatus = 0; /* CHECK_CONDITION<<1; */
>> +
>> +	/* We are called from SRBdone, original PCI mapping has been removed
>> +	 * already, new one is set up from StartSCSI */
>> +	pSRB->SGIndex = 0;
>> +
>> +	pSRB->TotalXferredLen = 0;
>> +	pSRB->SGToBeXferLen = 0;
>> +	return dc390_StartSCSI(pACB, pDCB, pSRB);
>> +}
>> +
>> +
>> +static void
>> +dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB )
>> +{
>> +    u8  bval, status;
>> +    struct scsi_cmnd *pcmd;
>> +
>> +    pcmd = pSRB->pcmd;
>> +    /* KG: Moved pci_unmap here */
>> +    dc390_pci_unmap(pSRB);
>> +
>> +    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 */
> 
> Here we come in after Request Sense above.
> 
>> +	pSRB->SRBFlag &= ~AUTO_REQSENSE;
>> +	pSRB->AdaptStatus = 0;
>> +	pSRB->TargetStatus = CHECK_CONDITION << 1;
>> +
>> +	//pcmd->result = MK_RES(DRIVER_SENSE,DID_OK,0,status);
>> +	if (status == (CHECK_CONDITION << 1))
>> +	    pcmd->result = MK_RES_LNX(0, DID_BAD_TARGET, 0, /*CHECK_CONDITION*/0);
>> +	else /* Retry */
>> +	{
>> +	    if( pSRB->pcmd->cmnd[0] == TEST_UNIT_READY /* || pSRB->pcmd->cmnd[0] == START_STOP */)
>> +	    {
>> +		/* Don't retry on TEST_UNIT_READY */
>> +		pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION);
>> +		REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->pcmd->cmnd[0],\
>> +		       (u32) pcmd->result, (u32) pSRB->TotalXferredLen));
>> +	    } else {
>> +		SET_RES_DRV(pcmd->result, DRIVER_SENSE);
>> +		pcmd->use_sg = pSRB->SavedSGCount;
>> +		//pSRB->ScsiCmdLen	 = (u8) (pSRB->Segment1[0] >> 8);
>> +		DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
>> +		pSRB->TotalXferredLen = 0;
>> +		SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
>> +	    }
>> +	}
>> +	goto cmd_done;
> 
> And here we jump out.
> 
>> +    }
>> +    if( status )
>> +    {
> 
> Therefore here we come only if we didn't request sense before.
> 
>> +	if( status_byte(status) == CHECK_CONDITION )
>> +	{
>> +	    if (dc390_RequestSense(pACB, pDCB, pSRB)) {
>> +		SET_RES_DID(pcmd->result, DID_ERROR);
>> +		goto cmd_done;
>> +	    }
>> +	    return;
>> +	}
>> +	else if( status_byte(status) == QUEUE_FULL )
>> +	{
>> +	    bval = (u8) pDCB->GoingSRBCnt;
>> +	    bval--;
>> +	    pDCB->MaxCommand = bval;
>> +	    pcmd->use_sg = pSRB->SavedSGCount;
> 
> Now, this I don't understand. If we didn't request sense, SavedSGCount is 
> not defined, is it?...
> 
> Thanks and sorry for taking you on a time-travel
> Guennadi
> ---
> Guennadi Liakhovetski
> -
Hi Guennadi.

I think the all thing is no longer relevant. It is leftovers from the time
scsi_error.c specifically scsi_send_eh_cmnd (used by scsi_request_sense) was
stepping all over the scsi_cmnd fields and things needed to be saved, if they
were needed for a retry. But now (since a later cleanup made by Christoph)
scsi_send_eh_cmnd() does not do that any more. In any way pcmd->use_sg is
never touched anywhere in the code and any code called from this driver.
So why save it?

Or am I missing some bigger picture Here?

Boaz


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] merge scsiiom.c into tmscsim.c
  2007-06-17 16:25   ` Boaz Harrosh
@ 2007-06-17 18:09     ` Guennadi Liakhovetski
  0 siblings, 0 replies; 8+ messages in thread
From: Guennadi Liakhovetski @ 2007-06-17 18:09 UTC (permalink / raw)
  To: Boaz Harrosh; +Cc: Christoph Hellwig, linux-scsi

On Sun, 17 Jun 2007, Boaz Harrosh wrote:

> I think the all thing is no longer relevant. It is leftovers from the time
> scsi_error.c specifically scsi_send_eh_cmnd (used by scsi_request_sense) was
> stepping all over the scsi_cmnd fields and things needed to be saved, if they
> were needed for a retry. But now (since a later cleanup made by Christoph)
> scsi_send_eh_cmnd() does not do that any more.

Ok, what I really was trying to understand is the auto request sense path 
in tmscsim, and, I think, I have a better idea now how it is supposed to 
work. In fact, I don't know how really necessary this path is. I guess, 
requesting sense would anyway be handled by the ml, so, doing it in the 
lld is just a (micro-) optimization, right? So, though superfluous and 
making the driver less maintainable, we might keep it for now.

> In any way pcmd->use_sg is
> never touched anywhere in the code and any code called from this driver.
> So why save it?
> 
> Or am I missing some bigger picture Here?

Looks like you're right. SavedSGCount seems indeed unneeded. I'll ack your 
patch.

Thanks
Guennadi
---
Guennadi Liakhovetski

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2007-06-17 18:09 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-10-03 13:47 [PATCH] merge scsiiom.c into tmscsim.c Christoph Hellwig
2004-10-03 20:42 ` Guennadi Liakhovetski
2004-10-09 12:29 ` Christoph Hellwig
2004-10-09 13:02   ` James Bottomley
2004-10-09 19:18     ` Guennadi Liakhovetski
2007-06-17 15:09 ` Guennadi Liakhovetski
2007-06-17 16:25   ` Boaz Harrosh
2007-06-17 18:09     ` Guennadi Liakhovetski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.