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

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