The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pci/scsiiom.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 
    8 
    9 static USHORT
   10 DC390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB )
   11 {
   12     USHORT ioport, rc;
   13     UCHAR  bval, bval1, i, cnt;
   14     PUCHAR ptr;
   15     ULONG  wlval;
   16 
   17     pSRB->TagNumber = 31;
   18     ioport = pACB->IOPortBase;
   19     bval = pDCB->UnitSCSIID;
   20     OutB(bval,ioport+Scsi_Dest_ID);
   21     bval = pDCB->SyncPeriod;
   22     OutB(bval,ioport+Sync_Period);
   23     bval = pDCB->SyncOffset;
   24     OutB(bval,ioport+Sync_Offset);
   25     bval = pDCB->CtrlR1;
   26     OutB(bval,ioport+CtrlReg1);
   27     bval = pDCB->CtrlR3;
   28     OutB(bval,ioport+CtrlReg3);
   29     bval = pDCB->CtrlR4;
   30     OutB(bval,ioport+CtrlReg4);
   31     bval = CLEAR_FIFO_CMD;         /* Flush FIFO */
   32     OutB(bval,ioport+ScsiCmd);
   33 
   34     pSRB->ScsiPhase = SCSI_NOP0;
   35     bval = pDCB->IdentifyMsg;
   36     if( !(pDCB->SyncMode & EN_ATN_STOP) )
   37     {
   38         if( (pSRB->CmdBlock[0] == INQUIRY) ||
   39             (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
   40             (pSRB->SRBFlag & AUTO_REQSENSE) )
   41         {
   42             bval &= 0xBF;       /* NO disconnection */
   43             OutB(bval,ioport+ScsiFifo);
   44             bval1 = SELECT_W_ATN;
   45             pSRB->SRBState = SRB_START_;
   46             if( pDCB->SyncMode & SYNC_ENABLE )
   47             {
   48                 if( !(pDCB->IdentifyMsg & 7) ||
   49                     (pSRB->CmdBlock[0] != INQUIRY) )
   50                 {
   51                     bval1 = SEL_W_ATN_STOP;
   52                     pSRB->SRBState = SRB_MSGOUT;
   53                 }
   54             }
   55         }
   56         else
   57         {
   58             if(pDCB->SyncMode & EN_TAG_QUEUING)
   59             {
   60                 OutB(bval,ioport+ScsiFifo);
   61                 bval = MSG_SIMPLE_QTAG;
   62                 OutB(bval,ioport+ScsiFifo);
   63                 wlval = 1;
   64                 bval = 0;
   65                 while( wlval & pDCB->TagMask )
   66                 {
   67                     wlval = wlval << 1;
   68                     bval++;
   69                 }
   70                 OutB(bval,ioport+ScsiFifo);
   71                 pDCB->TagMask |= wlval;
   72                 pSRB->TagNumber = bval;
   73                 bval1 = SEL_W_ATN2;
   74                 pSRB->SRBState = SRB_START_;
   75             }
   76             else
   77             {
   78                 OutB(bval,ioport+ScsiFifo);
   79                 bval1 = SELECT_W_ATN;
   80                 pSRB->SRBState = SRB_START_;
   81             }
   82         }
   83 
   84         if( pSRB->SRBFlag & AUTO_REQSENSE )
   85         {
   86             bval = REQUEST_SENSE;
   87             OutB(bval,ioport+ScsiFifo);
   88             bval = pDCB->IdentifyMsg << 5;
   89             OutB(bval,ioport+ScsiFifo);
   90             bval = 0;
   91             OutB(bval,ioport+ScsiFifo);
   92             OutB(bval,ioport+ScsiFifo);
   93             bval = sizeof(struct scsi_sense_data);
   94             OutB(bval,ioport+ScsiFifo);
   95             bval = 0;
   96             OutB(bval,ioport+ScsiFifo);
   97         }
   98         else
   99         {
  100             cnt = pSRB->ScsiCmdLen;
  101             ptr = (PUCHAR) pSRB->CmdBlock;
  102             for(i=0; i<cnt; i++)
  103             {
  104                 bval = *ptr++;
  105                 OutB(bval,ioport+ScsiFifo);
  106             }
  107         }
  108     }
  109     else        /* ATN_STOP */
  110     {
  111         if( (pSRB->CmdBlock[0] == INQUIRY) ||
  112             (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
  113             (pSRB->SRBFlag & AUTO_REQSENSE) )
  114         {
  115             bval &= 0xBF;
  116             OutB(bval,ioport+ScsiFifo);
  117             bval1 = SELECT_W_ATN;
  118             pSRB->SRBState = SRB_START_;
  119             if( pDCB->SyncMode & SYNC_ENABLE )
  120             {
  121                 if( !(pDCB->IdentifyMsg & 7) ||
  122                     (pSRB->CmdBlock[0] != INQUIRY) )
  123                 {
  124                     bval1 = SEL_W_ATN_STOP;
  125                     pSRB->SRBState = SRB_MSGOUT;
  126                 }
  127             }
  128         }
  129         else
  130         {
  131             if(pDCB->SyncMode & EN_TAG_QUEUING)
  132             {
  133                 OutB(bval,ioport+ScsiFifo);
  134                 pSRB->MsgOutBuf[0] = MSG_SIMPLE_QTAG;
  135                 wlval = 1;
  136                 bval = 0;
  137                 while( wlval & pDCB->TagMask )
  138                 {
  139                     wlval = wlval << 1;
  140                     bval++;
  141                 }
  142                 pDCB->TagMask |= wlval;
  143                 pSRB->TagNumber = bval;
  144                 pSRB->MsgOutBuf[1] = bval;
  145                 pSRB->MsgCnt = 2;
  146                 bval1 = SEL_W_ATN_STOP;
  147                 pSRB->SRBState = SRB_START_;
  148             }
  149             else
  150             {
  151                 OutB(bval,ioport+ScsiFifo);
  152                 pSRB->MsgOutBuf[0] = MSG_NOP;
  153                 pSRB->MsgCnt = 1;
  154                 pSRB->SRBState = SRB_START_;
  155                 bval1 = SEL_W_ATN_STOP;
  156             }
  157         }
  158     }
  159     bval = inb( ioport+Scsi_Status );
  160     if( bval & INTERRUPT )
  161     {
  162         pSRB->SRBState = SRB_READY;
  163         pDCB->TagMask &= ~( 1 << pSRB->TagNumber );
  164         rc = 1;
  165     }
  166     else
  167     {
  168         pSRB->ScsiPhase = SCSI_NOP1;
  169         pACB->pActiveDCB = pDCB;
  170         pDCB->pActiveSRB = pSRB;
  171         rc = 0;
  172         OutB(bval1,ioport+ScsiCmd);
  173     }
  174     return( rc );
  175 }
  176 
  177 
  178 #ifdef  REL_2_1_0
  179 static int DC390_Interrupt( PACB pACB )
  180 #endif
  181 #ifdef  REL_2_1_5
  182 static void DC390_Interrupt( PACB pACB )
  183 #endif
  184 {
  185     PDCB   pDCB;
  186     PSRB   pSRB;
  187     USHORT ioport = 0;
  188     USHORT phase;
  189     void   (*stateV)( PACB, PSRB, PUCHAR );
  190     UCHAR  istate = 0;
  191     UCHAR  sstatus=0, istatus;
  192 
  193     if( pACB == NULL )
  194 #ifdef  REL_2_1_0
  195         return 0;
  196 #endif
  197 #ifdef  REL_2_1_5
  198         return;
  199 #endif
  200     ioport = pACB->IOPortBase;
  201     sstatus = inb( ioport+Scsi_Status );
  202     if( !(sstatus & INTERRUPT) )
  203 #ifdef  REL_2_1_0
  204         return 0;
  205 #endif
  206 #ifdef  REL_2_1_5
  207         return;
  208 #endif
  209 
  210 #ifdef DC390_DEBUG1
  211         printf("sstatus=%2x,",sstatus);
  212 #endif
  213 
  214     istate = inb( ioport+Intern_State );
  215     istatus = inb( ioport+INT_Status );
  216 
  217 #ifdef DC390_DEBUG1
  218         printf("Istatus=%2x,",istatus);
  219 #endif
  220 
  221     if(istatus &  DISCONNECTED)
  222     {
  223         DC390_Disconnect( pACB );
  224 #ifdef  REL_2_1_0
  225         return 1;
  226 #endif
  227 #ifdef  REL_2_1_5
  228         return;
  229 #endif
  230     }
  231 
  232     if(istatus &  RESELECTED)
  233     {
  234         DC390_Reselect( pACB );
  235 #ifdef  REL_2_1_0
  236         return 1;
  237 #endif
  238 #ifdef  REL_2_1_5
  239         return;
  240 #endif
  241     }
  242 
  243     if(istatus &  INVALID_CMD)
  244     {
  245         DC390_InvalidCmd( pACB );
  246 #ifdef  REL_2_1_0
  247         return 1;
  248 #endif
  249 #ifdef  REL_2_1_5
  250         return;
  251 #endif
  252     }
  253 
  254     if(istatus &  SCSI_RESET_)
  255     {
  256         DC390_ScsiRstDetect( pACB );
  257 #ifdef  REL_2_1_0
  258         return 1;
  259 #endif
  260 #ifdef  REL_2_1_5
  261         return;
  262 #endif
  263     }
  264 
  265     if( istatus & (SUCCESSFUL_OP+SERVICE_REQUEST) )
  266     {
  267         pDCB = pACB->pActiveDCB;
  268         pSRB = pDCB->pActiveSRB;
  269         if( pDCB )
  270         {
  271             if( pDCB->DCBFlag & ABORT_DEV_ )
  272                 EnableMsgOut( pACB, pSRB );
  273         }
  274 
  275         phase = (USHORT) pSRB->ScsiPhase;
  276         stateV = (void *) DC390_phase0[phase];
  277         stateV( pACB, pSRB, &sstatus );
  278 
  279         pSRB->ScsiPhase = sstatus & 7;
  280         phase = (USHORT) sstatus & 7;
  281         stateV = (void *) DC390_phase1[phase];
  282         stateV( pACB, pSRB, &sstatus );
  283     }
  284 #ifdef  REL_2_1_0
  285         return 1;
  286 #endif
  287 }
  288 
  289 
  290 static void
  291 DC390_DataOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  292 {
  293     UCHAR   sstatus, bval;
  294     USHORT  ioport;
  295     PSEG    psgl;
  296     ULONG   ResidCnt, xferCnt;
  297 
  298     ioport = pACB->IOPortBase;
  299     sstatus = *psstatus;
  300 
  301     if( !(pSRB->SRBState & SRB_XFERPAD) )
  302     {
  303         if( sstatus & PARITY_ERR )
  304             pSRB->SRBStatus |= PARITY_ERROR;
  305 
  306         if( sstatus & COUNT_2_ZERO )
  307         {
  308             bval = inb(ioport+DMA_Status);
  309             while( !(bval & DMA_XFER_DONE) )
  310                 bval = inb(ioport+DMA_Status);
  311             pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
  312             pSRB->SGIndex++;
  313             if( pSRB->SGIndex < pSRB->SGcount )
  314             {
  315                 pSRB->pSegmentList++;
  316                 psgl = pSRB->pSegmentList;
  317                 pSRB->SGPhysAddr = psgl->SGXPtr;
  318                 pSRB->SGToBeXferLen = psgl->SGXLen;
  319             }
  320             else
  321                 pSRB->SGToBeXferLen = 0;
  322         }
  323         else
  324         {
  325             bval = inb( ioport+Current_Fifo );
  326             bval &= 0x1f;
  327             ResidCnt = (ULONG) inb(ioport+CtcReg_High);
  328             ResidCnt = ResidCnt << 8;
  329             ResidCnt |= (ULONG) inb(ioport+CtcReg_Mid);
  330             ResidCnt = ResidCnt << 8;
  331             ResidCnt |= (ULONG) inb(ioport+CtcReg_Low);
  332             ResidCnt += (ULONG) bval;
  333 
  334             xferCnt = pSRB->SGToBeXferLen - ResidCnt;
  335             pSRB->SGPhysAddr += xferCnt;
  336             pSRB->TotalXferredLen += xferCnt;
  337             pSRB->SGToBeXferLen = ResidCnt;
  338         }
  339     }
  340     bval = WRITE_DIRECTION+DMA_IDLE_CMD;
  341     OutB( bval, ioport+DMA_Cmd);
  342 }
  343 
  344 static void
  345 DC390_DataIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  346 {
  347     UCHAR   sstatus, bval;
  348     USHORT  i, ioport, residual;
  349     PSEG    psgl;
  350     ULONG   ResidCnt, xferCnt;
  351     PUCHAR  ptr;
  352 
  353 
  354     ioport = pACB->IOPortBase;
  355     sstatus = *psstatus;
  356 
  357     if( !(pSRB->SRBState & SRB_XFERPAD) )
  358     {
  359         if( sstatus & PARITY_ERR )
  360             pSRB->SRBStatus |= PARITY_ERROR;
  361 
  362         if( sstatus & COUNT_2_ZERO )
  363         {
  364             bval = inb(ioport+DMA_Status);
  365             while( !(bval & DMA_XFER_DONE) )
  366                 bval = inb(ioport+DMA_Status);
  367 
  368             bval = READ_DIRECTION+DMA_IDLE_CMD;
  369             OutB( bval, ioport+DMA_Cmd);
  370 
  371             pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
  372             pSRB->SGIndex++;
  373             if( pSRB->SGIndex < pSRB->SGcount )
  374             {
  375                 pSRB->pSegmentList++;
  376                 psgl = pSRB->pSegmentList;
  377                 pSRB->SGPhysAddr = psgl->SGXPtr;
  378                 pSRB->SGToBeXferLen = psgl->SGXLen;
  379             }
  380             else
  381                 pSRB->SGToBeXferLen = 0;
  382         }
  383         else    /* phase changed */
  384         {
  385             residual = 0;
  386             bval = inb(ioport+Current_Fifo);
  387             while( bval & 0x1f )
  388             {
  389                 if( (bval & 0x1f) == 1 )
  390                 {
  391                     for(i=0; i< 0x100; i++)
  392                     {
  393                         bval = inb(ioport+Current_Fifo);
  394                         if( !(bval & 0x1f) )
  395                             goto din_1;
  396                         else if( i == 0x0ff )
  397                         {
  398                             residual = 1;   /* ;1 residual byte */
  399                             goto din_1;
  400                         }
  401                     }
  402                 }
  403                 else
  404                     bval = inb(ioport+Current_Fifo);
  405             }
  406 din_1:
  407             bval = READ_DIRECTION+DMA_BLAST_CMD;
  408             OutB(bval, ioport+DMA_Cmd);
  409             for(i=0; i<0x8000; i++)
  410             {
  411                 bval = inb(ioport+DMA_Status);
  412                 if(bval & BLAST_COMPLETE)
  413                     break;
  414             }
  415             bval = READ_DIRECTION+DMA_IDLE_CMD;
  416             OutB(bval, ioport+DMA_Cmd);
  417 
  418             ResidCnt = (ULONG) inb(ioport+CtcReg_High);
  419             ResidCnt = ResidCnt << 8;
  420             ResidCnt |= (ULONG) inb(ioport+CtcReg_Mid);
  421             ResidCnt = ResidCnt << 8;
  422             ResidCnt |= (ULONG) inb(ioport+CtcReg_Low);
  423 
  424             xferCnt = pSRB->SGToBeXferLen - ResidCnt;
  425             pSRB->SGPhysAddr += xferCnt;
  426             pSRB->TotalXferredLen += xferCnt;
  427             pSRB->SGToBeXferLen = ResidCnt;
  428 
  429             if( residual )
  430             {
  431                 bval = inb(ioport+ScsiFifo);        /* get residual byte */
  432                 ptr = phystovirt( pSRB, xferCnt);
  433                 *ptr = bval;
  434                 pSRB->SGPhysAddr++;
  435                 pSRB->TotalXferredLen++;
  436                 pSRB->SGToBeXferLen--;
  437             }
  438         }
  439     }
  440 }
  441 
  442 static void
  443 DC390_Command_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  444 {
  445 }
  446 
  447 static void
  448 DC390_Status_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  449 {
  450     UCHAR  bval;
  451     USHORT ioport;
  452 
  453     ioport = pACB->IOPortBase;
  454     bval = inb(ioport+ScsiFifo);
  455     pSRB->TargetStatus = bval;
  456     bval++;
  457     bval = inb(ioport+ScsiFifo);        /* get message */
  458     pSRB->EndMessage = bval;
  459 
  460     *psstatus = SCSI_NOP0;
  461     pSRB->SRBState = SRB_COMPLETED;
  462     bval = MSG_ACCEPTED_CMD;
  463     OutB(bval, ioport+ScsiCmd);
  464 }
  465 
  466 static void
  467 DC390_MsgOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  468 {
  469     if( pSRB->SRBState & (SRB_UNEXPECT_RESEL+SRB_ABORT_SENT) )
  470         *psstatus = SCSI_NOP0;
  471 }
  472 
  473 static void
  474 DC390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  475 {
  476     UCHAR  bval;
  477     USHORT ioport, wval, wval1;
  478     PDCB   pDCB;
  479     PSRB   psrb;
  480 
  481     ioport = pACB->IOPortBase;
  482     pDCB = pACB->pActiveDCB;
  483 
  484     bval = inb( ioport+ScsiFifo );
  485     if( !(pSRB->SRBState & SRB_MSGIN_MULTI) )
  486     {
  487         if(bval == MSG_DISCONNECT)
  488         {
  489             pSRB->SRBState = SRB_DISCONNECT;
  490         }
  491         else if( bval == MSG_SAVE_PTR )
  492             goto  min6;
  493         else if( (bval == MSG_EXTENDED) || ((bval >= MSG_SIMPLE_QTAG) &&
  494                                             (bval <= MSG_ORDER_QTAG)) )
  495         {
  496             pSRB->SRBState |= SRB_MSGIN_MULTI;
  497             pSRB->MsgInBuf[0] = bval;
  498             pSRB->MsgCnt = 1;
  499             pSRB->pMsgPtr = &pSRB->MsgInBuf[1];
  500         }
  501         else if(bval == MSG_REJECT_)
  502         {
  503             bval = RESET_ATN_CMD;
  504             OutB(bval, ioport+ScsiCmd);
  505             if( pSRB->SRBState & DO_SYNC_NEGO)
  506                 goto  set_async;
  507         }
  508         else if( bval == MSG_RESTORE_PTR)
  509             goto  min6;
  510         else
  511             goto  min6;
  512     }
  513     else
  514     {   /* minx: */
  515 
  516         *pSRB->pMsgPtr = bval;
  517         pSRB->MsgCnt++;
  518         pSRB->pMsgPtr++;
  519         if( (pSRB->MsgInBuf[0] >= MSG_SIMPLE_QTAG) &&
  520             (pSRB->MsgInBuf[0] <= MSG_ORDER_QTAG) )
  521         {
  522             if( pSRB->MsgCnt == 2)
  523             {
  524                 pSRB->SRBState = 0;
  525                 bval = pSRB->MsgInBuf[1];
  526                 pSRB = pDCB->pGoingSRB;
  527                 psrb = pDCB->pGoingLast;
  528                 if( pSRB )
  529                 {
  530                     for( ;; )
  531                     {
  532                         if(pSRB->TagNumber != bval)
  533                         {
  534                             if( pSRB == psrb )
  535                                 goto  mingx0;
  536                             pSRB = pSRB->pNextSRB;
  537                         }
  538                         else
  539                             break;
  540                     }
  541                     if( pDCB->DCBFlag & ABORT_DEV_ )
  542                     {
  543                         pSRB->SRBState = SRB_ABORT_SENT;
  544                         EnableMsgOut( pACB, pSRB );
  545                     }
  546                     if( !(pSRB->SRBState & SRB_DISCONNECT) )
  547                         goto  mingx0;
  548                     pDCB->pActiveSRB = pSRB;
  549                     pSRB->SRBState = SRB_DATA_XFER;
  550                 }
  551                 else
  552                 {
  553 mingx0:
  554                     pSRB = pACB->pTmpSRB;
  555                     pSRB->SRBState = SRB_UNEXPECT_RESEL;
  556                     pDCB->pActiveSRB = pSRB;
  557                     pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;
  558                     EnableMsgOut2( pACB, pSRB );
  559                 }
  560             }
  561         }
  562         else if( (pSRB->MsgInBuf[0] == MSG_EXTENDED) && (pSRB->MsgCnt == 5) )
  563         {
  564             pSRB->SRBState &= ~(SRB_MSGIN_MULTI+DO_SYNC_NEGO);
  565             if( (pSRB->MsgInBuf[1] != 3) || (pSRB->MsgInBuf[2] != 1) )
  566             {   /* reject_msg: */
  567                 pSRB->MsgCnt = 1;
  568                 pSRB->MsgInBuf[0] = MSG_REJECT_;
  569                 bval = SET_ATN_CMD;
  570                 OutB(bval, ioport+ScsiCmd);
  571             }
  572             else if( !(pSRB->MsgInBuf[3]) || !(pSRB->MsgInBuf[4]) )
  573             {
  574 set_async:
  575                 pDCB = pSRB->pSRBDCB;
  576                 pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE);
  577                 pDCB->SyncPeriod = 0;
  578                 pDCB->SyncOffset = 0;
  579                 pDCB->CtrlR3 = FAST_CLK;     /* ;non_fast */
  580                 pDCB->CtrlR4 &= 0x3f;
  581                 pDCB->CtrlR4 |= EATER_25NS;  /* ; 25ns glitch eater */
  582                 goto  re_prog;
  583             }
  584             else
  585             {   /* set_sync: */
  586 
  587                 pDCB = pSRB->pSRBDCB;
  588                 pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE;
  589                 pDCB->SyncOffset &= 0x0f0;
  590                 pDCB->SyncOffset |= pSRB->MsgInBuf[4];
  591                 pDCB->NegoPeriod = pSRB->MsgInBuf[3];
  592                 wval = (USHORT) pSRB->MsgInBuf[3];
  593                 wval = wval << 2;
  594                 wval--;
  595                 wval1 = wval / 25;
  596                 if( (wval1 * 25) != wval)
  597                     wval1++;
  598                 bval = FAST_CLK+FAST_SCSI;
  599                 pDCB->CtrlR4 &= 0x3f;
  600                 if(wval1 >= 8)
  601                 {
  602                     wval1--;
  603                     bval = FAST_CLK;        /* ;fast clock/normal scsi */
  604                     pDCB->CtrlR4 |= EATER_25NS;   /* ;25 ns glitch eater */
  605                 }
  606                 pDCB->CtrlR3 = bval;
  607                 pDCB->SyncPeriod = (UCHAR)wval1;
  608 re_prog:
  609                 bval = pDCB->SyncPeriod;
  610                 OutB(bval, ioport+Sync_Period);
  611                 bval = pDCB->SyncOffset;
  612                 OutB(bval, ioport+Sync_Offset);
  613                 bval = pDCB->CtrlR3;
  614                 OutB(bval, ioport+CtrlReg3);
  615                 bval = pDCB->CtrlR4;
  616                 OutB(bval, ioport+CtrlReg4);
  617                 SetXferRate( pACB, pDCB);
  618             }
  619         }
  620     }
  621 min6:
  622     *psstatus = SCSI_NOP0;
  623     bval = MSG_ACCEPTED_CMD;
  624     OutB(bval, ioport+ScsiCmd);
  625 }
  626 
  627 static void
  628 DataIO_Comm( PACB pACB, PSRB pSRB, UCHAR ioDir)
  629 {
  630     PSEG   psgl;
  631     UCHAR  bval;
  632     USHORT ioport;
  633     ULONG  lval;
  634 
  635 
  636     ioport = pACB->IOPortBase;
  637     if( pSRB->SGIndex < pSRB->SGcount )
  638     {
  639         bval = DMA_IDLE_CMD | ioDir;   /* ;+EN_DMA_INT */
  640         OutB( bval, ioport+DMA_Cmd);
  641         if( !pSRB->SGToBeXferLen )
  642         {
  643             psgl = pSRB->pSegmentList;
  644             pSRB->SGPhysAddr = psgl->SGXPtr;
  645             pSRB->SGToBeXferLen = psgl->SGXLen;
  646         }
  647         lval = pSRB->SGToBeXferLen;
  648         bval = (UCHAR) lval;
  649         OutB(bval,ioport+CtcReg_Low);
  650         lval = lval >> 8;
  651         bval = (UCHAR) lval;
  652         OutB(bval,ioport+CtcReg_Mid);
  653         lval = lval >> 8;
  654         bval = (UCHAR) lval;
  655         OutB(bval,ioport+CtcReg_High);
  656 
  657         lval = pSRB->SGToBeXferLen;
  658         OutL(lval, ioport+DMA_XferCnt);
  659 
  660         lval = pSRB->SGPhysAddr;
  661         OutL( lval, ioport+DMA_XferAddr);
  662 
  663         pSRB->SRBState = SRB_DATA_XFER;
  664 
  665         bval = DMA_COMMAND+INFO_XFER_CMD;
  666         OutB(bval, ioport+ScsiCmd);
  667 
  668         bval = DMA_IDLE_CMD | ioDir;    /* ;+EN_DMA_INT */
  669         OutB(bval, ioport+DMA_Cmd);
  670 
  671         bval = DMA_START_CMD | ioDir;   /* ;+EN_DMA_INT */
  672         OutB(bval, ioport+DMA_Cmd);
  673     }
  674     else    /* xfer pad */
  675     {
  676         if( pSRB->SGcount )
  677         {
  678             pSRB->AdaptStatus = H_OVER_UNDER_RUN;
  679             pSRB->SRBStatus |= OVER_RUN;
  680         }
  681         bval = 0;
  682         OutB(bval,ioport+CtcReg_Low);
  683         OutB(bval,ioport+CtcReg_Mid);
  684         OutB(bval,ioport+CtcReg_High);
  685 
  686         pSRB->SRBState |= SRB_XFERPAD;
  687         bval = DMA_COMMAND+XFER_PAD_BYTE;
  688         OutB(bval, ioport+ScsiCmd);
  689 /*
  690         bval = DMA_IDLE_CMD | ioDir;    ;+EN_DMA_INT
  691         OutB(bval, ioport+DMA_Cmd);
  692         bval = DMA_START_CMD | ioDir;   ;+EN_DMA_INT
  693         OutB(bval, ioport+DMA_Cmd);
  694 */
  695     }
  696 }
  697 
  698 
  699 static void
  700 DC390_DataOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  701 {
  702     UCHAR  ioDir;
  703 
  704     ioDir = WRITE_DIRECTION;
  705     DataIO_Comm( pACB, pSRB, ioDir);
  706 }
  707 
  708 static void
  709 DC390_DataInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  710 {
  711     UCHAR  ioDir;
  712 
  713     ioDir = READ_DIRECTION;
  714     DataIO_Comm( pACB, pSRB, ioDir);
  715 }
  716 
  717 static void
  718 DC390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  719 {
  720     PDCB   pDCB;
  721     UCHAR  bval;
  722     PUCHAR ptr;
  723     USHORT ioport, i,  cnt;
  724 
  725 
  726     ioport = pACB->IOPortBase;
  727     bval = RESET_ATN_CMD;
  728     OutB(bval, ioport+ScsiCmd);
  729     bval = CLEAR_FIFO_CMD;
  730     OutB(bval, ioport+ScsiCmd);
  731     if( !(pSRB->SRBFlag & AUTO_REQSENSE) )
  732     {
  733         cnt = (USHORT) pSRB->ScsiCmdLen;
  734         ptr = (PUCHAR) pSRB->CmdBlock;
  735         for(i=0; i < cnt; i++)
  736         {
  737             OutB(*ptr, ioport+ScsiFifo);
  738             ptr++;
  739         }
  740     }
  741     else
  742     {
  743         bval = REQUEST_SENSE;
  744         OutB(bval, ioport+ScsiFifo);
  745         pDCB = pACB->pActiveDCB;
  746         bval = pDCB->IdentifyMsg << 5;
  747         OutB(bval, ioport+ScsiFifo);
  748         bval = 0;
  749         OutB(bval, ioport+ScsiFifo);
  750         OutB(bval, ioport+ScsiFifo);
  751         bval = sizeof(struct scsi_sense_data);
  752         OutB(bval, ioport+ScsiFifo);
  753         bval = 0;
  754         OutB(bval, ioport+ScsiFifo);
  755     }
  756     pSRB->SRBState = SRB_COMMAND;
  757     bval = INFO_XFER_CMD;
  758     OutB(bval, ioport+ScsiCmd);
  759 }
  760 
  761 static void
  762 DC390_StatusPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  763 {
  764     UCHAR  bval;
  765     USHORT ioport;
  766 
  767     ioport = pACB->IOPortBase;
  768     bval = CLEAR_FIFO_CMD;
  769     OutB(bval, ioport+ScsiCmd);
  770     pSRB->SRBState = SRB_STATUS;
  771     bval = INITIATOR_CMD_CMPLTE;
  772     OutB(bval, ioport+ScsiCmd);
  773 }
  774 
  775 static void
  776 DC390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  777 {
  778     UCHAR   bval;
  779     USHORT  ioport, i, cnt;
  780     PUCHAR  ptr;
  781     PDCB    pDCB;
  782 
  783     ioport = pACB->IOPortBase;
  784     bval = CLEAR_FIFO_CMD;
  785     OutB(bval, ioport+ScsiCmd);
  786     pDCB = pACB->pActiveDCB;
  787     if( !(pSRB->SRBState & SRB_MSGOUT) )
  788     {
  789         cnt = pSRB->MsgCnt;
  790         if( cnt )
  791         {
  792             ptr = (PUCHAR) pSRB->MsgOutBuf;
  793             for(i=0; i < cnt; i++)
  794             {
  795                 OutB(*ptr, ioport+ScsiFifo);
  796                 ptr++;
  797             }
  798             pSRB->MsgCnt = 0;
  799             if( (pDCB->DCBFlag & ABORT_DEV_) &&
  800                 (pSRB->MsgOutBuf[0] == MSG_ABORT) )
  801                 pSRB->SRBState = SRB_ABORT_SENT;
  802         }
  803         else
  804         {
  805             bval = MSG_ABORT;   /* ??? MSG_NOP */
  806             if( (pSRB->CmdBlock[0] == INQUIRY ) ||
  807                 (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
  808                 (pSRB->SRBFlag & AUTO_REQSENSE) )
  809             {
  810                 if( pDCB->SyncMode & SYNC_ENABLE )
  811                     goto  mop1;
  812             }
  813             OutB(bval, ioport+ScsiFifo);
  814         }
  815         bval = INFO_XFER_CMD;
  816         OutB( bval, ioport+ScsiCmd);
  817     }
  818     else
  819     {
  820 mop1:
  821         bval = MSG_EXTENDED;
  822         OutB(bval, ioport+ScsiFifo);
  823         bval = 3;       /*    ;length of extended msg */
  824         OutB(bval, ioport+ScsiFifo);
  825         bval = 1;       /*    ; sync nego */
  826         OutB(bval, ioport+ScsiFifo);
  827         bval = pDCB->NegoPeriod;
  828         OutB(bval, ioport+ScsiFifo);
  829         bval = SYNC_NEGO_OFFSET;
  830         OutB(bval, ioport+ScsiFifo);
  831         pSRB->SRBState |= DO_SYNC_NEGO;
  832         bval = INFO_XFER_CMD;
  833         OutB(bval, ioport+ScsiCmd);
  834     }
  835 }
  836 
  837 static void
  838 DC390_MsgInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  839 {
  840     UCHAR  bval;
  841     USHORT ioport;
  842 
  843     ioport = pACB->IOPortBase;
  844     bval = CLEAR_FIFO_CMD;
  845     OutB(bval, ioport+ScsiCmd);
  846     if( !(pSRB->SRBState & SRB_MSGIN) )
  847     {
  848         pSRB->SRBState &= SRB_DISCONNECT;
  849         pSRB->SRBState |= SRB_MSGIN;
  850     }
  851     bval = INFO_XFER_CMD;
  852     OutB(bval, ioport+ScsiCmd);
  853 }
  854 
  855 static void
  856 DC390_Nop_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  857 {
  858 }
  859 
  860 static void
  861 DC390_Nop_1( PACB pACB, PSRB pSRB, PUCHAR psstatus)
  862 {
  863 }
  864 
  865 
  866 static void
  867 SetXferRate( PACB pACB, PDCB pDCB )
  868 {
  869     UCHAR  bval;
  870     USHORT cnt, i;
  871     PDCB   ptr;
  872 
  873     if( !(pDCB->IdentifyMsg & 0x07) )
  874     {
  875         if( pACB->scan_devices )
  876         {
  877             CurrSyncOffset = pDCB->SyncOffset;
  878         }
  879         else
  880         {
  881             ptr = pACB->pLinkDCB;
  882             cnt = pACB->DeviceCnt;
  883             bval = pDCB->UnitSCSIID;
  884             for(i=0; i<cnt; i++)
  885             {
  886                 if( ptr->UnitSCSIID == bval )
  887                 {
  888                     ptr->SyncPeriod = pDCB->SyncPeriod;
  889                     ptr->SyncOffset = pDCB->SyncOffset;
  890                     ptr->CtrlR3 = pDCB->CtrlR3;
  891                     ptr->CtrlR4 = pDCB->CtrlR4;
  892                     ptr->SyncMode = pDCB->SyncMode;
  893                 }
  894                 ptr = ptr->pNextDCB;
  895             }
  896         }
  897     }
  898     return;
  899 }
  900 
  901 
  902 static void
  903 DC390_Disconnect( PACB pACB )
  904 {
  905     PDCB   pDCB;
  906     PSRB   pSRB, psrb;
  907     int    flags;
  908     USHORT ioport, i, cnt;
  909     UCHAR  bval;
  910 
  911 #ifdef DC390_DEBUG0
  912     printf("DISC,");
  913 #endif
  914 
  915     flags = splbio();
  916     ioport = pACB->IOPortBase;
  917     pDCB = pACB->pActiveDCB;
  918     pSRB = pDCB->pActiveSRB;
  919     pACB->pActiveDCB = 0;
  920     pSRB->ScsiPhase = SCSI_NOP0;
  921     bval = EN_SEL_RESEL;
  922     OutB(bval, ioport+ScsiCmd);
  923     if( pSRB->SRBState & SRB_UNEXPECT_RESEL )
  924     {
  925         pSRB->SRBState = 0;
  926         DoWaitingSRB( pACB );
  927     }
  928     else if( pSRB->SRBState & SRB_ABORT_SENT )
  929     {
  930         pDCB->TagMask = 0;
  931         pDCB->DCBFlag = 0;
  932         cnt = pDCB->GoingSRBCnt;
  933         pDCB->GoingSRBCnt = 0;
  934         pSRB = pDCB->pGoingSRB;
  935         for( i=0; i < cnt; i++)
  936         {
  937             psrb = pSRB->pNextSRB;
  938             pSRB->pNextSRB = pACB->pFreeSRB;
  939             pACB->pFreeSRB = pSRB;
  940             pSRB = psrb;
  941         }
  942         pDCB->pGoingSRB = 0;
  943         DoWaitingSRB( pACB );
  944     }
  945     else
  946     {
  947         if( (pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) ||
  948            !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED)) )
  949         {       /* Selection time out */
  950             if( !(pACB->scan_devices) )
  951             {
  952                 pSRB->SRBState = SRB_READY;
  953                 RewaitSRB( pDCB, pSRB);
  954             }
  955             else
  956             {
  957                 pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT;
  958                 goto  disc1;
  959             }
  960         }
  961         else if( pSRB->SRBState & SRB_DISCONNECT )
  962         {
  963             DoWaitingSRB( pACB );
  964         }
  965         else if( pSRB->SRBState & SRB_COMPLETED )
  966         {
  967 disc1:
  968             if(pDCB->MaxCommand > 1)
  969             {
  970                bval = pSRB->TagNumber;
  971                pDCB->TagMask &= (~(1 << bval));   /* free tag mask */
  972             }
  973             pDCB->pActiveSRB = 0;
  974             pSRB->SRBState = SRB_FREE;
  975             SRBdone( pACB, pDCB, pSRB);
  976         }
  977     }
  978     splx(flags);
  979     return;
  980 }
  981 
  982 
  983 static void
  984 DC390_Reselect( PACB pACB )
  985 {
  986     PDCB   pDCB;
  987     PSRB   pSRB;
  988     USHORT ioport, wval;
  989     UCHAR  bval, bval1;
  990 
  991 
  992 #ifdef DC390_DEBUG0
  993     printf("RSEL,");
  994 #endif
  995     ioport = pACB->IOPortBase;
  996     pDCB = pACB->pActiveDCB;
  997     if( pDCB )
  998     {   /* Arbitration lost but Reselection win */
  999         pSRB = pDCB->pActiveSRB;
 1000         if( !( pACB->scan_devices ) )
 1001         {
 1002             pSRB->SRBState = SRB_READY;
 1003             RewaitSRB( pDCB, pSRB);
 1004         }
 1005     }
 1006     bval = inb(ioport+ScsiFifo);        /* get ID */
 1007     bval = bval ^ pACB->HostID_Bit;
 1008     wval = 0;
 1009     bval1 = 1;
 1010     for(;;)
 1011     {
 1012         if( !(bval & bval1) )
 1013         {
 1014             bval1 = bval1 << 1;
 1015             wval++;
 1016         }
 1017         else
 1018             break;
 1019     }
 1020     wval |=  ( (USHORT) inb(ioport+ScsiFifo) & 7) << 8;  /* get LUN */
 1021     pDCB = pACB->pLinkDCB;
 1022     while( wval != *((PUSHORT) &pDCB->UnitSCSIID) )
 1023         pDCB = pDCB->pNextDCB;
 1024     pACB->pActiveDCB = pDCB;
 1025     if( pDCB->SyncMode & EN_TAG_QUEUING )
 1026     {
 1027         pSRB = pACB->pTmpSRB;
 1028         pDCB->pActiveSRB = pSRB;
 1029     }
 1030     else
 1031     {
 1032         pSRB = pDCB->pActiveSRB;
 1033         if( !pSRB || !(pSRB->SRBState & SRB_DISCONNECT) )
 1034         {
 1035             pSRB= pACB->pTmpSRB;
 1036             pSRB->SRBState = SRB_UNEXPECT_RESEL;
 1037             pDCB->pActiveSRB = pSRB;
 1038             EnableMsgOut( pACB, pSRB );
 1039         }
 1040         else
 1041         {
 1042             if( pDCB->DCBFlag & ABORT_DEV_ )
 1043             {
 1044                 pSRB->SRBState = SRB_ABORT_SENT;
 1045                 EnableMsgOut( pACB, pSRB );
 1046             }
 1047             else
 1048                 pSRB->SRBState = SRB_DATA_XFER;
 1049         }
 1050     }
 1051     pSRB->ScsiPhase = SCSI_NOP0;
 1052     bval = pDCB->UnitSCSIID;
 1053     OutB( bval, ioport+Scsi_Dest_ID);
 1054     bval = pDCB->SyncPeriod;
 1055     OutB(bval, ioport+Sync_Period);
 1056     bval = pDCB->SyncOffset;
 1057     OutB( bval, ioport+Sync_Offset);
 1058     bval = pDCB->CtrlR1;
 1059     OutB(bval, ioport+CtrlReg1);
 1060     bval = pDCB->CtrlR3;
 1061     OutB(bval, ioport+CtrlReg3);
 1062     bval = pDCB->CtrlR4;        /* ; Glitch eater */
 1063     OutB(bval, ioport+CtrlReg4);
 1064     bval = MSG_ACCEPTED_CMD;    /* ;to rls the /ACK signal */
 1065     OutB(bval, ioport+ScsiCmd);
 1066 }
 1067 
 1068 
 1069 static void
 1070 SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
 1071 {
 1072     PSRB   psrb;
 1073     UCHAR  bval, bval1, i, j, status;
 1074     PSCSICMD pcmd;
 1075     PSCLINK  plink;
 1076     PSCSI_INQDATA  ptr;
 1077     USHORT disable_tag;
 1078     int    flags;
 1079     PSEG   ptr2;
 1080     ULONG  swlval;
 1081 
 1082     pcmd = pSRB->pcmd;
 1083     plink = pcmd->sc_link;
 1084     status = pSRB->TargetStatus;
 1085     if(pSRB->SRBFlag & AUTO_REQSENSE)
 1086     {
 1087         pSRB->SRBFlag &= ~AUTO_REQSENSE;
 1088         pSRB->AdaptStatus = 0;
 1089         pSRB->TargetStatus = SCSI_STAT_CHECKCOND;
 1090         if(status == SCSI_STAT_CHECKCOND)
 1091         {
 1092             pcmd->error = XS_TIMEOUT;
 1093             goto ckc_e;
 1094         }
 1095 
 1096         if(pSRB->RetryCnt == 0)
 1097         {
 1098             *((PULONG) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
 1099             pSRB->TotalXferredLen = pSRB->Segment1[1];
 1100             if( pSRB->TotalXferredLen )
 1101             {
 1102                 pcmd->resid = pcmd->datalen - pSRB->TotalXferredLen;
 1103                 pcmd->error = XS_SENSE;
 1104                 pcmd->flags |= SCSI_RESID_VALID;
 1105             }
 1106             else
 1107             {
 1108                 pcmd->error = XS_SENSE;
 1109                 pcmd->status = SCSI_STAT_CHECKCOND;
 1110             }
 1111             goto ckc_e;
 1112         }
 1113         else
 1114         {
 1115             pSRB->RetryCnt--;
 1116             pSRB->AdaptStatus = 0;
 1117             pSRB->TargetStatus = 0;
 1118             *((PULONG) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
 1119             *((PULONG) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1];
 1120             if( pSRB->CmdBlock[0] == TEST_UNIT_READY )
 1121             {
 1122                 pcmd->error = XS_SENSE;
 1123                 pcmd->status = SCSI_STAT_CHECKCOND;
 1124                 goto ckc_e;
 1125             }
 1126             pcmd->error = XS_SENSE;
 1127             pSRB->SGcount      = (UCHAR) pSRB->Segment1[0];
 1128             pSRB->ScsiCmdLen   = (UCHAR) (pSRB->Segment1[0] >> 8);
 1129             pSRB->pSegmentList = (PSEG) &pSRB->SGsegment[0];
 1130             pSRB->SGIndex = 0;
 1131             pSRB->TotalXferredLen = 0;
 1132             pSRB->SGToBeXferLen = 0;
 1133             if( DC390_StartSCSI( pACB, pDCB, pSRB ) )
 1134                 RewaitSRB( pDCB, pSRB );
 1135             return;
 1136         }
 1137     }
 1138     if( status )
 1139     {
 1140         if( status == SCSI_STAT_CHECKCOND)
 1141         {
 1142             if( (pSRB->SGIndex < pSRB->SGcount) && (pSRB->SGcount) && (pSRB->SGToBeXferLen) )
 1143             {
 1144                 bval = pSRB->SGcount;
 1145                 swlval = pSRB->SGToBeXferLen;
 1146                 ptr2 = pSRB->pSegmentList;
 1147                 ptr2++;
 1148                 for( i=pSRB->SGIndex+1; i < bval; i++)
 1149                 {
 1150                     swlval += ptr2->SGXLen;
 1151                     ptr2++;
 1152                 }
 1153 #ifdef  DC390_DEBUG0
 1154                 printf("XferredLen=%8x,NotXferLen=%8x,",
 1155                         (UINT) pSRB->TotalXferredLen, (UINT) swlval);
 1156 #endif
 1157             }
 1158             RequestSense( pACB, pDCB, pSRB );
 1159             return;
 1160         }
 1161         else if( status == SCSI_STAT_QUEUEFULL )
 1162         {
 1163             bval = (UCHAR) pDCB->GoingSRBCnt;
 1164             bval--;
 1165             pDCB->MaxCommand = bval;
 1166             RewaitSRB( pDCB, pSRB );
 1167             pSRB->AdaptStatus = 0;
 1168             pSRB->TargetStatus = 0;
 1169             return;
 1170         }
 1171         else if(status == SCSI_STAT_SEL_TIMEOUT)
 1172         {
 1173             pSRB->AdaptStatus = H_SEL_TIMEOUT;
 1174             pSRB->TargetStatus = 0;
 1175             pcmd->error = XS_TIMEOUT;
 1176         }
 1177         else if (status == SCSI_STAT_BUSY)
 1178         {
 1179 #ifdef DC390_DEBUG0
 1180                 printf("DC390: target busy at %s %d\n", __FILE__, __LINE__);
 1181 #endif
 1182                 pcmd->error = XS_BUSY;
 1183         }
 1184         else if (status == SCSI_STAT_RESCONFLICT)
 1185         {
 1186 #ifdef DC390_DEBUG0
 1187                 printf("DC390: target reserved at %s %d\n", __FILE__, __LINE__);
 1188 #endif
 1189                 pcmd->error = XS_BUSY;  /*XXX*/
 1190         }
 1191         else
 1192         {
 1193             pSRB->AdaptStatus = 0;
 1194             if( pSRB->RetryCnt )
 1195             {
 1196                 pSRB->RetryCnt--;
 1197                 pSRB->TargetStatus = 0;
 1198                 pSRB->SGIndex = 0;
 1199                 pSRB->TotalXferredLen = 0;
 1200                 pSRB->SGToBeXferLen = 0;
 1201                 pSRB->pSegmentList = (PSEG) &pSRB->SGsegment[0];
 1202                 if( DC390_StartSCSI( pACB, pDCB, pSRB ) )
 1203                     RewaitSRB( pDCB, pSRB );
 1204                 return;
 1205             }
 1206             else
 1207             {
 1208 #ifdef DC390_DEBUG0
 1209                 printf("DC390: driver stuffup at %s %d\n", __FILE__, __LINE__);
 1210 #endif
 1211                 pcmd->error = XS_DRIVER_STUFFUP;
 1212             }
 1213         }
 1214     }
 1215     else
 1216     {
 1217         status = pSRB->AdaptStatus;
 1218         if(status & H_OVER_UNDER_RUN)
 1219         {
 1220             pSRB->TargetStatus = 0;
 1221             pcmd->error = XS_LENGTH;
 1222         }
 1223         else if( pSRB->SRBStatus & PARITY_ERROR)
 1224         {
 1225 #ifdef DC390_DEBUG0
 1226             printf("DC390: driver stuffup %s %d\n", __FILE__, __LINE__);
 1227 #endif
 1228             pcmd->error = XS_DRIVER_STUFFUP;
 1229         }
 1230         else                   /* No error */
 1231         {
 1232             pSRB->AdaptStatus = 0;
 1233             pSRB->TargetStatus = 0;
 1234             pcmd->error = XS_NOERROR;
 1235         }
 1236     }
 1237 
 1238 ckc_e:
 1239     if( pACB->scan_devices )
 1240     {
 1241         if( pSRB->CmdBlock[0] == TEST_UNIT_READY )
 1242         {
 1243             if(pcmd->error == XS_TIMEOUT )
 1244             {
 1245                 pACB->DCBmap[plink->target] &= ~(1 << plink->lun);
 1246                 pPrevDCB->pNextDCB = pACB->pLinkDCB;
 1247             }
 1248             else
 1249             {
 1250                 pPrevDCB->pNextDCB = pDCB;
 1251                 pDCB->pNextDCB = pACB->pLinkDCB;
 1252             }
 1253         }
 1254         else if( pSRB->CmdBlock[0] == INQUIRY )
 1255         {
 1256             if( (plink->target == pACB->max_id) && (plink->lun == pACB->max_lun) )
 1257                 pACB->scan_devices = 0;
 1258             if(pcmd->error == XS_TIMEOUT )
 1259                 goto NO_DEV;
 1260             ptr = (PSCSI_INQDATA) (pcmd->data);
 1261             bval1 = ptr->DevType & SCSI_DEVTYPE;
 1262             if(bval1 == SCSI_NODEV)
 1263             {
 1264 NO_DEV:
 1265                 pACB->DCBmap[plink->target] &= ~(1 << plink->lun);
 1266                 pPrevDCB->pNextDCB = pACB->pLinkDCB;
 1267             }
 1268             else
 1269             {
 1270                 pACB->DeviceCnt++;
 1271                 pPrevDCB = pDCB;
 1272                 pACB->pDCB_free = (PDCB) ((uintptr_t) (pACB->pDCB_free) + sizeof( DC390_DCB ));
 1273                 pDCB->DevType = bval1;
 1274                 if(bval1 == SCSI_DASD || bval1 == SCSI_OPTICAL)
 1275                 {
 1276                     if( (((ptr->Vers & 0x07) >= 2) || ((ptr->RDF & 0x0F) == 2)) &&
 1277                         (ptr->Flags & SCSI_INQ_CMDQUEUE) &&
 1278                         (pDCB->DevMode & TAG_QUEUING_) &&
 1279                         (pDCB->DevMode & EN_DISCONNECT_) )
 1280                     {
 1281                         disable_tag = 0;
 1282                         for(i=0; i<BADDEVCNT; i++)
 1283                         {
 1284                             for(j=0; j<28; j++)
 1285                             {
 1286                                 if( ((PUCHAR)ptr)[8+j] != baddevname1[i][j])
 1287                                     break;
 1288                             }
 1289                             if(j == 28)
 1290                             {
 1291                                 disable_tag = 1;
 1292                                 break;
 1293                             }
 1294                         }
 1295 
 1296                         if( !disable_tag )
 1297                         {
 1298                             pDCB->MaxCommand = pACB->TagMaxNum;
 1299                             pDCB->SyncMode |= EN_TAG_QUEUING;
 1300                             pDCB->TagMask = 0;
 1301                         }
 1302                         else
 1303                         {
 1304                             pDCB->SyncMode |= EN_ATN_STOP;
 1305                         }
 1306                     }
 1307                 }
 1308             }
 1309         }
 1310     }
 1311 
 1312     flags = splbio();
 1313 /*  ReleaseSRB( pDCB, pSRB ); */
 1314 
 1315     if(pSRB == pDCB->pGoingSRB )
 1316     {
 1317         pDCB->pGoingSRB = pSRB->pNextSRB;
 1318     }
 1319     else
 1320     {
 1321         psrb = pDCB->pGoingSRB;
 1322         while( psrb->pNextSRB != pSRB )
 1323             psrb = psrb->pNextSRB;
 1324         psrb->pNextSRB = pSRB->pNextSRB;
 1325         if( pSRB == pDCB->pGoingLast )
 1326             pDCB->pGoingLast = psrb;
 1327     }
 1328     pSRB->pNextSRB = pACB->pFreeSRB;
 1329     pACB->pFreeSRB = pSRB;
 1330     pDCB->GoingSRBCnt--;
 1331 
 1332     DoWaitingSRB( pACB );
 1333     splx(flags);
 1334 
 1335     pcmd->flags |= ITSDONE;
 1336 
 1337 /*  Notify cmd done */
 1338     scsi_done( pcmd );
 1339 }
 1340 
 1341 
 1342 static void
 1343 DoingSRB_Done( PACB pACB )
 1344 {
 1345     PDCB  pDCB, pdcb;
 1346     PSRB  psrb, psrb2;
 1347     USHORT  cnt, i;
 1348     PSCSICMD pcmd;
 1349 
 1350     pDCB = pACB->pLinkDCB;
 1351     pdcb = pDCB;
 1352     do
 1353     {
 1354         cnt = pdcb->GoingSRBCnt;
 1355         psrb = pdcb->pGoingSRB;
 1356         for( i=0; i<cnt; i++)
 1357         {
 1358             psrb2 = psrb->pNextSRB;
 1359             pcmd = psrb->pcmd;
 1360             pcmd->error = XS_TIMEOUT;
 1361 
 1362 /*          ReleaseSRB( pDCB, pSRB ); */
 1363 
 1364             psrb->pNextSRB = pACB->pFreeSRB;
 1365             pACB->pFreeSRB = psrb;
 1366 
 1367             scsi_done( pcmd );
 1368             psrb  = psrb2;
 1369         }
 1370         pdcb->GoingSRBCnt = 0;;
 1371         pdcb->pGoingSRB = NULL;
 1372         pdcb->TagMask = 0;
 1373         pdcb = pdcb->pNextDCB;
 1374     }
 1375     while( pdcb != pDCB );
 1376 }
 1377 
 1378 
 1379 static void
 1380 DC390_ResetSCSIBus( PACB pACB )
 1381 {
 1382     USHORT ioport;
 1383     UCHAR  bval;
 1384     int    flags;
 1385 
 1386     flags = splbio();
 1387     pACB->ACBFlag |= RESET_DEV;
 1388     ioport = pACB->IOPortBase;
 1389 
 1390     bval = DMA_IDLE_CMD;
 1391     OutB(bval,ioport+DMA_Cmd);
 1392 
 1393     bval = RST_SCSI_BUS_CMD;
 1394     OutB(bval,ioport+ScsiCmd);
 1395 
 1396     splx(flags);
 1397     return;
 1398 }
 1399 
 1400 
 1401 static void
 1402 DC390_ScsiRstDetect( PACB pACB )
 1403 {
 1404     int    flags;
 1405     ULONG  wlval;
 1406     USHORT ioport;
 1407     UCHAR  bval;
 1408 
 1409 #ifdef DC390_DEBUG0
 1410     printf("RST_DETEC");
 1411 #endif
 1412     wlval = 1000;
 1413     while( --wlval )    /* delay 1 sec */
 1414     {
 1415         DELAY(1000);
 1416     }
 1417     flags = splbio();
 1418     ioport = pACB->IOPortBase;
 1419     bval = DMA_IDLE_CMD;
 1420     OutB(bval,ioport+DMA_Cmd);
 1421     bval = CLEAR_FIFO_CMD;
 1422     OutB(bval,ioport+ScsiCmd);
 1423 
 1424     if( pACB->ACBFlag & RESET_DEV )
 1425         pACB->ACBFlag |= RESET_DONE;
 1426     else
 1427     {
 1428         pACB->ACBFlag |= RESET_DETECT;
 1429 
 1430         ResetDevParam( pACB );
 1431 /*      DoingSRB_Done( pACB ); ???? */
 1432         RecoverSRB( pACB );
 1433         pACB->pActiveDCB = NULL;
 1434         pACB->ACBFlag = 0;
 1435         DoWaitingSRB( pACB );
 1436     }
 1437     splx(flags);
 1438     return;
 1439 }
 1440 
 1441 
 1442 static void
 1443 RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB )
 1444 {
 1445     PSCSICMD  pcmd;
 1446 
 1447     pSRB->SRBFlag |= AUTO_REQSENSE;
 1448     pSRB->Segment0[0] = *((PULONG) &(pSRB->CmdBlock[0]));
 1449     pSRB->Segment0[1] = *((PULONG) &(pSRB->CmdBlock[4]));
 1450     pSRB->Segment1[0] = (ULONG) ((pSRB->ScsiCmdLen << 8) + pSRB->SGcount);
 1451     pSRB->Segment1[1] = pSRB->TotalXferredLen;
 1452     pSRB->AdaptStatus = 0;
 1453     pSRB->TargetStatus = 0;
 1454 
 1455     pcmd = pSRB->pcmd;
 1456 
 1457     pSRB->Segmentx.SGXPtr = (ULONG) vtophys(&pcmd->sense);
 1458     pSRB->Segmentx.SGXLen = (ULONG) sizeof(struct scsi_sense_data);
 1459     pSRB->pSegmentList = &pSRB->Segmentx;
 1460     pSRB->SGcount = 1;
 1461     pSRB->SGIndex = 0;
 1462 
 1463     *((PULONG) &(pSRB->CmdBlock[0])) = 0x00000003;
 1464     pSRB->CmdBlock[1] = pDCB->IdentifyMsg << 5;
 1465     *((PUSHORT) &(pSRB->CmdBlock[4])) = sizeof(struct scsi_sense_data);
 1466     pSRB->ScsiCmdLen = 6;
 1467 
 1468     pSRB->TotalXferredLen = 0;
 1469     pSRB->SGToBeXferLen = 0;
 1470     if( DC390_StartSCSI( pACB, pDCB, pSRB ) )
 1471         RewaitSRB( pDCB, pSRB );
 1472 }
 1473 
 1474 
 1475 static void
 1476 EnableMsgOut2( PACB pACB, PSRB pSRB )
 1477 {
 1478     USHORT ioport;
 1479     UCHAR  bval;
 1480 
 1481     ioport = pACB->IOPortBase;
 1482     pSRB->MsgCnt = 1;
 1483     bval = SET_ATN_CMD;
 1484     OutB(bval, ioport+ScsiCmd);
 1485 }
 1486 
 1487 
 1488 static void
 1489 EnableMsgOut( PACB pACB, PSRB pSRB )
 1490 {
 1491     pSRB->MsgOutBuf[0] = MSG_ABORT;
 1492     EnableMsgOut2( pACB, pSRB );
 1493 }
 1494 
 1495 
 1496 static void
 1497 DC390_InvalidCmd( PACB pACB )
 1498 {
 1499    UCHAR bval;
 1500    USHORT ioport;
 1501    PSRB   pSRB;
 1502 
 1503     pSRB = pACB->pActiveDCB->pActiveSRB;
 1504     if( pSRB->SRBState & (SRB_START_+SRB_MSGOUT) )
 1505     {
 1506         ioport = pACB->IOPortBase;
 1507         bval = CLEAR_FIFO_CMD;
 1508         OutB(bval,(ioport+ScsiCmd));
 1509     }
 1510 }
 1511 

Cache object: 34b2c55a8782fd6765f0a4581db41e1a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.