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

1.1     ! root        1: /*
        !             2:  *      eata.c - Low-level driver for EATA/DMA SCSI host adapters.
        !             3:  *
        !             4:  *       6 Jul 1995 rev. 2.01 for linux 1.3.7
        !             5:  *          Update required by the new /proc/scsi support.
        !             6:  *
        !             7:  *      11 Mar 1995 rev. 2.00 for linux 1.2.0
        !             8:  *          Fixed a bug which prevented media change detection for removable
        !             9:  *          disk drives.
        !            10:  *
        !            11:  *      23 Feb 1995 rev. 1.18 for linux 1.1.94
        !            12:  *          Added a check for scsi_register returning NULL.
        !            13:  *
        !            14:  *      11 Feb 1995 rev. 1.17 for linux 1.1.91
        !            15:  *          Now DEBUG_RESET is disabled by default.
        !            16:  *          Register a board even if it does not assert DMA protocol support
        !            17:  *          (DPT SK2011B does not report correctly the dmasup bit).
        !            18:  *
        !            19:  *       9 Feb 1995 rev. 1.16 for linux 1.1.90
        !            20:  *          Use host->wish_block instead of host->block.
        !            21:  *          New list of Data Out SCSI commands.
        !            22:  *
        !            23:  *       8 Feb 1995 rev. 1.15 for linux 1.1.89
        !            24:  *          Cleared target_time_out counter while performing a reset.
        !            25:  *          All external symbols renamed to avoid possible name conflicts.
        !            26:  *
        !            27:  *      28 Jan 1995 rev. 1.14 for linux 1.1.86
        !            28:  *          Added module support.
        !            29:  *          Log and do a retry when a disk drive returns a target status 
        !            30:  *          different from zero on a recovered error.
        !            31:  *
        !            32:  *      24 Jan 1995 rev. 1.13 for linux 1.1.85
        !            33:  *          Use optimized board configuration, with a measured performance
        !            34:  *          increase in the range 10%-20% on i/o throughput.
        !            35:  *
        !            36:  *      16 Jan 1995 rev. 1.12 for linux 1.1.81
        !            37:  *          Fix mscp structure comments (no functional change).
        !            38:  *          Display a message if check_region detects a port address
        !            39:  *          already in use.
        !            40:  *
        !            41:  *      17 Dec 1994 rev. 1.11 for linux 1.1.74
        !            42:  *          Use the scsicam_bios_param routine. This allows an easy
        !            43:  *          migration path from disk partition tables created using 
        !            44:  *          different SCSI drivers and non optimal disk geometry.
        !            45:  *
        !            46:  *      15 Dec 1994 rev. 1.10 for linux 1.1.74
        !            47:  *          Added support for ISA EATA boards (DPT PM2011, DPT PM2021).
        !            48:  *          The host->block flag is set for all the detected ISA boards.
        !            49:  *          The detect routine no longer enforces LEVEL triggering
        !            50:  *          for EISA boards, it just prints a warning message.
        !            51:  *
        !            52:  *      30 Nov 1994 rev. 1.09 for linux 1.1.68
        !            53:  *          Redo i/o on target status CHECK_CONDITION for TYPE_DISK only.
        !            54:  *          Added optional support for using a single board at a time.
        !            55:  *
        !            56:  *      18 Nov 1994 rev. 1.08 for linux 1.1.64
        !            57:  *          Forces sg_tablesize = 64 and can_queue = 64 if these
        !            58:  *          values are not correctly detected (DPT PM2012).
        !            59:  *
        !            60:  *      14 Nov 1994 rev. 1.07 for linux 1.1.63  Final BETA release.
        !            61:  *      04 Aug 1994 rev. 1.00 for linux 1.1.39  First BETA release.
        !            62:  *
        !            63:  *
        !            64:  *          This driver is based on the CAM (Common Access Method Committee)
        !            65:  *          EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol.
        !            66:  *
        !            67:  *      Copyright (C) 1994, 1995 Dario Ballabio ([email protected])
        !            68:  *
        !            69:  */
        !            70: 
        !            71: /*
        !            72:  *
        !            73:  *  Here is a brief description of the DPT SCSI host adapters.
        !            74:  *  All these boards provide an EATA/DMA compatible programming interface
        !            75:  *  and are fully supported by this driver:
        !            76:  *
        !            77:  *  PM2011B/9X -  Entry Level ISA
        !            78:  *  PM2021A/9X -  High Performance ISA
        !            79:  *  PM2012A       Old EISA
        !            80:  *  PM2012B       Old EISA
        !            81:  *  PM2022A/9X -  Entry Level EISA
        !            82:  *  PM2122A/9X -  High Performance EISA
        !            83:  *  PM2322A/9X -  Extra High Performance EISA
        !            84:  *
        !            85:  *  The DPT PM2001 provides only the EATA/PIO interface and hence is not
        !            86:  *  supported by this driver.
        !            87:  *
        !            88:  *  This code has been tested with up to 3 Distributed Processing Technology 
        !            89:  *  PM2122A/9X (DPT SCSI BIOS v002.D1, firmware v05E.0) eisa controllers,
        !            90:  *  no on board cache and no RAID option. 
        !            91:  *  BIOS must be enabled on the first board and must be disabled for all other 
        !            92:  *  boards. 
        !            93:  *  Support is provided for any number of DPT PM2122 eisa boards.
        !            94:  *  All boards should be configured at the same IRQ level.
        !            95:  *  Multiple IRQ configurations are supported too.
        !            96:  *  Boards can be located in any eisa slot (1-15) and are named EATA0, 
        !            97:  *  EATA1,... in increasing eisa slot number. ISA boards are detected
        !            98:  *  after the eisa slot probes.
        !            99:  *
        !           100:  *  The IRQ for EISA boards should be _level_ triggered (not _edge_ triggered).
        !           101:  *  This is a requirement in order to support multiple boards on the same IRQ.
        !           102:  *
        !           103:  *  Other eisa configuration parameters are:
        !           104:  *
        !           105:  *  COMMAND QUEUING   : ENABLED
        !           106:  *  COMMAND TIMEOUT   : ENABLED
        !           107:  *  CACHE             : DISABLED
        !           108:  *
        !           109:  *  In order to support multiple ISA boards in a reliable way,
        !           110:  *  the driver sets host->wish_block = TRUE for all ISA boards.
        !           111:  */
        !           112: 
        !           113: #if defined(MODULE)
        !           114: #include <linux/module.h>
        !           115: #include <linux/version.h>
        !           116: #endif
        !           117: 
        !           118: #include <linux/string.h>
        !           119: #include <linux/sched.h>
        !           120: #include <linux/kernel.h>
        !           121: #include <linux/ioport.h>
        !           122: #include <asm/io.h>
        !           123: #include <asm/system.h>
        !           124: #include <linux/proc_fs.h>
        !           125: #include <linux/blk.h>
        !           126: #include "scsi.h"
        !           127: #include "hosts.h"
        !           128: #include "sd.h"
        !           129: #include <asm/dma.h>
        !           130: #include <asm/irq.h>
        !           131: #include "linux/in.h"
        !           132: #include "eata.h"
        !           133: #include<linux/stat.h>
        !           134: 
        !           135: struct proc_dir_entry proc_scsi_eata2x = {
        !           136:     PROC_SCSI_EATA2X, 6, "eata2x",
        !           137:     S_IFDIR | S_IRUGO | S_IXUGO, 2
        !           138: };
        !           139: 
        !           140: /* Subversion values */
        !           141: #define ISA  0
        !           142: #define ESA 1
        !           143: 
        !           144: #undef FORCE_CONFIG
        !           145: 
        !           146: #undef  DEBUG_DETECT
        !           147: #undef  DEBUG_INTERRUPT
        !           148: #undef  DEBUG_STATISTICS
        !           149: #undef  DEBUG_RESET
        !           150: 
        !           151: #define MAX_TARGET 8
        !           152: #define MAX_IRQ 16
        !           153: #define MAX_BOARDS 18
        !           154: #define MAX_MAILBOXES 64
        !           155: #define MAX_SGLIST 64
        !           156: #define MAX_CMD_PER_LUN 2
        !           157: 
        !           158: #define FALSE 0
        !           159: #define TRUE 1
        !           160: #define FREE 0
        !           161: #define IN_USE   1
        !           162: #define LOCKED   2
        !           163: #define IN_RESET 3
        !           164: #define IGNORE   4
        !           165: #define NO_IRQ  0xff
        !           166: #define NO_DMA  0xff
        !           167: #define MAXLOOP 200000
        !           168: 
        !           169: #define REG_CMD         7
        !           170: #define REG_STATUS      7
        !           171: #define REG_AUX_STATUS  8
        !           172: #define REG_DATA        0
        !           173: #define REG_DATA2       1
        !           174: #define REG_SEE         6
        !           175: #define REG_LOW         2
        !           176: #define REG_LM          3
        !           177: #define REG_MID         4
        !           178: #define REG_MSB         5
        !           179: #define REGION_SIZE     9
        !           180: #define EISA_RANGE      0xf000
        !           181: #define BSY_ASSERTED      0x80
        !           182: #define DRQ_ASSERTED      0x08
        !           183: #define ABSY_ASSERTED     0x01
        !           184: #define IRQ_ASSERTED      0x02
        !           185: #define READ_CONFIG_PIO   0xf0
        !           186: #define SET_CONFIG_PIO    0xf1
        !           187: #define SEND_CP_PIO       0xf2
        !           188: #define RECEIVE_SP_PIO    0xf3
        !           189: #define TRUNCATE_XFR_PIO  0xf4
        !           190: #define RESET_PIO         0xf9
        !           191: #define READ_CONFIG_DMA   0xfd
        !           192: #define SET_CONFIG_DMA    0xfe
        !           193: #define SEND_CP_DMA       0xff
        !           194: #define ASOK              0x00
        !           195: #define ASST              0x01
        !           196: 
        !           197: #define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr)[0])
        !           198: 
        !           199: /* "EATA", in Big Endian format */
        !           200: #define EATA_SIGNATURE 0x41544145
        !           201: 
        !           202: /* Number of valid bytes in the board config structure for EATA 2.0x */
        !           203: #define EATA_2_0A_SIZE 28
        !           204: #define EATA_2_0B_SIZE 30
        !           205: 
        !           206: /* Board info structure */
        !           207: struct eata_info {
        !           208:    ulong  data_len;     /* Number of valid bytes after this field */
        !           209:    ulong  sign;         /* ASCII "EATA" signature */
        !           210:    unchar        :4,    /* unused low nibble */
        !           211:          version:4;    /* EATA version, should be 0x1 */
        !           212:    unchar  ocsena:1,    /* Overlap Command Support Enabled */
        !           213:           tarsup:1,    /* Target Mode Supported */
        !           214:                 :2,
        !           215:           dmasup:1,    /* DMA Supported */
        !           216:           drqvld:1,    /* DRQ Index (DRQX) is valid */
        !           217:              ata:1,    /* This is an ATA device */
        !           218:           haaval:1;    /* Host Adapter Address Valid */
        !           219:    ushort cp_pad_len;   /* Number of pad bytes after cp_len */
        !           220:    unchar host_addr[3]; /* Host Adapter SCSI ID for channels 2, 1, 0 */
        !           221:    unchar reserved;
        !           222:    ulong  cp_len;       /* Number of valid bytes in cp */
        !           223:    ulong  sp_len;       /* Number of valid bytes in sp */
        !           224:    ushort queue_size;   /* Max number of cp that can be queued */
        !           225:    ushort unused;
        !           226:    ushort scatt_size;   /* Max number of entries in scatter/gather table */
        !           227:    unchar     irq:4,    /* Interrupt Request assigned to this controller */
        !           228:           irq_tr:1,    /* 0 for edge triggered, 1 for level triggered */
        !           229:           second:1,    /* 1 if this is a secondary (not primary) controller */
        !           230:             drqx:2;    /* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */
        !           231:    unchar  sync;        /* 1 if scsi target id 7...0 is running sync scsi */
        !           232: 
        !           233:    /* Structure extension defined in EATA 2.0B */
        !           234:    unchar  isaena:1,    /* ISA i/o addressing is disabled/enabled */
        !           235:         forcaddr:1,    /* Port address has been forced */
        !           236:                 :6;
        !           237:    unchar  max_id:5,    /* Max number of SCSI target IDs */
        !           238:         max_chan:3;    /* Max SCSI channel number on this board */
        !           239: 
        !           240:    ushort ipad[249];
        !           241:    };
        !           242: 
        !           243: /* Board config structure */
        !           244: struct eata_config {
        !           245:    ushort len;          /* Number of bytes following this field */
        !           246:    unchar edis:1,       /* Disable EATA interface after config command */
        !           247:         ocena:1,       /* Overlapped Commands Enabled */
        !           248:        mdpena:1,       /* Transfer all Modified Data Pointer Messages */
        !           249:        tarena:1,       /* Target Mode Enabled for this controller */
        !           250:              :4;
        !           251:    unchar cpad[511];
        !           252:    };
        !           253: 
        !           254: /* Returned status packet structure */
        !           255: struct mssp {
        !           256:    unchar adapter_status:7,    /* State related to current command */
        !           257:                     eoc:1;    /* End Of Command (1 = command completed) */
        !           258:    unchar target_status;       /* SCSI status received after data transfer */
        !           259:    unchar unused[2];
        !           260:    ulong inv_res_len;          /* Number of bytes not transferred */
        !           261:    Scsi_Cmnd *SCpnt;           /* Address set in cp */
        !           262:    char mess[12];
        !           263:    };
        !           264: 
        !           265: /* MailBox SCSI Command Packet */
        !           266: struct mscp {
        !           267:    unchar  sreset:1,     /* SCSI Bus Reset Signal should be asserted */
        !           268:             init:1,     /* Re-initialize controller and self test */
        !           269:           reqsen:1,     /* Transfer Request Sense Data to addr using DMA */
        !           270:               sg:1,     /* Use Scatter/Gather */
        !           271:                 :1,
        !           272:           interp:1,     /* The controller interprets cp, not the target */ 
        !           273:             dout:1,     /* Direction of Transfer is Out (Host to Target) */
        !           274:              din:1;     /* Direction of Transfer is In (Target to Host) */
        !           275:    unchar sense_len;     /* Request Sense Length */
        !           276:    unchar unused[4];
        !           277:    unchar phsunit:1,     /* Send to Target Physical Unit (bypass RAID) */
        !           278:          notused:7;
        !           279:    unchar target;        /* SCSI Target ID */
        !           280:    unchar     lun:3,     /* LUN */
        !           281:                 :2,
        !           282:           luntar:1,     /* This cp is for Target (not LUN) */
        !           283:           dispri:1,     /* Disconnect Privilege granted */
        !           284:              one:1;     /* 1 */
        !           285:    unchar mess[3];       /* Massage to/from Target */
        !           286:    unchar cdb[12];       /* Command Descriptor Block */
        !           287:    ulong  data_len;      /* If sg=0 Data Length, if sg=1 sglist length */
        !           288:    Scsi_Cmnd *SCpnt;     /* Address to be returned is sp */
        !           289:    ulong  data_address;  /* If sg=0 Data Address, if sg=1 sglist address */
        !           290:    ulong  sp_addr;       /* Address where sp is DMA'ed when cp completes */
        !           291:    ulong  sense_addr;    /* Address where Sense Data is DMA'ed on error */
        !           292: 
        !           293:    struct sg_list {
        !           294:       unsigned int address;     /* Segment Address */
        !           295:       unsigned int num_bytes;   /* Segment Length */
        !           296:       } sglist[MAX_SGLIST];
        !           297: 
        !           298:    unsigned int index;   /* cp index */
        !           299:    };
        !           300: 
        !           301: struct hostdata {
        !           302:    struct mscp cp[MAX_MAILBOXES];       /* Mailboxes for this board */
        !           303:    unsigned int cp_stat[MAX_MAILBOXES]; /* FREE, IN_USE, LOCKED, IN_RESET */
        !           304:    unsigned int last_cp_used;           /* Index of last mailbox used */
        !           305:    unsigned int iocount;                /* Total i/o done for this board */
        !           306:    unsigned int multicount;             /* Total ... in second ihdlr loop */
        !           307:    int board_number;                    /* Number of this board */
        !           308:    char board_name[16];                 /* Name of this board */
        !           309:    char board_id[256];                  /* data from INQUIRY on this board */
        !           310:    int in_reset;                        /* True if board is doing a reset */
        !           311:    int target_time_out[MAX_TARGET];     /* N. of timeout errors on target */
        !           312:    int target_reset[MAX_TARGET];        /* If TRUE redo operation on target */
        !           313:    unsigned char subversion;            /* Bus type, either ISA or ESA */
        !           314:    unsigned char protocol_rev;          /* EATA 2.0 rev., 'A' or 'B' or 'C' */
        !           315:    struct mssp sp[MAX_MAILBOXES];       /* Returned status for this board */
        !           316:    };
        !           317: 
        !           318: static struct Scsi_Host * sh[MAX_BOARDS + 1];
        !           319: static const char* driver_name = "EATA";
        !           320: static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ];
        !           321: 
        !           322: #define HD(board) ((struct hostdata *) &sh[board]->hostdata)
        !           323: #define BN(board) (HD(board)->board_name)
        !           324: 
        !           325: static void eata2x_interrupt_handler(int, struct pt_regs *);
        !           326: static int do_trace = FALSE;
        !           327: 
        !           328: static inline unchar wait_on_busy(ushort iobase) {
        !           329:    unsigned int loop = MAXLOOP;
        !           330: 
        !           331:    while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED)
        !           332:       if (--loop == 0) return TRUE;
        !           333: 
        !           334:    return FALSE;
        !           335: }
        !           336: 
        !           337: static inline unchar do_dma (ushort iobase, unsigned int addr, unchar cmd) {
        !           338: 
        !           339:    if (wait_on_busy(iobase)) return TRUE;
        !           340: 
        !           341:    if (addr) {
        !           342:       outb((char)  addr,        iobase + REG_LOW);
        !           343:       outb((char) (addr >> 8),  iobase + REG_LM);
        !           344:       outb((char) (addr >> 16), iobase + REG_MID);
        !           345:       outb((char) (addr >> 24), iobase + REG_MSB);
        !           346:       }
        !           347: 
        !           348:    outb(cmd, iobase + REG_CMD);
        !           349:    return FALSE;
        !           350: }
        !           351: 
        !           352: static inline unchar read_pio (ushort iobase, ushort *start, ushort *end) {
        !           353:    unsigned int loop = MAXLOOP;
        !           354:    ushort *p;
        !           355: 
        !           356:    for (p = start; p <= end; p++) {
        !           357: 
        !           358:       while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) 
        !           359:         if (--loop == 0) return TRUE;
        !           360: 
        !           361:       loop = MAXLOOP;
        !           362:       *p = inw(iobase);
        !           363:       }
        !           364: 
        !           365:    return FALSE;
        !           366: }
        !           367: 
        !           368: static inline int port_detect(ushort *port_base, unsigned int j, 
        !           369:                              Scsi_Host_Template * tpnt) {
        !           370:    unsigned char irq, dma_channel, subversion;
        !           371:    unsigned char protocol_rev;
        !           372:    struct eata_info info;
        !           373:    const char *board_status;
        !           374: 
        !           375:    /* Allowed DMA channels for ISA (0 indicates reserved) */
        !           376:    unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };
        !           377: 
        !           378:    char name[16];
        !           379: 
        !           380:    sprintf(name, "%s%d", driver_name, j);
        !           381: 
        !           382:    if(check_region(*port_base, REGION_SIZE)) {
        !           383:       printk("%s: address 0x%03x in use, skipping probe.\n", 
        !           384:             name, *port_base);
        !           385:       return FALSE;
        !           386:       }
        !           387: 
        !           388:    if (do_dma(*port_base, 0, READ_CONFIG_PIO)) return FALSE;
        !           389: 
        !           390:    /* Read the info structure */
        !           391:    if (read_pio(*port_base, (ushort *)&info, (ushort *)&info.ipad[0])) 
        !           392:       return FALSE;
        !           393: 
        !           394:    /* Check the controller "EATA" signature */
        !           395:    if (info.sign != EATA_SIGNATURE) return FALSE;
        !           396: 
        !           397:    if (ntohl(info.data_len) < EATA_2_0A_SIZE) {
        !           398:       printk("%s: config structure size (%ld bytes) too short, detaching.\n", 
        !           399:             name, ntohl(info.data_len));
        !           400:       return FALSE;
        !           401:       }
        !           402:    else if (ntohl(info.data_len) == EATA_2_0A_SIZE)
        !           403:       protocol_rev = 'A';
        !           404:    else if (ntohl(info.data_len) == EATA_2_0B_SIZE)
        !           405:       protocol_rev = 'B';
        !           406:    else
        !           407:       protocol_rev = 'C';
        !           408: 
        !           409:    if (protocol_rev != 'A' && info.max_chan > 0)
        !           410:       printk("%s: warning, only scsi channel 0 is supported.\n", name);
        !           411: 
        !           412:    irq = info.irq;
        !           413: 
        !           414:    if (*port_base & EISA_RANGE) {
        !           415: 
        !           416:       if (!info.haaval || info.ata || info.drqvld) {
        !           417:         printk("%s: unusable EISA board found (%d%d%d), detaching.\n", 
        !           418:                name, info.haaval, info.ata, info.drqvld);
        !           419:         return FALSE;
        !           420:         }
        !           421: 
        !           422:       subversion = ESA;
        !           423:       dma_channel = NO_DMA;
        !           424:       }
        !           425:    else {
        !           426: 
        !           427:       if (!info.haaval || info.ata || !info.drqvld) {
        !           428:         printk("%s: unusable ISA board found (%d%d%d), detaching.\n",
        !           429:                name, info.haaval, info.ata, info.drqvld);
        !           430:         return FALSE;
        !           431:         }
        !           432: 
        !           433:       subversion = ISA;
        !           434:       dma_channel = dma_channel_table[3 - info.drqx];
        !           435:       }
        !           436: 
        !           437:    if (!info.dmasup)
        !           438:       printk("%s: warning, DMA protocol support not asserted.\n", name);
        !           439: 
        !           440:    if (subversion == ESA && !info.irq_tr)
        !           441:       printk("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",
        !           442:             name, irq);
        !           443: 
        !           444:    if (info.second)
        !           445:       board_status = "Sec.";
        !           446:    else
        !           447:       board_status = "Prim.";
        !           448: 
        !           449:    /* Board detected, allocate its IRQ if not already done */
        !           450:    if ((irq >= MAX_IRQ) || ((irqlist[irq] == NO_IRQ) && request_irq
        !           451:        (irq, eata2x_interrupt_handler, SA_INTERRUPT, driver_name))) {
        !           452:       printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
        !           453:       return FALSE;
        !           454:       }
        !           455: 
        !           456:    if (subversion == ISA && request_dma(dma_channel, driver_name)) {
        !           457:       printk("%s: unable to allocate DMA channel %u, detaching.\n",
        !           458:             name, dma_channel);
        !           459:       free_irq(irq);
        !           460:       return FALSE;
        !           461:       }
        !           462: 
        !           463: #if defined (FORCE_CONFIG)
        !           464:    {
        !           465:    struct eata_config config;
        !           466: 
        !           467:    /* Set board configuration */
        !           468:    memset((char *)&config, 0, sizeof(struct eata_config));
        !           469:    config.len = (ushort) htons((ushort)510);
        !           470:    config.ocena = TRUE;
        !           471: 
        !           472:    if (do_dma(*port_base, (unsigned int)&config, SET_CONFIG_DMA)) {
        !           473:       printk("%s: busy timeout sending configuration, detaching.\n", name);
        !           474:       return FALSE;
        !           475:       }
        !           476:    }
        !           477: #endif
        !           478: 
        !           479:    sh[j] = scsi_register(tpnt, sizeof(struct hostdata));
        !           480: 
        !           481:    if (sh[j] == NULL) {
        !           482:       printk("%s: unable to register host, detaching.\n", name);
        !           483: 
        !           484:       if (irqlist[irq] == NO_IRQ) free_irq(irq);
        !           485: 
        !           486:       if (subversion == ISA) free_dma(dma_channel);
        !           487: 
        !           488:       return FALSE;
        !           489:       }
        !           490: 
        !           491:    sh[j]->io_port = *port_base;
        !           492:    sh[j]->n_io_port = REGION_SIZE;
        !           493:    sh[j]->dma_channel = dma_channel;
        !           494:    sh[j]->irq = irq;
        !           495:    sh[j]->sg_tablesize = (ushort) ntohs(info.scatt_size);
        !           496:    sh[j]->this_id = (ushort) info.host_addr[3];
        !           497:    sh[j]->can_queue = (ushort) ntohs(info.queue_size);
        !           498:    sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;
        !           499: 
        !           500:    /* Register the I/O space that we use */
        !           501:    request_region(sh[j]->io_port, REGION_SIZE, driver_name);
        !           502: 
        !           503:    memset(HD(j), 0, sizeof(struct hostdata));
        !           504:    HD(j)->subversion = subversion;
        !           505:    HD(j)->protocol_rev = protocol_rev;
        !           506:    HD(j)->board_number = j;
        !           507:    irqlist[irq] = j;
        !           508: 
        !           509:    if (HD(j)->subversion == ESA)
        !           510:       sh[j]->unchecked_isa_dma = FALSE;
        !           511:    else {
        !           512:       sh[j]->wish_block = TRUE;
        !           513:       sh[j]->unchecked_isa_dma = TRUE;
        !           514:       disable_dma(dma_channel);
        !           515:       clear_dma_ff(dma_channel);
        !           516:       set_dma_mode(dma_channel, DMA_MODE_CASCADE);
        !           517:       enable_dma(dma_channel);
        !           518:       }
        !           519: 
        !           520:    strcpy(BN(j), name);
        !           521: 
        !           522:    printk("%s: 2.0%c, %s, ID %d, PORT 0x%03x, IRQ %u, DMA %u, SG %d, "\
        !           523:          "Mbox %d, CmdLun %d.\n", BN(j), HD(j)->protocol_rev, board_status, 
        !           524:           sh[j]->this_id, sh[j]->io_port, sh[j]->irq, sh[j]->dma_channel,
        !           525:           sh[j]->sg_tablesize, sh[j]->can_queue, sh[j]->cmd_per_lun);
        !           526: 
        !           527:    /* DPT PM2012 does not allow to detect sg_tablesize correctly */
        !           528:    if (sh[j]->sg_tablesize > MAX_SGLIST || sh[j]->sg_tablesize < 2) {
        !           529:       printk("%s: detect, forcing to use %d SG lists.\n", BN(j), MAX_SGLIST);
        !           530:       sh[j]->sg_tablesize = MAX_SGLIST;
        !           531:       }
        !           532: 
        !           533:    /* DPT PM2012 does not allow to detect can_queue correctly */
        !           534:    if (sh[j]->can_queue > MAX_MAILBOXES || sh[j]->can_queue  < 2) {
        !           535:       printk("%s: detect, forcing to use %d Mbox.\n", BN(j), MAX_MAILBOXES);
        !           536:       sh[j]->can_queue = MAX_MAILBOXES;
        !           537:       }
        !           538: 
        !           539: #if defined (DEBUG_DETECT)
        !           540:    if (protocol_rev != 'A')
        !           541:       printk("%s: EATA 2.0%c, isaena %u, forcaddr %u, max_id %u,"\
        !           542:             " max_chan %u.\n", name, protocol_rev, info.isaena, 
        !           543:             info.forcaddr, info.max_id, info.max_chan);
        !           544: 
        !           545:    printk("%s: Version 0x%x, SYNC 0x%x, infol %ld, cpl %ld spl %ld.\n", 
        !           546:          name, info.version, info.sync, ntohl(info.data_len), 
        !           547:          ntohl(info.cp_len), ntohl(info.sp_len));
        !           548: #endif
        !           549: 
        !           550:    return TRUE;
        !           551: }
        !           552: 
        !           553: int eata2x_detect (Scsi_Host_Template * tpnt) {
        !           554:    unsigned int j = 0, k, flags;
        !           555: 
        !           556:    ushort io_port[] = { 
        !           557:       0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88,
        !           558:       0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88, 
        !           559:       0x1f0,  0x170,  0x330,  0x230,  0x0
        !           560:       };
        !           561: 
        !           562:    ushort *port_base = io_port;
        !           563: 
        !           564:    tpnt->proc_dir = &proc_scsi_eata2x;
        !           565: 
        !           566:    save_flags(flags);
        !           567:    cli();
        !           568: 
        !           569:    for (k = 0; k < MAX_IRQ; k++) {
        !           570:       irqlist[k] = NO_IRQ;
        !           571:       calls[k] = 0;
        !           572:       }
        !           573: 
        !           574:    for (k = 0; k < MAX_BOARDS + 1; k++) sh[k] = NULL;
        !           575: 
        !           576:    while (*port_base) {
        !           577: 
        !           578:       if (j < MAX_BOARDS && port_detect(port_base, j, tpnt)) j++;
        !           579: 
        !           580:       port_base++;
        !           581:       }
        !           582: 
        !           583:    if (j > 0) 
        !           584:       printk("EATA/DMA 2.0x: Copyright (C) 1994, 1995 Dario Ballabio.\n");
        !           585: 
        !           586:    restore_flags(flags);
        !           587:    return j;
        !           588: }
        !           589: 
        !           590: static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
        !           591:    unsigned int k;
        !           592:    struct scatterlist * sgpnt;
        !           593: 
        !           594:    sgpnt = (struct scatterlist *) SCpnt->request_buffer;
        !           595: 
        !           596:    for (k = 0; k < SCpnt->use_sg; k++) {
        !           597:       cpp->sglist[k].address = htonl((unsigned int) sgpnt[k].address);
        !           598:       cpp->sglist[k].num_bytes = htonl((unsigned int) sgpnt[k].length);
        !           599:       }
        !           600: 
        !           601:    cpp->data_address = htonl((unsigned int) cpp->sglist);
        !           602:    cpp->data_len = htonl((SCpnt->use_sg * sizeof(struct sg_list)));
        !           603: }
        !           604: 
        !           605: int eata2x_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
        !           606:    unsigned int i, j, k, flags;
        !           607:    struct mscp *cpp;
        !           608:    struct mssp *spp;
        !           609: 
        !           610:    static const unsigned char data_out_cmds[] = {
        !           611:       0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x0b, 0x10, 0x16, 0x18, 0x1d, 
        !           612:       0x24, 0x2b, 0x2e, 0x30, 0x31, 0x32, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 
        !           613:       0x3f, 0x40, 0x41, 0x4c, 0xaa, 0xae, 0xb0, 0xb1, 0xb2, 0xb6, 0xea
        !           614:       };
        !           615: 
        !           616:    save_flags(flags);
        !           617:    cli();
        !           618:    /* j is the board number */
        !           619:    j = ((struct hostdata *) SCpnt->host->hostdata)->board_number;
        !           620: 
        !           621:    if (!done) panic("%s: qcomm, pid %ld, null done.\n", BN(j), SCpnt->pid);
        !           622: 
        !           623:    /* i is the mailbox number, look for the first free mailbox 
        !           624:       starting from last_cp_used */
        !           625:    i = HD(j)->last_cp_used + 1;
        !           626: 
        !           627:    for (k = 0; k < sh[j]->can_queue; k++, i++) {
        !           628: 
        !           629:       if (i >= sh[j]->can_queue) i = 0;
        !           630: 
        !           631:       if (HD(j)->cp_stat[i] == FREE) {
        !           632:         HD(j)->last_cp_used = i;
        !           633:         break;
        !           634:         }
        !           635:       }
        !           636: 
        !           637:    if (k == sh[j]->can_queue) {
        !           638:       printk("%s: qcomm, no free mailbox, resetting.\n", BN(j));
        !           639: 
        !           640:       if (HD(j)->in_reset) 
        !           641:         printk("%s: qcomm, already in reset.\n", BN(j));
        !           642:       else if (eata2x_reset(SCpnt) == SCSI_RESET_SUCCESS) 
        !           643:         panic("%s: qcomm, SCSI_RESET_SUCCESS.\n", BN(j));
        !           644: 
        !           645:       SCpnt->result = DID_BUS_BUSY << 16; 
        !           646:       SCpnt->host_scribble = NULL;
        !           647:       printk("%s: qcomm, pid %ld, DID_BUS_BUSY, done.\n", BN(j), SCpnt->pid);
        !           648:       restore_flags(flags);
        !           649:       done(SCpnt);    
        !           650:       return 0;
        !           651:       }
        !           652: 
        !           653:    /* Set pointer to control packet structure */
        !           654:    cpp = &HD(j)->cp[i];
        !           655: 
        !           656:    memset(cpp, 0, sizeof(struct mscp));
        !           657: 
        !           658:    /* Set pointer to status packet structure */
        !           659:    spp = &HD(j)->sp[i];
        !           660: 
        !           661:    memset(spp, 0, sizeof(struct mssp));
        !           662: 
        !           663:    /* The EATA protocol uses Big Endian format, while Intel is Little Endian */
        !           664:    cpp->sp_addr = htonl((unsigned int) spp);
        !           665: 
        !           666:    SCpnt->scsi_done = done;
        !           667:    cpp->index = i;
        !           668:    SCpnt->host_scribble = (unsigned char *) &cpp->index;
        !           669: 
        !           670:    if (do_trace) printk("%s: qcomm, mbox %d, target %d, pid %ld.\n",
        !           671:                        BN(j), i, SCpnt->target, SCpnt->pid);
        !           672: 
        !           673:    for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
        !           674:      if (SCpnt->cmnd[0] == data_out_cmds[k]) {
        !           675:        cpp->dout = TRUE;
        !           676:        break;
        !           677:        }
        !           678: 
        !           679:    cpp->din = !cpp->dout;
        !           680:    cpp->reqsen = TRUE;
        !           681:    cpp->dispri = TRUE;
        !           682:    cpp->one = TRUE;
        !           683:    cpp->target = SCpnt->target;
        !           684:    cpp->lun = SCpnt->lun;  
        !           685:    cpp->SCpnt = SCpnt;
        !           686:    cpp->sense_addr = htonl((unsigned int) SCpnt->sense_buffer); 
        !           687:    cpp->sense_len = sizeof SCpnt->sense_buffer;
        !           688: 
        !           689:    if (SCpnt->use_sg) {
        !           690:       cpp->sg = TRUE;
        !           691:       build_sg_list(cpp, SCpnt);
        !           692:       }
        !           693:    else {
        !           694:       cpp->data_address = htonl((unsigned int) SCpnt->request_buffer);
        !           695:       cpp->data_len = htonl(SCpnt->request_bufflen);
        !           696:       }
        !           697: 
        !           698:    memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);
        !           699: 
        !           700:    /* Send control packet to the board */
        !           701:    if (do_dma(sh[j]->io_port, (unsigned int) cpp, SEND_CP_DMA)) {
        !           702:       SCpnt->result = DID_ERROR << 16; 
        !           703:       SCpnt->host_scribble = NULL;
        !           704:       printk("%s: qcomm, target %d, pid %ld, adapter busy, DID_ERROR, done.\n", 
        !           705:             BN(j), SCpnt->target, SCpnt->pid);
        !           706:       restore_flags(flags);
        !           707:       done(SCpnt);    
        !           708:       return 0;
        !           709:       }
        !           710: 
        !           711:    HD(j)->cp_stat[i] = IN_USE;
        !           712:    restore_flags(flags);
        !           713:    return 0;
        !           714: }
        !           715: 
        !           716: int eata2x_abort (Scsi_Cmnd *SCarg) {
        !           717:    unsigned int i, j, flags;
        !           718: 
        !           719:    save_flags(flags);
        !           720:    cli();
        !           721:    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
        !           722: 
        !           723:    if (SCarg->host_scribble == NULL) {
        !           724:       printk("%s: abort, target %d, pid %ld inactive.\n",
        !           725:             BN(j), SCarg->target, SCarg->pid);
        !           726:       restore_flags(flags);
        !           727:       return SCSI_ABORT_NOT_RUNNING;
        !           728:       }
        !           729: 
        !           730:    i = *(unsigned int *)SCarg->host_scribble;
        !           731:    printk("%s: abort, mbox %d, target %d, pid %ld.\n", 
        !           732:          BN(j), i, SCarg->target, SCarg->pid);
        !           733: 
        !           734:    if (i >= sh[j]->can_queue)
        !           735:       panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
        !           736: 
        !           737:    if (wait_on_busy(sh[j]->io_port)) {
        !           738:       printk("%s: abort, timeout error.\n", BN(j));
        !           739:       restore_flags(flags);
        !           740:       return SCSI_ABORT_ERROR;
        !           741:       }
        !           742: 
        !           743:    if (HD(j)->cp_stat[i] == FREE) {
        !           744:       printk("%s: abort, mbox %d is free.\n", BN(j), i);
        !           745:       restore_flags(flags);
        !           746:       return SCSI_ABORT_NOT_RUNNING;
        !           747:       }
        !           748: 
        !           749:    if (HD(j)->cp_stat[i] == IN_USE) {
        !           750:       printk("%s: abort, mbox %d is in use.\n", BN(j), i);
        !           751: 
        !           752:       if (SCarg != HD(j)->cp[i].SCpnt)
        !           753:         panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",
        !           754:               BN(j), i, SCarg, HD(j)->cp[i].SCpnt);
        !           755: 
        !           756:       restore_flags(flags);
        !           757:       return SCSI_ABORT_SNOOZE;
        !           758:       }
        !           759: 
        !           760:    if (HD(j)->cp_stat[i] == IN_RESET) {
        !           761:       printk("%s: abort, mbox %d is in reset.\n", BN(j), i);
        !           762:       restore_flags(flags);
        !           763:       return SCSI_ABORT_ERROR;
        !           764:       }
        !           765: 
        !           766:    if (HD(j)->cp_stat[i] == LOCKED) {
        !           767:       printk("%s: abort, mbox %d is locked.\n", BN(j), i);
        !           768:       restore_flags(flags);
        !           769:       return SCSI_ABORT_NOT_RUNNING;
        !           770:       }
        !           771:    restore_flags(flags);
        !           772:    panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
        !           773: }
        !           774: 
        !           775: int eata2x_reset (Scsi_Cmnd *SCarg) {
        !           776:    unsigned int i, j, flags, time, k, limit = 0;
        !           777:    int arg_done = FALSE;
        !           778:    Scsi_Cmnd *SCpnt;
        !           779: 
        !           780:    save_flags(flags);
        !           781:    cli();
        !           782:    j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
        !           783:    printk("%s: reset, enter, target %d, pid %ld.\n", 
        !           784:          BN(j), SCarg->target, SCarg->pid);
        !           785: 
        !           786:    if (SCarg->host_scribble == NULL)
        !           787:       printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
        !           788: 
        !           789:    if (HD(j)->in_reset) {
        !           790:       printk("%s: reset, exit, already in reset.\n", BN(j));
        !           791:       restore_flags(flags);
        !           792:       return SCSI_RESET_ERROR;
        !           793:       }
        !           794: 
        !           795:    if (wait_on_busy(sh[j]->io_port)) {
        !           796:       printk("%s: reset, exit, timeout error.\n", BN(j));
        !           797:       restore_flags(flags);
        !           798:       return SCSI_RESET_ERROR;
        !           799:       }
        !           800: 
        !           801:    for (k = 0; k < MAX_TARGET; k++) HD(j)->target_reset[k] = TRUE;
        !           802: 
        !           803:    for (k = 0; k < MAX_TARGET; k++) HD(j)->target_time_out[k] = 0;
        !           804: 
        !           805:    for (i = 0; i < sh[j]->can_queue; i++) {
        !           806: 
        !           807:       if (HD(j)->cp_stat[i] == FREE) continue;
        !           808: 
        !           809:       if (HD(j)->cp_stat[i] == LOCKED) {
        !           810:         HD(j)->cp_stat[i] = FREE;
        !           811:         printk("%s: reset, locked mbox %d forced free.\n", BN(j), i);
        !           812:         continue;
        !           813:         }
        !           814: 
        !           815:       SCpnt = HD(j)->cp[i].SCpnt;
        !           816:       HD(j)->cp_stat[i] = IN_RESET;
        !           817:       printk("%s: reset, mbox %d in reset, pid %ld.\n",
        !           818:             BN(j), i, SCpnt->pid);
        !           819: 
        !           820:       if (SCpnt == NULL)
        !           821:         panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i);
        !           822: 
        !           823:       if (SCpnt->host_scribble == NULL)
        !           824:         panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i);
        !           825: 
        !           826:       if (*(unsigned int *)SCpnt->host_scribble != i) 
        !           827:         panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i);
        !           828: 
        !           829:       if (SCpnt->scsi_done == NULL) 
        !           830:         panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i);
        !           831: 
        !           832:       if (SCpnt == SCarg) arg_done = TRUE;
        !           833:       }
        !           834: 
        !           835:    if (do_dma(sh[j]->io_port, 0, RESET_PIO)) {
        !           836:       printk("%s: reset, cannot reset, timeout error.\n", BN(j));
        !           837:       restore_flags(flags);
        !           838:       return SCSI_RESET_ERROR;
        !           839:       }
        !           840: 
        !           841:    printk("%s: reset, board reset done, enabling interrupts.\n", BN(j));
        !           842: 
        !           843: #if defined (DEBUG_RESET)
        !           844:    do_trace = TRUE;
        !           845: #endif
        !           846: 
        !           847:    HD(j)->in_reset = TRUE;
        !           848:    sti();
        !           849:    time = jiffies;
        !           850:    while (jiffies < (time + 100) && limit++ < 100000000);
        !           851:    cli();
        !           852:    printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit);
        !           853: 
        !           854:    for (i = 0; i < sh[j]->can_queue; i++) {
        !           855: 
        !           856:       /* Skip mailboxes already set free by interrupt */
        !           857:       if (HD(j)->cp_stat[i] != IN_RESET) continue;
        !           858: 
        !           859:       SCpnt = HD(j)->cp[i].SCpnt;
        !           860:       SCpnt->result = DID_RESET << 16;
        !           861:       SCpnt->host_scribble = NULL;
        !           862: 
        !           863:       /* This mailbox is still waiting for its interrupt */
        !           864:       HD(j)->cp_stat[i] = LOCKED;
        !           865: 
        !           866:       printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
        !           867:             BN(j), i, SCpnt->pid);
        !           868:       restore_flags(flags);
        !           869:       SCpnt->scsi_done(SCpnt);
        !           870:       cli();
        !           871:       }
        !           872: 
        !           873:    HD(j)->in_reset = FALSE;
        !           874:    do_trace = FALSE;
        !           875:    restore_flags(flags);
        !           876: 
        !           877:    if (arg_done) {
        !           878:       printk("%s: reset, exit, success.\n", BN(j));
        !           879:       return SCSI_RESET_SUCCESS;
        !           880:       }
        !           881:    else {
        !           882:       printk("%s: reset, exit, wakeup.\n", BN(j));
        !           883:       return SCSI_RESET_PUNT;
        !           884:       }
        !           885: }
        !           886: 
        !           887: static void eata2x_interrupt_handler(int irq, struct pt_regs * regs) {
        !           888:    Scsi_Cmnd *SCpnt;
        !           889:    unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0;
        !           890:    struct mssp *spp;
        !           891:    struct mscp *cpp;
        !           892: 
        !           893:    save_flags(flags);
        !           894:    cli();
        !           895: 
        !           896:    if (irqlist[irq] == NO_IRQ) {
        !           897:       printk("%s, ihdlr, irq %d, unexpected interrupt.\n", driver_name, irq);
        !           898:       restore_flags(flags);
        !           899:       return;
        !           900:       }
        !           901: 
        !           902:    if (do_trace) printk("%s: ihdlr, enter, irq %d, calls %d.\n", 
        !           903:                        driver_name, irq, calls[irq]);
        !           904: 
        !           905:    /* Service all the boards configured on this irq */
        !           906:    for (j = 0; sh[j] != NULL; j++) {
        !           907: 
        !           908:       if (sh[j]->irq != irq) continue;
        !           909: 
        !           910:       loops = 0;
        !           911: 
        !           912:       /* Loop until all interrupts for a board are serviced */
        !           913:       while (inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED) {
        !           914:         total_loops++;
        !           915:         loops++;
        !           916: 
        !           917:         if (do_trace) printk("%s: ihdlr, start service, count %d.\n",
        !           918:                              BN(j), HD(j)->iocount);
        !           919:    
        !           920:         /* Read the status register to clear the interrupt indication */
        !           921:         inb(sh[j]->io_port + REG_STATUS);
        !           922:    
        !           923:         /* Service all mailboxes of this board */
        !           924:         for (i = 0; i < sh[j]->can_queue; i++) {
        !           925:            spp = &HD(j)->sp[i];
        !           926:    
        !           927:            /* Check if this mailbox has completed the operation */
        !           928:            if (spp->eoc == FALSE) continue;
        !           929:    
        !           930:            spp->eoc = FALSE;
        !           931:    
        !           932:            if (HD(j)->cp_stat[i] == IGNORE) {
        !           933:               HD(j)->cp_stat[i] = FREE;
        !           934:               continue;
        !           935:               }
        !           936:            else if (HD(j)->cp_stat[i] == LOCKED) {
        !           937:               HD(j)->cp_stat[i] = FREE;
        !           938:               printk("%s: ihdlr, mbox %d unlocked, count %d.\n",
        !           939:                      BN(j), i, HD(j)->iocount);
        !           940:               continue;
        !           941:               }
        !           942:            else if (HD(j)->cp_stat[i] == FREE) {
        !           943:               printk("%s: ihdlr, mbox %d is free, count %d.\n", 
        !           944:                      BN(j), i, HD(j)->iocount);
        !           945:               continue;
        !           946:               }
        !           947:            else if (HD(j)->cp_stat[i] == IN_RESET)
        !           948:               printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
        !           949:            else if (HD(j)->cp_stat[i] != IN_USE) 
        !           950:               panic("%s: ihdlr, mbox %d, invalid cp_stat.\n", BN(j), i);
        !           951:    
        !           952:            HD(j)->cp_stat[i] = FREE;
        !           953:            cpp = &HD(j)->cp[i];
        !           954:            SCpnt = spp->SCpnt;
        !           955:    
        !           956:            if (SCpnt == NULL)
        !           957:               panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", BN(j), i);
        !           958:    
        !           959:            if (SCpnt != cpp->SCpnt)
        !           960:               panic("%s: ihdlr, mbox %d, sp SCpnt %p, cp SCpnt %p.\n",
        !           961:                     BN(j), i, SCpnt, cpp->SCpnt);
        !           962:    
        !           963:            if (SCpnt->host_scribble == NULL)
        !           964:               panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n",
        !           965:                     BN(j), i, SCpnt->pid, SCpnt);
        !           966:    
        !           967:            if (*(unsigned int *)SCpnt->host_scribble != i) 
        !           968:               panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d,"\
        !           969:                     " irq %d.\n", BN(j), i, SCpnt->pid, 
        !           970:                     *(unsigned int *)SCpnt->host_scribble, irq);
        !           971:    
        !           972:            tstatus = status_byte(spp->target_status);
        !           973:    
        !           974:            switch (spp->adapter_status) {
        !           975:               case ASOK:     /* status OK */
        !           976:    
        !           977:                  /* Forces a reset if a disk drive keeps returning BUSY */
        !           978:                  if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE) 
        !           979:                     status = DID_ERROR << 16;
        !           980:    
        !           981:                  /* If there was a bus reset, redo operation on each target */
        !           982:                  else if (tstatus != GOOD
        !           983:                           && SCpnt->device->type == TYPE_DISK
        !           984:                           && HD(j)->target_reset[SCpnt->target])
        !           985:                     status = DID_BUS_BUSY << 16;
        !           986:    
        !           987:                  /* Works around a flaw in scsi.c */
        !           988:                  else if (tstatus == CHECK_CONDITION
        !           989:                           && SCpnt->device->type == TYPE_DISK
        !           990:                           && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
        !           991:                     status = DID_BUS_BUSY << 16;
        !           992: 
        !           993:                  else
        !           994:                     status = DID_OK << 16;
        !           995:    
        !           996:                  if (tstatus == GOOD)
        !           997:                     HD(j)->target_reset[SCpnt->target] = FALSE;
        !           998:    
        !           999:                  if (spp->target_status && SCpnt->device->type == TYPE_DISK)
        !          1000:                     printk("%s: ihdlr, target %d:%d, pid %ld, target_status "\
        !          1001:                            "0x%x, sense key 0x%x.\n", BN(j), 
        !          1002:                            SCpnt->target, SCpnt->lun, SCpnt->pid,
        !          1003:                            spp->target_status, SCpnt->sense_buffer[2]);
        !          1004:    
        !          1005:                  HD(j)->target_time_out[SCpnt->target] = 0;
        !          1006:    
        !          1007:                  break;
        !          1008:               case ASST:     /* Selection Time Out */
        !          1009:               case 0x02:     /* Command Time Out   */
        !          1010:    
        !          1011:                  if (HD(j)->target_time_out[SCpnt->target] > 1)
        !          1012:                     status = DID_ERROR << 16;
        !          1013:                  else {
        !          1014:                     status = DID_TIME_OUT << 16;
        !          1015:                     HD(j)->target_time_out[SCpnt->target]++;
        !          1016:                     }
        !          1017:    
        !          1018:                  break;
        !          1019:               case 0x03:     /* SCSI Bus Reset Received */
        !          1020:               case 0x04:     /* Initial Controller Power-up */
        !          1021:    
        !          1022:                  if (SCpnt->device->type != TYPE_TAPE)
        !          1023:                     status = DID_BUS_BUSY << 16;
        !          1024:                  else
        !          1025:                     status = DID_ERROR << 16;
        !          1026:    
        !          1027:                  for (k = 0; k < MAX_TARGET; k++) 
        !          1028:                     HD(j)->target_reset[k] = TRUE;
        !          1029:    
        !          1030:                  break;
        !          1031:               case 0x07:     /* Bus Parity Error */
        !          1032:               case 0x0c:     /* Controller Ram Parity */
        !          1033:               case 0x05:     /* Unexpected Bus Phase */
        !          1034:               case 0x06:     /* Unexpected Bus Free */
        !          1035:               case 0x08:     /* SCSI Hung */
        !          1036:               case 0x09:     /* Unexpected Message Reject */
        !          1037:               case 0x0a:     /* SCSI Bus Reset Stuck */
        !          1038:               case 0x0b:     /* Auto Request-Sense Failed */
        !          1039:               default:
        !          1040:                  status = DID_ERROR << 16;
        !          1041:                  break;
        !          1042:               }
        !          1043:    
        !          1044:            SCpnt->result = status | spp->target_status;
        !          1045:            HD(j)->iocount++;
        !          1046: 
        !          1047:            if (loops > 1) HD(j)->multicount++;
        !          1048: 
        !          1049: #if defined (DEBUG_INTERRUPT)
        !          1050:            if (SCpnt->result || do_trace)
        !          1051: #else
        !          1052:            if ((spp->adapter_status != ASOK && HD(j)->iocount >  1000) ||
        !          1053:                (spp->adapter_status != ASOK && 
        !          1054:                 spp->adapter_status != ASST && HD(j)->iocount <= 1000) ||
        !          1055:                do_trace)
        !          1056: #endif
        !          1057:               printk("%s: ihdlr, mbox %d, err 0x%x:%x,"\
        !          1058:                      " target %d:%d, pid %ld, count %d.\n",
        !          1059:                      BN(j), i, spp->adapter_status, spp->target_status,
        !          1060:                      SCpnt->target, SCpnt->lun, SCpnt->pid, HD(j)->iocount);
        !          1061:    
        !          1062:            /* Set the command state to inactive */
        !          1063:            SCpnt->host_scribble = NULL;
        !          1064:    
        !          1065:            restore_flags(flags);
        !          1066:            SCpnt->scsi_done(SCpnt);
        !          1067:            cli();
        !          1068: 
        !          1069:            }   /* Mailbox loop */
        !          1070: 
        !          1071:         }   /* Multiple command loop */
        !          1072: 
        !          1073:       }   /* Boards loop */
        !          1074: 
        !          1075:    calls[irq]++;
        !          1076: 
        !          1077:    if (total_loops == 0) 
        !          1078:      printk("%s: ihdlr, irq %d, no command completed, calls %d.\n",
        !          1079:            driver_name, irq, calls[irq]);
        !          1080: 
        !          1081:    if (do_trace) printk("%s: ihdlr, exit, irq %d, calls %d.\n", 
        !          1082:                        driver_name, irq, calls[irq]);
        !          1083: 
        !          1084: #if defined (DEBUG_STATISTICS)
        !          1085:    if ((calls[irq] % 100000) == 10000)
        !          1086:       for (j = 0; sh[j] != NULL; j++)
        !          1087:         printk("%s: ihdlr, calls %d, count %d, multi %d.\n", BN(j),
        !          1088:                calls[(sh[j]->irq)], HD(j)->iocount, HD(j)->multicount);
        !          1089: #endif
        !          1090: 
        !          1091:    restore_flags(flags);
        !          1092:    return;
        !          1093: }
        !          1094: 
        !          1095: #if defined(MODULE)
        !          1096: Scsi_Host_Template driver_template = EATA;
        !          1097: 
        !          1098: #include "scsi_module.c"
        !          1099: #endif

unix.superglobalmegacorp.com

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