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

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