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

Cache object: 6aebe9e1d45cda04e13e50a94214b8c3


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