root/drivers/scsi/ultrastor.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. find_and_clear_bit_16
  2. xchgb
  3. log_ultrastor_abort
  4. ultrastor_14f_detect
  5. ARRAY_SIZE
  6. request_irq
  7. request_dma
  8. ultrastor_24f_detect
  9. ultrastor_detect
  10. ultrastor_info
  11. build_sg_list
  12. ultrastor_queuecommand
  13. ultrastor_abort
  14. ultrastor_reset
  15. ultrastor_biosparam
  16. ultrastor_interrupt

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

/* [previous][next][first][last][top][bottom][index][help] */