root/drivers/scsi/buslogic.c

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

DEFINITIONS

This source file includes following definitions.
  1. wait
  2. buslogic_prefix
  3. buslogic_stat
  4. buslogic_out
  5. buslogic_in
  6. makecode
  7. test_port
  8. buslogic_info
  9. buslogic_interrupt
  10. buslogic_queuecommand
  11. internal_done
  12. buslogic_command
  13. setup_mailboxes
  14. getconfig
  15. buslogic_query
  16. buslogic_detect
  17. buslogic_abort
  18. buslogic_reset
  19. buslogic_biosparam

   1 /*
   2  *      buslogic.c      (C) 1993 David B. Gentzel
   3  *      Low-level scsi driver for BusLogic adapters
   4  *      by David B. Gentzel, Whitfield Software Services, Carnegie, PA
   5  *          (gentzel@nova.enet.dec.com)
   6  *      Thanks to BusLogic for providing the necessary documentation
   7  *
   8  *      The original version of this driver was derived from aha1542.[ch] which
   9  *      is Copyright (C) 1992 Tommy Thorn.  Much has been reworked, but most of
  10  *      basic structure and substantial chunks of code still remain.
  11  */
  12 
  13 /*
  14  * TODO:
  15  *      1. Cleanup error handling & reporting.
  16  *      2. Find out why scatter/gather is limited to 16 requests per command.
  17  *      3. Add multiple outstanding requests.
  18  *      4. See if we can make good use of having more than one command per lun.
  19  *      5. Test/improve/fix abort & reset functions.
  20  *      6. Look at command linking.
  21  */
  22 
  23 /*
  24  * NOTES:
  25  *    BusLogic (formerly BusTek) manufactures an extensive family of
  26  *    intelligent, high performance SCSI-2 host adapters.  They all support
  27  *    command queueing and scatter/gather I/O.  Most importantly, they all
  28  *    support identical programming interfaces, so a single driver can be used
  29  *    for all boards.
  30  *
  31  *    Actually, they all support TWO identical programming interfaces!  They
  32  *    have an Adaptec 154x compatible interface (complete with 24 bit
  33  *    addresses) as well as a "native" 32 bit interface.  As such, the Linux
  34  *    aha1542 driver can be used to drive them, but with less than optimal
  35  *    performance (at least for the EISA, VESA, and MCA boards).
  36  *
  37  *    Here is the scoop on the various models:
  38  *      BT-542B - ISA first-party DMA with floppy support.
  39  *      BT-545S - 542B + FAST SCSI and active termination.
  40  *      BT-545D - 545S + differential termination.
  41  *      BT-445S - VESA bus-master FAST SCSI with active termination and floppy
  42  *                support.
  43  *      BT-640A - MCA bus-master with floppy support.
  44  *      BT-646S - 640A + FAST SCSI and active termination.
  45  *      BT-646D - 646S + differential termination.
  46  *      BT-742A - EISA bus-master with floppy support.
  47  *      BT-747S - 742A + FAST SCSI, active termination, and 2.88M floppy.
  48  *      BT-747D - 747S + differential termination.
  49  *      BT-757S - 747S + WIDE SCSI.
  50  *      BT-757D - 747D + WIDE SCSI.
  51  *
  52  *    Should you require further information on any of these boards, BusLogic
  53  *    can be reached at (408)492-9090.
  54  *
  55  *    This driver SHOULD support all of these boards.  It has only been tested
  56  *    with a 747S.  An earlier version was tested with a 445S.
  57  *
  58  *    Places flagged with a triple question-mark are things which are either
  59  *    unfinished, questionable, or wrong.
  60  */
  61 
  62 #include <linux/string.h>
  63 #include <linux/sched.h>
  64 #include <linux/kernel.h>
  65 #include <linux/head.h>
  66 #include <linux/types.h>
  67 #include <linux/ioport.h>
  68 
  69 #include <asm/io.h>
  70 #include <asm/system.h>
  71 #include <asm/dma.h>
  72 
  73 #include "../block/blk.h"
  74 #include "scsi.h"
  75 #include "hosts.h"
  76 # include "sd.h"
  77 #define BUSLOGIC_PRIVATE_H      /* Get the "private" stuff */
  78 #include "buslogic.h"
  79 
  80 #ifndef BUSLOGIC_DEBUG
  81 # define BUSLOGIC_DEBUG UD_ABORT
  82 #endif
  83 
  84 #define BUSLOGIC_VERSION "1.00"
  85 
  86 /* ??? This *MAY* work to properly report the geometry of disks > 1G when the
  87    alternate geometry is enabled on the host adapter.  It is completely
  88    untested as I have no such disk to experiment with.  I rarely refuse gifts,
  89    however... */
  90 /* Check out the stuff in aha1542.c - is this the same as how buslogic does
  91    it? - ERY */
  92 /* ??? Not Yet Implemented */
  93 /*#ifdef BUSLOGIC_ALTERNATE_MAPPING*/
  94 
  95 /* Not a random value - if this is too large, the system hangs for a long time
  96    waiting for something to happen if a board is not installed. */
  97 #define WAITNEXTTIMEOUT 3000000
  98 
  99 /* This is for the scsi_malloc call in buslogic_queuecommand. */
 100 /* ??? I'd up this to 4096, but would we be in danger of using up the
 101    scsi_malloc memory pool? */
 102 /* This could be a concern, I guess.  It may be possible to fix things so that
 103    the table generated in sd.c is compatible with the low-level code, but
 104    don't hold your breath.  -ERY */
 105 #define BUSLOGIC_SG_MALLOC 512
 106 
 107 /* Since the SG list is malloced, we have to limit the length. */
 108 #define BUSLOGIC_MAX_SG (BUSLOGIC_SG_MALLOC / sizeof (struct chain))
 109 
 110 /* The DMA-Controller.  We need to fool with this because we want to be able to
 111    use an ISA BusLogic without having to have the BIOS enabled. */
 112 #define DMA_MODE_REG 0xD6
 113 #define DMA_MASK_REG 0xD4
 114 #define CASCADE 0xC0
 115 
 116 #define BUSLOGIC_MAILBOXES 16   /* ??? Arbitrary? */
 117 
 118 /* BusLogic boards can be configured for quite a number of port addresses (six
 119    to be exact), but I generally do not want the driver poking around at
 120    random.  We allow two port addresses - this allows people to use a BusLogic
 121    with a MIDI card, which frequently also used 0x330.  If different port
 122    addresses are needed (e.g. to install more than two cards), you must define
 123    BUSLOGIC_PORT_OVERRIDE to be a list of the addresses which will be checked.
 124    This can also be used to resolve a conflict if the port-probing at a
 125    standard port causes problems with another board. */
 126 static const unsigned int bases[] = {
 127 #ifdef BUSLOGIC_PORT_OVERRIDE
 128     BUSLOGIC_PORT_OVERRIDE
 129 #else
 130     0x330, 0x334, /* 0x130, 0x134, 0x230, 0x234 */
 131 #endif
 132 };
 133 
 134 #define BIOS_TRANSLATION_6432 1         /* Default case */
 135 #define BIOS_TRANSLATION_25563 2        /* Big disk case */
 136 
 137 struct hostdata {
 138     unsigned char bus_type;
 139     int bios_translation;       /* Mapping bios uses - for compatibility */
 140     size_t last_mbi_used;
 141     size_t last_mbo_used;
 142     Scsi_Cmnd *SCint[BUSLOGIC_MAILBOXES];
 143     struct mailbox mb[2 * BUSLOGIC_MAILBOXES];
 144     struct ccb ccbs[BUSLOGIC_MAILBOXES];
 145 };
 146 
 147 #define HOSTDATA(host) ((struct hostdata *)&(host)->hostdata)
 148 
 149 /* One for each IRQ level (9-15), although 13 will never be used. */
 150 static struct Scsi_Host *host[7] = { NULL, };
 151 
 152 static int setup_mailboxes(unsigned int base, struct Scsi_Host *SHpnt);
 153 
 154 #define INTR_RESET(base) outb(RINT, CONTROL(base))
 155 
 156 #define buslogic_printk buslogic_prefix(),printk
 157 
 158 #define CHECK(cond) if (cond) ; else goto fail
 159 
 160 #define WAIT(port, mask, allof, noneof) CHECK(wait(port, mask, allof, noneof))
 161 #define WAIT_WHILE(port, mask) WAIT(port, mask, 0, mask)
 162 #define WAIT_UNTIL(port, mask) WAIT(port, mask, mask, 0)
 163 
 164 static __inline__ int wait(unsigned short port, unsigned char mask,
     /* [previous][next][first][last][top][bottom][index][help] */
 165                            unsigned char allof, unsigned char noneof)
 166 {
 167     int bits;
 168     unsigned int timeout = WAITNEXTTIMEOUT;
 169 
 170     for (;;) {
 171         bits = inb(port) & mask;
 172         if ((bits & allof) == allof && (bits & noneof) == 0)
 173             break;
 174         if (--timeout == 0)
 175             return FALSE;
 176     }
 177     return TRUE;
 178 }
 179 
 180 static void buslogic_prefix(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 181 {
 182     printk("BusLogic SCSI: ");
 183 }
 184 
 185 #if 0
 186 static void buslogic_stat(unsigned int base)
     /* [previous][next][first][last][top][bottom][index][help] */
 187 {
 188     int s = inb(STATUS(base)), i = inb(INTERRUPT(base));
 189 
 190     printk("status=%02X intrflags=%02X\n", s, i);
 191 }
 192 #else
 193 # define buslogic_stat(base)
 194 #endif
 195 
 196 /* This is a bit complicated, but we need to make sure that an interrupt
 197    routine does not send something out while we are in the middle of this.
 198    Fortunately, it is only at boot time that multi-byte messages are ever
 199    sent. */
 200 static int buslogic_out(unsigned int base, const unsigned char *cmdp, size_t len)
     /* [previous][next][first][last][top][bottom][index][help] */
 201 {
 202     if (len == 1) {
 203         for (;;) {
 204             WAIT_WHILE(STATUS(base), CPRBSY);
 205             cli();
 206             if (!(inb(STATUS(base)) & CPRBSY)) {
 207                 outb(*cmdp, COMMAND_PARAMETER(base));
 208                 sti();
 209                 return FALSE;
 210             }
 211             sti();
 212         }
 213     } else {
 214         cli();
 215         while (len--) {
 216             WAIT_WHILE(STATUS(base), CPRBSY);
 217             outb(*cmdp++, COMMAND_PARAMETER(base));
 218         }
 219         sti();
 220     }
 221     return FALSE;
 222   fail:
 223     sti();
 224     buslogic_printk("buslogic_out failed(%u): ", len + 1);
 225     buslogic_stat(base);
 226     return TRUE;
 227 }
 228 
 229 static int buslogic_in(unsigned int base, unsigned char *cmdp, size_t len)
     /* [previous][next][first][last][top][bottom][index][help] */
 230 {
 231     cli();
 232     while (len--) {
 233         WAIT_UNTIL(STATUS(base), DIRRDY);
 234         *cmdp++ = inb(DATA_IN(base));
 235     }
 236     sti();
 237     return FALSE;
 238   fail:
 239     sti();
 240     buslogic_printk("buslogic_in failed(%u): ", len + 1);
 241     buslogic_stat(base);
 242     return TRUE;
 243 }
 244 
 245 static unsigned int makecode(unsigned int hosterr, unsigned int scsierr)
     /* [previous][next][first][last][top][bottom][index][help] */
 246 {
 247     switch (hosterr) {
 248       case 0x00:        /* Normal completion. */
 249       case 0x0A:        /* Linked command complete without error and linked
 250                            normally. */
 251       case 0x0B:        /* Linked command complete without error, interrupt
 252                            generated. */
 253         hosterr = DID_OK;
 254         break;
 255 
 256       case 0x11:        /* Selection time out: the initiator selection or
 257                            target reselection was not complete within the SCSI
 258                            Time out period. */
 259         hosterr = DID_TIME_OUT;
 260         break;
 261 
 262       case 0x14:        /* Target bus phase sequence failure - An invalid bus
 263                            phase or bus phase sequence was requested by the
 264                            target.  The host adapter will generate a SCSI
 265                            Reset Condition, notifying the host with a RSTS
 266                            interrupt. */
 267         hosterr = DID_RESET;    /* ??? Is this right? */
 268         break;
 269 
 270       case 0x12:        /* Data overrun/underrun: the target attempted to
 271                            transfer more data than was allocated by the Data
 272                            Length field or the sum of the Scatter/Gather Data
 273                            Length fields. */
 274       case 0x13:        /* Unexpected bus free - The target dropped the SCSI
 275                            BSY at an unexpected time. */
 276       case 0x15:        /* MBO command was not 00, 01, or 02 - The first byte
 277                            of the MB was invalid.  This usually indicates a
 278                            software failure. */
 279       case 0x16:        /* Invalid CCB Operation Code - The first byte of the
 280                            CCB was invalid.  This usually indicates a software
 281                            failure. */
 282       case 0x17:        /* Linked CCB does not have the same LUN - A
 283                            subsequent CCB of a set of linked CCB's does not
 284                            specify the same logical unit number as the
 285                            first. */
 286       case 0x18:        /* Invalid Target Direction received from Host - The
 287                            direction of a Target Mode CCB was invalid. */
 288       case 0x19:        /* Duplicate CCB Received in Target Mode - More than
 289                            once CCB was received to service data transfer
 290                            between the same target LUN and initiator SCSI ID
 291                            in the same direction. */
 292       case 0x1A:        /* Invalid CCB or Segment List Parameter - A segment
 293                            list with a zero length segment or invalid segment
 294                            list boundaries was received.  A CCB parameter was
 295                            invalid. */
 296       case 0x1B:        /* Auto request sense failed. */
 297       case 0x1C:        /* SCSI-2 tagged queueing message was rejected by the
 298                            target. */
 299       case 0x20:        /* The host adapter hardware failed. */
 300       case 0x21:        /* The target did not respond to SCSI ATN and the host
 301                            adapter consequently issued a SCSI bus reset to
 302                            clear up the failure. */
 303       case 0x22:        /* The host adapter asserted a SCSI bus reset. */
 304       case 0x23:        /* Other SCSI devices asserted a SCSI bus reset. */
 305 #if BUSLOGIC_DEBUG
 306         buslogic_printk("%X %X\n", hosterr, scsierr);
 307 #endif
 308         hosterr = DID_ERROR;    /* ??? Couldn't find any better. */
 309         break;
 310 
 311       default:
 312         buslogic_printk("makecode: unknown hoststatus %X\n", hosterr);
 313         break;
 314     }
 315     return (hosterr << 16) | scsierr;
 316 }
 317 
 318 static int test_port(unsigned int base, struct Scsi_Host *SHpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 319 {
 320     unsigned int i;
 321     unsigned char inquiry_cmd[] = { CMD_INQUIRY };
 322     unsigned char inquiry_result[4];
 323     unsigned char *cmdp;
 324     int len;
 325     volatile int debug = 0;
 326 
 327     /* Quick and dirty test for presence of the card. */
 328     if (inb(STATUS(base)) == 0xFF)
 329         return TRUE;
 330 
 331     /* Reset the adapter.  I ought to make a hard reset, but it's not really
 332        necessary. */
 333 
 334 #if BUSLOGIC_DEBUG
 335     buslogic_printk("test_port called\n");
 336 #endif
 337 
 338     outb(RSOFT | RINT/* | RSBUS*/, CONTROL(base));
 339 
 340     /* Wait a little bit for things to settle down. */
 341     i = jiffies + 2;
 342     while (i > jiffies);
 343 
 344     debug = 1;
 345     /* Expect INREQ and HARDY, any of the others are bad. */
 346     WAIT(STATUS(base), STATMASK, INREQ | HARDY,
 347          DACT | DFAIL | CMDINV | DIRRDY | CPRBSY);
 348 
 349     debug = 2;
 350     /* Shouldn't have generated any interrupts during reset. */
 351     if (inb(INTERRUPT(base)) & INTRMASK)
 352         goto fail;
 353 
 354     /* Perform a host adapter inquiry instead so we do not need to set up the
 355        mailboxes ahead of time. */
 356     buslogic_out(base, inquiry_cmd, 1);
 357 
 358     debug = 3;
 359     len = 4;
 360     cmdp = &inquiry_result[0];
 361     while (len--) {
 362         WAIT(STATUS(base), DIRRDY, DIRRDY, 0);
 363         *cmdp++ = inb(DATA_IN(base));
 364     }
 365 
 366     debug = 4;
 367     /* Reading port should reset DIRRDY. */
 368     if (inb(STATUS(base)) & DIRRDY)
 369         goto fail;
 370 
 371     debug = 5;
 372     /* When CMDC, command is completed, and we're though testing. */
 373     WAIT_UNTIL(INTERRUPT(base), CMDC);
 374 
 375     /* now initialize adapter. */
 376 
 377     debug = 6;
 378     /* Clear interrupts. */
 379     outb(RINT, CONTROL(base));
 380 
 381     debug = 7;
 382 
 383     return FALSE;                               /* 0 = ok */
 384   fail:
 385     return TRUE;                                /* 1 = not ok */
 386 }
 387 
 388 const char *buslogic_info(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 389 {
 390     return "BusLogic SCSI Driver version " BUSLOGIC_VERSION;
 391 }
 392 
 393 /* A "high" level interrupt handler. */
 394 static void buslogic_interrupt(int junk)
     /* [previous][next][first][last][top][bottom][index][help] */
 395 {
 396     void (*my_done)(Scsi_Cmnd *) = NULL;
 397     int errstatus, mbistatus = 0, number_serviced, found;
 398     size_t mbi, mbo = 0;
 399     struct Scsi_Host *SHpnt;
 400     Scsi_Cmnd *SCtmp;
 401     int irqno, base;
 402     struct mailbox *mb;
 403     struct ccb *ccb;
 404 
 405     /* Magic - this -2 is only required for slow interrupt handlers */
 406     irqno = ((int *)junk)[-2];
 407 
 408     SHpnt = host[irqno - 9];
 409     if (!SHpnt)
 410         panic("buslogic.c: NULL SCSI host entry");
 411 
 412     mb = HOSTDATA(SHpnt)->mb;
 413     ccb = HOSTDATA(SHpnt)->ccbs;
 414     base = SHpnt->io_port;
 415 
 416 #if BUSLOGIC_DEBUG
 417     {
 418         int flag = inb(INTERRUPT(base));
 419 
 420         buslogic_printk("buslogic_interrupt: ");
 421         if (!(flag & INTV))
 422             printk("no interrupt? ");
 423         if (flag & IMBL)
 424             printk("IMBL ");
 425         if (flag & MBOR)
 426             printk("MBOR ");
 427         if (flag & CMDC)
 428             printk("CMDC ");
 429         if (flag & RSTS)
 430             printk("RSTS ");
 431         printk("status %02X\n", inb(STATUS(base)));
 432     }
 433 #endif
 434 
 435     number_serviced = 0;
 436 
 437     for (;;) {
 438         INTR_RESET(base);
 439 
 440         cli();
 441 
 442         mbi = HOSTDATA(SHpnt)->last_mbi_used + 1;
 443         if (mbi >= 2 * BUSLOGIC_MAILBOXES)
 444             mbi = BUSLOGIC_MAILBOXES;
 445 
 446         /* I use the "found" variable as I like to keep cli/sti pairs at the
 447            same block level.  Debugging dropped sti's is no fun... */
 448 
 449         found = FALSE;
 450         do {
 451             if (mb[mbi].status != MBX_NOT_IN_USE) {
 452                 found = TRUE;
 453                 break;
 454             }
 455             mbi++;
 456             if (mbi >= 2 * BUSLOGIC_MAILBOXES)
 457                 mbi = BUSLOGIC_MAILBOXES;
 458         } while (mbi != HOSTDATA(SHpnt)->last_mbi_used);
 459 
 460         if (found) {
 461             mbo = (struct ccb *)mb[mbi].ccbptr - ccb;
 462             mbistatus = mb[mbi].status;
 463             mb[mbi].status = MBX_NOT_IN_USE;
 464             HOSTDATA(SHpnt)->last_mbi_used = mbi;
 465         }
 466 
 467         sti();
 468 
 469         if (!found) {
 470             /* Hmm, no mail.  Must have read it the last time around. */
 471             if (number_serviced)
 472                 return;
 473             buslogic_printk("interrupt received, but no mail\n");
 474             return;
 475         }
 476 
 477 #if BUSLOGIC_DEBUG
 478         if (ccb[mbo].tarstat || ccb[mbo].hastat)
 479             buslogic_printk("buslogic_interrupt: returning %08X (status %d)\n",
 480                             ((int)ccb[mbo].hastat << 16) | ccb[mbo].tarstat,
 481                             mb[mbi].status);
 482 #endif
 483 
 484         if (mbistatus == 0x03)  /* ??? 0x03 == Aborted CCB not found. */
 485             continue;
 486 
 487 #if BUSLOGIC_DEBUG
 488         buslogic_printk("...done %u %u\n", mbo, mbi);
 489 #endif
 490 
 491         SCtmp = HOSTDATA(SHpnt)->SCint[mbo];
 492 
 493         if (!SCtmp || !SCtmp->scsi_done) {
 494             buslogic_printk("buslogic_interrupt: Unexpected interrupt\n");
 495             return;
 496         }
 497 
 498         my_done = SCtmp->scsi_done;
 499         if (SCtmp->host_scribble)
 500             scsi_free(SCtmp->host_scribble, BUSLOGIC_SG_MALLOC);
 501 
 502         /* ??? more error checking left out here */
 503         if (mbistatus != 1)
 504             /* ??? This is surely wrong, but I don't know what's right. */
 505             errstatus = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
 506         else
 507             errstatus = 0;
 508 
 509 #if BUSLOGIC_DEBUG
 510         if (errstatus)
 511             buslogic_printk("error: %08X %04X %04X\n",
 512                             errstatus, ccb[mbo].hastat, ccb[mbo].tarstat);
 513 
 514         if (status_byte(ccb[mbo].tarstat) == CHECK_CONDITION) {
 515             size_t i;
 516 
 517             buslogic_printk("buslogic_interrupt: sense: ");
 518             for (i = 0; i < sizeof SCtmp->sense_buffer; i++)
 519                 printk(" %02X", SCtmp->sense_buffer[i]);
 520             printk("\n");
 521         }
 522 
 523         if (errstatus)
 524             buslogic_printk("buslogic_interrupt: returning %08X\n", errstatus);
 525 #endif
 526 
 527         SCtmp->result = errstatus;
 528         HOSTDATA(SHpnt)->SCint[mbo] = NULL;     /* This effectively frees up
 529                                                    the mailbox slot, as far as
 530                                                    queuecommand is concerned. */
 531         my_done(SCtmp);
 532         number_serviced++;
 533     }
 534 }
 535 
 536 int buslogic_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
     /* [previous][next][first][last][top][bottom][index][help] */
 537 {
 538     static const unsigned char buscmd[] = { CMD_START_SCSI };
 539     unsigned char direction;
 540     unsigned char *cmd = (unsigned char *)SCpnt->cmnd;
 541     unsigned char target = SCpnt->target;
 542     unsigned char lun = SCpnt->lun;
 543     void *buff = SCpnt->request_buffer;
 544     int bufflen = SCpnt->request_bufflen;
 545     int mbo;
 546     struct mailbox *mb;
 547     struct ccb *ccb;
 548 
 549 #if BUSLOGIC_DEBUG
 550     if (target > 1) {
 551         SCpnt->result = DID_TIME_OUT << 16;
 552         done(SCpnt);
 553         return 0;
 554     }
 555 #endif
 556 
 557     if (*cmd == REQUEST_SENSE) {
 558 #ifndef DEBUG
 559         if (bufflen != sizeof SCpnt->sense_buffer) {
 560             buslogic_printk("Wrong buffer length supplied for request sense (%d)\n",
 561                             bufflen);
 562         }
 563 #endif
 564         SCpnt->result = 0;
 565         done(SCpnt);
 566         return 0;
 567     }
 568 
 569 #if BUSLOGIC_DEBUG
 570     {
 571         int i;
 572 
 573         if (*cmd == READ_10 || *cmd == WRITE_10)
 574             i = xscsi2int(cmd + 2);
 575         else if (*cmd == READ_6 || *cmd == WRITE_6)
 576             i = scsi2int(cmd + 2);
 577         else
 578             i = -1;
 579         buslogic_printk("buslogic_queuecommand: dev %d cmd %02X pos %d len %d ",
 580                         target, *cmd, i, bufflen);
 581         buslogic_stat(SCpnt->host->io_port);
 582         buslogic_printk("buslogic_queuecommand: dumping scsi cmd: ");
 583         for (i = 0; i < (COMMAND_SIZE(*cmd)); i++)
 584             printk(" %02X", cmd[i]);
 585         printk("\n");
 586         if (*cmd == WRITE_10 || *cmd == WRITE_6)
 587             return 0;   /* we are still testing, so *don't* write */
 588     }
 589 #endif
 590 
 591     mb = HOSTDATA(SCpnt->host)->mb;
 592     ccb = HOSTDATA(SCpnt->host)->ccbs;
 593 
 594     /* Use the outgoing mailboxes in a round-robin fashion, because this
 595        is how the host adapter will scan for them. */
 596 
 597     cli();
 598 
 599     mbo = HOSTDATA(SCpnt->host)->last_mbo_used + 1;
 600     if (mbo >= BUSLOGIC_MAILBOXES)
 601         mbo = 0;
 602 
 603     do {
 604         if (mb[mbo].status == MBX_NOT_IN_USE
 605             && HOSTDATA(SCpnt->host)->SCint[mbo] == NULL)
 606             break;
 607         mbo++;
 608         if (mbo >= BUSLOGIC_MAILBOXES)
 609             mbo = 0;
 610     } while (mbo != HOSTDATA(SCpnt->host)->last_mbo_used);
 611 
 612     if (mb[mbo].status != MBX_NOT_IN_USE || HOSTDATA(SCpnt->host)->SCint[mbo]) {
 613         /* ??? Instead of panicing, we should enable OMBR interrupts and
 614            sleep until we get one. */
 615         panic("buslogic.c: unable to find empty mailbox");
 616     }
 617 
 618     HOSTDATA(SCpnt->host)->SCint[mbo] = SCpnt;  /* This will effectively
 619                                                    prevent someone else from
 620                                                    screwing with this cdb. */
 621 
 622     HOSTDATA(SCpnt->host)->last_mbo_used = mbo;
 623 
 624     sti();
 625 
 626 #if BUSLOGIC_DEBUG
 627     buslogic_printk("sending command (%d %08X)...", mbo, done);
 628 #endif
 629 
 630     /* This gets trashed for some reason */
 631     mb[mbo].ccbptr = &ccb[mbo];
 632 
 633     memset(&ccb[mbo], 0, sizeof (struct ccb));
 634 
 635     ccb[mbo].cdblen = COMMAND_SIZE(*cmd);       /* SCSI Command Descriptor
 636                                                    Block Length */
 637 
 638     direction = 0;
 639     if (*cmd == READ_10 || *cmd == READ_6)
 640         direction = 8;
 641     else if (*cmd == WRITE_10 || *cmd == WRITE_6)
 642         direction = 16;
 643 
 644     memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
 645 
 646     if (SCpnt->use_sg) {
 647         struct scatterlist *sgpnt;
 648         struct chain *cptr;
 649         size_t i;
 650 
 651         ccb[mbo].op = CCB_OP_INIT_SG;   /* SCSI Initiator Command w/scatter-gather */
 652         SCpnt->host_scribble = (unsigned char *)scsi_malloc(BUSLOGIC_SG_MALLOC);
 653         if (SCpnt->host_scribble == NULL)
 654             panic("buslogic.c: unable to allocate DMA memory");
 655         sgpnt = (struct scatterlist *)SCpnt->request_buffer;
 656         cptr = (struct chain *)SCpnt->host_scribble;
 657         if (SCpnt->use_sg > SCpnt->host->sg_tablesize) {
 658             buslogic_printk("buslogic_queuecommand bad segment list, %d > %d\n",
 659                             SCpnt->use_sg, SCpnt->host->sg_tablesize);
 660             panic("buslogic.c: bad segment list");
 661         }
 662         for (i = 0; i < SCpnt->use_sg; i++) {
 663             cptr[i].dataptr = sgpnt[i].address;
 664             cptr[i].datalen = sgpnt[i].length;
 665         }
 666         ccb[mbo].datalen = SCpnt->use_sg * sizeof (struct chain);
 667         ccb[mbo].dataptr = cptr;
 668 #if BUSLOGIC_DEBUG
 669         {
 670             unsigned char *ptr;
 671 
 672             buslogic_printk("cptr %08X: ", cptr);
 673             ptr = (unsigned char *)cptr;
 674             for (i = 0; i < 18; i++)
 675                 printk(" %02X", ptr[i]);
 676             printk("\n");
 677         }
 678 #endif
 679     } else {
 680         ccb[mbo].op = CCB_OP_INIT;      /* SCSI Initiator Command */
 681         SCpnt->host_scribble = NULL;
 682         ccb[mbo].datalen = bufflen;
 683         ccb[mbo].dataptr = buff;
 684     }
 685     ccb[mbo].id = target;
 686     ccb[mbo].lun = lun;
 687     ccb[mbo].dir = direction;
 688     ccb[mbo].rsalen = sizeof SCpnt->sense_buffer;
 689     ccb[mbo].senseptr = SCpnt->sense_buffer;
 690     ccb[mbo].linkptr = NULL;
 691     ccb[mbo].commlinkid = 0;
 692 
 693 #if BUSLOGIC_DEBUG
 694     {
 695         size_t i;
 696 
 697         buslogic_printk("buslogic_queuecommand: sending...");
 698         for (i = 0; i < sizeof ccb[mbo]; i++)
 699             printk(" %02X", ((unsigned char *)&ccb[mbo])[i]);
 700         printk("\n");
 701     }
 702 #endif
 703 
 704     if (done) {
 705 #if BUSLOGIC_DEBUG
 706         buslogic_printk("buslogic_queuecommand: now waiting for interrupt: ");
 707         buslogic_stat(SCpnt->host->io_port);
 708 #endif
 709         SCpnt->scsi_done = done;
 710         mb[mbo].status = MBX_ACTION_START;
 711         /* start scsi command */
 712         buslogic_out(SCpnt->host->io_port, buscmd, sizeof buscmd);
 713 #if BUSLOGIC_DEBUG
 714         buslogic_printk("buslogic_queuecommand: status: ");
 715         buslogic_stat(SCpnt->host->io_port);
 716 #endif
 717     } else
 718         buslogic_printk("buslogic_queuecommand: done can't be NULL\n");
 719 
 720     return 0;
 721 }
 722 
 723 #if 0
 724 static void internal_done(Scsi_Cmnd *SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 725 {
 726     SCpnt->SCp.Status++;
 727 }
 728 
 729 int buslogic_command(Scsi_Cmnd *SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 730 {
 731 #if BUSLOGIC_DEBUG
 732     buslogic_printk("buslogic_command: ..calling buslogic_queuecommand\n");
 733 #endif
 734 
 735     buslogic_queuecommand(SCpnt, internal_done);
 736 
 737     SCpnt->SCp.Status = 0;
 738     while (!SCpnt->SCp.Status)
 739         continue;
 740     return SCpnt->result;
 741     return internal_done_errcode;
 742 }
 743 #endif
 744 
 745 /* Initialize mailboxes. */
 746 static int setup_mailboxes(unsigned int base, struct Scsi_Host *SHpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 747 {
 748     size_t i;
 749     int ok = FALSE;             /* Innocent until proven guilty... */
 750     struct mailbox *mb = HOSTDATA(SHpnt)->mb;
 751     struct ccb *ccb = HOSTDATA(SHpnt)->ccbs;
 752     struct {
 753         unsigned char cmd, count;
 754         void *base PACKED;
 755     } cmd = { CMD_INITEXTMB, BUSLOGIC_MAILBOXES, mb };
 756 
 757     for (i = 0; i < BUSLOGIC_MAILBOXES; i++) {
 758         mb[i].status = mb[BUSLOGIC_MAILBOXES + i].status = MBX_NOT_IN_USE;
 759         mb[i].ccbptr = &ccb[i];
 760     }
 761     INTR_RESET(base);   /* reset interrupts, so they don't block */
 762 
 763     /* If this fails, this must be an Adaptec board */
 764     if (buslogic_out(base, (unsigned char *)&cmd, sizeof cmd))
 765         goto must_be_adaptec;
 766 
 767     /* Wait until host adapter is done messing around, and then check to see
 768        if the command was accepted.  If it failed, this must be an Adaptec
 769        board. */
 770     WAIT_UNTIL(STATUS(base), HARDY);
 771     if (inb(STATUS(base)) & CMDINV)
 772         goto must_be_adaptec;
 773 
 774     WAIT_UNTIL(INTERRUPT(base), CMDC);
 775     while (0) {
 776       fail:
 777         buslogic_printk("buslogic_detect: failed setting up mailboxes\n");
 778     }
 779     ok = TRUE;
 780     return ok;
 781   must_be_adaptec:
 782     INTR_RESET(base);
 783     printk("- must be Adaptec\n"); /* So that the adaptec detect looks clean */
 784     return ok;
 785 }
 786 
 787 static int getconfig(unsigned int base, unsigned char *irq,
     /* [previous][next][first][last][top][bottom][index][help] */
 788                      unsigned char *dma, unsigned char *id,
 789                      unsigned char *bus_type, unsigned short *max_sg)
 790 {
 791     unsigned char inquiry_cmd[2];
 792     unsigned char inquiry_result[4];
 793     int i;
 794 
 795     i = inb(STATUS(base));
 796     if (i & DIRRDY)
 797         i = inb(DATA_IN(base));
 798     inquiry_cmd[0] = CMD_RETCONF;
 799     buslogic_out(base, inquiry_cmd, 1);
 800     buslogic_in(base, inquiry_result, 3);
 801     WAIT_UNTIL(INTERRUPT(base), CMDC);
 802     INTR_RESET(base);
 803     /* Defer using the DMA value until we know the bus type. */
 804     *dma = inquiry_result[0];
 805     switch (inquiry_result[1]) {
 806       case 0x01:
 807         *irq = 9;
 808         break;
 809       case 0x02:
 810         *irq = 10;
 811         break;
 812       case 0x04:
 813         *irq = 11;
 814         break;
 815       case 0x08:
 816         *irq = 12;
 817         break;
 818       case 0x20:
 819         *irq = 14;
 820         break;
 821       case 0x40:
 822         *irq = 15;
 823         break;
 824       default:
 825         buslogic_printk("Unable to determine BusLogic IRQ level.  Disabling board.\n");
 826         return TRUE;
 827     }
 828     *id = inquiry_result[2] & 0x7;
 829 
 830     inquiry_cmd[0] = CMD_INQEXTSETUP;
 831     inquiry_cmd[1] = 4;
 832     if (buslogic_out(base, inquiry_cmd, 2)
 833         || buslogic_in(base, inquiry_result, 4))
 834         return TRUE;
 835     WAIT_UNTIL(INTERRUPT(base), CMDC);
 836     INTR_RESET(base);
 837 
 838 #ifdef BUSLOGIC_BUS_TYPE_OVERRIDE
 839     *bus_type = BUS_TYPE_OVERRIDE;
 840 #else
 841     *bus_type = inquiry_result[0];
 842 #endif
 843     CHECK(*bus_type == 'A' || *bus_type == 'E' || *bus_type == 'M');
 844 #ifdef BUSLOGIC_BUS_TYPE_OVERRIDE
 845     if (inquiry_result[0] != BUS_TYPE_OVERRIDE)
 846         buslogic_printk("Overriding bus type %c with %c\n",
 847                         inquiry_result[0], BUS_TYPE_OVERRIDE);
 848 #endif
 849     *max_sg = (inquiry_result[3] << 8) | inquiry_result[2];
 850 
 851     /* We only need a DMA channel for ISA boards.  Some other types of boards
 852        (such as the 747S) have an option to report a DMA channel even though
 853        none is used (for compatability with Adaptec drivers which require a
 854        DMA channel).  We ignore this. */
 855     if (*bus_type == 'A')
 856         switch (*dma) {
 857           case 0:       /* This indicates a that no DMA channel is used. */
 858             *dma = 0;
 859             break;
 860           case 0x20:
 861             *dma = 5;
 862             break;
 863           case 0x40:
 864             *dma = 6;
 865             break;
 866           case 0x80:
 867             *dma = 7;
 868             break;
 869           default:
 870             buslogic_printk("Unable to determine BusLogic DMA channel.  Disabling board.\n");
 871             return TRUE;
 872         }
 873     else
 874         *dma = 0;
 875 
 876     while (0) {
 877       fail:
 878         buslogic_printk("buslogic_detect: query board settings\n");
 879         return TRUE;
 880     }
 881 
 882     return FALSE;
 883 }
 884 
 885 /* Query the board to find out the model. */
 886 static int buslogic_query(unsigned int base, int *trans)
     /* [previous][next][first][last][top][bottom][index][help] */
 887 {
 888     unsigned const char inquiry_cmd[] = { CMD_INQUIRY };
 889     unsigned char inquiry_result[4];
 890     int i;
 891 
 892     i = inb(STATUS(base));
 893     if (i & DIRRDY)
 894         i = inb(DATA_IN(base));
 895     buslogic_out(base, inquiry_cmd, sizeof inquiry_cmd);
 896     buslogic_in(base, inquiry_result, 4);
 897     WAIT_UNTIL(INTERRUPT(base), CMDC);
 898     INTR_RESET(base);
 899 
 900     buslogic_printk("Inquiry Bytes: %X %X %X %X\n",
 901                     inquiry_result[0],inquiry_result[1],
 902                     inquiry_result[2],inquiry_result[3]);
 903     while (0) {
 904       fail:
 905         buslogic_printk("buslogic_query: query board settings\n");
 906         return TRUE;
 907     }
 908 
 909     *trans = BIOS_TRANSLATION_6432;     /* Default case */
 910 
 911     return FALSE;
 912 }
 913 
 914 /* return non-zero on detection */
 915 int buslogic_detect(Scsi_Host_Template * tpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 916 {
 917     unsigned char dma;
 918     unsigned char irq;
 919     unsigned int base = 0;
 920     unsigned char id;
 921     unsigned char bus_type;
 922     unsigned short max_sg;
 923     int trans;
 924     struct Scsi_Host *SHpnt = NULL;
 925     int count = 0;
 926     int indx;
 927     int val;
 928 
 929 #if BUSLOGIC_DEBUG
 930     buslogic_printk("buslogic_detect:\n");
 931 #endif
 932 
 933     for (indx = 0; indx < ARRAY_SIZE(bases); indx++)
 934         if (!check_region(bases[indx], 3)) {
 935             SHpnt = scsi_register(tpnt, sizeof (struct hostdata));
 936 
 937             base = bases[indx];
 938 
 939             if (test_port(base, SHpnt))
 940                 goto unregister;
 941 
 942             /* Set the Bus on/off-times as not to ruin floppy performance. */
 943             {
 944                 /* The default ON/OFF times for BusLogic adapters is 7/4. */
 945                 static const unsigned char oncmd[] = { CMD_BUSON_TIME, 7 };
 946                 static const unsigned char offcmd[] = { CMD_BUSOFF_TIME, 5 };
 947 
 948                 INTR_RESET(base);
 949                 buslogic_out(base, oncmd, sizeof oncmd);
 950                 WAIT_UNTIL(INTERRUPT(base), CMDC);
 951                 /* CMD_BUSOFF_TIME is a noop for EISA boards, but as there is
 952                    no way to to differentiate EISA from VESA we send it
 953                    unconditionally. */
 954                 INTR_RESET(base);
 955                 buslogic_out(base, offcmd, sizeof offcmd);
 956                 WAIT_UNTIL(INTERRUPT(base), CMDC);
 957                 while (0) {
 958                   fail:
 959                     buslogic_printk("buslogic_detect: setting bus on/off-time failed\n");
 960                 }
 961                 INTR_RESET(base);
 962             }
 963 
 964             if (buslogic_query(base, &trans))
 965                 goto unregister;
 966 
 967             if (getconfig(base, &irq, &dma, &id, &bus_type, &max_sg))
 968                 goto unregister;
 969 
 970 #if BUSLOGIC_DEBUG
 971             buslogic_stat(base);
 972 #endif
 973             /* Here is where we tell the men from the boys (i.e. an Adaptec
 974                will fail in setup_mailboxes, the men will not :-) */
 975             if (!setup_mailboxes(base, SHpnt))
 976                 goto unregister;
 977 
 978             printk("Configuring BusLogic %s HA at port 0x%03X, IRQ %u",
 979                    (bus_type == 'A' ? "ISA"
 980                     : (bus_type == 'E' ? "EISA/VESA" : "MCA")),
 981                    base, irq);
 982             if (dma != 0)
 983                 printk(", DMA %u", dma);
 984             printk(", ID %u\n", id);
 985 
 986 #if BUSLOGIC_DEBUG
 987             buslogic_stat(base);
 988 #endif
 989 
 990 #if BUSLOGIC_DEBUG
 991             buslogic_printk("buslogic_detect: enable interrupt channel %d\n",
 992                             irq);
 993 #endif
 994 
 995             cli();
 996             val = request_irq(irq, buslogic_interrupt);
 997             if (val) {
 998                 buslogic_printk("Unable to allocate IRQ for "
 999                                 "BusLogic controller.\n");
1000                 sti();
1001                 goto unregister;
1002             }
1003 
1004             if (dma) {
1005                 if (request_dma(dma)) {
1006                     buslogic_printk("Unable to allocate DMA channel for "
1007                                     "BusLogic controller.\n");
1008                     free_irq(irq);
1009                     sti();
1010                     goto unregister;
1011                 }
1012 
1013                 if (dma >= 5) {
1014                     outb((dma - 4) | CASCADE, DMA_MODE_REG);
1015                     outb(dma - 4, DMA_MASK_REG);
1016                 }
1017             }
1018 
1019             host[irq - 9] = SHpnt;
1020             SHpnt->this_id = id;
1021 #ifdef CONFIG_NO_BUGGY_BUSLOGIC
1022             /* Only type 'A' (AT/ISA) bus adapters use unchecked DMA. */
1023             SHpnt->unchecked_isa_dma = (bus_type == 'A');
1024 #else
1025             /* bugs in the firmware with 16M+. Gaah */
1026             SHpnt->unchecked_isa_dma = 1;
1027 #endif
1028             SHpnt->sg_tablesize = max_sg;
1029             if (SHpnt->sg_tablesize > BUSLOGIC_MAX_SG)
1030                 SHpnt->sg_tablesize = BUSLOGIC_MAX_SG;
1031             /* ??? If we can dynamically allocate the mailbox arrays, I'll
1032                probably bump up this number. */
1033             SHpnt->hostt->can_queue = BUSLOGIC_MAILBOXES;
1034             /*SHpnt->base = ???;*/
1035             SHpnt->io_port = base;
1036             SHpnt->dma_channel = dma;
1037             SHpnt->irq = irq;
1038             HOSTDATA(SHpnt)->bios_translation = trans;
1039             if (trans == BIOS_TRANSLATION_25563)
1040                 buslogic_printk("Using extended bios translation.\n");
1041             HOSTDATA(SHpnt)->last_mbi_used  = 2 * BUSLOGIC_MAILBOXES - 1;
1042             HOSTDATA(SHpnt)->last_mbo_used  = BUSLOGIC_MAILBOXES - 1;
1043             memset(HOSTDATA(SHpnt)->SCint, 0, sizeof HOSTDATA(SHpnt)->SCint);
1044             sti();
1045 
1046 #if 0
1047             {
1048                 unsigned char buf[8];
1049                 unsigned char cmd[]
1050                     = { READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1051                 size_t i;
1052 
1053 #if BUSLOGIC_DEBUG
1054                 buslogic_printk("*** READ CAPACITY ***\n");
1055 #endif
1056                 for (i = 0; i < sizeof buf; i++)
1057                     buf[i] = 0x87;
1058                 for (i = 0; i < 2; i++)
1059                     if (!buslogic_command(i, cmd, buf, sizeof buf)) {
1060                         buslogic_printk("bus_detect: LU %u sector_size %d "
1061                                         "device_size %d\n",
1062                                         i, xscsi2int(buf + 4), xscsi2int(buf));
1063                     }
1064 
1065 #if BUSLOGIC_DEBUG
1066                 buslogic_printk("*** NOW RUNNING MY OWN TEST ***\n");
1067 #endif
1068                 for (i = 0; i < 4; i++) {
1069                     static buffer[512];
1070 
1071                     cmd[0] = READ_10;
1072                     cmd[1] = 0;
1073                     xany2scsi(cmd + 2, i);
1074                     cmd[6] = 0;
1075                     cmd[7] = 0;
1076                     cmd[8] = 1;
1077                     cmd[9] = 0;
1078                     buslogic_command(0, cmd, buffer, sizeof buffer);
1079                 }
1080             }
1081 #endif
1082 
1083             snarf_region(bases[indx], 3);       /* Register the IO ports that
1084                                                    we use */
1085             count++;
1086             continue;
1087           unregister:
1088             scsi_unregister(SHpnt);
1089         }
1090     return count;
1091 }
1092 
1093 /* ??? The abort command for the aha1542 does not leave the device in a clean
1094    state where it is available to be used again.  As it is not clear whether
1095    the same problem exists with BusLogic boards, we will enable this and see
1096    if it works. */
1097 int buslogic_abort(Scsi_Cmnd *SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
1098 {
1099     static const unsigned char buscmd[] = { CMD_START_SCSI };
1100     struct mailbox *mb;
1101     int mbi, mbo, i;
1102 
1103     buslogic_printk("buslogic_abort: %X %X\n",
1104                     inb(STATUS(SCpnt->host->io_port)),
1105                     inb(INTERRUPT(SCpnt->host->io_port)));
1106 
1107     cli();
1108     mb = HOSTDATA(SCpnt->host)->mb;
1109     mbi = HOSTDATA(SCpnt->host)->last_mbi_used + 1;
1110     if (mbi >= 2 * BUSLOGIC_MAILBOXES)
1111         mbi = BUSLOGIC_MAILBOXES;
1112 
1113     do {
1114         if (mb[mbi].status != MBX_NOT_IN_USE)
1115             break;
1116         mbi++;
1117         if (mbi >= 2 * BUSLOGIC_MAILBOXES)
1118             mbi = BUSLOGIC_MAILBOXES;
1119     } while (mbi != HOSTDATA(SCpnt->host)->last_mbi_used);
1120     sti();
1121 
1122     if (mb[mbi].status != MBX_NOT_IN_USE) {
1123         buslogic_printk("Lost interrupt discovered on irq %d - attempting to recover\n",
1124                         SCpnt->host->irq);
1125         {
1126             int intval[3];
1127 
1128             intval[0] = SCpnt->host->irq;
1129             buslogic_interrupt((int)&intval[2]);
1130             return SCSI_ABORT_SUCCESS;
1131         }
1132     }
1133 
1134     /* OK, no lost interrupt.  Try looking to see how many pending commands we
1135        think we have. */
1136     for (i = 0; i < BUSLOGIC_MAILBOXES; i++)
1137         if (HOSTDATA(SCpnt->host)->SCint[i]) {
1138             if (HOSTDATA(SCpnt->host)->SCint[i] == SCpnt) {
1139                 buslogic_printk("Timed out command pending for %4.4X\n",
1140                                 SCpnt->request.dev);
1141                 if (HOSTDATA(SCpnt->host)->mb[i].status != MBX_NOT_IN_USE) {
1142                     buslogic_printk("OGMB still full - restarting\n");
1143                     buslogic_out(SCpnt->host->io_port, buscmd, sizeof buscmd);
1144                 }
1145             } else
1146                 buslogic_printk("Other pending command %4.4X\n",
1147                                 SCpnt->request.dev);
1148         }
1149 
1150 #if (BUSLOGIC_DEBUG & BD_ABORT)
1151     buslogic_printk("buslogic_abort\n");
1152 #endif
1153 
1154 #if 1
1155     /* This section of code should be used carefully - some devices cannot
1156        abort a command, and this merely makes it worse. */
1157     cli();
1158     for (mbo = 0; mbo < BUSLOGIC_MAILBOXES; mbo++)
1159         if (SCpnt == HOSTDATA(SCpnt->host)->SCint[mbo]) {
1160             HOSTDATA(SCpnt->host)->mb[mbo].status = MBX_ACTION_ABORT;
1161             buslogic_out(SCpnt->host->io_port, buscmd, sizeof buscmd);
1162             break;
1163         }
1164     sti();
1165 #endif
1166 
1167     return SCSI_ABORT_PENDING;
1168 }
1169 
1170 /* We do not implement a reset function here, but the upper level code assumes
1171    that it will get some kind of response for the command in SCpnt.  We must
1172    oblige, or the command will hang the SCSI system. */
1173 int buslogic_reset(Scsi_Cmnd *SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
1174 {
1175 #if BUSLOGIC_DEBUG
1176     buslogic_printk("buslogic_reset\n");
1177 #endif
1178     return SCSI_RESET_PUNT;
1179 }
1180 
1181 int buslogic_biosparam(Disk * disk, int dev, int *ip)
     /* [previous][next][first][last][top][bottom][index][help] */
1182 {
1183   int size = disk->capacity;
1184   int translation_algorithm;
1185 
1186   /* ??? This is wrong if disk is configured for > 1G mapping.
1187      Unfortunately, unlike UltraStor, I see know way of determining whether
1188      > 1G mapping has been enabled. */
1189 
1190 
1191     translation_algorithm = HOSTDATA(disk->device->host)->bios_translation;
1192     /* ??? Should this be > 1024, or >= 1024?  Enquiring minds want to know. */
1193     if ((size >> 11) > 1024
1194         && translation_algorithm == BIOS_TRANSLATION_25563) {
1195         /* Please verify that this is the same as what DOS returns */
1196         ip[0] = 255;
1197         ip[1] = 63;
1198         ip[2] = size / 255 / 63;
1199     } else {
1200         ip[0] = 64;
1201         ip[1] = 32;
1202         ip[2] = size >> 11;
1203     }
1204 /*    if (ip[2] > 1024)
1205       ip[2] = 1024; */
1206     return 0;
1207 }

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