Annotation of Gnu-Mach/linux/src/drivers/scsi/tmscsiw.c, revision 1.1

1.1     ! root        1: /***********************************************************************
        !             2:  *     FILE NAME : TMSCSIW.C                                          *
        !             3:  *          BY   : C.L. Huang    ([email protected])                *
        !             4:  *     Description: Device Driver for Tekram DC-390W/U/F (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/03/96  CLH     First release                           *
        !            15:  *     1.01  04/11/96  CLH     Maximum support up to 4 Adapters,       *
        !            16:  *                             support KV 1_3_85                       *
        !            17:  *     1.02  04/26/96  CLH     fixed bug about EEpromBuf when >1 HA    *
        !            18:  *     1.03  06/12/96  CLH     fixed bug of Media Change for Removable *
        !            19:  *                             Device, scan all LUN. Support Pre2.0.10 *
        !            20:  *     1.04  06/18/96  CLH     fixed bug of Command timeout ....       *
        !            21:  *     1.05  10/04/96  CLH     Updating for support KV 2.0.0, 2.0.20   *
        !            22:  *     1.06  10/30/96  KG      Fixed bug in DC390W_abort(), module     *
        !            23:  *                             support, added tmscsiw_proc_info()      *
        !            24:  *     1.07  11/09/96  KG      Fixed bug in tmscsiw_proc_info()        *
        !            25:  *     1.08  11/18/96  CLH/KG  ditto, null ptr in DC390W_Disconnect()  *
        !            26:  *     1.09  11/30/96  KG      Fixed bug in CheckEEpromCheckSum(),     *
        !            27:  *                             add register the allocated IO space     *
        !            28:  *     1.10  12/05/96  CLH     Modify in tmscsiw_proc_info() and add   *
        !            29:  *                             in DC390W_initAdapter() for 53C875      *
        !            30:  *                             Rev. F with double clock.               *
        !            31:  *     1.11  02/04/97  CLH     Fixed bug of Formatting a partition that*
        !            32:  *                             across 1GB boundary, with bad sector    *
        !            33:  *                             checking.                               *
        !            34:  *     1.12  02/17/97  CLH     Fixed bug in CheckEEpromCheckSum()      *
        !            35:  ***********************************************************************/
        !            36: 
        !            37: 
        !            38: #define DC390W_DEBUG
        !            39: /* #define CHK_UNDER_RUN */
        !            40: 
        !            41: #define SCSI_MALLOC
        !            42: 
        !            43: #ifdef MODULE
        !            44: #include <linux/module.h>
        !            45: #endif
        !            46: 
        !            47: #include <asm/dma.h>
        !            48: #include <asm/io.h>
        !            49: #include <asm/system.h>
        !            50: #include <linux/delay.h>
        !            51: #include <linux/signal.h>
        !            52: #include <linux/sched.h>
        !            53: #include <linux/errno.h>
        !            54: #include <linux/kernel.h>
        !            55: #include <linux/ioport.h>
        !            56: #include <linux/bios32.h>
        !            57: #include <linux/pci.h>
        !            58: #include <linux/proc_fs.h>
        !            59: #include <linux/string.h>
        !            60: #include <linux/mm.h>
        !            61: #include <linux/config.h>
        !            62: 
        !            63: #include <linux/version.h>
        !            64: #if LINUX_VERSION_CODE < 66354 /* 1.3.50 */
        !            65: #include "../block/blk.h"
        !            66: #else
        !            67: #include <linux/blk.h>
        !            68: #endif
        !            69: 
        !            70: #include "scsi.h"
        !            71: #include "hosts.h"
        !            72: #include "tmscsiw.h"
        !            73: #include "constants.h"
        !            74: #include "sd.h"
        !            75: #include "scripts.h"
        !            76: #include <linux/stat.h>
        !            77: 
        !            78: #include "dc390w.h"
        !            79: 
        !            80: #ifndef VERSION_ELF_1_2_13
        !            81: struct proc_dir_entry  proc_scsi_tmscsiw ={
        !            82:        PROC_SCSI_DC390WUF, 7 ,"tmscsiw",
        !            83:        S_IFDIR | S_IRUGO | S_IXUGO, 2
        !            84:        };
        !            85: #endif
        !            86: 
        !            87: static void DC390W_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB );
        !            88: static void PrepareSG( PACB pACB, PDCB pDCB, PSRB pSRB );
        !            89: static void DoingSRB_Done( PACB pACB );
        !            90: static void ExceptionHandler(ULONG wlval, PACB pACB, PDCB pDCB);
        !            91: static void ParityError( PACB pACB, PDCB pDCB );
        !            92: static void PhaseMismatch( PACB pACB );
        !            93: static void DC390W_ScsiRstDetect( PACB pACB );
        !            94: static void DC390W_ResetSCSIBus( PACB pACB );
        !            95: static void DC390W_ResetSCSIBus2( PACB pACB );
        !            96: static void AdjustTemp( PACB pACB, PDCB pDCB, PSRB pSRB );
        !            97: static void SetXferRate( PACB pACB, PDCB pDCB );
        !            98: static void DataIOcommon( PACB pACB, ULONG  Swlval, ULONG  Cwlval );
        !            99: static void SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB );
        !           100: static void RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB );
        !           101: 
        !           102: static void DC390W_CmdCompleted( PACB pACB );
        !           103: static void DC390W_Reselected( PACB pACB );
        !           104: static void DC390W_Reselected1( PACB pACB );
        !           105: static void DC390W_ReselectedT( PACB pACB );
        !           106: static void DC390W_Disconnected( PACB pACB );
        !           107: static void DC390W_MessageExtnd( PACB pACB );
        !           108: static void DC390W_Signal( PACB pACB );
        !           109: static void DC390W_UnknownMsg( PACB pACB );
        !           110: static void DC390W_MessageOut( PACB pACB );
        !           111: static void DC390W_FatalError( PACB pACB );
        !           112: static void DC390W_MessageSync( PACB pACB );
        !           113: static void DC390W_MessageWide( PACB pACB );
        !           114: static void DC390W_RestorePtr( PACB pACB );
        !           115: static void DC390W_MsgReject( PACB pACB );
        !           116: static void DC390W_Debug( PACB pACB );
        !           117: static void DC390W_download_script (struct Scsi_Host *host);
        !           118: 
        !           119: int    DC390W_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index);
        !           120: void   DC390W_initDCB( PACB pACB, PDCB pDCB, PSCSICMD cmd );
        !           121: void   MyDelay( void );
        !           122: void   EnDisableCE( UCHAR Flag, USHORT scsiIOPort );
        !           123: void   EEpromOutDI( USHORT Carry, USHORT scsiIOPort );
        !           124: void   EEpromPrepare( UCHAR EEpromCmd, USHORT scsiIOPort );
        !           125: void   ReadEEprom( PUCHAR EEpromBuf, USHORT scsiIOPort );
        !           126: UCHAR  EEpromInDo(USHORT scsiIOPort);
        !           127: USHORT EEpromGetData(USHORT scsiIOPort);
        !           128: USHORT CheckEEpromCheckSum( PUCHAR EEpromBuf, USHORT scsiIOPort);
        !           129: 
        !           130: #ifdef MODULE
        !           131: static int DC390W_release(struct Scsi_Host *host);
        !           132: static int DC390W_shutdown (struct Scsi_Host *host);
        !           133: #endif
        !           134: 
        !           135: 
        !           136: static ULONG   jmp_table16;
        !           137: static ULONG   jmp_din16;
        !           138: static ULONG   jmp_dout16;
        !           139: static PSHT    pSHT_start = NULL;
        !           140: static PSH     pSH_start = NULL;
        !           141: static PSH     pSH_current = NULL;
        !           142: static PACB    pACB_start= NULL;
        !           143: static PACB    pACB_current = NULL;
        !           144: static PDCB    pPrevDCB = NULL;
        !           145: static USHORT  adapterCnt = 0;
        !           146: static USHORT  InitialTime = 0;
        !           147: static USHORT  CurrDCBscntl3 = 0;
        !           148: static UCHAR   pad_buffer[128];
        !           149: 
        !           150: static PVOID IntVector[]={
        !           151:        DC390W_CmdCompleted,
        !           152:        DC390W_Reselected,
        !           153:        DC390W_Reselected1,
        !           154:        DC390W_ReselectedT,
        !           155:        DC390W_Disconnected,
        !           156:        DC390W_MessageExtnd,
        !           157:        DC390W_Signal,
        !           158:        DC390W_UnknownMsg,
        !           159:        DC390W_MessageOut,
        !           160:        DC390W_FatalError,
        !           161:        DC390W_MessageSync,
        !           162:        DC390W_MessageWide,
        !           163:        DC390W_RestorePtr,
        !           164:        DC390W_MsgReject,
        !           165:        DC390W_Debug,
        !           166:        DC390W_FatalError
        !           167:        };
        !           168: 
        !           169: UCHAR  eepromBuf[MAX_ADAPTER_NUM][128];
        !           170: 
        !           171: UCHAR  clock_period[12] = {25, 31, 37, 43, 50, 62, 75, 125, 12, 15, 18, 21};
        !           172: UCHAR  baddevname[2][28] ={
        !           173:        "SEAGATE ST3390N         9546",
        !           174:        "SEAGATE ST3390N ???     0399"};
        !           175: 
        !           176: #define BADDEVCNT      2
        !           177: 
        !           178: /***********************************************************************
        !           179:  *
        !           180:  *
        !           181:  *
        !           182:  **********************************************************************/
        !           183: static void
        !           184: QLinkcmd( PSCSICMD cmd, PDCB pDCB )
        !           185: {
        !           186:     ULONG  flags;
        !           187:     PSCSICMD  pcmd;
        !           188: 
        !           189:     save_flags(flags);
        !           190:     cli();
        !           191: 
        !           192:     if( !pDCB->QIORBCnt )
        !           193:     {
        !           194:        pDCB->pQIORBhead = cmd;
        !           195:        pDCB->pQIORBtail = cmd;
        !           196:        pDCB->QIORBCnt++;
        !           197:        cmd->next = NULL;
        !           198:     }
        !           199:     else
        !           200:     {
        !           201:        pcmd = pDCB->pQIORBtail;
        !           202:        pcmd->next = cmd;
        !           203:        pDCB->pQIORBtail = cmd;
        !           204:        pDCB->QIORBCnt++;
        !           205:        cmd->next = NULL;
        !           206:     }
        !           207: 
        !           208:     restore_flags(flags);
        !           209: }
        !           210: 
        !           211: 
        !           212: static PSCSICMD
        !           213: Getcmd( PDCB pDCB )
        !           214: {
        !           215:     ULONG  flags;
        !           216:     PSCSICMD  pcmd;
        !           217: 
        !           218:     save_flags(flags);
        !           219:     cli();
        !           220: 
        !           221:     pcmd = pDCB->pQIORBhead;
        !           222:     pDCB->pQIORBhead = pcmd->next;
        !           223:     pcmd->next = NULL;
        !           224:     pDCB->QIORBCnt--;
        !           225: 
        !           226:     restore_flags(flags);
        !           227:     return( pcmd );
        !           228: }
        !           229: 
        !           230: 
        !           231: static PSRB
        !           232: GetSRB( PACB pACB )
        !           233: {
        !           234:     ULONG  flags;
        !           235:     PSRB   pSRB;
        !           236: 
        !           237:     save_flags(flags);
        !           238:     cli();
        !           239: 
        !           240:     pSRB = pACB->pFreeSRB;
        !           241:     if( pSRB )
        !           242:     {
        !           243:        pACB->pFreeSRB = pSRB->pNextSRB;
        !           244:        pSRB->pNextSRB = NULL;
        !           245:     }
        !           246:     restore_flags(flags);
        !           247:     return( pSRB );
        !           248: }
        !           249: 
        !           250: 
        !           251: static void
        !           252: RewaitSRB( PDCB pDCB, PSRB pSRB )
        !           253: {
        !           254:     PSRB   psrb1;
        !           255:     ULONG  flags;
        !           256:     UCHAR  bval;
        !           257: 
        !           258:     save_flags(flags);
        !           259:     cli();
        !           260:     pDCB->GoingSRBCnt--;
        !           261:     psrb1 = pDCB->pGoingSRB;
        !           262:     if( pSRB == psrb1 )
        !           263:     {
        !           264:        pDCB->pGoingSRB = psrb1->pNextSRB;
        !           265:     }
        !           266:     else
        !           267:     {
        !           268:        while( pSRB != psrb1->pNextSRB )
        !           269:            psrb1 = psrb1->pNextSRB;
        !           270:        psrb1->pNextSRB = pSRB->pNextSRB;
        !           271:        if( pSRB == pDCB->pGoingLast )
        !           272:            pDCB->pGoingLast = psrb1;
        !           273:     }
        !           274:     if( (psrb1 = pDCB->pWaitingSRB) )
        !           275:     {
        !           276:        pSRB->pNextSRB = psrb1;
        !           277:        pDCB->pWaitingSRB = pSRB;
        !           278:     }
        !           279:     else
        !           280:     {
        !           281:        pSRB->pNextSRB = NULL;
        !           282:        pDCB->pWaitingSRB = pSRB;
        !           283:        pDCB->pWaitLast = pSRB;
        !           284:     }
        !           285: 
        !           286:     bval = pSRB->TagNumber;
        !           287:     pDCB->TagMask &= (~(1 << bval));     /* Free TAG number */
        !           288:     restore_flags(flags);
        !           289: }
        !           290: 
        !           291: 
        !           292: static void
        !           293: DoWaitingSRB( PACB pACB )
        !           294: {
        !           295:     ULONG  flags;
        !           296:     PDCB   ptr, ptr1;
        !           297:     PSRB   pSRB;
        !           298: 
        !           299:     save_flags(flags);
        !           300:     cli();
        !           301: 
        !           302:     if( !(pACB->pActiveDCB) && !(pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) ) )
        !           303:     {
        !           304:        ptr = pACB->pDCBRunRobin;
        !           305:        if( !ptr )
        !           306:        {
        !           307:            ptr = pACB->pLinkDCB;
        !           308:            pACB->pDCBRunRobin = ptr;
        !           309:        }
        !           310:        ptr1 = ptr;
        !           311:        for( ;ptr1; )
        !           312:        {
        !           313:            pACB->pDCBRunRobin = ptr1->pNextDCB;
        !           314:            if( !( ptr1->MaxCommand > ptr1->GoingSRBCnt ) ||
        !           315:                !( pSRB = ptr1->pWaitingSRB ) )
        !           316:            {
        !           317:                if(pACB->pDCBRunRobin == ptr)
        !           318:                    break;
        !           319:                ptr1 = ptr1->pNextDCB;
        !           320:            }
        !           321:            else
        !           322:            {
        !           323:                DC390W_StartSCSI(pACB, ptr1, pSRB);
        !           324:                ptr1->GoingSRBCnt++;
        !           325:                if( ptr1->pWaitLast == pSRB )
        !           326:                {
        !           327:                    ptr1->pWaitingSRB = NULL;
        !           328:                    ptr1->pWaitLast = NULL;
        !           329:                }
        !           330:                else
        !           331:                {
        !           332:                    ptr1->pWaitingSRB = pSRB->pNextSRB;
        !           333:                }
        !           334:                pSRB->pNextSRB = NULL;
        !           335: 
        !           336:                if( ptr1->pGoingSRB )
        !           337:                    ptr1->pGoingLast->pNextSRB = pSRB;
        !           338:                else
        !           339:                    ptr1->pGoingSRB = pSRB;
        !           340:                ptr1->pGoingLast = pSRB;
        !           341: 
        !           342:                break;
        !           343:            }
        !           344:        }
        !           345:     }
        !           346:     restore_flags(flags);
        !           347:     return;
        !           348: }
        !           349: 
        !           350: 
        !           351: static void
        !           352: SRBwaiting( PDCB pDCB, PSRB pSRB)
        !           353: {
        !           354:     if( pDCB->pWaitingSRB )
        !           355:     {
        !           356:        pDCB->pWaitLast->pNextSRB = pSRB;
        !           357:        pDCB->pWaitLast = pSRB;
        !           358:        pSRB->pNextSRB = NULL;
        !           359:     }
        !           360:     else
        !           361:     {
        !           362:        pDCB->pWaitingSRB = pSRB;
        !           363:        pDCB->pWaitLast = pSRB;
        !           364:     }
        !           365: }
        !           366: 
        !           367: 
        !           368: static void
        !           369: SendSRB( PSCSICMD pcmd, PACB pACB, PSRB pSRB )
        !           370: {
        !           371:     ULONG  flags;
        !           372:     PDCB   pDCB;
        !           373: 
        !           374:     save_flags(flags);
        !           375:     cli();
        !           376: 
        !           377:     pDCB = pSRB->pSRBDCB;
        !           378:     PrepareSG( pACB, pDCB, pSRB );
        !           379:     if( !(pDCB->MaxCommand > pDCB->GoingSRBCnt) || (pACB->pActiveDCB) ||
        !           380:        (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV)) )
        !           381:     {
        !           382:        SRBwaiting(pDCB, pSRB);
        !           383:        goto SND_EXIT;
        !           384:     }
        !           385: 
        !           386:     if( pDCB->pWaitingSRB )
        !           387:     {
        !           388:        SRBwaiting(pDCB, pSRB);
        !           389: /*     pSRB = GetWaitingSRB(pDCB); */
        !           390:        pSRB = pDCB->pWaitingSRB;
        !           391:        pDCB->pWaitingSRB = pSRB->pNextSRB;
        !           392:        pSRB->pNextSRB = NULL;
        !           393:     }
        !           394: 
        !           395:     DC390W_StartSCSI(pACB, pDCB, pSRB);
        !           396:     pDCB->GoingSRBCnt++;
        !           397:     if( pDCB->pGoingSRB )
        !           398:     {
        !           399:        pDCB->pGoingLast->pNextSRB = pSRB;
        !           400:        pDCB->pGoingLast = pSRB;
        !           401:     }
        !           402:     else
        !           403:     {
        !           404:        pDCB->pGoingSRB = pSRB;
        !           405:        pDCB->pGoingLast = pSRB;
        !           406:     }
        !           407: 
        !           408: SND_EXIT:
        !           409:     restore_flags(flags);
        !           410:     return;
        !           411: }
        !           412: 
        !           413: 
        !           414: /***********************************************************************
        !           415:  * Function : static int DC390W_queue_command (Scsi_Cmnd *cmd,
        !           416:  *                                            void (*done)(Scsi_Cmnd *))
        !           417:  *
        !           418:  * Purpose : enqueues a SCSI command
        !           419:  *
        !           420:  * Inputs : cmd - SCSI command, done - function called on completion, with
        !           421:  *         a pointer to the command descriptor.
        !           422:  *
        !           423:  * Returns : 0
        !           424:  *
        !           425:  ***********************************************************************/
        !           426: 
        !           427: int
        !           428: DC390W_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
        !           429: {
        !           430:     USHORT ioport, i;
        !           431:     Scsi_Cmnd *pcmd;
        !           432:     struct Scsi_Host *psh;
        !           433:     PACB   pACB;
        !           434:     PDCB   pDCB;
        !           435:     PSRB   pSRB;
        !           436:     ULONG  flags;
        !           437:     PUCHAR ptr,ptr1;
        !           438: 
        !           439:     psh = cmd->host;
        !           440:     pACB = (PACB ) psh->hostdata;
        !           441:     ioport = pACB->IOPortBase;
        !           442: 
        !           443: #ifdef DC390W_DEBUG0
        !           444:        printk("Cmd=%x,",cmd->cmnd[0]);
        !           445: #endif
        !           446: 
        !           447:     if( (pACB->scan_devices == END_SCAN) && (cmd->cmnd[0] != INQUIRY) )
        !           448:     {
        !           449:        pACB->scan_devices = 0;
        !           450:        pPrevDCB->pNextDCB = pACB->pLinkDCB;
        !           451:     }
        !           452:     else if( (pACB->scan_devices) && (cmd->cmnd[0] == 8) )
        !           453:     {
        !           454:        pACB->scan_devices = 0;
        !           455:        pPrevDCB->pNextDCB = pACB->pLinkDCB;
        !           456:     }
        !           457: 
        !           458:     if ( ( cmd->target > pACB->max_id ) || (cmd->lun > pACB->max_lun) )
        !           459:     {
        !           460: /*     printk("DC390W: Ignore target %d lun %d\n",
        !           461:                cmd->target, cmd->lun); */
        !           462:        cmd->result = (DID_BAD_TARGET << 16);
        !           463:        done(cmd);
        !           464:        return( 0 );
        !           465:     }
        !           466: 
        !           467:     if( (pACB->scan_devices) && !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) )
        !           468:     {
        !           469:        if( pACB->DeviceCnt < MAX_DEVICES )
        !           470:        {
        !           471:            pACB->DCBmap[cmd->target] |= (1 << cmd->lun);
        !           472:            pDCB = pACB->pDCB_free;
        !           473: #ifdef DC390W_DEBUG0
        !           474:            printk("pDCB=%8x,ID=%2x,", (UINT) pDCB, cmd->target);
        !           475: #endif
        !           476:            DC390W_initDCB( pACB, pDCB, cmd );
        !           477:        }
        !           478:        else    /* ???? */
        !           479:        {
        !           480: /*     printk("DC390W: Ignore target %d lun %d\n",
        !           481:                    cmd->target, cmd->lun); */
        !           482:            cmd->result = (DID_BAD_TARGET << 16);
        !           483:            done(cmd);
        !           484:            return(0);
        !           485:        }
        !           486:     }
        !           487:     else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) )
        !           488:     {
        !           489: /*     printk("DC390W: Ignore target %d lun %d\n",
        !           490:                cmd->target, cmd->lun); */
        !           491:        cmd->result = (DID_BAD_TARGET << 16);
        !           492:        done(cmd);
        !           493:        return(0);
        !           494:     }
        !           495:     else
        !           496:     {
        !           497:        pDCB = pACB->pLinkDCB;
        !           498:        while( (pDCB->UnitSCSIID != cmd->target) ||
        !           499:               (pDCB->UnitSCSILUN != cmd->lun) )
        !           500:        {
        !           501:            pDCB = pDCB->pNextDCB;
        !           502:        }
        !           503: #ifdef DC390W_DEBUG0
        !           504:        printk("pDCB=%8x,ID=%2x,Scan=%1x", (UINT) pDCB, cmd->target,
        !           505:                pACB->scan_devices);
        !           506: #endif
        !           507:     }
        !           508: 
        !           509:     cmd->scsi_done = done;
        !           510:     cmd->result = 0;
        !           511: 
        !           512:     save_flags(flags);
        !           513:     cli();
        !           514: 
        !           515:     if( pDCB->QIORBCnt )
        !           516:     {
        !           517:        QLinkcmd( cmd, pDCB );
        !           518:        pcmd = Getcmd( pDCB );
        !           519:     }
        !           520:     else
        !           521:        pcmd = cmd;
        !           522: 
        !           523:     pSRB = GetSRB( pACB );
        !           524: 
        !           525:     if( !pSRB )
        !           526:     {
        !           527:        QLinkcmd( pcmd, pDCB );
        !           528:        restore_flags(flags);
        !           529:        return(0);
        !           530:     }
        !           531: 
        !           532: /*  BuildSRB(pSRB); */
        !           533: 
        !           534:     pSRB->pSRBDCB = pDCB;
        !           535:     pSRB->pcmd = pcmd;
        !           536:     ptr = (PUCHAR) pSRB->CmdBlock;
        !           537:     ptr1 = (PUCHAR) pcmd->cmnd;
        !           538:     (UCHAR) pSRB->__command[0] = pcmd->cmd_len;
        !           539:     for(i=0; i< pcmd->cmd_len; i++)
        !           540:     {
        !           541:        *ptr = *ptr1;
        !           542:        ptr++;
        !           543:        ptr1++;
        !           544:     }
        !           545:     if( pcmd->use_sg )
        !           546:     {
        !           547:        pSRB->SGcount = (UCHAR) pcmd->use_sg;
        !           548:        pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
        !           549:     }
        !           550:     else if( pcmd->request_buffer )
        !           551:     {
        !           552:        pSRB->SGcount = 1;
        !           553:        pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
        !           554:        pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
        !           555:        pSRB->Segmentx.length = pcmd->request_bufflen;
        !           556:     }
        !           557:     else
        !           558:        pSRB->SGcount = 0;
        !           559: 
        !           560:     pSRB->AdaptStatus = 0;
        !           561:     pSRB->TargetStatus = 0;
        !           562:     pSRB->MsgCnt = 0;
        !           563:     if( pDCB->DevType != TYPE_TAPE )
        !           564:        pSRB->RetryCnt = 1;
        !           565:     else
        !           566:        pSRB->RetryCnt = 0;
        !           567:     pSRB->SRBStatus = 0;
        !           568:     pSRB->SRBFlag = 0;
        !           569:     pSRB->ScratchABuf = 0;
        !           570:     pSRB->SRBState = 0;
        !           571:     pSRB->RemainSegPtr = 0;
        !           572:     pSRB->XferredLen = 0;
        !           573:     SendSRB( pcmd, pACB, pSRB );
        !           574: 
        !           575:     restore_flags(flags);
        !           576:     return(0);
        !           577: }
        !           578: 
        !           579: 
        !           580: static void
        !           581: DoNextCmd( PACB pACB, PDCB pDCB )
        !           582: {
        !           583:     Scsi_Cmnd *pcmd;
        !           584:     PSRB   pSRB;
        !           585:     ULONG  flags;
        !           586:     PUCHAR ptr,ptr1;
        !           587:     USHORT i;
        !           588: 
        !           589: 
        !           590:     if( pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) )
        !           591:        return;
        !           592:     save_flags(flags);
        !           593:     cli();
        !           594: 
        !           595:     pcmd = Getcmd( pDCB );
        !           596:     pSRB = GetSRB( pACB );
        !           597:     if( !pSRB )
        !           598:     {
        !           599:        QLinkcmd( pcmd, pDCB );
        !           600:        restore_flags(flags);
        !           601:        return;
        !           602:     }
        !           603: 
        !           604:     pSRB->pSRBDCB = pDCB;
        !           605:     pSRB->pcmd = pcmd;
        !           606:     ptr = (PUCHAR) pSRB->CmdBlock;
        !           607:     ptr1 = (PUCHAR) pcmd->cmnd;
        !           608:     (UCHAR) pSRB->__command[0] = pcmd->cmd_len;
        !           609:     for(i=0; i< pcmd->cmd_len; i++)
        !           610:     {
        !           611:        *ptr = *ptr1;
        !           612:        ptr++;
        !           613:        ptr1++;
        !           614:     }
        !           615:     if( pcmd->use_sg )
        !           616:     {
        !           617:        pSRB->SGcount = (UCHAR) pcmd->use_sg;
        !           618:        pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
        !           619:     }
        !           620:     else if( pcmd->request_buffer )
        !           621:     {
        !           622:        pSRB->SGcount = 1;
        !           623:        pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
        !           624:        pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
        !           625:        pSRB->Segmentx.length = pcmd->request_bufflen;
        !           626:     }
        !           627:     else
        !           628:        pSRB->SGcount = 0;
        !           629: 
        !           630:     pSRB->AdaptStatus = 0;
        !           631:     pSRB->TargetStatus = 0;
        !           632:     pSRB->MsgCnt = 0;
        !           633:     if( pDCB->DevType != TYPE_TAPE )
        !           634:        pSRB->RetryCnt = 1;
        !           635:     else
        !           636:        pSRB->RetryCnt = 0;
        !           637:     pSRB->SRBStatus = 0;
        !           638:     pSRB->SRBFlag = 0;
        !           639:     pSRB->ScratchABuf = 0;
        !           640:     pSRB->SRBState = 0;
        !           641:     SendSRB( pcmd, pACB, pSRB );
        !           642: 
        !           643:     restore_flags(flags);
        !           644:     return;
        !           645: }
        !           646: 
        !           647: 
        !           648: /***********************************************************************
        !           649:  * Function:
        !           650:  *   DC390W_bios_param
        !           651:  *
        !           652:  * Description:
        !           653:  *   Return the disk geometry for the given SCSI device.
        !           654:  ***********************************************************************/
        !           655: #ifdef VERSION_ELF_1_2_13
        !           656: int DC390W_bios_param(Disk *disk, int devno, int geom[])
        !           657: #else
        !           658: int DC390W_bios_param(Disk *disk, kdev_t devno, int geom[])
        !           659: #endif
        !           660: {
        !           661:     int heads, sectors, cylinders;
        !           662:     PACB pACB;
        !           663: 
        !           664:     pACB = (PACB) disk->device->host->hostdata;
        !           665:     heads = 64;
        !           666:     sectors = 32;
        !           667:     cylinders = disk->capacity / (heads * sectors);
        !           668: 
        !           669:     if ( (pACB->Gmode2 & GREATER_1G) && (cylinders > 1024) )
        !           670:     {
        !           671:       heads = 255;
        !           672:       sectors = 63;
        !           673:       cylinders = disk->capacity / (heads * sectors);
        !           674:     }
        !           675: 
        !           676:     geom[0] = heads;
        !           677:     geom[1] = sectors;
        !           678:     geom[2] = cylinders;
        !           679: 
        !           680:     return (0);
        !           681: }
        !           682: 
        !           683: 
        !           684: /***********************************************************************
        !           685:  * Function : int DC390W_abort (Scsi_Cmnd *cmd)
        !           686:  *
        !           687:  * Purpose : Abort an errant SCSI command
        !           688:  *
        !           689:  * Inputs : cmd - command to abort
        !           690:  *
        !           691:  * Returns : 0 on success, -1 on failure.
        !           692:  ***********************************************************************/
        !           693: 
        !           694: int
        !           695: DC390W_abort (Scsi_Cmnd *cmd)
        !           696: {
        !           697:     ULONG flags;
        !           698:     PACB  pACB;
        !           699:     PDCB  pDCB, pdcb;
        !           700:     PSRB  pSRB, psrb;
        !           701:     USHORT count, i;
        !           702:     PSCSICMD  pcmd, pcmd1;
        !           703:     int   status;
        !           704: 
        !           705: 
        !           706: #ifdef DC390W_DEBUG0
        !           707:     printk("DC390W : Abort Cmd.");
        !           708: #endif
        !           709: 
        !           710:     save_flags(flags);
        !           711:     cli();
        !           712: 
        !           713:     pACB = (PACB) cmd->host->hostdata;
        !           714:     pDCB = pACB->pLinkDCB;
        !           715:     pdcb = pDCB;
        !           716:     while( (pDCB->UnitSCSIID != cmd->target) ||
        !           717:           (pDCB->UnitSCSILUN != cmd->lun) )
        !           718:     {
        !           719:        pDCB = pDCB->pNextDCB;
        !           720:        if( pDCB == pdcb )
        !           721:            goto  NOT_RUN;
        !           722:     }
        !           723: 
        !           724:     if( pDCB->QIORBCnt )
        !           725:     {
        !           726:        pcmd = pDCB->pQIORBhead;
        !           727:        if( pcmd == cmd )
        !           728:        {
        !           729:            pDCB->pQIORBhead = pcmd->next;
        !           730:            pcmd->next = NULL;
        !           731:            pDCB->QIORBCnt--;
        !           732:            status = SCSI_ABORT_SUCCESS;
        !           733:            goto  ABO_X;
        !           734:        }
        !           735:        for( count = pDCB->QIORBCnt, i=0; i<count-1; i++)
        !           736:        {
        !           737:            if( pcmd->next == cmd )
        !           738:            {
        !           739:                pcmd1 = pcmd->next;
        !           740:                pcmd->next = pcmd1->next;
        !           741:                pcmd1->next = NULL;
        !           742:                pDCB->QIORBCnt--;
        !           743:                status = SCSI_ABORT_SUCCESS;
        !           744:                goto  ABO_X;
        !           745:            }
        !           746:            else
        !           747:            {
        !           748:                pcmd = pcmd->next;
        !           749:            }
        !           750:        }
        !           751:     }
        !           752: 
        !           753:     pSRB = pDCB->pWaitingSRB;
        !           754:     if( !pSRB )
        !           755:        goto  ON_GOING;
        !           756:     if( pSRB->pcmd == cmd )
        !           757:     {
        !           758:        pDCB->pWaitingSRB = pSRB->pNextSRB;
        !           759:        goto  IN_WAIT;
        !           760:     }
        !           761:     else
        !           762:     {
        !           763:        psrb = pSRB;
        !           764:        if( !(psrb->pNextSRB) )
        !           765:            goto ON_GOING;
        !           766:        while( psrb->pNextSRB->pcmd != cmd )
        !           767:        {
        !           768:            psrb = psrb->pNextSRB;
        !           769:            if( !(psrb->pNextSRB) )
        !           770:                goto ON_GOING;
        !           771:        }
        !           772:        pSRB = psrb->pNextSRB;
        !           773:        psrb->pNextSRB = pSRB->pNextSRB;
        !           774:        if( pSRB == pDCB->pWaitLast )
        !           775:            pDCB->pWaitLast = psrb;
        !           776: IN_WAIT:
        !           777:        pSRB->pNextSRB = pACB->pFreeSRB;
        !           778:        pACB->pFreeSRB = pSRB;
        !           779:        cmd->next = NULL;
        !           780:        status = SCSI_ABORT_SUCCESS;
        !           781:        goto  ABO_X;
        !           782:     }
        !           783: 
        !           784: ON_GOING:
        !           785:     pSRB = pDCB->pGoingSRB;
        !           786:     for( count = pDCB->GoingSRBCnt, i=0; i<count; i++)
        !           787:     {
        !           788:        if( pSRB->pcmd != cmd )
        !           789:            pSRB = pSRB->pNextSRB;
        !           790:        else
        !           791:        {
        !           792:            if( (pACB->pActiveDCB == pDCB) && (pDCB->pActiveSRB == pSRB) )
        !           793:            {
        !           794:                status = SCSI_ABORT_BUSY;
        !           795:                goto  ABO_X;
        !           796:            }
        !           797:            else
        !           798:            {
        !           799:                status = SCSI_ABORT_SNOOZE;
        !           800:                goto  ABO_X;
        !           801:            }
        !           802:        }
        !           803:     }
        !           804: 
        !           805: NOT_RUN:
        !           806:     status = SCSI_ABORT_NOT_RUNNING;
        !           807: 
        !           808: ABO_X:
        !           809:     cmd->result = DID_ABORT << 16;
        !           810:     cmd->scsi_done(cmd);
        !           811:     restore_flags(flags);
        !           812:     return( status );
        !           813: }
        !           814: 
        !           815: 
        !           816: static void
        !           817: ResetDevParam( PACB pACB )
        !           818: {
        !           819:     PDCB   pDCB, pdcb;
        !           820: 
        !           821:     pDCB = pACB->pLinkDCB;
        !           822:     if( pDCB == NULL )
        !           823:        return;
        !           824:     pdcb = pDCB;
        !           825:     do
        !           826:     {
        !           827:        if( pACB->AdaptType == DC390W )
        !           828:            pdcb->DCBscntl3 = SYNC_CLK_F2+ASYNC_CLK_F2;
        !           829:        else
        !           830:            pdcb->DCBscntl3 = SYNC_CLK_F4+ASYNC_CLK_F4;
        !           831:        pdcb->DCBsxfer = 0;
        !           832:        pdcb = pdcb->pNextDCB;
        !           833:     }
        !           834:     while( pdcb != pDCB );
        !           835: }
        !           836: 
        !           837: 
        !           838: static void
        !           839: RecoverSRB( PACB pACB )
        !           840: {
        !           841:     PDCB   pDCB, pdcb;
        !           842:     PSRB   psrb, psrb2;
        !           843:     USHORT cnt, i;
        !           844: 
        !           845:     pDCB = pACB->pLinkDCB;
        !           846:     if( pDCB == NULL )
        !           847:        return;
        !           848:     pdcb = pDCB;
        !           849:     do
        !           850:     {
        !           851:        cnt = pdcb->GoingSRBCnt;
        !           852:        psrb = pdcb->pGoingSRB;
        !           853:        for (i=0; i<cnt; i++)
        !           854:        {
        !           855:            PrepareSG( pACB, pdcb, psrb );
        !           856:            psrb2 = psrb;
        !           857:            psrb = psrb->pNextSRB;
        !           858: /*         RewaitSRB( pDCB, psrb ); */
        !           859:            if( pdcb->pWaitingSRB )
        !           860:            {
        !           861:                psrb2->pNextSRB = pdcb->pWaitingSRB;
        !           862:                pdcb->pWaitingSRB = psrb2;
        !           863:            }
        !           864:            else
        !           865:            {
        !           866:                pdcb->pWaitingSRB = psrb2;
        !           867:                pdcb->pWaitLast = psrb2;
        !           868:                psrb2->pNextSRB = NULL;
        !           869:            }
        !           870:        }
        !           871:        pdcb->GoingSRBCnt = 0;
        !           872:        pdcb->pGoingSRB = NULL;
        !           873:        pdcb->TagMask = 0;
        !           874:        pdcb = pdcb->pNextDCB;
        !           875:     }
        !           876:     while( pdcb != pDCB );
        !           877: }
        !           878: 
        !           879: 
        !           880: /***********************************************************************
        !           881:  * Function : int DC390W_reset (Scsi_Cmnd *cmd, ...)
        !           882:  *
        !           883:  * Purpose : perform a hard reset on the SCSI bus( and NCR chip).
        !           884:  *
        !           885:  * Inputs : cmd - command which caused the SCSI RESET
        !           886:  *
        !           887:  * Returns : 0 on success.
        !           888:  ***********************************************************************/
        !           889: 
        !           890: #ifdef VERSION_2_0_0
        !           891: int DC390W_reset(Scsi_Cmnd *cmd, unsigned int resetFlags)
        !           892: #else
        !           893: int DC390W_reset (Scsi_Cmnd *cmd)
        !           894: #endif
        !           895: {
        !           896:     USHORT   ioport;
        !           897:     unsigned long flags;
        !           898:     PACB  pACB;
        !           899:     ULONG    wlval;
        !           900:     UCHAR    bval;
        !           901:     USHORT   wval;
        !           902:     USHORT  i;
        !           903: 
        !           904: 
        !           905: #ifdef DC390W_DEBUG0
        !           906:     printk("DC390W : Reset Cmd0,");
        !           907: #endif
        !           908: 
        !           909:     pACB = (PACB ) cmd->host->hostdata;
        !           910:     ioport = pACB->IOPortBase;
        !           911:     save_flags(flags);
        !           912:     cli();
        !           913:     bval = inb(ioport+DCNTL);
        !           914:     bval |= IRQ_DISABLE;
        !           915:     outb(bval,ioport+DCNTL);  /* disable interrupt */
        !           916:     DC390W_ResetSCSIBus( pACB );
        !           917:     for( i=0; i<500; i++ )
        !           918:        udelay(1000);
        !           919:     for(;;)
        !           920:     {
        !           921:         bval = inb(ioport+ISTAT);
        !           922:         if( bval & SCSI_INT_PENDING )
        !           923:         {
        !           924:             wval = inw( ioport+SIST0 );
        !           925:             if( wval & (SCSI_RESET+SCSI_GERROR) )
        !           926:                 break;
        !           927:         }
        !           928:         if(bval & DMA_INT_PENDING)
        !           929:         {
        !           930:             bval = inb(ioport+DSTAT);
        !           931:             if(bval & ABORT_)
        !           932:             {
        !           933:                 wval = inw( ioport+SIST0 );
        !           934:                 break;
        !           935:             }
        !           936:         }
        !           937:     }
        !           938:     bval = inb(ioport+DCNTL);
        !           939:     bval &= ~IRQ_DISABLE;
        !           940:     outb(bval,ioport+DCNTL); /* re-enable interrupt */
        !           941: 
        !           942:     ioport = pACB->IOPortBase;
        !           943:     bval = inb(ioport+STEST3);
        !           944:     bval |= CLR_SCSI_FIFO;
        !           945:     outb(bval,ioport+STEST3);
        !           946:     bval = CLR_DMA_FIFO;
        !           947:     outb(bval,ioport+CTEST3);
        !           948:     ResetDevParam( pACB );
        !           949:     DoingSRB_Done( pACB );
        !           950:     pACB->pActiveDCB = NULL;
        !           951:     wlval = pACB->jmp_reselect;
        !           952:     outl(wlval,(ioport+DSP));
        !           953: 
        !           954:     pACB->ACBFlag = 0;
        !           955:     DoWaitingSRB( pACB );
        !           956:     restore_flags(flags);
        !           957:     return( SCSI_RESET_SUCCESS );
        !           958: }
        !           959: 
        !           960: 
        !           961: #include "scsiio.c"
        !           962: 
        !           963: 
        !           964: /***********************************************************************
        !           965:  * Function : static void DC390W_initDCB
        !           966:  *
        !           967:  * Purpose :  initialize the internal structures for a given DCB
        !           968:  *
        !           969:  * Inputs : cmd - pointer to this scsi cmd request block structure
        !           970:  *
        !           971:  ***********************************************************************/
        !           972: void DC390W_initDCB( PACB pACB, PDCB pDCB, PSCSICMD cmd )
        !           973: {
        !           974:     PEEprom    prom;
        !           975:     UCHAR      bval;
        !           976:     USHORT     index;
        !           977: 
        !           978:     if( pACB->DeviceCnt == 0 )
        !           979:     {
        !           980:        pACB->pLinkDCB = pDCB;
        !           981:        pACB->pDCBRunRobin = pDCB;
        !           982:        pDCB->pNextDCB = pDCB;
        !           983:        pPrevDCB = pDCB;
        !           984:     }
        !           985:     else
        !           986:        pPrevDCB->pNextDCB = pDCB;
        !           987: 
        !           988:     pDCB->pDCBACB = pACB;
        !           989:     pDCB->QIORBCnt = 0;
        !           990:     pDCB->DCBselect = 0;
        !           991:     pDCB->DCBsxfer = 0;
        !           992:     pDCB->DCBsdid = cmd->target;
        !           993:     pDCB->UnitSCSIID = cmd->target;
        !           994:     pDCB->UnitSCSILUN = cmd->lun;
        !           995:     pDCB->pWaitingSRB = NULL;
        !           996:     pDCB->GoingSRBCnt = 0;
        !           997:     pDCB->TagMask = 0;
        !           998: 
        !           999:     pDCB->MaxCommand = 1;
        !          1000:     pDCB->AdaptIndex = pACB->AdapterIndex;
        !          1001:     index = pACB->AdapterIndex;
        !          1002: 
        !          1003:     prom = (PEEprom) &eepromBuf[index][cmd->target << 2];
        !          1004:     pDCB->DevMode = prom->EE_MODE1;
        !          1005:     pDCB->NegoPeriod = clock_period[prom->EE_SPEED];
        !          1006: 
        !          1007:     if( pACB->AdaptType == DC390W )
        !          1008:        pDCB->DCBscntl3 = SYNC_CLK_F2+ASYNC_CLK_F2;
        !          1009:     else
        !          1010:        pDCB->DCBscntl3 = SYNC_CLK_F4+ASYNC_CLK_F4;
        !          1011: 
        !          1012:     if( pDCB->DevMode & PARITY_CHK_ )
        !          1013:        pDCB->DCBscntl0 = EN_PARITY_CHK+SATN_IF_PARITY_ERR+FULL_ARBITRATION;
        !          1014:     else
        !          1015:        pDCB->DCBscntl0 = FULL_ARBITRATION;
        !          1016: 
        !          1017:     pDCB->AdpMode = eepromBuf[index][EE_MODE2];
        !          1018: 
        !          1019:     if( pDCB->DevMode & EN_DISCONNECT_ )
        !          1020:        bval = 0xC0;
        !          1021:     else
        !          1022:        bval = 0x80;
        !          1023:     bval |= cmd->lun;
        !          1024:     pDCB->IdentifyMsg = bval;
        !          1025: 
        !          1026:     if( pDCB->DevMode & SYNC_NEGO_ )
        !          1027:     {
        !          1028:        pDCB->SyncMode = SYNC_ENABLE;
        !          1029:        pDCB->SyncOffset = SYNC_NEGO_OFFSET;
        !          1030:     }
        !          1031: 
        !          1032:     if( pDCB->DevMode & WIDE_NEGO_ )
        !          1033:     {
        !          1034:        if( cmd->lun )
        !          1035:        {
        !          1036:            if( !(CurrDCBscntl3 & EN_WIDE_SCSI) )
        !          1037:                pDCB->DevMode &= ~WIDE_NEGO_;
        !          1038:        }
        !          1039:        else
        !          1040:            CurrDCBscntl3 = 0;
        !          1041:     }
        !          1042:     pDCB->DCBFlag = 0;
        !          1043: }
        !          1044: 
        !          1045: 
        !          1046: /***********************************************************************
        !          1047:  * Function : static void DC390W_initSRB
        !          1048:  *
        !          1049:  * Purpose :  initialize the internal structures for a given SRB
        !          1050:  *
        !          1051:  * Inputs : psrb - pointer to this scsi request block structure
        !          1052:  *
        !          1053:  ***********************************************************************/
        !          1054: void DC390W_initSRB( PSRB psrb )
        !          1055: {
        !          1056: #ifndef VERSION_ELF_1_2_13
        !          1057:        psrb->PhysSRB = virt_to_phys( psrb );
        !          1058:        psrb->__command[1] = virt_to_phys( psrb->CmdBlock );
        !          1059:        psrb->__msgout0[0] = 1;
        !          1060:        psrb->__msgout0[1] = virt_to_phys( psrb->MsgOutBuf );
        !          1061:        psrb->SegmentPad[0] = 16;
        !          1062:        psrb->SegmentPad[1] = virt_to_phys( pad_buffer );
        !          1063: #else
        !          1064:        psrb->PhysSRB = (ULONG) psrb;
        !          1065:        psrb->__command[1] = (ULONG) psrb->CmdBlock;
        !          1066:        psrb->__msgout0[0] = 1;
        !          1067:        psrb->__msgout0[1] = (ULONG) psrb->MsgOutBuf;
        !          1068:        psrb->SegmentPad[0] = 16;
        !          1069:        psrb->SegmentPad[1] = (ULONG) pad_buffer;
        !          1070: #endif
        !          1071: }
        !          1072: 
        !          1073: 
        !          1074: void DC390W_linkSRB( PACB pACB )
        !          1075: {
        !          1076:     USHORT  count, i;
        !          1077:     PSRB    psrb;
        !          1078: 
        !          1079:     count = pACB->SRBCount;
        !          1080: 
        !          1081:     for( i=0; i< count; i++)
        !          1082:     {
        !          1083:        if( i != count - 1)
        !          1084:            pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[i+1];
        !          1085:        else
        !          1086:            pACB->SRB_array[i].pNextSRB = NULL;
        !          1087:        psrb = (PSRB) &pACB->SRB_array[i];
        !          1088:        DC390W_initSRB( psrb );
        !          1089:     }
        !          1090: }
        !          1091: 
        !          1092: 
        !          1093: /***********************************************************************
        !          1094:  * Function : static void DC390W_initACB
        !          1095:  *
        !          1096:  * Purpose :  initialize the internal structures for a given SCSI host
        !          1097:  *
        !          1098:  * Inputs : psh - pointer to this host adapter's structure
        !          1099:  *
        !          1100:  ***********************************************************************/
        !          1101: void DC390W_initACB( PSH psh, USHORT chipType, ULONG io_port, UCHAR Irq, USHORT index )
        !          1102: {
        !          1103:     PACB    pACB;
        !          1104:     USHORT  i;
        !          1105:     UCHAR   adaptType, bval;
        !          1106: 
        !          1107: 
        !          1108:     psh->can_queue = MAX_CMD_QUEUE;
        !          1109:     psh->cmd_per_lun = MAX_CMD_PER_LUN;
        !          1110:     psh->this_id = (int) eepromBuf[index][EE_ADAPT_SCSI_ID];
        !          1111:     psh->io_port = io_port;
        !          1112:     psh->n_io_port = 0x80;
        !          1113:     psh->irq = Irq;
        !          1114: 
        !          1115:     if( chipType == PCI_DEVICE_ID_NCR53C825A )
        !          1116:        adaptType = DC390W;
        !          1117:     else
        !          1118:     {
        !          1119:        outb( 2, io_port+GPREG );
        !          1120:        bval = inb( io_port+GPREG );
        !          1121:        if( bval & 8 )
        !          1122:            adaptType = DC390U;
        !          1123:        else
        !          1124:            adaptType = DC390F;
        !          1125:     }
        !          1126: 
        !          1127:     pACB = (PACB) psh->hostdata;
        !          1128: 
        !          1129: #ifndef VERSION_ELF_1_2_13
        !          1130:     if( adaptType == DC390U )
        !          1131:     {
        !          1132:        psh->max_id = 8;
        !          1133:        pACB->max_id = 7;
        !          1134:     }
        !          1135:     else
        !          1136:     {
        !          1137:        psh->max_id = 16;
        !          1138:        pACB->max_id = 15;
        !          1139:     }
        !          1140: 
        !          1141: #ifdef CONFIG_SCSI_MULTI_LUN
        !          1142:     if( eepromBuf[index][EE_MODE2] & LUN_CHECK )
        !          1143:        psh->max_lun = 8;
        !          1144:     else
        !          1145: #endif
        !          1146:        psh->max_lun = 1;
        !          1147: 
        !          1148: #else
        !          1149:        pACB->max_id = 7;
        !          1150: #endif
        !          1151:     if( pACB->max_id == eepromBuf[index][EE_ADAPT_SCSI_ID] )
        !          1152:        pACB->max_id--;
        !          1153: 
        !          1154: #ifdef CONFIG_SCSI_MULTI_LUN
        !          1155:     if( eepromBuf[index][EE_MODE2] & LUN_CHECK )
        !          1156:        pACB->max_lun = 7;
        !          1157:     else
        !          1158: #endif
        !          1159:        pACB->max_lun = 0;
        !          1160: 
        !          1161:     pACB->pScsiHost = psh;
        !          1162:     pACB->IOPortBase = (USHORT) io_port;
        !          1163:     pACB->pLinkDCB = NULL;
        !          1164:     pACB->pDCBRunRobin = NULL;
        !          1165:     pACB->pActiveDCB = NULL;
        !          1166:     pACB->pFreeSRB = pACB->SRB_array;
        !          1167:     pACB->SRBCount = MAX_SRB_CNT;
        !          1168:     pACB->AdapterIndex = index;
        !          1169:     pACB->status = 0;
        !          1170:     pACB->AdaptSCSIID = eepromBuf[index][EE_ADAPT_SCSI_ID];
        !          1171:     pACB->AdaptSCSILUN = 0;
        !          1172:     pACB->DeviceCnt = 0;
        !          1173:     pACB->IRQLevel = Irq;
        !          1174:     pACB->AdaptType = adaptType;
        !          1175:     pACB->TagMaxNum = eepromBuf[index][EE_TAG_CMD_NUM] << 2;
        !          1176:     pACB->ACBFlag = 0;
        !          1177:     pACB->scan_devices = 1;
        !          1178:     pACB->Gmode2 = eepromBuf[index][EE_MODE2];
        !          1179:     if( eepromBuf[index][EE_MODE2] & LUN_CHECK )
        !          1180:        pACB->LUNchk = 1;
        !          1181:     pACB->pDCB_free = &pACB->DCB_array[0];
        !          1182:     DC390W_linkSRB( pACB );
        !          1183:     for(i=0; i<MAX_SCSI_ID; i++)
        !          1184:        pACB->DCBmap[i] = 0;
        !          1185: }
        !          1186: 
        !          1187: 
        !          1188: /***********************************************************************
        !          1189:  * Function : static int DC390W_initAdapter
        !          1190:  *
        !          1191:  * Purpose :  initialize the SCSI chip ctrl registers
        !          1192:  *
        !          1193:  * Inputs : psh - pointer to this host adapter's structure
        !          1194:  *
        !          1195:  ***********************************************************************/
        !          1196: int DC390W_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index )
        !          1197: {
        !          1198:     USHORT ioport, wval;
        !          1199:     UCHAR  bval;
        !          1200:     PACB   pACB, pacb;
        !          1201:     USHORT used_irq = 0;
        !          1202: 
        !          1203:     pacb = pACB_start;
        !          1204:     if( pacb != NULL )
        !          1205:     {
        !          1206:        for ( ; (pacb != (PACB) -1) ; )
        !          1207:        {
        !          1208:            if( pacb->IRQLevel == Irq )
        !          1209:            {
        !          1210:                used_irq = 1;
        !          1211:                break;
        !          1212:            }
        !          1213:            else
        !          1214:                pacb = pacb->pNextACB;
        !          1215:        }
        !          1216:     }
        !          1217: 
        !          1218:     if( !used_irq )
        !          1219:     {
        !          1220: #ifdef VERSION_ELF_1_2_13
        !          1221:        if( request_irq(Irq, DC390W_Interrupt, SA_INTERRUPT, "tmscsiw"))
        !          1222: #else
        !          1223:        if( request_irq(Irq, DC390W_Interrupt, SA_INTERRUPT | SA_SHIRQ, "tmscsiw", NULL))
        !          1224: #endif
        !          1225:        {
        !          1226:            printk("DC390W : register IRQ error!\n");
        !          1227:            return( -1 );
        !          1228:        }
        !          1229:     }
        !          1230:     request_region(io_port,psh->n_io_port,"tmscsiw");
        !          1231: 
        !          1232:     ioport = (USHORT) io_port;
        !          1233:     outb(IRQ_DISABLE, ioport+DCNTL);
        !          1234:     outb(ABORT_OP, ioport+ISTAT);
        !          1235:     udelay(100000);
        !          1236:     outb(0, ioport+ISTAT);
        !          1237:     bval = inb(ioport+DSTAT);
        !          1238:     bval = inb(ioport+ISTAT);
        !          1239:     wval = inw(ioport+SIST0);
        !          1240: 
        !          1241:     pACB = (PACB) psh->hostdata;
        !          1242:     bval = pACB->AdaptSCSIID;
        !          1243:     bval |= ENABLE_RESEL;
        !          1244:     outb(bval,ioport+SCID);
        !          1245: 
        !          1246:     if(pACB->AdaptType == DC390W)
        !          1247:        bval = SYNC_CLK_F2+ASYNC_CLK_F2;
        !          1248:     else
        !          1249:     {                                          /* @1.09 */
        !          1250:        bval = inb(ioport+CTEST3);
        !          1251:        if( (bval & CHIP_REV_MASK) < 0x30 )     /* 53C875 Rev. F or later ? */
        !          1252:            goto  REVF;
        !          1253:        bval = inb(ioport+STEST1);
        !          1254:        if( (bval & 0x0C) == 0x0C )             /* double clock already enable ? */
        !          1255:            goto  REVF;
        !          1256:        outb(8,ioport+STEST1);                  /* enable clock doubler */
        !          1257:        udelay(20);
        !          1258:        outb(HALT_SCSI_CLK,ioport+STEST3);      /* halt clock */
        !          1259:        outb(0x0C,ioport+STEST1);               /* select double SCSI clock */
        !          1260:        outb(0,ioport+STEST3);                  /* re-enable clock */
        !          1261: REVF:
        !          1262:        bval = SYNC_CLK_F4+ASYNC_CLK_F4;
        !          1263:     }
        !          1264:     outb(bval,ioport+SCNTL3);
        !          1265: 
        !          1266:     bval = SYNC_PERIOD_F4+ASYNCHRONOUS;        /* set to async */
        !          1267:     outb(bval,ioport+SXFER);
        !          1268: 
        !          1269:     bval = WRT_EN_INVALIDATE;          /* Enable write and invalidate */
        !          1270:     outb(bval,ioport+CTEST3);
        !          1271: 
        !          1272:     bval = EN_DMA_FIFO_536+BURST_LEN_MSB;      /* select 536 bytes DMA FIFO, burst len bit2=1 */
        !          1273:     outb(bval,ioport+CTEST5);
        !          1274: 
        !          1275:     bval = BURST_LEN8+EN_READ_LINE+EN_READ_MULTIPLE+BURST_OPCODE_FETCH+AUTO_START;   /* set DMA parameter */
        !          1276:     outb(bval,ioport+DMODE);
        !          1277: 
        !          1278:     bval = EN_ABORTED+EN_SCRIPT_INT+EN_ILLEGAL_INST;   /* enable DMA interrupt */
        !          1279:     outb(bval,ioport+DIEN);
        !          1280: 
        !          1281:     bval = EN_CACHE_LINE_SIZE+EN_PRE_FETCH+TOTEM_POLE_IRQ+COMPATIBLE_700;
        !          1282:     outb(bval,ioport+DCNTL);
        !          1283: 
        !          1284:     bval = EN_PHASE_MISMATCH+EN_SCSI_GERROR+EN_UNEXPECT_DISC+EN_SCSI_RESET+EN_PARITY_ERROR;
        !          1285:     outb(bval,ioport+SIEN0);
        !          1286: 
        !          1287:     bval = EN_SEL_TIMEOUT+EN_GENERAL_TIMEOUT;
        !          1288:     outb(bval,ioport+SIEN1);
        !          1289: 
        !          1290:     bval = SEL_TO_204ms;       /* 250ms selection timeout */
        !          1291:     outb(bval,ioport+STIME0);
        !          1292: 
        !          1293:     wval = 1 << (eepromBuf[index][EE_ADAPT_SCSI_ID]);  /* @1.11 */
        !          1294:     outw(wval,ioport+RESPID0);
        !          1295: 
        !          1296:     bval = DIS_SINGLE_INIT;
        !          1297:     if( eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION )
        !          1298:         bval |= ACTIVE_NEGATION_;
        !          1299:     outb(bval,ioport+STEST3);
        !          1300: 
        !          1301:     return(0);
        !          1302: }
        !          1303: 
        !          1304: 
        !          1305: /***********************************************************************
        !          1306:  * Function : static int DC390W_init (struct Scsi_Host *host)
        !          1307:  *
        !          1308:  * Purpose :  initialize the internal structures for a given SCSI host
        !          1309:  *
        !          1310:  * Inputs : host - pointer to this host adapter's structure/
        !          1311:  *
        !          1312:  * Preconditions : when this function is called, the chip_type
        !          1313:  *     field of the pACB structure MUST have been set.
        !          1314:  ***********************************************************************/
        !          1315: 
        !          1316: static int
        !          1317: DC390W_init (PSHT psht, USHORT chipType, ULONG io_port, UCHAR Irq, USHORT index)
        !          1318: {
        !          1319:     PSH   psh;
        !          1320:     PACB  pACB;
        !          1321: 
        !          1322:     if( ! CheckEEpromCheckSum( &eepromBuf[index][0], (USHORT) io_port) )
        !          1323:     {
        !          1324:        psh = scsi_register( psht, sizeof(DC390W_ACB) );
        !          1325:        if( !psh )
        !          1326:            return( -1 );
        !          1327:        if( !pSH_start )
        !          1328:        {
        !          1329:            pSH_start = psh;
        !          1330:            pSH_current = psh;
        !          1331:        }
        !          1332:        else
        !          1333:        {
        !          1334:            pSH_current->next = psh;
        !          1335:            pSH_current = psh;
        !          1336:        }
        !          1337: 
        !          1338: #ifdef DC390W_DEBUG0
        !          1339:        printk("DC390W : pSH = %8x,", (UINT) psh);
        !          1340: #endif
        !          1341: 
        !          1342:        DC390W_initACB( psh, chipType, io_port, Irq, index );
        !          1343:        if( !DC390W_initAdapter( psh, io_port, Irq, index  ) )
        !          1344:        {
        !          1345:            pACB = (PACB) psh->hostdata;
        !          1346:            if( !pACB_start )
        !          1347:            {
        !          1348:                pACB_start = pACB;
        !          1349:                pACB_current = pACB;
        !          1350:                pACB->pNextACB = (PACB) -1;
        !          1351:            }
        !          1352:            else
        !          1353:            {
        !          1354:                pACB_current->pNextACB = pACB;
        !          1355:                pACB_current = pACB;
        !          1356:                pACB->pNextACB = (PACB)  -1;
        !          1357:            }
        !          1358: 
        !          1359: #ifdef DC390W_DEBUG0
        !          1360:        printk("DC390W : pACB = %8x, pDCB_array = %8x, pSRB_array = %8x\n",
        !          1361:              (UINT) pACB, (UINT) pACB->DCB_array, (UINT) pACB->SRB_array);
        !          1362:        printk("DC390W : ACB size= %4x, DCB size= %4x, SRB size= %4x\n",
        !          1363:              sizeof(DC390W_ACB), sizeof(DC390W_DCB), sizeof(DC390W_SRB) );
        !          1364: #endif
        !          1365: 
        !          1366:        }
        !          1367:        else
        !          1368:        {
        !          1369:            pSH_start = NULL;
        !          1370:            scsi_unregister( psh );
        !          1371:            return( -1 );
        !          1372:        }
        !          1373:        DC390W_download_script( psh );
        !          1374:        return( 0 );
        !          1375:     }
        !          1376:     else
        !          1377:     {
        !          1378:        printk("DC390W_init: EEPROM reading error!\n");
        !          1379:        return( -1 );
        !          1380:     }
        !          1381: }
        !          1382: 
        !          1383: 
        !          1384: void  MyDelay( void )
        !          1385: {
        !          1386:        UCHAR   i,j;
        !          1387: 
        !          1388:        j = inb(0x61) & 0x10;
        !          1389: 
        !          1390:        for(;;)
        !          1391:        {
        !          1392:            i = inb(0x61) & 0x10;
        !          1393:            if( j ^ i)
        !          1394:                break;
        !          1395:        }
        !          1396: }
        !          1397: 
        !          1398: 
        !          1399: void  EnDisableCE( UCHAR Flag, USHORT scsiIOPort )
        !          1400: {
        !          1401: 
        !          1402:     UCHAR bval;
        !          1403:     USHORT port;
        !          1404: 
        !          1405:     port = (scsiIOPort & 0xff00) + GPREG;
        !          1406:     if(Flag == ENABLE_CE)
        !          1407:        bval = 0x10;
        !          1408:     else
        !          1409:        bval = 0x00;
        !          1410:     outb(bval,port);
        !          1411:     udelay(8); /* Delay();*/
        !          1412: }
        !          1413: 
        !          1414: 
        !          1415: void  EEpromOutDI( USHORT Carry, USHORT scsiIOPort )
        !          1416: {
        !          1417:     UCHAR  bval;
        !          1418:     USHORT port;
        !          1419: 
        !          1420:     port = (scsiIOPort & 0xff00) + GPREG;
        !          1421:     bval = 0x10;
        !          1422:     if(Carry)
        !          1423:        bval |= 0x02;   /* SK=0, DI */
        !          1424:     outb(bval,port);
        !          1425:     udelay(8); /* Delay();*/
        !          1426:     bval |= 0x04;      /* SK=1, DI */
        !          1427:     outb(bval,port);
        !          1428:     udelay(8); /* Delay();*/
        !          1429:     bval &= 0xfb;      /* SK=0, DI */
        !          1430:     outb(bval,port);
        !          1431:     udelay(8); /* Delay();*/
        !          1432: }
        !          1433: 
        !          1434: 
        !          1435: void  EEpromPrepare( UCHAR EEpromCmd, USHORT scsiIOPort )
        !          1436: {
        !          1437:     UCHAR i,j;
        !          1438:     USHORT carryFlag;
        !          1439: 
        !          1440:     carryFlag = 1;
        !          1441:     j = 0x80;
        !          1442:     for(i=0;i<9;i++)
        !          1443:     {
        !          1444:        EEpromOutDI(carryFlag,scsiIOPort);
        !          1445:        carryFlag = (EEpromCmd & j) ? 1 : 0;
        !          1446:        j >>= 1;
        !          1447:     }
        !          1448: }
        !          1449: 
        !          1450: 
        !          1451: UCHAR  EEpromInDo(USHORT scsiIOPort)
        !          1452: {
        !          1453:     UCHAR  bval;
        !          1454:     USHORT port;
        !          1455: 
        !          1456:     port = (scsiIOPort & 0xff00) + GPREG;
        !          1457:     bval = 0x14;       /* SK=1 */
        !          1458:     outb(bval,port);
        !          1459:     udelay(8); /* Delay();*/
        !          1460:     bval = 0x10;       /* SK=0 */
        !          1461:     outb(bval,port);
        !          1462:     udelay(8); /* Delay();*/
        !          1463:     bval = inb(port);
        !          1464:     if(bval & 0x01)
        !          1465:        return( 1 );
        !          1466:     else
        !          1467:        return( 0 );
        !          1468: }
        !          1469: 
        !          1470: 
        !          1471: USHORT EEpromGetData(USHORT scsiIOPort)
        !          1472: {
        !          1473:     UCHAR i;
        !          1474:     UCHAR carryFlag;
        !          1475:     USHORT wval;
        !          1476: 
        !          1477:     wval = 0;
        !          1478:     for(i=0;i<16;i++)
        !          1479:     {
        !          1480:        wval <<= 1;
        !          1481:        carryFlag = EEpromInDo(scsiIOPort);
        !          1482:        wval |= carryFlag;
        !          1483:     }
        !          1484:     return( wval );
        !          1485: }
        !          1486: 
        !          1487: 
        !          1488: void  ReadEEprom( PUCHAR EEpromBuf, USHORT scsiIOPort )
        !          1489: {
        !          1490:     UCHAR cmd;
        !          1491: 
        !          1492:     cmd = EEPROM_READ;
        !          1493: loop_rd:
        !          1494:     EnDisableCE(ENABLE_CE, scsiIOPort);
        !          1495:     EEpromPrepare(cmd, scsiIOPort);
        !          1496:     *((PUSHORT)EEpromBuf) = EEpromGetData(scsiIOPort);
        !          1497:     EEpromBuf++;
        !          1498:     EEpromBuf++;
        !          1499:     cmd++;
        !          1500:     EnDisableCE(DISABLE_CE, scsiIOPort);
        !          1501:     if(cmd & 0x3f)
        !          1502:        goto loop_rd;
        !          1503: }
        !          1504: 
        !          1505: 
        !          1506: USHORT CheckEEpromCheckSum( PUCHAR EEpromBuf, USHORT scsiIOPort)
        !          1507: {
        !          1508:     USHORT wval,port, *ptr;
        !          1509:     UCHAR  i,bval;
        !          1510: 
        !          1511:     port = (scsiIOPort & 0xff00) + GPCNTL;
        !          1512:     bval = 0x09;                       /* configure IO Pin */
        !          1513:     outb(bval,port);
        !          1514:     ReadEEprom(EEpromBuf,scsiIOPort);  /* read eeprom data */
        !          1515:     wval = 0;
        !          1516:     ptr = (PUSHORT) EEpromBuf;
        !          1517:     for(i=0; i<128 ;i+=2, ptr++)
        !          1518:        wval += *ptr;
        !          1519:     return( (wval == 0x1234) ? 0 : -1);
        !          1520: }
        !          1521: 
        !          1522: 
        !          1523: 
        !          1524: static void
        !          1525: DC390W_download_script (struct Scsi_Host *host)
        !          1526: {
        !          1527:     ULONG   wlval, wlval1, length, alignm;
        !          1528:     USHORT  j, k, m;
        !          1529:     USHORT  ioport;
        !          1530:     UCHAR   bval;
        !          1531:     PACB    pACB;
        !          1532:     PSRB    pSRB;
        !          1533:     void    *pSrc, *pSrc1;
        !          1534:     ULONG   *pStart;
        !          1535:     ULONG   Ent_reselected;
        !          1536:     ULONG   Ent_reselecttag;
        !          1537:     ULONG   Ent_select0;
        !          1538:     ULONG   Ent_select1;
        !          1539:     ULONG   Ent_check_phase;
        !          1540:     ULONG   Ent_status1_phase;
        !          1541:     ULONG   Ent_command_phase;
        !          1542:     ULONG   Ent_jump_table0;
        !          1543:     ULONG   Ent_din_phaseB;
        !          1544:     ULONG   Ent_dout_phaseB;
        !          1545:     ULONG   Ent_din_pad_0;
        !          1546:     ULONG   Ent_dout_pad_0;
        !          1547:     ULONG   Ent_jump_tablew;
        !          1548:     ULONG   Ent_din_pad_1;
        !          1549:     ULONG   Ent_dout_pad_1;
        !          1550:     ULONG   Ent_mout_phase;
        !          1551:     ULONG   Ent_status_phase;
        !          1552:     ULONG   Ent_min_phase;
        !          1553:     ULONG   Ent_jump_msgok;
        !          1554:     ULONG   Ent_msg__1;
        !          1555:     ULONG   Ent_msg___3;
        !          1556:     ULONG   Ent_msg___2;
        !          1557:     ULONG   Ent_set_atn;
        !          1558:     ULONG   Ent_msg__a;
        !          1559:     ULONG   Ent_msg__23;
        !          1560:     ULONG   Ent_msg__3;
        !          1561:     ULONG   Ent_msg__4;
        !          1562:     ULONG   Ent_clr_atn;
        !          1563:     ULONG   Ent_din_phaseW;
        !          1564:     ULONG   Ent_dout_phaseW;
        !          1565:     ULONG   Ent_din_pad_addrB;
        !          1566:     ULONG   Ent_dout_pad_addrB;
        !          1567:     ULONG   Ent_din_pad_addrW;
        !          1568:     ULONG   Ent_dout_pad_addrW;
        !          1569: 
        !          1570: 
        !          1571:     pACB = (PACB) host->hostdata;
        !          1572:     ioport = pACB->IOPortBase;
        !          1573:     bval = SCRATCHAB_AS_BASE;   /* set scratchB contains 4K RAM base address */
        !          1574:     outb(bval,ioport+CTEST2);
        !          1575: 
        !          1576:     wlval = inl((ioport+SCRATCHB)); /* get starting address of 4K RAM */
        !          1577: /*  wlval += 0x800; */          /* point to Upper 2K RAM */
        !          1578:     DesPhysAddr[0] = wlval;     /* destination address */
        !          1579: 
        !          1580: #ifdef DC390W_DEBUG0
        !          1581:        printk("DesAddr=%8x,",(UINT) wlval);
        !          1582: #endif
        !          1583:     bval = 0;                   /* set Scratch_A and Scratch_B to normal mode */
        !          1584:     outb(bval,ioport+CTEST2);
        !          1585: 
        !          1586:    /*-------------------------------------------------------------------
        !          1587:     * patch the label in jump instruction: using offset relative
        !          1588:     * to start_script
        !          1589:     *------------------------------------------------------------------*/
        !          1590: 
        !          1591:     Ent_reselected      = (ULONG) reselected - (ULONG) start_script;
        !          1592:     Ent_reselecttag     = (ULONG) reselecttag - (ULONG) start_script;
        !          1593:     Ent_select0         = (ULONG) select0 - (ULONG) start_script;
        !          1594:     Ent_select1         = (ULONG) select1 - (ULONG) start_script;
        !          1595:     Ent_check_phase     = (ULONG) check_phase - (ULONG) start_script;
        !          1596:     Ent_status1_phase   = (ULONG) status1_phase - (ULONG) start_script;
        !          1597:     Ent_command_phase   = (ULONG) command_phase - (ULONG) start_script;
        !          1598:     Ent_din_phaseB      = (ULONG) din_phaseB - (ULONG) start_script;
        !          1599:     Ent_dout_phaseB     = (ULONG) dout_phaseB - (ULONG) start_script;
        !          1600:     Ent_din_phaseW      = (ULONG) din_phaseW - (ULONG) start_script;
        !          1601:     Ent_dout_phaseW     = (ULONG) dout_phaseW - (ULONG) start_script;
        !          1602:     Ent_jump_table0     = (ULONG) jump_table0 - (ULONG) start_script;
        !          1603:     Ent_din_pad_0       = (ULONG) din_pad_0 - (ULONG) start_script;
        !          1604:     Ent_din_pad_addrB   = (ULONG) din_pad_addrB - (ULONG) start_script;
        !          1605:     Ent_dout_pad_0      = (ULONG) dout_pad_0 - (ULONG) start_script;
        !          1606:     Ent_dout_pad_addrB  = (ULONG) dout_pad_addrB - (ULONG) start_script;
        !          1607:     Ent_jump_tablew     = (ULONG) jump_tablew - (ULONG) start_script;
        !          1608:     Ent_din_pad_1       = (ULONG) din_pad_1 - (ULONG) start_script;
        !          1609:     Ent_din_pad_addrW   = (ULONG) din_pad_addrW - (ULONG) start_script;
        !          1610:     Ent_dout_pad_1      = (ULONG) dout_pad_1 - (ULONG) start_script;
        !          1611:     Ent_dout_pad_addrW  = (ULONG) dout_pad_addrW - (ULONG) start_script;
        !          1612:     Ent_mout_phase      = (ULONG) mout_phase - (ULONG) start_script;
        !          1613:     Ent_status_phase    = (ULONG) status_phase - (ULONG) start_script;
        !          1614:     Ent_min_phase       = (ULONG) min_phase - (ULONG) start_script;
        !          1615:     Ent_jump_msgok      = (ULONG) jump_msgok - (ULONG) start_script;
        !          1616:     Ent_msg__1          = (ULONG) msg__1 - (ULONG) start_script;
        !          1617:     Ent_msg___3         = (ULONG) msg___3 - (ULONG) start_script;
        !          1618:     Ent_msg___2         = (ULONG) msg___2 - (ULONG) start_script;
        !          1619:     Ent_set_atn         = (ULONG) set_atn - (ULONG) start_script;
        !          1620:     Ent_msg__a          = (ULONG) msg__a - (ULONG) start_script;
        !          1621:     Ent_msg__23         = (ULONG) msg__23 - (ULONG) start_script;
        !          1622:     Ent_msg__3          = (ULONG) msg__3 - (ULONG) start_script;
        !          1623:     Ent_msg__4          = (ULONG) msg__4 - (ULONG) start_script;
        !          1624:     Ent_clr_atn         = (ULONG) clr_atn - (ULONG) start_script;
        !          1625: 
        !          1626:     jmp_select0[0]       = Ent_select0 + wlval;
        !          1627:     jmp_reselected[0]    = Ent_reselected + wlval;
        !          1628:     jmp_check_phase[0]   = Ent_check_phase + wlval;
        !          1629:     jmp_check_phase1[0]   = Ent_check_phase + wlval;
        !          1630:     jmp_check_phase2[0]   = Ent_check_phase + wlval;
        !          1631:     jmp_check_phase3[0]   = Ent_check_phase + wlval;
        !          1632:     jmp_check_phase4[0]   = Ent_check_phase + wlval;
        !          1633:     jmp_check_phase5[0]   = Ent_check_phase + wlval;
        !          1634:     jmp_check_phase6[0]   = Ent_check_phase + wlval;
        !          1635:     jmp_status1_phase[0]  = Ent_status1_phase + wlval;
        !          1636:     jmp_status1_phase1[0] = Ent_status1_phase + wlval;
        !          1637:     jmp_status1_phase2[0] = Ent_status1_phase + wlval;
        !          1638:     jmp_status1_phase3[0] = Ent_status1_phase + wlval;
        !          1639:     jmp_command_phase[0]  = Ent_command_phase + wlval;
        !          1640:     for(j=0,k=1,m=0; j< (MAX_SG_LIST_BUF+1); j++)
        !          1641:     {
        !          1642:        jmp_dio_phaseB[k] = Ent_din_phaseB + m + wlval;
        !          1643:        jmp_dio_phaseW[k] = Ent_din_phaseW + m + wlval;
        !          1644:        k += 2;
        !          1645:        jmp_dio_phaseB[k] = Ent_dout_phaseB + m + wlval;
        !          1646:        jmp_dio_phaseW[k] = Ent_dout_phaseW + m + wlval;
        !          1647:        k += 2;
        !          1648:        m += 8;
        !          1649:     }
        !          1650:     jmp_din_pad_0[0]     = Ent_din_pad_0 + wlval;
        !          1651:     jmp_dout_pad_0[0]    = Ent_dout_pad_0 + wlval;
        !          1652:     jmp_din_pad_addrB[0]  = Ent_din_pad_addrB + wlval;
        !          1653:     jmp_dout_pad_addrB[0] = Ent_dout_pad_addrB + wlval;
        !          1654:     jmp_din_pad_addrW[0]  = Ent_din_pad_addrW + wlval;
        !          1655:     jmp_dout_pad_addrW[0] = Ent_dout_pad_addrW + wlval;
        !          1656:     jmp_din_pad_1[0]     = Ent_din_pad_1 + wlval;
        !          1657:     jmp_dout_pad_1[0]    = Ent_dout_pad_1 + wlval;
        !          1658:     jmp_status_phase[0]   = Ent_status_phase + wlval;
        !          1659:     jmp_min_phase[0]     = Ent_min_phase + wlval;
        !          1660:     jmp_mout_phase[0]    = Ent_mout_phase + wlval;
        !          1661:     jmp_jump_msgok[0]    = Ent_jump_msgok + wlval;
        !          1662:     jmp_msg__1[0]        = Ent_msg__1 + wlval;
        !          1663:     jmp_msg___3[0]       = Ent_msg___3 + wlval;
        !          1664:     jmp_msg___2[0]       = Ent_msg___2 + wlval;
        !          1665:     jmp_msg__a[0]        = Ent_msg__a + wlval;
        !          1666:     jmp_msg__a1[0]       = Ent_msg__a + wlval;
        !          1667:     jmp_msg__a2[0]       = Ent_msg__a + wlval;
        !          1668:     jmp_msg__23[0]       = Ent_msg__23 + wlval;
        !          1669:     jmp_msg__3[0]        = Ent_msg__3 + wlval;
        !          1670:     jmp_msg__4[0]        = Ent_msg__4 + wlval;
        !          1671: 
        !          1672:    /*--------------------------------------------------------------------
        !          1673:    // patch the element in ACB struct: using Physical address
        !          1674:    //-------------------------------------------------------------------*/
        !          1675: 
        !          1676: #ifndef VERSION_ELF_1_2_13
        !          1677:     wlval1 = virt_to_phys( pACB->msgin123 );
        !          1678: #else
        !          1679:     wlval1 = (ULONG) pACB->msgin123;
        !          1680: #endif
        !          1681:     ACB_msgin123_1[0] = wlval1;
        !          1682:     ACB_msgin123_2[0] = wlval1;
        !          1683:     ACB_msgin123_3[0] = wlval1;
        !          1684:     ACB_msgin123_4[0] = wlval1;
        !          1685:     ACB_msgin123_5[0] = wlval1;
        !          1686:     ACB_msgin123_6[0] = wlval1;
        !          1687:     ACB_msgin123_7[0] = wlval1;
        !          1688: 
        !          1689: #ifndef VERSION_ELF_1_2_13
        !          1690:     ACB_status[0] = virt_to_phys( &pACB->status );
        !          1691: #else
        !          1692:     ACB_status[0] = (ULONG) &pACB->status;
        !          1693: #endif
        !          1694:    /*--------------------------------------------------------------------
        !          1695:    // patch the element in SRB struct: using offset in struct
        !          1696:    //-------------------------------------------------------------------*/
        !          1697: 
        !          1698:     pSRB = (PSRB) pACB->SRB_array;
        !          1699:     select1[0] = (select1[0] & 0xffff0000) + ((ULONG) &pSRB->__select - (ULONG) &pSRB->CmdBlock);
        !          1700:     SRB_msgout0[0]  = (ULONG) &pSRB->__msgout0 - (ULONG) &pSRB->CmdBlock;
        !          1701:     SRB_msgout01[0] = (ULONG) &pSRB->__msgout0 - (ULONG) &pSRB->CmdBlock;
        !          1702:     SRB_command[0] = (ULONG) &pSRB->__command - (ULONG) &pSRB->CmdBlock;
        !          1703:     SRB_SegmentPad[0]  = (ULONG) &pSRB->SegmentPad - (ULONG) &pSRB->CmdBlock;
        !          1704:     SRB_SegmentPad1[0] = (ULONG) &pSRB->SegmentPad - (ULONG) &pSRB->CmdBlock;
        !          1705:     SRB_SegmentPad2[0] = (ULONG) &pSRB->SegmentPad - (ULONG) &pSRB->CmdBlock;
        !          1706:     SRB_SegmentPad3[0] = (ULONG) &pSRB->SegmentPad - (ULONG) &pSRB->CmdBlock;
        !          1707:     wlval = (ULONG) &pSRB->Segment0 - (ULONG) &pSRB->CmdBlock;
        !          1708:     for(j=0,k=1; j<(MAX_SG_LIST_BUF+1); j++)
        !          1709:     {
        !          1710:         din_phaseB[k]  = wlval;
        !          1711:         dout_phaseB[k] = wlval;
        !          1712:         din_phaseW[k]  = wlval;
        !          1713:         dout_phaseW[k] = wlval;
        !          1714:         k += 2;
        !          1715:         wlval += 8;
        !          1716:     }
        !          1717: 
        !          1718: 
        !          1719:     bval = inb(ioport+DCNTL);
        !          1720:     bval |= IRQ_DISABLE;
        !          1721:     outb(bval,ioport+DCNTL);  /* disable interrupt */
        !          1722: 
        !          1723: /*  pSrc = scsi_init_malloc( 2048, GFP_ATOMIC); */
        !          1724:     pSrc = scsi_init_malloc( 4096, GFP_ATOMIC); /* 1.11 */
        !          1725: #ifdef DC390W_DEBUG0
        !          1726:        printk("SrcAlloc=%8x,",(UINT) pSrc);
        !          1727: #endif
        !          1728:     alignm = 4 - (((ULONG) pSrc) & 3);
        !          1729:     pSrc1 = (void *)(((ULONG) pSrc) + alignm);
        !          1730:     length = (ULONG) end_script - (ULONG) start_script;
        !          1731:     memcpy( pSrc1, (void *) start_script, length);
        !          1732:     pStart = (ULONG *) ((ULONG) start_mov - (ULONG) start_script);
        !          1733:     pStart =(ULONG *) (((ULONG) pStart) + ((ULONG) pSrc1));
        !          1734: 
        !          1735: #ifdef DC390W_DEBUG0
        !          1736:        printk("SrcAddr=%8x,\n",(UINT) pSrc1);
        !          1737: #endif
        !          1738: #ifndef VERSION_ELF_1_2_13
        !          1739:     (ULONG *)pStart[1] = virt_to_phys( pSrc1 );
        !          1740: #else
        !          1741:     (ULONG *)pStart[1] = (ULONG) pSrc1;
        !          1742: #endif
        !          1743: 
        !          1744: /* wlval = virt_to_phys( start_script ); */ /* physical address of start_script */
        !          1745: /* SrcPhysAddr[0] = wlval; */  /* sources address */
        !          1746: 
        !          1747: /* start to download SCRIPT instruction to the RAM of NCR53c825A,875 */
        !          1748: 
        !          1749: /* wlval = virt_to_phys( start_mov ); */
        !          1750: 
        !          1751: #ifndef VERSION_ELF_1_2_13
        !          1752:    wlval = virt_to_phys( pStart );
        !          1753: #else
        !          1754:    wlval = (ULONG) pStart;
        !          1755: #endif
        !          1756: 
        !          1757:    outl(wlval,ioport+DSP);
        !          1758: 
        !          1759:    bval = inb(ioport+ISTAT);
        !          1760:    while(!(bval & DMA_INT_PENDING))    /* check load start_script is finished? */
        !          1761:        bval = inb(ioport+ISTAT);
        !          1762: 
        !          1763:    bval = inb(ioport+DSTAT); /* clear interrupt */
        !          1764: 
        !          1765:    bval = inb(ioport+DCNTL);
        !          1766:    bval &= ~IRQ_DISABLE;
        !          1767:    outb(bval,ioport+DCNTL); /* re-enable interrupt */
        !          1768: 
        !          1769:    scsi_init_free((char *) pSrc, 4096);
        !          1770: 
        !          1771:    wlval = DesPhysAddr[0];     /* starting addr of RAM */
        !          1772:    wlval -=  (ULONG) start_script;
        !          1773: 
        !          1774:    pACB->jmp_reselect   = wlval  + (ULONG) start_script;
        !          1775:    pACB->jmp_select     = wlval  + (ULONG) select1;
        !          1776:    pACB->jmp_table8     = wlval  + (ULONG) jump_table0;
        !          1777:    pACB->jmp_set_atn    = wlval  + (ULONG) set_atn;
        !          1778:    pACB->jmp_clear_ack  = wlval  + (ULONG) msg__a;
        !          1779:    pACB->jmp_next       = wlval  + (ULONG) check_phase;
        !          1780:    pACB->jmp_din8       = wlval  + (ULONG) din_phaseB+8;
        !          1781:    pACB->jmp_dout8      = wlval  + (ULONG) dout_phaseB+8;
        !          1782:    pACB->jmp_clear_atn  = wlval  + (ULONG) clr_atn;
        !          1783:    pACB->jmp_reselecttag = wlval  + (ULONG) reselecttag;
        !          1784: 
        !          1785:    wlval = pACB->jmp_reselect;
        !          1786:    outl(wlval,(ioport+DSP));
        !          1787:    return;
        !          1788: }
        !          1789: 
        !          1790: 
        !          1791: /***********************************************************************
        !          1792:  * Function : int DC390W_detect(Scsi_Host_Template *psht)
        !          1793:  *
        !          1794:  * Purpose : detects and initializes NCR53c825A,875 SCSI chips
        !          1795:  *          that were autoprobed, overridden on the LILO command line,
        !          1796:  *          or specified at compile time.
        !          1797:  *
        !          1798:  * Inputs : psht - template for this SCSI adapter
        !          1799:  *
        !          1800:  * Returns : number of host adapters detected
        !          1801:  *
        !          1802:  ***********************************************************************/
        !          1803: 
        !          1804: int
        !          1805: DC390W_detect(Scsi_Host_Template *psht)
        !          1806: {
        !          1807:     UCHAR   pci_bus, pci_device_fn, irq;
        !          1808: #ifndef VERSION_ELF_1_2_13
        !          1809:     UINT    io_port, ram_base;
        !          1810: #else
        !          1811:     ULONG   io_port, ram_base;
        !          1812: #endif
        !          1813:     USHORT  i;
        !          1814:     int     error = 0;
        !          1815:     USHORT  adaptCnt = 0;      /* Number of boards detected */
        !          1816:     USHORT  pci_index = 0;     /* Device index to PCI BIOS calls */
        !          1817:     USHORT  pci_index2 = 0;    /* Device index to PCI BIOS calls */
        !          1818:     USHORT  chipType = 0;
        !          1819: 
        !          1820: 
        !          1821: #ifndef VERSION_ELF_1_2_13
        !          1822:     psht->proc_dir = &proc_scsi_tmscsiw;
        !          1823: #endif
        !          1824: 
        !          1825:     InitialTime = 1;
        !          1826:     pSHT_start = psht;
        !          1827:     jmp_table16 = (ULONG) jump_tablew - (ULONG) jump_table0;
        !          1828:     jmp_din16 = (ULONG) din_phaseW - (ULONG) din_phaseB;
        !          1829:     jmp_dout16 = (ULONG) dout_phaseW - (ULONG) dout_phaseB;
        !          1830:     pACB_start = NULL;
        !          1831: 
        !          1832:     if ( pcibios_present() )
        !          1833:     {
        !          1834:        for (i = 0; i < MAX_ADAPTER_NUM; ++i)
        !          1835:        {
        !          1836:            if( !pcibios_find_device( PCI_VENDOR_ID_NCR,
        !          1837:                                PCI_DEVICE_ID_NCR53C825A,
        !          1838:                                pci_index, &pci_bus, &pci_device_fn) )
        !          1839:            {
        !          1840:                chipType = PCI_DEVICE_ID_NCR53C825A;
        !          1841:                pci_index++;
        !          1842:            }
        !          1843:            else if( !pcibios_find_device( PCI_VENDOR_ID_NCR,
        !          1844:                                PCI_DEVICE_ID_NCR53C875,
        !          1845:                                pci_index2, &pci_bus, &pci_device_fn) )
        !          1846:            {
        !          1847:                chipType = PCI_DEVICE_ID_NCR53C875;
        !          1848:                pci_index2++;
        !          1849:            }
        !          1850: 
        !          1851:            if( chipType )
        !          1852:            {
        !          1853:                error = pcibios_read_config_dword(pci_bus, pci_device_fn,
        !          1854:                                        PCI_BASE_ADDRESS_0, &io_port);
        !          1855:                error |= pcibios_read_config_dword(pci_bus, pci_device_fn,
        !          1856:                                        PCI_BASE_ADDRESS_2, &ram_base);
        !          1857:                error |= pcibios_read_config_byte(pci_bus, pci_device_fn,
        !          1858:                                                  PCI_INTERRUPT_LINE, &irq);
        !          1859:                if( error )
        !          1860:                {
        !          1861:                    printk("DC390W_detect: reading configuration registers error!\n");
        !          1862:                    InitialTime = 0;
        !          1863:                    return( 0 );
        !          1864:                }
        !          1865: 
        !          1866:                (USHORT) io_port = (USHORT) io_port & 0xFFFE;
        !          1867: #ifdef DC390W_DEBUG0
        !          1868:                printk("DC390W : IO_PORT=%4x,RAM_BASE=%8x,IRQ=%x,CHIPID=%x,\n",
        !          1869:                      (UINT) io_port, (UINT) ram_base, irq, (UCHAR)chipType);
        !          1870: #endif
        !          1871: 
        !          1872:                if( !DC390W_init(psht, chipType, io_port, irq, i) )
        !          1873:                    adaptCnt++;
        !          1874:                chipType = 0;
        !          1875:            }
        !          1876:            else
        !          1877:                break;
        !          1878:        }
        !          1879:     }
        !          1880:     InitialTime = 0;
        !          1881:     adapterCnt = adaptCnt;
        !          1882:     return( adaptCnt );
        !          1883: }
        !          1884: 
        !          1885: #ifndef VERSION_ELF_1_2_13
        !          1886: 
        !          1887: /********************************************************************
        !          1888:  * Function: tmscsiw_set_info()
        !          1889:  *
        !          1890:  * Purpose: Set adapter info (!)
        !          1891:  *
        !          1892:  * Not yet implemented
        !          1893:  *
        !          1894:  *******************************************************************/
        !          1895: 
        !          1896: int tmscsiw_set_info(char *buffer, int length, struct Scsi_Host *shpnt)
        !          1897: {
        !          1898:   return(-ENOSYS);  /* Currently this is a no-op */
        !          1899: }
        !          1900: 
        !          1901: /********************************************************************
        !          1902:  * Function: tmscsiw_proc_info(char* buffer, char **start,
        !          1903:  *                          off_t offset, int length, int hostno, int inout)
        !          1904:  *
        !          1905:  * Purpose: return SCSI Adapter/Device Info
        !          1906:  *
        !          1907:  * Input: buffer: Pointer to a buffer where to write info
        !          1908:  *       start :
        !          1909:  *       offset:
        !          1910:  *       hostno: Host adapter index
        !          1911:  *       inout : Read (=0) or set(!=0) info
        !          1912:  *
        !          1913:  * Output: buffer: contains info
        !          1914:  *        length; length of info in buffer
        !          1915:  *
        !          1916:  * return value: length
        !          1917:  *
        !          1918:  ********************************************************************/
        !          1919: 
        !          1920: /* KG: proc_info taken from driver aha152x.c */
        !          1921: 
        !          1922: #undef SPRINTF
        !          1923: #define SPRINTF(args...) pos += sprintf(pos, ## args)
        !          1924: 
        !          1925: #define YESNO(YN)\
        !          1926: if (YN) SPRINTF(" Yes ");\
        !          1927: else SPRINTF(" No  ")
        !          1928: 
        !          1929: int tmscsiw_proc_info(char *buffer, char **start,
        !          1930:                      off_t offset, int length, int hostno, int inout)
        !          1931: {
        !          1932:   int dev, spd, spd1;
        !          1933:   char *pos = buffer;
        !          1934:   PSH shpnt;
        !          1935:   PACB acbpnt;
        !          1936:   PDCB dcbpnt;
        !          1937:   unsigned long flags;
        !          1938: /*  Scsi_Cmnd *ptr; */
        !          1939: 
        !          1940:   acbpnt = pACB_start;
        !          1941: 
        !          1942:   while(acbpnt != (PACB)-1)
        !          1943:      {
        !          1944:        shpnt = acbpnt->pScsiHost;
        !          1945:        if (shpnt->host_no == hostno) break;
        !          1946:        acbpnt = acbpnt->pNextACB;
        !          1947:      }
        !          1948: 
        !          1949:   if (acbpnt == (PACB)-1) return(-ESRCH);
        !          1950:   if (!shpnt) return(-ESRCH);
        !          1951: 
        !          1952:   if(inout) /* Has data been written to the file ? */
        !          1953:     return(tmscsiw_set_info(buffer, length, shpnt));
        !          1954: 
        !          1955:   SPRINTF("Tekram DC390W/U/F (T) PCI SCSI Host Adadpter, ");
        !          1956:   SPRINTF("Driver Version 1.12, 1997/02/17\n");
        !          1957: 
        !          1958:   save_flags(flags);
        !          1959:   cli();
        !          1960: 
        !          1961:   SPRINTF("SCSI Host Nr %i, ", hostno);
        !          1962:   SPRINTF("DC390WUF Adapter Nr %i\n", acbpnt->AdapterIndex);
        !          1963:   SPRINTF("IOPortBase 0x%04x, ", acbpnt -> IOPortBase);
        !          1964:   SPRINTF("IRQLevel 0x%02x\n",acbpnt -> IRQLevel);
        !          1965: 
        !          1966:   SPRINTF("Adapter Type: ");
        !          1967:   switch(acbpnt->AdaptType)
        !          1968:      {
        !          1969:       case DC390W: SPRINTF("DC390W, Fast Wide SCSI \n"); break;
        !          1970:       case DC390U: SPRINTF("DC390U, Ultra SCSI\n"); break;
        !          1971:       case DC390F: SPRINTF("DC390F, Ultra Wide SCSI\n"); break;
        !          1972:       default: SPRINTF("Unknown !\n");
        !          1973:      }
        !          1974: 
        !          1975:   SPRINTF("MaxID %i, MaxLUN %i, ", acbpnt->max_id, acbpnt->max_lun);
        !          1976:   SPRINTF("AdapterID %i, AdapterLUN %i\n", acbpnt->AdaptSCSIID, acbpnt->AdaptSCSILUN);
        !          1977: 
        !          1978:   SPRINTF("TagMaxNum %i, Status %i\n", acbpnt->TagMaxNum, acbpnt->status);
        !          1979: 
        !          1980:   SPRINTF("Nr of attached devices: %i\n", acbpnt->DeviceCnt);
        !          1981: 
        !          1982:   SPRINTF("Un ID LUN Prty Sync DsCn SndS TagQ Wide NegoPeriod SyncSpeed SyncOffs\n");
        !          1983:   dcbpnt = acbpnt->pLinkDCB;
        !          1984: 
        !          1985:   for (dev = 0; dev < acbpnt->DeviceCnt; dev++)
        !          1986:      {
        !          1987:       SPRINTF("%02i %02i  %02i ", dev, dcbpnt->UnitSCSIID, dcbpnt->UnitSCSILUN);
        !          1988:       YESNO(dcbpnt->DevMode & PARITY_CHK_);
        !          1989:       YESNO(dcbpnt->DCBsxfer & OFFSET_MASK);
        !          1990:       YESNO(dcbpnt->DevMode & EN_DISCONNECT_);
        !          1991:       YESNO(dcbpnt->DevMode & SEND_START_);
        !          1992:       YESNO(dcbpnt->MaxCommand > 1);
        !          1993:       YESNO(dcbpnt->DCBscntl3 & EN_WIDE_SCSI);
        !          1994:       SPRINTF("  %03i ns ", (dcbpnt->NegoPeriod) << 2);
        !          1995:       if (dcbpnt->DCBsxfer & OFFSET_MASK)
        !          1996:       {
        !          1997:         spd = 1000/(dcbpnt->SyncPeriod <<2);
        !          1998:         spd1 = 1000%(dcbpnt->SyncPeriod <<2);
        !          1999:         spd1 = (spd1 * 10)/(dcbpnt->SyncPeriod <<2);
        !          2000:         SPRINTF("   %2i.%1i M      %02i\n", spd, spd1, dcbpnt->DCBsxfer & OFFSET_MASK);
        !          2001:       }
        !          2002:       else SPRINTF("\n");
        !          2003:       /* Add more info ...*/
        !          2004:       dcbpnt = dcbpnt->pNextDCB;
        !          2005:      }
        !          2006: 
        !          2007:   restore_flags(flags);
        !          2008:   *start = buffer + offset;
        !          2009: 
        !          2010:   if (pos - buffer < offset)
        !          2011:     return 0;
        !          2012:   else if (pos - buffer - offset < length)
        !          2013:     return pos - buffer - offset;
        !          2014:   else
        !          2015:     return length;
        !          2016: }
        !          2017: #endif /* VERSION_ELF_1_2_13 */
        !          2018: 
        !          2019: #ifdef MODULE
        !          2020: 
        !          2021: /***********************************************************************
        !          2022:  * Function : static int DC390W_shutdown (struct Scsi_Host *host)
        !          2023:  *
        !          2024:  * Purpose : does a clean (we hope) shutdown of the NCR SCSI chip.
        !          2025:  *          Use prior to dumping core, unloading the NCR driver, etc.
        !          2026:  *
        !          2027:  * Returns : 0 on success
        !          2028:  ***********************************************************************/
        !          2029: static int
        !          2030: DC390W_shutdown (struct Scsi_Host *host)
        !          2031: {
        !          2032:     USHORT   ioport;
        !          2033:     unsigned long flags;
        !          2034:     PACB pACB = (PACB) host->hostdata;
        !          2035: 
        !          2036:     ioport = (unsigned int) pACB->IOPortBase;
        !          2037: 
        !          2038:     save_flags (flags);
        !          2039:     cli();
        !          2040: 
        !          2041: /*  pACB->soft_reset(host); */
        !          2042: /*
        !          2043:  * For now, we take the simplest solution : reset the SCSI bus. Eventually,
        !          2044:  * - If a command is connected, kill it with an ABORT message
        !          2045:  * - If commands are disconnected, connect to each target/LUN and
        !          2046:  *     do a ABORT, followed by a SOFT reset, followed by a hard
        !          2047:  *     reset.
        !          2048:  */
        !          2049: 
        !          2050: #ifdef DC390W_DEBUG0
        !          2051:     printk("DC390W: shutdown,");
        !          2052: #endif
        !          2053:     outb(ASSERT_RST, ioport+SCNTL1);
        !          2054:     udelay(25); /* Minimum amount of time to assert RST */
        !          2055:     outb(0, ioport+SCNTL1);
        !          2056:     restore_flags (flags);
        !          2057:     return( 0 );
        !          2058: }
        !          2059: 
        !          2060: 
        !          2061: int DC390W_release(struct Scsi_Host *host)
        !          2062: {
        !          2063:     int irq_count;
        !          2064:     struct Scsi_Host *tmp;
        !          2065: 
        !          2066:     DC390W_shutdown (host);
        !          2067: 
        !          2068:     if (host->irq != IRQ_NONE)
        !          2069:     {
        !          2070:        for (irq_count = 0, tmp = pSH_start; tmp; tmp = tmp->next)
        !          2071:        {
        !          2072:            if ( tmp->irq == host->irq )
        !          2073:                ++irq_count;
        !          2074:        }
        !          2075:        if (irq_count == 1)
        !          2076:         {
        !          2077: #ifdef DC390W_DEBUG0
        !          2078:            printk("DC390W: Free IRQ %i.",host->irq);
        !          2079: #endif
        !          2080: #ifndef VERSION_ELF_1_2_13
        !          2081:            free_irq(host->irq,NULL);
        !          2082: #else
        !          2083:            free_irq(host->irq);
        !          2084: #endif
        !          2085:         }
        !          2086:     }
        !          2087: 
        !          2088:     release_region(host->io_port,host->n_io_port);
        !          2089: 
        !          2090:    return( 1 );
        !          2091: }
        !          2092: 
        !          2093: Scsi_Host_Template driver_template = DC390WUF;
        !          2094: #include "scsi_module.c"
        !          2095: #endif /* def MODULE */
        !          2096: 

unix.superglobalmegacorp.com

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