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 (eric@tantalus.nrl.navy.mil).
  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, int code)
     /* [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) return 0;  /* Do not attempt an abort for the 24f */
 811 
 812     mscp_index = ((struct mscp *)SCpnt->host_scribble) - config.mscp;
 813     if (mscp_index >= ULTRASTOR_MAX_CMDS)
 814         panic("Ux4F aborting invalid MSCP");
 815 
 816 #if ULTRASTOR_DEBUG & UD_ABORT
 817     if (config.slot)
 818       {
 819         int port0 = (config.slot << 12) | 0xc80;
 820         int i;
 821         int flags;
 822         save_flags(flags);
 823         cli();
 824         strcpy(out, "OGM %d:%x ICM %d:%x ports:  ");
 825         for (i = 0; i < 16; i++)
 826           {
 827             unsigned char p = inb(port0 + i);
 828             out[28 + i * 3] = "0123456789abcdef"[p >> 4];
 829             out[29 + i * 3] = "0123456789abcdef"[p & 15];
 830             out[30 + i * 3] = ' ';
 831           }
 832         out[28 + i * 3] = '\n';
 833         out[29 + i * 3] = 0;
 834         ogm_status = inb(port0 + 22);
 835         ogm_addr = inl(port0 + 23);
 836         icm_status = inb(port0 + 27);
 837         icm_addr = inl(port0 + 28);
 838         restore_flags(flags);
 839       }
 840 
 841     /* First check to see if an interrupt is pending.  I suspect the SiS
 842        chipset loses interrupts.  (I also suspect is mangles data, but
 843        one bug at a time... */
 844     if (config.slot ? inb(config.icm_address - 1) == 2 :
 845         (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
 846       {
 847         int flags;
 848         save_flags(flags);
 849         printk("Ux4F: abort while completed command pending\n");
 850         restore_flags(flags);
 851         cli();
 852         ultrastor_interrupt(0);
 853         restore_flags(flags);
 854         return 0;
 855       }
 856 #endif
 857 
 858     old_aborted = xchgb(code ? code : DID_ABORT, &config.aborted[mscp_index]);
 859 
 860     /* aborted == 0xff is the signal that queuecommand has not yet sent
 861        the command.  It will notice the new abort flag and fail.  */
 862     if (old_aborted == 0xff)
 863         return 0;
 864 
 865     /* On 24F, send an abort MSCP request.  The adapter will interrupt
 866        and the interrupt handler will call done.  */
 867     if (config.slot && inb(config.ogm_address - 1) == 0)
 868       {
 869         int flags;
 870 
 871         save_flags(flags);
 872         cli();
 873         outl((int)&config.mscp[mscp_index], config.ogm_address);
 874         inb(0xc80);     /* delay */
 875         outb(0x80, config.ogm_address - 1);
 876         outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
 877 #if ULTRASTOR_DEBUG & UD_ABORT
 878         log_ultrastor_abort(&config, mscp_index);
 879         printk(out, ogm_status, ogm_addr, icm_status, icm_addr);
 880 #endif
 881         restore_flags(flags);
 882         return 0;
 883       }
 884 
 885 #if ULTRASTOR_DEBUG & UD_ABORT
 886     log_ultrastor_abort(&config, mscp_index);
 887 #endif
 888 
 889     /* Can't request a graceful abort.  Either this is not a 24F or
 890        the OGM is busy.  Don't free the command -- the adapter might
 891        still be using it.  Setting SCint = 0 causes the interrupt
 892        handler to ignore the command.  */
 893 
 894 #if ULTRASTOR_DEBUG & UD_ABORT
 895     if (config.mscp[mscp_index].SCint != SCpnt)
 896         printk("abort: command mismatch, %x != %x\n",
 897                config.mscp[mscp_index].SCint, SCpnt);
 898 #endif
 899     if (config.mscp[mscp_index].SCint == 0)
 900         return 1;
 901 
 902     if (config.mscp[mscp_index].SCint != SCpnt) panic("Bad abort");
 903     config.mscp[mscp_index].SCint = 0;
 904     done = config.mscp[mscp_index].done;
 905     config.mscp[mscp_index].done = 0;
 906     SCpnt->result = DID_ABORT << 16;
 907     /* I worry about reentrancy in scsi.c  */
 908     done(SCpnt);
 909 
 910     /* Need to set a timeout here in case command never completes.  */
 911     return 0;
 912 
 913 }
 914 
 915 int ultrastor_reset(Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 916 {
 917     int flags;
 918     register int i;
 919 #if (ULTRASTOR_DEBUG & UD_RESET)
 920     printk("US14F: reset: called\n");
 921 #endif
 922 
 923     if(config.slot) {
 924       if (SCpnt) SCpnt->flags |= NEEDS_JUMPSTART;
 925       return 0;  /* Do not attempt a reset for the 24f */
 926     };
 927 
 928     save_flags(flags);
 929     cli();
 930 
 931     /* Reset the adapter and SCSI bus.  The SCSI bus reset can be
 932        inhibited by clearing ultrastor_bus_reset before probe.  */
 933     outb(0xc0, LCL_DOORBELL_INTR(config.doorbell_address));
 934     if (config.slot)
 935       {
 936         outb(0, config.ogm_address - 1);
 937         outb(0, config.icm_address - 1);
 938       }
 939 
 940 #if ULTRASTOR_MAX_CMDS == 1
 941     if (config.mscp_busy && config.mscp->done && config.mscp->SCint)
 942       {
 943         config.mscp->SCint->result = DID_RESET << 16;
 944         config.mscp->done(config.mscp->SCint);
 945       }
 946     config.mscp->SCint = 0;
 947 #else
 948     for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
 949       {
 950         if (! (config.mscp_free & (1 << i)) &&
 951             config.mscp[i].done && config.mscp[i].SCint)
 952           {
 953             config.mscp[i].SCint->result = DID_RESET << 16;
 954             config.mscp[i].done(config.mscp[i].SCint);
 955             config.mscp[i].done = 0;
 956           }
 957         config.mscp[i].SCint = 0;
 958       }
 959 #endif
 960 
 961     memset((unsigned char *)config.aborted, 0, sizeof config.aborted);
 962 #if ULTRASTOR_MAX_CMDS == 1
 963     config.mscp_busy = 0;
 964 #else
 965     config.mscp_free = ~0;
 966 #endif
 967 
 968     restore_flags(flags);
 969     return 0;
 970 
 971 }
 972 
 973 int ultrastor_biosparam(int size, int dev, int * dkinfo)
     /* [previous][next][first][last][top][bottom][index][help] */
 974 {
 975     unsigned int s = config.heads * config.sectors;
 976 
 977     dkinfo[0] = config.heads;
 978     dkinfo[1] = config.sectors;
 979     dkinfo[2] = size / s;       /* Ignore partial cylinders */
 980 #if 0
 981     if (dkinfo[2] > 1024)
 982         dkinfo[2] = 1024;
 983 #endif
 984     return 0;
 985 }
 986 
 987 static void ultrastor_interrupt(int cpl)
     /* [previous][next][first][last][top][bottom][index][help] */
 988 {
 989     unsigned int status;
 990 #if ULTRASTOR_MAX_CMDS > 1
 991     unsigned int mscp_index;
 992 #endif
 993     register struct mscp *mscp;
 994     void (*done)(Scsi_Cmnd *);
 995     Scsi_Cmnd *SCtmp;
 996 
 997 #if ULTRASTOR_MAX_CMDS == 1
 998     mscp = &config.mscp[0];
 999 #else
1000     mscp = (struct mscp *)inl(config.icm_address);
1001     mscp_index = mscp - config.mscp;
1002     if (mscp_index >= ULTRASTOR_MAX_CMDS) {
1003         printk("Ux4F interrupt: bad MSCP address %x\n", (unsigned int) mscp);
1004         /* A command has been lost.  Reset and report an error
1005            for all commands.  */
1006         ultrastor_reset(NULL);
1007         return;
1008     }
1009 #endif
1010 
1011     /* Clean ICM slot (set ICMINT bit to 0) */
1012     if (config.slot) {
1013         unsigned char icm_status = inb(config.icm_address - 1);
1014 #if ULTRASTOR_DEBUG & (UD_INTERRUPT|UD_ERROR|UD_ABORT)
1015         if (icm_status != 1 && icm_status != 2)
1016             printk("US24F: ICM status %x for MSCP %d (%x)\n", icm_status,
1017                    mscp_index, (unsigned int) mscp);
1018 #endif
1019         /* The manual says clear interrupt then write 0 to ICM status.
1020            This seems backwards, but I'll do it anyway.  --jfc */
1021         outb(2, SYS_DOORBELL_INTR(config.doorbell_address));
1022         outb(0, config.icm_address - 1);
1023         if (icm_status == 4) {
1024             printk("UltraStor abort command failed\n");
1025             return;
1026         }
1027         if (icm_status == 3) {
1028             void (*done)(Scsi_Cmnd *) = mscp->done;
1029             if (done) {
1030                 mscp->done = 0;
1031                 mscp->SCint->result = DID_ABORT << 16;
1032                 done(mscp->SCint);
1033             }
1034             return;
1035         }
1036     } else {
1037         outb(1, SYS_DOORBELL_INTR(config.doorbell_address));
1038     }
1039 
1040     SCtmp = mscp->SCint;
1041     mscp->SCint = NULL;
1042 
1043     if (SCtmp == 0)
1044       {
1045 #if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
1046         printk("MSCP %d (%x): no command\n", mscp_index, (unsigned int) mscp);
1047 #endif  
1048 #if ULTRASTOR_MAX_CMDS == 1
1049         config.mscp_busy = FALSE;
1050 #else
1051         set_bit(mscp_index, &config.mscp_free);
1052 #endif
1053         config.aborted[mscp_index] = 0;
1054         return;
1055       }
1056 
1057     /* Save done locally and zero before calling.  This is needed as
1058        once we call done, we may get another command queued before this
1059        interrupt service routine can return. */
1060     done = mscp->done;
1061     mscp->done = 0;
1062 
1063     /* Let the higher levels know that we're done */
1064     switch (mscp->adapter_status)
1065       {
1066       case 0:
1067         status = DID_OK << 16;
1068         break;
1069       case 0x01:        /* invalid command */
1070       case 0x02:        /* invalid parameters */
1071       case 0x03:        /* invalid data list */
1072       default:
1073         status = DID_ERROR << 16;
1074         break;
1075       case 0x84:        /* SCSI bus abort */
1076         status = DID_ABORT << 16;
1077         break;
1078       case 0x91:
1079         status = DID_TIME_OUT << 16;
1080         break;
1081       }
1082 
1083     SCtmp->result = status | mscp->target_status;
1084 
1085     SCtmp->host_scribble = 0;
1086 
1087     /* Free up mscp block for next command */
1088 #if ULTRASTOR_MAX_CMDS == 1
1089     config.mscp_busy = FALSE;
1090 #else
1091     set_bit(mscp_index, &config.mscp_free);
1092 #endif
1093 
1094 #if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
1095     if (config.aborted[mscp_index])
1096         printk("Ux4 interrupt: MSCP %d (%x) aborted = %d\n",
1097                mscp_index, (unsigned int) mscp, config.aborted[mscp_index]);
1098 #endif
1099     config.aborted[mscp_index] = 0;
1100 
1101     if (done)
1102         done(SCtmp);
1103     else
1104         printk("US14F: interrupt: unexpected interrupt\n");
1105 
1106     if (config.slot ? inb(config.icm_address - 1) : (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
1107       printk("Ux4F: multiple commands completed\n");
1108 
1109 #if (ULTRASTOR_DEBUG & UD_INTERRUPT)
1110     printk("USx4F: interrupt: returning\n");
1111 #endif
1112 }

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