root/drivers/scsi/wd7000.c

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

DEFINITIONS

This source file includes following definitions.
  1. any2scsi
  2. scsi2int
  3. wd7000_enable_intr
  4. wd7000_enable_dma
  5. delay
  6. command_out
  7. alloc_scbs
  8. free_scb
  9. init_scbs
  10. mail_out
  11. make_code
  12. wd7000_scsi_done
  13. wd7000_intr_handle
  14. wd7000_queuecommand
  15. wd7000_command
  16. wd7000_diagnostics
  17. wd7000_init
  18. wd7000_revision
  19. wd7000_detect
  20. wd7000_abort
  21. wd7000_reset
  22. wd7000_biosparam

   1 /* $Id: $
   2  *  linux/drivers/scsi/wd7000.c
   3  *
   4  *  Copyright (C) 1992  Thomas Wuensche
   5  *      closely related to the aha1542 driver from Tommy Thorn
   6  *      ( as close as different hardware allows on a lowlevel-driver :-) )
   7  *
   8  *  Revised (and renamed) by John Boyd <boyd@cis.ohio-state.edu> to
   9  *  accommodate Eric Youngdale's modifications to scsi.c.  Nov 1992.
  10  *
  11  *  Additional changes to support scatter/gather.  Dec. 1992.  tw/jb
  12  *
  13  *  No longer tries to reset SCSI bus at boot (it wasn't working anyway).
  14  *  Rewritten to support multiple host adapters.
  15  *  Miscellaneous cleanup.
  16  *  So far, still doesn't do reset or abort correctly, since I have no idea
  17  *  how to do them with this board (8^(.                      Jan 1994 jb
  18  *
  19  * This driver now supports both of the two standard configurations (per
  20  * the 3.36 Owner's Manual, my latest reference) by the same method as
  21  * before; namely, by looking for a BIOS signature.  Thus, the location of
  22  * the BIOS signature determines the board configuration.  Until I have
  23  * time to do something more flexible, users should stick to one of the
  24  * following:
  25  *
  26  * Standard configuration for single-adapter systems:
  27  *    - BIOS at CE00h
  28  *    - I/O base address 350h
  29  *    - IRQ level 15
  30  *    - DMA channel 6
  31  * Standard configuration for a second adapter in a system:
  32  *    - BIOS at C800h
  33  *    - I/O base address 330h
  34  *    - IRQ level 11
  35  *    - DMA channel 5
  36  *
  37  * Anyone who can recompile the kernel is welcome to add others as need
  38  * arises, but unpredictable results may occur if there are conflicts.
  39  * In any event, if there are multiple adapters in a system, they MUST
  40  * use different I/O bases, IRQ levels, and DMA channels, since they will be
  41  * indistinguishable (and in direct conflict) otherwise.
  42  *
  43  *   As a point of information, the NO_OP command toggles the CMD_RDY bit
  44  * of the status port, and this fact could be used as a test for the I/O
  45  * base address (or more generally, board detection).  There is an interrupt
  46  * status port, so IRQ probing could also be done.  I suppose the full
  47  * DMA diagnostic could be used to detect the DMA channel being used.  I
  48  * haven't done any of this, though, because I think there's too much of
  49  * a chance that such explorations could be destructive, if some other
  50  * board's resources are used inadvertently.  So, call me a wimp, but I
  51  * don't want to try it.  The only kind of exploration I trust is memory
  52  * exploration, since it's more certain that reading memory won't be
  53  * destructive.
  54  *
  55  * More to my liking would be a LILO boot command line specification, such
  56  * as is used by the aha152x driver (and possibly others).  I'll look into
  57  * it, as I have time...
  58  *
  59  *   I get mail occasionally from people who either are using or are
  60  * considering using a WD7000 with Linux.  There is a variety of
  61  * nomenclature describing WD7000's.  To the best of my knowledge, the
  62  * following is a brief summary (from an old WD doc - I don't work for
  63  * them or anything like that):
  64  *
  65  * WD7000-FASST2: This is a WD7000 board with the real-mode SST ROM BIOS
  66  *        installed.  Last I heard, the BIOS was actually done by Columbia
  67  *        Data Products.  The BIOS is only used by this driver (and thus
  68  *        by Linux) to identify the board; none of it can be executed under
  69  *        Linux.
  70  *
  71  * WD7000-ASC: This is the original adapter board, with or without BIOS.
  72  *        The board uses a WD33C93 or WD33C93A SBIC, which in turn is
  73  *        controlled by an onboard Z80 processor.  The board interface
  74  *        visible to the host CPU is defined effectively by the Z80's
  75  *        firmware, and it is this firmware's revision level that is
  76  *        determined and reported by this driver.  (The version of the
  77  *        on-board BIOS is of no interest whatsoever.)  The host CPU has
  78  *        no access to the SBIC; hence the fact that it is a WD33C93 is
  79  *        also of no interest to this driver.
  80  *
  81  * WD7000-AX:
  82  * WD7000-MX:
  83  * WD7000-EX: These are newer versions of the WD7000-ASC.  The -ASC is
  84  *        largely built from discrete components; these boards use more
  85  *        integration.  The -AX is an ISA bus board (like the -ASC),
  86  *        the -MX is an MCA (i.e., PS/2) bus board), and the -EX is an
  87  *        EISA bus board.
  88  *
  89  *  At the time of my documentation, the -?X boards were "future" products,
  90  *  and were not yet available.  However, I vaguely recall that Thomas
  91  *  Wuensche had an -AX, so I believe at least it is supported by this
  92  *  driver.  I have no personal knowledge of either -MX or -EX boards.
  93  *
  94  *  P.S. Just recently, I've discovered (directly from WD and Future
  95  *  Domain) that all but the WD7000-EX have been out of production for
  96  *  two years now.  FD has production rights to the 7000-EX, and are
  97  *  producing it under a new name, and with a new BIOS.  If anyone has
  98  *  one of the FD boards, it would be nice to come up with a signature
  99  *  for it.
 100  *                                                           J.B. Jan 1994.
 101  */
 102 
 103 #include <stdarg.h>
 104 #include <linux/kernel.h>
 105 #include <linux/head.h>
 106 #include <linux/types.h>
 107 #include <linux/string.h>
 108 #include <linux/sched.h>
 109 #include <linux/malloc.h>
 110 #include <asm/system.h>
 111 #include <asm/dma.h>
 112 #include <asm/io.h>
 113 #include <linux/ioport.h>
 114 
 115 #include "../block/blk.h"
 116 #include "scsi.h"
 117 #include "hosts.h"
 118 #include "sd.h"
 119 
 120 #define ANY2SCSI_INLINE    /* undef this to use old macros */
 121 #undef DEBUG
 122 
 123 #include "wd7000.h"
 124 
 125 
 126 /*
 127  *  Mailbox structure sizes.
 128  *  I prefer to keep the number of ICMBs much larger than the number of
 129  *  OGMBs.  OGMBs are used very quickly by the driver to start one or
 130  *  more commands, while ICMBs are used by the host adapter per command.
 131  */
 132 #define OGMB_CNT        16
 133 #define ICMB_CNT        32
 134 
 135 /*
 136  *  Scb's are shared by all active adapters.  So, if they all become busy,
 137  *  callers may be made to wait in alloc_scbs for them to free.  That can
 138  *  be avoided by setting MAX_SCBS to NUM_CONFIG * WD7000_Q.  If you'd
 139  *  rather conserve memory, use a smaller number (> 0, of course) - things
 140  *  will should still work OK.
 141  */
 142 #define MAX_SCBS        32
 143 
 144 /*
 145  *  WD7000-specific mailbox structure
 146  *
 147  */
 148 typedef volatile struct mailbox{
 149   unchar status;
 150   unchar scbptr[3];             /* SCSI-style - MSB first (big endian) */
 151 } Mailbox;
 152 
 153 /*
 154  *  This structure should contain all per-adapter global data.  I.e., any
 155  *  new global per-adapter data should put in here.
 156  *
 157  */
 158 typedef struct adapter {
 159   struct Scsi_Host *sh;             /* Pointer to Scsi_Host structure */
 160   int iobase;                       /* This adapter's I/O base address */
 161   int irq;                          /* This adapter's IRQ level */
 162   int dma;                          /* This adapter's DMA channel */
 163   struct {                          /* This adapter's mailboxes */
 164     Mailbox ogmb[OGMB_CNT];             /* Outgoing mailboxes */
 165     Mailbox icmb[ICMB_CNT];             /* Incoming mailboxes */
 166   } mb;
 167   int next_ogmb;                    /* to reduce contention at mailboxes */
 168   unchar control;                   /* shadows CONTROL port value */
 169   unchar rev1, rev2;                /* filled in by wd7000_revision */
 170 } Adapter;
 171 
 172 /*
 173  * The following is set up by wd7000_detect, and used thereafter by
 174  * wd7000_intr_handle to map the irq level to the corresponding Adapter.
 175  * Note that if SA_INTERRUPT is not used, wd7000_intr_handle must be
 176  * changed to pick up the IRQ level correctly.
 177  */
 178 Adapter *irq2host[16] = {NULL};  /* Possible IRQs are 0-15 */
 179 
 180 /*
 181  *  Standard Adapter Configurations - used by wd7000_detect
 182  */
 183 typedef struct {
 184   const void *bios;             /* (linear) base address for ROM BIOS */
 185   int iobase;                   /* I/O ports base address */
 186   int irq;                      /* IRQ level */
 187   int dma;                      /* DMA channel */
 188 } Config;
 189 
 190 static const Config configs[] = {
 191   {(void *) 0xce000, 0x350, 15, 6},  /* defaults for single adapter */
 192   {(void *) 0xc8000, 0x330, 11, 5},  /* defaults for second adapter */
 193   {(void *) 0xd8000, 0x350, 15, 6},  /* Arghhh.... who added this ? */
 194 };
 195 #define NUM_CONFIGS (sizeof(configs)/sizeof(Config))
 196 
 197 /*
 198  *  The following list defines strings to look for in the BIOS that identify
 199  *  it as the WD7000-FASST2 SST BIOS.  I suspect that something should be
 200  *  added for the Future Domain version.
 201  */
 202 typedef struct signature {
 203     void    *sig;           /* String to look for */
 204     unsigned ofs;           /* offset from BIOS base address */
 205     unsigned len;           /* length of string */
 206 } Signature;
 207 
 208 static const Signature signatures[] = {
 209   {"SSTBIOS",0x0000d,7}                  /* "SSTBIOS" @ offset 0x0000d */
 210 };
 211 #define NUM_SIGNATURES (sizeof(signatures)/sizeof(Signature))
 212 
 213 
 214 /*
 215  *  I/O Port Offsets and Bit Definitions
 216  *  4 addresses are used.  Those not defined here are reserved.
 217  */
 218 #define ASC_STAT        0       /* Status,  Read */
 219 #define ASC_COMMAND     0       /* Command, Write */
 220 #define ASC_INTR_STAT   1       /* Interrupt Status, Read */
 221 #define ASC_INTR_ACK    1       /* Acknowledge, Write */
 222 #define ASC_CONTROL     2       /* Control, Write */
 223 
 224 /* ASC Status Port
 225  */
 226 #define INT_IM          0x80            /* Interrupt Image Flag */
 227 #define CMD_RDY         0x40            /* Command Port Ready */
 228 #define CMD_REJ         0x20            /* Command Port Byte Rejected */
 229 #define ASC_INIT        0x10            /* ASC Initialized Flag */
 230 #define ASC_STATMASK    0xf0            /* The lower 4 Bytes are reserved */
 231 
 232 /* COMMAND opcodes
 233  *
 234  *  Unfortunately, I have no idea how to properly use some of these commands,
 235  *  as the OEM manual does not make it clear.  I have not been able to use
 236  *  enable/disable unsolicited interrupts or the reset commands with any
 237  *  discernible effect whatsoever.  I think they may be related to certain
 238  *  ICB commands, but again, the OEM manual doesn't make that clear.
 239  */
 240 #define NO_OP             0     /* NO-OP toggles CMD_RDY bit in ASC_STAT */
 241 #define INITIALIZATION    1     /* initialization (10 bytes) */
 242 #define DISABLE_UNS_INTR  2     /* disable unsolicited interrupts */
 243 #define ENABLE_UNS_INTR   3     /* enable unsolicited interrupts */
 244 #define INTR_ON_FREE_OGMB 4     /* interrupt on free OGMB */
 245 #define SOFT_RESET        5     /* SCSI bus soft reset */
 246 #define HARD_RESET_ACK    6     /* SCSI bus hard reset acknowledge */
 247 #define START_OGMB        0x80  /* start command in OGMB (n) */
 248 #define SCAN_OGMBS        0xc0  /* start multiple commands, signature (n) */
 249                                 /*    where (n) = lower 6 bits */
 250 /* For INITIALIZATION:
 251  */
 252 typedef struct initCmd {
 253   unchar op;                   /* command opcode (= 1) */
 254   unchar ID;                   /* Adapter's SCSI ID */
 255   unchar bus_on;               /* Bus on time, x 125ns (see below) */
 256   unchar bus_off;              /* Bus off time, ""         ""      */
 257   unchar rsvd;                 /* Reserved */
 258   unchar mailboxes[3];         /* Address of Mailboxes, MSB first  */
 259   unchar ogmbs;                /* Number of outgoing MBs, max 64, 0,1 = 1 */
 260   unchar icmbs;                /* Number of incoming MBs,   ""       ""   */
 261 } InitCmd;
 262 
 263 #define BUS_ON            64    /* x 125ns = 8000ns (BIOS default) */
 264 #define BUS_OFF           15    /* x 125ns = 1875ns (BIOS default) */
 265  
 266 /* Interrupt Status Port - also returns diagnostic codes at ASC reset
 267  *
 268  * if msb is zero, the lower bits are diagnostic status
 269  * Diagnostics:
 270  * 01   No diagnostic error occurred
 271  * 02   RAM failure
 272  * 03   FIFO R/W failed
 273  * 04   SBIC register read/write failed
 274  * 05   Initialization D-FF failed
 275  * 06   Host IRQ D-FF failed
 276  * 07   ROM checksum error
 277  * Interrupt status (bitwise):
 278  * 10NNNNNN   outgoing mailbox NNNNNN is free
 279  * 11NNNNNN   incoming mailbox NNNNNN needs service
 280  */
 281 #define MB_INTR  0xC0           /* Mailbox Service possible/required */
 282 #define IMB_INTR 0x40           /* 1 Incoming / 0 Outgoing */
 283 #define MB_MASK  0x3f           /* mask for mailbox number */
 284 
 285 /* CONTROL port bits
 286  */
 287 #define INT_EN          0x08    /* Interrupt Enable     */
 288 #define DMA_EN          0x04    /* DMA Enable           */
 289 #define SCSI_RES        0x02    /* SCSI Reset           */
 290 #define ASC_RES         0x01    /* ASC Reset            */
 291 
 292 /*
 293    Driver data structures:
 294    - mb and scbs are required for interfacing with the host adapter.
 295      An SCB has extra fields not visible to the adapter; mb's
 296      _cannot_ do this, since the adapter assumes they are contiguous in
 297      memory, 4 bytes each, with ICMBs following OGMBs, and uses this fact
 298      to access them.
 299    - An icb is for host-only (non-SCSI) commands.  ICBs are 16 bytes each;
 300      the additional bytes are used only by the driver.
 301    - For now, a pool of SCBs are kept in global storage by this driver,
 302      and are allocated and freed as needed.
 303 
 304   The 7000-FASST2 marks OGMBs empty as soon as it has _started_ a command,
 305   not when it has finished.  Since the SCB must be around for completion,
 306   problems arise when SCBs correspond to OGMBs, which may be reallocated
 307   earlier (or delayed unnecessarily until a command completes).
 308   Mailboxes are used as transient data structures, simply for
 309   carrying SCB addresses to/from the 7000-FASST2.
 310 
 311   Note also since SCBs are not "permanently" associated with mailboxes,
 312   there is no need to keep a global list of Scsi_Cmnd pointers indexed
 313   by OGMB.   Again, SCBs reference their Scsi_Cmnds directly, so mailbox
 314   indices need not be involved.
 315 */
 316 
 317 /*
 318  *  WD7000-specific scatter/gather element structure
 319  */
 320 typedef struct sgb {
 321     unchar len[3];
 322     unchar ptr[3];              /* Also SCSI-style - MSB first */
 323 } Sgb;
 324 
 325 typedef struct scb {            /* Command Control Block 5.4.1 */
 326   unchar op;                    /* Command Control Block Operation Code */
 327   unchar idlun;                 /* op=0,2:Target Id, op=1:Initiator Id */
 328                                 /* Outbound data transfer, length is checked*/
 329                                 /* Inbound data transfer, length is checked */
 330                                 /* Logical Unit Number */
 331   unchar cdb[12];               /* SCSI Command Block */
 332   volatile unchar status;       /* SCSI Return Status */
 333   volatile unchar vue;          /* Vendor Unique Error Code */
 334   unchar maxlen[3];             /* Maximum Data Transfer Length */
 335   unchar dataptr[3];            /* SCSI Data Block Pointer */
 336   unchar linkptr[3];            /* Next Command Link Pointer */
 337   unchar direc;                 /* Transfer Direction */
 338   unchar reserved2[6];          /* SCSI Command Descriptor Block */
 339                                 /* end of hardware SCB */
 340   Scsi_Cmnd *SCpnt;             /* Scsi_Cmnd using this SCB */
 341   Sgb sgb[WD7000_SG];           /* Scatter/gather list for this SCB */
 342   Adapter *host;                /* host adapter */
 343   struct scb *next;             /* for lists of scbs */
 344 } Scb;
 345 
 346 /*
 347  *  This driver is written to allow host-only commands to be executed.
 348  *  These use a 16-byte block called an ICB.  The format is extended by the
 349  *  driver to 18 bytes, to support the status returned in the ICMB and
 350  *  an execution phase code.
 351  *
 352  *  There are other formats besides these; these are the ones I've tried
 353  *  to use.  Formats for some of the defined ICB opcodes are not defined
 354  *  (notably, get/set unsolicited interrupt status) in my copy of the OEM
 355  *  manual, and others are ambiguous/hard to follow.
 356  */
 357 #define ICB_OP_MASK             0x80  /* distinguishes scbs from icbs */
 358 #define ICB_OP_OPEN_RBUF        0x80  /* open receive buffer */
 359 #define ICB_OP_RECV_CMD         0x81  /* receive command from initiator */
 360 #define ICB_OP_RECV_DATA        0x82  /* receive data from initiator */
 361 #define ICB_OP_RECV_SDATA       0x83  /* receive data with status from init. */
 362 #define ICB_OP_SEND_DATA        0x84  /* send data with status to initiator */
 363 #define ICB_OP_SEND_STAT        0x86  /* send command status to initiator */
 364                              /* 0x87 is reserved */
 365 #define ICB_OP_READ_INIT        0x88  /* read initialization bytes */
 366 #define ICB_OP_READ_ID          0x89  /* read adapter's SCSI ID */
 367 #define ICB_OP_SET_UMASK        0x8A  /* set unsolicited interrupt mask */
 368 #define ICB_OP_GET_UMASK        0x8B  /* read unsolicited interrupt mask */
 369 #define ICB_OP_GET_REVISION     0x8C  /* read firmware revision level */
 370 #define ICB_OP_DIAGNOSTICS      0x8D  /* execute diagnostics */
 371 #define ICB_OP_SET_EPARMS       0x8E  /* set execution parameters */
 372 #define ICB_OP_GET_EPARMS       0x8F  /* read execution parameters */
 373 
 374 typedef struct icbRecvCmd {
 375   unchar op;
 376   unchar IDlun;                 /* Initiator SCSI ID/lun */
 377   unchar len[3];                /* command buffer length */
 378   unchar ptr[3];                /* command buffer address */
 379   unchar rsvd[7];               /* reserved */
 380   volatile unchar vue;          /* vendor-unique error code */
 381   volatile unchar status;       /* returned (icmb) status */
 382   volatile unchar phase;        /* used by interrupt handler */
 383 } IcbRecvCmd;
 384 
 385 typedef struct icbSendStat {
 386   unchar op;
 387   unchar IDlun;                 /* Target SCSI ID/lun */
 388   unchar stat;                  /* (outgoing) completion status byte 1 */
 389   unchar rsvd[12];              /* reserved */
 390   volatile unchar vue;          /* vendor-unique error code */
 391   volatile unchar status;       /* returned (icmb) status */
 392   volatile unchar phase;        /* used by interrupt handler */
 393 } IcbSendStat;
 394 
 395 typedef struct icbRevLvl {
 396   unchar op;
 397   volatile unchar primary;      /* primary revision level (returned) */
 398   volatile unchar secondary;    /* secondary revision level (returned) */
 399   unchar rsvd[12];              /* reserved */
 400   volatile unchar vue;          /* vendor-unique error code */
 401   volatile unchar status;       /* returned (icmb) status */
 402   volatile unchar phase;        /* used by interrupt handler */
 403 } IcbRevLvl;
 404 
 405 typedef struct icbUnsMask {     /* I'm totally guessing here */
 406   unchar op;
 407   volatile unchar mask[14];     /* mask bits */
 408 #ifdef 0
 409   unchar rsvd[12];              /* reserved */
 410 #endif
 411   volatile unchar vue;          /* vendor-unique error code */
 412   volatile unchar status;       /* returned (icmb) status */
 413   volatile unchar phase;        /* used by interrupt handler */
 414 } IcbUnsMask;
 415 
 416 typedef struct icbDiag {
 417   unchar op;
 418   unchar type;                  /* diagnostics type code (0-3) */
 419   unchar len[3];                /* buffer length */
 420   unchar ptr[3];                /* buffer address */
 421   unchar rsvd[7];               /* reserved */
 422   volatile unchar vue;          /* vendor-unique error code */
 423   volatile unchar status;       /* returned (icmb) status */
 424   volatile unchar phase;        /* used by interrupt handler */
 425 } IcbDiag;
 426 
 427 #define ICB_DIAG_POWERUP        0     /* Power-up diags only */
 428 #define ICB_DIAG_WALKING        1     /* walking 1's pattern */
 429 #define ICB_DIAG_DMA            2     /* DMA - system memory diags */
 430 #define ICB_DIAG_FULL           3     /* do both 1 & 2 */
 431 
 432 typedef struct icbParms {
 433   unchar op;
 434   unchar rsvd1;                 /* reserved */
 435   unchar len[3];                /* parms buffer length */
 436   unchar ptr[3];                /* parms buffer address */
 437   unchar idx[2];                /* index (MSB-LSB) */
 438   unchar rsvd2[5];              /* reserved */
 439   volatile unchar vue;          /* vendor-unique error code */
 440   volatile unchar status;       /* returned (icmb) status */
 441   volatile unchar phase;        /* used by interrupt handler */
 442 } IcbParms;
 443 
 444 typedef struct icbAny {
 445   unchar op;
 446   unchar data[14];              /* format-specific data */
 447   volatile unchar vue;          /* vendor-unique error code */
 448   volatile unchar status;       /* returned (icmb) status */
 449   volatile unchar phase;        /* used by interrupt handler */
 450 } IcbAny;
 451 
 452 typedef union icb {
 453   unchar op;                    /* ICB opcode */
 454   IcbRecvCmd recv_cmd;          /* format for receive command */
 455   IcbSendStat send_stat;        /* format for send status */
 456   IcbRevLvl rev_lvl;            /* format for get revision level */
 457   IcbDiag diag;                 /* format for execute diagnostics */
 458   IcbParms eparms;              /* format for get/set exec parms */
 459   IcbAny icb;                   /* generic format */
 460   unchar data[18];
 461 } Icb;
 462 
 463 
 464 /*
 465  *  Driver SCB structure pool.
 466  *
 467  *  The SCBs declared here are shared by all host adapters; hence, this
 468  *  structure is not part of the Adapter structure.
 469  */
 470 static Scb scbs[MAX_SCBS];
 471 static Scb *scbfree = NULL;      /* free list */
 472 static int freescbs = MAX_SCBS;  /* free list counter */
 473 
 474 /*
 475  *  END of data/declarations - code follows.
 476  */
 477 
 478 
 479 #ifdef ANY2SCSI_INLINE
 480 /*
 481    Since they're used a lot, I've redone the following from the macros
 482    formerly in wd7000.h, hopefully to speed them up by getting rid of
 483    all the shifting (it may not matter; GCC might have done as well anyway).
 484 
 485    xany2scsi and xscsi2int were not being used, and are no longer defined.
 486    (They were simply 4-byte versions of these routines).
 487 */
 488 
 489 typedef union {  /* let's cheat... */
 490   int i;
 491   unchar u[sizeof(int)];  /* the sizeof(int) makes it more portable */
 492 } i_u;
 493 
 494 
 495 static inline void any2scsi( unchar *scsi, int any )
     /* [previous][next][first][last][top][bottom][index][help] */
 496 {
 497     *scsi++ = ((i_u) any).u[2];
 498     *scsi++ = ((i_u) any).u[1];
 499     *scsi++ = ((i_u) any).u[0];
 500 }
 501 
 502 
 503 static inline int scsi2int( unchar *scsi )
     /* [previous][next][first][last][top][bottom][index][help] */
 504 {
 505     i_u result;
 506 
 507     result.i = 0;  /* clears unused bytes */
 508     *(result.u+2) = *scsi++;
 509     *(result.u+1) = *scsi++;
 510       *(result.u) = *scsi++;
 511     return result.i;
 512 }
 513 #else
 514 /*
 515    These are the old ones - I've just moved them here...
 516 */
 517 #undef any2scsi
 518 #define any2scsi(up, p)                 \
 519 (up)[0] = (((unsigned long)(p)) >> 16);         \
 520 (up)[1] = ((unsigned long)(p)) >> 8;            \
 521 (up)[2] = ((unsigned long)(p));
 522 
 523 #undef scsi2int
 524 #define scsi2int(up) ( (((unsigned long)*(up)) << 16) + \
 525  (((unsigned long)(up)[1]) << 8) + ((unsigned long)(up)[2]) )
 526 #endif
 527 
 528     
 529 static inline void wd7000_enable_intr(Adapter *host)
     /* [previous][next][first][last][top][bottom][index][help] */
 530 {
 531     host->control |= INT_EN;
 532     outb(host->control, host->iobase+ASC_CONTROL);
 533 }
 534 
 535 
 536 static inline void wd7000_enable_dma(Adapter *host)
     /* [previous][next][first][last][top][bottom][index][help] */
 537 {
 538     host->control |= DMA_EN;
 539     outb(host->control,host->iobase+ASC_CONTROL);
 540     set_dma_mode(host->dma, DMA_MODE_CASCADE);
 541     enable_dma(host->dma);
 542 }
 543 
 544 
 545 #define WAITnexttimeout 200  /* 2 seconds */
 546 
 547 #define WAIT(port, mask, allof, noneof)                                 \
 548  { register volatile unsigned WAITbits;                                 \
 549    register unsigned long WAITtimeout = jiffies + WAITnexttimeout;      \
 550    while (1) {                                                          \
 551      WAITbits = inb(port) & (mask);                                     \
 552      if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
 553        break;                                                           \
 554      if (jiffies > WAITtimeout) goto fail;                              \
 555    }                                                                    \
 556  }
 557 
 558 
 559 static inline void delay( unsigned how_long )
     /* [previous][next][first][last][top][bottom][index][help] */
 560 {
 561      register unsigned long time = jiffies + how_long;
 562 
 563      while (jiffies < time);
 564 }
 565 
 566 
 567 static inline int command_out(Adapter *host, unchar *cmd, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 568 {
 569     WAIT(host->iobase+ASC_STAT,ASC_STATMASK,CMD_RDY,0);
 570     while (len--)  {
 571         do  {
 572             outb(*cmd, host->iobase+ASC_COMMAND);
 573             WAIT(host->iobase+ASC_STAT, ASC_STATMASK, CMD_RDY, 0);
 574         }  while (inb(host->iobase+ASC_STAT) & CMD_REJ);
 575         cmd++;
 576     }
 577     return 1;
 578 
 579 fail:
 580     printk("wd7000 command_out: WAIT failed(%d)\n", len+1);
 581     return 0;
 582 }
 583 
 584 
 585 /*
 586  *  This version of alloc_scbs is in preparation for supporting multiple
 587  *  commands per lun and command chaining, by queueing pending commands.
 588  *  We will need to allocate Scbs in blocks since they will wait to be
 589  *  executed so there is the possibility of deadlock otherwise.
 590  *  Also, to keep larger requests from being starved by smaller requests,
 591  *  we limit access to this routine with an internal busy flag, so that
 592  *  the satisfiability of a request is not dependent on the size of the
 593  *  request.
 594  */
 595 static inline Scb *alloc_scbs(int needed)
     /* [previous][next][first][last][top][bottom][index][help] */
 596 {
 597     register Scb *scb, *p;
 598     register unsigned long flags;
 599     register unsigned long timeout = jiffies + WAITnexttimeout;
 600     register unsigned long now;
 601     static int busy = 0;
 602     int i;
 603 
 604     if (needed <= 0)  return NULL;  /* sanity check */
 605 
 606     save_flags(flags);
 607     cli();
 608     while (busy)  { /* someone else is allocating */
 609         sti();  /* Yes this is really needed here */
 610         now = jiffies;  while (jiffies == now)  /* wait a jiffy */;
 611         cli();
 612     }
 613     busy = 1;          /* not busy now; it's our turn */
 614 
 615     while (freescbs < needed)  {
 616         timeout = jiffies + WAITnexttimeout;
 617         do {
 618             sti();      /* Yes this is really needed here */
 619             now = jiffies;   while (jiffies == now) /* wait a jiffy */;
 620             cli();
 621         }  while (freescbs < needed && jiffies <= timeout);
 622         /*
 623          *  If we get here with enough free Scbs, we can take them.
 624          *  Otherwise, we timed out and didn't get enough.
 625          */
 626         if (freescbs < needed)  {
 627             busy = 0;
 628             panic("wd7000: can't get enough free SCBs.\n");
 629             restore_flags(flags);
 630             return NULL;
 631         }
 632     }
 633     scb = scbfree;  freescbs -= needed;
 634     for (i = 0; i < needed; i++)  { p = scbfree;  scbfree = p->next; }
 635     p->next = NULL;
 636     
 637     busy = 0;   /* we're done */
 638 
 639     restore_flags(flags);
 640 
 641     return scb;
 642 }
 643 
 644 
 645 static inline void free_scb( Scb *scb )
     /* [previous][next][first][last][top][bottom][index][help] */
 646 {
 647     register unsigned long flags;
 648 
 649     save_flags(flags);
 650     cli();
 651 
 652     memset(scb, 0, sizeof(Scb));
 653     scb->next = scbfree;  scbfree = scb;
 654     freescbs++;
 655 
 656     restore_flags(flags);
 657 }
 658 
 659 
 660 static inline void init_scbs(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 661 {
 662     int i;
 663     unsigned long flags;
 664 
 665     save_flags(flags);
 666     cli();
 667 
 668     scbfree = &(scbs[0]);
 669     memset(scbs, 0, sizeof(scbs));
 670     for (i = 0;  i < MAX_SCBS-1;  i++)  {
 671       scbs[i].next = &(scbs[i+1]);  scbs[i].SCpnt = NULL;
 672     }
 673     scbs[MAX_SCBS-1].next = NULL;
 674     scbs[MAX_SCBS-1].SCpnt = NULL;
 675 
 676     restore_flags(flags);
 677 }    
 678     
 679 
 680 static int mail_out( Adapter *host, Scb *scbptr )
     /* [previous][next][first][last][top][bottom][index][help] */
 681 /*
 682  *  Note: this can also be used for ICBs; just cast to the parm type.
 683  */
 684 {
 685     register int i, ogmb;
 686     register unsigned long flags;
 687     unchar start_ogmb;
 688     Mailbox *ogmbs = host->mb.ogmb;
 689     int *next_ogmb = &(host->next_ogmb);
 690 #ifdef DEBUG
 691     printk("wd7000 mail_out: %06x",(unsigned int) scbptr);
 692 #endif
 693     /* We first look for a free outgoing mailbox */
 694     save_flags(flags);
 695     cli();
 696     ogmb = *next_ogmb;
 697     for (i = 0; i < OGMB_CNT; i++) {
 698         if (ogmbs[ogmb].status == 0)  {
 699 #ifdef DEBUG
 700             printk(" using OGMB %x",ogmb);
 701 #endif
 702             ogmbs[ogmb].status = 1;
 703             any2scsi((unchar *) ogmbs[ogmb].scbptr, (int) scbptr);
 704 
 705             *next_ogmb = (ogmb+1) % OGMB_CNT;
 706             break;
 707         }  else
 708             ogmb = (++ogmb) % OGMB_CNT;
 709     }
 710     restore_flags(flags);
 711 #ifdef DEBUG
 712     printk(", scb is %x",(unsigned int) scbptr);
 713 #endif
 714     if (i >= OGMB_CNT) {
 715         /*
 716          *  Alternatively, we might issue the "interrupt on free OGMB",
 717          *  and sleep, but it must be ensured that it isn't the init
 718          *  task running.  Instead, this version assumes that the caller
 719          *  will be persistent, and try again.  Since it's the adapter
 720          *  that marks OGMB's free, waiting even with interrupts off
 721          *  should work, since they are freed very quickly in most cases.
 722          */
 723         #ifdef DEBUG
 724         printk(", no free OGMBs.\n");
 725 #endif
 726         return 0;
 727     }
 728 
 729     wd7000_enable_intr(host); 
 730 
 731     start_ogmb = START_OGMB | ogmb;
 732     command_out( host, &start_ogmb, 1 );
 733 #ifdef DEBUG
 734     printk(", awaiting interrupt.\n");
 735 #endif
 736     return 1;
 737 }
 738 
 739 
 740 int make_code(unsigned hosterr, unsigned scsierr)
     /* [previous][next][first][last][top][bottom][index][help] */
 741 {   
 742 #ifdef DEBUG
 743     int in_error = hosterr;
 744 #endif
 745 
 746     switch ((hosterr>>8)&0xff){
 747         case 0: /* Reserved */
 748                 hosterr = DID_ERROR;
 749                 break;
 750         case 1: /* Command Complete, no errors */
 751                 hosterr = DID_OK;
 752                 break;
 753         case 2: /* Command complete, error logged in scb status (scsierr) */ 
 754                 hosterr = DID_OK;
 755                 break;
 756         case 4: /* Command failed to complete - timeout */
 757                 hosterr = DID_TIME_OUT;
 758                 break;
 759         case 5: /* Command terminated; Bus reset by external device */
 760                 hosterr = DID_RESET;
 761                 break;
 762         case 6: /* Unexpected Command Received w/ host as target */
 763                 hosterr = DID_BAD_TARGET;
 764                 break;
 765         case 80: /* Unexpected Reselection */
 766         case 81: /* Unexpected Selection */
 767                 hosterr = DID_BAD_INTR;
 768                 break;
 769         case 82: /* Abort Command Message  */
 770                 hosterr = DID_ABORT;
 771                 break;
 772         case 83: /* SCSI Bus Software Reset */
 773         case 84: /* SCSI Bus Hardware Reset */
 774                 hosterr = DID_RESET;
 775                 break;
 776         default: /* Reserved */
 777                 hosterr = DID_ERROR;
 778                 break;
 779         }
 780 #ifdef DEBUG
 781     if (scsierr||hosterr)
 782         printk("\nSCSI command error: SCSI %02x host %04x return %d",
 783                scsierr,in_error,hosterr);
 784 #endif
 785     return scsierr | (hosterr << 16);
 786 }
 787 
 788 
 789 static void wd7000_scsi_done(Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 790 {
 791 #ifdef DEBUG
 792     printk("wd7000_scsi_done: %06x\n",(unsigned int) SCpnt);
 793 #endif
 794     SCpnt->SCp.phase = 0;
 795 }
 796 
 797 
 798 #define wd7000_intr_ack(host)  outb(0,host->iobase+ASC_INTR_ACK)
 799 
 800 void wd7000_intr_handle(int irq, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 801 {
 802     register int flag, icmb, errstatus, icmb_status;
 803     register int host_error, scsi_error;
 804     register Scb *scb;             /* for SCSI commands */
 805     register IcbAny *icb;          /* for host commands */
 806     register Scsi_Cmnd *SCpnt;
 807     Adapter *host = irq2host[irq];  /* This MUST be set!!! */
 808     Mailbox *icmbs = host->mb.icmb;
 809 
 810 #ifdef DEBUG
 811     printk("wd7000_intr_handle: irq = %d, host = %06x\n", irq, host);
 812 #endif
 813 
 814     flag = inb(host->iobase+ASC_INTR_STAT);
 815 #ifdef DEBUG
 816     printk("wd7000_intr_handle: intr stat = %02x\n",flag);
 817 #endif
 818 
 819     if (!(inb(host->iobase+ASC_STAT) & INT_IM))  {
 820         /* NB: these are _very_ possible if IRQ 15 is being used, since
 821            it's the "garbage collector" on the 2nd 8259 PIC.  Specifically,
 822            any interrupt signal into the 8259 which can't be identified
 823            comes out as 7 from the 8259, which is 15 to the host.  Thus, it
 824            is a good thing the WD7000 has an interrupt status port, so we
 825            can sort these out.  Otherwise, electrical noise and other such
 826            problems would be indistinguishable from valid interrupts...
 827         */
 828 #ifdef DEBUG 
 829         printk("wd7000_intr_handle: phantom interrupt...\n");
 830 #endif
 831         wd7000_intr_ack(host);
 832         return; 
 833     }
 834 
 835     if (flag & MB_INTR)  {
 836         /* The interrupt is for a mailbox */
 837         if (!(flag & IMB_INTR)) {
 838 #ifdef DEBUG
 839             printk("wd7000_intr_handle: free outgoing mailbox");
 840 #endif
 841             /*
 842              * If sleep_on() and the "interrupt on free OGMB" command are
 843              * used in mail_out(), wake_up() should correspondingly be called
 844              * here.  For now, we don't need to do anything special.
 845              */
 846             wd7000_intr_ack(host);
 847             return;
 848         }  else  {
 849             /* The interrupt is for an incoming mailbox */
 850             icmb = flag & MB_MASK;
 851             icmb_status = icmbs[icmb].status;
 852             if (icmb_status & 0x80)  {  /* unsolicited - result in ICMB */
 853 #ifdef DEBUG
 854                 printk("wd7000_intr_handle: unsolicited interrupt %02xh\n",
 855                        icmb_status);
 856 #endif
 857                 wd7000_intr_ack(host);
 858                 return;
 859             }
 860             scb = (struct scb *) scsi2int((unchar *)icmbs[icmb].scbptr);
 861             icmbs[icmb].status = 0;
 862             if (!(scb->op & ICB_OP_MASK))  {   /* an SCB is done */
 863                 SCpnt = scb->SCpnt;
 864                 if (--(SCpnt->SCp.phase) <= 0)  {  /* all scbs are done */
 865                     host_error = scb->vue | (icmb_status << 8);
 866                     scsi_error = scb->status;
 867                     errstatus = make_code(host_error,scsi_error);    
 868                     SCpnt->result = errstatus;
 869 
 870                     free_scb(scb);
 871 
 872                     SCpnt->scsi_done(SCpnt);
 873                 }
 874             }  else  {    /* an ICB is done */
 875                 icb = (IcbAny *) scb;
 876                 icb->status = icmb_status;
 877                 icb->phase  = 0;
 878             }
 879         }  /* incoming mailbox */
 880     }
 881 
 882     wd7000_intr_ack(host);
 883     return;
 884 }
 885 
 886 
 887 int wd7000_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
     /* [previous][next][first][last][top][bottom][index][help] */
 888 {
 889     register Scb *scb;
 890     register Sgb *sgb;
 891     register unchar *cdb = (unchar *) SCpnt->cmnd;
 892     register unchar idlun;
 893     register short cdblen;
 894     Adapter *host = (Adapter *) SCpnt->host->hostdata;
 895 
 896     cdblen = SCpnt->cmd_len;
 897     idlun = ((SCpnt->target << 5) & 0xe0) | (SCpnt->lun & 7);
 898     SCpnt->scsi_done = done;
 899     SCpnt->SCp.phase = 1;
 900     scb = alloc_scbs(1);
 901     scb->idlun = idlun;
 902     memcpy(scb->cdb, cdb, cdblen);
 903     scb->direc = 0x40;          /* Disable direction check */
 904 
 905     scb->SCpnt = SCpnt;         /* so we can find stuff later */
 906     SCpnt->host_scribble = (unchar *) scb;
 907     scb->host = host;
 908 
 909     if (SCpnt->use_sg)  {
 910         struct scatterlist *sg = (struct scatterlist *) SCpnt->request_buffer;
 911         unsigned i;
 912 
 913         if (SCpnt->host->sg_tablesize == SG_NONE)  {
 914             panic("wd7000_queuecommand: scatter/gather not supported.\n");
 915         }
 916 #ifdef DEBUG
 917         printk("Using scatter/gather with %d elements.\n",SCpnt->use_sg);
 918 #endif
 919 
 920         sgb = scb->sgb;
 921         scb->op = 1;
 922         any2scsi(scb->dataptr, (int) sgb);
 923         any2scsi(scb->maxlen, SCpnt->use_sg * sizeof (Sgb) );
 924 
 925         for (i = 0;  i < SCpnt->use_sg;  i++)  {
 926             any2scsi(sgb[i].ptr, (int) sg[i].address);
 927             any2scsi(sgb[i].len, sg[i].length);
 928         }
 929     }  else  {
 930         scb->op = 0;
 931         any2scsi(scb->dataptr, (int) SCpnt->request_buffer);
 932         any2scsi(scb->maxlen, SCpnt->request_bufflen);
 933     }
 934     while (!mail_out(host, scb)) /* keep trying */;
 935 
 936     return 1;
 937 }
 938 
 939 
 940 int wd7000_command(Scsi_Cmnd *SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 941 {
 942     wd7000_queuecommand(SCpnt, wd7000_scsi_done);
 943 
 944     while (SCpnt->SCp.phase > 0);  /* phase counts scbs down to 0 */
 945 
 946     return SCpnt->result;
 947 }
 948 
 949 
 950 int wd7000_diagnostics( Adapter *host, int code )
     /* [previous][next][first][last][top][bottom][index][help] */
 951 {
 952     static IcbDiag icb = {ICB_OP_DIAGNOSTICS};
 953     static unchar buf[256];
 954     unsigned long timeout;
 955 
 956     icb.type = code;
 957     any2scsi(icb.len, sizeof(buf));
 958     any2scsi(icb.ptr, (int) &buf);
 959     icb.phase = 1;
 960     /*
 961      * This routine is only called at init, so there should be OGMBs
 962      * available.  I'm assuming so here.  If this is going to
 963      * fail, I can just let the timeout catch the failure.
 964      */
 965     mail_out(host, (struct scb *) &icb);
 966     timeout = jiffies + WAITnexttimeout;  /* wait up to 2 seconds */
 967     while (icb.phase && jiffies < timeout) /* wait for completion */;
 968 
 969     if (icb.phase)  {
 970         printk("wd7000_diagnostics: timed out.\n");
 971         return 0;
 972     }
 973     if (make_code(icb.vue|(icb.status << 8),0))  {
 974         printk("wd7000_diagnostics: failed (%02x,%02x)\n",
 975                icb.vue, icb.status);
 976         return 0;
 977     }
 978 
 979     return 1;
 980 }
 981 
 982 
 983 int wd7000_init( Adapter *host )
     /* [previous][next][first][last][top][bottom][index][help] */
 984 {
 985     InitCmd init_cmd = {
 986         INITIALIZATION, 7, BUS_ON, BUS_OFF, 0, 0,0,0, OGMB_CNT, ICMB_CNT
 987     };
 988     int diag;
 989 
 990     /*
 991        Reset the adapter - only.  The SCSI bus was initialized at power-up,
 992        and we need to do this just so we control the mailboxes, etc.
 993     */
 994     outb(ASC_RES, host->iobase+ASC_CONTROL);
 995     delay(1);  /* reset pulse: this is 10ms, only need 25us */
 996     outb(0,host->iobase+ASC_CONTROL);
 997     host->control = 0;   /* this must always shadow ASC_CONTROL */
 998     WAIT(host->iobase+ASC_STAT, ASC_STATMASK, CMD_RDY, 0);
 999 
1000     if ((diag = inb(host->iobase+ASC_INTR_STAT)) != 1)  {
1001         printk("wd7000_init: ");
1002         switch (diag)  {
1003         case 2:
1004           printk("RAM failure.\n");
1005           break;
1006         case 3:
1007           printk("FIFO R/W failed\n");
1008           break;
1009         case 4:
1010           printk("SBIC register R/W failed\n");
1011           break;
1012         case 5:
1013           printk("Initialization D-FF failed.\n");
1014           break;
1015         case 6:
1016           printk("Host IRQ D-FF failed.\n");
1017           break;
1018         case 7:
1019           printk("ROM checksum error.\n");
1020           break;
1021         default:
1022           printk("diagnostic code %02Xh received.\n", diag);
1023           break;
1024         }
1025         return 0;
1026     }
1027     
1028     /* Clear mailboxes */
1029     memset(&(host->mb), 0, sizeof(host->mb));
1030 
1031     /* Execute init command */
1032     any2scsi((unchar *) &(init_cmd.mailboxes), (int) &(host->mb));
1033     if (!command_out(host, (unchar *) &init_cmd, sizeof(init_cmd)))  {
1034         printk("wd7000_init: adapter initialization failed.\n"); 
1035         return 0;
1036     }
1037     WAIT(host->iobase+ASC_STAT, ASC_STATMASK, ASC_INIT, 0);
1038 
1039     if (request_irq(host->irq, wd7000_intr_handle, SA_INTERRUPT, "wd7000")) {
1040         printk("wd7000_init: can't get IRQ %d.\n", host->irq);
1041         return 0;
1042     }
1043     if (request_dma(host->dma,"wd7000"))  {
1044         printk("wd7000_init: can't get DMA channel %d.\n", host->dma);
1045         free_irq(host->irq);
1046         return 0;
1047     }
1048     wd7000_enable_dma(host);
1049     wd7000_enable_intr(host);
1050 
1051     if (!wd7000_diagnostics(host,ICB_DIAG_FULL))  {
1052         free_dma(host->dma);
1053         free_irq(host->irq);
1054         return 0;
1055     }
1056 
1057     return 1;
1058 
1059   fail:
1060     printk("wd7000_init: WAIT timed out.\n"); 
1061     return 0;                                   /* 0 = not ok */
1062 }
1063 
1064 
1065 void wd7000_revision(Adapter *host)
     /* [previous][next][first][last][top][bottom][index][help] */
1066 {
1067     static IcbRevLvl icb = {ICB_OP_GET_REVISION};
1068 
1069     icb.phase = 1;
1070     /*
1071      * Like diagnostics, this is only done at init time, in fact, from
1072      * wd7000_detect, so there should be OGMBs available.  If it fails,
1073      * the only damage will be that the revision will show up as 0.0,
1074      * which in turn means that scatter/gather will be disabled.
1075      */
1076     mail_out(host, (struct scb *) &icb);
1077     while (icb.phase) /* wait for completion */;
1078     host->rev1 = icb.primary;
1079     host->rev2 = icb.secondary;
1080 }
1081 
1082 
1083 int wd7000_detect(Scsi_Host_Template * tpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
1084 /* 
1085  *  Returns the number of adapters this driver is supporting.
1086  *
1087  *  The source for hosts.c says to wait to call scsi_register until 100%
1088  *  sure about an adapter.  We need to do it a little sooner here; we
1089  *  need the storage set up by scsi_register before wd7000_init, and
1090  *  changing the location of an Adapter structure is more trouble than
1091  *  calling scsi_unregister.
1092  *
1093  */
1094 {
1095     int i,j, present = 0;
1096     const Config *cfg;
1097     const Signature *sig;
1098     Adapter *host = NULL;
1099     struct Scsi_Host *sh;
1100 
1101     /* Set up SCB free list, which is shared by all adapters */
1102     init_scbs();
1103 
1104     cfg = configs;
1105     for (i = 0; i < NUM_CONFIGS; i++)  {
1106         sig = signatures;
1107         for (j = 0; j < NUM_SIGNATURES; j++)  {
1108             if (!memcmp(cfg->bios+sig->ofs, sig->sig, sig->len))  {
1109                 /* matched this one */
1110 #ifdef DEBUG
1111                 printk("WD-7000 SST BIOS detected at %04X: checking...\n",
1112                        (int) cfg->bios);
1113 #endif
1114                 /*
1115                  *  We won't explicitly test the configuration (in this
1116                  *  version); instead, we'll just see if it works to
1117                  *  setup the adapter; if it does, we'll use it.
1118                  */
1119                 if (check_region(cfg->iobase, 4))  {  /* ports in use */
1120                     printk("IO %xh already in use.\n", host->iobase);
1121                     continue;
1122                 }
1123                 /*
1124                  *  We register here, to get a pointer to the extra space,
1125                  *  which we'll use as the Adapter structure (host) for
1126                  *  this adapter.  It is located just after the registered
1127                  *  Scsi_Host structure (sh), and is located by the empty
1128                  *  array hostdata.
1129                  */
1130                 sh = scsi_register(tpnt, sizeof(Adapter) );
1131                 host = (Adapter *) sh->hostdata;
1132 #ifdef DEBUG
1133                 printk("wd7000_detect: adapter allocated at %06x\n",
1134                        (int)host);
1135 #endif
1136                 memset( host, 0, sizeof(Adapter) );
1137                 host->sh = sh;
1138                 host->irq = cfg->irq;
1139                 host->iobase = cfg->iobase;
1140                 host->dma = cfg->dma;
1141                 irq2host[host->irq] = host;
1142 
1143                 if (!wd7000_init(host))  {  /* Initialization failed */
1144                     scsi_unregister (sh);
1145                     continue;
1146                 }
1147 
1148                 /*
1149                  *  OK from here - we'll use this adapter/configuration.
1150                  */
1151                 wd7000_revision(host);   /* important for scatter/gather */
1152 
1153                 printk("Western Digital WD-7000 (%d.%d) ",
1154                        host->rev1, host->rev2);
1155                 printk("using IO %xh IRQ %d DMA %d.\n",
1156                        host->iobase, host->irq, host->dma);
1157 
1158                 request_region(host->iobase, 4,"wd7000"); /* Register our ports */
1159                 /*
1160                  *  For boards before rev 6.0, scatter/gather isn't supported.
1161                  */
1162                 if (host->rev1 < 6)  sh->sg_tablesize = SG_NONE;
1163 
1164                 present++;                      /* count it */
1165                 break;                          /* don't try any more sigs */
1166             }
1167             sig++;  /* try next signature with this configuration */
1168         }
1169         cfg++;      /* try next configuration */
1170     }
1171 
1172     return present;
1173 }
1174 
1175 
1176 /*
1177  *  I have absolutely NO idea how to do an abort with the WD7000...
1178  */
1179 int wd7000_abort(Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
1180 {
1181     Adapter *host = (Adapter *) SCpnt->host->hostdata;
1182 
1183     if (inb(host->iobase+ASC_STAT) & INT_IM)  {
1184         printk("wd7000_abort: lost interrupt\n");
1185         wd7000_intr_handle(host->irq, NULL);
1186         return SCSI_ABORT_SUCCESS;
1187     }
1188 
1189     return SCSI_ABORT_SNOOZE;
1190 }
1191 
1192 
1193 /*
1194  *  I also have no idea how to do a reset...
1195  */
1196 int wd7000_reset(Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
1197 {
1198     return SCSI_RESET_PUNT;
1199 }
1200 
1201 
1202 /*
1203  *  This was borrowed directly from aha1542.c, but my disks are organized
1204  *  this way, so I think it will work OK.  Someone who is ambitious can
1205  *  borrow a newer or more complete version from another driver.
1206  */
1207 int wd7000_biosparam(Disk * disk, int dev, int* ip)
     /* [previous][next][first][last][top][bottom][index][help] */
1208 {
1209   int size = disk->capacity;
1210   ip[0] = 64;
1211   ip[1] = 32;
1212   ip[2] = size >> 11;
1213 /*  if (ip[2] >= 1024) ip[2] = 1024; */
1214   return 0;
1215 }

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