Annotation of Gnu-Mach/linux/src/drivers/scsi/scsiiom.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.