Annotation of Gnu-Mach/linux/src/drivers/scsi/tmscsim.c, revision 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.