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     if( !(pcmd->flags & SCSI_NOMASK) )
 1084         untimeout(DC390_timeout, (caddr_t) pSRB);
 1085     plink = pcmd->sc_link;
 1086     status = pSRB->TargetStatus;
 1087     if(pSRB->SRBFlag & AUTO_REQSENSE)
 1088     {
 1089         pSRB->SRBFlag &= ~AUTO_REQSENSE;
 1090         pSRB->AdaptStatus = 0;
 1091         pSRB->TargetStatus = SCSI_STAT_CHECKCOND;
 1092         if(status == SCSI_STAT_CHECKCOND)
 1093         {
 1094             pcmd->error = XS_TIMEOUT;
 1095             goto ckc_e;
 1096         }
 1097 
 1098         if(pSRB->RetryCnt == 0)
 1099         {
 1100             *((PULONG) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
 1101             pSRB->TotalXferredLen = pSRB->Segment1[1];
 1102             if( pSRB->TotalXferredLen )
 1103             {
 1104                 pcmd->resid = pcmd->datalen - pSRB->TotalXferredLen;
 1105                 pcmd->error = XS_SENSE;
 1106                 pcmd->flags |= SCSI_RESID_VALID;
 1107             }
 1108             else
 1109             {
 1110                 pcmd->error = XS_SENSE;
 1111                 pcmd->status = SCSI_STAT_CHECKCOND;
 1112             }
 1113             goto ckc_e;
 1114         }
 1115         else
 1116         {
 1117             pSRB->RetryCnt--;
 1118             pSRB->AdaptStatus = 0;
 1119             pSRB->TargetStatus = 0;
 1120             *((PULONG) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
 1121             *((PULONG) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1];
 1122             if( pSRB->CmdBlock[0] == TEST_UNIT_READY )
 1123             {
 1124                 pcmd->error = XS_SENSE;
 1125                 pcmd->status = SCSI_STAT_CHECKCOND;
 1126                 goto ckc_e;
 1127             }
 1128             pcmd->error = XS_SENSE;
 1129             pSRB->SGcount      = (UCHAR) pSRB->Segment1[0];
 1130             pSRB->ScsiCmdLen   = (UCHAR) (pSRB->Segment1[0] >> 8);
 1131             pSRB->pSegmentList = (PSEG) &pSRB->SGsegment[0];
 1132             pSRB->SGIndex = 0;
 1133             pSRB->TotalXferredLen = 0;
 1134             pSRB->SGToBeXferLen = 0;
 1135             if( DC390_StartSCSI( pACB, pDCB, pSRB ) )
 1136                 RewaitSRB( pDCB, pSRB );
 1137             return;
 1138         }
 1139     }
 1140     if( status )
 1141     {
 1142         if( status == SCSI_STAT_CHECKCOND)
 1143         {
 1144             if( (pSRB->SGIndex < pSRB->SGcount) && (pSRB->SGcount) && (pSRB->SGToBeXferLen) )
 1145             {
 1146                 bval = pSRB->SGcount;
 1147                 swlval = pSRB->SGToBeXferLen;
 1148                 ptr2 = pSRB->pSegmentList;
 1149                 ptr2++;
 1150                 for( i=pSRB->SGIndex+1; i < bval; i++)
 1151                 {
 1152                     swlval += ptr2->SGXLen;
 1153                     ptr2++;
 1154                 }
 1155 #ifdef  DC390_DEBUG0
 1156                 printf("XferredLen=%8x,NotXferLen=%8x,",
 1157                         (UINT) pSRB->TotalXferredLen, (UINT) swlval);
 1158 #endif
 1159             }
 1160             RequestSense( pACB, pDCB, pSRB );
 1161             return;
 1162         }
 1163         else if( status == SCSI_STAT_QUEUEFULL )
 1164         {
 1165             bval = (UCHAR) pDCB->GoingSRBCnt;
 1166             bval--;
 1167             pDCB->MaxCommand = bval;
 1168             RewaitSRB( pDCB, pSRB );
 1169             pSRB->AdaptStatus = 0;
 1170             pSRB->TargetStatus = 0;
 1171             return;
 1172         }
 1173         else if(status == SCSI_STAT_SEL_TIMEOUT)
 1174         {
 1175             pSRB->AdaptStatus = H_SEL_TIMEOUT;
 1176             pSRB->TargetStatus = 0;
 1177             pcmd->error = XS_TIMEOUT;
 1178         }
 1179         else if (status == SCSI_STAT_BUSY)
 1180         {
 1181 #ifdef DC390_DEBUG0
 1182                 printf("DC390: target busy at %s %d\n", __FILE__, __LINE__);
 1183 #endif
 1184                 pcmd->error = XS_BUSY;
 1185         }
 1186         else if (status == SCSI_STAT_RESCONFLICT)
 1187         {
 1188 #ifdef DC390_DEBUG0
 1189                 printf("DC390: target reserved at %s %d\n", __FILE__, __LINE__);
 1190 #endif
 1191                 pcmd->error = XS_BUSY;  /*XXX*/
 1192         }
 1193         else
 1194         {
 1195             pSRB->AdaptStatus = 0;
 1196             if( pSRB->RetryCnt )
 1197             {
 1198                 pSRB->RetryCnt--;
 1199                 pSRB->TargetStatus = 0;
 1200                 pSRB->SGIndex = 0;
 1201                 pSRB->TotalXferredLen = 0;
 1202                 pSRB->SGToBeXferLen = 0;
 1203                 pSRB->pSegmentList = (PSEG) &pSRB->SGsegment[0];
 1204                 if( DC390_StartSCSI( pACB, pDCB, pSRB ) )
 1205                     RewaitSRB( pDCB, pSRB );
 1206                 return;
 1207             }
 1208             else
 1209             {
 1210 #ifdef DC390_DEBUG0
 1211                 printf("DC390: driver stuffup at %s %d\n", __FILE__, __LINE__);
 1212 #endif
 1213                 pcmd->error = XS_DRIVER_STUFFUP;
 1214             }
 1215         }
 1216     }
 1217     else
 1218     {
 1219         status = pSRB->AdaptStatus;
 1220         if(status & H_OVER_UNDER_RUN)
 1221         {
 1222             pSRB->TargetStatus = 0;
 1223             pcmd->error = XS_LENGTH;
 1224         }
 1225         else if( pSRB->SRBStatus & PARITY_ERROR)
 1226         {
 1227 #ifdef DC390_DEBUG0
 1228             printf("DC390: driver stuffup %s %d\n", __FILE__, __LINE__);
 1229 #endif
 1230             pcmd->error = XS_DRIVER_STUFFUP;
 1231         }
 1232         else                   /* No error */
 1233         {
 1234             pSRB->AdaptStatus = 0;
 1235             pSRB->TargetStatus = 0;
 1236             pcmd->error = XS_NOERROR;
 1237         }
 1238     }
 1239 
 1240 ckc_e:
 1241     if( pACB->scan_devices )
 1242     {
 1243         if( pSRB->CmdBlock[0] == TEST_UNIT_READY )
 1244         {
 1245             if(pcmd->error == XS_TIMEOUT )
 1246             {
 1247                 pACB->DCBmap[plink->target] &= ~(1 << plink->lun);
 1248                 pPrevDCB->pNextDCB = pACB->pLinkDCB;
 1249             }
 1250             else
 1251             {
 1252                 pPrevDCB->pNextDCB = pDCB;
 1253                 pDCB->pNextDCB = pACB->pLinkDCB;
 1254             }
 1255         }
 1256         else if( pSRB->CmdBlock[0] == INQUIRY )
 1257         {
 1258             if( (plink->target == pACB->max_id) && (plink->lun == pACB->max_lun) )
 1259                 pACB->scan_devices = 0;
 1260             if(pcmd->error == XS_TIMEOUT )
 1261                 goto NO_DEV;
 1262             ptr = (PSCSI_INQDATA) (pcmd->data);
 1263             bval1 = ptr->DevType & SCSI_DEVTYPE;
 1264             if(bval1 == SCSI_NODEV)
 1265             {
 1266 NO_DEV:
 1267                 pACB->DCBmap[plink->target] &= ~(1 << plink->lun);
 1268                 pPrevDCB->pNextDCB = pACB->pLinkDCB;
 1269             }
 1270             else
 1271             {
 1272                 pACB->DeviceCnt++;
 1273                 pPrevDCB = pDCB;
 1274                 pACB->pDCB_free = (PDCB) ((ULONG) (pACB->pDCB_free) + sizeof( DC390_DCB ));
 1275                 pDCB->DevType = bval1;
 1276                 if(bval1 == SCSI_DASD || bval1 == SCSI_OPTICAL)
 1277                 {
 1278                     if( (((ptr->Vers & 0x07) >= 2) || ((ptr->RDF & 0x0F) == 2)) &&
 1279                         (ptr->Flags & SCSI_INQ_CMDQUEUE) &&
 1280                         (pDCB->DevMode & TAG_QUEUING_) &&
 1281                         (pDCB->DevMode & EN_DISCONNECT_) )
 1282                     {
 1283                         disable_tag = 0;
 1284                         for(i=0; i<BADDEVCNT; i++)
 1285                         {
 1286                             for(j=0; j<28; j++)
 1287                             {
 1288                                 if( ((PUCHAR)ptr)[8+j] != baddevname1[i][j])
 1289                                     break;
 1290                             }
 1291                             if(j == 28)
 1292                             {
 1293                                 disable_tag = 1;
 1294                                 break;
 1295                             }
 1296                         }
 1297 
 1298                         if( !disable_tag )
 1299                         {
 1300                             pDCB->MaxCommand = pACB->TagMaxNum;
 1301                             pDCB->SyncMode |= EN_TAG_QUEUING;
 1302                             pDCB->TagMask = 0;
 1303                         }
 1304                         else
 1305                         {
 1306                             pDCB->SyncMode |= EN_ATN_STOP;
 1307                         }
 1308                     }
 1309                 }
 1310             }
 1311         }
 1312     }
 1313 
 1314     flags = splbio();
 1315 /*  ReleaseSRB( pDCB, pSRB ); */
 1316 
 1317     if(pSRB == pDCB->pGoingSRB )
 1318     {
 1319         pDCB->pGoingSRB = pSRB->pNextSRB;
 1320     }
 1321     else
 1322     {
 1323         psrb = pDCB->pGoingSRB;
 1324         while( psrb->pNextSRB != pSRB )
 1325             psrb = psrb->pNextSRB;
 1326         psrb->pNextSRB = pSRB->pNextSRB;
 1327         if( pSRB == pDCB->pGoingLast )
 1328             pDCB->pGoingLast = psrb;
 1329     }
 1330     pSRB->pNextSRB = pACB->pFreeSRB;
 1331     pACB->pFreeSRB = pSRB;
 1332     pDCB->GoingSRBCnt--;
 1333 
 1334     DoWaitingSRB( pACB );
 1335     splx(flags);
 1336 
 1337     pcmd->flags |= ITSDONE;
 1338 
 1339 /*  Notify cmd done */
 1340     scsi_done( pcmd );
 1341 }
 1342 
 1343 
 1344 static void
 1345 DoingSRB_Done( PACB pACB )
 1346 {
 1347     PDCB  pDCB, pdcb;
 1348     PSRB  psrb, psrb2;
 1349     USHORT  cnt, i;
 1350     PSCSICMD pcmd;
 1351 
 1352     pDCB = pACB->pLinkDCB;
 1353     pdcb = pDCB;
 1354     do
 1355     {
 1356         cnt = pdcb->GoingSRBCnt;
 1357         psrb = pdcb->pGoingSRB;
 1358         for( i=0; i<cnt; i++)
 1359         {
 1360             psrb2 = psrb->pNextSRB;
 1361             pcmd = psrb->pcmd;
 1362             pcmd->error = XS_TIMEOUT;
 1363 
 1364 /*          ReleaseSRB( pDCB, pSRB ); */
 1365 
 1366             psrb->pNextSRB = pACB->pFreeSRB;
 1367             pACB->pFreeSRB = psrb;
 1368 
 1369             scsi_done( pcmd );
 1370             psrb  = psrb2;
 1371         }
 1372         pdcb->GoingSRBCnt = 0;;
 1373         pdcb->pGoingSRB = NULL;
 1374         pdcb->TagMask = 0;
 1375         pdcb = pdcb->pNextDCB;
 1376     }
 1377     while( pdcb != pDCB );
 1378 }
 1379 
 1380 
 1381 static void
 1382 DC390_ResetSCSIBus( PACB pACB )
 1383 {
 1384     USHORT ioport;
 1385     UCHAR  bval;
 1386     int    flags;
 1387 
 1388     flags = splbio();
 1389     pACB->ACBFlag |= RESET_DEV;
 1390     ioport = pACB->IOPortBase;
 1391 
 1392     bval = DMA_IDLE_CMD;
 1393     OutB(bval,ioport+DMA_Cmd);
 1394 
 1395     bval = RST_SCSI_BUS_CMD;
 1396     OutB(bval,ioport+ScsiCmd);
 1397 
 1398     splx(flags);
 1399     return;
 1400 }
 1401 
 1402 
 1403 static void
 1404 DC390_ScsiRstDetect( PACB pACB )
 1405 {
 1406     int    flags;
 1407     ULONG  wlval;
 1408     USHORT ioport;
 1409     UCHAR  bval;
 1410 
 1411 #ifdef DC390_DEBUG0
 1412     printf("RST_DETEC");
 1413 #endif
 1414     wlval = 1000;
 1415     while( --wlval )    /* delay 1 sec */
 1416     {
 1417         DELAY(1000);
 1418     }
 1419     flags = splbio();
 1420     ioport = pACB->IOPortBase;
 1421     bval = DMA_IDLE_CMD;
 1422     OutB(bval,ioport+DMA_Cmd);
 1423     bval = CLEAR_FIFO_CMD;
 1424     OutB(bval,ioport+ScsiCmd);
 1425 
 1426     if( pACB->ACBFlag & RESET_DEV )
 1427         pACB->ACBFlag |= RESET_DONE;
 1428     else
 1429     {
 1430         pACB->ACBFlag |= RESET_DETECT;
 1431 
 1432         ResetDevParam( pACB );
 1433 /*      DoingSRB_Done( pACB ); ???? */
 1434         RecoverSRB( pACB );
 1435         pACB->pActiveDCB = NULL;
 1436         pACB->ACBFlag = 0;
 1437         DoWaitingSRB( pACB );
 1438     }
 1439     splx(flags);
 1440     return;
 1441 }
 1442 
 1443 
 1444 static void
 1445 RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB )
 1446 {
 1447     PSCSICMD  pcmd;
 1448 
 1449     pSRB->SRBFlag |= AUTO_REQSENSE;
 1450     pSRB->Segment0[0] = *((PULONG) &(pSRB->CmdBlock[0]));
 1451     pSRB->Segment0[1] = *((PULONG) &(pSRB->CmdBlock[4]));
 1452     pSRB->Segment1[0] = (ULONG) ((pSRB->ScsiCmdLen << 8) + pSRB->SGcount);
 1453     pSRB->Segment1[1] = pSRB->TotalXferredLen;
 1454     pSRB->AdaptStatus = 0;
 1455     pSRB->TargetStatus = 0;
 1456 
 1457     pcmd = pSRB->pcmd;
 1458 
 1459     pSRB->Segmentx.SGXPtr = (ULONG) vtophys(&pcmd->sense);
 1460     pSRB->Segmentx.SGXLen = (ULONG) sizeof(struct scsi_sense_data);
 1461     pSRB->pSegmentList = &pSRB->Segmentx;
 1462     pSRB->SGcount = 1;
 1463     pSRB->SGIndex = 0;
 1464 
 1465     *((PULONG) &(pSRB->CmdBlock[0])) = 0x00000003;
 1466     pSRB->CmdBlock[1] = pDCB->IdentifyMsg << 5;
 1467     *((PUSHORT) &(pSRB->CmdBlock[4])) = sizeof(struct scsi_sense_data);
 1468     pSRB->ScsiCmdLen = 6;
 1469 
 1470     pSRB->TotalXferredLen = 0;
 1471     pSRB->SGToBeXferLen = 0;
 1472     if( DC390_StartSCSI( pACB, pDCB, pSRB ) )
 1473         RewaitSRB( pDCB, pSRB );
 1474 }
 1475 
 1476 
 1477 static void
 1478 EnableMsgOut2( PACB pACB, PSRB pSRB )
 1479 {
 1480     USHORT ioport;
 1481     UCHAR  bval;
 1482 
 1483     ioport = pACB->IOPortBase;
 1484     pSRB->MsgCnt = 1;
 1485     bval = SET_ATN_CMD;
 1486     OutB(bval, ioport+ScsiCmd);
 1487 }
 1488 
 1489 
 1490 static void
 1491 EnableMsgOut( PACB pACB, PSRB pSRB )
 1492 {
 1493     pSRB->MsgOutBuf[0] = MSG_ABORT;
 1494     EnableMsgOut2( pACB, pSRB );
 1495 }
 1496 
 1497 
 1498 static void
 1499 DC390_InvalidCmd( PACB pACB )
 1500 {
 1501    UCHAR bval;
 1502    USHORT ioport;
 1503    PSRB   pSRB;
 1504 
 1505     pSRB = pACB->pActiveDCB->pActiveSRB;
 1506     if( pSRB->SRBState & (SRB_START_+SRB_MSGOUT) )
 1507     {
 1508         ioport = pACB->IOPortBase;
 1509         bval = CLEAR_FIFO_CMD;
 1510         OutB(bval,(ioport+ScsiCmd));
 1511     }
 1512 }
 1513 

Cache object: 0d4dab2395add02d9ff49527754a3954


[ 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.