Annotation of Gnu-Mach/i386/i386at/gpl/linux/scsi/u14-34f.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *      u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
        !             3:  *
        !             4:  *      13 Jun 1995 rev. 2.01 for linux 1.2.10
        !             5:  *         HAVE_OLD_UX4F_FIRMWARE should be defined for U34F boards when
        !             6:  *         the firmware prom is not the lastest one (28008-006).
        !             7:  *
        !             8:  *      11 Mar 1995 rev. 2.00 for linux 1.2.0
        !             9:  *          Fixed a bug which prevented media change detection for removable
        !            10:  *          disk drives.
        !            11:  *
        !            12:  *      23 Feb 1995 rev. 1.18 for linux 1.1.94
        !            13:  *          Added a check for scsi_register returning NULL.
        !            14:  *
        !            15:  *      11 Feb 1995 rev. 1.17 for linux 1.1.91
        !            16:  *          U14F qualified to run with 32 sglists.
        !            17:  *          Now DEBUG_RESET is disabled by default.
        !            18:  *
        !            19:  *       9 Feb 1995 rev. 1.16 for linux 1.1.90
        !            20:  *          Use host->wish_block instead of host->block.
        !            21:  *
        !            22:  *       8 Feb 1995 rev. 1.15 for linux 1.1.89
        !            23:  *          Cleared target_time_out counter while performing a reset.
        !            24:  *
        !            25:  *      28 Jan 1995 rev. 1.14 for linux 1.1.86
        !            26:  *          Added module support.
        !            27:  *          Log and do a retry when a disk drive returns a target status
        !            28:  *          different from zero on a recovered error.
        !            29:  *          Auto detects if U14F boards have an old firmware revision.
        !            30:  *          Max number of scatter/gather lists set to 16 for all boards
        !            31:  *          (most installation run fine using 33 sglists, while other
        !            32:  *          has problems when using more then 16).
        !            33:  *
        !            34:  *      16 Jan 1995 rev. 1.13 for linux 1.1.81
        !            35:  *          Display a message if check_region detects a port address
        !            36:  *          already in use.
        !            37:  *
        !            38:  *      15 Dec 1994 rev. 1.12 for linux 1.1.74
        !            39:  *          The host->block flag is set for all the detected ISA boards.
        !            40:  *
        !            41:  *      30 Nov 1994 rev. 1.11 for linux 1.1.68
        !            42:  *          Redo i/o on target status CHECK_CONDITION for TYPE_DISK only.
        !            43:  *          Added optional support for using a single board at a time.
        !            44:  *
        !            45:  *      14 Nov 1994 rev. 1.10 for linux 1.1.63
        !            46:  *
        !            47:  *      28 Oct 1994 rev. 1.09 for linux 1.1.58  Final BETA release.
        !            48:  *      16 Jul 1994 rev. 1.00 for linux 1.1.29  Initial ALPHA release.
        !            49:  *
        !            50:  *          This driver is a total replacement of the original UltraStor 
        !            51:  *          scsi driver, but it supports ONLY the 14F and 34F boards.
        !            52:  *          It can be configured in the same kernel in which the original
        !            53:  *          ultrastor driver is configured to allow the original U24F
        !            54:  *          support.
        !            55:  * 
        !            56:  *          Multiple U14F and/or U34F host adapters are supported.
        !            57:  *
        !            58:  *      Copyright (C) 1994, 1995 Dario Ballabio ([email protected])
        !            59:  *
        !            60:  *      WARNING: if your 14/34F board has an old firmware revision (see below)
        !            61:  *               you must change "#undef" into "#define" in the following
        !            62:  *               statement.
        !            63:  */
        !            64: #undef HAVE_OLD_UX4F_FIRMWARE
        !            65: /*
        !            66:  *  The UltraStor 14F, 24F, and 34F are a family of intelligent, high
        !            67:  *  performance SCSI-2 host adapters.
        !            68:  *  Here is the scoop on the various models:
        !            69:  *
        !            70:  *  14F - ISA first-party DMA HA with floppy support and WD1003 emulation.
        !            71:  *  24F - EISA Bus Master HA with floppy support and WD1003 emulation.
        !            72:  *  34F - VESA Local-Bus Bus Master HA (no WD1003 emulation).
        !            73:  *
        !            74:  *  This code has been tested with up to two U14F boards, using both 
        !            75:  *  firmware 28004-005/38004-004 (BIOS rev. 2.00) and the latest firmware
        !            76:  *  28004-006/38004-005 (BIOS rev. 2.01). 
        !            77:  *
        !            78:  *  The latest firmware is required in order to get reliable operations when 
        !            79:  *  clustering is enabled. ENABLE_CLUSTERING provides a performance increase
        !            80:  *  up to 50% on sequential access.
        !            81:  *
        !            82:  *  Since the Scsi_Host_Template structure is shared among all 14F and 34F,
        !            83:  *  the last setting of use_clustering is in effect for all of these boards.
        !            84:  *
        !            85:  *  Here a sample configuration using two U14F boards:
        !            86:  *
        !            87:  U14F0: PORT 0x330, BIOS 0xc8000, IRQ 11, DMA 5, SG 32, Mbox 16, CmdLun 2, C1.
        !            88:  U14F1: PORT 0x340, BIOS 0x00000, IRQ 10, DMA 6, SG 32, Mbox 16, CmdLun 2, C1.
        !            89:  *
        !            90:  *  The boot controller must have its BIOS enabled, while other boards can
        !            91:  *  have their BIOS disabled, or enabled to an higher address.
        !            92:  *  Boards are named Ux4F0, Ux4F1..., according to the port address order in
        !            93:  *  the io_port[] array.
        !            94:  *  
        !            95:  *  The following facts are based on real testing results (not on
        !            96:  *  documentation) on the above U14F board.
        !            97:  *  
        !            98:  *  - The U14F board should be jumpered for bus on time less or equal to 7 
        !            99:  *    microseconds, while the default is 11 microseconds. This is order to 
        !           100:  *    get acceptable performance while using floppy drive and hard disk 
        !           101:  *    together. The jumpering for 7 microseconds is: JP13 pin 15-16, 
        !           102:  *    JP14 pin 7-8 and pin 9-10.
        !           103:  *    The reduction has a little impact on scsi performance.
        !           104:  *  
        !           105:  *  - If scsi bus length exceeds 3m., the scsi bus speed needs to be reduced
        !           106:  *    from 10Mhz to 5Mhz (do this by inserting a jumper on JP13 pin 7-8).
        !           107:  *
        !           108:  *  - If U14F on board firmware is older than 28004-006/38004-005,
        !           109:  *    the U14F board is unable to provide reliable operations if the scsi 
        !           110:  *    request length exceeds 16Kbyte. When this length is exceeded the
        !           111:  *    behavior is: 
        !           112:  *    - adapter_status equal 0x96 or 0xa3 or 0x93 or 0x94;
        !           113:  *    - adapter_status equal 0 and target_status equal 2 on for all targets
        !           114:  *      in the next operation following the reset.
        !           115:  *    This sequence takes a long time (>3 seconds), so in the meantime
        !           116:  *    the SD_TIMEOUT in sd.c could expire giving rise to scsi aborts
        !           117:  *    (SD_TIMEOUT has been increased from 3 to 6 seconds in 1.1.31).
        !           118:  *    Because of this I had to DISABLE_CLUSTERING and to work around the
        !           119:  *    bus reset in the interrupt service routine, returning DID_BUS_BUSY
        !           120:  *    so that the operations are retried without complains from the scsi.c
        !           121:  *    code.
        !           122:  *    Any reset of the scsi bus is going to kill tape operations, since
        !           123:  *    no retry is allowed for tapes. Bus resets are more likely when the
        !           124:  *    scsi bus is under heavy load.
        !           125:  *    Requests using scatter/gather have a maximum length of 16 x 1024 bytes 
        !           126:  *    when DISABLE_CLUSTERING is in effect, but unscattered requests could be
        !           127:  *    larger than 16Kbyte.
        !           128:  *
        !           129:  *    The new firmware has fixed all the above problems.
        !           130:  *
        !           131:  *  For U34F boards the latest bios prom is 38008-002 (BIOS rev. 2.01),
        !           132:  *  the latest firmware prom is 28008-006. Older firmware 28008-005 has
        !           133:  *  problems when using more then 16 scatter/gather lists.
        !           134:  *
        !           135:  *  In order to support multiple ISA boards in a reliable way,
        !           136:  *  the driver sets host->wish_block = TRUE for all ISA boards.
        !           137:  */
        !           138: 
        !           139: #if defined(MODULE)
        !           140: #include <linux/module.h>
        !           141: #include <linux/version.h>
        !           142: #endif
        !           143: 
        !           144: #include <linux/string.h>
        !           145: #include <linux/sched.h>
        !           146: #include <linux/kernel.h>
        !           147: #include <linux/ioport.h>
        !           148: #include <asm/io.h>
        !           149: #include <asm/system.h>
        !           150: #include <linux/proc_fs.h>
        !           151: #include <linux/blk.h>
        !           152: #include "scsi.h"
        !           153: #include "hosts.h"
        !           154: #include "sd.h"
        !           155: #include <asm/dma.h>
        !           156: #include <asm/irq.h>
        !           157: #include "u14-34f.h"
        !           158: #include<linux/stat.h>
        !           159: 
        !           160: struct proc_dir_entry proc_scsi_u14_34f = {
        !           161:     PROC_SCSI_U14_34F, 6, "u14_34f",
        !           162:     S_IFDIR | S_IRUGO | S_IXUGO, 2
        !           163: };
        !           164: 
        !           165: /* Values for the PRODUCT_ID ports for the 14/34F */
        !           166: #define PRODUCT_ID1  0x56
        !           167: #define PRODUCT_ID2  0x40        /* NOTE: Only upper nibble is used */
        !           168: 
        !           169: /* Subversion values */
        !           170: #define ISA  0
        !           171: #define ESA 1
        !           172: 
        !           173: #define OP_HOST_ADAPTER   0x1
        !           174: #define OP_SCSI           0x2
        !           175: #define OP_RESET          0x4
        !           176: #define DTD_SCSI          0x0
        !           177: #define DTD_IN            0x1
        !           178: #define DTD_OUT           0x2
        !           179: #define DTD_NONE          0x3
        !           180: #define HA_CMD_INQUIRY    0x1
        !           181: #define HA_CMD_SELF_DIAG  0x2
        !           182: #define HA_CMD_READ_BUFF  0x3
        !           183: #define HA_CMD_WRITE_BUFF 0x4
        !           184: 
        !           185: #undef  DEBUG_DETECT
        !           186: #undef  DEBUG_INTERRUPT
        !           187: #undef  DEBUG_STATISTICS
        !           188: #undef  DEBUG_RESET
        !           189: 
        !           190: #define MAX_TARGET 8
        !           191: #define MAX_IRQ 16
        !           192: #define MAX_BOARDS 4
        !           193: #define MAX_MAILBOXES 16
        !           194: #define MAX_SGLIST 32
        !           195: #define MAX_SAFE_SGLIST 16
        !           196: #define MAX_CMD_PER_LUN 2
        !           197: 
        !           198: #define FALSE 0
        !           199: #define TRUE 1
        !           200: #define FREE 0
        !           201: #define IN_USE   1
        !           202: #define LOCKED   2
        !           203: #define IN_RESET 3
        !           204: #define IGNORE   4
        !           205: #define NO_IRQ  0xff
        !           206: #define NO_DMA  0xff
        !           207: #define MAXLOOP 200000
        !           208: 
        !           209: #define REG_LCL_MASK      0
        !           210: #define REG_LCL_INTR      1
        !           211: #define REG_SYS_MASK      2
        !           212: #define REG_SYS_INTR      3
        !           213: #define REG_PRODUCT_ID1   4
        !           214: #define REG_PRODUCT_ID2   5
        !           215: #define REG_CONFIG1       6
        !           216: #define REG_CONFIG2       7
        !           217: #define REG_OGM           8
        !           218: #define REG_ICM           12
        !           219: #define REGION_SIZE       13
        !           220: #define BSY_ASSERTED      0x01
        !           221: #define IRQ_ASSERTED      0x01
        !           222: #define CMD_RESET         0xc0
        !           223: #define CMD_OGM_INTR      0x01
        !           224: #define CMD_CLR_INTR      0x01
        !           225: #define CMD_ENA_INTR      0x81
        !           226: #define ASOK              0x00
        !           227: #define ASST              0x91
        !           228: 
        !           229: #define PACKED          __attribute__((packed))
        !           230: 
        !           231: /* MailBox SCSI Command Packet */
        !           232: struct mscp {
        !           233:    unsigned char opcode: 3;             /* type of command */
        !           234:    unsigned char xdir: 2;               /* data transfer direction */
        !           235:    unsigned char dcn: 1;                /* disable disconnect */
        !           236:    unsigned char ca: 1;                 /* use cache (if available) */
        !           237:    unsigned char sg: 1;                 /* scatter/gather operation */
        !           238:    unsigned char target: 3;             /* target SCSI id */
        !           239:    unsigned char ch_no: 2;              /* SCSI channel (always 0 for 14f) */
        !           240:    unsigned char lun: 3;                /* logical unit number */
        !           241:    unsigned int data_address PACKED;    /* transfer data pointer */
        !           242:    unsigned int data_len PACKED;        /* length in bytes */
        !           243:    unsigned int command_link PACKED;    /* for linking command chains */
        !           244:    unsigned char scsi_command_link_id;  /* identifies command in chain */
        !           245:    unsigned char use_sg;                /* (if sg is set) 8 bytes per list */
        !           246:    unsigned char sense_len;
        !           247:    unsigned char scsi_cdbs_len;         /* 6, 10, or 12 */
        !           248:    unsigned char scsi_cdbs[12];         /* SCSI commands */
        !           249:    unsigned char adapter_status;        /* non-zero indicates HA error */
        !           250:    unsigned char target_status;         /* non-zero indicates target error */
        !           251:    unsigned int sense_addr PACKED;
        !           252: 
        !           253:    Scsi_Cmnd *SCpnt;
        !           254: 
        !           255:    struct sg_list {
        !           256:       unsigned int address;     /* Segment Address */
        !           257:       unsigned int num_bytes;   /* Segment Length */
        !           258:       } sglist[MAX_SGLIST];
        !           259: 
        !           260:    unsigned int index;   /* cp index */
        !           261:    };
        !           262: 
        !           263: struct hostdata {
        !           264:    struct mscp cp[MAX_MAILBOXES];       /* Mailboxes for this board */
        !           265:    unsigned int cp_stat[MAX_MAILBOXES]; /* FREE, IN_USE, LOCKED, IN_RESET */
        !           266:    unsigned int last_cp_used;           /* Index of last mailbox used */
        !           267:    unsigned int iocount;                /* Total i/o done for this board */
        !           268:    unsigned int multicount;             /* Total ... in second ihdlr loop */
        !           269:    int board_number;                    /* Number of this board */
        !           270:    char board_name[16];                 /* Name of this board */
        !           271:    char board_id[256];                  /* data from INQUIRY on this board */
        !           272:    int in_reset;                        /* True if board is doing a reset */
        !           273:    int target_time_out[MAX_TARGET];     /* N. of timeout errors on target */
        !           274:    int target_reset[MAX_TARGET];        /* If TRUE redo operation on target */
        !           275:    unsigned char subversion;            /* Bus type, either ISA or ESA */
        !           276:    unsigned char heads;
        !           277:    unsigned char sectors;
        !           278: 
        !           279:    /* slot != 0 for the U24F, slot == 0 for both the U14F and U34F */
        !           280:    unsigned char slot;
        !           281:    };
        !           282: 
        !           283: static struct Scsi_Host * sh[MAX_BOARDS + 1];
        !           284: static const char* driver_name = "Ux4F";
        !           285: static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ];
        !           286: 
        !           287: #define HD(board) ((struct hostdata *) &sh[board]->hostdata)
        !           288: #define BN(board) (HD(board)->board_name)
        !           289: 
        !           290: static void u14_34f_interrupt_handler(int, struct pt_regs *);
        !           291: static int do_trace = FALSE;
        !           292: 
        !           293: static inline unchar wait_on_busy(ushort iobase) {
        !           294:    unsigned int loop = MAXLOOP;
        !           295: 
        !           296:    while (inb(iobase + REG_LCL_INTR) & BSY_ASSERTED)
        !           297:       if (--loop == 0) return TRUE;
        !           298: 
        !           299:    return FALSE;
        !           300: }
        !           301: 
        !           302: static int board_inquiry(unsigned int j) {
        !           303:    struct mscp *cpp;
        !           304:    unsigned int time, limit = 0;
        !           305: 
        !           306:    cpp = &HD(j)->cp[0];
        !           307:    memset(cpp, 0, sizeof(struct mscp));
        !           308:    cpp->opcode = OP_HOST_ADAPTER;
        !           309:    cpp->xdir = DTD_IN;
        !           310:    cpp->data_address = (unsigned int) HD(j)->board_id;
        !           311:    cpp->data_len = sizeof(HD(j)->board_id);
        !           312:    cpp->scsi_cdbs_len = 6;
        !           313:    cpp->scsi_cdbs[0] = HA_CMD_INQUIRY;
        !           314: 
        !           315:    if (wait_on_busy(sh[j]->io_port)) {
        !           316:       printk("%s: board_inquiry, adapter busy.\n", BN(j));
        !           317:       return TRUE;
        !           318:       }
        !           319: 
        !           320:    HD(j)->cp_stat[0] = IGNORE;
        !           321: 
        !           322:    /* Clear the interrupt indication */
        !           323:    outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR);
        !           324: 
        !           325:    /* Store pointer in OGM address bytes */
        !           326:    outl((unsigned int)cpp, sh[j]->io_port + REG_OGM);
        !           327: 
        !           328:    /* Issue OGM interrupt */
        !           329:    outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR);
        !           330: 
        !           331:    sti();
        !           332:    time = jiffies;
        !           333:    while (jiffies < (time + 100) && limit++ < 100000000);
        !           334:    cli();
        !           335: 
        !           336:    if (cpp->adapter_status || HD(j)->cp_stat[0] != FREE) {
        !           337:       HD(j)->cp_stat[0] = FREE;
        !           338:       printk("%s: board_inquiry, err 0x%x.\n", BN(j), cpp->adapter_status);
        !           339:       return TRUE;
        !           340:       }
        !           341: 
        !           342:    return FALSE;
        !           343: }
        !           344: 
        !           345: static inline int port_detect(ushort *port_base, unsigned int j, 
        !           346:                              Scsi_Host_Template * tpnt) {
        !           347:    unsigned char irq, dma_channel, subversion;
        !           348:    unsigned char in_byte;
        !           349: 
        !           350:    /* Allowed BIOS base addresses (NULL indicates reserved) */
        !           351:    void *bios_segment_table[8] = { 
        !           352:       NULL, 
        !           353:       (void *) 0xc4000, (void *) 0xc8000, (void *) 0xcc000, (void *) 0xd0000,
        !           354:       (void *) 0xd4000, (void *) 0xd8000, (void *) 0xdc000
        !           355:       };
        !           356:    
        !           357:    /* Allowed IRQs */
        !           358:    unsigned char interrupt_table[4] = { 15, 14, 11, 10 };
        !           359:    
        !           360:    /* Allowed DMA channels for ISA (0 indicates reserved) */
        !           361:    unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };
        !           362:    
        !           363:    /* Head/sector mappings */
        !           364:    struct {
        !           365:       unsigned char heads;
        !           366:       unsigned char sectors;
        !           367:       } mapping_table[4] = { 
        !           368:           { 16, 63 }, { 64, 32 }, { 64, 63 }, { 64, 32 }
        !           369:           };
        !           370: 
        !           371:    struct config_1 {
        !           372:       unsigned char bios_segment: 3;
        !           373:       unsigned char removable_disks_as_fixed: 1;
        !           374:       unsigned char interrupt: 2;
        !           375:       unsigned char dma_channel: 2;
        !           376:       } config_1;
        !           377: 
        !           378:    struct config_2 {
        !           379:       unsigned char ha_scsi_id: 3;
        !           380:       unsigned char mapping_mode: 2;
        !           381:       unsigned char bios_drive_number: 1;
        !           382:       unsigned char tfr_port: 2;
        !           383:       } config_2;
        !           384: 
        !           385:    char name[16];
        !           386: 
        !           387:    sprintf(name, "%s%d", driver_name, j);
        !           388: 
        !           389:    if(check_region(*port_base, REGION_SIZE)) {
        !           390:       printk("%s: address 0x%03x in use, skipping probe.\n", 
        !           391:             name, *port_base);
        !           392:       return FALSE;
        !           393:       }
        !           394: 
        !           395:    if (inb(*port_base + REG_PRODUCT_ID1) != PRODUCT_ID1) return FALSE;
        !           396: 
        !           397:    in_byte = inb(*port_base + REG_PRODUCT_ID2);
        !           398: 
        !           399:    if ((in_byte & 0xf0) != PRODUCT_ID2) return FALSE;
        !           400: 
        !           401:    *(char *)&config_1 = inb(*port_base + REG_CONFIG1);
        !           402:    *(char *)&config_2 = inb(*port_base + REG_CONFIG2);
        !           403: 
        !           404:    irq = interrupt_table[config_1.interrupt];
        !           405:    dma_channel = dma_channel_table[config_1.dma_channel];
        !           406:    subversion = (in_byte & 0x0f);
        !           407: 
        !           408:    /* Board detected, allocate its IRQ if not already done */
        !           409:    if ((irq >= MAX_IRQ) || ((irqlist[irq] == NO_IRQ) && request_irq
        !           410:        (irq, u14_34f_interrupt_handler, SA_INTERRUPT, driver_name))) {
        !           411:       printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
        !           412:       return FALSE;
        !           413:       }
        !           414: 
        !           415:    if (subversion == ISA && request_dma(dma_channel, driver_name)) {
        !           416:       printk("%s: unable to allocate DMA channel %u, detaching.\n",
        !           417:             name, dma_channel);
        !           418:       free_irq(irq);
        !           419:       return FALSE;
        !           420:       }
        !           421: 
        !           422:    sh[j] = scsi_register(tpnt, sizeof(struct hostdata));
        !           423: 
        !           424:    if (sh[j] == NULL) {
        !           425:       printk("%s: unable to register host, detaching.\n", name);
        !           426: 
        !           427:       if (irqlist[irq] == NO_IRQ) free_irq(irq);
        !           428: 
        !           429:       if (subversion == ISA) free_dma(dma_channel);
        !           430: 
        !           431:       return FALSE;
        !           432:       }
        !           433: 
        !           434:    sh[j]->io_port = *port_base;
        !           435:    sh[j]->n_io_port = REGION_SIZE;
        !           436:    sh[j]->base = bios_segment_table[config_1.bios_segment];
        !           437:    sh[j]->irq = irq;
        !           438:    sh[j]->sg_tablesize = MAX_SGLIST;
        !           439:    sh[j]->this_id = config_2.ha_scsi_id;
        !           440:    sh[j]->can_queue = MAX_MAILBOXES;
        !           441:    sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;
        !           442: 
        !           443: #if defined(DEBUG_DETECT)
        !           444:    {
        !           445:    unsigned char sys_mask, lcl_mask;
        !           446: 
        !           447:    sys_mask = inb(sh[j]->io_port + REG_SYS_MASK);
        !           448:    lcl_mask = inb(sh[j]->io_port + REG_LCL_MASK);
        !           449:    printk("SYS_MASK 0x%x, LCL_MASK 0x%x.\n", sys_mask, lcl_mask);
        !           450:    }
        !           451: #endif
        !           452: 
        !           453:    /* If BIOS is disabled, force enable interrupts */
        !           454:    if (sh[j]->base == 0) outb(CMD_ENA_INTR, sh[j]->io_port + REG_SYS_MASK);
        !           455: 
        !           456:    /* Register the I/O space that we use */
        !           457:    request_region(sh[j]->io_port, REGION_SIZE, driver_name);
        !           458: 
        !           459:    memset(HD(j), 0, sizeof(struct hostdata));
        !           460:    HD(j)->heads = mapping_table[config_2.mapping_mode].heads;
        !           461:    HD(j)->sectors = mapping_table[config_2.mapping_mode].sectors;
        !           462:    HD(j)->subversion = subversion;
        !           463:    HD(j)->board_number = j;
        !           464:    irqlist[irq] = j;
        !           465: 
        !           466:    if (HD(j)->subversion == ESA) {
        !           467: 
        !           468: #if defined (HAVE_OLD_UX4F_FIRMWARE)
        !           469:       sh[j]->sg_tablesize = MAX_SAFE_SGLIST;
        !           470: #endif
        !           471: 
        !           472:       sh[j]->dma_channel = NO_DMA;
        !           473:       sh[j]->unchecked_isa_dma = FALSE;
        !           474:       sprintf(BN(j), "U34F%d", j);
        !           475:       }
        !           476:    else {
        !           477:       sh[j]->wish_block = TRUE;
        !           478: 
        !           479: #if defined (HAVE_OLD_UX4F_FIRMWARE)
        !           480:       sh[j]->hostt->use_clustering = DISABLE_CLUSTERING;
        !           481:       sh[j]->sg_tablesize = MAX_SAFE_SGLIST;
        !           482: #endif
        !           483: 
        !           484:       sh[j]->dma_channel = dma_channel;
        !           485:       sh[j]->unchecked_isa_dma = TRUE;
        !           486:       sprintf(BN(j), "U14F%d", j);
        !           487:       disable_dma(dma_channel);
        !           488:       clear_dma_ff(dma_channel);
        !           489:       set_dma_mode(dma_channel, DMA_MODE_CASCADE);
        !           490:       enable_dma(dma_channel);
        !           491:       }
        !           492: 
        !           493:    if (HD(j)->subversion == ISA && !board_inquiry(j)) {
        !           494:       HD(j)->board_id[40] = 0;
        !           495: 
        !           496:       if (strcmp(&HD(j)->board_id[32], "06000600")) {
        !           497:         printk("%s: %s.\n", BN(j), &HD(j)->board_id[8]);
        !           498:         printk("%s: firmware %s is outdated, FW PROM should be 28004-006.\n",
        !           499:                BN(j), &HD(j)->board_id[32]);
        !           500:         sh[j]->hostt->use_clustering = DISABLE_CLUSTERING;
        !           501:         sh[j]->sg_tablesize = MAX_SAFE_SGLIST;
        !           502:         }
        !           503:       }
        !           504: 
        !           505:    printk("%s: PORT 0x%03x, BIOS 0x%05x, IRQ %u, DMA %u, SG %d, "\
        !           506:          "Mbox %d, CmdLun %d, C%d.\n", BN(j), sh[j]->io_port, 
        !           507:          (int)sh[j]->base, sh[j]->irq, 
        !           508:          sh[j]->dma_channel, sh[j]->sg_tablesize, 
        !           509:          sh[j]->can_queue, sh[j]->cmd_per_lun,
        !           510:          sh[j]->hostt->use_clustering);
        !           511:    return TRUE;
        !           512: }
        !           513: 
        !           514: int u14_34f_detect (Scsi_Host_Template * tpnt) {
        !           515:    unsigned int j = 0, k, flags;
        !           516: 
        !           517:    ushort io_port[] = {
        !           518:       0x330, 0x340, 0x230, 0x240, 0x210, 0x130, 0x140, 0x0
        !           519:       };
        !           520: 
        !           521:    ushort *port_base = io_port;
        !           522: 
        !           523:    tpnt->proc_dir = &proc_scsi_u14_34f;
        !           524: 
        !           525:    save_flags(flags);
        !           526:    cli();
        !           527: 
        !           528:    for (k = 0; k < MAX_IRQ; k++) {
        !           529:       irqlist[k] = NO_IRQ;
        !           530:       calls[k] = 0;
        !           531:       }
        !           532: 
        !           533:    for (k = 0; k < MAX_BOARDS + 1; k++) sh[k] = NULL;
        !           534: 
        !           535:    while (*port_base) {
        !           536: 
        !           537:       if (j < MAX_BOARDS && port_detect(port_base, j, tpnt)) j++;
        !           538: 
        !           539:       port_base++;
        !           540:       }
        !           541: 
        !           542:    if (j > 0) 
        !           543:       printk("UltraStor 14F/34F: Copyright (C) 1994, 1995 Dario Ballabio.\n");
        !           544: 
        !           545:    restore_flags(flags);
        !           546:    return j;
        !           547: }
        !           548: 
        !           549: static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
        !           550:    unsigned int k, data_len = 0;
        !           551:    struct scatterlist * sgpnt;
        !           552: 
        !           553:    sgpnt = (struct scatterlist *) SCpnt->request_buffer;
        !           554: 
        !           555:    for (k = 0; k < SCpnt->use_sg; k++) {
        !           556:       cpp->sglist[k].address = (unsigned int) sgpnt[k].address;
        !           557:       cpp->sglist[k].num_bytes = sgpnt[k].length;
        !           558:       data_len += sgpnt[k].length;
        !           559:       }
        !           560: 
        !           561:    cpp->use_sg = SCpnt->use_sg;
        !           562:    cpp->data_address = (unsigned int) cpp->sglist;
        !           563:    cpp->data_len = data_len;
        !           564: }
        !           565: 
        !           566: int u14_34f_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
        !           567:    unsigned int i, j, k, flags;
        !           568:    struct mscp *cpp;
        !           569: 
        !           570:    save_flags(flags);
        !           571:    cli();
        !           572:    /* j is the board number */
        !           573:    j = ((struct hostdata *) SCpnt->host->hostdata)->board_number;
        !           574: 
        !           575:    if (!done) panic("%s: qcomm, pid %ld, null done.\n", BN(j), SCpnt->pid);
        !           576: 
        !           577:    /* i is the mailbox number, look for the first free mailbox 
        !           578:       starting from last_cp_used */
        !           579:    i = HD(j)->last_cp_used + 1;
        !           580: 
        !           581:    for (k = 0; k < sh[j]->can_queue; k++, i++) {
        !           582: 
        !           583:       if (i >= sh[j]->can_queue) i = 0;
        !           584: 
        !           585:       if (HD(j)->cp_stat[i] == FREE) {
        !           586:         HD(j)->last_cp_used = i;
        !           587:         break;
        !           588:         }
        !           589:       }
        !           590: 
        !           591:    if (k == sh[j]->can_queue) {
        !           592:       printk("%s: qcomm, no free mailbox, resetting.\n", BN(j));
        !           593: 
        !           594:       if (HD(j)->in_reset) 
        !           595:         printk("%s: qcomm, already in reset.\n", BN(j));
        !           596:       else if (u14_34f_reset(SCpnt) == SCSI_RESET_SUCCESS) 
        !           597:         panic("%s: qcomm, SCSI_RESET_SUCCESS.\n", BN(j));
        !           598: 
        !           599:       SCpnt->result = DID_BUS_BUSY << 16; 
        !           600:       SCpnt->host_scribble = NULL;
        !           601:       printk("%s: qcomm, pid %ld, DID_BUS_BUSY, done.\n", BN(j), SCpnt->pid);
        !           602:       restore_flags(flags);
        !           603:       done(SCpnt);    
        !           604:       return 0;
        !           605:       }
        !           606: 
        !           607:    /* Set pointer to control packet structure */
        !           608:    cpp = &HD(j)->cp[i];
        !           609: 
        !           610:    memset(cpp, 0, sizeof(struct mscp));
        !           611:    SCpnt->scsi_done = done;
        !           612:    cpp->index = i;
        !           613:    SCpnt->host_scribble = (unsigned char *) &cpp->index;
        !           614: 
        !           615:    if (do_trace) printk("%s: qcomm, mbox %d, target %d, pid %ld.\n",
        !           616:                        BN(j), i, SCpnt->target, SCpnt->pid);
        !           617: 
        !           618:    cpp->opcode = OP_SCSI;
        !           619:    cpp->xdir = DTD_SCSI;
        !           620:    cpp->target = SCpnt->target;
        !           621:    cpp->lun = SCpnt->lun;
        !           622:    cpp->SCpnt = SCpnt;
        !           623:    cpp->sense_addr = (unsigned int) SCpnt->sense_buffer;
        !           624:    cpp->sense_len = sizeof SCpnt->sense_buffer;
        !           625: 
        !           626:    if (SCpnt->use_sg) {
        !           627:       cpp->sg = TRUE;
        !           628:       build_sg_list(cpp, SCpnt);
        !           629:       }
        !           630:    else {
        !           631:       cpp->data_address = (unsigned int)SCpnt->request_buffer;
        !           632:       cpp->data_len = SCpnt->request_bufflen;
        !           633:       }
        !           634: 
        !           635:    cpp->scsi_cdbs_len = SCpnt->cmd_len;
        !           636:    memcpy(cpp->scsi_cdbs, SCpnt->cmnd, cpp->scsi_cdbs_len);
        !           637: 
        !           638:    if (wait_on_busy(sh[j]->io_port)) {
        !           639:       SCpnt->result = DID_ERROR << 16;
        !           640:       SCpnt->host_scribble = NULL;
        !           641:       printk("%s: qcomm, target %d, pid %ld, adapter busy, DID_ERROR, done.\n", 
        !           642:             BN(j), SCpnt->target, SCpnt->pid);
        !           643:       restore_flags(flags);
        !           644:       done(SCpnt);
        !           645:       return 0;
        !           646:       }
        !           647: 
        !           648:    /* Store pointer in OGM address bytes */
        !           649:    outl((unsigned int)cpp, sh[j]->io_port + REG_OGM);
        !           650: 
        !           651:    /* Issue OGM interrupt */
        !           652:    outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR);
        !           653: 
        !           654:    HD(j)->cp_stat[i] = IN_USE;
        !           655:    restore_flags(flags);
        !           656:    return 0;
        !           657: }
        !           658: 
        !           659: int u14_34f_abort(Scsi_Cmnd *SCarg) {
        !           660:    unsigned int i, j, flags;
        !           661: 
        !           662:    save_flags(flags);
        !           663:    cli();
        !           664:    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
        !           665: 
        !           666:    if (SCarg->host_scribble == NULL) {
        !           667:       printk("%s: abort, target %d, pid %ld inactive.\n",
        !           668:             BN(j), SCarg->target, SCarg->pid);
        !           669:       restore_flags(flags);
        !           670:       return SCSI_ABORT_NOT_RUNNING;
        !           671:       }
        !           672: 
        !           673:    i = *(unsigned int *)SCarg->host_scribble;
        !           674:    printk("%s: abort, mbox %d, target %d, pid %ld.\n",
        !           675:          BN(j), i, SCarg->target, SCarg->pid);
        !           676: 
        !           677:    if (i >= sh[j]->can_queue)
        !           678:       panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
        !           679: 
        !           680:    if (wait_on_busy(sh[j]->io_port)) {
        !           681:       printk("%s: abort, timeout error.\n", BN(j));
        !           682:       restore_flags(flags);
        !           683:       return SCSI_ABORT_ERROR;
        !           684:       }
        !           685: 
        !           686:    if (HD(j)->cp_stat[i] == FREE) {
        !           687:       printk("%s: abort, mbox %d is free.\n", BN(j), i);
        !           688:       restore_flags(flags);
        !           689:       return SCSI_ABORT_NOT_RUNNING;
        !           690:       }
        !           691: 
        !           692:    if (HD(j)->cp_stat[i] == IN_USE) {
        !           693:       printk("%s: abort, mbox %d is in use.\n", BN(j), i);
        !           694: 
        !           695:       if (SCarg != HD(j)->cp[i].SCpnt)
        !           696:         panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",
        !           697:               BN(j), i, SCarg, HD(j)->cp[i].SCpnt);
        !           698: 
        !           699:       restore_flags(flags);
        !           700:       return SCSI_ABORT_SNOOZE;
        !           701:       }
        !           702: 
        !           703:    if (HD(j)->cp_stat[i] == IN_RESET) {
        !           704:       printk("%s: abort, mbox %d is in reset.\n", BN(j), i);
        !           705:       restore_flags(flags);
        !           706:       return SCSI_ABORT_ERROR;
        !           707:       }
        !           708: 
        !           709:    if (HD(j)->cp_stat[i] == LOCKED) {
        !           710:       printk("%s: abort, mbox %d is locked.\n", BN(j), i);
        !           711:       restore_flags(flags);
        !           712:       return SCSI_ABORT_NOT_RUNNING;
        !           713:       }
        !           714:    restore_flags(flags);
        !           715:    panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
        !           716: }
        !           717: 
        !           718: int u14_34f_reset(Scsi_Cmnd * SCarg) {
        !           719:    unsigned int i, j, flags, time, k, limit = 0;
        !           720:    int arg_done = FALSE;
        !           721:    Scsi_Cmnd *SCpnt;
        !           722: 
        !           723:    save_flags(flags);
        !           724:    cli();
        !           725:    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
        !           726:    printk("%s: reset, enter, target %d, pid %ld.\n", 
        !           727:          BN(j), SCarg->target, SCarg->pid);
        !           728: 
        !           729:    if (SCarg->host_scribble == NULL)
        !           730:       printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
        !           731: 
        !           732:    if (HD(j)->in_reset) {
        !           733:       printk("%s: reset, exit, already in reset.\n", BN(j));
        !           734:       restore_flags(flags);
        !           735:       return SCSI_RESET_ERROR;
        !           736:       }
        !           737: 
        !           738:    if (wait_on_busy(sh[j]->io_port)) {
        !           739:       printk("%s: reset, exit, timeout error.\n", BN(j));
        !           740:       restore_flags(flags);
        !           741:       return SCSI_RESET_ERROR;
        !           742:       }
        !           743: 
        !           744:    for (k = 0; k < MAX_TARGET; k++) HD(j)->target_reset[k] = TRUE;
        !           745: 
        !           746:    for (k = 0; k < MAX_TARGET; k++) HD(j)->target_time_out[k] = 0;
        !           747: 
        !           748:    for (i = 0; i < sh[j]->can_queue; i++) {
        !           749: 
        !           750:       if (HD(j)->cp_stat[i] == FREE) continue;
        !           751: 
        !           752:       if (HD(j)->cp_stat[i] == LOCKED) {
        !           753:         HD(j)->cp_stat[i] = FREE;
        !           754:         printk("%s: reset, locked mbox %d forced free.\n", BN(j), i);
        !           755:         continue;
        !           756:         }
        !           757: 
        !           758:       SCpnt = HD(j)->cp[i].SCpnt;
        !           759:       HD(j)->cp_stat[i] = IN_RESET;
        !           760:       printk("%s: reset, mbox %d in reset, pid %ld.\n",
        !           761:             BN(j), i, SCpnt->pid);
        !           762: 
        !           763:       if (SCpnt == NULL)
        !           764:         panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i);
        !           765: 
        !           766:       if (SCpnt->host_scribble == NULL)
        !           767:         panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i);
        !           768: 
        !           769:       if (*(unsigned int *)SCpnt->host_scribble != i) 
        !           770:         panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i);
        !           771: 
        !           772:       if (SCpnt->scsi_done == NULL) 
        !           773:         panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i);
        !           774: 
        !           775:       if (SCpnt == SCarg) arg_done = TRUE;
        !           776:       }
        !           777: 
        !           778:    if (wait_on_busy(sh[j]->io_port)) {
        !           779:       printk("%s: reset, cannot reset, timeout error.\n", BN(j));
        !           780:       restore_flags(flags);
        !           781:       return SCSI_RESET_ERROR;
        !           782:       }
        !           783: 
        !           784:    outb(CMD_RESET, sh[j]->io_port + REG_LCL_INTR);
        !           785:    printk("%s: reset, board reset done, enabling interrupts.\n", BN(j));
        !           786: 
        !           787: #if defined (DEBUG_RESET)
        !           788:    do_trace = TRUE;
        !           789: #endif
        !           790: 
        !           791:    HD(j)->in_reset = TRUE;
        !           792:    sti();
        !           793:    time = jiffies;
        !           794:    while (jiffies < (time + 100) && limit++ < 100000000);
        !           795:    cli();
        !           796:    printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit);
        !           797: 
        !           798:    for (i = 0; i < sh[j]->can_queue; i++) {
        !           799: 
        !           800:       /* Skip mailboxes already set free by interrupt */
        !           801:       if (HD(j)->cp_stat[i] != IN_RESET) continue;
        !           802: 
        !           803:       SCpnt = HD(j)->cp[i].SCpnt;
        !           804:       SCpnt->result = DID_RESET << 16;
        !           805:       SCpnt->host_scribble = NULL;
        !           806: 
        !           807:       /* This mailbox is still waiting for its interrupt */
        !           808:       HD(j)->cp_stat[i] = LOCKED;
        !           809: 
        !           810:       printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
        !           811:             BN(j), i, SCpnt->pid);
        !           812:       restore_flags(flags);
        !           813:       SCpnt->scsi_done(SCpnt);
        !           814:       cli();
        !           815:       }
        !           816: 
        !           817:    HD(j)->in_reset = FALSE;
        !           818:    do_trace = FALSE;
        !           819:    restore_flags(flags);
        !           820: 
        !           821:    if (arg_done) {
        !           822:       printk("%s: reset, exit, success.\n", BN(j));
        !           823:       return SCSI_RESET_SUCCESS;
        !           824:       }
        !           825:    else {
        !           826:       printk("%s: reset, exit, wakeup.\n", BN(j));
        !           827:       return SCSI_RESET_PUNT;
        !           828:       }
        !           829: }
        !           830: 
        !           831: int u14_34f_biosparam(Disk * disk, kdev_t dev, int * dkinfo) {
        !           832:    unsigned int j = 0;
        !           833:    int size = disk->capacity;
        !           834: 
        !           835:    dkinfo[0] = HD(j)->heads;
        !           836:    dkinfo[1] = HD(j)->sectors;
        !           837:    dkinfo[2] = size / (HD(j)->heads * HD(j)->sectors);
        !           838:    return 0;
        !           839: }
        !           840: 
        !           841: static void u14_34f_interrupt_handler(int irq, struct pt_regs * regs) {
        !           842:    Scsi_Cmnd *SCpnt;
        !           843:    unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0;
        !           844:    struct mscp *spp;
        !           845: 
        !           846:    save_flags(flags);
        !           847:    cli();
        !           848: 
        !           849:    if (irqlist[irq] == NO_IRQ) {
        !           850:       printk("%s, ihdlr, irq %d, unexpected interrupt.\n", driver_name, irq);
        !           851:       restore_flags(flags);
        !           852:       return;
        !           853:       }
        !           854: 
        !           855:    if (do_trace) printk("%s: ihdlr, enter, irq %d, calls %d.\n", 
        !           856:                        driver_name, irq, calls[irq]);
        !           857: 
        !           858:    /* Service all the boards configured on this irq */
        !           859:    for (j = 0; sh[j] != NULL; j++) {
        !           860: 
        !           861:       if (sh[j]->irq != irq) continue;
        !           862: 
        !           863:       loops = 0;
        !           864: 
        !           865:       /* Loop until all interrupts for a board are serviced */
        !           866:       while (inb(sh[j]->io_port + REG_SYS_INTR) & IRQ_ASSERTED) {
        !           867:         total_loops++;
        !           868:         loops++;
        !           869: 
        !           870:         if (do_trace) printk("%s: ihdlr, start service, count %d.\n",
        !           871:                              BN(j), HD(j)->iocount);
        !           872: 
        !           873:         spp = (struct mscp *)inl(sh[j]->io_port + REG_ICM);
        !           874: 
        !           875:         /* Clear interrupt pending flag */
        !           876:         outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR);
        !           877: 
        !           878:         i = spp - HD(j)->cp;
        !           879: 
        !           880:         if (i >= sh[j]->can_queue)
        !           881:            panic("%s: ihdlr, invalid mscp address.\n", BN(j));
        !           882: 
        !           883:         if (HD(j)->cp_stat[i] == IGNORE) {
        !           884:            HD(j)->cp_stat[i] = FREE;
        !           885:            continue;
        !           886:            }
        !           887:         else if (HD(j)->cp_stat[i] == LOCKED) {
        !           888:            HD(j)->cp_stat[i] = FREE;
        !           889:            printk("%s: ihdlr, mbox %d unlocked, count %d.\n",
        !           890:                   BN(j), i, HD(j)->iocount);
        !           891:            continue;
        !           892:            }
        !           893:         else if (HD(j)->cp_stat[i] == FREE) {
        !           894:            printk("%s: ihdlr, mbox %d is free, count %d.\n", 
        !           895:                   BN(j), i, HD(j)->iocount);
        !           896:            continue;
        !           897:            }
        !           898:         else if (HD(j)->cp_stat[i] == IN_RESET)
        !           899:            printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
        !           900:         else if (HD(j)->cp_stat[i] != IN_USE) 
        !           901:            panic("%s: ihdlr, mbox %d, invalid cp_stat.\n", BN(j), i);
        !           902: 
        !           903:         HD(j)->cp_stat[i] = FREE;
        !           904:         SCpnt = spp->SCpnt;
        !           905: 
        !           906:         if (SCpnt == NULL) 
        !           907:            panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", BN(j), i);
        !           908: 
        !           909:         if (SCpnt->host_scribble == NULL) 
        !           910:            panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n",
        !           911:                  BN(j), i, SCpnt->pid, SCpnt);
        !           912: 
        !           913:         if (*(unsigned int *)SCpnt->host_scribble != i) 
        !           914:            panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d,"\
        !           915:                  " irq %d.\n", BN(j), i, SCpnt->pid, 
        !           916:                  *(unsigned int *)SCpnt->host_scribble, irq);
        !           917: 
        !           918:         tstatus = status_byte(spp->target_status);
        !           919: 
        !           920:         switch (spp->adapter_status) {
        !           921:            case ASOK:     /* status OK */
        !           922: 
        !           923:               /* Forces a reset if a disk drive keeps returning BUSY */
        !           924:               if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE) 
        !           925:                  status = DID_ERROR << 16;
        !           926: 
        !           927:               /* If there was a bus reset, redo operation on each target */
        !           928:               else if (tstatus != GOOD
        !           929:                        && SCpnt->device->type == TYPE_DISK
        !           930:                        && HD(j)->target_reset[SCpnt->target])
        !           931:                  status = DID_BUS_BUSY << 16;
        !           932: 
        !           933:               /* Works around a flaw in scsi.c */
        !           934:               else if (tstatus == CHECK_CONDITION
        !           935:                        && SCpnt->device->type == TYPE_DISK
        !           936:                        && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
        !           937:                  status = DID_BUS_BUSY << 16;
        !           938: 
        !           939:               else
        !           940:                  status = DID_OK << 16;
        !           941: 
        !           942:               if (tstatus == GOOD)
        !           943:                  HD(j)->target_reset[SCpnt->target] = FALSE;
        !           944: 
        !           945:               if (spp->target_status && SCpnt->device->type == TYPE_DISK)
        !           946:                  printk("%s: ihdlr, target %d:%d, pid %ld, target_status "\
        !           947:                         "0x%x, sense key 0x%x.\n", BN(j), 
        !           948:                         SCpnt->target, SCpnt->lun, SCpnt->pid,
        !           949:                         spp->target_status, SCpnt->sense_buffer[2]);
        !           950: 
        !           951:               HD(j)->target_time_out[SCpnt->target] = 0;
        !           952: 
        !           953:               break;
        !           954:            case ASST:     /* Selection Time Out */
        !           955: 
        !           956:               if (HD(j)->target_time_out[SCpnt->target] > 1)
        !           957:                  status = DID_ERROR << 16;
        !           958:               else {
        !           959:                  status = DID_TIME_OUT << 16;
        !           960:                  HD(j)->target_time_out[SCpnt->target]++;
        !           961:                  }
        !           962: 
        !           963:               break;
        !           964:            case 0x92:     /* Data over/under-run */
        !           965:            case 0x93:     /* Unexpected bus free */
        !           966:            case 0x94:     /* Target bus phase sequence failure */
        !           967:            case 0x96:     /* Illegal SCSI command */
        !           968:            case 0xa3:     /* SCSI bus reset error */
        !           969: 
        !           970:               if (SCpnt->device->type != TYPE_TAPE)
        !           971:                  status = DID_BUS_BUSY << 16;
        !           972:               else
        !           973:                  status = DID_ERROR << 16;
        !           974: 
        !           975:               for (k = 0; k < MAX_TARGET; k++) 
        !           976:                  HD(j)->target_reset[k] = TRUE;
        !           977: 
        !           978:               break;
        !           979:            case 0x01:     /* Invalid command */
        !           980:            case 0x02:     /* Invalid parameters */
        !           981:            case 0x03:     /* Invalid data list */
        !           982:            case 0x84:     /* SCSI bus abort error */
        !           983:            case 0x9b:     /* Auto request sense error */
        !           984:            case 0x9f:     /* Unexpected command complete message error */
        !           985:            case 0xff:     /* Invalid parameter in the S/G list */
        !           986:            default:
        !           987:               status = DID_ERROR << 16;
        !           988:               break;
        !           989:            }
        !           990: 
        !           991:         SCpnt->result = status | spp->target_status;
        !           992:         HD(j)->iocount++;
        !           993: 
        !           994:         if (loops > 1) HD(j)->multicount++;
        !           995: 
        !           996: #if defined (DEBUG_INTERRUPT)
        !           997:         if (SCpnt->result || do_trace) 
        !           998: #else
        !           999:         if ((spp->adapter_status != ASOK && HD(j)->iocount >  1000) ||
        !          1000:             (spp->adapter_status != ASOK && 
        !          1001:              spp->adapter_status != ASST && HD(j)->iocount <= 1000) ||
        !          1002:             do_trace)
        !          1003: #endif
        !          1004:            printk("%s: ihdlr, mbox %d, err 0x%x:%x,"\
        !          1005:                   " target %d:%d, pid %ld, count %d.\n",
        !          1006:                   BN(j), i, spp->adapter_status, spp->target_status,
        !          1007:                   SCpnt->target, SCpnt->lun, SCpnt->pid, HD(j)->iocount);
        !          1008: 
        !          1009:         /* Set the command state to inactive */
        !          1010:         SCpnt->host_scribble = NULL;
        !          1011: 
        !          1012:         restore_flags(flags);
        !          1013:         SCpnt->scsi_done(SCpnt);
        !          1014:         cli();
        !          1015: 
        !          1016:         }   /* Multiple command loop */
        !          1017: 
        !          1018:       }   /* Boards loop */
        !          1019: 
        !          1020:    calls[irq]++;
        !          1021: 
        !          1022:    if (total_loops == 0) 
        !          1023:      printk("%s: ihdlr, irq %d, no command completed, calls %d.\n",
        !          1024:            driver_name, irq, calls[irq]);
        !          1025: 
        !          1026:    if (do_trace) printk("%s: ihdlr, exit, irq %d, calls %d.\n",
        !          1027:                        driver_name, irq, calls[irq]);
        !          1028: 
        !          1029: #if defined (DEBUG_STATISTICS)
        !          1030:    if ((calls[irq] % 100000) == 10000)
        !          1031:       for (j = 0; sh[j] != NULL; j++)
        !          1032:         printk("%s: ihdlr, calls %d, count %d, multi %d.\n", BN(j),
        !          1033:                calls[(sh[j]->irq)], HD(j)->iocount, HD(j)->multicount);
        !          1034: #endif
        !          1035: 
        !          1036:    restore_flags(flags);
        !          1037:    return;
        !          1038: }
        !          1039: 
        !          1040: #if defined(MODULE)
        !          1041: Scsi_Host_Template driver_template = ULTRASTOR_14_34F;
        !          1042: 
        !          1043: #include "scsi_module.c"
        !          1044: #endif

unix.superglobalmegacorp.com

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