scsiiom.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:51k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /***********************************************************************
  2.  * FILE NAME : SCSIIOM.C        *
  3.  *      BY   : C.L. Huang,    ching@tekram.com.tw        *
  4.  * Description: Device Driver for Tekram DC-390 (T) PCI SCSI      *
  5.  *      Bus Master Host Adapter        *
  6.  ***********************************************************************/
  7. /* $Id: scsiiom.c,v 2.55.2.17 2000/12/20 00:39:37 garloff Exp $ */
  8. static void __inline__
  9. dc390_freetag (PDCB pDCB, PSRB pSRB)
  10. {
  11. if (pSRB->TagNumber < 255) {
  12. pDCB->TagMask &= ~(1 << pSRB->TagNumber);   /* free tag mask */
  13. pSRB->TagNumber = 255;
  14. }
  15. };
  16. UCHAR
  17. dc390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
  18. {
  19.     UCHAR cmd; UCHAR  disc_allowed, try_sync_nego;
  20.     pSRB->ScsiPhase = SCSI_NOP0;
  21.     if (pACB->Connected)
  22.     {
  23. // Should not happen normally
  24. printk (KERN_WARNING "DC390: Can't select when connected! (%08x,%02x)n",
  25. pSRB->SRBState, pSRB->SRBFlag);
  26. pSRB->SRBState = SRB_READY;
  27. pACB->SelConn++;
  28. return 1;
  29.     }
  30.     if (time_before (jiffies, pACB->pScsiHost->last_reset))
  31.     {
  32. DEBUG0(printk ("DC390: We were just reset and don't accept commands yet!n");)
  33. return 1;
  34.     }
  35.     DC390_write8 (Scsi_Dest_ID, pDCB->TargetID);
  36.     DC390_write8 (Sync_Period, pDCB->SyncPeriod);
  37.     DC390_write8 (Sync_Offset, pDCB->SyncOffset);
  38.     DC390_write8 (CtrlReg1, pDCB->CtrlR1);
  39.     DC390_write8 (CtrlReg3, pDCB->CtrlR3);
  40.     DC390_write8 (CtrlReg4, pDCB->CtrlR4);
  41.     DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); /* Flush FIFO */
  42.     DEBUG1(printk (KERN_INFO "DC390: Start SCSI command: %02x (Sync:%02x)n",
  43.     pSRB->pcmd->cmnd[0], pDCB->SyncMode);)
  44.     disc_allowed = pDCB->DevMode & EN_DISCONNECT_; try_sync_nego = 0;
  45.     /* Don't disconnect on AUTO_REQSENSE, cause it might be an
  46.      * Contingent Allegiance Condition (6.6), where no tags should be used.
  47.      * All other have to be allowed to disconnect to prevent Incorrect 
  48.      * Initiator Connection (6.8.2/6.5.2) */
  49.     /* Changed KG, 99/06/06 */
  50.     if( /*(((pSRB->pcmd->cmnd[0] == INQUIRY) || (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) ||
  51.  * (pSRB->pcmd->cmnd[0] == TEST_UNIT_READY)) && pACB->scan_devices)
  52. ||*/ (pSRB->SRBFlag & AUTO_REQSENSE) ) 
  53.       disc_allowed = 0;
  54.     if ( (pDCB->SyncMode & SYNC_ENABLE) && (pDCB->TargetLUN == 0) && (pDCB->Inquiry7 & 0x10) &&
  55. ( ( ( (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) || (pSRB->SRBFlag & AUTO_REQSENSE) )
  56.   && !(pDCB->SyncMode & SYNC_NEGO_DONE) ) || (pSRB->pcmd->cmnd[0] == INQUIRY) ) )
  57.       try_sync_nego = 1;
  58.     pSRB->MsgCnt = 0; cmd = SEL_W_ATN;
  59.     DC390_write8 (ScsiFifo, IDENTIFY(disc_allowed, pDCB->TargetLUN));
  60.     /* Change 99/05/31: Don't use tags when not disconnecting (BUSY) */
  61.     if ((pDCB->SyncMode & EN_TAG_QUEUEING) && disc_allowed)
  62.       {
  63. UCHAR tag_no = 0;
  64. while ((1 << tag_no) & pDCB->TagMask) tag_no++;
  65. if (tag_no >= sizeof (pDCB->TagMask)*8 || tag_no >= pDCB->MaxCommand) { 
  66. printk (KERN_WARNING "DC390: Out of tags for Dev. %02x %02xn", pDCB->TargetID, pDCB->TargetLUN); 
  67. return 1;
  68. //goto no_tag;
  69. };
  70. DC390_write8 (ScsiFifo, SIMPLE_QUEUE_TAG);
  71. pDCB->TagMask |= (1 << tag_no); pSRB->TagNumber = tag_no;
  72. DC390_write8 (ScsiFifo, tag_no);
  73. DEBUG1(printk (KERN_DEBUG "DC390: Select w/DisCn for Cmd %li (SRB %p), Using Tag %02xn", pSRB->pcmd->pid, pSRB, tag_no);)
  74. cmd = SEL_W_ATN3;
  75.       }
  76.     else /* No TagQ */
  77.       {
  78. //      no_tag:
  79. DEBUG1(printk (KERN_DEBUG "DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQn", (disc_allowed?"":"o"), pSRB->pcmd->pid, pSRB);) 
  80.       };
  81.     pSRB->SRBState = SRB_START_;
  82.     if (try_sync_nego)
  83.       { 
  84. UCHAR Sync_Off = pDCB->SyncOffset;
  85.         DEBUG0(printk (KERN_INFO "DC390: NEW Sync Nego code triggered (%i %i)n", pDCB->TargetID, pDCB->TargetLUN);)
  86. pSRB->MsgOutBuf[0] = EXTENDED_MESSAGE;
  87. pSRB->MsgOutBuf[1] = 3;
  88. pSRB->MsgOutBuf[2] = EXTENDED_SDTR;
  89. pSRB->MsgOutBuf[3] = pDCB->NegoPeriod;
  90. if (!(Sync_Off & 0x0f)) Sync_Off = SYNC_NEGO_OFFSET;
  91. pSRB->MsgOutBuf[4] = Sync_Off;
  92. pSRB->MsgCnt = 5;
  93. //pSRB->SRBState = SRB_MSGOUT_;
  94. pSRB->SRBState |= DO_SYNC_NEGO;
  95. cmd = SEL_W_ATN_STOP;
  96.       };
  97.     /* Command is written in CommandPhase, if SEL_W_ATN_STOP ... */
  98.     if (cmd != SEL_W_ATN_STOP)
  99.       {
  100. if( pSRB->SRBFlag & AUTO_REQSENSE )
  101.   {
  102.     DC390_write8 (ScsiFifo, REQUEST_SENSE);
  103.     DC390_write8 (ScsiFifo, pDCB->TargetLUN << 5);
  104.     DC390_write8 (ScsiFifo, 0);
  105.     DC390_write8 (ScsiFifo, 0);
  106.     DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
  107.     DC390_write8 (ScsiFifo, 0);
  108.     DEBUG1(printk (KERN_DEBUG "DC390: AutoReqSense !n");)
  109.   }
  110. else /* write cmnd to bus */ 
  111.   {
  112.     PUCHAR ptr; UCHAR i;
  113.     ptr = (PUCHAR) pSRB->pcmd->cmnd;
  114.     for (i=0; i<pSRB->pcmd->cmd_len; i++)
  115.       DC390_write8 (ScsiFifo, *(ptr++));
  116.   };
  117.       }
  118.     DEBUG0(if (pACB->pActiveDCB)
  119.    printk (KERN_WARNING "DC390: ActiveDCB != 0n");)
  120.     DEBUG0(if (pDCB->pActiveSRB)
  121.    printk (KERN_WARNING "DC390: ActiveSRB != 0n");)
  122.     //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
  123.     if (DC390_read8 (Scsi_Status) & INTERRUPT)
  124.     {
  125. dc390_freetag (pDCB, pSRB);
  126. DEBUG0(printk ("DC390: Interrupt during Start SCSI (pid %li, target %02i-%02i)n",
  127. pSRB->pcmd->pid, pSRB->pcmd->target, pSRB->pcmd->lun);)
  128. pSRB->SRBState = SRB_READY;
  129. //DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
  130. pACB->SelLost++;
  131. return 1;
  132.     };
  133.     DC390_write8 (ScsiCmd, cmd);
  134.     pACB->pActiveDCB = pDCB; pDCB->pActiveSRB = pSRB;
  135.     pACB->Connected = 1;
  136.     pSRB->ScsiPhase = SCSI_NOP1;
  137.     return 0;
  138. }
  139. //#define DMA_INT EN_DMA_INT /*| EN_PAGE_INT*/
  140. #define DMA_INT 0
  141. #if DMA_INT
  142. /* This is similar to AM53C974.c ... */
  143. static UCHAR 
  144. dc390_dma_intr (PACB pACB)
  145. {
  146.   PSRB pSRB;
  147.   UCHAR dstate;
  148.   DEBUG0(USHORT pstate;PDEVDECL1;)
  149.   
  150.   DEBUG0(PDEVSET1;)
  151.   DEBUG0(PCI_READ_CONFIG_WORD (PDEV, PCI_STATUS, &pstate);)
  152.   DEBUG0(if (pstate & (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY))
  153. { printk(KERN_WARNING "DC390: PCI state = %04x!n", pstate); 
  154.   PCI_WRITE_CONFIG_WORD (PDEV, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));};)
  155.   dstate = DC390_read8 (DMA_Status); 
  156.   if (! pACB->pActiveDCB || ! pACB->pActiveDCB->pActiveSRB) return dstate;
  157.   else pSRB  = pACB->pActiveDCB->pActiveSRB;
  158.   
  159.   if (dstate & (DMA_XFER_ABORT | DMA_XFER_ERROR | POWER_DOWN | PCI_MS_ABORT))
  160.     {
  161. printk (KERN_ERR "DC390: DMA error (%02x)!n", dstate);
  162. return dstate;
  163.     };
  164.   if (dstate & DMA_XFER_DONE)
  165.     {
  166. UINT residual, xferCnt; int ctr = 6000000;
  167. if (! (DC390_read8 (DMA_Cmd) & READ_DIRECTION))
  168.   {
  169.     do
  170.       {
  171. DEBUG1(printk (KERN_DEBUG "DC390: read residual bytes ... n");)
  172. dstate = DC390_read8 (DMA_Status);
  173. residual = DC390_read8 (CtcReg_Low) | DC390_read8 (CtcReg_Mid) << 8 |
  174.   DC390_read8 (CtcReg_High) << 16;
  175. residual += DC390_read8 (Current_Fifo) & 0x1f;
  176.       } while (residual && ! (dstate & SCSI_INTERRUPT) && --ctr);
  177.     if (!ctr) printk (KERN_CRIT "DC390: dma_intr: DMA aborted unfinished: %06x bytes remain!!n", DC390_read32 (DMA_Wk_ByteCntr));
  178.     /* residual =  ... */
  179.   }
  180. else
  181.     residual = 0;
  182. /* ??? */
  183. xferCnt = pSRB->SGToBeXferLen - residual;
  184. pSRB->SGBusAddr += xferCnt;
  185. pSRB->TotalXferredLen += xferCnt;
  186. pSRB->SGToBeXferLen = residual;
  187. # ifdef DC390_DEBUG0
  188. printk (KERN_INFO "DC390: DMA: residual = %i, xfer = %in", 
  189. (unsigned int)residual, (unsigned int)xferCnt);
  190. # endif
  191. DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
  192.     }
  193.   dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24;
  194.   return dstate;
  195. };
  196. #endif
  197. void __inline__
  198. DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
  199. {
  200.     PACB   pACB, pACB2;
  201.     PDCB   pDCB;
  202.     PSRB   pSRB;
  203.     UCHAR  sstatus=0;
  204.     UCHAR  phase;
  205.     void   (*stateV)( PACB, PSRB, PUCHAR );
  206.     UCHAR  istate, istatus;
  207. #if DMA_INT
  208.     UCHAR  dstatus;
  209. #endif
  210.     DC390_AFLAGS DC390_IFLAGS //DC390_DFLAGS
  211.     pACB = (PACB)dev_id;
  212.     for (pACB2 = dc390_pACB_start; (pACB2 && pACB2 != pACB); pACB2 = pACB2->pNextACB);
  213.     if (!pACB2)
  214.     {
  215. printk ("DC390: IRQ called with foreign dev_id %p!n", pACB);
  216. return;
  217.     }
  218.     
  219.     //DC390_LOCK_DRV;
  220.     sstatus = DC390_read8 (Scsi_Status);
  221.     if( !(sstatus & INTERRUPT) )
  222. { /*DC390_UNLOCK_DRV;*/ return; };
  223.     DEBUG1(printk (KERN_DEBUG "sstatus=%02x,", sstatus);)
  224. #if DMA_INT
  225.     DC390_LOCK_IO;
  226.     DC390_LOCK_ACB;
  227.     dstatus = dc390_dma_intr (pACB);
  228.     DC390_UNLOCK_ACB;
  229.     DC390_UNLOCK_IO;
  230.     DEBUG1(printk (KERN_DEBUG "dstatus=%02x,", dstatus);)
  231.     if (! (dstatus & SCSI_INTERRUPT))
  232.       {
  233. DEBUG0(printk (KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)n");)
  234. //DC390_UNLOCK_DRV;
  235. return;
  236.       };
  237. #else
  238.     //DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
  239.     //dstatus = DC390_read8 (DMA_Status);
  240.     //DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
  241. #endif
  242.     DC390_LOCK_IO;
  243.     DC390_LOCK_ACB;
  244.     //DC390_UNLOCK_DRV_NI; /* Allow _other_ CPUs to process IRQ (useful for shared IRQs) */
  245.     istate = DC390_read8 (Intern_State);
  246.     istatus = DC390_read8 (INT_Status); /* This clears Scsi_Status, Intern_State and INT_Status ! */
  247.     DEBUG1(printk (KERN_INFO "Istatus(Res,Inv,Dis,Serv,Succ,ReS,SelA,Sel)=%02x,",istatus);)
  248.     dc390_laststatus &= ~0x00ffffff;
  249.     dc390_laststatus |= /* dstatus<<24 | */ sstatus<<16 | istate<<8 | istatus;
  250.     if (sstatus & ILLEGAL_OP_ERR)
  251.     {
  252. printk ("DC390: Illegal Operation detected (%08x)!n", dc390_laststatus);
  253. dc390_dumpinfo (pACB, pACB->pActiveDCB, pACB->pActiveDCB->pActiveSRB);
  254.     }
  255.     else if (istatus &  INVALID_CMD)
  256.     {
  257. printk ("DC390: Invalid Command detected (%08x)!n", dc390_laststatus);
  258. dc390_InvalidCmd( pACB );
  259. goto unlock;
  260.     }
  261.     if (istatus &  SCSI_RESET)
  262.     {
  263. dc390_ScsiRstDetect( pACB );
  264. goto unlock;
  265.     }
  266.     if (istatus &  DISCONNECTED)
  267.     {
  268. dc390_Disconnect( pACB );
  269. goto unlock;
  270.     }
  271.     if (istatus &  RESELECTED)
  272.     {
  273. dc390_Reselect( pACB );
  274. goto unlock;
  275.     }
  276.     else if (istatus & (SELECTED | SEL_ATTENTION))
  277.     {
  278. printk (KERN_ERR "DC390: Target mode not supported!n");
  279. goto unlock;
  280.     }
  281.     if (istatus & (SUCCESSFUL_OP|SERVICE_REQUEST) )
  282.     {
  283. pDCB = pACB->pActiveDCB;
  284. if (!pDCB)
  285. {
  286. printk (KERN_ERR "DC390: Suc. op/ Serv. req: pActiveDCB = 0!n");
  287. goto unlock;
  288. };
  289. pSRB = pDCB->pActiveSRB;
  290. if( pDCB->DCBFlag & ABORT_DEV_ )
  291.   dc390_EnableMsgOut_Abort (pACB, pSRB);
  292. phase = pSRB->ScsiPhase;
  293. DEBUG1(printk (KERN_INFO "DC390: [%i]%s(0) (%02x)n", phase, dc390_p0_str[phase], sstatus);)
  294. stateV = (void *) dc390_phase0[phase];
  295. ( *stateV )( pACB, pSRB, &sstatus );
  296. pSRB->ScsiPhase = sstatus & 7;
  297. phase = (UCHAR) sstatus & 7;
  298. DEBUG1(printk (KERN_INFO "DC390: [%i]%s(1) (%02x)n", phase, dc390_p1_str[phase], sstatus);)
  299. stateV = (void *) dc390_phase1[phase];
  300. ( *stateV )( pACB, pSRB, &sstatus );
  301. goto unlock;
  302.     }
  303.  unlock:
  304.     //DC390_LOCK_DRV_NI;
  305.     DC390_UNLOCK_ACB;
  306.     DC390_UNLOCK_IO;
  307.     //DC390_UNLOCK_DRV; /* Restore initial flags */
  308. }
  309. void
  310. do_DC390_Interrupt( int irq, void *dev_id, struct pt_regs *regs)
  311. {
  312.     DEBUG1(printk (KERN_INFO "DC390: Irq (%i) caught: ", irq);)
  313.     /* Locking is done in DC390_Interrupt */
  314.     DC390_Interrupt(irq, dev_id, regs);
  315.     DEBUG1(printk (".. IRQ returnedn");)
  316. }
  317. void
  318. dc390_DataOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  319. {
  320.     UCHAR   sstatus;
  321.     PSGL    psgl;
  322.     UINT    ResidCnt, xferCnt;
  323.     UCHAR   dstate = 0;
  324.     sstatus = *psstatus;
  325.     if( !(pSRB->SRBState & SRB_XFERPAD) )
  326.     {
  327. if( sstatus & (PARITY_ERR | ILLEGAL_OP_ERR) )
  328.     pSRB->SRBStatus |= PARITY_ERROR;
  329. if( sstatus & COUNT_2_ZERO )
  330. {
  331.     int ctr = 6000000; /* only try for about a second */
  332.     while( --ctr && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen );
  333.     if (!ctr) printk (KERN_CRIT "DC390: Deadlock in DataOut_0: DMA aborted unfinished: %06x bytes remain!!n", DC390_read32 (DMA_Wk_ByteCntr));
  334.     dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24;
  335.     pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
  336.     pSRB->SGIndex++;
  337.     if( pSRB->SGIndex < pSRB->SGcount )
  338.     {
  339. pSRB->pSegmentList++;
  340. psgl = pSRB->pSegmentList;
  341. pSRB->SGBusAddr = virt_to_bus( psgl->address );
  342. pSRB->SGToBeXferLen = (ULONG) psgl->length;
  343.     }
  344.     else
  345. pSRB->SGToBeXferLen = 0;
  346. }
  347. else
  348. {
  349.     ResidCnt  = (UINT) DC390_read8 (Current_Fifo) & 0x1f;
  350.     ResidCnt |= (UINT) DC390_read8 (CtcReg_High) << 16;
  351.     ResidCnt |= (UINT) DC390_read8 (CtcReg_Mid) << 8; 
  352.     ResidCnt += (UINT) DC390_read8 (CtcReg_Low);
  353.     xferCnt = pSRB->SGToBeXferLen - ResidCnt;
  354.     pSRB->SGBusAddr += xferCnt;
  355.     pSRB->TotalXferredLen += xferCnt;
  356.     pSRB->SGToBeXferLen = ResidCnt;
  357. }
  358.     }
  359.     if ((*psstatus & 7) != SCSI_DATA_OUT)
  360.     {
  361.     DC390_write8 (DMA_Cmd, WRITE_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
  362.     DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
  363.     }     
  364. }
  365. void
  366. dc390_DataIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  367. {
  368.     UCHAR   sstatus, residual, bval;
  369.     PSGL    psgl;
  370.     UINT    ResidCnt, i;
  371.     ULONG   xferCnt;
  372.     PUCHAR  ptr;
  373.     sstatus = *psstatus;
  374.     if( !(pSRB->SRBState & SRB_XFERPAD) )
  375.     {
  376. if( sstatus & (PARITY_ERR | ILLEGAL_OP_ERR))
  377.     pSRB->SRBStatus |= PARITY_ERROR;
  378. if( sstatus & COUNT_2_ZERO )
  379. {
  380.     int ctr = 6000000; /* only try for about a second */
  381.     int dstate = 0;
  382.     while( --ctr && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE) && pSRB->SGToBeXferLen );
  383.     if (!ctr) printk (KERN_CRIT "DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!n", DC390_read32 (DMA_Wk_ByteCntr));
  384.     if (!ctr) printk (KERN_CRIT "DC390: DataIn_0: DMA State: %in", dstate);
  385.     dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24;
  386.     DEBUG1(ResidCnt = ((ULONG) DC390_read8 (CtcReg_High) << 16)
  387. + ((ULONG) DC390_read8 (CtcReg_Mid) << 8)
  388. + ((ULONG) DC390_read8 (CtcReg_Low));)
  389.     DEBUG1(printk (KERN_DEBUG "Count_2_Zero (ResidCnt=%i,ToBeXfer=%li),", ResidCnt, pSRB->SGToBeXferLen);)
  390.     DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
  391.     pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
  392.     pSRB->SGIndex++;
  393.     if( pSRB->SGIndex < pSRB->SGcount )
  394.     {
  395. pSRB->pSegmentList++;
  396. psgl = pSRB->pSegmentList;
  397. pSRB->SGBusAddr = virt_to_bus( psgl->address );
  398. pSRB->SGToBeXferLen = (ULONG) psgl->length;
  399.     }
  400.     else
  401. pSRB->SGToBeXferLen = 0;
  402. }
  403. else /* phase changed */
  404. {
  405.     residual = 0;
  406.     bval = DC390_read8 (Current_Fifo);
  407.     while( bval & 0x1f )
  408.     {
  409. DEBUG1(printk (KERN_DEBUG "Check for residuals,");)
  410. if( (bval & 0x1f) == 1 )
  411. {
  412.     for(i=0; i < 0x100; i++)
  413.     {
  414. bval = DC390_read8 (Current_Fifo);
  415. if( !(bval & 0x1f) )
  416.     goto din_1;
  417. else if( i == 0x0ff )
  418. {
  419.     residual = 1;   /* ;1 residual byte */
  420.     goto din_1;
  421. }
  422.     }
  423. }
  424. else
  425.     bval = DC390_read8 (Current_Fifo);
  426.     }
  427. din_1:
  428.     DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_BLAST_CMD);
  429.     for (i = 0xa000; i; i--)
  430.     {
  431. bval = DC390_read8 (DMA_Status);
  432. if (bval & BLAST_COMPLETE)
  433.     break;
  434.     }
  435.     /* It seems a DMA Blast abort isn't that bad ... */
  436.     if (!i) printk (KERN_ERR "DC390: DMA Blast aborted unfinished!n");
  437.     //DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
  438.     dc390_laststatus &= ~0xff000000; dc390_laststatus |= bval << 24;
  439.     DEBUG1(printk (KERN_DEBUG "Blast: Read %i times DMA_Status %02x", 0xa000-i, bval);)
  440.     ResidCnt = (UINT) DC390_read8 (CtcReg_High);
  441.     ResidCnt <<= 8;
  442.     ResidCnt |= (UINT) DC390_read8 (CtcReg_Mid);
  443.     ResidCnt <<= 8;
  444.     ResidCnt |= (UINT) DC390_read8 (CtcReg_Low);
  445.     xferCnt = pSRB->SGToBeXferLen - ResidCnt;
  446.     pSRB->SGBusAddr += xferCnt;
  447.     pSRB->TotalXferredLen += xferCnt;
  448.     pSRB->SGToBeXferLen = ResidCnt;
  449.     if( residual )
  450.     {
  451. bval = DC390_read8 (ScsiFifo);     /* get one residual byte */
  452. ptr = (PUCHAR) bus_to_virt( pSRB->SGBusAddr );
  453. *ptr = bval;
  454. pSRB->SGBusAddr++; xferCnt++;
  455. pSRB->TotalXferredLen++;
  456. pSRB->SGToBeXferLen--;
  457.     }
  458.     DEBUG1(printk (KERN_DEBUG "Xfered: %li, Total: %li, Remaining: %lin", xferCnt,
  459.    pSRB->TotalXferredLen, pSRB->SGToBeXferLen);)
  460. }
  461.     }
  462.     if ((*psstatus & 7) != SCSI_DATA_IN)
  463.     {
  464.     DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
  465.     DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD); /* | DMA_INT */
  466.     }     
  467. }
  468. static void
  469. dc390_Command_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  470. {
  471. }
  472. static void
  473. dc390_Status_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  474. {
  475.     pSRB->TargetStatus = DC390_read8 (ScsiFifo);
  476.     //udelay (1);
  477.     pSRB->EndMessage = DC390_read8 (ScsiFifo); /* get message */
  478.     *psstatus = SCSI_NOP0;
  479.     pSRB->SRBState = SRB_COMPLETED;
  480.     DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);
  481. }
  482. static void
  483. dc390_MsgOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  484. {
  485.     if( pSRB->SRBState & (SRB_UNEXPECT_RESEL+SRB_ABORT_SENT) )
  486. *psstatus = SCSI_NOP0;
  487.     //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
  488. }
  489. static void __inline__
  490. dc390_reprog (PACB pACB, PDCB pDCB)
  491. {
  492.   DC390_write8 (Sync_Period, pDCB->SyncPeriod);
  493.   DC390_write8 (Sync_Offset, pDCB->SyncOffset);
  494.   DC390_write8 (CtrlReg3, pDCB->CtrlR3);
  495.   DC390_write8 (CtrlReg4, pDCB->CtrlR4);
  496.   dc390_SetXferRate (pACB, pDCB);
  497. };
  498. #ifdef DC390_DEBUG0
  499. static void
  500. dc390_printMsg (UCHAR *MsgBuf, UCHAR len)
  501. {
  502.   int i;
  503.   printk (" %02x", MsgBuf[0]);
  504.   for (i = 1; i < len; i++)
  505.     printk (" %02x", MsgBuf[i]);
  506.   printk ("n");
  507. };
  508. #endif
  509. #define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD)
  510. /* reject_msg */
  511. static void __inline__
  512. dc390_MsgIn_reject (PACB pACB, PSRB pSRB)
  513. {
  514.   pSRB->MsgOutBuf[0] = MESSAGE_REJECT;
  515.   pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
  516.   DEBUG0 (printk (KERN_INFO "DC390: Reject messagen");)
  517. }
  518. /* abort command */
  519. static void __inline__
  520. dc390_EnableMsgOut_Abort ( PACB pACB, PSRB pSRB )
  521. {
  522.     pSRB->MsgOutBuf[0] = ABORT; 
  523.     pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
  524.     pSRB->pSRBDCB->DCBFlag &= ~ABORT_DEV_;
  525. }
  526. static PSRB
  527. dc390_MsgIn_QTag (PACB pACB, PDCB pDCB, UCHAR tag)
  528. {
  529.   PSRB lastSRB = pDCB->pGoingLast;
  530.   PSRB pSRB = pDCB->pGoingSRB;
  531.   if (pSRB)
  532.     {
  533.       for( ;pSRB ; )
  534. {
  535.   if (pSRB->TagNumber == tag) break;
  536.   if (pSRB == lastSRB) goto mingx0;
  537.   pSRB = pSRB->pNextSRB;
  538. }
  539.       if( pDCB->DCBFlag & ABORT_DEV_ )
  540. {
  541.   pSRB->SRBState = SRB_ABORT_SENT;
  542.   dc390_EnableMsgOut_Abort( pACB, pSRB );
  543. }
  544.       if( !(pSRB->SRBState & SRB_DISCONNECT) )
  545. goto  mingx0;
  546.       pDCB->pActiveSRB = pSRB;
  547.       pSRB->SRBState = SRB_DATA_XFER;
  548.     }
  549.   else
  550.     {
  551.     mingx0:
  552.       pSRB = pACB->pTmpSRB;
  553.       pSRB->SRBState = SRB_UNEXPECT_RESEL;
  554.       pDCB->pActiveSRB = pSRB;
  555.       pSRB->MsgOutBuf[0] = ABORT_TAG;
  556.       pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
  557.     }
  558.   return pSRB;
  559. }
  560. /* set async transfer mode */
  561. static void 
  562. dc390_MsgIn_set_async (PACB pACB, PSRB pSRB)
  563. {
  564.   PDCB pDCB = pSRB->pSRBDCB;
  565.   if (!(pSRB->SRBState & DO_SYNC_NEGO)) 
  566.     printk (KERN_INFO "DC390: Target %i initiates Non-Sync?n", pDCB->TargetID);
  567.   pSRB->SRBState &= ~DO_SYNC_NEGO;
  568.   pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE);
  569.   pDCB->SyncPeriod = 0;
  570.   pDCB->SyncOffset = 0;
  571.   //pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
  572.   pDCB->CtrlR3 = FAST_CLK; /* fast clock / normal scsi */
  573.   pDCB->CtrlR4 &= 0x3f;
  574.   pDCB->CtrlR4 |= pACB->glitch_cfg; /* glitch eater */
  575.   dc390_reprog (pACB, pDCB);
  576. }
  577. /* set sync transfer mode */
  578. static void
  579. dc390_MsgIn_set_sync (PACB pACB, PSRB pSRB)
  580. {
  581.   UCHAR bval;
  582.   USHORT wval, wval1;
  583.   PDCB pDCB = pSRB->pSRBDCB;
  584.   UCHAR oldsyncperiod = pDCB->SyncPeriod;
  585.   UCHAR oldsyncoffset = pDCB->SyncOffset;
  586.   
  587.   if (!(pSRB->SRBState & DO_SYNC_NEGO))
  588.     {
  589.       printk (KERN_INFO "DC390: Target %i initiates Sync: %ins %i ... answer ...n", 
  590.       pDCB->TargetID, pSRB->MsgInBuf[3]<<2, pSRB->MsgInBuf[4]);
  591.       /* reject */
  592.       //dc390_MsgIn_reject (pACB, pSRB);
  593.       //return dc390_MsgIn_set_async (pACB, pSRB);
  594.       /* Reply with corrected SDTR Message */
  595.       if (pSRB->MsgInBuf[4] > 15)
  596.   printk (KERN_INFO "DC390: Lower Sync Offset to 15n");
  597.   pSRB->MsgInBuf[4] = 15;
  598. }
  599.       if (pSRB->MsgInBuf[3] < pDCB->NegoPeriod)
  600. {
  601.   printk (KERN_INFO "DC390: Set sync nego period to %insn", pDCB->NegoPeriod << 2);
  602.   pSRB->MsgInBuf[3] = pDCB->NegoPeriod;
  603. };
  604.       memcpy (pSRB->MsgOutBuf, pSRB->MsgInBuf, 5);
  605.       pSRB->MsgCnt = 5;
  606.       DC390_ENABLE_MSGOUT;
  607.     };
  608.   pSRB->SRBState &= ~DO_SYNC_NEGO;
  609.   pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE;
  610.   pDCB->SyncOffset &= 0x0f0;
  611.   pDCB->SyncOffset |= pSRB->MsgInBuf[4];
  612.   pDCB->NegoPeriod = pSRB->MsgInBuf[3];
  613.   wval = (USHORT) pSRB->MsgInBuf[3];
  614.   wval = wval << 2; wval -= 3; wval1 = wval / 25; /* compute speed */
  615.   if( (wval1 * 25) != wval) wval1++;
  616.   bval = FAST_CLK+FAST_SCSI; /* fast clock / fast scsi */
  617.   pDCB->CtrlR4 &= 0x3f; /* Glitch eater: 12ns less than normal */
  618.   if (pACB->glitch_cfg != NS_TO_GLITCH(0))
  619.     pDCB->CtrlR4 |= NS_TO_GLITCH(((GLITCH_TO_NS(pACB->glitch_cfg)) - 1));
  620.   else
  621.     pDCB->CtrlR4 |= NS_TO_GLITCH(0);
  622.   if (wval1 < 4) pDCB->CtrlR4 |= NS_TO_GLITCH(0); /* Ultra */
  623.   if (wval1 >= 8)
  624.     {
  625.       wval1--; /* Timing computation differs by 1 from FAST_SCSI */
  626.       bval = FAST_CLK; /* fast clock / normal scsi */
  627.       pDCB->CtrlR4 |= pACB->glitch_cfg;  /* glitch eater */
  628.     }
  629.   pDCB->CtrlR3 = bval;
  630.   pDCB->SyncPeriod = (UCHAR)wval1;
  631.   
  632.   if ((oldsyncperiod != wval1 || oldsyncoffset != pDCB->SyncOffset) && pDCB->TargetLUN == 0)
  633.     {
  634.       if (! (bval & FAST_SCSI)) wval1++;
  635.       printk (KERN_INFO "DC390: Target %i: Sync transfer %i.%1i MHz, Offset %in", pDCB->TargetID, 
  636.       40/wval1, ((40%wval1)*10+wval1/2)/wval1, pDCB->SyncOffset & 0x0f);
  637.     }
  638.   
  639.   dc390_reprog (pACB, pDCB);
  640. };
  641. /* handle RESTORE_PTR */
  642. static void 
  643. dc390_restore_ptr (PACB pACB, PSRB pSRB)
  644. {
  645.   PSGL psgl;
  646.   pSRB->TotalXferredLen = 0;
  647.   pSRB->SGIndex = 0;
  648.   if( pSRB->pcmd->use_sg )
  649.     {
  650.       pSRB->SGcount = (UCHAR) pSRB->pcmd->use_sg;
  651.       pSRB->pSegmentList = (PSGL) pSRB->pcmd->request_buffer;
  652.       psgl = pSRB->pSegmentList;
  653.       while (pSRB->TotalXferredLen + (ULONG) psgl->length < pSRB->Saved_Ptr)
  654. {
  655.   pSRB->TotalXferredLen += (ULONG) psgl->length;
  656.   pSRB->SGIndex++;
  657.   if( pSRB->SGIndex < pSRB->SGcount )
  658.     {
  659.       pSRB->pSegmentList++;
  660.       psgl = pSRB->pSegmentList;
  661.       
  662.       pSRB->SGBusAddr = virt_to_bus( psgl->address );
  663.       pSRB->SGToBeXferLen = (ULONG) psgl->length;
  664.     }
  665.   else
  666.     pSRB->SGToBeXferLen = 0;
  667. }
  668.       pSRB->SGToBeXferLen -= (pSRB->Saved_Ptr - pSRB->TotalXferredLen);
  669.       pSRB->SGBusAddr += (pSRB->Saved_Ptr - pSRB->TotalXferredLen);
  670.       printk (KERN_INFO "DC390: Pointer restored. Segment %i, Total %li, Bus %08lxn", pSRB->SGIndex, pSRB->Saved_Ptr, pSRB->SGBusAddr);
  671.     }
  672.     else if( pSRB->pcmd->request_buffer )
  673.     {
  674. pSRB->SGcount = 1;
  675. pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
  676. pSRB->Segmentx.address = (PUCHAR) pSRB->pcmd->request_buffer + pSRB->Saved_Ptr;
  677. pSRB->Segmentx.length = pSRB->pcmd->request_bufflen - pSRB->Saved_Ptr;
  678. printk (KERN_INFO "DC390: Pointer restored. Total %li, Bus %pn",
  679. pSRB->Saved_Ptr, pSRB->Segmentx.address);
  680.     }
  681.      else
  682.        {
  683.  pSRB->SGcount = 0;
  684.  printk (KERN_INFO "DC390: RESTORE_PTR message for Transfer without Scatter-Gather ??n");
  685.        };
  686.   pSRB->TotalXferredLen = pSRB->Saved_Ptr;
  687. };
  688. /* According to the docs, the AM53C974 reads the message and 
  689.  * generates a Succesful Operation IRQ before asserting ACK for
  690.  * the last byte (how does it know whether it's the last ?) */
  691. /* The old code handled it in another way, indicating, that on
  692.  * every message byte an IRQ is generated and every byte has to
  693.  * be manually ACKed. Hmmm ?  (KG, 98/11/28) */
  694. /* The old implementation was correct. Sigh! */
  695. /* Check if the message is complete */
  696. static UCHAR __inline__
  697. dc390_MsgIn_complete (UCHAR *msgbuf, UINT len)
  698.   if (*msgbuf == EXTENDED_MESSAGE)
  699.   {
  700. if (len < 2) return 0;
  701. if (len < msgbuf[1] + 2) return 0;
  702.   }
  703.   else if (*msgbuf >= 0x20 && *msgbuf <= 0x2f) // two byte messages
  704. if (len < 2) return 0;
  705.   return 1;
  706. }
  707. /* read and eval received messages */
  708. void
  709. dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  710. {
  711.     PDCB   pDCB = pACB->pActiveDCB;
  712.     /* Read the msg */
  713.     pSRB->MsgInBuf[pACB->MsgLen++] = DC390_read8 (ScsiFifo);
  714.     //pSRB->SRBState = 0;
  715.     /* Msg complete ? */
  716.     if (dc390_MsgIn_complete (pSRB->MsgInBuf, pACB->MsgLen))
  717.       {
  718. DEBUG0 (printk (KERN_INFO "DC390: MsgIn:"); dc390_printMsg (pSRB->MsgInBuf, pACB->MsgLen);)
  719. /* Now eval the msg */
  720. switch (pSRB->MsgInBuf[0]) 
  721.   {
  722.   case DISCONNECT: 
  723.     pSRB->SRBState = SRB_DISCONNECT; break;
  724.     
  725.   case SIMPLE_QUEUE_TAG:
  726.   case HEAD_OF_QUEUE_TAG:
  727.   case ORDERED_QUEUE_TAG:
  728.     pSRB = dc390_MsgIn_QTag (pACB, pDCB, pSRB->MsgInBuf[1]);
  729.     break;
  730.     
  731.   case MESSAGE_REJECT: 
  732.     DC390_write8 (ScsiCmd, RESET_ATN_CMD);
  733.     pDCB->NegoPeriod = 50; /* 200ns <=> 5 MHz */
  734.     if( pSRB->SRBState & DO_SYNC_NEGO)
  735.       dc390_MsgIn_set_async (pACB, pSRB);
  736.     break;
  737.     
  738.   case EXTENDED_MESSAGE:
  739.     /* reject every extended msg but SDTR */
  740.     if (pSRB->MsgInBuf[1] != 3 || pSRB->MsgInBuf[2] != EXTENDED_SDTR)
  741.       dc390_MsgIn_reject (pACB, pSRB);
  742.     else
  743.       {
  744. if (pSRB->MsgInBuf[3] == 0 || pSRB->MsgInBuf[4] == 0)
  745.   dc390_MsgIn_set_async (pACB, pSRB);
  746. else
  747.   dc390_MsgIn_set_sync (pACB, pSRB);
  748.       };
  749.     
  750.     // nothing has to be done
  751.   case COMMAND_COMPLETE: break;
  752.     
  753.     // SAVE POINTER may be ignored as we have the PSRB associated with the
  754.     // scsi command. Thanks, Gerard, for pointing it out.
  755.   case SAVE_POINTERS: 
  756.     pSRB->Saved_Ptr = pSRB->TotalXferredLen;
  757.     break;
  758.     // The device might want to restart transfer with a RESTORE
  759.   case RESTORE_POINTERS:
  760.     DEBUG0(printk ("DC390: RESTORE POINTER message received ... try to handlen");)
  761.     dc390_restore_ptr (pACB, pSRB);
  762.     break;
  763.     // reject unknown messages
  764.   default: dc390_MsgIn_reject (pACB, pSRB);
  765.   }
  766. /* Clear counter and MsgIn state */
  767. pSRB->SRBState &= ~SRB_MSGIN;
  768. pACB->MsgLen = 0;
  769.       };
  770.     *psstatus = SCSI_NOP0;
  771.     DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);
  772.     //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
  773. }
  774. void
  775. dc390_DataIO_Comm( PACB pACB, PSRB pSRB, UCHAR ioDir)
  776. {
  777.     PSGL   psgl;
  778.     ULONG  lval;
  779.     PDCB   pDCB = pACB->pActiveDCB;
  780.     if (pSRB == pACB->pTmpSRB)
  781.     {
  782. if (pDCB) printk (KERN_ERR "DC390: pSRB == pTmpSRB! (TagQ Error?) (%02i-%i)n",
  783.   pDCB->TargetID, pDCB->TargetLUN);
  784. else printk (KERN_ERR "DC390: pSRB == pTmpSRB! (TagQ Error?) (DCB 0!)n");
  785. dc390_EnableMsgOut_Abort (pACB, pSRB);
  786. if (pDCB) pDCB->DCBFlag |= ABORT_DEV;
  787. return;
  788.     }
  789.     if( pSRB->SGIndex < pSRB->SGcount )
  790.     {
  791. DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir /* | DMA_INT */);
  792. if( !pSRB->SGToBeXferLen )
  793. {
  794.     psgl = pSRB->pSegmentList;
  795.     pSRB->SGBusAddr = virt_to_bus( psgl->address );
  796.     pSRB->SGToBeXferLen = (ULONG) psgl->length;
  797.     DEBUG1(printk (KERN_DEBUG " DC390: Next SG segment.");)
  798. }
  799. lval = pSRB->SGToBeXferLen;
  800. DEBUG1(printk (KERN_DEBUG " DC390: Start transfer: %li bytes (address %08lx)n", lval, pSRB->SGBusAddr);)
  801. DC390_write8 (CtcReg_Low, (UCHAR) lval);
  802. lval >>= 8;
  803. DC390_write8 (CtcReg_Mid, (UCHAR) lval);
  804. lval >>= 8;
  805. DC390_write8 (CtcReg_High, (UCHAR) lval);
  806. DC390_write32 (DMA_XferCnt, pSRB->SGToBeXferLen);
  807. DC390_write32 (DMA_XferAddr, pSRB->SGBusAddr);
  808. //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); /* | DMA_INT; */
  809. pSRB->SRBState = SRB_DATA_XFER;
  810. DC390_write8 (ScsiCmd, DMA_COMMAND+INFO_XFER_CMD);
  811. DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
  812. //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);)
  813. //DEBUG1(printk (KERN_DEBUG "DC390: DMA_Status: %02xn", DC390_read8 (DMA_Status));)
  814. //DEBUG1(DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);)
  815.     }
  816.     else    /* xfer pad */
  817.     {
  818. if( pSRB->SGcount )
  819. {
  820.     pSRB->AdaptStatus = H_OVER_UNDER_RUN;
  821.     pSRB->SRBStatus |= OVER_RUN;
  822.     DEBUG0(printk (KERN_WARNING " DC390: Overrun -");)
  823. }
  824. DEBUG0(printk (KERN_WARNING " Clear transfer pad n");)
  825. DC390_write8 (CtcReg_Low, 0);
  826. DC390_write8 (CtcReg_Mid, 0);
  827. DC390_write8 (CtcReg_High, 0);
  828. pSRB->SRBState |= SRB_XFERPAD;
  829. DC390_write8 (ScsiCmd, DMA_COMMAND+XFER_PAD_BYTE);
  830. /*
  831. DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir); // | DMA_INT;
  832. DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
  833. */
  834.     }
  835. }
  836. static void
  837. dc390_DataOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  838. {
  839.     dc390_DataIO_Comm (pACB, pSRB, WRITE_DIRECTION);
  840. }
  841. static void
  842. dc390_DataInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  843. {
  844.     dc390_DataIO_Comm (pACB, pSRB, READ_DIRECTION);
  845. }
  846. void
  847. dc390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  848. {
  849.     PDCB   pDCB;
  850.     UCHAR  i, cnt;
  851.     PUCHAR ptr;
  852.     DC390_write8 (ScsiCmd, RESET_ATN_CMD);
  853.     DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
  854.     if( !(pSRB->SRBFlag & AUTO_REQSENSE) )
  855.     {
  856. cnt = (UCHAR) pSRB->pcmd->cmd_len;
  857. ptr = (PUCHAR) pSRB->pcmd->cmnd;
  858. for(i=0; i < cnt; i++)
  859.     DC390_write8 (ScsiFifo, *(ptr++));
  860.     }
  861.     else
  862.     {
  863. UCHAR bval = 0;
  864. DC390_write8 (ScsiFifo, REQUEST_SENSE);
  865. pDCB = pACB->pActiveDCB;
  866. DC390_write8 (ScsiFifo, pDCB->TargetLUN << 5);
  867. DC390_write8 (ScsiFifo, bval);
  868. DC390_write8 (ScsiFifo, bval);
  869. DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
  870. DC390_write8 (ScsiFifo, bval);
  871. DEBUG0(printk(KERN_DEBUG "DC390: AutoReqSense (CmndPhase)!n");)
  872.     }
  873.     pSRB->SRBState = SRB_COMMAND;
  874.     DC390_write8 (ScsiCmd, INFO_XFER_CMD);
  875. }
  876. static void
  877. dc390_StatusPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  878. {
  879.     DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
  880.     pSRB->SRBState = SRB_STATUS;
  881.     DC390_write8 (ScsiCmd, INITIATOR_CMD_CMPLTE);
  882.     //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
  883. }
  884. void
  885. dc390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  886. {
  887.     UCHAR   bval, i, cnt;
  888.     PUCHAR  ptr;
  889.     PDCB    pDCB;
  890.     DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
  891.     pDCB = pACB->pActiveDCB;
  892.     if( !(pSRB->SRBState & SRB_MSGOUT) )
  893.     {
  894. cnt = pSRB->MsgCnt;
  895. if( cnt )
  896. {
  897.     ptr = (PUCHAR) pSRB->MsgOutBuf;
  898.     for(i=0; i < cnt; i++)
  899. DC390_write8 (ScsiFifo, *(ptr++));
  900.     pSRB->MsgCnt = 0;
  901.     if( (pDCB->DCBFlag & ABORT_DEV_) &&
  902. (pSRB->MsgOutBuf[0] == ABORT) )
  903. pSRB->SRBState = SRB_ABORT_SENT;
  904. }
  905. else
  906. {
  907.     bval = ABORT; /* ??? MSG_NOP */
  908.     if( (pSRB->pcmd->cmnd[0] == INQUIRY ) ||
  909. (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) ||
  910. (pSRB->SRBFlag & AUTO_REQSENSE) )
  911.     {
  912. if( pDCB->SyncMode & SYNC_ENABLE )
  913.     goto  mop1;
  914.     }
  915.     DC390_write8 (ScsiFifo, bval);
  916. }
  917. DC390_write8 (ScsiCmd, INFO_XFER_CMD);
  918.     }
  919.     else
  920.     {
  921. mop1:
  922.         printk (KERN_ERR "DC390: OLD Sync Nego code triggered! (%i %i)n", pDCB->TargetID, pDCB->TargetLUN);
  923. DC390_write8 (ScsiFifo, EXTENDED_MESSAGE);
  924. DC390_write8 (ScsiFifo, 3); /*    ;length of extended msg */
  925. DC390_write8 (ScsiFifo, EXTENDED_SDTR); /*    ; sync nego */
  926. DC390_write8 (ScsiFifo, pDCB->NegoPeriod);
  927. if (pDCB->SyncOffset & 0x0f)
  928.     DC390_write8 (ScsiFifo, pDCB->SyncOffset);
  929. else
  930.     DC390_write8 (ScsiFifo, SYNC_NEGO_OFFSET);     
  931. pSRB->SRBState |= DO_SYNC_NEGO;
  932. DC390_write8 (ScsiCmd, INFO_XFER_CMD);
  933.     }
  934. }
  935. static void
  936. dc390_MsgInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  937. {
  938.     DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
  939.     if( !(pSRB->SRBState & SRB_MSGIN) )
  940.     {
  941. pSRB->SRBState &= ~SRB_DISCONNECT;
  942. pSRB->SRBState |= SRB_MSGIN;
  943.     }
  944.     DC390_write8 (ScsiCmd, INFO_XFER_CMD);
  945.     //DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
  946. }
  947. static void
  948. dc390_Nop_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  949. {
  950. }
  951. static void
  952. dc390_Nop_1( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  953. {
  954. }
  955. static void
  956. dc390_SetXferRate( PACB pACB, PDCB pDCB )
  957. {
  958.     UCHAR  bval, i, cnt;
  959.     PDCB   ptr;
  960.     if( !(pDCB->TargetLUN) )
  961.     {
  962. if( !pACB->scan_devices )
  963. {
  964.     ptr = pACB->pLinkDCB;
  965.     cnt = pACB->DCBCnt;
  966.     bval = pDCB->TargetID;
  967.     for(i=0; i<cnt; i++)
  968.     {
  969. if( ptr->TargetID == bval )
  970. {
  971.     ptr->SyncPeriod = pDCB->SyncPeriod;
  972.     ptr->SyncOffset = pDCB->SyncOffset;
  973.     ptr->CtrlR3 = pDCB->CtrlR3;
  974.     ptr->CtrlR4 = pDCB->CtrlR4;
  975.     ptr->SyncMode = pDCB->SyncMode;
  976. }
  977. ptr = ptr->pNextDCB;
  978.     }
  979. }
  980.     }
  981.     return;
  982. }
  983. void
  984. dc390_Disconnect( PACB pACB )
  985. {
  986.     PDCB   pDCB;
  987.     PSRB   pSRB, psrb;
  988.     UCHAR  i, cnt;
  989.     DEBUG0(printk(KERN_INFO "DISC,");)
  990.     if (!pACB->Connected) printk(KERN_ERR "DC390: Disconnect not-connected bus?n");
  991.     pACB->Connected = 0;
  992.     pDCB = pACB->pActiveDCB;
  993.     if (!pDCB)
  994.      {
  995. int j = 400;
  996. DEBUG0(printk(KERN_ERR "ACB:%p->ActiveDCB:%p IOPort:%04x IRQ:%02x !n",
  997.        pACB, pDCB, pACB->IOPortBase, pACB->IRQLevel);)
  998. while (--j) udelay (1000);
  999. DC390_read8 (INT_Status); /* Reset Pending INT */
  1000. DC390_write8 (ScsiCmd, EN_SEL_RESEL);
  1001. return;
  1002.      }
  1003.     DC390_write8 (ScsiCmd, EN_SEL_RESEL);
  1004.     pSRB = pDCB->pActiveSRB;
  1005.     pACB->pActiveDCB = 0;
  1006.     pSRB->ScsiPhase = SCSI_NOP0;
  1007.     if( pSRB->SRBState & SRB_UNEXPECT_RESEL )
  1008.     {
  1009. pSRB->SRBState = 0;
  1010. dc390_Waiting_process ( pACB );
  1011.     }
  1012.     else if( pSRB->SRBState & SRB_ABORT_SENT )
  1013.     {
  1014. pDCB->TagMask = 0;
  1015. pDCB->DCBFlag = 0;
  1016. cnt = pDCB->GoingSRBCnt;
  1017. pDCB->GoingSRBCnt = 0;
  1018. pSRB = pDCB->pGoingSRB;
  1019. for( i=0; i < cnt; i++)
  1020. {
  1021.     psrb = pSRB->pNextSRB;
  1022.     dc390_Free_insert (pACB, pSRB);
  1023.     pSRB = psrb;
  1024. }
  1025. pDCB->pGoingSRB = 0;
  1026. dc390_Query_to_Waiting (pACB);
  1027. dc390_Waiting_process (pACB);
  1028.     }
  1029.     else
  1030.     {
  1031. if( (pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) ||
  1032.    !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED)) )
  1033. { /* Selection time out */
  1034.     if( !(1/*pACB->scan_devices*/) )
  1035.     {
  1036. pSRB->SRBState = SRB_READY;
  1037. dc390_freetag (pDCB, pSRB);
  1038. dc390_Going_to_Waiting (pDCB, pSRB);
  1039. dc390_waiting_timer (pACB, HZ/5);
  1040.     }
  1041.     else
  1042.     {
  1043. pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT;
  1044. goto  disc1;
  1045.     }
  1046. }
  1047. else if( pSRB->SRBState & SRB_DISCONNECT )
  1048. {
  1049.     dc390_Waiting_process ( pACB );
  1050. }
  1051. else if( pSRB->SRBState & SRB_COMPLETED )
  1052. {
  1053. disc1:
  1054.     dc390_freetag (pDCB, pSRB);
  1055.     pDCB->pActiveSRB = 0;
  1056.     pSRB->SRBState = SRB_FREE;
  1057.     dc390_SRBdone( pACB, pDCB, pSRB);
  1058. }
  1059.     }
  1060.     pACB->MsgLen = 0;
  1061. }
  1062. void
  1063. dc390_Reselect( PACB pACB )
  1064. {
  1065.     PDCB   pDCB;
  1066.     PSRB   pSRB;
  1067.     UCHAR  id, lun;
  1068.     DEBUG0(printk(KERN_INFO "RSEL,");)
  1069.     pACB->Connected = 1;
  1070.     pDCB = pACB->pActiveDCB;
  1071.     if( pDCB )
  1072.     { /* Arbitration lost but Reselection won */
  1073. DEBUG0(printk ("DC390: (ActiveDCB != 0: Arb. lost but resel. won)!n");)
  1074. pSRB = pDCB->pActiveSRB;
  1075. if( !( pACB->scan_devices ) )
  1076. {
  1077.     pSRB->SRBState = SRB_READY;
  1078.     dc390_freetag (pDCB, pSRB);
  1079.     dc390_Going_to_Waiting ( pDCB, pSRB);
  1080.     dc390_waiting_timer (pACB, HZ/5);
  1081. }
  1082.     }
  1083.     /* Get ID */
  1084.     lun = DC390_read8 (ScsiFifo);
  1085.     DEBUG0(printk ("Dev %02x,", lun);)
  1086.     if (!(lun & (1 << pACB->pScsiHost->this_id)))
  1087.       printk (KERN_ERR "DC390: Reselection must select host adapter: %02x!n", lun);
  1088.     else
  1089.       lun ^= 1 << pACB->pScsiHost->this_id; /* Mask AdapterID */
  1090.     id = 0; while (lun >>= 1) id++;
  1091.     /* Get LUN */
  1092.     lun = DC390_read8 (ScsiFifo);
  1093.     if (!(lun & IDENTIFY_BASE)) printk (KERN_ERR "DC390: Resel: Expect identify message!n");
  1094.     lun &= 7;
  1095.     DEBUG0(printk ("(%02i-%i),", id, lun);)
  1096.     pDCB = dc390_findDCB (pACB, id, lun);
  1097.     if (!pDCB)
  1098.     {
  1099. printk (KERN_ERR "DC390: Reselect from non existing device (%02i-%i)n",
  1100.     id, lun);
  1101. return;
  1102.     }
  1103.     pACB->pActiveDCB = pDCB;
  1104.     /* TagQ: We expect a message soon, so never mind the exact SRB */
  1105.     if( pDCB->SyncMode & EN_TAG_QUEUEING )
  1106.     {
  1107. pSRB = pACB->pTmpSRB;
  1108. pDCB->pActiveSRB = pSRB;
  1109.     }
  1110.     else
  1111.     {
  1112. pSRB = pDCB->pActiveSRB;
  1113. if( !pSRB || !(pSRB->SRBState & SRB_DISCONNECT) )
  1114. {
  1115.     pSRB= pACB->pTmpSRB;
  1116.     pSRB->SRBState = SRB_UNEXPECT_RESEL;
  1117.     printk (KERN_ERR "DC390: Reselect without outstanding cmnd (%02i-%i)n",
  1118.     id, lun);
  1119.     pDCB->pActiveSRB = pSRB;
  1120.     dc390_EnableMsgOut_Abort ( pACB, pSRB );
  1121. }
  1122. else
  1123. {
  1124.     if( pDCB->DCBFlag & ABORT_DEV_ )
  1125.     {
  1126. pSRB->SRBState = SRB_ABORT_SENT;
  1127. printk (KERN_INFO "DC390: Reselect: Abort (%02i-%i)n",
  1128. id, lun);
  1129. dc390_EnableMsgOut_Abort( pACB, pSRB );
  1130.     }
  1131.     else
  1132. pSRB->SRBState = SRB_DATA_XFER;
  1133. }
  1134.     }
  1135.     DEBUG1(printk (KERN_DEBUG "Resel SRB(%p): TagNum (%02x)n", pSRB, pSRB->TagNumber);)
  1136.     pSRB->ScsiPhase = SCSI_NOP0;
  1137.     DC390_write8 (Scsi_Dest_ID, pDCB->TargetID);
  1138.     DC390_write8 (Sync_Period, pDCB->SyncPeriod);
  1139.     DC390_write8 (Sync_Offset, pDCB->SyncOffset);
  1140.     DC390_write8 (CtrlReg1, pDCB->CtrlR1);
  1141.     DC390_write8 (CtrlReg3, pDCB->CtrlR3);
  1142.     DC390_write8 (CtrlReg4, pDCB->CtrlR4); /* ; Glitch eater */
  1143.     DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD); /* ;to release the /ACK signal */
  1144. }
  1145. static void 
  1146. dc390_remove_dev (PACB pACB, PDCB pDCB)
  1147. {
  1148.    PDCB pPrevDCB = pACB->pLinkDCB;
  1149.    if (pDCB->GoingSRBCnt > 1)
  1150.      {
  1151. DCBDEBUG(printk (KERN_INFO "DC390: Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %in",
  1152. pDCB->TargetID, pDCB->TargetLUN, (int)pDCB, pDCB->GoingSRBCnt);)
  1153. return;
  1154.      };
  1155.    pACB->DCBmap[pDCB->TargetID] &= ~(1 << pDCB->TargetLUN);
  1156.    
  1157.    // The first one
  1158.    if (pDCB == pACB->pLinkDCB) 
  1159.    {
  1160. // The last one
  1161. if (pACB->pLastDCB == pDCB) {
  1162. pDCB->pNextDCB = 0; pACB->pLastDCB = 0;
  1163. }
  1164. pACB->pLinkDCB = pDCB->pNextDCB;
  1165.    }
  1166.    else
  1167.    {
  1168. while (pPrevDCB->pNextDCB != pDCB) pPrevDCB = pPrevDCB->pNextDCB;
  1169. pPrevDCB->pNextDCB = pDCB->pNextDCB;
  1170. if (pDCB == pACB->pLastDCB) pACB->pLastDCB = pPrevDCB;
  1171.    }
  1172.    DCBDEBUG(printk (KERN_INFO "DC390: Driver about to free DCB (ID %i, LUN %i): %pn",
  1173.    pDCB->TargetID, pDCB->TargetLUN, pDCB);)
  1174.    if (pDCB == pACB->pActiveDCB) pACB->pActiveDCB = 0;
  1175.    if (pDCB == pACB->pLinkDCB) pACB->pLinkDCB = pDCB->pNextDCB;
  1176.    if (pDCB == pACB->pDCBRunRobin) pACB->pDCBRunRobin = pDCB->pNextDCB;
  1177.    kfree (pDCB); 
  1178.    pACB->DCBCnt--;
  1179.    /* pACB->DeviceCnt--; */
  1180. };
  1181. static UCHAR __inline__
  1182. dc390_tagq_blacklist (char* name)
  1183. {
  1184.    UCHAR i;
  1185.    for(i=0; i<BADDEVCNT; i++)
  1186.      if (memcmp (name, dc390_baddevname1[i], 28) == 0)
  1187. return 1;
  1188.    return 0;
  1189. };
  1190.    
  1191. static void 
  1192. dc390_disc_tagq_set (PDCB pDCB, PSCSI_INQDATA ptr)
  1193. {
  1194.    /* Check for SCSI format (ANSI and Response data format) */
  1195.    if ( (ptr->Vers & 0x07) >= 2 || (ptr->RDF & 0x0F) == 2 )
  1196.    {
  1197. if ( (ptr->Flags & SCSI_INQ_CMDQUEUE) &&
  1198.     (pDCB->DevMode & TAG_QUEUEING_) &&
  1199.     /* ((pDCB->DevType == TYPE_DISK) 
  1200. || (pDCB->DevType == TYPE_MOD)) &&*/
  1201.     !dc390_tagq_blacklist (((char*)ptr)+8) )
  1202.   {
  1203.      if (pDCB->MaxCommand ==1) pDCB->MaxCommand = pDCB->pDCBACB->TagMaxNum;
  1204.      pDCB->SyncMode |= EN_TAG_QUEUEING /* | EN_ATN_STOP */;
  1205.      //pDCB->TagMask = 0;
  1206.   }
  1207. else
  1208.      pDCB->MaxCommand = 1;
  1209.      }
  1210. };
  1211. static void 
  1212. dc390_add_dev (PACB pACB, PDCB pDCB, PSCSI_INQDATA ptr)
  1213. {
  1214.    UCHAR bval1 = ptr->DevType & SCSI_DEVTYPE;
  1215.    pDCB->DevType = bval1;
  1216.    /* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */
  1217. dc390_disc_tagq_set (pDCB, ptr);
  1218. };
  1219. void
  1220. dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
  1221. {
  1222.     UCHAR  bval, status, i, DCB_removed;
  1223.     PSCSICMD pcmd;
  1224.     PSCSI_INQDATA  ptr;
  1225.     PSGL   ptr2;
  1226.     ULONG  swlval;
  1227.     pcmd = pSRB->pcmd; DCB_removed = 0;
  1228.     status = pSRB->TargetStatus;
  1229.     ptr = (PSCSI_INQDATA) (pcmd->request_buffer);
  1230.     if( pcmd->use_sg )
  1231. ptr = (PSCSI_INQDATA) (((PSGL) ptr)->address);
  1232.     DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %lin", status, pcmd->result,
  1233. pSRB, pcmd->pid);)
  1234.     if(pSRB->SRBFlag & AUTO_REQSENSE)
  1235.     { /* Last command was a Request Sense */
  1236. pSRB->SRBFlag &= ~AUTO_REQSENSE;
  1237. pSRB->AdaptStatus = 0;
  1238. pSRB->TargetStatus = CHECK_CONDITION << 1;
  1239. #ifdef DC390_REMOVABLEDEBUG
  1240. switch (pcmd->sense_buffer[2] & 0x0f)
  1241. {     
  1242.  case NOT_READY: printk (KERN_INFO "DC390: ReqSense: NOT_READY (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)n",
  1243.  pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
  1244.  status, pACB->scan_devices); break;
  1245.  case UNIT_ATTENTION: printk (KERN_INFO "DC390: ReqSense: UNIT_ATTENTION (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)n",
  1246.       pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
  1247.       status, pACB->scan_devices); break;
  1248.  case ILLEGAL_REQUEST: printk (KERN_INFO "DC390: ReqSense: ILLEGAL_REQUEST (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)n",
  1249.        pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
  1250.        status, pACB->scan_devices); break;
  1251.  case MEDIUM_ERROR: printk (KERN_INFO "DC390: ReqSense: MEDIUM_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)n",
  1252.     pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
  1253.     status, pACB->scan_devices); break;
  1254.  case HARDWARE_ERROR: printk (KERN_INFO "DC390: ReqSense: HARDWARE_ERROR (Cmnd = 0x%02x, Dev = %i-%i, Stat = %i, Scan = %i)n",
  1255.       pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN,
  1256.       status, pACB->scan_devices); break;
  1257. }
  1258. #endif
  1259. //pcmd->result = MK_RES(DRIVER_SENSE,DID_OK,0,status);
  1260. if (status == (CHECK_CONDITION << 1))
  1261. {
  1262.     pcmd->result = MK_RES_LNX(0,DID_BAD_TARGET,0,/*CHECK_CONDITION*/0);
  1263.     goto ckc_e;
  1264. }
  1265. if(pSRB->RetryCnt == 0)
  1266. {
  1267.     //(UINT)(pSRB->pcmd->cmnd[0]) = pSRB->Segment0[0];
  1268.     pSRB->TotalXferredLen = pSRB->SavedTotXLen;
  1269.     if( (pSRB->TotalXferredLen) &&
  1270. (pSRB->TotalXferredLen >= pcmd->underflow) )
  1271.   SET_RES_DID(pcmd->result,DID_OK)
  1272.     else
  1273.   pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION);
  1274.   REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x,Result=%08x,XferL=%08xn",pSRB->pcmd->cmnd[0],
  1275. (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);)
  1276.     goto ckc_e;
  1277. }
  1278. else /* Retry */
  1279. {
  1280.     pSRB->RetryCnt--;
  1281.     pSRB->AdaptStatus = 0;
  1282.     pSRB->TargetStatus = 0;
  1283.     //*((PUINT) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
  1284.     //*((PUINT) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1];
  1285.     /* Don't retry on TEST_UNIT_READY */
  1286.     if( pSRB->pcmd->cmnd[0] == TEST_UNIT_READY /* || pSRB->pcmd->cmnd[0] == START_STOP */)
  1287.     {
  1288. pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION);
  1289. REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08xn",pSRB->pcmd->cmnd[0],
  1290.        (UINT) pcmd->result, (UINT) pSRB->TotalXferredLen);)
  1291. goto ckc_e;
  1292.     }
  1293.     SET_RES_DRV(pcmd->result,DRIVER_SENSE);
  1294.     pSRB->SGcount  = (UCHAR) pSRB->SavedSGCount;
  1295.     //pSRB->ScsiCmdLen  = (UCHAR) (pSRB->Segment1[0] >> 8);
  1296.     DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02in", pcmd->pid, pcmd->cmnd[0], pcmd->target, pcmd->lun);)
  1297.     pSRB->SGIndex = 0;
  1298.     pSRB->TotalXferredLen = 0;
  1299.     pSRB->SGToBeXferLen = 0;
  1300.     if( pcmd->use_sg )
  1301. pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
  1302.     else if( pcmd->request_buffer )
  1303.     {
  1304. pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
  1305. pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
  1306. pSRB->Segmentx.length = pcmd->request_bufflen;
  1307.     }
  1308.     if( dc390_StartSCSI( pACB, pDCB, pSRB ) ) {
  1309. dc390_Going_to_Waiting ( pDCB, pSRB );
  1310. dc390_waiting_timer (pACB, HZ/5);
  1311.     }
  1312.     return;
  1313. }
  1314.     }
  1315.     if( status )
  1316.     {
  1317. if( status_byte(status) == CHECK_CONDITION )
  1318. {
  1319.     REMOVABLEDEBUG(printk (KERN_INFO "DC390: Check_Condition (Cmd %02x, Id %02x, LUN %02x)n",
  1320.     pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN);)
  1321.     if( (pSRB->SGIndex < pSRB->SGcount) && (pSRB->SGcount) && (pSRB->SGToBeXferLen) )
  1322.     {
  1323. bval = pSRB->SGcount;
  1324. swlval = 0;
  1325. ptr2 = pSRB->pSegmentList;
  1326. for( i=pSRB->SGIndex; i < bval; i++)
  1327. {
  1328.     swlval += ptr2->length;
  1329.     ptr2++;
  1330. }
  1331. REMOVABLEDEBUG(printk(KERN_INFO "XferredLen=%08x,NotXferLen=%08xn",
  1332. (UINT) pSRB->TotalXferredLen, (UINT) swlval);)
  1333.     }
  1334.     dc390_RequestSense( pACB, pDCB, pSRB );
  1335.     return;
  1336. }
  1337. else if( status_byte(status) == QUEUE_FULL )
  1338. {
  1339.     bval = (UCHAR) pDCB->GoingSRBCnt;
  1340.     bval--;
  1341.     pDCB->MaxCommand = bval;
  1342.     dc390_freetag (pDCB, pSRB);
  1343.     dc390_Going_to_Waiting ( pDCB, pSRB );
  1344.     dc390_waiting_timer (pACB, HZ/5);
  1345.     pSRB->AdaptStatus = 0;
  1346.     pSRB->TargetStatus = 0;
  1347.     return;
  1348. }
  1349. else if(status == SCSI_STAT_SEL_TIMEOUT)
  1350. {
  1351.     pSRB->AdaptStatus = H_SEL_TIMEOUT;
  1352.     pSRB->TargetStatus = 0;
  1353.     pcmd->result = MK_RES(0,DID_NO_CONNECT,0,0);
  1354.     /* Devices are removed below ... */
  1355. }
  1356. else if (status_byte(status) == BUSY && 
  1357.  (pcmd->cmnd[0] == TEST_UNIT_READY || pcmd->cmnd[0] == INQUIRY) &&
  1358.  pACB->scan_devices)
  1359. {
  1360.     pSRB->AdaptStatus = 0;
  1361.     pSRB->TargetStatus = status;
  1362.     pcmd->result = MK_RES(0,0,pSRB->EndMessage,/*status*/0);
  1363. }
  1364. else
  1365. {   /* Another error */
  1366.     pSRB->AdaptStatus = 0;
  1367.     if( pSRB->RetryCnt )
  1368.     { /* Retry */
  1369. //printk ("DC390: retryn");
  1370. pSRB->RetryCnt--;
  1371. pSRB->TargetStatus = 0;
  1372. pSRB->SGIndex = 0;
  1373. pSRB->TotalXferredLen = 0;
  1374. pSRB->SGToBeXferLen = 0;
  1375. if( pcmd->use_sg )
  1376.     pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
  1377. else if( pcmd->request_buffer )
  1378. {
  1379.     pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
  1380.     pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
  1381.     pSRB->Segmentx.length = pcmd->request_bufflen;
  1382. }
  1383. if( dc390_StartSCSI( pACB, pDCB, pSRB ) ) {
  1384.     dc390_Going_to_Waiting ( pDCB, pSRB );
  1385.     dc390_waiting_timer (pACB, HZ/5);
  1386. }
  1387.        return;
  1388.     }
  1389.     else
  1390.     { /* Report error */
  1391.       //pcmd->result = MK_RES(0, DID_ERROR, pSRB->EndMessage, status);
  1392.       SET_RES_DID(pcmd->result,DID_ERROR);
  1393.       SET_RES_MSG(pcmd->result,pSRB->EndMessage);
  1394.       SET_RES_TARGET(pcmd->result,status);
  1395.     }
  1396. }
  1397.     }
  1398.     else
  1399.     { /*  Target status == 0 */
  1400. status = pSRB->AdaptStatus;
  1401. if(status & H_OVER_UNDER_RUN)
  1402. {
  1403.     pSRB->TargetStatus = 0;
  1404.     SET_RES_DID(pcmd->result,DID_OK);
  1405.     SET_RES_MSG(pcmd->result,pSRB->EndMessage);
  1406. }
  1407. else if( pSRB->SRBStatus & PARITY_ERROR)
  1408. {
  1409.     //pcmd->result = MK_RES(0,DID_PARITY,pSRB->EndMessage,0);
  1410.     SET_RES_DID(pcmd->result,DID_PARITY);
  1411.     SET_RES_MSG(pcmd->result,pSRB->EndMessage);
  1412. }
  1413. else        /* No error */
  1414. {
  1415.     pSRB->AdaptStatus = 0;
  1416.     pSRB->TargetStatus = 0;
  1417.     SET_RES_DID(pcmd->result,DID_OK);
  1418. }
  1419.     }
  1420.     if ((pcmd->result & RES_DID) == 0 &&
  1421. pcmd->cmnd[0] == INQUIRY && 
  1422. pcmd->cmnd[2] == 0 &&
  1423. pcmd->request_bufflen >= 8 &&
  1424. ptr &&
  1425. (ptr->Vers & 0x07) >= 2)
  1426.     pDCB->Inquiry7 = ptr->Flags;
  1427. ckc_e:
  1428.     if( pACB->scan_devices )
  1429.     {
  1430. if( pcmd->cmnd[0] == TEST_UNIT_READY ||
  1431.     pcmd->cmnd[0] == INQUIRY)
  1432. {
  1433. #ifdef DC390_DEBUG0
  1434.     printk (KERN_INFO "DC390: %s: result: %08x", 
  1435.     (pcmd->cmnd[0] == INQUIRY? "INQUIRY": "TEST_UNIT_READY"),
  1436.     pcmd->result);
  1437.     if (pcmd->result & (DRIVER_SENSE << 24)) printk (" (sense: %02x %02x %02x %02x)n",
  1438.    pcmd->sense_buffer[0], pcmd->sense_buffer[1],
  1439.    pcmd->sense_buffer[2], pcmd->sense_buffer[3]);
  1440.     else printk ("n");
  1441. #endif
  1442.     if( (host_byte(pcmd->result) != DID_OK && !(status_byte(pcmd->result) & CHECK_CONDITION) && !(status_byte(pcmd->result) & BUSY)) ||
  1443.        ((driver_byte(pcmd->result) & DRIVER_SENSE) && (pcmd->sense_buffer[0] & 0x70) == 0x70 &&
  1444. (pcmd->sense_buffer[2] & 0xf) == ILLEGAL_REQUEST) || host_byte(pcmd->result) & DID_ERROR )
  1445.     {
  1446.        /* device not present: remove */ 
  1447.        //dc390_Going_remove (pDCB, pSRB);
  1448.        dc390_remove_dev (pACB, pDCB); DCB_removed = 1;
  1449.        
  1450.        if( (pcmd->target == pACB->pScsiHost->max_id - 1) &&
  1451.   ((pcmd->lun == 0) || (pcmd->lun == pACB->pScsiHost->max_lun - 1)) )
  1452.  pACB->scan_devices = 0;
  1453.     }
  1454.     else
  1455.     {
  1456.         /* device present: add */
  1457. if( (pcmd->target == pACB->pScsiHost->max_id - 1) && 
  1458.     (pcmd->lun == pACB->pScsiHost->max_lun - 1) )
  1459.     pACB->scan_devices = END_SCAN ;
  1460.         /* pACB->DeviceCnt++; */ /* Dev is added on INQUIRY */
  1461.     }
  1462. }
  1463.     }
  1464.    
  1465.     //if( pSRB->pcmd->cmnd[0] == INQUIRY && 
  1466.     //  (host_byte(pcmd->result) == DID_OK || status_byte(pcmd->result) & CHECK_CONDITION) )
  1467.     if( pcmd->cmnd[0] == INQUIRY && 
  1468. (pcmd->result == (DID_OK << 16) || status_byte(pcmd->result) & CHECK_CONDITION) )
  1469.      {
  1470. if ((ptr->DevType & SCSI_DEVTYPE) == TYPE_NODEV && !DCB_removed)
  1471.   {
  1472.      //printk ("DC390: Type = nodev! (%02i-%i)n", pcmd->target, pcmd->lun);
  1473.      /* device not present: remove */
  1474.      //dc390_Going_remove (pDCB, pSRB);
  1475.      dc390_remove_dev (pACB, pDCB); DCB_removed = 1;
  1476.   }
  1477. else
  1478.   {
  1479.      /* device found: add */ 
  1480.      dc390_add_dev (pACB, pDCB, ptr);
  1481.      if (pACB->scan_devices) pACB->DeviceCnt++;
  1482.   }
  1483. if( (pcmd->target == pACB->pScsiHost->max_id - 1) &&
  1484.     (pcmd->lun == pACB->pScsiHost->max_lun - 1) )
  1485.   pACB->scan_devices = 0;
  1486.      };
  1487. #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,30)
  1488.     pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen;
  1489. #endif
  1490.     if (!DCB_removed) dc390_Going_remove (pDCB, pSRB);
  1491.     /* Add to free list */
  1492.     dc390_Free_insert (pACB, pSRB);
  1493.     DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done pid %lin", pcmd->pid);)
  1494.     DC390_UNLOCK_ACB_NI;
  1495.     pcmd->scsi_done (pcmd);
  1496.     DC390_LOCK_ACB_NI;
  1497.     dc390_Query_to_Waiting (pACB);
  1498.     dc390_Waiting_process (pACB);
  1499.     return;
  1500. }
  1501. /* Remove all SRBs from Going list and inform midlevel */
  1502. void
  1503. dc390_DoingSRB_Done( PACB pACB, PSCSICMD cmd )
  1504. {
  1505.     PDCB   pDCB, pdcb;
  1506.     PSRB   psrb, psrb2;
  1507.     UCHAR  i;
  1508.     PSCSICMD pcmd;
  1509.     pDCB = pACB->pLinkDCB;
  1510.     pdcb = pDCB;
  1511.     if (! pdcb) return;
  1512.     do
  1513.     {
  1514. psrb = pdcb->pGoingSRB;
  1515. for( i=0; i<pdcb->GoingSRBCnt; i++)
  1516. {
  1517.     psrb2 = psrb->pNextSRB;
  1518.     pcmd = psrb->pcmd;
  1519.     dc390_Free_insert (pACB, psrb);
  1520. #ifndef USE_NEW_EH
  1521.     /* New EH will crash on being given timed out cmnds */
  1522.     if (pcmd == cmd)
  1523. pcmd->result = MK_RES(0,DID_ABORT,0,0);
  1524.     else
  1525. pcmd->result = MK_RES(0,DID_RESET,0,0);
  1526. /*     ReleaseSRB( pDCB, pSRB ); */
  1527.     DEBUG0(printk (KERN_DEBUG "DC390: DoingSRB_Done: done pid %lin", pcmd->pid);)
  1528.     DC390_UNLOCK_ACB_NI;
  1529.     pcmd->scsi_done( pcmd );
  1530.     DC390_LOCK_ACB_NI;
  1531. #endif
  1532.     psrb  = psrb2;
  1533. }
  1534. pdcb->GoingSRBCnt = 0;;
  1535. pdcb->pGoingSRB = NULL;
  1536. pdcb->TagMask = 0;
  1537. pdcb = pdcb->pNextDCB;
  1538.     } while( pdcb != pDCB );
  1539.     dc390_Query_to_Waiting (pACB);
  1540. }
  1541. static void
  1542. dc390_ResetSCSIBus( PACB pACB )
  1543. {
  1544.     //DC390_write8 (ScsiCmd, RST_DEVICE_CMD);
  1545.     //udelay (250);
  1546.     //DC390_write8 (ScsiCmd, NOP_CMD);
  1547.     DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
  1548.     DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
  1549.     DC390_write8 (ScsiCmd, RST_SCSI_BUS_CMD);
  1550.     pACB->Connected = 0;
  1551.     return;
  1552. }
  1553. static void
  1554. dc390_ScsiRstDetect( PACB pACB )
  1555. {
  1556.     printk ("DC390: Rst_Detect: laststat = %08xn", dc390_laststatus);
  1557.     //DEBUG0(printk(KERN_INFO "RST_DETECT,");)
  1558.     if (timer_pending (&pACB->Waiting_Timer)) del_timer (&pACB->Waiting_Timer);
  1559.     DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
  1560.     /* Unlock before ? */
  1561.     /* delay half a second */
  1562.     udelay (1000);
  1563.     DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
  1564.     pACB->pScsiHost->last_reset = jiffies + 5*HZ/2
  1565.     + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
  1566.     pACB->Connected = 0;
  1567.     if( pACB->ACBFlag & RESET_DEV )
  1568. pACB->ACBFlag |= RESET_DONE;
  1569.     else
  1570.     {   /* Reset was issued by sb else */
  1571. pACB->ACBFlag |= RESET_DETECT;
  1572. dc390_ResetDevParam( pACB );
  1573. dc390_DoingSRB_Done( pACB, 0 );
  1574. //dc390_RecoverSRB( pACB );
  1575. pACB->pActiveDCB = NULL;
  1576. pACB->ACBFlag = 0;
  1577. dc390_Waiting_process( pACB );
  1578.     }
  1579.     return;
  1580. }
  1581. static void __inline__
  1582. dc390_RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB )
  1583. {
  1584.     PSCSICMD  pcmd;
  1585.     REMOVABLEDEBUG(printk (KERN_INFO "DC390: RequestSense (Cmd %02x, Id %02x, LUN %02x)n",
  1586.     pSRB->pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN);)
  1587.     pSRB->SRBFlag |= AUTO_REQSENSE;
  1588.     //pSRB->Segment0[0] = (UINT) pSRB->CmdBlock[0];
  1589.     //pSRB->Segment0[1] = (UINT) pSRB->CmdBlock[4];
  1590.     //pSRB->Segment1[0] = ((UINT)(pSRB->pcmd->cmd_len) << 8) + pSRB->SGcount;
  1591.     //pSRB->Segment1[1] = pSRB->TotalXferredLen;
  1592.     pSRB->SavedSGCount = pSRB->SGcount;
  1593.     pSRB->SavedTotXLen = pSRB->TotalXferredLen;
  1594.     pSRB->AdaptStatus = 0;
  1595.     pSRB->TargetStatus = 0; /* CHECK_CONDITION<<1; */
  1596.     pcmd = pSRB->pcmd;
  1597.     pSRB->Segmentx.address = (PUCHAR) &(pcmd->sense_buffer);
  1598.     pSRB->Segmentx.length = sizeof(pcmd->sense_buffer);
  1599.     pSRB->pSegmentList = &pSRB->Segmentx;
  1600.     pSRB->SGcount = 1;
  1601.     pSRB->SGIndex = 0;
  1602.     //pSRB->CmdBlock[0] = REQUEST_SENSE;
  1603.     //pSRB->CmdBlock[1] = pDCB->TargetLUN << 5;
  1604.     //(USHORT) pSRB->CmdBlock[2] = 0;
  1605.     //(USHORT) pSRB->CmdBlock[4] = sizeof(pcmd->sense_buffer);
  1606.     //pSRB->ScsiCmdLen = 6;
  1607.     pSRB->TotalXferredLen = 0;
  1608.     pSRB->SGToBeXferLen = 0;
  1609.     if( dc390_StartSCSI( pACB, pDCB, pSRB ) ) {
  1610. dc390_Going_to_Waiting ( pDCB, pSRB );
  1611. dc390_waiting_timer (pACB, HZ/5);
  1612.     }
  1613. }
  1614. static void __inline__
  1615. dc390_InvalidCmd( PACB pACB )
  1616. {
  1617.     if( pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_+SRB_MSGOUT) )
  1618. DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
  1619. }