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

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