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

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