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