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

1.1       root        1: /***********************************************************************
                      2:  *     FILE NAME : TMSCSIM.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:  * (C)Copyright 1995-1996 Tekram Technology Co., Ltd.                 *
                      7:  ***********************************************************************/
                      8: /*     Minor enhancements and bugfixes by                              *
                      9:  *     Kurt Garloff <[email protected]>                                *
                     10:  ***********************************************************************/
                     11: /*     HISTORY:                                                        *
                     12:  *                                                                     *
                     13:  *     REV#    DATE    NAME    DESCRIPTION                             *
                     14:  *     1.00  04/24/96  CLH     First release                           *
                     15:  *     1.01  06/12/96  CLH     Fixed bug of Media Change for Removable *
                     16:  *                             Device, scan all LUN. Support Pre2.0.10 *
                     17:  *     1.02  06/18/96  CLH     Fixed bug of Command timeout ...        *
                     18:  *     1.03  09/25/96  KG      Added tmscsim_proc_info()               *
                     19:  *     1.04  10/11/96  CLH     Updating for support KV 2.0.x           *
                     20:  *     1.05  10/18/96  KG      Fixed bug in DC390_abort(null ptr deref)*
                     21:  *     1.06  10/25/96  KG      Fixed module support                    *
                     22:  *     1.07  11/09/96  KG      Fixed tmscsim_proc_info()               *
                     23:  *     1.08  11/18/96  KG      Fixed null ptr in DC390_Disconnect()    *
                     24:  *     1.09  11/30/96  KG      Added register the allocated IO space   *
                     25:  *     1.10  12/05/96  CLH     Modified tmscsim_proc_info(), and reset *
                     26:  *                             pending interrupt in DC390_detect()     *
                     27:  *     1.11  02/05/97  KG/CLH  Fixeds problem with partitions greater  *
                     28:  *                             than 1GB                                *
                     29:  ***********************************************************************/
                     30: 
                     31: 
                     32: #define DC390_DEBUG
                     33: 
                     34: #define SCSI_MALLOC
                     35: 
                     36: #ifdef MODULE
                     37: #include <linux/module.h>
                     38: #endif
                     39: 
                     40: #include <asm/dma.h>
                     41: #include <asm/io.h>
                     42: #include <asm/system.h>
                     43: #include <linux/delay.h>
                     44: #include <linux/signal.h>
                     45: #include <linux/sched.h>
                     46: #include <linux/errno.h>
                     47: #include <linux/kernel.h>
                     48: #include <linux/ioport.h>
                     49: #include <linux/bios32.h>
                     50: #include <linux/pci.h>
                     51: #include <linux/proc_fs.h>
                     52: #include <linux/string.h>
                     53: #include <linux/mm.h>
                     54: #include <linux/config.h>
                     55: 
                     56: #include <linux/version.h>
                     57: #if LINUX_VERSION_CODE < 66354 /* 1.3.50 */
                     58: #include "../block/blk.h"
                     59: #else
                     60: #include <linux/blk.h>
                     61: #endif
                     62: 
                     63: #include "scsi.h"
                     64: #include "hosts.h"
                     65: #include "tmscsim.h"
                     66: #include "constants.h"
                     67: #include "sd.h"
                     68: #include <linux/stat.h>
                     69: 
                     70: #include "dc390.h"
                     71: 
                     72: #define PCI_DEVICE_ID_AMD53C974        PCI_DEVICE_ID_AMD_SCSI
                     73: 
                     74: 
                     75: #ifndef  VERSION_ELF_1_2_13
                     76: struct proc_dir_entry  proc_scsi_tmscsim ={
                     77:        PROC_SCSI_DC390T, 7 ,"tmscsim",
                     78:        S_IFDIR | S_IRUGO | S_IXUGO, 2
                     79:        };
                     80: #endif
                     81: 
                     82: static USHORT DC390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB );
                     83: static void DC390_DataOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
                     84: static void DC390_DataIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
                     85: static void DC390_Command_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
                     86: static void DC390_Status_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
                     87: static void DC390_MsgOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
                     88: static void DC390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
                     89: static void DC390_DataOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
                     90: static void DC390_DataInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
                     91: static void DC390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
                     92: static void DC390_StatusPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
                     93: static void DC390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
                     94: static void DC390_MsgInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
                     95: static void DC390_Nop_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
                     96: static void DC390_Nop_1( PACB pACB, PSRB pSRB, PUCHAR psstatus);
                     97: 
                     98: static void SetXferRate( PACB pACB, PDCB pDCB );
                     99: static void DC390_Disconnect( PACB pACB );
                    100: static void DC390_Reselect( PACB pACB );
                    101: static void SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB );
                    102: static void DoingSRB_Done( PACB pACB );
                    103: static void DC390_ScsiRstDetect( PACB pACB );
                    104: static void DC390_ResetSCSIBus( PACB pACB );
                    105: static void RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB );
                    106: static void EnableMsgOut2( PACB pACB, PSRB pSRB );
                    107: static void EnableMsgOut( PACB pACB, PSRB pSRB );
                    108: static void DC390_InvalidCmd( PACB pACB );
                    109: 
                    110: int    DC390_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index );
                    111: void   DC390_initDCB( PACB pACB, PDCB pDCB, PSCSICMD cmd );
                    112: 
                    113: #ifdef MODULE
                    114: static int DC390_release(struct Scsi_Host *host);
                    115: static int DC390_shutdown (struct Scsi_Host *host);
                    116: #endif
                    117: 
                    118: 
                    119: static PSHT    pSHT_start = NULL;
                    120: static PSH     pSH_start = NULL;
                    121: static PSH     pSH_current = NULL;
                    122: static PACB    pACB_start= NULL;
                    123: static PACB    pACB_current = NULL;
                    124: static PDCB    pPrevDCB = NULL;
                    125: static USHORT  adapterCnt = 0;
                    126: static USHORT  InitialTime = 0;
                    127: static USHORT  CurrSyncOffset = 0;
                    128: static ULONG   mech1addr;
                    129: static UCHAR   mech2bus, mech2Agent, mech2CfgSPenR;
                    130: 
                    131: static PVOID DC390_phase0[]={
                    132:        DC390_DataOut_0,
                    133:        DC390_DataIn_0,
                    134:        DC390_Command_0,
                    135:        DC390_Status_0,
                    136:        DC390_Nop_0,
                    137:        DC390_Nop_0,
                    138:        DC390_MsgOut_0,
                    139:        DC390_MsgIn_0,
                    140:        DC390_Nop_1
                    141:        };
                    142: 
                    143: static PVOID DC390_phase1[]={
                    144:        DC390_DataOutPhase,
                    145:        DC390_DataInPhase,
                    146:        DC390_CommandPhase,
                    147:        DC390_StatusPhase,
                    148:        DC390_Nop_0,
                    149:        DC390_Nop_0,
                    150:        DC390_MsgOutPhase,
                    151:        DC390_MsgInPhase,
                    152:        DC390_Nop_1,
                    153:        };
                    154: 
                    155: UCHAR  eepromBuf[MAX_ADAPTER_NUM][128];
                    156: 
                    157: 
                    158: UCHAR  clock_period1[] = {4, 5, 6, 7, 8, 10, 13, 20};
                    159: 
                    160: UCHAR  baddevname1[2][28] ={
                    161:        "SEAGATE ST3390N         9546",
                    162:        "HP      C3323-300       4269"};
                    163: 
                    164: #define BADDEVCNT      2
                    165: 
                    166: 
                    167: /***********************************************************************
                    168:  *
                    169:  *
                    170:  *
                    171:  **********************************************************************/
                    172: static void
                    173: QLinkcmd( PSCSICMD cmd, PDCB pDCB )
                    174: {
                    175:     ULONG  flags;
                    176:     PSCSICMD  pcmd;
                    177: 
                    178:     save_flags(flags);
                    179:     cli();
                    180: 
                    181:     if( !pDCB->QIORBCnt )
                    182:     {
                    183:        pDCB->pQIORBhead = cmd;
                    184:        pDCB->pQIORBtail = cmd;
                    185:        pDCB->QIORBCnt++;
                    186:        cmd->next = NULL;
                    187:     }
                    188:     else
                    189:     {
                    190:        pcmd = pDCB->pQIORBtail;
                    191:        pcmd->next = cmd;
                    192:        pDCB->pQIORBtail = cmd;
                    193:        pDCB->QIORBCnt++;
                    194:        cmd->next = NULL;
                    195:     }
                    196: 
                    197:     restore_flags(flags);
                    198: }
                    199: 
                    200: 
                    201: static PSCSICMD
                    202: Getcmd( PDCB pDCB )
                    203: {
                    204:     ULONG  flags;
                    205:     PSCSICMD  pcmd;
                    206: 
                    207:     save_flags(flags);
                    208:     cli();
                    209: 
                    210:     pcmd = pDCB->pQIORBhead;
                    211:     pDCB->pQIORBhead = pcmd->next;
                    212:     pcmd->next = NULL;
                    213:     pDCB->QIORBCnt--;
                    214: 
                    215:     restore_flags(flags);
                    216:     return( pcmd );
                    217: }
                    218: 
                    219: 
                    220: static PSRB
                    221: GetSRB( PACB pACB )
                    222: {
                    223:     ULONG  flags;
                    224:     PSRB   pSRB;
                    225: 
                    226:     save_flags(flags);
                    227:     cli();
                    228: 
                    229:     pSRB = pACB->pFreeSRB;
                    230:     if( pSRB )
                    231:     {
                    232:        pACB->pFreeSRB = pSRB->pNextSRB;
                    233:        pSRB->pNextSRB = NULL;
                    234:     }
                    235:     restore_flags(flags);
                    236:     return( pSRB );
                    237: }
                    238: 
                    239: 
                    240: static void
                    241: RewaitSRB0( PDCB pDCB, PSRB pSRB )
                    242: {
                    243:     PSRB   psrb1;
                    244:     ULONG  flags;
                    245: 
                    246:     save_flags(flags);
                    247:     cli();
                    248: 
                    249:     if( (psrb1 = pDCB->pWaitingSRB) )
                    250:     {
                    251:        pSRB->pNextSRB = psrb1;
                    252:        pDCB->pWaitingSRB = pSRB;
                    253:     }
                    254:     else
                    255:     {
                    256:        pSRB->pNextSRB = NULL;
                    257:        pDCB->pWaitingSRB = pSRB;
                    258:        pDCB->pWaitLast = pSRB;
                    259:     }
                    260:     restore_flags(flags);
                    261: }
                    262: 
                    263: 
                    264: static void
                    265: RewaitSRB( PDCB pDCB, PSRB pSRB )
                    266: {
                    267:     PSRB   psrb1;
                    268:     ULONG  flags;
                    269:     UCHAR  bval;
                    270: 
                    271:     save_flags(flags);
                    272:     cli();
                    273:     pDCB->GoingSRBCnt--;
                    274:     psrb1 = pDCB->pGoingSRB;
                    275:     if( pSRB == psrb1 )
                    276:     {
                    277:        pDCB->pGoingSRB = psrb1->pNextSRB;
                    278:     }
                    279:     else
                    280:     {
                    281:        while( pSRB != psrb1->pNextSRB )
                    282:            psrb1 = psrb1->pNextSRB;
                    283:        psrb1->pNextSRB = pSRB->pNextSRB;
                    284:        if( pSRB == pDCB->pGoingLast )
                    285:            pDCB->pGoingLast = psrb1;
                    286:     }
                    287:     if( (psrb1 = pDCB->pWaitingSRB) )
                    288:     {
                    289:        pSRB->pNextSRB = psrb1;
                    290:        pDCB->pWaitingSRB = pSRB;
                    291:     }
                    292:     else
                    293:     {
                    294:        pSRB->pNextSRB = NULL;
                    295:        pDCB->pWaitingSRB = pSRB;
                    296:        pDCB->pWaitLast = pSRB;
                    297:     }
                    298: 
                    299:     bval = pSRB->TagNumber;
                    300:     pDCB->TagMask &= (~(1 << bval));     /* Free TAG number */
                    301:     restore_flags(flags);
                    302: }
                    303: 
                    304: 
                    305: static void
                    306: DoWaitingSRB( PACB pACB )
                    307: {
                    308:     ULONG  flags;
                    309:     PDCB   ptr, ptr1;
                    310:     PSRB   pSRB;
                    311: 
                    312:     save_flags(flags);
                    313:     cli();
                    314: 
                    315:     if( !(pACB->pActiveDCB) && !(pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) ) )
                    316:     {
                    317:        ptr = pACB->pDCBRunRobin;
                    318:        if( !ptr )
                    319:        {
                    320:            ptr = pACB->pLinkDCB;
                    321:            pACB->pDCBRunRobin = ptr;
                    322:        }
                    323:        ptr1 = ptr;
                    324:        for( ;ptr1; )
                    325:        {
                    326:            pACB->pDCBRunRobin = ptr1->pNextDCB;
                    327:            if( !( ptr1->MaxCommand > ptr1->GoingSRBCnt ) ||
                    328:                !( pSRB = ptr1->pWaitingSRB ) )
                    329:            {
                    330:                if(pACB->pDCBRunRobin == ptr)
                    331:                    break;
                    332:                ptr1 = ptr1->pNextDCB;
                    333:            }
                    334:            else
                    335:            {
                    336:                if( !DC390_StartSCSI(pACB, ptr1, pSRB) )
                    337:                {
                    338:                    ptr1->GoingSRBCnt++;
                    339:                    if( ptr1->pWaitLast == pSRB )
                    340:                    {
                    341:                        ptr1->pWaitingSRB = NULL;
                    342:                        ptr1->pWaitLast = NULL;
                    343:                    }
                    344:                    else
                    345:                    {
                    346:                        ptr1->pWaitingSRB = pSRB->pNextSRB;
                    347:                    }
                    348:                    pSRB->pNextSRB = NULL;
                    349: 
                    350:                    if( ptr1->pGoingSRB )
                    351:                        ptr1->pGoingLast->pNextSRB = pSRB;
                    352:                    else
                    353:                        ptr1->pGoingSRB = pSRB;
                    354:                    ptr1->pGoingLast = pSRB;
                    355:                }
                    356:                break;
                    357:            }
                    358:        }
                    359:     }
                    360:     restore_flags(flags);
                    361:     return;
                    362: }
                    363: 
                    364: 
                    365: static void
                    366: SRBwaiting( PDCB pDCB, PSRB pSRB)
                    367: {
                    368:     if( pDCB->pWaitingSRB )
                    369:     {
                    370:        pDCB->pWaitLast->pNextSRB = pSRB;
                    371:        pDCB->pWaitLast = pSRB;
                    372:        pSRB->pNextSRB = NULL;
                    373:     }
                    374:     else
                    375:     {
                    376:        pDCB->pWaitingSRB = pSRB;
                    377:        pDCB->pWaitLast = pSRB;
                    378:     }
                    379: }
                    380: 
                    381: 
                    382: static void
                    383: SendSRB( PSCSICMD pcmd, PACB pACB, PSRB pSRB )
                    384: {
                    385:     ULONG  flags;
                    386:     PDCB   pDCB;
                    387: 
                    388:     save_flags(flags);
                    389:     cli();
                    390: 
                    391:     pDCB = pSRB->pSRBDCB;
                    392:     if( !(pDCB->MaxCommand > pDCB->GoingSRBCnt) || (pACB->pActiveDCB) ||
                    393:        (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV)) )
                    394:     {
                    395:        SRBwaiting(pDCB, pSRB);
                    396:        goto SND_EXIT;
                    397:     }
                    398: 
                    399:     if( pDCB->pWaitingSRB )
                    400:     {
                    401:        SRBwaiting(pDCB, pSRB);
                    402: /*     pSRB = GetWaitingSRB(pDCB); */
                    403:        pSRB = pDCB->pWaitingSRB;
                    404:        pDCB->pWaitingSRB = pSRB->pNextSRB;
                    405:        pSRB->pNextSRB = NULL;
                    406:     }
                    407: 
                    408:     if( !DC390_StartSCSI(pACB, pDCB, pSRB) )
                    409:     {
                    410:        pDCB->GoingSRBCnt++;
                    411:        if( pDCB->pGoingSRB )
                    412:        {
                    413:            pDCB->pGoingLast->pNextSRB = pSRB;
                    414:            pDCB->pGoingLast = pSRB;
                    415:        }
                    416:        else
                    417:        {
                    418:            pDCB->pGoingSRB = pSRB;
                    419:            pDCB->pGoingLast = pSRB;
                    420:        }
                    421:     }
                    422:     else
                    423:        RewaitSRB0( pDCB, pSRB );
                    424: 
                    425: SND_EXIT:
                    426:     restore_flags(flags);
                    427:     return;
                    428: }
                    429: 
                    430: 
                    431: /***********************************************************************
                    432:  * Function : static int DC390_queue_command (Scsi_Cmnd *cmd,
                    433:  *                                            void (*done)(Scsi_Cmnd *))
                    434:  *
                    435:  * Purpose : enqueues a SCSI command
                    436:  *
                    437:  * Inputs : cmd - SCSI command, done - function called on completion, with
                    438:  *         a pointer to the command descriptor.
                    439:  *
                    440:  * Returns : 0
                    441:  *
                    442:  ***********************************************************************/
                    443: 
                    444: int
                    445: DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
                    446: {
                    447:     USHORT ioport, i;
                    448:     Scsi_Cmnd *pcmd;
                    449:     struct Scsi_Host *psh;
                    450:     PACB   pACB;
                    451:     PDCB   pDCB;
                    452:     PSRB   pSRB;
                    453:     ULONG  flags;
                    454:     PUCHAR ptr,ptr1;
                    455: 
                    456:     psh = cmd->host;
                    457:     pACB = (PACB ) psh->hostdata;
                    458:     ioport = pACB->IOPortBase;
                    459: 
                    460: #ifdef DC390_DEBUG0
                    461: /*  if(pACB->scan_devices) */
                    462:        printk("Cmd=%2x,ID=%d,LUN=%d,",cmd->cmnd[0],cmd->target,cmd->lun);
                    463: #endif
                    464: 
                    465:     if( (pACB->scan_devices == END_SCAN) && (cmd->cmnd[0] != INQUIRY) )
                    466:     {
                    467:        pACB->scan_devices = 0;
                    468:        pPrevDCB->pNextDCB = pACB->pLinkDCB;
                    469:     }
                    470:     else if( (pACB->scan_devices) && (cmd->cmnd[0] == 8) )
                    471:     {
                    472:        pACB->scan_devices = 0;
                    473:        pPrevDCB->pNextDCB = pACB->pLinkDCB;
                    474:     }
                    475: 
                    476:     if ( ( cmd->target > pACB->max_id ) || (cmd->lun > pACB->max_lun) )
                    477:     {
                    478: /*     printk("DC390: Ignore target %d lun %d\n",
                    479:                cmd->target, cmd->lun); */
                    480:        cmd->result = (DID_BAD_TARGET << 16);
                    481:        done(cmd);
                    482:        return( 0 );
                    483:     }
                    484: 
                    485:     if( (pACB->scan_devices) && !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) )
                    486:     {
                    487:        if( pACB->DeviceCnt < MAX_DEVICES )
                    488:        {
                    489:            pACB->DCBmap[cmd->target] |= (1 << cmd->lun);
                    490:            pDCB = pACB->pDCB_free;
                    491: #ifdef DC390_DEBUG0
                    492:            printk("pDCB=%8x,ID=%2x,", (UINT) pDCB, cmd->target);
                    493: #endif
                    494:            DC390_initDCB( pACB, pDCB, cmd );
                    495:        }
                    496:        else    /* ???? */
                    497:        {
                    498: /*         printk("DC390: Ignore target %d lun %d\n",
                    499:                    cmd->target, cmd->lun); */
                    500:            cmd->result = (DID_BAD_TARGET << 16);
                    501:            done(cmd);
                    502:            return(0);
                    503:        }
                    504:     }
                    505:     else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) )
                    506:     {
                    507: /*     printk("DC390: Ignore target %d lun %d\n",
                    508:                cmd->target, cmd->lun); */
                    509:        cmd->result = (DID_BAD_TARGET << 16);
                    510:        done(cmd);
                    511:        return(0);
                    512:     }
                    513:     else
                    514:     {
                    515:        pDCB = pACB->pLinkDCB;
                    516:        while( (pDCB->UnitSCSIID != cmd->target) ||
                    517:               (pDCB->UnitSCSILUN != cmd->lun) )
                    518:        {
                    519:            pDCB = pDCB->pNextDCB;
                    520:        }
                    521: #ifdef DC390_DEBUG0
                    522:            printk("pDCB=%8x,ID=%2x,", (UINT) pDCB, cmd->target);
                    523: #endif
                    524:     }
                    525: 
                    526:     cmd->scsi_done = done;
                    527:     cmd->result = 0;
                    528: 
                    529:     save_flags(flags);
                    530:     cli();
                    531: 
                    532:     if( pDCB->QIORBCnt )
                    533:     {
                    534:        QLinkcmd( cmd, pDCB );
                    535:        pcmd = Getcmd( pDCB );
                    536:     }
                    537:     else
                    538:        pcmd = cmd;
                    539: 
                    540:     pSRB = GetSRB( pACB );
                    541: 
                    542:     if( !pSRB )
                    543:     {
                    544:        QLinkcmd( pcmd, pDCB );
                    545:        restore_flags(flags);
                    546:        return(0);
                    547:     }
                    548: 
                    549: /*  BuildSRB(pSRB); */
                    550: 
                    551:     pSRB->pSRBDCB = pDCB;
                    552:     pSRB->pcmd = pcmd;
                    553:     ptr = (PUCHAR) pSRB->CmdBlock;
                    554:     ptr1 = (PUCHAR) pcmd->cmnd;
                    555:     pSRB->ScsiCmdLen = pcmd->cmd_len;
                    556:     for(i=0; i< pcmd->cmd_len; i++)
                    557:     {
                    558:        *ptr = *ptr1;
                    559:        ptr++;
                    560:        ptr1++;
                    561:     }
                    562:     if( pcmd->use_sg )
                    563:     {
                    564:        pSRB->SGcount = (UCHAR) pcmd->use_sg;
                    565:        pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
                    566:     }
                    567:     else if( pcmd->request_buffer )
                    568:     {
                    569:        pSRB->SGcount = 1;
                    570:        pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
                    571:        pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
                    572:        pSRB->Segmentx.length = pcmd->request_bufflen;
                    573:     }
                    574:     else
                    575:        pSRB->SGcount = 0;
                    576: 
                    577:     pSRB->SGIndex = 0;
                    578:     pSRB->AdaptStatus = 0;
                    579:     pSRB->TargetStatus = 0;
                    580:     pSRB->MsgCnt = 0;
                    581:     if( pDCB->DevType != TYPE_TAPE )
                    582:        pSRB->RetryCnt = 1;
                    583:     else
                    584:        pSRB->RetryCnt = 0;
                    585:     pSRB->SRBStatus = 0;
                    586:     pSRB->SRBFlag = 0;
                    587:     pSRB->SRBState = 0;
                    588:     pSRB->TotalXferredLen = 0;
                    589:     pSRB->SGPhysAddr = 0;
                    590:     pSRB->SGToBeXferLen = 0;
                    591:     pSRB->ScsiPhase = 0;
                    592:     pSRB->EndMessage = 0;
                    593:     SendSRB( pcmd, pACB, pSRB );
                    594: 
                    595:     restore_flags(flags);
                    596:     return(0);
                    597: }
                    598: 
                    599: 
                    600: static void
                    601: DoNextCmd( PACB pACB, PDCB pDCB )
                    602: {
                    603:     Scsi_Cmnd *pcmd;
                    604:     PSRB   pSRB;
                    605:     ULONG  flags;
                    606:     PUCHAR ptr,ptr1;
                    607:     USHORT i;
                    608: 
                    609: 
                    610:     if( pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) )
                    611:        return;
                    612:     save_flags(flags);
                    613:     cli();
                    614: 
                    615:     pcmd = Getcmd( pDCB );
                    616:     pSRB = GetSRB( pACB );
                    617:     if( !pSRB )
                    618:     {
                    619:        QLinkcmd( pcmd, pDCB );
                    620:        restore_flags(flags);
                    621:        return;
                    622:     }
                    623: 
                    624:     pSRB->pSRBDCB = pDCB;
                    625:     pSRB->pcmd = pcmd;
                    626:     ptr = (PUCHAR) pSRB->CmdBlock;
                    627:     ptr1 = (PUCHAR) pcmd->cmnd;
                    628:     pSRB->ScsiCmdLen = pcmd->cmd_len;
                    629:     for(i=0; i< pcmd->cmd_len; i++)
                    630:     {
                    631:        *ptr = *ptr1;
                    632:        ptr++;
                    633:        ptr1++;
                    634:     }
                    635:     if( pcmd->use_sg )
                    636:     {
                    637:        pSRB->SGcount = (UCHAR) pcmd->use_sg;
                    638:        pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
                    639:     }
                    640:     else if( pcmd->request_buffer )
                    641:     {
                    642:        pSRB->SGcount = 1;
                    643:        pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
                    644:        pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
                    645:        pSRB->Segmentx.length = pcmd->request_bufflen;
                    646:     }
                    647:     else
                    648:        pSRB->SGcount = 0;
                    649: 
                    650:     pSRB->SGIndex = 0;
                    651:     pSRB->AdaptStatus = 0;
                    652:     pSRB->TargetStatus = 0;
                    653:     pSRB->MsgCnt = 0;
                    654:     if( pDCB->DevType != TYPE_TAPE )
                    655:        pSRB->RetryCnt = 1;
                    656:     else
                    657:        pSRB->RetryCnt = 0;
                    658:     pSRB->SRBStatus = 0;
                    659:     pSRB->SRBFlag = 0;
                    660:     pSRB->SRBState = 0;
                    661:     pSRB->TotalXferredLen = 0;
                    662:     pSRB->SGPhysAddr = 0;
                    663:     pSRB->SGToBeXferLen = 0;
                    664:     pSRB->ScsiPhase = 0;
                    665:     pSRB->EndMessage = 0;
                    666:     SendSRB( pcmd, pACB, pSRB );
                    667: 
                    668:     restore_flags(flags);
                    669:     return;
                    670: }
                    671: 
                    672: 
                    673: /***********************************************************************
                    674:  * Function:
                    675:  *   DC390_bios_param
                    676:  *
                    677:  * Description:
                    678:  *   Return the disk geometry for the given SCSI device.
                    679:  ***********************************************************************/
                    680: #ifdef VERSION_ELF_1_2_13
                    681: int DC390_bios_param(Disk *disk, int devno, int geom[])
                    682: #else
                    683: int DC390_bios_param(Disk *disk, kdev_t devno, int geom[])
                    684: #endif
                    685: {
                    686:     int heads, sectors, cylinders;
                    687:     PACB pACB;
                    688: 
                    689:     pACB = (PACB) disk->device->host->hostdata;
                    690:     heads = 64;
                    691:     sectors = 32;
                    692:     cylinders = disk->capacity / (heads * sectors);
                    693: 
                    694:     if ( (pACB->Gmode2 & GREATER_1G) && (cylinders > 1024) )
                    695:     {
                    696:       heads = 255;
                    697:       sectors = 63;
                    698:       cylinders = disk->capacity / (heads * sectors);
                    699:     }
                    700: 
                    701:     geom[0] = heads;
                    702:     geom[1] = sectors;
                    703:     geom[2] = cylinders;
                    704: 
                    705:     return (0);
                    706: }
                    707: 
                    708: 
                    709: /***********************************************************************
                    710:  * Function : int DC390_abort (Scsi_Cmnd *cmd)
                    711:  *
                    712:  * Purpose : Abort an errant SCSI command
                    713:  *
                    714:  * Inputs : cmd - command to abort
                    715:  *
                    716:  * Returns : 0 on success, -1 on failure.
                    717:  ***********************************************************************/
                    718: 
                    719: int
                    720: DC390_abort (Scsi_Cmnd *cmd)
                    721: {
                    722:     ULONG flags;
                    723:     PACB  pACB;
                    724:     PDCB  pDCB, pdcb;
                    725:     PSRB  pSRB, psrb;
                    726:     USHORT count, i;
                    727:     PSCSICMD  pcmd, pcmd1;
                    728:     int   status;
                    729: 
                    730: 
                    731: #ifdef DC390_DEBUG0
                    732:     printk("DC390 : Abort Cmd.");
                    733: #endif
                    734: 
                    735:     save_flags(flags);
                    736:     cli();
                    737: 
                    738:     pACB = (PACB) cmd->host->hostdata;
                    739:     pDCB = pACB->pLinkDCB;
                    740:     pdcb = pDCB;
                    741:     while( (pDCB->UnitSCSIID != cmd->target) ||
                    742:           (pDCB->UnitSCSILUN != cmd->lun) )
                    743:     {
                    744:        pDCB = pDCB->pNextDCB;
                    745:        if( pDCB == pdcb )
                    746:            goto  NOT_RUN;
                    747:     }
                    748: 
                    749:     if( pDCB->QIORBCnt )
                    750:     {
                    751:        pcmd = pDCB->pQIORBhead;
                    752:        if( pcmd == cmd )
                    753:        {
                    754:            pDCB->pQIORBhead = pcmd->next;
                    755:            pcmd->next = NULL;
                    756:            pDCB->QIORBCnt--;
                    757:            status = SCSI_ABORT_SUCCESS;
                    758:            goto  ABO_X;
                    759:        }
                    760:        for( count = pDCB->QIORBCnt, i=0; i<count-1; i++)
                    761:        {
                    762:            if( pcmd->next == cmd )
                    763:            {
                    764:                pcmd1 = pcmd->next;
                    765:                pcmd->next = pcmd1->next;
                    766:                pcmd1->next = NULL;
                    767:                pDCB->QIORBCnt--;
                    768:                status = SCSI_ABORT_SUCCESS;
                    769:                goto  ABO_X;
                    770:            }
                    771:            else
                    772:            {
                    773:                pcmd = pcmd->next;
                    774:            }
                    775:        }
                    776:     }
                    777: 
                    778:     pSRB = pDCB->pWaitingSRB;
                    779:     if( !pSRB )
                    780:        goto  ON_GOING;
                    781:     if( pSRB->pcmd == cmd )
                    782:     {
                    783:        pDCB->pWaitingSRB = pSRB->pNextSRB;
                    784:        goto  IN_WAIT;
                    785:     }
                    786:     else
                    787:     {
                    788:        psrb = pSRB;
                    789:        if( !(psrb->pNextSRB) )
                    790:            goto ON_GOING;
                    791:        while( psrb->pNextSRB->pcmd != cmd )
                    792:        {
                    793:            psrb = psrb->pNextSRB;
                    794:            if( !(psrb->pNextSRB) )
                    795:                goto ON_GOING;
                    796:        }
                    797:        pSRB = psrb->pNextSRB;
                    798:        psrb->pNextSRB = pSRB->pNextSRB;
                    799:        if( pSRB == pDCB->pWaitLast )
                    800:            pDCB->pWaitLast = psrb; /* No check for psrb == NULL ? */
                    801: IN_WAIT:
                    802:        pSRB->pNextSRB = pACB->pFreeSRB;
                    803:        pACB->pFreeSRB = pSRB;
                    804:        cmd->next = NULL;
                    805:        status = SCSI_ABORT_SUCCESS;
                    806:        goto  ABO_X;
                    807:     }
                    808: 
                    809: ON_GOING:
                    810:     pSRB = pDCB->pGoingSRB;
                    811:     for( count = pDCB->GoingSRBCnt, i=0; i<count; i++)
                    812:     {
                    813:        if( pSRB->pcmd != cmd )
                    814:            pSRB = pSRB->pNextSRB;
                    815:        else
                    816:        {
                    817:            if( (pACB->pActiveDCB == pDCB) && (pDCB->pActiveSRB == pSRB) )
                    818:            {
                    819:                status = SCSI_ABORT_BUSY;
                    820:                goto  ABO_X;
                    821:            }
                    822:            else
                    823:            {
                    824:                status = SCSI_ABORT_SNOOZE;
                    825:                goto  ABO_X;
                    826:            }
                    827:        }
                    828:     }
                    829: 
                    830: NOT_RUN:
                    831:     status = SCSI_ABORT_NOT_RUNNING;
                    832: 
                    833: ABO_X:
                    834:     cmd->result = DID_ABORT << 16;
                    835:     cmd->scsi_done(cmd);
                    836:     restore_flags(flags);
                    837:     return( status );
                    838: }
                    839: 
                    840: 
                    841: static void
                    842: ResetDevParam( PACB pACB )
                    843: {
                    844:     PDCB   pDCB, pdcb;
                    845: 
                    846:     pDCB = pACB->pLinkDCB;
                    847:     if( pDCB == NULL )
                    848:        return;
                    849:     pdcb = pDCB;
                    850:     do
                    851:     {
                    852:        pDCB->SyncMode &= ~SYNC_NEGO_DONE;
                    853:        pDCB->SyncPeriod = 0;
                    854:        pDCB->SyncOffset = 0;
                    855:        pDCB->CtrlR3 = FAST_CLK;
                    856:        pDCB->CtrlR4 &= NEGATE_REQACKDATA;
                    857:        pDCB->CtrlR4 |= EATER_25NS;
                    858:        pDCB = pDCB->pNextDCB;
                    859:     }
                    860:     while( pdcb != pDCB );
                    861: }
                    862: 
                    863: 
                    864: static void
                    865: RecoverSRB( PACB pACB )
                    866: {
                    867:     PDCB   pDCB, pdcb;
                    868:     PSRB   psrb, psrb2;
                    869:     USHORT cnt, i;
                    870: 
                    871:     pDCB = pACB->pLinkDCB;
                    872:     if( pDCB == NULL )
                    873:        return;
                    874:     pdcb = pDCB;
                    875:     do
                    876:     {
                    877:        cnt = pdcb->GoingSRBCnt;
                    878:        psrb = pdcb->pGoingSRB;
                    879:        for (i=0; i<cnt; i++)
                    880:        {
                    881:            psrb2 = psrb;
                    882:            psrb = psrb->pNextSRB;
                    883: /*         RewaitSRB( pDCB, psrb ); */
                    884:            if( pdcb->pWaitingSRB )
                    885:            {
                    886:                psrb2->pNextSRB = pdcb->pWaitingSRB;
                    887:                pdcb->pWaitingSRB = psrb2;
                    888:            }
                    889:            else
                    890:            {
                    891:                pdcb->pWaitingSRB = psrb2;
                    892:                pdcb->pWaitLast = psrb2;
                    893:                psrb2->pNextSRB = NULL;
                    894:            }
                    895:        }
                    896:        pdcb->GoingSRBCnt = 0;
                    897:        pdcb->pGoingSRB = NULL;
                    898:        pdcb->TagMask = 0;
                    899:        pdcb = pdcb->pNextDCB;
                    900:     }
                    901:     while( pdcb != pDCB );
                    902: }
                    903: 
                    904: 
                    905: /***********************************************************************
                    906:  * Function : int DC390_reset (Scsi_Cmnd *cmd, ...)
                    907:  *
                    908:  * Purpose : perform a hard reset on the SCSI bus
                    909:  *
                    910:  * Inputs : cmd - command which caused the SCSI RESET
                    911:  *
                    912:  * Returns : 0 on success.
                    913:  ***********************************************************************/
                    914: 
                    915: #ifdef VERSION_2_0_0
                    916: int DC390_reset(Scsi_Cmnd *cmd, unsigned int resetFlags)
                    917: #else
                    918: int DC390_reset (Scsi_Cmnd *cmd)
                    919: #endif
                    920: {
                    921:     USHORT   ioport;
                    922:     unsigned long flags;
                    923:     PACB  pACB;
                    924:     UCHAR    bval;
                    925:     USHORT  i;
                    926: 
                    927: 
                    928: #ifdef DC390_DEBUG1
                    929:     printk("DC390: RESET,");
                    930: #endif
                    931: 
                    932:     pACB = (PACB ) cmd->host->hostdata;
                    933:     ioport = pACB->IOPortBase;
                    934:     save_flags(flags);
                    935:     cli();
                    936:     bval = inb(ioport+CtrlReg1);
                    937:     bval |= DIS_INT_ON_SCSI_RST;
                    938:     outb(bval,ioport+CtrlReg1);  /* disable interrupt */
                    939:     DC390_ResetSCSIBus( pACB );
                    940:     for( i=0; i<500; i++ )
                    941:        udelay(1000);
                    942:     bval = inb(ioport+CtrlReg1);
                    943:     bval &= ~DIS_INT_ON_SCSI_RST;
                    944:     outb(bval,ioport+CtrlReg1); /* re-enable interrupt */
                    945: 
                    946:     bval = DMA_IDLE_CMD;
                    947:     outb(bval,ioport+DMA_Cmd);
                    948:     bval = CLEAR_FIFO_CMD;
                    949:     outb(bval,ioport+ScsiCmd);
                    950: 
                    951:     ResetDevParam( pACB );
                    952:     DoingSRB_Done( pACB );
                    953:     pACB->pActiveDCB = NULL;
                    954: 
                    955:     pACB->ACBFlag = 0;
                    956:     DoWaitingSRB( pACB );
                    957: 
                    958:     restore_flags(flags);
                    959: #ifdef DC390_DEBUG1
                    960:     printk("DC390: RESET1,");
                    961: #endif
                    962:     return( SCSI_RESET_SUCCESS );
                    963: }
                    964: 
                    965: 
                    966: #include "scsiiom.c"
                    967: 
                    968: 
                    969: /***********************************************************************
                    970:  * Function : static void DC390_initDCB
                    971:  *
                    972:  * Purpose :  initialize the internal structures for a given DCB
                    973:  *
                    974:  * Inputs : cmd - pointer to this scsi cmd request block structure
                    975:  *
                    976:  ***********************************************************************/
                    977: void DC390_initDCB( PACB pACB, PDCB pDCB, PSCSICMD cmd )
                    978: {
                    979:     PEEprom    prom;
                    980:     UCHAR      bval;
                    981:     USHORT     index;
                    982: 
                    983:     if( pACB->DeviceCnt == 0 )
                    984:     {
                    985:        pACB->pLinkDCB = pDCB;
                    986:        pACB->pDCBRunRobin = pDCB;
                    987:        pDCB->pNextDCB = pDCB;
                    988:        pPrevDCB = pDCB;
                    989:     }
                    990:     else
                    991:        pPrevDCB->pNextDCB = pDCB;
                    992: 
                    993:     pDCB->pDCBACB = pACB;
                    994:     pDCB->QIORBCnt = 0;
                    995:     pDCB->UnitSCSIID = cmd->target;
                    996:     pDCB->UnitSCSILUN = cmd->lun;
                    997:     pDCB->pWaitingSRB = NULL;
                    998:     pDCB->pGoingSRB = NULL;
                    999:     pDCB->GoingSRBCnt = 0;
                   1000:     pDCB->pActiveSRB = NULL;
                   1001:     pDCB->TagMask = 0;
                   1002:     pDCB->MaxCommand = 1;
                   1003:     pDCB->AdaptIndex = pACB->AdapterIndex;
                   1004:     index = pACB->AdapterIndex;
                   1005:     pDCB->DCBFlag = 0;
                   1006: 
                   1007:     prom = (PEEprom) &eepromBuf[index][cmd->target << 2];
                   1008:     pDCB->DevMode = prom->EE_MODE1;
                   1009:     pDCB->AdpMode = eepromBuf[index][EE_MODE2];
                   1010: 
                   1011:     if( pDCB->DevMode & EN_DISCONNECT_ )
                   1012:        bval = 0xC0;
                   1013:     else
                   1014:        bval = 0x80;
                   1015:     bval |= cmd->lun;
                   1016:     pDCB->IdentifyMsg = bval;
                   1017: 
                   1018:     pDCB->SyncMode = 0;
                   1019:     if( pDCB->DevMode & SYNC_NEGO_ )
                   1020:     {
                   1021:        if( !(cmd->lun) || CurrSyncOffset )
                   1022:            pDCB->SyncMode = SYNC_ENABLE;
                   1023:     }
                   1024: 
                   1025:     pDCB->SyncPeriod = 0;
                   1026:     pDCB->SyncOffset = 0;
                   1027:     pDCB->NegoPeriod = (clock_period1[prom->EE_SPEED] * 25) >> 2;
                   1028: 
                   1029:     pDCB->CtrlR1 = pACB->AdaptSCSIID;
                   1030:     if( pDCB->DevMode & PARITY_CHK_ )
                   1031:        pDCB->CtrlR1 |= PARITY_ERR_REPO;
                   1032: 
                   1033:     pDCB->CtrlR3 = FAST_CLK;
                   1034: 
                   1035:     pDCB->CtrlR4 = EATER_25NS;
                   1036:     if( pDCB->AdpMode & ACTIVE_NEGATION)
                   1037:        pDCB->CtrlR4 |= NEGATE_REQACKDATA;
                   1038: }
                   1039: 
                   1040: 
                   1041: /***********************************************************************
                   1042:  * Function : static void DC390_initSRB
                   1043:  *
                   1044:  * Purpose :  initialize the internal structures for a given SRB
                   1045:  *
                   1046:  * Inputs : psrb - pointer to this scsi request block structure
                   1047:  *
                   1048:  ***********************************************************************/
                   1049: void DC390_initSRB( PSRB psrb )
                   1050: {
                   1051: #ifndef VERSION_ELF_1_2_13
                   1052: #ifdef DC390_DEBUG0
                   1053:    printk("DC390 init: %08lx %08lx,",(ULONG)psrb,(ULONG)virt_to_bus(psrb));
                   1054: #endif
                   1055:        psrb->PhysSRB = virt_to_bus( psrb );
                   1056: #else
                   1057:        psrb->PhysSRB = (ULONG) psrb;
                   1058: #endif
                   1059: }
                   1060: 
                   1061: 
                   1062: void DC390_linkSRB( PACB pACB )
                   1063: {
                   1064:     USHORT  count, i;
                   1065:     PSRB    psrb;
                   1066: 
                   1067:     count = pACB->SRBCount;
                   1068: 
                   1069:     for( i=0; i< count; i++)
                   1070:     {
                   1071:        if( i != count - 1)
                   1072:            pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[i+1];
                   1073:        else
                   1074:            pACB->SRB_array[i].pNextSRB = NULL;
                   1075:        psrb = (PSRB) &pACB->SRB_array[i];
                   1076:        DC390_initSRB( psrb );
                   1077:     }
                   1078: }
                   1079: 
                   1080: 
                   1081: /***********************************************************************
                   1082:  * Function : static void DC390_initACB
                   1083:  *
                   1084:  * Purpose :  initialize the internal structures for a given SCSI host
                   1085:  *
                   1086:  * Inputs : psh - pointer to this host adapter's structure
                   1087:  *
                   1088:  ***********************************************************************/
                   1089: void DC390_initACB( PSH psh, ULONG io_port, UCHAR Irq, USHORT index )
                   1090: {
                   1091:     PACB    pACB;
                   1092:     USHORT  i;
                   1093: 
                   1094:     psh->can_queue = MAX_CMD_QUEUE;
                   1095:     psh->cmd_per_lun = MAX_CMD_PER_LUN;
                   1096:     psh->this_id = (int) eepromBuf[index][EE_ADAPT_SCSI_ID];
                   1097:     psh->io_port = io_port;
                   1098:     psh->n_io_port = 0x80;
                   1099:     psh->irq = Irq;
                   1100: 
                   1101:     pACB = (PACB) psh->hostdata;
                   1102: 
                   1103: #ifndef VERSION_ELF_1_2_13
                   1104:     psh->max_id = 8;
                   1105: #ifdef CONFIG_SCSI_MULTI_LUN
                   1106:     if( eepromBuf[index][EE_MODE2] & LUN_CHECK )
                   1107:        psh->max_lun = 8;
                   1108:     else
                   1109: #endif
                   1110:        psh->max_lun = 1;
                   1111: #endif
                   1112: 
                   1113:     pACB->max_id = 7;
                   1114:     if( pACB->max_id == eepromBuf[index][EE_ADAPT_SCSI_ID] )
                   1115:        pACB->max_id--;
                   1116: #ifdef CONFIG_SCSI_MULTI_LUN
                   1117:     if( eepromBuf[index][EE_MODE2] & LUN_CHECK )
                   1118:        pACB->max_lun = 7;
                   1119:     else
                   1120: #endif
                   1121:        pACB->max_lun = 0;
                   1122: 
                   1123:     pACB->pScsiHost = psh;
                   1124:     pACB->IOPortBase = (USHORT) io_port;
                   1125:     pACB->pLinkDCB = NULL;
                   1126:     pACB->pDCBRunRobin = NULL;
                   1127:     pACB->pActiveDCB = NULL;
                   1128:     pACB->pFreeSRB = pACB->SRB_array;
                   1129:     pACB->SRBCount = MAX_SRB_CNT;
                   1130:     pACB->AdapterIndex = index;
                   1131:     pACB->status = 0;
                   1132:     pACB->AdaptSCSIID = eepromBuf[index][EE_ADAPT_SCSI_ID];
                   1133:     pACB->HostID_Bit = (1 << pACB->AdaptSCSIID);
                   1134:     pACB->AdaptSCSILUN = 0;
                   1135:     pACB->DeviceCnt = 0;
                   1136:     pACB->IRQLevel = Irq;
                   1137:     pACB->TagMaxNum = eepromBuf[index][EE_TAG_CMD_NUM] << 2;
                   1138:     pACB->ACBFlag = 0;
                   1139:     pACB->scan_devices = 1;
                   1140:     pACB->Gmode2 = eepromBuf[index][EE_MODE2];
                   1141:     if( eepromBuf[index][EE_MODE2] & LUN_CHECK )
                   1142:        pACB->LUNchk = 1;
                   1143:     pACB->pDCB_free = &pACB->DCB_array[0];
                   1144:     DC390_linkSRB( pACB );
                   1145:     pACB->pTmpSRB = &pACB->TmpSRB;
                   1146:     DC390_initSRB( pACB->pTmpSRB );
                   1147:     for(i=0; i<MAX_SCSI_ID; i++)
                   1148:        pACB->DCBmap[i] = 0;
                   1149: }
                   1150: 
                   1151: 
                   1152: /***********************************************************************
                   1153:  * Function : static int DC390_initAdapter
                   1154:  *
                   1155:  * Purpose :  initialize the SCSI chip ctrl registers
                   1156:  *
                   1157:  * Inputs : psh - pointer to this host adapter's structure
                   1158:  *
                   1159:  ***********************************************************************/
                   1160: int DC390_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index )
                   1161: {
                   1162:     USHORT ioport;
                   1163:     UCHAR  bval;
                   1164:     PACB   pACB, pacb;
                   1165:     USHORT used_irq = 0;
                   1166: 
                   1167:     pacb = pACB_start;
                   1168:     if( pacb != NULL )
                   1169:     {
                   1170:        for ( ; (pacb != (PACB) -1) ; )
                   1171:        {
                   1172:            if( pacb->IRQLevel == Irq )
                   1173:            {
                   1174:                used_irq = 1;
                   1175:                break;
                   1176:            }
                   1177:            else
                   1178:                pacb = pacb->pNextACB;
                   1179:        }
                   1180:     }
                   1181: 
                   1182:     if( !used_irq )
                   1183:     {
                   1184: #ifdef VERSION_ELF_1_2_13
                   1185:        if( request_irq(Irq, DC390_Interrupt, SA_INTERRUPT, "tmscsim"))
                   1186: #else
                   1187:        if( request_irq(Irq, DC390_Interrupt, SA_INTERRUPT | SA_SHIRQ, "tmscsim", NULL))
                   1188: #endif
                   1189:        {
                   1190:            printk("DC390: register IRQ error!\n");
                   1191:            return( -1 );
                   1192:        }
                   1193:     }
                   1194: 
                   1195:     request_region(io_port,psh->n_io_port,"tmscsim");
                   1196: 
                   1197:     ioport = (USHORT) io_port;
                   1198: 
                   1199:     pACB = (PACB) psh->hostdata;
                   1200:     bval = SEL_TIMEOUT;                /* 250ms selection timeout */
                   1201:     outb(bval,ioport+Scsi_TimeOut);
                   1202: 
                   1203:     bval = CLK_FREQ_40MHZ;             /* Conversion factor = 0 , 40MHz clock */
                   1204:     outb(bval,ioport+Clk_Factor);
                   1205: 
                   1206:     bval = NOP_CMD;                    /* NOP cmd - clear command register */
                   1207:     outb(bval,ioport+ScsiCmd);
                   1208: 
                   1209:     bval = EN_FEATURE+EN_SCSI2_CMD;    /* Enable Feature and SCSI-2 */
                   1210:     outb(bval,ioport+CtrlReg2);
                   1211: 
                   1212:     bval = FAST_CLK;                   /* fast clock */
                   1213:     outb(bval,ioport+CtrlReg3);
                   1214: 
                   1215:     bval = EATER_25NS;
                   1216:     if( eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION )
                   1217:         bval |= NEGATE_REQACKDATA;
                   1218:     outb(bval,ioport+CtrlReg4);
                   1219: 
                   1220:     bval = DIS_INT_ON_SCSI_RST;        /* Disable SCSI bus reset interrupt */
                   1221:     outb(bval,ioport+CtrlReg1);
                   1222: 
                   1223:     return(0);
                   1224: }
                   1225: 
                   1226: 
                   1227: void
                   1228: DC390_EnableCfg( USHORT mechnum, UCHAR regval )
                   1229: {
                   1230:     ULONG wlval;
                   1231: 
                   1232:     if(mechnum == 2)
                   1233:     {
                   1234:        outb(mech2bus, PCI_CFG2_FORWARD_REG);
                   1235:        outb(mech2CfgSPenR, PCI_CFG2_ENABLE_REG);
                   1236:     }
                   1237:     else
                   1238:     {
                   1239:        regval &= 0xFC;
                   1240:        wlval = mech1addr;
                   1241:        wlval |= (((ULONG)regval) & 0xff);
                   1242:        outl(wlval, PCI_CFG1_ADDRESS_REG);
                   1243:     }
                   1244: }
                   1245: 
                   1246: 
                   1247: void
                   1248: DC390_DisableCfg( USHORT mechnum )
                   1249: {
                   1250: 
                   1251:     if(mechnum == 2)
                   1252:        outb(0, PCI_CFG2_ENABLE_REG);
                   1253:     else
                   1254:        outl(0, PCI_CFG1_ADDRESS_REG);
                   1255: }
                   1256: 
                   1257: 
                   1258: UCHAR
                   1259: DC390_inByte( USHORT mechnum, UCHAR regval )
                   1260: {
                   1261:     UCHAR bval;
                   1262:     ULONG wval;
                   1263:     ULONG flags;
                   1264: 
                   1265:     save_flags(flags);
                   1266:     cli();
                   1267:     DC390_EnableCfg( mechnum, regval );
                   1268:     if(mechnum == 2)
                   1269:     {
                   1270:        wval = mech2Agent;
                   1271:        wval <<= 8;
                   1272:        wval |= ((USHORT) regval) & 0xff;
                   1273:        bval = inb(wval);
                   1274:     }
                   1275:     else
                   1276:     {
                   1277:        regval &= 3;
                   1278:        bval = inb(PCI_CFG1_DATA_REG | regval);
                   1279:     }
                   1280:     DC390_DisableCfg(mechnum);
                   1281:     restore_flags(flags);
                   1282:     return(bval);
                   1283: }
                   1284: 
                   1285: 
                   1286: USHORT
                   1287: DC390_inWord( USHORT mechnum, UCHAR regval )
                   1288: {
                   1289:     USHORT wval;
                   1290:     ULONG flags;
                   1291: 
                   1292:     save_flags(flags);
                   1293:     cli();
                   1294:     DC390_EnableCfg(mechnum,regval);
                   1295:     if(mechnum == 2)
                   1296:     {
                   1297:        wval = mech2Agent;
                   1298:        wval <<= 8;
                   1299:        wval |= regval;
                   1300:        wval = inw(wval);
                   1301:     }
                   1302:     else
                   1303:     {
                   1304:        regval &= 3;
                   1305:        wval = inw(PCI_CFG1_DATA_REG | regval);
                   1306:     }
                   1307:     DC390_DisableCfg(mechnum);
                   1308:     restore_flags(flags);
                   1309:     return(wval);
                   1310: }
                   1311: 
                   1312: 
                   1313: ULONG
                   1314: DC390_inDword(USHORT mechnum, UCHAR regval )
                   1315: {
                   1316:     ULONG wlval;
                   1317:     ULONG flags;
                   1318:     USHORT wval;
                   1319: 
                   1320:     save_flags(flags);
                   1321:     cli();
                   1322:     DC390_EnableCfg(mechnum,regval);
                   1323:     if(mechnum == 2)
                   1324:     {
                   1325:        wval = mech2Agent;
                   1326:        wval <<= 8;
                   1327:        wval |= regval;
                   1328:        wlval = inl(wval);
                   1329:     }
                   1330:     else
                   1331:     {
                   1332:        wlval = inl(PCI_CFG1_DATA_REG);
                   1333:     }
                   1334:     DC390_DisableCfg(mechnum);
                   1335:     restore_flags(flags);
                   1336:     return(wlval);
                   1337: }
                   1338: 
                   1339: 
                   1340: void
                   1341: DC390_OutB(USHORT mechnum, UCHAR regval, UCHAR bval )
                   1342: {
                   1343: 
                   1344:     USHORT wval;
                   1345:     ULONG  flags;
                   1346: 
                   1347:     save_flags(flags);
                   1348:     cli();
                   1349:     DC390_EnableCfg(mechnum,regval);
                   1350:     if(mechnum == 2)
                   1351:     {
                   1352:        wval = mech2Agent;
                   1353:        wval <<= 8;
                   1354:        wval |= regval;
                   1355:        outb(bval, wval);
                   1356:     }
                   1357:     else
                   1358:     {
                   1359:        regval &= 3;
                   1360:        outb(bval, PCI_CFG1_DATA_REG | regval);
                   1361:     }
                   1362:     DC390_DisableCfg(mechnum);
                   1363:     restore_flags(flags);
                   1364: }
                   1365: 
                   1366: 
                   1367: void
                   1368: DC390_EnDisableCE( UCHAR mode, USHORT mechnum, PUCHAR regval )
                   1369: {
                   1370: 
                   1371:     UCHAR bval;
                   1372: 
                   1373:     bval = 0;
                   1374:     if(mode == ENABLE_CE)
                   1375:        *regval = 0xc0;
                   1376:     else
                   1377:        *regval = 0x80;
                   1378:     DC390_OutB(mechnum,*regval,bval);
                   1379:     if(mode == DISABLE_CE)
                   1380:        DC390_OutB(mechnum,*regval,bval);
                   1381:     udelay(160);
                   1382: }
                   1383: 
                   1384: 
                   1385: void
                   1386: DC390_EEpromOutDI( USHORT mechnum, PUCHAR regval, USHORT Carry )
                   1387: {
                   1388:     UCHAR bval;
                   1389: 
                   1390:     bval = 0;
                   1391:     if(Carry)
                   1392:     {
                   1393:        bval = 0x40;
                   1394:        *regval = 0x80;
                   1395:        DC390_OutB(mechnum,*regval,bval);
                   1396:     }
                   1397:     udelay(160);
                   1398:     bval |= 0x80;
                   1399:     DC390_OutB(mechnum,*regval,bval);
                   1400:     udelay(160);
                   1401:     bval = 0;
                   1402:     DC390_OutB(mechnum,*regval,bval);
                   1403:     udelay(160);
                   1404: }
                   1405: 
                   1406: 
                   1407: UCHAR
                   1408: DC390_EEpromInDO( USHORT mechnum )
                   1409: {
                   1410:     UCHAR bval,regval;
                   1411: 
                   1412:     regval = 0x80;
                   1413:     bval = 0x80;
                   1414:     DC390_OutB(mechnum,regval,bval);
                   1415:     udelay(160);
                   1416:     bval = 0x40;
                   1417:     DC390_OutB(mechnum,regval,bval);
                   1418:     udelay(160);
                   1419:     regval = 0x0;
                   1420:     bval = DC390_inByte(mechnum,regval);
                   1421:     if(bval == 0x22)
                   1422:        return(1);
                   1423:     else
                   1424:        return(0);
                   1425: }
                   1426: 
                   1427: 
                   1428: USHORT
                   1429: EEpromGetData1( USHORT mechnum )
                   1430: {
                   1431:     UCHAR i;
                   1432:     UCHAR carryFlag;
                   1433:     USHORT wval;
                   1434: 
                   1435:     wval = 0;
                   1436:     for(i=0; i<16; i++)
                   1437:     {
                   1438:        wval <<= 1;
                   1439:        carryFlag = DC390_EEpromInDO(mechnum);
                   1440:        wval |= carryFlag;
                   1441:     }
                   1442:     return(wval);
                   1443: }
                   1444: 
                   1445: 
                   1446: void
                   1447: DC390_Prepare( USHORT mechnum, PUCHAR regval, UCHAR EEpromCmd )
                   1448: {
                   1449:     UCHAR i,j;
                   1450:     USHORT carryFlag;
                   1451: 
                   1452:     carryFlag = 1;
                   1453:     j = 0x80;
                   1454:     for(i=0; i<9; i++)
                   1455:     {
                   1456:        DC390_EEpromOutDI(mechnum,regval,carryFlag);
                   1457:        carryFlag = (EEpromCmd & j) ? 1 : 0;
                   1458:        j >>= 1;
                   1459:     }
                   1460: }
                   1461: 
                   1462: 
                   1463: void
                   1464: DC390_ReadEEprom( USHORT mechnum, USHORT index )
                   1465: {
                   1466:     UCHAR   regval,cmd;
                   1467:     PUSHORT ptr;
                   1468:     USHORT  i;
                   1469: 
                   1470:     ptr = (PUSHORT) &eepromBuf[index][0];
                   1471:     cmd = EEPROM_READ;
                   1472:     for(i=0; i<0x40; i++)
                   1473:     {
                   1474:        DC390_EnDisableCE(ENABLE_CE, mechnum, &regval);
                   1475:        DC390_Prepare(mechnum, &regval, cmd);
                   1476:        *ptr = EEpromGetData1(mechnum);
                   1477:        ptr++;
                   1478:        cmd++;
                   1479:        DC390_EnDisableCE(DISABLE_CE,mechnum,&regval);
                   1480:     }
                   1481: }
                   1482: 
                   1483: 
                   1484: USHORT
                   1485: DC390_CheckEEpromCheckSum( USHORT MechNum, USHORT index )
                   1486: {
                   1487:     USHORT wval, rc, *ptr;
                   1488:     UCHAR  i;
                   1489: 
                   1490:     DC390_ReadEEprom( MechNum, index );
                   1491:     wval = 0;
                   1492:     ptr = (PUSHORT) &eepromBuf[index][0];
                   1493:     for(i=0; i<128 ;i+=2, ptr++)
                   1494:        wval += *ptr;
                   1495:     if( wval == 0x1234 )
                   1496:        rc = 0;
                   1497:     else
                   1498:        rc = -1;
                   1499:     return( rc );
                   1500: }
                   1501: 
                   1502: 
                   1503: USHORT
                   1504: DC390_ToMech( USHORT Mechnum, USHORT BusDevFunNum )
                   1505: {
                   1506:     USHORT devnum;
                   1507: 
                   1508:     devnum = BusDevFunNum;
                   1509: 
                   1510:     if(Mechnum == 2)
                   1511:     {
                   1512:        if(devnum & 0x80)
                   1513:             return(-1);
                   1514:        mech2bus = (UCHAR)((devnum & 0xff00) >> 8);       /* Bus num */
                   1515:        mech2Agent = ((UCHAR)(devnum & 0xff)) >> 3;       /* Dev num */
                   1516:        mech2Agent |= 0xc0;
                   1517:        mech2CfgSPenR = ((UCHAR)(devnum & 0xff)) & 0x07;  /* Fun num */
                   1518:        mech2CfgSPenR = (mech2CfgSPenR << 1) | 0x20;
                   1519:     }
                   1520:     else       /* use mech #1 method */
                   1521:     {
                   1522:        mech1addr = 0x80000000 | ((ULONG)devnum << 8);
                   1523:     }
                   1524:     return(0);
                   1525: }
                   1526: 
                   1527: /***********************************************************************
                   1528:  * Function : static int DC390_init (struct Scsi_Host *host)
                   1529:  *
                   1530:  * Purpose :  initialize the internal structures for a given SCSI host
                   1531:  *
                   1532:  * Inputs : host - pointer to this host adapter's structure/
                   1533:  *
                   1534:  * Preconditions : when this function is called, the chip_type
                   1535:  *     field of the pACB structure MUST have been set.
                   1536:  ***********************************************************************/
                   1537: 
                   1538: static int
                   1539: DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, USHORT index, USHORT MechNum)
                   1540: {
                   1541:     PSH   psh;
                   1542:     PACB  pACB;
                   1543: 
                   1544:     if( !DC390_CheckEEpromCheckSum( MechNum, index) )
                   1545:     {
                   1546:        psh = scsi_register( psht, sizeof(DC390_ACB) );
                   1547:        if( !psh )
                   1548:            return( -1 );
                   1549:        if( !pSH_start )
                   1550:        {
                   1551:            pSH_start = psh;
                   1552:            pSH_current = psh;
                   1553:        }
                   1554:        else
                   1555:        {
                   1556:            pSH_current->next = psh;
                   1557:            pSH_current = psh;
                   1558:        }
                   1559: 
                   1560: #ifdef DC390_DEBUG0
                   1561:        printk("DC390: pSH = %8x,", (UINT) psh);
                   1562:        printk("DC390: Index %02i,", index);
                   1563: #endif
                   1564: 
                   1565:        DC390_initACB( psh, io_port, Irq, index );
                   1566:        if( !DC390_initAdapter( psh, io_port, Irq, index ) )
                   1567:        {
                   1568:            pACB = (PACB) psh->hostdata;
                   1569:            if( !pACB_start )
                   1570:            {
                   1571:                pACB_start = pACB;
                   1572:                pACB_current = pACB;
                   1573:                pACB->pNextACB = (PACB) -1;
                   1574:            }
                   1575:            else
                   1576:            {
                   1577:                pACB_current->pNextACB = pACB;
                   1578:                pACB_current = pACB;
                   1579:                pACB->pNextACB = (PACB)  -1;
                   1580:            }
                   1581: 
                   1582: #ifdef DC390_DEBUG0
                   1583:        printk("DC390: pACB = %8x, pDCB_array = %8x, pSRB_array = %8x\n",
                   1584:              (UINT) pACB, (UINT) pACB->DCB_array, (UINT) pACB->SRB_array);
                   1585:        printk("DC390: ACB size= %4x, DCB size= %4x, SRB size= %4x\n",
                   1586:              sizeof(DC390_ACB), sizeof(DC390_DCB), sizeof(DC390_SRB) );
                   1587: #endif
                   1588: 
                   1589:        }
                   1590:        else
                   1591:        {
                   1592:            pSH_start = NULL;
                   1593:            scsi_unregister( psh );
                   1594:            return( -1 );
                   1595:        }
                   1596:        return( 0 );
                   1597:     }
                   1598:     else
                   1599:     {
                   1600:        printk("DC390_init: EEPROM reading error!\n");
                   1601:        return( -1 );
                   1602:     }
                   1603: }
                   1604: 
                   1605: 
                   1606: /***********************************************************************
                   1607:  * Function : int DC390_detect(Scsi_Host_Template *psht)
                   1608:  *
                   1609:  * Purpose : detects and initializes AMD53C974 SCSI chips
                   1610:  *          that were autoprobed, overridden on the LILO command line,
                   1611:  *          or specified at compile time.
                   1612:  *
                   1613:  * Inputs : psht - template for this SCSI adapter
                   1614:  *
                   1615:  * Returns : number of host adapters detected
                   1616:  *
                   1617:  ***********************************************************************/
                   1618: 
                   1619: int
                   1620: DC390_detect(Scsi_Host_Template *psht)
                   1621: {
                   1622: #ifdef FOR_PCI_OK
                   1623:     UCHAR   pci_bus, pci_device_fn;
                   1624:     int     error = 0;
                   1625:     USHORT  chipType = 0;
                   1626:     USHORT  i;
                   1627: #endif
                   1628: 
                   1629:     UCHAR   irq;
                   1630:     UCHAR   istatus;
                   1631: #ifndef VERSION_ELF_1_2_13
                   1632:     UINT    io_port;
                   1633: #else
                   1634:     ULONG   io_port;
                   1635: #endif
                   1636:     USHORT  adaptCnt = 0;      /* Number of boards detected */
                   1637:     USHORT  pci_index = 0;     /* Device index to PCI BIOS calls */
                   1638:     USHORT  MechNum, BusDevFunNum;
                   1639:     ULONG   wlval;
                   1640: 
                   1641: #ifndef VERSION_ELF_1_2_13
                   1642:     psht->proc_dir = &proc_scsi_tmscsim;
                   1643: #endif
                   1644: 
                   1645:     InitialTime = 1;
                   1646:     pSHT_start = psht;
                   1647:     pACB_start = NULL;
                   1648: 
                   1649:     MechNum = 1;
                   1650:     for( ; (MechNum < 3) && (!adaptCnt); MechNum++)
                   1651:     {
                   1652:        BusDevFunNum = 0;
                   1653:        for (; adaptCnt < MAX_ADAPTER_NUM ;)
                   1654:        {
                   1655:            if( !DC390_ToMech( MechNum, BusDevFunNum) )
                   1656:            {
                   1657:                 wlval = DC390_inDword( MechNum, PCI_VENDOR_ID);
                   1658:                 if(wlval == ( (PCI_DEVICE_ID_AMD53C974 << 16)+
                   1659:                                PCI_VENDOR_ID_AMD) )
                   1660:                 {
                   1661:                    io_port =DC390_inDword(MechNum,PCI_BASE_ADDRESS_0) & 0xFFFE;
                   1662:                    irq = DC390_inByte( MechNum, PCI_INTERRUPT_LINE);
                   1663: #ifdef DC390_DEBUG0
                   1664:                printk("DC390: IO_PORT=%4x,IRQ=%x,\n",(UINT) io_port, irq);
                   1665: #endif
                   1666:                    if( !DC390_init(psht, io_port, irq, pci_index, MechNum) )
                   1667:                    {
                   1668:                        adaptCnt++;
                   1669:                        pci_index++;
                   1670:                        istatus = inb( (USHORT)io_port+INT_Status );    /* Reset Pending INT */
                   1671: #ifdef DC390_DEBUG0
                   1672:                printk("DC390: Mech=%2x,\n",(UCHAR) MechNum);
                   1673: #endif
                   1674:                    }
                   1675:                 }
                   1676:            }
                   1677:            if( BusDevFunNum != 0xfff8 )
                   1678:                BusDevFunNum += 8;          /* next device # */
                   1679:            else
                   1680:                break;
                   1681:        }
                   1682:     }
                   1683: 
                   1684: #ifdef FOR_PCI_OK
                   1685:     if ( pcibios_present() )
                   1686:     {
                   1687:        for (i = 0; i < MAX_ADAPTER_NUM; ++i)
                   1688:        {
                   1689:            if( !pcibios_find_device( PCI_VENDOR_ID_AMD,
                   1690:                                PCI_DEVICE_ID_AMD53C974,
                   1691:                                pci_index, &pci_bus, &pci_device_fn) )
                   1692:            {
                   1693:                chipType = PCI_DEVICE_ID_AMD53C974;
                   1694:                pci_index++;
                   1695:            }
                   1696: 
                   1697:            if( chipType )
                   1698:            {
                   1699: 
                   1700:                error = pcibios_read_config_dword(pci_bus, pci_device_fn,
                   1701:                                                  PCI_BASE_ADDRESS_0, &io_port);
                   1702:                error |= pcibios_read_config_byte(pci_bus, pci_device_fn,
                   1703:                                                  PCI_INTERRUPT_LINE, &irq);
                   1704:                if( error )
                   1705:                {
                   1706:                    printk("DC390_detect: reading configuration registers error!\n");
                   1707:                    InitialTime = 0;
                   1708:                    return( 0 );
                   1709:                }
                   1710: 
                   1711:                (USHORT) io_port = (USHORT) io_port & 0xFFFE;
                   1712: #ifdef DC390_DEBUG0
                   1713:                printk("DC390: IO_PORT=%4x,IRQ=%x,\n",(UINT) io_port, irq);
                   1714: #endif
                   1715:                if( !DC390_init(psht, io_port, irq, i) )
                   1716:                    adaptCnt++;
                   1717:                chipType = 0;
                   1718:            }
                   1719:            else
                   1720:                break;
                   1721:        }
                   1722:     }
                   1723: #endif
                   1724: 
                   1725:     InitialTime = 0;
                   1726:     adapterCnt = adaptCnt;
                   1727:     return( adaptCnt );
                   1728: }
                   1729: 
                   1730: 
                   1731: #ifndef VERSION_ELF_1_2_13
                   1732: 
                   1733: /********************************************************************
                   1734:  * Function: tmscsim_set_info()
                   1735:  *
                   1736:  * Purpose: Set adapter info (!)
                   1737:  *
                   1738:  * Not yet implemented
                   1739:  *
                   1740:  *******************************************************************/
                   1741: 
                   1742: int tmscsim_set_info(char *buffer, int length, struct Scsi_Host *shpnt)
                   1743: {
                   1744:   return(-ENOSYS);  /* Currently this is a no-op */
                   1745: }
                   1746: 
                   1747: /********************************************************************
                   1748:  * Function: tmscsim_proc_info(char* buffer, char **start,
                   1749:  *                          off_t offset, int length, int hostno, int inout)
                   1750:  *
                   1751:  * Purpose: return SCSI Adapter/Device Info
                   1752:  *
                   1753:  * Input: buffer: Pointer to a buffer where to write info
                   1754:  *       start :
                   1755:  *       offset:
                   1756:  *       hostno: Host adapter index
                   1757:  *       inout : Read (=0) or set(!=0) info
                   1758:  *
                   1759:  * Output: buffer: contains info
                   1760:  *        length; length of info in buffer
                   1761:  *
                   1762:  * return value: length
                   1763:  *
                   1764:  ********************************************************************/
                   1765: 
                   1766: /* KG: proc_info taken from driver aha152x.c */
                   1767: 
                   1768: #undef SPRINTF
                   1769: #define SPRINTF(args...) pos += sprintf(pos, ## args)
                   1770: 
                   1771: #define YESNO(YN)\
                   1772: if (YN) SPRINTF(" Yes ");\
                   1773: else SPRINTF(" No  ")
                   1774: 
                   1775: int tmscsim_proc_info(char *buffer, char **start,
                   1776:                      off_t offset, int length, int hostno, int inout)
                   1777: {
                   1778:   int dev, spd, spd1;
                   1779:   char *pos = buffer;
                   1780:   PSH shpnt;
                   1781:   PACB acbpnt;
                   1782:   PDCB dcbpnt;
                   1783:   unsigned long flags;
                   1784: /*  Scsi_Cmnd *ptr; */
                   1785: 
                   1786:   acbpnt = pACB_start;
                   1787: 
                   1788:   while(acbpnt != (PACB)-1)
                   1789:      {
                   1790:        shpnt = acbpnt->pScsiHost;
                   1791:        if (shpnt->host_no == hostno) break;
                   1792:        acbpnt = acbpnt->pNextACB;
                   1793:      }
                   1794: 
                   1795:   if (acbpnt == (PACB)-1) return(-ESRCH);
                   1796:   if(!shpnt) return(-ESRCH);
                   1797: 
                   1798:   if(inout) /* Has data been written to the file ? */
                   1799:     return(tmscsim_set_info(buffer, length, shpnt));
                   1800: 
                   1801:   SPRINTF("Tekram DC390(T) PCI SCSI Host Adadpter, ");
                   1802:   SPRINTF("Driver Version 1.10, 1996/12/05\n");
                   1803: 
                   1804:   save_flags(flags);
                   1805:   cli();
                   1806: 
                   1807:   SPRINTF("SCSI Host Nr %i, ", shpnt->host_no);
                   1808:   SPRINTF("DC390 Adapter Nr %i\n", acbpnt->AdapterIndex);
                   1809:   SPRINTF("IOPortBase 0x%04x, ", acbpnt->IOPortBase);
                   1810:   SPRINTF("IRQLevel 0x%02x\n", acbpnt->IRQLevel);
                   1811: 
                   1812:   SPRINTF("MaxID %i, MaxLUN %i, ",acbpnt->max_id, acbpnt->max_lun);
                   1813:   SPRINTF("AdapterID %i, AdapterLUN %i\n", acbpnt->AdaptSCSIID, acbpnt->AdaptSCSILUN);
                   1814: 
                   1815:   SPRINTF("TagMaxNum %i, Status %i\n", acbpnt->TagMaxNum, acbpnt->status);
                   1816: 
                   1817:   SPRINTF("Nr of attached devices: %i\n", acbpnt->DeviceCnt);
                   1818: 
                   1819:   SPRINTF("Un ID LUN Prty Sync DsCn SndS TagQ NegoPeriod SyncSpeed SyncOffs\n");
                   1820: 
                   1821:   dcbpnt = acbpnt->pLinkDCB;
                   1822:   for (dev = 0; dev < acbpnt->DeviceCnt; dev++)
                   1823:      {
                   1824:       SPRINTF("%02i %02i  %02i ", dev, dcbpnt->UnitSCSIID, dcbpnt->UnitSCSILUN);
                   1825:       YESNO(dcbpnt->DevMode & PARITY_CHK_);
                   1826:       YESNO(dcbpnt->SyncMode & SYNC_NEGO_DONE);
                   1827:       YESNO(dcbpnt->DevMode & EN_DISCONNECT_);
                   1828:       YESNO(dcbpnt->DevMode & SEND_START_);
                   1829:       YESNO(dcbpnt->SyncMode & EN_TAG_QUEUING);
                   1830:       SPRINTF("  %03i ns ", (dcbpnt->NegoPeriod) << 2);
                   1831:       if (dcbpnt->SyncOffset & 0x0f)
                   1832:       {
                   1833:         spd = 1000/(dcbpnt->NegoPeriod <<2);
                   1834:         spd1 = 1000%(dcbpnt->NegoPeriod <<2);
                   1835:         spd1 = (spd1 * 10)/(dcbpnt->NegoPeriod <<2);
                   1836:         SPRINTF("   %2i.%1i M      %02i\n", spd, spd1, (dcbpnt->SyncOffset & 0x0f));
                   1837:       }
                   1838:       else SPRINTF("\n");
                   1839:       /* Add more info ...*/
                   1840:       dcbpnt = dcbpnt->pNextDCB;
                   1841:      }
                   1842: 
                   1843:   restore_flags(flags);
                   1844:   *start = buffer + offset;
                   1845: 
                   1846:   if (pos - buffer < offset)
                   1847:     return 0;
                   1848:   else if (pos - buffer - offset < length)
                   1849:     return pos - buffer - offset;
                   1850:   else
                   1851:     return length;
                   1852: }
                   1853: #endif /* VERSION_ELF_1_2_13 */
                   1854: 
                   1855: 
                   1856: #ifdef MODULE
                   1857: 
                   1858: /***********************************************************************
                   1859:  * Function : static int DC390_shutdown (struct Scsi_Host *host)
                   1860:  *
                   1861:  * Purpose : does a clean (we hope) shutdown of the SCSI chip.
                   1862:  *          Use prior to dumping core, unloading the driver, etc.
                   1863:  *
                   1864:  * Returns : 0 on success
                   1865:  ***********************************************************************/
                   1866: static int
                   1867: DC390_shutdown (struct Scsi_Host *host)
                   1868: {
                   1869:     UCHAR    bval;
                   1870:     USHORT   ioport;
                   1871:     unsigned long flags;
                   1872:     PACB pACB = (PACB)(host->hostdata);
                   1873: 
                   1874:     ioport = (unsigned int) pACB->IOPortBase;
                   1875: 
                   1876:     save_flags (flags);
                   1877:     cli();
                   1878: 
                   1879: /*  pACB->soft_reset(host); */
                   1880: 
                   1881: #ifdef DC390_DEBUG0
                   1882:     printk("DC390: shutdown,");
                   1883: #endif
                   1884: 
                   1885:     bval = inb(ioport+CtrlReg1);
                   1886:     bval |= DIS_INT_ON_SCSI_RST;
                   1887:     outb(bval,ioport+CtrlReg1);  /* disable interrupt */
                   1888:     DC390_ResetSCSIBus( pACB );
                   1889: 
                   1890:     restore_flags (flags);
                   1891:     return( 0 );
                   1892: }
                   1893: 
                   1894: 
                   1895: int DC390_release(struct Scsi_Host *host)
                   1896: {
                   1897:     int irq_count;
                   1898:     struct Scsi_Host *tmp;
                   1899: 
                   1900:     DC390_shutdown (host);
                   1901: 
                   1902:     if (host->irq != IRQ_NONE)
                   1903:     {
                   1904:        for (irq_count = 0, tmp = pSH_start; tmp; tmp = tmp->next)
                   1905:        {
                   1906:            if ( tmp->irq == host->irq )
                   1907:                ++irq_count;
                   1908:        }
                   1909:        if (irq_count == 1)
                   1910:         {
                   1911: #ifdef DC390_DEBUG0
                   1912:            printk("DC390: Free IRQ %i.",host->irq);
                   1913: #endif
                   1914: #ifndef VERSION_ELF_1_2_13
                   1915:            free_irq(host->irq,NULL);
                   1916: #else
                   1917:            free_irq(host->irq);
                   1918: #endif
                   1919:         }
                   1920:     }
                   1921: 
                   1922:     release_region(host->io_port,host->n_io_port);
                   1923: 
                   1924:     return( 1 );
                   1925: }
                   1926: 
                   1927: Scsi_Host_Template driver_template = DC390_T;
                   1928: #include "scsi_module.c"
                   1929: #endif /* def MODULE */
                   1930: 

unix.superglobalmegacorp.com

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