Annotation of Gnu-Mach/linux/src/drivers/scsi/ultrastor.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     ultrastor.c     Copyright (C) 1992 David B. Gentzel
                      3:  *     Low-level SCSI driver for UltraStor 14F, 24F, and 34F
                      4:  *     by David B. Gentzel, Whitfield Software Services, Carnegie, PA
                      5:  *         ([email protected])
                      6:  *  scatter/gather added by Scott Taylor ([email protected])
                      7:  *  24F and multiple command support by John F. Carr ([email protected])
                      8:  *    John's work modified by Caleb Epstein ([email protected]) and 
                      9:  *    Eric Youngdale ([email protected]).
                     10:  *     Thanks to UltraStor for providing the necessary documentation
                     11:  */
                     12: 
                     13: /*
                     14:  * TODO:
                     15:  *     1. Find out why scatter/gather is limited to 16 requests per command.
                     16:  *         This is fixed, at least on the 24F, as of version 1.12 - CAE.
                     17:  *     2. Look at command linking (mscp.command_link and
                     18:  *        mscp.command_link_id).  (Does not work with many disks, 
                     19:  *                             and no performance increase.  ERY).
                     20:  *     3. Allow multiple adapters.
                     21:  */
                     22: 
                     23: /*
                     24:  * NOTES:
                     25:  *    The UltraStor 14F, 24F, and 34F are a family of intelligent, high
                     26:  *    performance SCSI-2 host adapters.  They all support command queueing
                     27:  *    and scatter/gather I/O.  Some of them can also emulate the standard
                     28:  *    WD1003 interface for use with OS's which don't support SCSI.  Here
                     29:  *    is the scoop on the various models:
                     30:  *     14F - ISA first-party DMA HA with floppy support and WD1003 emulation.
                     31:  *     14N - ISA HA with floppy support.  I think that this is a non-DMA
                     32:  *           HA.  Nothing further known.
                     33:  *     24F - EISA Bus Master HA with floppy support and WD1003 emulation.
                     34:  *     34F - VL-Bus Bus Master HA with floppy support (no WD1003 emulation).
                     35:  *
                     36:  *    The 14F, 24F, and 34F are supported by this driver.
                     37:  *
                     38:  *    Places flagged with a triple question-mark are things which are either
                     39:  *    unfinished, questionable, or wrong.
                     40:  */
                     41: 
                     42: /* Changes from version 1.11 alpha to 1.12
                     43:  *
                     44:  * Increased the size of the scatter-gather list to 33 entries for
                     45:  * the 24F adapter (it was 16).  I don't have the specs for the 14F
                     46:  * or the 34F, so they may support larger s-g lists as well.
                     47:  *
                     48:  * Caleb Epstein <[email protected]>
                     49:  */
                     50: 
                     51: /* Changes from version 1.9 to 1.11
                     52:  *
                     53:  * Patches to bring this driver up to speed with the default kernel
                     54:  * driver which supports only the 14F and 34F adapters.  This version
                     55:  * should compile cleanly into 0.99.13, 0.99.12 and probably 0.99.11.
                     56:  *
                     57:  * Fixes from Eric Youngdale to fix a few possible race conditions and
                     58:  * several problems with bit testing operations (insufficient
                     59:  * parentheses).
                     60:  *
                     61:  * Removed the ultrastor_abort() and ultrastor_reset() functions
                     62:  * (enclosed them in #if 0 / #endif).  These functions, at least on
                     63:  * the 24F, cause the SCSI bus to do odd things and generally lead to
                     64:  * kernel panics and machine hangs.  This is like the Adaptec code.
                     65:  *
                     66:  * Use check/snarf_region for 14f, 34f to avoid I/O space address conflicts.
                     67:  */
                     68: 
                     69: /* Changes from version 1.8 to version 1.9
                     70:  *
                     71:  *  0.99.11 patches ([email protected]) */
                     72: 
                     73: /* Changes from version 1.7 to version 1.8
                     74:  *
                     75:  * Better error reporting.
                     76:  */
                     77: 
                     78: /* Changes from version 1.6 to version 1.7
                     79:  *
                     80:  * Removed CSIR command code.
                     81:  *
                     82:  * Better race condition avoidance (xchgb function added).
                     83:  *
                     84:  * Set ICM and OGM status to zero at probe (24F)
                     85:  *
                     86:  * reset sends soft reset to UltraStor adapter
                     87:  *
                     88:  * reset adapter if adapter interrupts with an invalid MSCP address
                     89:  *
                     90:  * handle aborted command interrupt (24F)
                     91:  *
                     92:  */
                     93: 
                     94: /* Changes from version 1.5 to version 1.6:
                     95:  *
                     96:  * Read MSCP address from ICM _before_ clearing the interrupt flag.
                     97:  * This fixes a race condition.
                     98:  */
                     99: 
                    100: /* Changes from version 1.4 to version 1.5:
                    101:  *
                    102:  * Abort now calls done when multiple commands are enabled.
                    103:  *
                    104:  * Clear busy when aborted command finishes, not when abort is called.
                    105:  *
                    106:  * More debugging messages for aborts.
                    107:  */
                    108: 
                    109: /* Changes from version 1.3 to version 1.4:
                    110:  *
                    111:  * Enable automatic request of sense data on error (requires newer version
                    112:  * of scsi.c to be useful).
                    113:  *
                    114:  * Fix PORT_OVERRIDE for 14F.
                    115:  *
                    116:  * Fix abort and reset to work properly (config.aborted wasn't cleared
                    117:  * after it was tested, so after a command abort no further commands would
                    118:  * work).
                    119:  *
                    120:  * Boot time test to enable SCSI bus reset (defaults to not allowing reset).
                    121:  *
                    122:  * Fix test for OGM busy -- the busy bit is in different places on the 24F.
                    123:  *
                    124:  * Release ICM slot by clearing first byte on 24F.
                    125:  */
                    126: 
                    127: #ifdef MODULE
                    128: #include <linux/module.h>
                    129: #endif
                    130: 
                    131: #include <linux/stddef.h>
                    132: #include <linux/string.h>
                    133: #include <linux/sched.h>
                    134: #include <linux/kernel.h>
                    135: #include <linux/ioport.h>
                    136: #include <linux/proc_fs.h>
                    137: #include <asm/io.h>
                    138: #include <asm/bitops.h>
                    139: #include <asm/system.h>
                    140: #include <asm/dma.h>
                    141: 
                    142: #define ULTRASTOR_PRIVATE      /* Get the private stuff from ultrastor.h */
                    143: #include <linux/blk.h>
                    144: #include "scsi.h"
                    145: #include "hosts.h"
                    146: #include "ultrastor.h"
                    147: #include "sd.h"
                    148: #include<linux/stat.h>
                    149: 
                    150: struct proc_dir_entry proc_scsi_ultrastor = {
                    151:     PROC_SCSI_ULTRASTOR, 9, "ultrastor",
                    152:     S_IFDIR | S_IRUGO | S_IXUGO, 2
                    153: };
                    154: 
                    155: #define FALSE 0
                    156: #define TRUE 1
                    157: 
                    158: #ifndef ULTRASTOR_DEBUG
                    159: #define ULTRASTOR_DEBUG (UD_ABORT|UD_CSIR|UD_RESET)
                    160: #endif
                    161: 
                    162: #define VERSION "1.12"
                    163: 
                    164: #define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr)[0])
                    165: 
                    166: #define PACKED         __attribute__((packed))
                    167: #define ALIGNED(x)     __attribute__((aligned(x)))
                    168: 
                    169: 
                    170: /* The 14F uses an array of 4-byte ints for its scatter/gather list.
                    171:    The data can be unaligned, but need not be.  It's easier to give
                    172:    the list normal alignment since it doesn't need to fit into a
                    173:    packed structure.  */
                    174: 
                    175: typedef struct {
                    176:   unsigned int address;
                    177:   unsigned int num_bytes;
                    178: } ultrastor_sg_list;
                    179: 
                    180: 
                    181: /* MailBox SCSI Command Packet.  Basic command structure for communicating
                    182:    with controller. */
                    183: struct mscp {
                    184:   unsigned char opcode: 3;             /* type of command */
                    185:   unsigned char xdir: 2;               /* data transfer direction */
                    186:   unsigned char dcn: 1;                /* disable disconnect */
                    187:   unsigned char ca: 1;         /* use cache (if available) */
                    188:   unsigned char sg: 1;         /* scatter/gather operation */
                    189:   unsigned char target_id: 3;          /* target SCSI id */
                    190:   unsigned char ch_no: 2;              /* SCSI channel (always 0 for 14f) */
                    191:   unsigned char lun: 3;                /* logical unit number */
                    192:   unsigned int transfer_data PACKED;   /* transfer data pointer */
                    193:   unsigned int transfer_data_length PACKED;    /* length in bytes */
                    194:   unsigned int command_link PACKED;    /* for linking command chains */
                    195:   unsigned char scsi_command_link_id;  /* identifies command in chain */
                    196:   unsigned char number_of_sg_list;     /* (if sg is set) 8 bytes per list */
                    197:   unsigned char length_of_sense_byte;
                    198:   unsigned char length_of_scsi_cdbs;   /* 6, 10, or 12 */
                    199:   unsigned char scsi_cdbs[12]; /* SCSI commands */
                    200:   unsigned char adapter_status;        /* non-zero indicates HA error */
                    201:   unsigned char target_status; /* non-zero indicates target error */
                    202:   unsigned int sense_data PACKED;
                    203:   /* The following fields are for software only.  They are included in
                    204:      the MSCP structure because they are associated with SCSI requests.  */
                    205:   void (*done)(Scsi_Cmnd *);
                    206:   Scsi_Cmnd *SCint;
                    207:   ultrastor_sg_list sglist[ULTRASTOR_24F_MAX_SG]; /* use larger size for 24F */
                    208: };
                    209: 
                    210: 
                    211: /* Port addresses (relative to the base address) */
                    212: #define U14F_PRODUCT_ID(port) ((port) + 0x4)
                    213: #define CONFIG(port) ((port) + 0x6)
                    214: 
                    215: /* Port addresses relative to the doorbell base address.  */
                    216: #define LCL_DOORBELL_MASK(port) ((port) + 0x0)
                    217: #define LCL_DOORBELL_INTR(port) ((port) + 0x1)
                    218: #define SYS_DOORBELL_MASK(port) ((port) + 0x2)
                    219: #define SYS_DOORBELL_INTR(port) ((port) + 0x3)
                    220: 
                    221: 
                    222: /* Used to store configuration info read from config i/o registers.  Most of
                    223:    this is not used yet, but might as well save it.
                    224:    
                    225:    This structure also holds port addresses that are not at the same offset
                    226:    on the 14F and 24F.
                    227:    
                    228:    This structure holds all data that must be duplicated to support multiple
                    229:    adapters.  */
                    230: 
                    231: static struct ultrastor_config
                    232: {
                    233:   unsigned short port_address;         /* base address of card */
                    234:   unsigned short doorbell_address;     /* base address of doorbell CSRs */
                    235:   unsigned short ogm_address;          /* base address of OGM */
                    236:   unsigned short icm_address;          /* base address of ICM */
                    237:   const void *bios_segment;
                    238:   unsigned char interrupt: 4;
                    239:   unsigned char dma_channel: 3;
                    240:   unsigned char bios_drive_number: 1;
                    241:   unsigned char heads;
                    242:   unsigned char sectors;
                    243:   unsigned char ha_scsi_id: 3;
                    244:   unsigned char subversion: 4;
                    245:   unsigned char revision;
                    246:   /* The slot number is used to distinguish the 24F (slot != 0) from
                    247:      the 14F and 34F (slot == 0). */
                    248:   unsigned char slot;
                    249: 
                    250: #ifdef PRINT_U24F_VERSION
                    251:   volatile int csir_done;
                    252: #endif
                    253: 
                    254:   /* A pool of MSCP structures for this adapter, and a bitmask of
                    255:      busy structures.  (If ULTRASTOR_14F_MAX_CMDS == 1, a 1 byte
                    256:      busy flag is used instead.)  */
                    257: 
                    258: #if ULTRASTOR_MAX_CMDS == 1
                    259:   unsigned char mscp_busy;
                    260: #else
                    261:   unsigned short mscp_free;
                    262: #endif
                    263:   volatile unsigned char aborted[ULTRASTOR_MAX_CMDS];
                    264:   struct mscp mscp[ULTRASTOR_MAX_CMDS];
                    265: } config = {0};
                    266: 
                    267: /* Set this to 1 to reset the SCSI bus on error.  */
                    268: int ultrastor_bus_reset = 0;
                    269: 
                    270: 
                    271: /* Allowed BIOS base addresses (NULL indicates reserved) */
                    272: static const void *const bios_segment_table[8] = {
                    273:   NULL,             (void *)0xC4000, (void *)0xC8000, (void *)0xCC000,
                    274:   (void *)0xD0000, (void *)0xD4000, (void *)0xD8000, (void *)0xDC000,
                    275: };
                    276: 
                    277: /* Allowed IRQs for 14f */
                    278: static const unsigned char interrupt_table_14f[4] = { 15, 14, 11, 10 };
                    279: 
                    280: /* Allowed DMA channels for 14f (0 indicates reserved) */
                    281: static const unsigned char dma_channel_table_14f[4] = { 5, 6, 7, 0 };
                    282: 
                    283: /* Head/sector mappings allowed by 14f */
                    284: static const struct {
                    285:   unsigned char heads;
                    286:   unsigned char sectors;
                    287: } mapping_table[4] = { { 16, 63 }, { 64, 32 }, { 64, 63 }, { 64, 32 } };
                    288: 
                    289: #ifndef PORT_OVERRIDE
                    290: /* ??? A probe of address 0x310 screws up NE2000 cards */
                    291: static const unsigned short ultrastor_ports_14f[] = {
                    292:   0x330, 0x340, /*0x310,*/ 0x230, 0x240, 0x210, 0x130, 0x140,
                    293: };
                    294: #endif
                    295: 
                    296: static void ultrastor_interrupt(int, void *, struct pt_regs *);
                    297: static inline void build_sg_list(struct mscp *, Scsi_Cmnd *SCpnt);
                    298: 
                    299: 
                    300: static inline int find_and_clear_bit_16(unsigned short *field)
                    301: {
                    302:   int rv;
                    303:   unsigned long flags;
                    304: 
                    305:   save_flags(flags);
                    306:   cli();
                    307:   if (*field == 0) panic("No free mscp");
                    308:   asm("xorl %0,%0\n0:\tbsfw %1,%w0\n\tbtr %0,%1\n\tjnc 0b"
                    309:       : "=&r" (rv), "=m" (*field) : "1" (*field));
                    310:   restore_flags(flags);
                    311:   return rv;
                    312: }
                    313: 
                    314: /* This has been re-implemented with the help of Richard Earnshaw,
                    315:    <[email protected]> and works with gcc-2.5.8 and gcc-2.6.0.
                    316:    The instability noted by jfc below appears to be a bug in
                    317:    gcc-2.5.x when compiling w/o optimization.  --Caleb
                    318: 
                    319:    This asm is fragile: it doesn't work without the casts and it may
                    320:    not work without optimization.  Maybe I should add a swap builtin
                    321:    to gcc.  --jfc  */
                    322: static inline unsigned char xchgb(unsigned char reg,
                    323:                                  volatile unsigned char *mem)
                    324: {
                    325:   __asm__ ("xchgb %0,%1" : "=q" (reg), "=m" (*mem) : "0" (reg));
                    326:   return reg;
                    327: }
                    328: 
                    329: #if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
                    330: 
                    331: static void log_ultrastor_abort(register struct ultrastor_config *config,
                    332:                                int command)
                    333: {
                    334:   static char fmt[80] = "abort %d (%x); MSCP free pool: %x;";
                    335:   register int i;
                    336:   int flags;
                    337:   save_flags(flags);
                    338:   cli();
                    339: 
                    340:   for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
                    341:     {
                    342:       fmt[20 + i*2] = ' ';
                    343:       if (! (config->mscp_free & (1 << i)))
                    344:        fmt[21 + i*2] = '0' + config->mscp[i].target_id;
                    345:       else
                    346:        fmt[21 + i*2] = '-';
                    347:     }
                    348:   fmt[20 + ULTRASTOR_MAX_CMDS * 2] = '\n';
                    349:   fmt[21 + ULTRASTOR_MAX_CMDS * 2] = 0;
                    350:   printk(fmt, command, &config->mscp[command], config->mscp_free);
                    351:   restore_flags(flags);
                    352: }
                    353: #endif
                    354: 
                    355: static int ultrastor_14f_detect(Scsi_Host_Template * tpnt)
                    356: {
                    357:     size_t i;
                    358:     unsigned char in_byte, version_byte = 0;
                    359:     struct config_1 {
                    360:       unsigned char bios_segment: 3;
                    361:       unsigned char removable_disks_as_fixed: 1;
                    362:       unsigned char interrupt: 2;
                    363:     unsigned char dma_channel: 2;
                    364:     } config_1;
                    365:     struct config_2 {
                    366:       unsigned char ha_scsi_id: 3;
                    367:       unsigned char mapping_mode: 2;
                    368:       unsigned char bios_drive_number: 1;
                    369:       unsigned char tfr_port: 2;
                    370:     } config_2;
                    371: 
                    372: #if (ULTRASTOR_DEBUG & UD_DETECT)
                    373:     printk("US14F: detect: called\n");
                    374: #endif
                    375: 
                    376:     /* If a 24F has already been configured, don't look for a 14F.  */
                    377:     if (config.bios_segment)
                    378:        return FALSE;
                    379: 
                    380: #ifdef PORT_OVERRIDE
                    381:     if(check_region(PORT_OVERRIDE, 0xc)) {
                    382:       printk("Ultrastor I/O space already in use\n");
                    383:       return FALSE;
                    384:     };
                    385:     config.port_address = PORT_OVERRIDE;
                    386: #else
                    387:     for (i = 0; i < ARRAY_SIZE(ultrastor_ports_14f); i++) {
                    388:       if(check_region(ultrastor_ports_14f[i], 0x0c)) continue;
                    389:       config.port_address = ultrastor_ports_14f[i];
                    390: #endif
                    391: 
                    392: #if (ULTRASTOR_DEBUG & UD_DETECT)
                    393:        printk("US14F: detect: testing port address %03X\n", config.port_address);
                    394: #endif
                    395: 
                    396:        in_byte = inb(U14F_PRODUCT_ID(config.port_address));
                    397:        if (in_byte != US14F_PRODUCT_ID_0) {
                    398: #if (ULTRASTOR_DEBUG & UD_DETECT)
                    399: # ifdef PORT_OVERRIDE
                    400:            printk("US14F: detect: wrong product ID 0 - %02X\n", in_byte);
                    401: # else
                    402:            printk("US14F: detect: no adapter at port %03X\n", config.port_address);
                    403: # endif
                    404: #endif
                    405: #ifdef PORT_OVERRIDE
                    406:            return FALSE;
                    407: #else
                    408:            continue;
                    409: #endif
                    410:        }
                    411:        in_byte = inb(U14F_PRODUCT_ID(config.port_address) + 1);
                    412:        /* Only upper nibble is significant for Product ID 1 */
                    413:        if ((in_byte & 0xF0) != US14F_PRODUCT_ID_1) {
                    414: #if (ULTRASTOR_DEBUG & UD_DETECT)
                    415: # ifdef PORT_OVERRIDE
                    416:            printk("US14F: detect: wrong product ID 1 - %02X\n", in_byte);
                    417: # else
                    418:            printk("US14F: detect: no adapter at port %03X\n", config.port_address);
                    419: # endif
                    420: #endif
                    421: #ifdef PORT_OVERRIDE
                    422:            return FALSE;
                    423: #else
                    424:            continue;
                    425: #endif
                    426:        }
                    427:        version_byte = in_byte;
                    428: #ifndef PORT_OVERRIDE
                    429:        break;
                    430:     }
                    431:     if (i == ARRAY_SIZE(ultrastor_ports_14f)) {
                    432: # if (ULTRASTOR_DEBUG & UD_DETECT)
                    433:        printk("US14F: detect: no port address found!\n");
                    434: # endif
                    435:        return FALSE;
                    436:     }
                    437: #endif
                    438: 
                    439: #if (ULTRASTOR_DEBUG & UD_DETECT)
                    440:     printk("US14F: detect: adapter found at port address %03X\n",
                    441:           config.port_address);
                    442: #endif
                    443: 
                    444:     /* Set local doorbell mask to disallow bus reset unless
                    445:        ultrastor_bus_reset is true.  */
                    446:     outb(ultrastor_bus_reset ? 0xc2 : 0x82, LCL_DOORBELL_MASK(config.port_address));
                    447: 
                    448:     /* All above tests passed, must be the right thing.  Get some useful
                    449:        info. */
                    450: 
                    451:     request_region(config.port_address, 0x0c,"ultrastor"); 
                    452:     /* Register the I/O space that we use */
                    453: 
                    454:     *(char *)&config_1 = inb(CONFIG(config.port_address + 0));
                    455:     *(char *)&config_2 = inb(CONFIG(config.port_address + 1));
                    456:     config.bios_segment = bios_segment_table[config_1.bios_segment];
                    457:     config.doorbell_address = config.port_address;
                    458:     config.ogm_address = config.port_address + 0x8;
                    459:     config.icm_address = config.port_address + 0xC;
                    460:     config.interrupt = interrupt_table_14f[config_1.interrupt];
                    461:     config.ha_scsi_id = config_2.ha_scsi_id;
                    462:     config.heads = mapping_table[config_2.mapping_mode].heads;
                    463:     config.sectors = mapping_table[config_2.mapping_mode].sectors;
                    464:     config.bios_drive_number = config_2.bios_drive_number;
                    465:     config.subversion = (version_byte & 0x0F);
                    466:     if (config.subversion == U34F)
                    467:        config.dma_channel = 0;
                    468:     else
                    469:        config.dma_channel = dma_channel_table_14f[config_1.dma_channel];
                    470: 
                    471:     if (!config.bios_segment) {
                    472: #if (ULTRASTOR_DEBUG & UD_DETECT)
                    473:        printk("US14F: detect: not detected.\n");
                    474: #endif
                    475:        return FALSE;
                    476:     }
                    477: 
                    478:     /* Final consistency check, verify previous info. */
                    479:     if (config.subversion != U34F)
                    480:        if (!config.dma_channel || !(config_2.tfr_port & 0x2)) {
                    481: #if (ULTRASTOR_DEBUG & UD_DETECT)
                    482:            printk("US14F: detect: consistency check failed\n");
                    483: #endif
                    484:            return FALSE;
                    485:        }
                    486: 
                    487:     /* If we were TRULY paranoid, we could issue a host adapter inquiry
                    488:        command here and verify the data returned.  But frankly, I'm
                    489:        exhausted! */
                    490: 
                    491:     /* Finally!  Now I'm satisfied... */
                    492: #if (ULTRASTOR_DEBUG & UD_DETECT)
                    493:     printk("US14F: detect: detect succeeded\n"
                    494:           "  Port address: %03X\n"
                    495:           "  BIOS segment: %05X\n"
                    496:           "  Interrupt: %u\n"
                    497:           "  DMA channel: %u\n"
                    498:           "  H/A SCSI ID: %u\n"
                    499:           "  Subversion: %u\n",
                    500:           config.port_address, config.bios_segment, config.interrupt,
                    501:           config.dma_channel, config.ha_scsi_id, config.subversion);
                    502: #endif
                    503:     tpnt->this_id = config.ha_scsi_id;
                    504:     tpnt->unchecked_isa_dma = (config.subversion != U34F);
                    505: 
                    506: #if ULTRASTOR_MAX_CMDS > 1
                    507:     config.mscp_free = ~0;
                    508: #endif
                    509: 
                    510:     if (request_irq(config.interrupt, ultrastor_interrupt, 0, "Ultrastor", NULL)) {
                    511:        printk("Unable to allocate IRQ%u for UltraStor controller.\n",
                    512:               config.interrupt);
                    513:        return FALSE;
                    514:     }
                    515:     if (config.dma_channel && request_dma(config.dma_channel,"Ultrastor")) {
                    516:        printk("Unable to allocate DMA channel %u for UltraStor controller.\n",
                    517:               config.dma_channel);
                    518:        free_irq(config.interrupt, NULL);
                    519:        return FALSE;
                    520:     }
                    521:     tpnt->sg_tablesize = ULTRASTOR_14F_MAX_SG;
                    522:     printk("UltraStor driver version" VERSION ".  Using %d SG lists.\n",
                    523:           ULTRASTOR_14F_MAX_SG);
                    524: 
                    525:     return TRUE;
                    526: }
                    527: 
                    528: static int ultrastor_24f_detect(Scsi_Host_Template * tpnt)
                    529: {
                    530:   register int i;
                    531:   struct Scsi_Host * shpnt = NULL;
                    532: 
                    533: #if (ULTRASTOR_DEBUG & UD_DETECT)
                    534:   printk("US24F: detect");
                    535: #endif
                    536: 
                    537:   /* probe each EISA slot at slot address C80 */
                    538:   for (i = 1; i < 15; i++)
                    539:     {
                    540:       unsigned char config_1, config_2;
                    541:       unsigned short addr = (i << 12) | ULTRASTOR_24F_PORT;
                    542: 
                    543:       if (inb(addr) != US24F_PRODUCT_ID_0 &&
                    544:          inb(addr+1) != US24F_PRODUCT_ID_1 &&
                    545:          inb(addr+2) != US24F_PRODUCT_ID_2)
                    546:        continue;
                    547: 
                    548:       config.revision = inb(addr+3);
                    549:       config.slot = i;
                    550:       if (! (inb(addr+4) & 1))
                    551:        {
                    552: #if (ULTRASTOR_DEBUG & UD_DETECT)
                    553:          printk("U24F: found disabled card in slot %u\n", i);
                    554: #endif
                    555:          continue;
                    556:        }
                    557: #if (ULTRASTOR_DEBUG & UD_DETECT)
                    558:       printk("U24F: found card in slot %u\n", i);
                    559: #endif
                    560:       config_1 = inb(addr + 5);
                    561:       config.bios_segment = bios_segment_table[config_1 & 7];
                    562:       switch(config_1 >> 4)
                    563:        {
                    564:        case 1:
                    565:          config.interrupt = 15;
                    566:          break;
                    567:        case 2:
                    568:          config.interrupt = 14;
                    569:          break;
                    570:        case 4:
                    571:          config.interrupt = 11;
                    572:          break;
                    573:        case 8:
                    574:          config.interrupt = 10;
                    575:          break;
                    576:        default:
                    577:          printk("U24F: invalid IRQ\n");
                    578:          return FALSE;
                    579:        }
                    580:       if (request_irq(config.interrupt, ultrastor_interrupt, 0, "Ultrastor", NULL))
                    581:        {
                    582:          printk("Unable to allocate IRQ%u for UltraStor controller.\n",
                    583:                 config.interrupt);
                    584:          return FALSE;
                    585:        }
                    586:       /* BIOS addr set */
                    587:       /* base port set */
                    588:       config.port_address = addr;
                    589:       config.doorbell_address = addr + 12;
                    590:       config.ogm_address = addr + 0x17;
                    591:       config.icm_address = addr + 0x1C;
                    592:       config_2 = inb(addr + 7);
                    593:       config.ha_scsi_id = config_2 & 7;
                    594:       config.heads = mapping_table[(config_2 >> 3) & 3].heads;
                    595:       config.sectors = mapping_table[(config_2 >> 3) & 3].sectors;
                    596: #if (ULTRASTOR_DEBUG & UD_DETECT)
                    597:       printk("US24F: detect: detect succeeded\n"
                    598:             "  Port address: %03X\n"
                    599:             "  BIOS segment: %05X\n"
                    600:             "  Interrupt: %u\n"
                    601:             "  H/A SCSI ID: %u\n",
                    602:             config.port_address, config.bios_segment,
                    603:             config.interrupt, config.ha_scsi_id);
                    604: #endif
                    605:       tpnt->this_id = config.ha_scsi_id;
                    606:       tpnt->unchecked_isa_dma = 0;
                    607:       tpnt->sg_tablesize = ULTRASTOR_24F_MAX_SG;
                    608: 
                    609:       shpnt = scsi_register(tpnt, 0);
                    610:       shpnt->irq = config.interrupt;
                    611:       shpnt->dma_channel = config.dma_channel;
                    612:       shpnt->io_port = config.port_address;
                    613: 
                    614: #if ULTRASTOR_MAX_CMDS > 1
                    615:       config.mscp_free = ~0;
                    616: #endif
                    617:       /* Mark ICM and OGM free */
                    618:       outb(0, addr + 0x16);
                    619:       outb(0, addr + 0x1B);
                    620: 
                    621:       /* Set local doorbell mask to disallow bus reset unless
                    622:         ultrastor_bus_reset is true.  */
                    623:       outb(ultrastor_bus_reset ? 0xc2 : 0x82, LCL_DOORBELL_MASK(addr+12));
                    624:       outb(0x02, SYS_DOORBELL_MASK(addr+12));
                    625:       printk("UltraStor driver version " VERSION ".  Using %d SG lists.\n",
                    626:             tpnt->sg_tablesize);
                    627:       return TRUE;
                    628:     }
                    629:   return FALSE;
                    630: }
                    631: 
                    632: int ultrastor_detect(Scsi_Host_Template * tpnt)
                    633: {
                    634:     tpnt->proc_dir = &proc_scsi_ultrastor;
                    635:   return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt);
                    636: }
                    637: 
                    638: const char *ultrastor_info(struct Scsi_Host * shpnt)
                    639: {
                    640:     static char buf[64];
                    641: 
                    642:     if (config.slot)
                    643:       sprintf(buf, "UltraStor 24F SCSI @ Slot %u IRQ%u",
                    644:              config.slot, config.interrupt);
                    645:     else if (config.subversion)
                    646:       sprintf(buf, "UltraStor 34F SCSI @ Port %03X BIOS %05X IRQ%u",
                    647:              config.port_address, (int)config.bios_segment,
                    648:              config.interrupt);
                    649:     else
                    650:       sprintf(buf, "UltraStor 14F SCSI @ Port %03X BIOS %05X IRQ%u DMA%u",
                    651:              config.port_address, (int)config.bios_segment,
                    652:              config.interrupt, config.dma_channel);
                    653:     return buf;
                    654: }
                    655: 
                    656: static inline void build_sg_list(register struct mscp *mscp, Scsi_Cmnd *SCpnt)
                    657: {
                    658:        struct scatterlist *sl;
                    659:        long transfer_length = 0;
                    660:        int i, max;
                    661: 
                    662:        sl = (struct scatterlist *) SCpnt->request_buffer;
                    663:        max = SCpnt->use_sg;
                    664:        for (i = 0; i < max; i++) {
                    665:                mscp->sglist[i].address = (unsigned int)sl[i].address;
                    666:                mscp->sglist[i].num_bytes = sl[i].length;
                    667:                transfer_length += sl[i].length;
                    668:        }
                    669:        mscp->number_of_sg_list = max;
                    670:        mscp->transfer_data = (unsigned int)mscp->sglist;
                    671:        /* ??? May not be necessary.  Docs are unclear as to whether transfer
                    672:           length field is ignored or whether it should be set to the total
                    673:           number of bytes of the transfer.  */
                    674:        mscp->transfer_data_length = transfer_length;
                    675: }
                    676: 
                    677: int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
                    678: {
                    679:     register struct mscp *my_mscp;
                    680: #if ULTRASTOR_MAX_CMDS > 1
                    681:     int mscp_index;
                    682: #endif
                    683:     unsigned int status;
                    684:     int flags;
                    685: 
                    686:     /* Next test is for debugging; "can't happen" */
                    687:     if ((config.mscp_free & ((1U << ULTRASTOR_MAX_CMDS) - 1)) == 0)
                    688:        panic("ultrastor_queuecommand: no free MSCP\n");
                    689:     mscp_index = find_and_clear_bit_16(&config.mscp_free);
                    690: 
                    691:     /* Has the command been aborted?  */
                    692:     if (xchgb(0xff, &config.aborted[mscp_index]) != 0)
                    693:       {
                    694:        status = DID_ABORT << 16;
                    695:        goto aborted;
                    696:       }
                    697: 
                    698:     my_mscp = &config.mscp[mscp_index];
                    699: 
                    700: #if 1
                    701:     /* This way is faster.  */
                    702:     *(unsigned char *)my_mscp = OP_SCSI | (DTD_SCSI << 3);
                    703: #else
                    704:     my_mscp->opcode = OP_SCSI;
                    705:     my_mscp->xdir = DTD_SCSI;
                    706:     my_mscp->dcn = FALSE;
                    707: #endif
                    708:     /* Tape drives don't work properly if the cache is used.  The SCSI
                    709:        READ command for a tape doesn't have a block offset, and the adapter
                    710:        incorrectly assumes that all reads from the tape read the same
                    711:        blocks.  Results will depend on read buffer size and other disk
                    712:        activity. 
                    713: 
                    714:        ???  Which other device types should never use the cache?   */
                    715:     my_mscp->ca = SCpnt->device->type != TYPE_TAPE;
                    716:     my_mscp->target_id = SCpnt->target;
                    717:     my_mscp->ch_no = 0;
                    718:     my_mscp->lun = SCpnt->lun;
                    719:     if (SCpnt->use_sg) {
                    720:        /* Set scatter/gather flag in SCSI command packet */
                    721:        my_mscp->sg = TRUE;
                    722:        build_sg_list(my_mscp, SCpnt);
                    723:     } else {
                    724:        /* Unset scatter/gather flag in SCSI command packet */
                    725:        my_mscp->sg = FALSE;
                    726:        my_mscp->transfer_data = (unsigned int)SCpnt->request_buffer;
                    727:        my_mscp->transfer_data_length = SCpnt->request_bufflen;
                    728:     }
                    729:     my_mscp->command_link = 0;         /*???*/
                    730:     my_mscp->scsi_command_link_id = 0; /*???*/
                    731:     my_mscp->length_of_sense_byte = sizeof SCpnt->sense_buffer;
                    732:     my_mscp->length_of_scsi_cdbs = SCpnt->cmd_len;
                    733:     memcpy(my_mscp->scsi_cdbs, SCpnt->cmnd, my_mscp->length_of_scsi_cdbs);
                    734:     my_mscp->adapter_status = 0;
                    735:     my_mscp->target_status = 0;
                    736:     my_mscp->sense_data = (unsigned int)&SCpnt->sense_buffer;
                    737:     my_mscp->done = done;
                    738:     my_mscp->SCint = SCpnt;
                    739:     SCpnt->host_scribble = (unsigned char *)my_mscp;
                    740: 
                    741:     /* Find free OGM slot.  On 24F, look for OGM status byte == 0.
                    742:        On 14F and 34F, wait for local interrupt pending flag to clear.  */
                    743: 
                    744:   retry:
                    745:     if (config.slot)
                    746:        while (inb(config.ogm_address - 1) != 0 &&
                    747:               config.aborted[mscp_index] == 0xff) barrier();
                    748: 
                    749:     /* else??? */
                    750: 
                    751:     while ((inb(LCL_DOORBELL_INTR(config.doorbell_address)) & 
                    752:            (config.slot ? 2 : 1)) 
                    753:           && config.aborted[mscp_index] == 0xff) barrier();
                    754: 
                    755:     /* To avoid race conditions, make the code to write to the adapter
                    756:        atomic.  This simplifies the abort code.  */
                    757: 
                    758:     save_flags(flags);
                    759:     cli();
                    760: 
                    761:     if (inb(LCL_DOORBELL_INTR(config.doorbell_address)) &
                    762:        (config.slot ? 2 : 1))
                    763:       {
                    764:       restore_flags(flags);
                    765:       goto retry;
                    766:       }
                    767: 
                    768:     status = xchgb(0, &config.aborted[mscp_index]);
                    769:     if (status != 0xff) {
                    770:        restore_flags(flags);
                    771: 
                    772: #if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
                    773:        printk("USx4F: queuecommand: aborted\n");
                    774: #if ULTRASTOR_MAX_CMDS > 1
                    775:        log_ultrastor_abort(&config, mscp_index);
                    776: #endif
                    777: #endif
                    778:        status <<= 16;
                    779: 
                    780:       aborted:
                    781:        set_bit(mscp_index, &config.mscp_free);
                    782:        /* If the driver queues commands, call the done proc here.  Otherwise
                    783:           return an error.  */
                    784: #if ULTRASTOR_MAX_CMDS > 1
                    785:        SCpnt->result = status;
                    786:        done(SCpnt);
                    787:        return 0;
                    788: #else
                    789:        return status;
                    790: #endif
                    791:     }
                    792: 
                    793:     /* Store pointer in OGM address bytes */
                    794:     outl((unsigned int)my_mscp, config.ogm_address);
                    795: 
                    796:     /* Issue OGM interrupt */
                    797:     if (config.slot) {
                    798:        /* Write OGM command register on 24F */
                    799:        outb(1, config.ogm_address - 1);
                    800:        outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
                    801:     } else {
                    802:        outb(0x1, LCL_DOORBELL_INTR(config.doorbell_address));
                    803:     }
                    804: 
                    805:     restore_flags(flags);
                    806: 
                    807: #if (ULTRASTOR_DEBUG & UD_COMMAND)
                    808:     printk("USx4F: queuecommand: returning\n");
                    809: #endif
                    810: 
                    811:     return 0;
                    812: }
                    813: 
                    814: /* This code must deal with 2 cases:
                    815: 
                    816:    1. The command has not been written to the OGM.  In this case, set
                    817:    the abort flag and return.
                    818: 
                    819:    2. The command has been written to the OGM and is stuck somewhere in
                    820:    the adapter.
                    821: 
                    822:    2a.  On a 24F, ask the adapter to abort the command.  It will interrupt
                    823:    when it does.
                    824: 
                    825:    2b.  Call the command's done procedure.
                    826: 
                    827:  */
                    828: 
                    829: int ultrastor_abort(Scsi_Cmnd *SCpnt)
                    830: {
                    831: #if ULTRASTOR_DEBUG & UD_ABORT
                    832:     char out[108];
                    833:     unsigned char icm_status = 0, ogm_status = 0;
                    834:     unsigned int icm_addr = 0, ogm_addr = 0;
                    835: #endif
                    836:     unsigned int mscp_index;
                    837:     unsigned char old_aborted;
                    838:     void (*done)(Scsi_Cmnd *);
                    839: 
                    840:     if(config.slot) 
                    841:       return SCSI_ABORT_SNOOZE;  /* Do not attempt an abort for the 24f */
                    842: 
                    843:     /* Simple consistency checking */
                    844:     if(!SCpnt->host_scribble)
                    845:       return SCSI_ABORT_NOT_RUNNING;
                    846: 
                    847:     mscp_index = ((struct mscp *)SCpnt->host_scribble) - config.mscp;
                    848:     if (mscp_index >= ULTRASTOR_MAX_CMDS)
                    849:        panic("Ux4F aborting invalid MSCP");
                    850: 
                    851: #if ULTRASTOR_DEBUG & UD_ABORT
                    852:     if (config.slot)
                    853:       {
                    854:        int port0 = (config.slot << 12) | 0xc80;
                    855:        int i;
                    856:        int flags;
                    857:        save_flags(flags);
                    858:        cli();
                    859:        strcpy(out, "OGM %d:%x ICM %d:%x ports:  ");
                    860:        for (i = 0; i < 16; i++)
                    861:          {
                    862:            unsigned char p = inb(port0 + i);
                    863:            out[28 + i * 3] = "0123456789abcdef"[p >> 4];
                    864:            out[29 + i * 3] = "0123456789abcdef"[p & 15];
                    865:            out[30 + i * 3] = ' ';
                    866:          }
                    867:        out[28 + i * 3] = '\n';
                    868:        out[29 + i * 3] = 0;
                    869:        ogm_status = inb(port0 + 22);
                    870:        ogm_addr = inl(port0 + 23);
                    871:        icm_status = inb(port0 + 27);
                    872:        icm_addr = inl(port0 + 28);
                    873:        restore_flags(flags);
                    874:       }
                    875: 
                    876:     /* First check to see if an interrupt is pending.  I suspect the SiS
                    877:        chipset loses interrupts.  (I also suspect is mangles data, but
                    878:        one bug at a time... */
                    879:     if (config.slot ? inb(config.icm_address - 1) == 2 :
                    880:        (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
                    881:       {
                    882:        int flags;
                    883:        save_flags(flags);
                    884:        printk("Ux4F: abort while completed command pending\n");
                    885:        restore_flags(flags);
                    886:        cli();
                    887:        ultrastor_interrupt(0, NULL, NULL);
                    888:        restore_flags(flags);
                    889:        return SCSI_ABORT_SUCCESS;  /* FIXME - is this correct? -ERY */
                    890:       }
                    891: #endif
                    892: 
                    893:     old_aborted = xchgb(DID_ABORT, &config.aborted[mscp_index]);
                    894: 
                    895:     /* aborted == 0xff is the signal that queuecommand has not yet sent
                    896:        the command.  It will notice the new abort flag and fail.  */
                    897:     if (old_aborted == 0xff)
                    898:        return SCSI_ABORT_SUCCESS;
                    899: 
                    900:     /* On 24F, send an abort MSCP request.  The adapter will interrupt
                    901:        and the interrupt handler will call done.  */
                    902:     if (config.slot && inb(config.ogm_address - 1) == 0)
                    903:       {
                    904:        int flags;
                    905: 
                    906:        save_flags(flags);
                    907:        cli();
                    908:        outl((int)&config.mscp[mscp_index], config.ogm_address);
                    909:        inb(0xc80);     /* delay */
                    910:        outb(0x80, config.ogm_address - 1);
                    911:        outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
                    912: #if ULTRASTOR_DEBUG & UD_ABORT
                    913:        log_ultrastor_abort(&config, mscp_index);
                    914:        printk(out, ogm_status, ogm_addr, icm_status, icm_addr);
                    915: #endif
                    916:        restore_flags(flags);
                    917:        return SCSI_ABORT_PENDING;
                    918:       }
                    919: 
                    920: #if ULTRASTOR_DEBUG & UD_ABORT
                    921:     log_ultrastor_abort(&config, mscp_index);
                    922: #endif
                    923: 
                    924:     /* Can't request a graceful abort.  Either this is not a 24F or
                    925:        the OGM is busy.  Don't free the command -- the adapter might
                    926:        still be using it.  Setting SCint = 0 causes the interrupt
                    927:        handler to ignore the command.  */
                    928: 
                    929:     /* FIXME - devices that implement soft resets will still be running
                    930:        the command after a bus reset.  We would probably rather leave
                    931:        the command in the queue.  The upper level code will automatically
                    932:        leave the command in the active state instead of requeueing it. ERY */
                    933: 
                    934: #if ULTRASTOR_DEBUG & UD_ABORT
                    935:     if (config.mscp[mscp_index].SCint != SCpnt)
                    936:        printk("abort: command mismatch, %p != %p\n",
                    937:               config.mscp[mscp_index].SCint, SCpnt);
                    938: #endif
                    939:     if (config.mscp[mscp_index].SCint == 0)
                    940:        return SCSI_ABORT_NOT_RUNNING;
                    941: 
                    942:     if (config.mscp[mscp_index].SCint != SCpnt) panic("Bad abort");
                    943:     config.mscp[mscp_index].SCint = 0;
                    944:     done = config.mscp[mscp_index].done;
                    945:     config.mscp[mscp_index].done = 0;
                    946:     SCpnt->result = DID_ABORT << 16;
                    947:     /* I worry about reentrancy in scsi.c  */
                    948:     done(SCpnt);
                    949: 
                    950:     /* Need to set a timeout here in case command never completes.  */
                    951:     return SCSI_ABORT_SUCCESS;
                    952: }
                    953: 
                    954: int ultrastor_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
                    955: {
                    956:     int flags;
                    957:     register int i;
                    958: #if (ULTRASTOR_DEBUG & UD_RESET)
                    959:     printk("US14F: reset: called\n");
                    960: #endif
                    961: 
                    962:     if(config.slot)
                    963:       return SCSI_RESET_PUNT;  /* Do not attempt a reset for the 24f */
                    964: 
                    965:     save_flags(flags);
                    966:     cli();
                    967: 
                    968:     /* Reset the adapter and SCSI bus.  The SCSI bus reset can be
                    969:        inhibited by clearing ultrastor_bus_reset before probe.  */
                    970:     outb(0xc0, LCL_DOORBELL_INTR(config.doorbell_address));
                    971:     if (config.slot)
                    972:       {
                    973:        outb(0, config.ogm_address - 1);
                    974:        outb(0, config.icm_address - 1);
                    975:       }
                    976: 
                    977: #if ULTRASTOR_MAX_CMDS == 1
                    978:     if (config.mscp_busy && config.mscp->done && config.mscp->SCint)
                    979:       {
                    980:        config.mscp->SCint->result = DID_RESET << 16;
                    981:        config.mscp->done(config.mscp->SCint);
                    982:       }
                    983:     config.mscp->SCint = 0;
                    984: #else
                    985:     for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
                    986:       {
                    987:        if (! (config.mscp_free & (1 << i)) &&
                    988:            config.mscp[i].done && config.mscp[i].SCint)
                    989:          {
                    990:            config.mscp[i].SCint->result = DID_RESET << 16;
                    991:            config.mscp[i].done(config.mscp[i].SCint);
                    992:            config.mscp[i].done = 0;
                    993:          }
                    994:        config.mscp[i].SCint = 0;
                    995:       }
                    996: #endif
                    997: 
                    998:     /* FIXME - if the device implements soft resets, then the command
                    999:        will still be running.  ERY */
                   1000: 
                   1001:     memset((unsigned char *)config.aborted, 0, sizeof config.aborted);
                   1002: #if ULTRASTOR_MAX_CMDS == 1
                   1003:     config.mscp_busy = 0;
                   1004: #else
                   1005:     config.mscp_free = ~0;
                   1006: #endif
                   1007: 
                   1008:     restore_flags(flags);
                   1009:     return SCSI_RESET_SUCCESS;
                   1010: 
                   1011: }
                   1012: 
                   1013: int ultrastor_biosparam(Disk * disk, kdev_t dev, int * dkinfo)
                   1014: {
                   1015:     int size = disk->capacity;
                   1016:     unsigned int s = config.heads * config.sectors;
                   1017: 
                   1018:     dkinfo[0] = config.heads;
                   1019:     dkinfo[1] = config.sectors;
                   1020:     dkinfo[2] = size / s;      /* Ignore partial cylinders */
                   1021: #if 0
                   1022:     if (dkinfo[2] > 1024)
                   1023:        dkinfo[2] = 1024;
                   1024: #endif
                   1025:     return 0;
                   1026: }
                   1027: 
                   1028: static void ultrastor_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                   1029: {
                   1030:     unsigned int status;
                   1031: #if ULTRASTOR_MAX_CMDS > 1
                   1032:     unsigned int mscp_index;
                   1033: #endif
                   1034:     register struct mscp *mscp;
                   1035:     void (*done)(Scsi_Cmnd *);
                   1036:     Scsi_Cmnd *SCtmp;
                   1037: 
                   1038: #if ULTRASTOR_MAX_CMDS == 1
                   1039:     mscp = &config.mscp[0];
                   1040: #else
                   1041:     mscp = (struct mscp *)inl(config.icm_address);
                   1042:     mscp_index = mscp - config.mscp;
                   1043:     if (mscp_index >= ULTRASTOR_MAX_CMDS) {
                   1044:        printk("Ux4F interrupt: bad MSCP address %x\n", (unsigned int) mscp);
                   1045:        /* A command has been lost.  Reset and report an error
                   1046:           for all commands.  */
                   1047:        ultrastor_reset(NULL, 0);
                   1048:        return;
                   1049:     }
                   1050: #endif
                   1051: 
                   1052:     /* Clean ICM slot (set ICMINT bit to 0) */
                   1053:     if (config.slot) {
                   1054:        unsigned char icm_status = inb(config.icm_address - 1);
                   1055: #if ULTRASTOR_DEBUG & (UD_INTERRUPT|UD_ERROR|UD_ABORT)
                   1056:        if (icm_status != 1 && icm_status != 2)
                   1057:            printk("US24F: ICM status %x for MSCP %d (%x)\n", icm_status,
                   1058:                   mscp_index, (unsigned int) mscp);
                   1059: #endif
                   1060:        /* The manual says clear interrupt then write 0 to ICM status.
                   1061:           This seems backwards, but I'll do it anyway.  --jfc */
                   1062:        outb(2, SYS_DOORBELL_INTR(config.doorbell_address));
                   1063:        outb(0, config.icm_address - 1);
                   1064:        if (icm_status == 4) {
                   1065:            printk("UltraStor abort command failed\n");
                   1066:            return;
                   1067:        }
                   1068:        if (icm_status == 3) {
                   1069:            void (*done)(Scsi_Cmnd *) = mscp->done;
                   1070:            if (done) {
                   1071:                mscp->done = 0;
                   1072:                mscp->SCint->result = DID_ABORT << 16;
                   1073:                done(mscp->SCint);
                   1074:            }
                   1075:            return;
                   1076:        }
                   1077:     } else {
                   1078:        outb(1, SYS_DOORBELL_INTR(config.doorbell_address));
                   1079:     }
                   1080: 
                   1081:     SCtmp = mscp->SCint;
                   1082:     mscp->SCint = NULL;
                   1083: 
                   1084:     if (SCtmp == 0)
                   1085:       {
                   1086: #if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
                   1087:        printk("MSCP %d (%x): no command\n", mscp_index, (unsigned int) mscp);
                   1088: #endif 
                   1089: #if ULTRASTOR_MAX_CMDS == 1
                   1090:        config.mscp_busy = FALSE;
                   1091: #else
                   1092:        set_bit(mscp_index, &config.mscp_free);
                   1093: #endif
                   1094:        config.aborted[mscp_index] = 0;
                   1095:        return;
                   1096:       }
                   1097: 
                   1098:     /* Save done locally and zero before calling.  This is needed as
                   1099:        once we call done, we may get another command queued before this
                   1100:        interrupt service routine can return. */
                   1101:     done = mscp->done;
                   1102:     mscp->done = 0;
                   1103: 
                   1104:     /* Let the higher levels know that we're done */
                   1105:     switch (mscp->adapter_status)
                   1106:       {
                   1107:       case 0:
                   1108:        status = DID_OK << 16;
                   1109:        break;
                   1110:       case 0x01:       /* invalid command */
                   1111:       case 0x02:       /* invalid parameters */
                   1112:       case 0x03:       /* invalid data list */
                   1113:       default:
                   1114:        status = DID_ERROR << 16;
                   1115:        break;
                   1116:       case 0x84:       /* SCSI bus abort */
                   1117:        status = DID_ABORT << 16;
                   1118:        break;
                   1119:       case 0x91:
                   1120:        status = DID_TIME_OUT << 16;
                   1121:        break;
                   1122:       }
                   1123: 
                   1124:     SCtmp->result = status | mscp->target_status;
                   1125: 
                   1126:     SCtmp->host_scribble = 0;
                   1127: 
                   1128:     /* Free up mscp block for next command */
                   1129: #if ULTRASTOR_MAX_CMDS == 1
                   1130:     config.mscp_busy = FALSE;
                   1131: #else
                   1132:     set_bit(mscp_index, &config.mscp_free);
                   1133: #endif
                   1134: 
                   1135: #if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
                   1136:     if (config.aborted[mscp_index])
                   1137:        printk("Ux4 interrupt: MSCP %d (%x) aborted = %d\n",
                   1138:               mscp_index, (unsigned int) mscp, config.aborted[mscp_index]);
                   1139: #endif
                   1140:     config.aborted[mscp_index] = 0;
                   1141: 
                   1142:     if (done)
                   1143:        done(SCtmp);
                   1144:     else
                   1145:        printk("US14F: interrupt: unexpected interrupt\n");
                   1146: 
                   1147:     if (config.slot ? inb(config.icm_address - 1) :
                   1148:        (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
                   1149: #if (ULTRASTOR_DEBUG & UD_MULTI_CMD)
                   1150:       printk("Ux4F: multiple commands completed\n");
                   1151: #else
                   1152:       ;
                   1153: #endif
                   1154: 
                   1155: #if (ULTRASTOR_DEBUG & UD_INTERRUPT)
                   1156:     printk("USx4F: interrupt: returning\n");
                   1157: #endif
                   1158: }
                   1159: 
                   1160: #ifdef MODULE
                   1161: /* Eventually this will go into an include file, but this will be later */
                   1162: Scsi_Host_Template driver_template = ULTRASTOR_14F;
                   1163: 
                   1164: #include "scsi_module.c"
                   1165: #endif

unix.superglobalmegacorp.com

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