linux/drivers/scsi/wd7000.c
<<
>>
Prefs
   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 *  Revisions by Miroslav Zagorac <zaga@fly.cc.fer.hr>
 104 *
 105 *  08/24/1996.
 106 *
 107 *  Enhancement for wd7000_detect function has been made, so you don't have
 108 *  to enter BIOS ROM address in initialisation data (see struct Config).
 109 *  We cannot detect IRQ, DMA and I/O base address for now, so we have to
 110 *  enter them as arguments while wd_7000 is detected. If someone has IRQ,
 111 *  DMA or I/O base address set to some other value, he can enter them in
 112 *  configuration without any problem. Also I wrote a function wd7000_setup,
 113 *  so now you can enter WD-7000 definition as kernel arguments,
 114 *  as in lilo.conf:
 115 *
 116 *     append="wd7000=IRQ,DMA,IO"
 117 *
 118 *  PS: If card BIOS ROM is disabled, function wd7000_detect now will recognize
 119 *      adapter, unlike the old one. Anyway, BIOS ROM from WD7000 adapter is
 120 *      useless for Linux. B^)
 121 *
 122 *
 123 *  09/06/1996.
 124 *
 125 *  Autodetecting of I/O base address from wd7000_detect function is removed,
 126 *  some little bugs removed, etc...
 127 *
 128 *  Thanks to Roger Scott for driver debugging.
 129 *
 130 *  06/07/1997
 131 *
 132 *  Added support for /proc file system (/proc/scsi/wd7000/[0...] files).
 133 *  Now, driver can handle hard disks with capacity >1GB.
 134 *
 135 *  01/15/1998
 136 *
 137 *  Added support for BUS_ON and BUS_OFF parameters in config line.
 138 *  Miscellaneous cleanup.
 139 *
 140 *  03/01/1998
 141 *
 142 *  WD7000 driver now work on kernels >= 2.1.x
 143 *
 144 *
 145 * 12/31/2001 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
 146 *
 147 * use host->host_lock, not io_request_lock, cleanups
 148 *
 149 * 2002/10/04 - Alan Cox <alan@lxorguk.ukuu.org.uk>
 150 *
 151 * Use dev_id for interrupts, kill __func__ pasting
 152 * Add a lock for the scb pool, clean up all other cli/sti usage stuff
 153 * Use the adapter lock for the other places we had the cli's
 154 *
 155 * 2002/10/06 - Alan Cox <alan@lxorguk.ukuu.org.uk>
 156 *
 157 * Switch to new style error handling
 158 * Clean up delay to udelay, and yielding sleeps
 159 * Make host reset actually reset the card
 160 * Make everything static
 161 *
 162 * 2003/02/12 - Christoph Hellwig <hch@infradead.org>
 163 *
 164 * Cleaned up host template defintion
 165 * Removed now obsolete wd7000.h
 166 */
 167
 168#include <linux/delay.h>
 169#include <linux/module.h>
 170#include <linux/interrupt.h>
 171#include <linux/kernel.h>
 172#include <linux/types.h>
 173#include <linux/string.h>
 174#include <linux/slab.h>
 175#include <linux/spinlock.h>
 176#include <linux/ioport.h>
 177#include <linux/proc_fs.h>
 178#include <linux/blkdev.h>
 179#include <linux/init.h>
 180#include <linux/stat.h>
 181#include <linux/io.h>
 182
 183#include <asm/system.h>
 184#include <asm/dma.h>
 185
 186#include <scsi/scsi.h>
 187#include <scsi/scsi_cmnd.h>
 188#include <scsi/scsi_device.h>
 189#include <scsi/scsi_host.h>
 190#include <scsi/scsicam.h>
 191
 192
 193#undef  WD7000_DEBUG            /* general debug                */
 194#ifdef WD7000_DEBUG
 195#define dprintk printk
 196#else
 197#define dprintk(format,args...)
 198#endif
 199
 200/*
 201 *  Mailbox structure sizes.
 202 *  I prefer to keep the number of ICMBs much larger than the number of
 203 *  OGMBs.  OGMBs are used very quickly by the driver to start one or
 204 *  more commands, while ICMBs are used by the host adapter per command.
 205 */
 206#define OGMB_CNT        16
 207#define ICMB_CNT        32
 208
 209/*
 210 *  Scb's are shared by all active adapters.  So, if they all become busy,
 211 *  callers may be made to wait in alloc_scbs for them to free.  That can
 212 *  be avoided by setting MAX_SCBS to NUM_CONFIG * WD7000_Q.  If you'd
 213 *  rather conserve memory, use a smaller number (> 0, of course) - things
 214 *  will should still work OK.
 215 */
 216#define MAX_SCBS        32
 217
 218/*
 219 *  In this version, sg_tablesize now defaults to WD7000_SG, and will
 220 *  be set to SG_NONE for older boards.  This is the reverse of the
 221 *  previous default, and was changed so that the driver-level
 222 *  scsi_host_template would reflect the driver's support for scatter/
 223 *  gather.
 224 *
 225 *  Also, it has been reported that boards at Revision 6 support scatter/
 226 *  gather, so the new definition of an "older" board has been changed
 227 *  accordingly.
 228 */
 229#define WD7000_Q        16
 230#define WD7000_SG       16
 231
 232
 233/*
 234 *  WD7000-specific mailbox structure
 235 *
 236 */
 237typedef volatile struct mailbox {
 238        unchar status;
 239        unchar scbptr[3];       /* SCSI-style - MSB first (big endian) */
 240} Mailbox;
 241
 242/*
 243 *  This structure should contain all per-adapter global data.  I.e., any
 244 *  new global per-adapter data should put in here.
 245 */
 246typedef struct adapter {
 247        struct Scsi_Host *sh;   /* Pointer to Scsi_Host structure    */
 248        int iobase;             /* This adapter's I/O base address   */
 249        int irq;                /* This adapter's IRQ level          */
 250        int dma;                /* This adapter's DMA channel        */
 251        int int_counter;        /* This adapter's interrupt counter  */
 252        int bus_on;             /* This adapter's BUS_ON time        */
 253        int bus_off;            /* This adapter's BUS_OFF time       */
 254        struct {                /* This adapter's mailboxes          */
 255                Mailbox ogmb[OGMB_CNT]; /* Outgoing mailboxes                */
 256                Mailbox icmb[ICMB_CNT]; /* Incoming mailboxes                */
 257        } mb;
 258        int next_ogmb;          /* to reduce contention at mailboxes */
 259        unchar control;         /* shadows CONTROL port value        */
 260        unchar rev1, rev2;      /* filled in by wd7000_revision      */
 261} Adapter;
 262
 263/*
 264 * (linear) base address for ROM BIOS
 265 */
 266static const long wd7000_biosaddr[] = {
 267        0xc0000, 0xc2000, 0xc4000, 0xc6000, 0xc8000, 0xca000, 0xcc000, 0xce000,
 268        0xd0000, 0xd2000, 0xd4000, 0xd6000, 0xd8000, 0xda000, 0xdc000, 0xde000
 269};
 270#define NUM_ADDRS ARRAY_SIZE(wd7000_biosaddr)
 271
 272static const unsigned short wd7000_iobase[] = {
 273        0x0300, 0x0308, 0x0310, 0x0318, 0x0320, 0x0328, 0x0330, 0x0338,
 274        0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370, 0x0378,
 275        0x0380, 0x0388, 0x0390, 0x0398, 0x03a0, 0x03a8, 0x03b0, 0x03b8,
 276        0x03c0, 0x03c8, 0x03d0, 0x03d8, 0x03e0, 0x03e8, 0x03f0, 0x03f8
 277};
 278#define NUM_IOPORTS ARRAY_SIZE(wd7000_iobase)
 279
 280static const short wd7000_irq[] = { 3, 4, 5, 7, 9, 10, 11, 12, 14, 15 };
 281#define NUM_IRQS ARRAY_SIZE(wd7000_irq)
 282
 283static const short wd7000_dma[] = { 5, 6, 7 };
 284#define NUM_DMAS ARRAY_SIZE(wd7000_dma)
 285
 286/*
 287 * The following is set up by wd7000_detect, and used thereafter for
 288 * proc and other global ookups
 289 */
 290
 291#define UNITS   8
 292static struct Scsi_Host *wd7000_host[UNITS];
 293
 294#define BUS_ON    64            /* x 125ns = 8000ns (BIOS default) */
 295#define BUS_OFF   15            /* x 125ns = 1875ns (BIOS default) */
 296
 297/*
 298 *  Standard Adapter Configurations - used by wd7000_detect
 299 */
 300typedef struct {
 301        short irq;              /* IRQ level                                  */
 302        short dma;              /* DMA channel                                */
 303        unsigned iobase;        /* I/O base address                           */
 304        short bus_on;           /* Time that WD7000 spends on the AT-bus when */
 305        /* transferring data. BIOS default is 8000ns. */
 306        short bus_off;          /* Time that WD7000 spends OFF THE BUS after  */
 307        /* while it is transferring data.             */
 308        /* BIOS default is 1875ns                     */
 309} Config;
 310
 311/*
 312 * Add here your configuration...
 313 */
 314static Config configs[] = {
 315        {15, 6, 0x350, BUS_ON, BUS_OFF},        /* defaults for single adapter */
 316        {11, 5, 0x320, BUS_ON, BUS_OFF},        /* defaults for second adapter */
 317        {7, 6, 0x350, BUS_ON, BUS_OFF}, /* My configuration (Zaga)     */
 318        {-1, -1, 0x0, BUS_ON, BUS_OFF}  /* Empty slot                  */
 319};
 320#define NUM_CONFIGS ARRAY_SIZE(configs)
 321
 322/*
 323 *  The following list defines strings to look for in the BIOS that identify
 324 *  it as the WD7000-FASST2 SST BIOS.  I suspect that something should be
 325 *  added for the Future Domain version.
 326 */
 327typedef struct signature {
 328        const char *sig;        /* String to look for            */
 329        unsigned long ofs;      /* offset from BIOS base address */
 330        unsigned len;           /* length of string              */
 331} Signature;
 332
 333static const Signature signatures[] = {
 334        {"SSTBIOS", 0x0000d, 7} /* "SSTBIOS" @ offset 0x0000d */
 335};
 336#define NUM_SIGNATURES ARRAY_SIZE(signatures)
 337
 338
 339/*
 340 *  I/O Port Offsets and Bit Definitions
 341 *  4 addresses are used.  Those not defined here are reserved.
 342 */
 343#define ASC_STAT        0       /* Status,  Read          */
 344#define ASC_COMMAND     0       /* Command, Write         */
 345#define ASC_INTR_STAT   1       /* Interrupt Status, Read */
 346#define ASC_INTR_ACK    1       /* Acknowledge, Write     */
 347#define ASC_CONTROL     2       /* Control, Write         */
 348
 349/*
 350 * ASC Status Port
 351 */
 352#define INT_IM          0x80    /* Interrupt Image Flag           */
 353#define CMD_RDY         0x40    /* Command Port Ready             */
 354#define CMD_REJ         0x20    /* Command Port Byte Rejected     */
 355#define ASC_INIT        0x10    /* ASC Initialized Flag           */
 356#define ASC_STATMASK    0xf0    /* The lower 4 Bytes are reserved */
 357
 358/*
 359 * COMMAND opcodes
 360 *
 361 *  Unfortunately, I have no idea how to properly use some of these commands,
 362 *  as the OEM manual does not make it clear.  I have not been able to use
 363 *  enable/disable unsolicited interrupts or the reset commands with any
 364 *  discernible effect whatsoever.  I think they may be related to certain
 365 *  ICB commands, but again, the OEM manual doesn't make that clear.
 366 */
 367#define NO_OP             0     /* NO-OP toggles CMD_RDY bit in ASC_STAT  */
 368#define INITIALIZATION    1     /* initialization (10 bytes)              */
 369#define DISABLE_UNS_INTR  2     /* disable unsolicited interrupts         */
 370#define ENABLE_UNS_INTR   3     /* enable unsolicited interrupts          */
 371#define INTR_ON_FREE_OGMB 4     /* interrupt on free OGMB                 */
 372#define SOFT_RESET        5     /* SCSI bus soft reset                    */
 373#define HARD_RESET_ACK    6     /* SCSI bus hard reset acknowledge        */
 374#define START_OGMB        0x80  /* start command in OGMB (n)              */
 375#define SCAN_OGMBS        0xc0  /* start multiple commands, signature (n) */
 376                                /*    where (n) = lower 6 bits            */
 377/*
 378 * For INITIALIZATION:
 379 */
 380typedef struct initCmd {
 381        unchar op;              /* command opcode (= 1)                    */
 382        unchar ID;              /* Adapter's SCSI ID                       */
 383        unchar bus_on;          /* Bus on time, x 125ns (see below)        */
 384        unchar bus_off;         /* Bus off time, ""         ""             */
 385        unchar rsvd;            /* Reserved                                */
 386        unchar mailboxes[3];    /* Address of Mailboxes, MSB first         */
 387        unchar ogmbs;           /* Number of outgoing MBs, max 64, 0,1 = 1 */
 388        unchar icmbs;           /* Number of incoming MBs,   ""       ""   */
 389} InitCmd;
 390
 391/*
 392 * Interrupt Status Port - also returns diagnostic codes at ASC reset
 393 *
 394 * if msb is zero, the lower bits are diagnostic status
 395 * Diagnostics:
 396 * 01   No diagnostic error occurred
 397 * 02   RAM failure
 398 * 03   FIFO R/W failed
 399 * 04   SBIC register read/write failed
 400 * 05   Initialization D-FF failed
 401 * 06   Host IRQ D-FF failed
 402 * 07   ROM checksum error
 403 * Interrupt status (bitwise):
 404 * 10NNNNNN   outgoing mailbox NNNNNN is free
 405 * 11NNNNNN   incoming mailbox NNNNNN needs service
 406 */
 407#define MB_INTR    0xC0         /* Mailbox Service possible/required */
 408#define IMB_INTR   0x40         /* 1 Incoming / 0 Outgoing           */
 409#define MB_MASK    0x3f         /* mask for mailbox number           */
 410
 411/*
 412 * CONTROL port bits
 413 */
 414#define INT_EN     0x08         /* Interrupt Enable */
 415#define DMA_EN     0x04         /* DMA Enable       */
 416#define SCSI_RES   0x02         /* SCSI Reset       */
 417#define ASC_RES    0x01         /* ASC Reset        */
 418
 419/*
 420 * Driver data structures:
 421 *   - mb and scbs are required for interfacing with the host adapter.
 422 *     An SCB has extra fields not visible to the adapter; mb's
 423 *     _cannot_ do this, since the adapter assumes they are contiguous in
 424 *     memory, 4 bytes each, with ICMBs following OGMBs, and uses this fact
 425 *     to access them.
 426 *   - An icb is for host-only (non-SCSI) commands.  ICBs are 16 bytes each;
 427 *     the additional bytes are used only by the driver.
 428 *   - For now, a pool of SCBs are kept in global storage by this driver,
 429 *     and are allocated and freed as needed.
 430 *
 431 *  The 7000-FASST2 marks OGMBs empty as soon as it has _started_ a command,
 432 *  not when it has finished.  Since the SCB must be around for completion,
 433 *  problems arise when SCBs correspond to OGMBs, which may be reallocated
 434 *  earlier (or delayed unnecessarily until a command completes).
 435 *  Mailboxes are used as transient data structures, simply for
 436 *  carrying SCB addresses to/from the 7000-FASST2.
 437 *
 438 *  Note also since SCBs are not "permanently" associated with mailboxes,
 439 *  there is no need to keep a global list of scsi_cmnd pointers indexed
 440 *  by OGMB.   Again, SCBs reference their scsi_cmnds directly, so mailbox
 441 *  indices need not be involved.
 442 */
 443
 444/*
 445 *  WD7000-specific scatter/gather element structure
 446 */
 447typedef struct sgb {
 448        unchar len[3];
 449        unchar ptr[3];          /* Also SCSI-style - MSB first */
 450} Sgb;
 451
 452typedef struct scb {            /* Command Control Block 5.4.1               */
 453        unchar op;              /* Command Control Block Operation Code      */
 454        unchar idlun;           /* op=0,2:Target Id, op=1:Initiator Id       */
 455        /* Outbound data transfer, length is checked */
 456        /* Inbound data transfer, length is checked  */
 457        /* Logical Unit Number                       */
 458        unchar cdb[12];         /* SCSI Command Block                        */
 459        volatile unchar status; /* SCSI Return Status                        */
 460        volatile unchar vue;    /* Vendor Unique Error Code                  */
 461        unchar maxlen[3];       /* Maximum Data Transfer Length              */
 462        unchar dataptr[3];      /* SCSI Data Block Pointer                   */
 463        unchar linkptr[3];      /* Next Command Link Pointer                 */
 464        unchar direc;           /* Transfer Direction                        */
 465        unchar reserved2[6];    /* SCSI Command Descriptor Block             */
 466        /* end of hardware SCB                       */
 467        struct scsi_cmnd *SCpnt;/* scsi_cmnd using this SCB                  */
 468        Sgb sgb[WD7000_SG];     /* Scatter/gather list for this SCB          */
 469        Adapter *host;          /* host adapter                              */
 470        struct scb *next;       /* for lists of scbs                         */
 471} Scb;
 472
 473/*
 474 *  This driver is written to allow host-only commands to be executed.
 475 *  These use a 16-byte block called an ICB.  The format is extended by the
 476 *  driver to 18 bytes, to support the status returned in the ICMB and
 477 *  an execution phase code.
 478 *
 479 *  There are other formats besides these; these are the ones I've tried
 480 *  to use.  Formats for some of the defined ICB opcodes are not defined
 481 *  (notably, get/set unsolicited interrupt status) in my copy of the OEM
 482 *  manual, and others are ambiguous/hard to follow.
 483 */
 484#define ICB_OP_MASK           0x80      /* distinguishes scbs from icbs        */
 485#define ICB_OP_OPEN_RBUF      0x80      /* open receive buffer                 */
 486#define ICB_OP_RECV_CMD       0x81      /* receive command from initiator      */
 487#define ICB_OP_RECV_DATA      0x82      /* receive data from initiator         */
 488#define ICB_OP_RECV_SDATA     0x83      /* receive data with status from init. */
 489#define ICB_OP_SEND_DATA      0x84      /* send data with status to initiator  */
 490#define ICB_OP_SEND_STAT      0x86      /* send command status to initiator    */
 491                                        /* 0x87 is reserved                    */
 492#define ICB_OP_READ_INIT      0x88      /* read initialization bytes           */
 493#define ICB_OP_READ_ID        0x89      /* read adapter's SCSI ID              */
 494#define ICB_OP_SET_UMASK      0x8A      /* set unsolicited interrupt mask      */
 495#define ICB_OP_GET_UMASK      0x8B      /* read unsolicited interrupt mask     */
 496#define ICB_OP_GET_REVISION   0x8C      /* read firmware revision level        */
 497#define ICB_OP_DIAGNOSTICS    0x8D      /* execute diagnostics                 */
 498#define ICB_OP_SET_EPARMS     0x8E      /* set execution parameters            */
 499#define ICB_OP_GET_EPARMS     0x8F      /* read execution parameters           */
 500
 501typedef struct icbRecvCmd {
 502        unchar op;
 503        unchar IDlun;           /* Initiator SCSI ID/lun     */
 504        unchar len[3];          /* command buffer length     */
 505        unchar ptr[3];          /* command buffer address    */
 506        unchar rsvd[7];         /* reserved                  */
 507        volatile unchar vue;    /* vendor-unique error code  */
 508        volatile unchar status; /* returned (icmb) status    */
 509        volatile unchar phase;  /* used by interrupt handler */
 510} IcbRecvCmd;
 511
 512typedef struct icbSendStat {
 513        unchar op;
 514        unchar IDlun;           /* Target SCSI ID/lun                  */
 515        unchar stat;            /* (outgoing) completion status byte 1 */
 516        unchar rsvd[12];        /* reserved                            */
 517        volatile unchar vue;    /* vendor-unique error code            */
 518        volatile unchar status; /* returned (icmb) status              */
 519        volatile unchar phase;  /* used by interrupt handler           */
 520} IcbSendStat;
 521
 522typedef struct icbRevLvl {
 523        unchar op;
 524        volatile unchar primary;        /* primary revision level (returned)   */
 525        volatile unchar secondary;      /* secondary revision level (returned) */
 526        unchar rsvd[12];        /* reserved                            */
 527        volatile unchar vue;    /* vendor-unique error code            */
 528        volatile unchar status; /* returned (icmb) status              */
 529        volatile unchar phase;  /* used by interrupt handler           */
 530} IcbRevLvl;
 531
 532typedef struct icbUnsMask {     /* I'm totally guessing here */
 533        unchar op;
 534        volatile unchar mask[14];       /* mask bits                 */
 535#if 0
 536        unchar rsvd[12];        /* reserved                  */
 537#endif
 538        volatile unchar vue;    /* vendor-unique error code  */
 539        volatile unchar status; /* returned (icmb) status    */
 540        volatile unchar phase;  /* used by interrupt handler */
 541} IcbUnsMask;
 542
 543typedef struct icbDiag {
 544        unchar op;
 545        unchar type;            /* diagnostics type code (0-3) */
 546        unchar len[3];          /* buffer length               */
 547        unchar ptr[3];          /* buffer address              */
 548        unchar rsvd[7];         /* reserved                    */
 549        volatile unchar vue;    /* vendor-unique error code    */
 550        volatile unchar status; /* returned (icmb) status      */
 551        volatile unchar phase;  /* used by interrupt handler   */
 552} IcbDiag;
 553
 554#define ICB_DIAG_POWERUP   0    /* Power-up diags only       */
 555#define ICB_DIAG_WALKING   1    /* walking 1's pattern       */
 556#define ICB_DIAG_DMA       2    /* DMA - system memory diags */
 557#define ICB_DIAG_FULL      3    /* do both 1 & 2             */
 558
 559typedef struct icbParms {
 560        unchar op;
 561        unchar rsvd1;           /* reserved                  */
 562        unchar len[3];          /* parms buffer length       */
 563        unchar ptr[3];          /* parms buffer address      */
 564        unchar idx[2];          /* index (MSB-LSB)           */
 565        unchar rsvd2[5];        /* reserved                  */
 566        volatile unchar vue;    /* vendor-unique error code  */
 567        volatile unchar status; /* returned (icmb) status    */
 568        volatile unchar phase;  /* used by interrupt handler */
 569} IcbParms;
 570
 571typedef struct icbAny {
 572        unchar op;
 573        unchar data[14];        /* format-specific data      */
 574        volatile unchar vue;    /* vendor-unique error code  */
 575        volatile unchar status; /* returned (icmb) status    */
 576        volatile unchar phase;  /* used by interrupt handler */
 577} IcbAny;
 578
 579typedef union icb {
 580        unchar op;              /* ICB opcode                     */
 581        IcbRecvCmd recv_cmd;    /* format for receive command     */
 582        IcbSendStat send_stat;  /* format for send status         */
 583        IcbRevLvl rev_lvl;      /* format for get revision level  */
 584        IcbDiag diag;           /* format for execute diagnostics */
 585        IcbParms eparms;        /* format for get/set exec parms  */
 586        IcbAny icb;             /* generic format                 */
 587        unchar data[18];
 588} Icb;
 589
 590#ifdef MODULE
 591static char *wd7000;
 592module_param(wd7000, charp, 0);
 593#endif
 594
 595/*
 596 *  Driver SCB structure pool.
 597 *
 598 *  The SCBs declared here are shared by all host adapters; hence, this
 599 *  structure is not part of the Adapter structure.
 600 */
 601static Scb scbs[MAX_SCBS];
 602static Scb *scbfree;            /* free list         */
 603static int freescbs = MAX_SCBS; /* free list counter */
 604static spinlock_t scbpool_lock; /* guards the scb free list and count */
 605
 606/*
 607 *  END of data/declarations - code follows.
 608 */
 609static void __init setup_error(char *mesg, int *ints)
 610{
 611        if (ints[0] == 3)
 612                printk(KERN_ERR "wd7000_setup: \"wd7000=%d,%d,0x%x\" -> %s\n", ints[1], ints[2], ints[3], mesg);
 613        else if (ints[0] == 4)
 614                printk(KERN_ERR "wd7000_setup: \"wd7000=%d,%d,0x%x,%d\" -> %s\n", ints[1], ints[2], ints[3], ints[4], mesg);
 615        else
 616                printk(KERN_ERR "wd7000_setup: \"wd7000=%d,%d,0x%x,%d,%d\" -> %s\n", ints[1], ints[2], ints[3], ints[4], ints[5], mesg);
 617}
 618
 619
 620/*
 621 * Note: You can now set these options from the kernel's "command line".
 622 * The syntax is:
 623 *
 624 *     wd7000=<IRQ>,<DMA>,<IO>[,<BUS_ON>[,<BUS_OFF>]]
 625 *
 626 * , where BUS_ON and BUS_OFF are in nanoseconds. BIOS default values
 627 * are 8000ns for BUS_ON and 1875ns for BUS_OFF.
 628 * eg:
 629 *     wd7000=7,6,0x350
 630 *
 631 * will configure the driver for a WD-7000 controller
 632 * using IRQ 15 with a DMA channel 6, at IO base address 0x350.
 633 */
 634static int __init wd7000_setup(char *str)
 635{
 636        static short wd7000_card_num;   /* .bss will zero this */
 637        short i;
 638        int ints[6];
 639
 640        (void) get_options(str, ARRAY_SIZE(ints), ints);
 641
 642        if (wd7000_card_num >= NUM_CONFIGS) {
 643                printk(KERN_ERR "%s: Too many \"wd7000=\" configurations in " "command line!\n", __func__);
 644                return 0;
 645        }
 646
 647        if ((ints[0] < 3) || (ints[0] > 5)) {
 648                printk(KERN_ERR "%s: Error in command line!  " "Usage: wd7000=<IRQ>,<DMA>,IO>[,<BUS_ON>" "[,<BUS_OFF>]]\n", __func__);
 649        } else {
 650                for (i = 0; i < NUM_IRQS; i++)
 651                        if (ints[1] == wd7000_irq[i])
 652                                break;
 653
 654                if (i == NUM_IRQS) {
 655                        setup_error("invalid IRQ.", ints);
 656                        return 0;
 657                } else
 658                        configs[wd7000_card_num].irq = ints[1];
 659
 660                for (i = 0; i < NUM_DMAS; i++)
 661                        if (ints[2] == wd7000_dma[i])
 662                                break;
 663
 664                if (i == NUM_DMAS) {
 665                        setup_error("invalid DMA channel.", ints);
 666                        return 0;
 667                } else
 668                        configs[wd7000_card_num].dma = ints[2];
 669
 670                for (i = 0; i < NUM_IOPORTS; i++)
 671                        if (ints[3] == wd7000_iobase[i])
 672                                break;
 673
 674                if (i == NUM_IOPORTS) {
 675                        setup_error("invalid I/O base address.", ints);
 676                        return 0;
 677                } else
 678                        configs[wd7000_card_num].iobase = ints[3];
 679
 680                if (ints[0] > 3) {
 681                        if ((ints[4] < 500) || (ints[4] > 31875)) {
 682                                setup_error("BUS_ON value is out of range (500" " to 31875 nanoseconds)!", ints);
 683                                configs[wd7000_card_num].bus_on = BUS_ON;
 684                        } else
 685                                configs[wd7000_card_num].bus_on = ints[4] / 125;
 686                } else
 687                        configs[wd7000_card_num].bus_on = BUS_ON;
 688
 689                if (ints[0] > 4) {
 690                        if ((ints[5] < 500) || (ints[5] > 31875)) {
 691                                setup_error("BUS_OFF value is out of range (500" " to 31875 nanoseconds)!", ints);
 692                                configs[wd7000_card_num].bus_off = BUS_OFF;
 693                        } else
 694                                configs[wd7000_card_num].bus_off = ints[5] / 125;
 695                } else
 696                        configs[wd7000_card_num].bus_off = BUS_OFF;
 697
 698                if (wd7000_card_num) {
 699                        for (i = 0; i < (wd7000_card_num - 1); i++) {
 700                                int j = i + 1;
 701
 702                                for (; j < wd7000_card_num; j++)
 703                                        if (configs[i].irq == configs[j].irq) {
 704                                                setup_error("duplicated IRQ!", ints);
 705                                                return 0;
 706                                        }
 707                                if (configs[i].dma == configs[j].dma) {
 708                                        setup_error("duplicated DMA " "channel!", ints);
 709                                        return 0;
 710                                }
 711                                if (configs[i].iobase == configs[j].iobase) {
 712                                        setup_error("duplicated I/O " "base address!", ints);
 713                                        return 0;
 714                                }
 715                        }
 716                }
 717
 718                dprintk(KERN_DEBUG "wd7000_setup: IRQ=%d, DMA=%d, I/O=0x%x, "
 719                        "BUS_ON=%dns, BUS_OFF=%dns\n", configs[wd7000_card_num].irq, configs[wd7000_card_num].dma, configs[wd7000_card_num].iobase, configs[wd7000_card_num].bus_on * 125, configs[wd7000_card_num].bus_off * 125);
 720
 721                wd7000_card_num++;
 722        }
 723        return 1;
 724}
 725
 726__setup("wd7000=", wd7000_setup);
 727
 728static inline void any2scsi(unchar * scsi, int any)
 729{
 730        *scsi++ = (unsigned)any >> 16;
 731        *scsi++ = (unsigned)any >> 8;
 732        *scsi++ = any;
 733}
 734
 735static inline int scsi2int(unchar * scsi)
 736{
 737        return (scsi[0] << 16) | (scsi[1] << 8) | scsi[2];
 738}
 739
 740static inline void wd7000_enable_intr(Adapter * host)
 741{
 742        host->control |= INT_EN;
 743        outb(host->control, host->iobase + ASC_CONTROL);
 744}
 745
 746
 747static inline void wd7000_enable_dma(Adapter * host)
 748{
 749        unsigned long flags;
 750        host->control |= DMA_EN;
 751        outb(host->control, host->iobase + ASC_CONTROL);
 752
 753        flags = claim_dma_lock();
 754        set_dma_mode(host->dma, DMA_MODE_CASCADE);
 755        enable_dma(host->dma);
 756        release_dma_lock(flags);
 757
 758}
 759
 760
 761#define WAITnexttimeout 200     /* 2 seconds */
 762
 763static inline short WAIT(unsigned port, unsigned mask, unsigned allof, unsigned noneof)
 764{
 765        unsigned WAITbits;
 766        unsigned long WAITtimeout = jiffies + WAITnexttimeout;
 767
 768        while (time_before_eq(jiffies, WAITtimeout)) {
 769                WAITbits = inb(port) & mask;
 770
 771                if (((WAITbits & allof) == allof) && ((WAITbits & noneof) == 0))
 772                        return (0);
 773        }
 774
 775        return (1);
 776}
 777
 778
 779static inline int command_out(Adapter * host, unchar * cmd, int len)
 780{
 781        if (!WAIT(host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0)) {
 782                while (len--) {
 783                        do {
 784                                outb(*cmd, host->iobase + ASC_COMMAND);
 785                                WAIT(host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0);
 786                        } while (inb(host->iobase + ASC_STAT) & CMD_REJ);
 787
 788                        cmd++;
 789                }
 790
 791                return (1);
 792        }
 793
 794        printk(KERN_WARNING "wd7000 command_out: WAIT failed(%d)\n", len + 1);
 795
 796        return (0);
 797}
 798
 799
 800/*
 801 *  This version of alloc_scbs is in preparation for supporting multiple
 802 *  commands per lun and command chaining, by queueing pending commands.
 803 *  We will need to allocate Scbs in blocks since they will wait to be
 804 *  executed so there is the possibility of deadlock otherwise.
 805 *  Also, to keep larger requests from being starved by smaller requests,
 806 *  we limit access to this routine with an internal busy flag, so that
 807 *  the satisfiability of a request is not dependent on the size of the
 808 *  request.
 809 */
 810static inline Scb *alloc_scbs(struct Scsi_Host *host, int needed)
 811{
 812        Scb *scb, *p = NULL;
 813        unsigned long flags;
 814        unsigned long timeout = jiffies + WAITnexttimeout;
 815        unsigned long now;
 816        int i;
 817
 818        if (needed <= 0)
 819                return (NULL);  /* sanity check */
 820
 821        spin_unlock_irq(host->host_lock);
 822
 823      retry:
 824        while (freescbs < needed) {
 825                timeout = jiffies + WAITnexttimeout;
 826                do {
 827                        /* FIXME: can we actually just yield here ?? */
 828                        for (now = jiffies; now == jiffies;)
 829                                cpu_relax();    /* wait a jiffy */
 830                } while (freescbs < needed && time_before_eq(jiffies, timeout));
 831                /*
 832                 *  If we get here with enough free Scbs, we can take them.
 833                 *  Otherwise, we timed out and didn't get enough.
 834                 */
 835                if (freescbs < needed) {
 836                        printk(KERN_ERR "wd7000: can't get enough free SCBs.\n");
 837                        return (NULL);
 838                }
 839        }
 840
 841        /* Take the lock, then check we didnt get beaten, if so try again */
 842        spin_lock_irqsave(&scbpool_lock, flags);
 843        if (freescbs < needed) {
 844                spin_unlock_irqrestore(&scbpool_lock, flags);
 845                goto retry;
 846        }
 847
 848        scb = scbfree;
 849        freescbs -= needed;
 850        for (i = 0; i < needed; i++) {
 851                p = scbfree;
 852                scbfree = p->next;
 853        }
 854        p->next = NULL;
 855
 856        spin_unlock_irqrestore(&scbpool_lock, flags);
 857
 858        spin_lock_irq(host->host_lock);
 859        return (scb);
 860}
 861
 862
 863static inline void free_scb(Scb * scb)
 864{
 865        unsigned long flags;
 866
 867        spin_lock_irqsave(&scbpool_lock, flags);
 868
 869        memset(scb, 0, sizeof(Scb));
 870        scb->next = scbfree;
 871        scbfree = scb;
 872        freescbs++;
 873
 874        spin_unlock_irqrestore(&scbpool_lock, flags);
 875}
 876
 877
 878static inline void init_scbs(void)
 879{
 880        int i;
 881
 882        spin_lock_init(&scbpool_lock);
 883
 884        /* This is only ever called before the SCB pool is active */
 885
 886        scbfree = &(scbs[0]);
 887        memset(scbs, 0, sizeof(scbs));
 888        for (i = 0; i < MAX_SCBS - 1; i++) {
 889                scbs[i].next = &(scbs[i + 1]);
 890                scbs[i].SCpnt = NULL;
 891        }
 892        scbs[MAX_SCBS - 1].next = NULL;
 893        scbs[MAX_SCBS - 1].SCpnt = NULL;
 894}
 895
 896
 897static int mail_out(Adapter * host, Scb * scbptr)
 898/*
 899 *  Note: this can also be used for ICBs; just cast to the parm type.
 900 */
 901{
 902        int i, ogmb;
 903        unsigned long flags;
 904        unchar start_ogmb;
 905        Mailbox *ogmbs = host->mb.ogmb;
 906        int *next_ogmb = &(host->next_ogmb);
 907
 908        dprintk("wd7000_mail_out: 0x%06lx", (long) scbptr);
 909
 910        /* We first look for a free outgoing mailbox */
 911        spin_lock_irqsave(host->sh->host_lock, flags);
 912        ogmb = *next_ogmb;
 913        for (i = 0; i < OGMB_CNT; i++) {
 914                if (ogmbs[ogmb].status == 0) {
 915                        dprintk(" using OGMB 0x%x", ogmb);
 916                        ogmbs[ogmb].status = 1;
 917                        any2scsi((unchar *) ogmbs[ogmb].scbptr, (int) scbptr);
 918
 919                        *next_ogmb = (ogmb + 1) % OGMB_CNT;
 920                        break;
 921                } else
 922                        ogmb = (ogmb + 1) % OGMB_CNT;
 923        }
 924        spin_unlock_irqrestore(host->sh->host_lock, flags);
 925
 926        dprintk(", scb is 0x%06lx", (long) scbptr);
 927
 928        if (i >= OGMB_CNT) {
 929                /*
 930                 *  Alternatively, we might issue the "interrupt on free OGMB",
 931                 *  and sleep, but it must be ensured that it isn't the init
 932                 *  task running.  Instead, this version assumes that the caller
 933                 *  will be persistent, and try again.  Since it's the adapter
 934                 *  that marks OGMB's free, waiting even with interrupts off
 935                 *  should work, since they are freed very quickly in most cases.
 936                 */
 937                dprintk(", no free OGMBs.\n");
 938                return (0);
 939        }
 940
 941        wd7000_enable_intr(host);
 942
 943        start_ogmb = START_OGMB | ogmb;
 944        command_out(host, &start_ogmb, 1);
 945
 946        dprintk(", awaiting interrupt.\n");
 947
 948        return (1);
 949}
 950
 951
 952static int make_code(unsigned hosterr, unsigned scsierr)
 953{
 954#ifdef WD7000_DEBUG
 955        int in_error = hosterr;
 956#endif
 957
 958        switch ((hosterr >> 8) & 0xff) {
 959        case 0:         /* Reserved */
 960                hosterr = DID_ERROR;
 961                break;
 962        case 1:         /* Command Complete, no errors */
 963                hosterr = DID_OK;
 964                break;
 965        case 2:         /* Command complete, error logged in scb status (scsierr) */
 966                hosterr = DID_OK;
 967                break;
 968        case 4:         /* Command failed to complete - timeout */
 969                hosterr = DID_TIME_OUT;
 970                break;
 971        case 5:         /* Command terminated; Bus reset by external device */
 972                hosterr = DID_RESET;
 973                break;
 974        case 6:         /* Unexpected Command Received w/ host as target */
 975                hosterr = DID_BAD_TARGET;
 976                break;
 977        case 80:                /* Unexpected Reselection */
 978        case 81:                /* Unexpected Selection */
 979                hosterr = DID_BAD_INTR;
 980                break;
 981        case 82:                /* Abort Command Message  */
 982                hosterr = DID_ABORT;
 983                break;
 984        case 83:                /* SCSI Bus Software Reset */
 985        case 84:                /* SCSI Bus Hardware Reset */
 986                hosterr = DID_RESET;
 987                break;
 988        default:                /* Reserved */
 989                hosterr = DID_ERROR;
 990        }
 991#ifdef WD7000_DEBUG
 992        if (scsierr || hosterr)
 993                dprintk("\nSCSI command error: SCSI 0x%02x host 0x%04x return %d\n", scsierr, in_error, hosterr);
 994#endif
 995        return (scsierr | (hosterr << 16));
 996}
 997
 998#define wd7000_intr_ack(host)   outb (0, host->iobase + ASC_INTR_ACK)
 999
1000
1001static irqreturn_t wd7000_intr(int irq, void *dev_id)
1002{
1003        Adapter *host = (Adapter *) dev_id;
1004        int flag, icmb, errstatus, icmb_status;
1005        int host_error, scsi_error;
1006        Scb *scb;       /* for SCSI commands */
1007        IcbAny *icb;    /* for host commands */
1008        struct scsi_cmnd *SCpnt;
1009        Mailbox *icmbs = host->mb.icmb;
1010        unsigned long flags;
1011
1012        spin_lock_irqsave(host->sh->host_lock, flags);
1013        host->int_counter++;
1014
1015        dprintk("wd7000_intr: irq = %d, host = 0x%06lx\n", irq, (long) host);
1016
1017        flag = inb(host->iobase + ASC_INTR_STAT);
1018
1019        dprintk("wd7000_intr: intr stat = 0x%02x\n", flag);
1020
1021        if (!(inb(host->iobase + ASC_STAT) & INT_IM)) {
1022                /* NB: these are _very_ possible if IRQ 15 is being used, since
1023                 * it's the "garbage collector" on the 2nd 8259 PIC.  Specifically,
1024                 * any interrupt signal into the 8259 which can't be identified
1025                 * comes out as 7 from the 8259, which is 15 to the host.  Thus, it
1026                 * is a good thing the WD7000 has an interrupt status port, so we
1027                 * can sort these out.  Otherwise, electrical noise and other such
1028                 * problems would be indistinguishable from valid interrupts...
1029                 */
1030                dprintk("wd7000_intr: phantom interrupt...\n");
1031                goto ack;
1032        }
1033
1034        if (!(flag & MB_INTR))
1035                goto ack;
1036
1037        /* The interrupt is for a mailbox */
1038        if (!(flag & IMB_INTR)) {
1039                dprintk("wd7000_intr: free outgoing mailbox\n");
1040                /*
1041                 * If sleep_on() and the "interrupt on free OGMB" command are
1042                 * used in mail_out(), wake_up() should correspondingly be called
1043                 * here.  For now, we don't need to do anything special.
1044                 */
1045                goto ack;
1046        }
1047
1048        /* The interrupt is for an incoming mailbox */
1049        icmb = flag & MB_MASK;
1050        icmb_status = icmbs[icmb].status;
1051        if (icmb_status & 0x80) {       /* unsolicited - result in ICMB */
1052                dprintk("wd7000_intr: unsolicited interrupt 0x%02x\n", icmb_status);
1053                goto ack;
1054        }
1055
1056        /* Aaaargh! (Zaga) */
1057        scb = isa_bus_to_virt(scsi2int((unchar *) icmbs[icmb].scbptr));
1058        icmbs[icmb].status = 0;
1059        if (scb->op & ICB_OP_MASK) {    /* an SCB is done */
1060                icb = (IcbAny *) scb;
1061                icb->status = icmb_status;
1062                icb->phase = 0;
1063                goto ack;
1064        }
1065
1066        SCpnt = scb->SCpnt;
1067        if (--(SCpnt->SCp.phase) <= 0) {        /* all scbs are done */
1068                host_error = scb->vue | (icmb_status << 8);
1069                scsi_error = scb->status;
1070                errstatus = make_code(host_error, scsi_error);
1071                SCpnt->result = errstatus;
1072
1073                free_scb(scb);
1074
1075                SCpnt->scsi_done(SCpnt);
1076        }
1077
1078 ack:
1079        dprintk("wd7000_intr: return from interrupt handler\n");
1080        wd7000_intr_ack(host);
1081
1082        spin_unlock_irqrestore(host->sh->host_lock, flags);
1083        return IRQ_HANDLED;
1084}
1085
1086static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
1087                void (*done)(struct scsi_cmnd *))
1088{
1089        Scb *scb;
1090        Sgb *sgb;
1091        unchar *cdb = (unchar *) SCpnt->cmnd;
1092        unchar idlun;
1093        short cdblen;
1094        int nseg;
1095        Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
1096
1097        cdblen = SCpnt->cmd_len;
1098        idlun = ((SCpnt->device->id << 5) & 0xe0) | (SCpnt->device->lun & 7);
1099        SCpnt->scsi_done = done;
1100        SCpnt->SCp.phase = 1;
1101        scb = alloc_scbs(SCpnt->device->host, 1);
1102        scb->idlun = idlun;
1103        memcpy(scb->cdb, cdb, cdblen);
1104        scb->direc = 0x40;      /* Disable direction check */
1105
1106        scb->SCpnt = SCpnt;     /* so we can find stuff later */
1107        SCpnt->host_scribble = (unchar *) scb;
1108        scb->host = host;
1109
1110        nseg = scsi_sg_count(SCpnt);
1111        if (nseg > 1) {
1112                struct scatterlist *sg;
1113                unsigned i;
1114
1115                dprintk("Using scatter/gather with %d elements.\n", nseg);
1116
1117                sgb = scb->sgb;
1118                scb->op = 1;
1119                any2scsi(scb->dataptr, (int) sgb);
1120                any2scsi(scb->maxlen, nseg * sizeof(Sgb));
1121
1122                scsi_for_each_sg(SCpnt, sg, nseg, i) {
1123                        any2scsi(sgb[i].ptr, isa_page_to_bus(sg_page(sg)) + sg->offset);
1124                        any2scsi(sgb[i].len, sg->length);
1125                }
1126        } else {
1127                scb->op = 0;
1128                if (nseg) {
1129                        struct scatterlist *sg = scsi_sglist(SCpnt);
1130                        any2scsi(scb->dataptr, isa_page_to_bus(sg_page(sg)) + sg->offset);
1131                }
1132                any2scsi(scb->maxlen, scsi_bufflen(SCpnt));
1133        }
1134
1135        /* FIXME: drop lock and yield here ? */
1136
1137        while (!mail_out(host, scb))
1138                cpu_relax();    /* keep trying */
1139
1140        return 0;
1141}
1142
1143static int wd7000_diagnostics(Adapter * host, int code)
1144{
1145        static IcbDiag icb = { ICB_OP_DIAGNOSTICS };
1146        static unchar buf[256];
1147        unsigned long timeout;
1148
1149        icb.type = code;
1150        any2scsi(icb.len, sizeof(buf));
1151        any2scsi(icb.ptr, (int) &buf);
1152        icb.phase = 1;
1153        /*
1154         * This routine is only called at init, so there should be OGMBs
1155         * available.  I'm assuming so here.  If this is going to
1156         * fail, I can just let the timeout catch the failure.
1157         */
1158        mail_out(host, (struct scb *) &icb);
1159        timeout = jiffies + WAITnexttimeout;    /* wait up to 2 seconds */
1160        while (icb.phase && time_before(jiffies, timeout)) {
1161                cpu_relax();    /* wait for completion */
1162                barrier();
1163        }
1164
1165        if (icb.phase) {
1166                printk("wd7000_diagnostics: timed out.\n");
1167                return (0);
1168        }
1169        if (make_code(icb.vue | (icb.status << 8), 0)) {
1170                printk("wd7000_diagnostics: failed (0x%02x,0x%02x)\n", icb.vue, icb.status);
1171                return (0);
1172        }
1173
1174        return (1);
1175}
1176
1177
1178static int wd7000_adapter_reset(Adapter * host)
1179{
1180        InitCmd init_cmd = {
1181                INITIALIZATION,
1182                7,
1183                host->bus_on,
1184                host->bus_off,
1185                0,
1186                {0, 0, 0},
1187                OGMB_CNT,
1188                ICMB_CNT
1189        };
1190        int diag;
1191        /*
1192         *  Reset the adapter - only.  The SCSI bus was initialized at power-up,
1193         *  and we need to do this just so we control the mailboxes, etc.
1194         */
1195        outb(ASC_RES, host->iobase + ASC_CONTROL);
1196        udelay(40);             /* reset pulse: this is 40us, only need 25us */
1197        outb(0, host->iobase + ASC_CONTROL);
1198        host->control = 0;      /* this must always shadow ASC_CONTROL */
1199
1200        if (WAIT(host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0)) {
1201                printk(KERN_ERR "wd7000_init: WAIT timed out.\n");
1202                return -1;      /* -1 = not ok */
1203        }
1204
1205        if ((diag = inb(host->iobase + ASC_INTR_STAT)) != 1) {
1206                printk("wd7000_init: ");
1207
1208                switch (diag) {
1209                case 2:
1210                        printk(KERN_ERR "RAM failure.\n");
1211                        break;
1212                case 3:
1213                        printk(KERN_ERR "FIFO R/W failed\n");
1214                        break;
1215                case 4:
1216                        printk(KERN_ERR "SBIC register R/W failed\n");
1217                        break;
1218                case 5:
1219                        printk(KERN_ERR "Initialization D-FF failed.\n");
1220                        break;
1221                case 6:
1222                        printk(KERN_ERR "Host IRQ D-FF failed.\n");
1223                        break;
1224                case 7:
1225                        printk(KERN_ERR "ROM checksum error.\n");
1226                        break;
1227                default:
1228                        printk(KERN_ERR "diagnostic code 0x%02Xh received.\n", diag);
1229                }
1230                return -1;
1231        }
1232        /* Clear mailboxes */
1233        memset(&(host->mb), 0, sizeof(host->mb));
1234
1235        /* Execute init command */
1236        any2scsi((unchar *) & (init_cmd.mailboxes), (int) &(host->mb));
1237        if (!command_out(host, (unchar *) & init_cmd, sizeof(init_cmd))) {
1238                printk(KERN_ERR "wd7000_adapter_reset: adapter initialization failed.\n");
1239                return -1;
1240        }
1241
1242        if (WAIT(host->iobase + ASC_STAT, ASC_STATMASK, ASC_INIT, 0)) {
1243                printk("wd7000_adapter_reset: WAIT timed out.\n");
1244                return -1;
1245        }
1246        return 0;
1247}
1248
1249static int wd7000_init(Adapter * host)
1250{
1251        if (wd7000_adapter_reset(host) == -1)
1252                return 0;
1253
1254
1255        if (request_irq(host->irq, wd7000_intr, IRQF_DISABLED, "wd7000", host)) {
1256                printk("wd7000_init: can't get IRQ %d.\n", host->irq);
1257                return (0);
1258        }
1259        if (request_dma(host->dma, "wd7000")) {
1260                printk("wd7000_init: can't get DMA channel %d.\n", host->dma);
1261                free_irq(host->irq, host);
1262                return (0);
1263        }
1264        wd7000_enable_dma(host);
1265        wd7000_enable_intr(host);
1266
1267        if (!wd7000_diagnostics(host, ICB_DIAG_FULL)) {
1268                free_dma(host->dma);
1269                free_irq(host->irq, NULL);
1270                return (0);
1271        }
1272
1273        return (1);
1274}
1275
1276
1277static void wd7000_revision(Adapter * host)
1278{
1279        static IcbRevLvl icb = { ICB_OP_GET_REVISION };
1280
1281        icb.phase = 1;
1282        /*
1283         * Like diagnostics, this is only done at init time, in fact, from
1284         * wd7000_detect, so there should be OGMBs available.  If it fails,
1285         * the only damage will be that the revision will show up as 0.0,
1286         * which in turn means that scatter/gather will be disabled.
1287         */
1288        mail_out(host, (struct scb *) &icb);
1289        while (icb.phase) {
1290                cpu_relax();    /* wait for completion */
1291                barrier();
1292        }
1293        host->rev1 = icb.primary;
1294        host->rev2 = icb.secondary;
1295}
1296
1297
1298#undef SPRINTF
1299#define SPRINTF(args...) { if (pos < (buffer + length)) pos += sprintf (pos, ## args); }
1300
1301static int wd7000_set_info(char *buffer, int length, struct Scsi_Host *host)
1302{
1303        dprintk("Buffer = <%.*s>, length = %d\n", length, buffer, length);
1304
1305        /*
1306         * Currently this is a no-op
1307         */
1308        dprintk("Sorry, this function is currently out of order...\n");
1309        return (length);
1310}
1311
1312
1313static int wd7000_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length,  int inout)
1314{
1315        Adapter *adapter = (Adapter *)host->hostdata;
1316        unsigned long flags;
1317        char *pos = buffer;
1318#ifdef WD7000_DEBUG
1319        Mailbox *ogmbs, *icmbs;
1320        short count;
1321#endif
1322
1323        /*
1324         * Has data been written to the file ?
1325         */
1326        if (inout)
1327                return (wd7000_set_info(buffer, length, host));
1328
1329        spin_lock_irqsave(host->host_lock, flags);
1330        SPRINTF("Host scsi%d: Western Digital WD-7000 (rev %d.%d)\n", host->host_no, adapter->rev1, adapter->rev2);
1331        SPRINTF("  IO base:      0x%x\n", adapter->iobase);
1332        SPRINTF("  IRQ:          %d\n", adapter->irq);
1333        SPRINTF("  DMA channel:  %d\n", adapter->dma);
1334        SPRINTF("  Interrupts:   %d\n", adapter->int_counter);
1335        SPRINTF("  BUS_ON time:  %d nanoseconds\n", adapter->bus_on * 125);
1336        SPRINTF("  BUS_OFF time: %d nanoseconds\n", adapter->bus_off * 125);
1337
1338#ifdef WD7000_DEBUG
1339        ogmbs = adapter->mb.ogmb;
1340        icmbs = adapter->mb.icmb;
1341
1342        SPRINTF("\nControl port value: 0x%x\n", adapter->control);
1343        SPRINTF("Incoming mailbox:\n");
1344        SPRINTF("  size: %d\n", ICMB_CNT);
1345        SPRINTF("  queued messages: ");
1346
1347        for (i = count = 0; i < ICMB_CNT; i++)
1348                if (icmbs[i].status) {
1349                        count++;
1350                        SPRINTF("0x%x ", i);
1351                }
1352
1353        SPRINTF(count ? "\n" : "none\n");
1354
1355        SPRINTF("Outgoing mailbox:\n");
1356        SPRINTF("  size: %d\n", OGMB_CNT);
1357        SPRINTF("  next message: 0x%x\n", adapter->next_ogmb);
1358        SPRINTF("  queued messages: ");
1359
1360        for (i = count = 0; i < OGMB_CNT; i++)
1361                if (ogmbs[i].status) {
1362                        count++;
1363                        SPRINTF("0x%x ", i);
1364                }
1365
1366        SPRINTF(count ? "\n" : "none\n");
1367#endif
1368
1369        spin_unlock_irqrestore(host->host_lock, flags);
1370
1371        /*
1372         * Calculate start of next buffer, and return value.
1373         */
1374        *start = buffer + offset;
1375
1376        if ((pos - buffer) < offset)
1377                return (0);
1378        else if ((pos - buffer - offset) < length)
1379                return (pos - buffer - offset);
1380        else
1381                return (length);
1382}
1383
1384
1385/*
1386 *  Returns the number of adapters this driver is supporting.
1387 *
1388 *  The source for hosts.c says to wait to call scsi_register until 100%
1389 *  sure about an adapter.  We need to do it a little sooner here; we
1390 *  need the storage set up by scsi_register before wd7000_init, and
1391 *  changing the location of an Adapter structure is more trouble than
1392 *  calling scsi_unregister.
1393 *
1394 */
1395
1396static __init int wd7000_detect(struct scsi_host_template *tpnt)
1397{
1398        short present = 0, biosaddr_ptr, sig_ptr, i, pass;
1399        short biosptr[NUM_CONFIGS];
1400        unsigned iobase;
1401        Adapter *host = NULL;
1402        struct Scsi_Host *sh;
1403        int unit = 0;
1404
1405        dprintk("wd7000_detect: started\n");
1406
1407#ifdef MODULE
1408        if (wd7000)
1409                wd7000_setup(wd7000);
1410#endif
1411
1412        for (i = 0; i < UNITS; wd7000_host[i++] = NULL);
1413        for (i = 0; i < NUM_CONFIGS; biosptr[i++] = -1);
1414
1415        tpnt->proc_name = "wd7000";
1416        tpnt->proc_info = &wd7000_proc_info;
1417
1418        /*
1419         * Set up SCB free list, which is shared by all adapters
1420         */
1421        init_scbs();
1422
1423        for (pass = 0; pass < NUM_CONFIGS; pass++) {
1424                /*
1425                 * First, search for BIOS SIGNATURE...
1426                 */
1427                for (biosaddr_ptr = 0; biosaddr_ptr < NUM_ADDRS; biosaddr_ptr++)
1428                        for (sig_ptr = 0; sig_ptr < NUM_SIGNATURES; sig_ptr++) {
1429                                for (i = 0; i < pass; i++)
1430                                        if (biosptr[i] == biosaddr_ptr)
1431                                                break;
1432
1433                                if (i == pass) {
1434                                        void __iomem *biosaddr = ioremap(wd7000_biosaddr[biosaddr_ptr] + signatures[sig_ptr].ofs,
1435                                                                 signatures[sig_ptr].len);
1436                                        short bios_match = 1;
1437
1438                                        if (biosaddr)
1439                                                bios_match = check_signature(biosaddr, signatures[sig_ptr].sig, signatures[sig_ptr].len);
1440
1441                                        iounmap(biosaddr);
1442
1443                                        if (bios_match)
1444                                                goto bios_matched;
1445                                }
1446                        }
1447
1448              bios_matched:
1449                /*
1450                 * BIOS SIGNATURE has been found.
1451                 */
1452#ifdef WD7000_DEBUG
1453                dprintk("wd7000_detect: pass %d\n", pass + 1);
1454
1455                if (biosaddr_ptr == NUM_ADDRS)
1456                        dprintk("WD-7000 SST BIOS not detected...\n");
1457                else
1458                        dprintk("WD-7000 SST BIOS detected at 0x%lx: checking...\n", wd7000_biosaddr[biosaddr_ptr]);
1459#endif
1460
1461                if (configs[pass].irq < 0)
1462                        continue;
1463
1464                if (unit == UNITS)
1465                        continue;
1466
1467                iobase = configs[pass].iobase;
1468
1469                dprintk("wd7000_detect: check IO 0x%x region...\n", iobase);
1470
1471                if (request_region(iobase, 4, "wd7000")) {
1472
1473                        dprintk("wd7000_detect: ASC reset (IO 0x%x) ...", iobase);
1474                        /*
1475                         * ASC reset...
1476                         */
1477                        outb(ASC_RES, iobase + ASC_CONTROL);
1478                        msleep(10);
1479                        outb(0, iobase + ASC_CONTROL);
1480
1481                        if (WAIT(iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0)) {
1482                                dprintk("failed!\n");
1483                                goto err_release;
1484                        } else
1485                                dprintk("ok!\n");
1486
1487                        if (inb(iobase + ASC_INTR_STAT) == 1) {
1488                                /*
1489                                 *  We register here, to get a pointer to the extra space,
1490                                 *  which we'll use as the Adapter structure (host) for
1491                                 *  this adapter.  It is located just after the registered
1492                                 *  Scsi_Host structure (sh), and is located by the empty
1493                                 *  array hostdata.
1494                                 */
1495                                sh = scsi_register(tpnt, sizeof(Adapter));
1496                                if (sh == NULL)
1497                                        goto err_release;
1498
1499                                host = (Adapter *) sh->hostdata;
1500
1501                                dprintk("wd7000_detect: adapter allocated at 0x%x\n", (int) host);
1502                                memset(host, 0, sizeof(Adapter));
1503
1504                                host->irq = configs[pass].irq;
1505                                host->dma = configs[pass].dma;
1506                                host->iobase = iobase;
1507                                host->int_counter = 0;
1508                                host->bus_on = configs[pass].bus_on;
1509                                host->bus_off = configs[pass].bus_off;
1510                                host->sh = wd7000_host[unit] = sh;
1511                                unit++;
1512
1513                                dprintk("wd7000_detect: Trying init WD-7000 card at IO " "0x%x, IRQ %d, DMA %d...\n", host->iobase, host->irq, host->dma);
1514
1515                                if (!wd7000_init(host)) /* Initialization failed */
1516                                        goto err_unregister;
1517
1518                                /*
1519                                 *  OK from here - we'll use this adapter/configuration.
1520                                 */
1521                                wd7000_revision(host);  /* important for scatter/gather */
1522
1523                                /*
1524                                 *  For boards before rev 6.0, scatter/gather isn't supported.
1525                                 */
1526                                if (host->rev1 < 6)
1527                                        sh->sg_tablesize = 1;
1528
1529                                present++;      /* count it */
1530
1531                                if (biosaddr_ptr != NUM_ADDRS)
1532                                        biosptr[pass] = biosaddr_ptr;
1533
1534                                printk(KERN_INFO "Western Digital WD-7000 (rev %d.%d) ", host->rev1, host->rev2);
1535                                printk("using IO 0x%x, IRQ %d, DMA %d.\n", host->iobase, host->irq, host->dma);
1536                                printk("  BUS_ON time: %dns, BUS_OFF time: %dns\n", host->bus_on * 125, host->bus_off * 125);
1537                        }
1538                } else
1539                        dprintk("wd7000_detect: IO 0x%x region already allocated!\n", iobase);
1540
1541                continue;
1542
1543              err_unregister:
1544                scsi_unregister(sh);
1545              err_release:
1546                release_region(iobase, 4);
1547
1548        }
1549
1550        if (!present)
1551                printk("Failed initialization of WD-7000 SCSI card!\n");
1552
1553        return (present);
1554}
1555
1556static int wd7000_release(struct Scsi_Host *shost)
1557{
1558        if (shost->irq)
1559                free_irq(shost->irq, NULL);
1560        if (shost->io_port && shost->n_io_port)
1561                release_region(shost->io_port, shost->n_io_port);
1562        scsi_unregister(shost);
1563        return 0;
1564}
1565
1566#if 0
1567/*
1568 *  I have absolutely NO idea how to do an abort with the WD7000...
1569 */
1570static int wd7000_abort(Scsi_Cmnd * SCpnt)
1571{
1572        Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
1573
1574        if (inb(host->iobase + ASC_STAT) & INT_IM) {
1575                printk("wd7000_abort: lost interrupt\n");
1576                wd7000_intr_handle(host->irq, NULL, NULL);
1577                return FAILED;
1578        }
1579        return FAILED;
1580}
1581#endif
1582
1583/*
1584 *  Last resort. Reinitialize the board.
1585 */
1586
1587static int wd7000_host_reset(struct scsi_cmnd *SCpnt)
1588{
1589        Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
1590
1591        spin_unlock_irq(SCpnt->device->host->host_lock);
1592
1593        if (wd7000_adapter_reset(host) < 0) {
1594                spin_unlock_irq(SCpnt->device->host->host_lock);
1595                return FAILED;
1596        }
1597
1598        wd7000_enable_intr(host);
1599
1600        spin_unlock_irq(SCpnt->device->host->host_lock);
1601        return SUCCESS;
1602}
1603
1604/*
1605 *  This was borrowed directly from aha1542.c. (Zaga)
1606 */
1607
1608static int wd7000_biosparam(struct scsi_device *sdev,
1609                struct block_device *bdev, sector_t capacity, int *ip)
1610{
1611        char b[BDEVNAME_SIZE];
1612
1613        dprintk("wd7000_biosparam: dev=%s, size=%d, ",
1614                bdevname(bdev, b), capacity);
1615        (void)b;        /* unused var warning? */
1616
1617        /*
1618         * try default translation
1619         */
1620        ip[0] = 64;
1621        ip[1] = 32;
1622        ip[2] = capacity >> 11;
1623
1624        /*
1625         * for disks >1GB do some guessing
1626         */
1627        if (ip[2] >= 1024) {
1628                int info[3];
1629
1630                /*
1631                 * try to figure out the geometry from the partition table
1632                 */
1633                if ((scsicam_bios_param(bdev, capacity, info) < 0) || !(((info[0] == 64) && (info[1] == 32)) || ((info[0] == 255) && (info[1] == 63)))) {
1634                        printk("wd7000_biosparam: unable to verify geometry for disk with >1GB.\n" "                  using extended translation.\n");
1635
1636                        ip[0] = 255;
1637                        ip[1] = 63;
1638                        ip[2] = (unsigned long) capacity / (255 * 63);
1639                } else {
1640                        ip[0] = info[0];
1641                        ip[1] = info[1];
1642                        ip[2] = info[2];
1643
1644                        if (info[0] == 255)
1645                                printk(KERN_INFO "%s: current partition table is " "using extended translation.\n", __func__);
1646                }
1647        }
1648
1649        dprintk("bios geometry: head=%d, sec=%d, cyl=%d\n", ip[0], ip[1], ip[2]);
1650        dprintk("WARNING: check, if the bios geometry is correct.\n");
1651
1652        return (0);
1653}
1654
1655MODULE_AUTHOR("Thomas Wuensche, John Boyd, Miroslav Zagorac");
1656MODULE_DESCRIPTION("Driver for the WD7000 series ISA controllers");
1657MODULE_LICENSE("GPL");
1658
1659static struct scsi_host_template driver_template = {
1660        .proc_name              = "wd7000",
1661        .proc_info              = wd7000_proc_info,
1662        .name                   = "Western Digital WD-7000",
1663        .detect                 = wd7000_detect,
1664        .release                = wd7000_release,
1665        .queuecommand           = wd7000_queuecommand,
1666        .eh_host_reset_handler  = wd7000_host_reset,
1667        .bios_param             = wd7000_biosparam,
1668        .can_queue              = WD7000_Q,
1669        .this_id                = 7,
1670        .sg_tablesize           = WD7000_SG,
1671        .cmd_per_lun            = 1,
1672        .unchecked_isa_dma      = 1,
1673        .use_clustering         = ENABLE_CLUSTERING,
1674};
1675
1676#include "scsi_module.c"
1677