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 definition
 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/spinlock.h>
 175#include <linux/ioport.h>
 176#include <linux/proc_fs.h>
 177#include <linux/blkdev.h>
 178#include <linux/init.h>
 179#include <linux/stat.h>
 180#include <linux/io.h>
 181
 182#include <asm/dma.h>
 183
 184#include <scsi/scsi.h>
 185#include <scsi/scsi_cmnd.h>
 186#include <scsi/scsi_device.h>
 187#include <scsi/scsi_host.h>
 188#include <scsi/scsicam.h>
 189
 190
 191#undef  WD7000_DEBUG            /* general debug                */
 192#ifdef WD7000_DEBUG
 193#define dprintk printk
 194#else
 195#define dprintk(format,args...)
 196#endif
 197
 198/*
 199 *  Mailbox structure sizes.
 200 *  I prefer to keep the number of ICMBs much larger than the number of
 201 *  OGMBs.  OGMBs are used very quickly by the driver to start one or
 202 *  more commands, while ICMBs are used by the host adapter per command.
 203 */
 204#define OGMB_CNT        16
 205#define ICMB_CNT        32
 206
 207/*
 208 *  Scb's are shared by all active adapters.  So, if they all become busy,
 209 *  callers may be made to wait in alloc_scbs for them to free.  That can
 210 *  be avoided by setting MAX_SCBS to NUM_CONFIG * WD7000_Q.  If you'd
 211 *  rather conserve memory, use a smaller number (> 0, of course) - things
 212 *  will should still work OK.
 213 */
 214#define MAX_SCBS        32
 215
 216/*
 217 *  In this version, sg_tablesize now defaults to WD7000_SG, and will
 218 *  be set to SG_NONE for older boards.  This is the reverse of the
 219 *  previous default, and was changed so that the driver-level
 220 *  scsi_host_template would reflect the driver's support for scatter/
 221 *  gather.
 222 *
 223 *  Also, it has been reported that boards at Revision 6 support scatter/
 224 *  gather, so the new definition of an "older" board has been changed
 225 *  accordingly.
 226 */
 227#define WD7000_Q        16
 228#define WD7000_SG       16
 229
 230
 231/*
 232 *  WD7000-specific mailbox structure
 233 *
 234 */
 235typedef volatile struct mailbox {
 236        unchar status;
 237        unchar scbptr[3];       /* SCSI-style - MSB first (big endian) */
 238} Mailbox;
 239
 240/*
 241 *  This structure should contain all per-adapter global data.  I.e., any
 242 *  new global per-adapter data should put in here.
 243 */
 244typedef struct adapter {
 245        struct Scsi_Host *sh;   /* Pointer to Scsi_Host structure    */
 246        int iobase;             /* This adapter's I/O base address   */
 247        int irq;                /* This adapter's IRQ level          */
 248        int dma;                /* This adapter's DMA channel        */
 249        int int_counter;        /* This adapter's interrupt counter  */
 250        int bus_on;             /* This adapter's BUS_ON time        */
 251        int bus_off;            /* This adapter's BUS_OFF time       */
 252        struct {                /* This adapter's mailboxes          */
 253                Mailbox ogmb[OGMB_CNT]; /* Outgoing mailboxes                */
 254                Mailbox icmb[ICMB_CNT]; /* Incoming mailboxes                */
 255        } mb;
 256        int next_ogmb;          /* to reduce contention at mailboxes */
 257        unchar control;         /* shadows CONTROL port value        */
 258        unchar rev1, rev2;      /* filled in by wd7000_revision      */
 259} Adapter;
 260
 261/*
 262 * (linear) base address for ROM BIOS
 263 */
 264static const long wd7000_biosaddr[] = {
 265        0xc0000, 0xc2000, 0xc4000, 0xc6000, 0xc8000, 0xca000, 0xcc000, 0xce000,
 266        0xd0000, 0xd2000, 0xd4000, 0xd6000, 0xd8000, 0xda000, 0xdc000, 0xde000
 267};
 268#define NUM_ADDRS ARRAY_SIZE(wd7000_biosaddr)
 269
 270static const unsigned short wd7000_iobase[] = {
 271        0x0300, 0x0308, 0x0310, 0x0318, 0x0320, 0x0328, 0x0330, 0x0338,
 272        0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370, 0x0378,
 273        0x0380, 0x0388, 0x0390, 0x0398, 0x03a0, 0x03a8, 0x03b0, 0x03b8,
 274        0x03c0, 0x03c8, 0x03d0, 0x03d8, 0x03e0, 0x03e8, 0x03f0, 0x03f8
 275};
 276#define NUM_IOPORTS ARRAY_SIZE(wd7000_iobase)
 277
 278static const short wd7000_irq[] = { 3, 4, 5, 7, 9, 10, 11, 12, 14, 15 };
 279#define NUM_IRQS ARRAY_SIZE(wd7000_irq)
 280
 281static const short wd7000_dma[] = { 5, 6, 7 };
 282#define NUM_DMAS ARRAY_SIZE(wd7000_dma)
 283
 284/*
 285 * The following is set up by wd7000_detect, and used thereafter for
 286 * proc and other global ookups
 287 */
 288
 289#define UNITS   8
 290static struct Scsi_Host *wd7000_host[UNITS];
 291
 292#define BUS_ON    64            /* x 125ns = 8000ns (BIOS default) */
 293#define BUS_OFF   15            /* x 125ns = 1875ns (BIOS default) */
 294
 295/*
 296 *  Standard Adapter Configurations - used by wd7000_detect
 297 */
 298typedef struct {
 299        short irq;              /* IRQ level                                  */
 300        short dma;              /* DMA channel                                */
 301        unsigned iobase;        /* I/O base address                           */
 302        short bus_on;           /* Time that WD7000 spends on the AT-bus when */
 303        /* transferring data. BIOS default is 8000ns. */
 304        short bus_off;          /* Time that WD7000 spends OFF THE BUS after  */
 305        /* while it is transferring data.             */
 306        /* BIOS default is 1875ns                     */
 307} Config;
 308
 309/*
 310 * Add here your configuration...
 311 */
 312static Config configs[] = {
 313        {15, 6, 0x350, BUS_ON, BUS_OFF},        /* defaults for single adapter */
 314        {11, 5, 0x320, BUS_ON, BUS_OFF},        /* defaults for second adapter */
 315        {7, 6, 0x350, BUS_ON, BUS_OFF}, /* My configuration (Zaga)     */
 316        {-1, -1, 0x0, BUS_ON, BUS_OFF}  /* Empty slot                  */
 317};
 318#define NUM_CONFIGS ARRAY_SIZE(configs)
 319
 320/*
 321 *  The following list defines strings to look for in the BIOS that identify
 322 *  it as the WD7000-FASST2 SST BIOS.  I suspect that something should be
 323 *  added for the Future Domain version.
 324 */
 325typedef struct signature {
 326        const char *sig;        /* String to look for            */
 327        unsigned long ofs;      /* offset from BIOS base address */
 328        unsigned len;           /* length of string              */
 329} Signature;
 330
 331static const Signature signatures[] = {
 332        {"SSTBIOS", 0x0000d, 7} /* "SSTBIOS" @ offset 0x0000d */
 333};
 334#define NUM_SIGNATURES ARRAY_SIZE(signatures)
 335
 336
 337/*
 338 *  I/O Port Offsets and Bit Definitions
 339 *  4 addresses are used.  Those not defined here are reserved.
 340 */
 341#define ASC_STAT        0       /* Status,  Read          */
 342#define ASC_COMMAND     0       /* Command, Write         */
 343#define ASC_INTR_STAT   1       /* Interrupt Status, Read */
 344#define ASC_INTR_ACK    1       /* Acknowledge, Write     */
 345#define ASC_CONTROL     2       /* Control, Write         */
 346
 347/*
 348 * ASC Status Port
 349 */
 350#define INT_IM          0x80    /* Interrupt Image Flag           */
 351#define CMD_RDY         0x40    /* Command Port Ready             */
 352#define CMD_REJ         0x20    /* Command Port Byte Rejected     */
 353#define ASC_INIT        0x10    /* ASC Initialized Flag           */
 354#define ASC_STATMASK    0xf0    /* The lower 4 Bytes are reserved */
 355
 356/*
 357 * COMMAND opcodes
 358 *
 359 *  Unfortunately, I have no idea how to properly use some of these commands,
 360 *  as the OEM manual does not make it clear.  I have not been able to use
 361 *  enable/disable unsolicited interrupts or the reset commands with any
 362 *  discernible effect whatsoever.  I think they may be related to certain
 363 *  ICB commands, but again, the OEM manual doesn't make that clear.
 364 */
 365#define NO_OP             0     /* NO-OP toggles CMD_RDY bit in ASC_STAT  */
 366#define INITIALIZATION    1     /* initialization (10 bytes)              */
 367#define DISABLE_UNS_INTR  2     /* disable unsolicited interrupts         */
 368#define ENABLE_UNS_INTR   3     /* enable unsolicited interrupts          */
 369#define INTR_ON_FREE_OGMB 4     /* interrupt on free OGMB                 */
 370#define SOFT_RESET        5     /* SCSI bus soft reset                    */
 371#define HARD_RESET_ACK    6     /* SCSI bus hard reset acknowledge        */
 372#define START_OGMB        0x80  /* start command in OGMB (n)              */
 373#define SCAN_OGMBS        0xc0  /* start multiple commands, signature (n) */
 374                                /*    where (n) = lower 6 bits            */
 375/*
 376 * For INITIALIZATION:
 377 */
 378typedef struct initCmd {
 379        unchar op;              /* command opcode (= 1)                    */
 380        unchar ID;              /* Adapter's SCSI ID                       */
 381        unchar bus_on;          /* Bus on time, x 125ns (see below)        */
 382        unchar bus_off;         /* Bus off time, ""         ""             */
 383        unchar rsvd;            /* Reserved                                */
 384        unchar mailboxes[3];    /* Address of Mailboxes, MSB first         */
 385        unchar ogmbs;           /* Number of outgoing MBs, max 64, 0,1 = 1 */
 386        unchar icmbs;           /* Number of incoming MBs,   ""       ""   */
 387} InitCmd;
 388
 389/*
 390 * Interrupt Status Port - also returns diagnostic codes at ASC reset
 391 *
 392 * if msb is zero, the lower bits are diagnostic status
 393 * Diagnostics:
 394 * 01   No diagnostic error occurred
 395 * 02   RAM failure
 396 * 03   FIFO R/W failed
 397 * 04   SBIC register read/write failed
 398 * 05   Initialization D-FF failed
 399 * 06   Host IRQ D-FF failed
 400 * 07   ROM checksum error
 401 * Interrupt status (bitwise):
 402 * 10NNNNNN   outgoing mailbox NNNNNN is free
 403 * 11NNNNNN   incoming mailbox NNNNNN needs service
 404 */
 405#define MB_INTR    0xC0         /* Mailbox Service possible/required */
 406#define IMB_INTR   0x40         /* 1 Incoming / 0 Outgoing           */
 407#define MB_MASK    0x3f         /* mask for mailbox number           */
 408
 409/*
 410 * CONTROL port bits
 411 */
 412#define INT_EN     0x08         /* Interrupt Enable */
 413#define DMA_EN     0x04         /* DMA Enable       */
 414#define SCSI_RES   0x02         /* SCSI Reset       */
 415#define ASC_RES    0x01         /* ASC Reset        */
 416
 417/*
 418 * Driver data structures:
 419 *   - mb and scbs are required for interfacing with the host adapter.
 420 *     An SCB has extra fields not visible to the adapter; mb's
 421 *     _cannot_ do this, since the adapter assumes they are contiguous in
 422 *     memory, 4 bytes each, with ICMBs following OGMBs, and uses this fact
 423 *     to access them.
 424 *   - An icb is for host-only (non-SCSI) commands.  ICBs are 16 bytes each;
 425 *     the additional bytes are used only by the driver.
 426 *   - For now, a pool of SCBs are kept in global storage by this driver,
 427 *     and are allocated and freed as needed.
 428 *
 429 *  The 7000-FASST2 marks OGMBs empty as soon as it has _started_ a command,
 430 *  not when it has finished.  Since the SCB must be around for completion,
 431 *  problems arise when SCBs correspond to OGMBs, which may be reallocated
 432 *  earlier (or delayed unnecessarily until a command completes).
 433 *  Mailboxes are used as transient data structures, simply for
 434 *  carrying SCB addresses to/from the 7000-FASST2.
 435 *
 436 *  Note also since SCBs are not "permanently" associated with mailboxes,
 437 *  there is no need to keep a global list of scsi_cmnd pointers indexed
 438 *  by OGMB.   Again, SCBs reference their scsi_cmnds directly, so mailbox
 439 *  indices need not be involved.
 440 */
 441
 442/*
 443 *  WD7000-specific scatter/gather element structure
 444 */
 445typedef struct sgb {
 446        unchar len[3];
 447        unchar ptr[3];          /* Also SCSI-style - MSB first */
 448} Sgb;
 449
 450typedef struct scb {            /* Command Control Block 5.4.1               */
 451        unchar op;              /* Command Control Block Operation Code      */
 452        unchar idlun;           /* op=0,2:Target Id, op=1:Initiator Id       */
 453        /* Outbound data transfer, length is checked */
 454        /* Inbound data transfer, length is checked  */
 455        /* Logical Unit Number                       */
 456        unchar cdb[12];         /* SCSI Command Block                        */
 457        volatile unchar status; /* SCSI Return Status                        */
 458        volatile unchar vue;    /* Vendor Unique Error Code                  */
 459        unchar maxlen[3];       /* Maximum Data Transfer Length              */
 460        unchar dataptr[3];      /* SCSI Data Block Pointer                   */
 461        unchar linkptr[3];      /* Next Command Link Pointer                 */
 462        unchar direc;           /* Transfer Direction                        */
 463        unchar reserved2[6];    /* SCSI Command Descriptor Block             */
 464        /* end of hardware SCB                       */
 465        struct scsi_cmnd *SCpnt;/* scsi_cmnd using this SCB                  */
 466        Sgb sgb[WD7000_SG];     /* Scatter/gather list for this SCB          */
 467        Adapter *host;          /* host adapter                              */
 468        struct scb *next;       /* for lists of scbs                         */
 469} Scb;
 470
 471/*
 472 *  This driver is written to allow host-only commands to be executed.
 473 *  These use a 16-byte block called an ICB.  The format is extended by the
 474 *  driver to 18 bytes, to support the status returned in the ICMB and
 475 *  an execution phase code.
 476 *
 477 *  There are other formats besides these; these are the ones I've tried
 478 *  to use.  Formats for some of the defined ICB opcodes are not defined
 479 *  (notably, get/set unsolicited interrupt status) in my copy of the OEM
 480 *  manual, and others are ambiguous/hard to follow.
 481 */
 482#define ICB_OP_MASK           0x80      /* distinguishes scbs from icbs        */
 483#define ICB_OP_OPEN_RBUF      0x80      /* open receive buffer                 */
 484#define ICB_OP_RECV_CMD       0x81      /* receive command from initiator      */
 485#define ICB_OP_RECV_DATA      0x82      /* receive data from initiator         */
 486#define ICB_OP_RECV_SDATA     0x83      /* receive data with status from init. */
 487#define ICB_OP_SEND_DATA      0x84      /* send data with status to initiator  */
 488#define ICB_OP_SEND_STAT      0x86      /* send command status to initiator    */
 489                                        /* 0x87 is reserved                    */
 490#define ICB_OP_READ_INIT      0x88      /* read initialization bytes           */
 491#define ICB_OP_READ_ID        0x89      /* read adapter's SCSI ID              */
 492#define ICB_OP_SET_UMASK      0x8A      /* set unsolicited interrupt mask      */
 493#define ICB_OP_GET_UMASK      0x8B      /* read unsolicited interrupt mask     */
 494#define ICB_OP_GET_REVISION   0x8C      /* read firmware revision level        */
 495#define ICB_OP_DIAGNOSTICS    0x8D      /* execute diagnostics                 */
 496#define ICB_OP_SET_EPARMS     0x8E      /* set execution parameters            */
 497#define ICB_OP_GET_EPARMS     0x8F      /* read execution parameters           */
 498
 499typedef struct icbRecvCmd {
 500        unchar op;
 501        unchar IDlun;           /* Initiator SCSI ID/lun     */
 502        unchar len[3];          /* command buffer length     */
 503        unchar ptr[3];          /* command buffer address    */
 504        unchar rsvd[7];         /* reserved                  */
 505        volatile unchar vue;    /* vendor-unique error code  */
 506        volatile unchar status; /* returned (icmb) status    */
 507        volatile unchar phase;  /* used by interrupt handler */
 508} IcbRecvCmd;
 509
 510typedef struct icbSendStat {
 511        unchar op;
 512        unchar IDlun;           /* Target SCSI ID/lun                  */
 513        unchar stat;            /* (outgoing) completion status byte 1 */
 514        unchar rsvd[12];        /* reserved                            */
 515        volatile unchar vue;    /* vendor-unique error code            */
 516        volatile unchar status; /* returned (icmb) status              */
 517        volatile unchar phase;  /* used by interrupt handler           */
 518} IcbSendStat;
 519
 520typedef struct icbRevLvl {
 521        unchar op;
 522        volatile unchar primary;        /* primary revision level (returned)   */
 523        volatile unchar secondary;      /* secondary revision level (returned) */
 524        unchar rsvd[12];        /* reserved                            */
 525        volatile unchar vue;    /* vendor-unique error code            */
 526        volatile unchar status; /* returned (icmb) status              */
 527        volatile unchar phase;  /* used by interrupt handler           */
 528} IcbRevLvl;
 529
 530typedef struct icbUnsMask {     /* I'm totally guessing here */
 531        unchar op;
 532        volatile unchar mask[14];       /* mask bits                 */
 533#if 0
 534        unchar rsvd[12];        /* reserved                  */
 535#endif
 536        volatile unchar vue;    /* vendor-unique error code  */
 537        volatile unchar status; /* returned (icmb) status    */
 538        volatile unchar phase;  /* used by interrupt handler */
 539} IcbUnsMask;
 540
 541typedef struct icbDiag {
 542        unchar op;
 543        unchar type;            /* diagnostics type code (0-3) */
 544        unchar len[3];          /* buffer length               */
 545        unchar ptr[3];          /* buffer address              */
 546        unchar rsvd[7];         /* reserved                    */
 547        volatile unchar vue;    /* vendor-unique error code    */
 548        volatile unchar status; /* returned (icmb) status      */
 549        volatile unchar phase;  /* used by interrupt handler   */
 550} IcbDiag;
 551
 552#define ICB_DIAG_POWERUP   0    /* Power-up diags only       */
 553#define ICB_DIAG_WALKING   1    /* walking 1's pattern       */
 554#define ICB_DIAG_DMA       2    /* DMA - system memory diags */
 555#define ICB_DIAG_FULL      3    /* do both 1 & 2             */
 556
 557typedef struct icbParms {
 558        unchar op;
 559        unchar rsvd1;           /* reserved                  */
 560        unchar len[3];          /* parms buffer length       */
 561        unchar ptr[3];          /* parms buffer address      */
 562        unchar idx[2];          /* index (MSB-LSB)           */
 563        unchar rsvd2[5];        /* reserved                  */
 564        volatile unchar vue;    /* vendor-unique error code  */
 565        volatile unchar status; /* returned (icmb) status    */
 566        volatile unchar phase;  /* used by interrupt handler */
 567} IcbParms;
 568
 569typedef struct icbAny {
 570        unchar op;
 571        unchar data[14];        /* format-specific data      */
 572        volatile unchar vue;    /* vendor-unique error code  */
 573        volatile unchar status; /* returned (icmb) status    */
 574        volatile unchar phase;  /* used by interrupt handler */
 575} IcbAny;
 576
 577typedef union icb {
 578        unchar op;              /* ICB opcode                     */
 579        IcbRecvCmd recv_cmd;    /* format for receive command     */
 580        IcbSendStat send_stat;  /* format for send status         */
 581        IcbRevLvl rev_lvl;      /* format for get revision level  */
 582        IcbDiag diag;           /* format for execute diagnostics */
 583        IcbParms eparms;        /* format for get/set exec parms  */
 584        IcbAny icb;             /* generic format                 */
 585        unchar data[18];
 586} Icb;
 587
 588#ifdef MODULE
 589static char *wd7000;
 590module_param(wd7000, charp, 0);
 591#endif
 592
 593/*
 594 *  Driver SCB structure pool.
 595 *
 596 *  The SCBs declared here are shared by all host adapters; hence, this
 597 *  structure is not part of the Adapter structure.
 598 */
 599static Scb scbs[MAX_SCBS];
 600static Scb *scbfree;            /* free list         */
 601static int freescbs = MAX_SCBS; /* free list counter */
 602static spinlock_t scbpool_lock; /* guards the scb free list and count */
 603
 604/*
 605 *  END of data/declarations - code follows.
 606 */
 607static void __init setup_error(char *mesg, int *ints)
 608{
 609        if (ints[0] == 3)
 610                printk(KERN_ERR "wd7000_setup: \"wd7000=%d,%d,0x%x\" -> %s\n", ints[1], ints[2], ints[3], mesg);
 611        else if (ints[0] == 4)
 612                printk(KERN_ERR "wd7000_setup: \"wd7000=%d,%d,0x%x,%d\" -> %s\n", ints[1], ints[2], ints[3], ints[4], mesg);
 613        else
 614                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);
 615}
 616
 617
 618/*
 619 * Note: You can now set these options from the kernel's "command line".
 620 * The syntax is:
 621 *
 622 *     wd7000=<IRQ>,<DMA>,<IO>[,<BUS_ON>[,<BUS_OFF>]]
 623 *
 624 * , where BUS_ON and BUS_OFF are in nanoseconds. BIOS default values
 625 * are 8000ns for BUS_ON and 1875ns for BUS_OFF.
 626 * eg:
 627 *     wd7000=7,6,0x350
 628 *
 629 * will configure the driver for a WD-7000 controller
 630 * using IRQ 15 with a DMA channel 6, at IO base address 0x350.
 631 */
 632static int __init wd7000_setup(char *str)
 633{
 634        static short wd7000_card_num;   /* .bss will zero this */
 635        short i;
 636        int ints[6];
 637
 638        (void) get_options(str, ARRAY_SIZE(ints), ints);
 639
 640        if (wd7000_card_num >= NUM_CONFIGS) {
 641                printk(KERN_ERR "%s: Too many \"wd7000=\" configurations in " "command line!\n", __func__);
 642                return 0;
 643        }
 644
 645        if ((ints[0] < 3) || (ints[0] > 5)) {
 646                printk(KERN_ERR "%s: Error in command line!  " "Usage: wd7000=<IRQ>,<DMA>,IO>[,<BUS_ON>" "[,<BUS_OFF>]]\n", __func__);
 647        } else {
 648                for (i = 0; i < NUM_IRQS; i++)
 649                        if (ints[1] == wd7000_irq[i])
 650                                break;
 651
 652                if (i == NUM_IRQS) {
 653                        setup_error("invalid IRQ.", ints);
 654                        return 0;
 655                } else
 656                        configs[wd7000_card_num].irq = ints[1];
 657
 658                for (i = 0; i < NUM_DMAS; i++)
 659                        if (ints[2] == wd7000_dma[i])
 660                                break;
 661
 662                if (i == NUM_DMAS) {
 663                        setup_error("invalid DMA channel.", ints);
 664                        return 0;
 665                } else
 666                        configs[wd7000_card_num].dma = ints[2];
 667
 668                for (i = 0; i < NUM_IOPORTS; i++)
 669                        if (ints[3] == wd7000_iobase[i])
 670                                break;
 671
 672                if (i == NUM_IOPORTS) {
 673                        setup_error("invalid I/O base address.", ints);
 674                        return 0;
 675                } else
 676                        configs[wd7000_card_num].iobase = ints[3];
 677
 678                if (ints[0] > 3) {
 679                        if ((ints[4] < 500) || (ints[4] > 31875)) {
 680                                setup_error("BUS_ON value is out of range (500" " to 31875 nanoseconds)!", ints);
 681                                configs[wd7000_card_num].bus_on = BUS_ON;
 682                        } else
 683                                configs[wd7000_card_num].bus_on = ints[4] / 125;
 684                } else
 685                        configs[wd7000_card_num].bus_on = BUS_ON;
 686
 687                if (ints[0] > 4) {
 688                        if ((ints[5] < 500) || (ints[5] > 31875)) {
 689                                setup_error("BUS_OFF value is out of range (500" " to 31875 nanoseconds)!", ints);
 690                                configs[wd7000_card_num].bus_off = BUS_OFF;
 691                        } else
 692                                configs[wd7000_card_num].bus_off = ints[5] / 125;
 693                } else
 694                        configs[wd7000_card_num].bus_off = BUS_OFF;
 695
 696                if (wd7000_card_num) {
 697                        for (i = 0; i < (wd7000_card_num - 1); i++) {
 698                                int j = i + 1;
 699
 700                                for (; j < wd7000_card_num; j++)
 701                                        if (configs[i].irq == configs[j].irq) {
 702                                                setup_error("duplicated IRQ!", ints);
 703                                                return 0;
 704                                        }
 705                                if (configs[i].dma == configs[j].dma) {
 706                                        setup_error("duplicated DMA " "channel!", ints);
 707                                        return 0;
 708                                }
 709                                if (configs[i].iobase == configs[j].iobase) {
 710                                        setup_error("duplicated I/O " "base address!", ints);
 711                                        return 0;
 712                                }
 713                        }
 714                }
 715
 716                dprintk(KERN_DEBUG "wd7000_setup: IRQ=%d, DMA=%d, I/O=0x%x, "
 717                        "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);
 718
 719                wd7000_card_num++;
 720        }
 721        return 1;
 722}
 723
 724__setup("wd7000=", wd7000_setup);
 725
 726static inline void any2scsi(unchar * scsi, int any)
 727{
 728        *scsi++ = (unsigned)any >> 16;
 729        *scsi++ = (unsigned)any >> 8;
 730        *scsi++ = any;
 731}
 732
 733static inline int scsi2int(unchar * scsi)
 734{
 735        return (scsi[0] << 16) | (scsi[1] << 8) | scsi[2];
 736}
 737
 738static inline void wd7000_enable_intr(Adapter * host)
 739{
 740        host->control |= INT_EN;
 741        outb(host->control, host->iobase + ASC_CONTROL);
 742}
 743
 744
 745static inline void wd7000_enable_dma(Adapter * host)
 746{
 747        unsigned long flags;
 748        host->control |= DMA_EN;
 749        outb(host->control, host->iobase + ASC_CONTROL);
 750
 751        flags = claim_dma_lock();
 752        set_dma_mode(host->dma, DMA_MODE_CASCADE);
 753        enable_dma(host->dma);
 754        release_dma_lock(flags);
 755
 756}
 757
 758
 759#define WAITnexttimeout 200     /* 2 seconds */
 760
 761static inline short WAIT(unsigned port, unsigned mask, unsigned allof, unsigned noneof)
 762{
 763        unsigned WAITbits;
 764        unsigned long WAITtimeout = jiffies + WAITnexttimeout;
 765
 766        while (time_before_eq(jiffies, WAITtimeout)) {
 767                WAITbits = inb(port) & mask;
 768
 769                if (((WAITbits & allof) == allof) && ((WAITbits & noneof) == 0))
 770                        return (0);
 771        }
 772
 773        return (1);
 774}
 775
 776
 777static inline int command_out(Adapter * host, unchar * cmd, int len)
 778{
 779        if (!WAIT(host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0)) {
 780                while (len--) {
 781                        do {
 782                                outb(*cmd, host->iobase + ASC_COMMAND);
 783                                WAIT(host->iobase + ASC_STAT, ASC_STATMASK, CMD_RDY, 0);
 784                        } while (inb(host->iobase + ASC_STAT) & CMD_REJ);
 785
 786                        cmd++;
 787                }
 788
 789                return (1);
 790        }
 791
 792        printk(KERN_WARNING "wd7000 command_out: WAIT failed(%d)\n", len + 1);
 793
 794        return (0);
 795}
 796
 797
 798/*
 799 *  This version of alloc_scbs is in preparation for supporting multiple
 800 *  commands per lun and command chaining, by queueing pending commands.
 801 *  We will need to allocate Scbs in blocks since they will wait to be
 802 *  executed so there is the possibility of deadlock otherwise.
 803 *  Also, to keep larger requests from being starved by smaller requests,
 804 *  we limit access to this routine with an internal busy flag, so that
 805 *  the satisfiability of a request is not dependent on the size of the
 806 *  request.
 807 */
 808static inline Scb *alloc_scbs(struct Scsi_Host *host, int needed)
 809{
 810        Scb *scb, *p = NULL;
 811        unsigned long flags;
 812        unsigned long timeout = jiffies + WAITnexttimeout;
 813        unsigned long now;
 814        int i;
 815
 816        if (needed <= 0)
 817                return (NULL);  /* sanity check */
 818
 819        spin_unlock_irq(host->host_lock);
 820
 821      retry:
 822        while (freescbs < needed) {
 823                timeout = jiffies + WAITnexttimeout;
 824                do {
 825                        /* FIXME: can we actually just yield here ?? */
 826                        for (now = jiffies; now == jiffies;)
 827                                cpu_relax();    /* wait a jiffy */
 828                } while (freescbs < needed && time_before_eq(jiffies, timeout));
 829                /*
 830                 *  If we get here with enough free Scbs, we can take them.
 831                 *  Otherwise, we timed out and didn't get enough.
 832                 */
 833                if (freescbs < needed) {
 834                        printk(KERN_ERR "wd7000: can't get enough free SCBs.\n");
 835                        return (NULL);
 836                }
 837        }
 838
 839        /* Take the lock, then check we didn't get beaten, if so try again */
 840        spin_lock_irqsave(&scbpool_lock, flags);
 841        if (freescbs < needed) {
 842                spin_unlock_irqrestore(&scbpool_lock, flags);
 843                goto retry;
 844        }
 845
 846        scb = scbfree;
 847        freescbs -= needed;
 848        for (i = 0; i < needed; i++) {
 849                p = scbfree;
 850                scbfree = p->next;
 851        }
 852        p->next = NULL;
 853
 854        spin_unlock_irqrestore(&scbpool_lock, flags);
 855
 856        spin_lock_irq(host->host_lock);
 857        return (scb);
 858}
 859
 860
 861static inline void free_scb(Scb * scb)
 862{
 863        unsigned long flags;
 864
 865        spin_lock_irqsave(&scbpool_lock, flags);
 866
 867        memset(scb, 0, sizeof(Scb));
 868        scb->next = scbfree;
 869        scbfree = scb;
 870        freescbs++;
 871
 872        spin_unlock_irqrestore(&scbpool_lock, flags);
 873}
 874
 875
 876static inline void init_scbs(void)
 877{
 878        int i;
 879
 880        spin_lock_init(&scbpool_lock);
 881
 882        /* This is only ever called before the SCB pool is active */
 883
 884        scbfree = &(scbs[0]);
 885        memset(scbs, 0, sizeof(scbs));
 886        for (i = 0; i < MAX_SCBS - 1; i++) {
 887                scbs[i].next = &(scbs[i + 1]);
 888                scbs[i].SCpnt = NULL;
 889        }
 890        scbs[MAX_SCBS - 1].next = NULL;
 891        scbs[MAX_SCBS - 1].SCpnt = NULL;
 892}
 893
 894
 895static int mail_out(Adapter * host, Scb * scbptr)
 896/*
 897 *  Note: this can also be used for ICBs; just cast to the parm type.
 898 */
 899{
 900        int i, ogmb;
 901        unsigned long flags;
 902        unchar start_ogmb;
 903        Mailbox *ogmbs = host->mb.ogmb;
 904        int *next_ogmb = &(host->next_ogmb);
 905
 906        dprintk("wd7000_mail_out: 0x%06lx", (long) scbptr);
 907
 908        /* We first look for a free outgoing mailbox */
 909        spin_lock_irqsave(host->sh->host_lock, flags);
 910        ogmb = *next_ogmb;
 911        for (i = 0; i < OGMB_CNT; i++) {
 912                if (ogmbs[ogmb].status == 0) {
 913                        dprintk(" using OGMB 0x%x", ogmb);
 914                        ogmbs[ogmb].status = 1;
 915                        any2scsi((unchar *) ogmbs[ogmb].scbptr, (int) scbptr);
 916
 917                        *next_ogmb = (ogmb + 1) % OGMB_CNT;
 918                        break;
 919                } else
 920                        ogmb = (ogmb + 1) % OGMB_CNT;
 921        }
 922        spin_unlock_irqrestore(host->sh->host_lock, flags);
 923
 924        dprintk(", scb is 0x%06lx", (long) scbptr);
 925
 926        if (i >= OGMB_CNT) {
 927                /*
 928                 *  Alternatively, we might issue the "interrupt on free OGMB",
 929                 *  and sleep, but it must be ensured that it isn't the init
 930                 *  task running.  Instead, this version assumes that the caller
 931                 *  will be persistent, and try again.  Since it's the adapter
 932                 *  that marks OGMB's free, waiting even with interrupts off
 933                 *  should work, since they are freed very quickly in most cases.
 934                 */
 935                dprintk(", no free OGMBs.\n");
 936                return (0);
 937        }
 938
 939        wd7000_enable_intr(host);
 940
 941        start_ogmb = START_OGMB | ogmb;
 942        command_out(host, &start_ogmb, 1);
 943
 944        dprintk(", awaiting interrupt.\n");
 945
 946        return (1);
 947}
 948
 949
 950static int make_code(unsigned hosterr, unsigned scsierr)
 951{
 952#ifdef WD7000_DEBUG
 953        int in_error = hosterr;
 954#endif
 955
 956        switch ((hosterr >> 8) & 0xff) {
 957        case 0:         /* Reserved */
 958                hosterr = DID_ERROR;
 959                break;
 960        case 1:         /* Command Complete, no errors */
 961                hosterr = DID_OK;
 962                break;
 963        case 2:         /* Command complete, error logged in scb status (scsierr) */
 964                hosterr = DID_OK;
 965                break;
 966        case 4:         /* Command failed to complete - timeout */
 967                hosterr = DID_TIME_OUT;
 968                break;
 969        case 5:         /* Command terminated; Bus reset by external device */
 970                hosterr = DID_RESET;
 971                break;
 972        case 6:         /* Unexpected Command Received w/ host as target */
 973                hosterr = DID_BAD_TARGET;
 974                break;
 975        case 80:                /* Unexpected Reselection */
 976        case 81:                /* Unexpected Selection */
 977                hosterr = DID_BAD_INTR;
 978                break;
 979        case 82:                /* Abort Command Message  */
 980                hosterr = DID_ABORT;
 981                break;
 982        case 83:                /* SCSI Bus Software Reset */
 983        case 84:                /* SCSI Bus Hardware Reset */
 984                hosterr = DID_RESET;
 985                break;
 986        default:                /* Reserved */
 987                hosterr = DID_ERROR;
 988        }
 989#ifdef WD7000_DEBUG
 990        if (scsierr || hosterr)
 991                dprintk("\nSCSI command error: SCSI 0x%02x host 0x%04x return %d\n", scsierr, in_error, hosterr);
 992#endif
 993        return (scsierr | (hosterr << 16));
 994}
 995
 996#define wd7000_intr_ack(host)   outb (0, host->iobase + ASC_INTR_ACK)
 997
 998
 999static irqreturn_t wd7000_intr(int irq, void *dev_id)
1000{
1001        Adapter *host = (Adapter *) dev_id;
1002        int flag, icmb, errstatus, icmb_status;
1003        int host_error, scsi_error;
1004        Scb *scb;       /* for SCSI commands */
1005        IcbAny *icb;    /* for host commands */
1006        struct scsi_cmnd *SCpnt;
1007        Mailbox *icmbs = host->mb.icmb;
1008        unsigned long flags;
1009
1010        spin_lock_irqsave(host->sh->host_lock, flags);
1011        host->int_counter++;
1012
1013        dprintk("wd7000_intr: irq = %d, host = 0x%06lx\n", irq, (long) host);
1014
1015        flag = inb(host->iobase + ASC_INTR_STAT);
1016
1017        dprintk("wd7000_intr: intr stat = 0x%02x\n", flag);
1018
1019        if (!(inb(host->iobase + ASC_STAT) & INT_IM)) {
1020                /* NB: these are _very_ possible if IRQ 15 is being used, since
1021                 * it's the "garbage collector" on the 2nd 8259 PIC.  Specifically,
1022                 * any interrupt signal into the 8259 which can't be identified
1023                 * comes out as 7 from the 8259, which is 15 to the host.  Thus, it
1024                 * is a good thing the WD7000 has an interrupt status port, so we
1025                 * can sort these out.  Otherwise, electrical noise and other such
1026                 * problems would be indistinguishable from valid interrupts...
1027                 */
1028                dprintk("wd7000_intr: phantom interrupt...\n");
1029                goto ack;
1030        }
1031
1032        if (!(flag & MB_INTR))
1033                goto ack;
1034
1035        /* The interrupt is for a mailbox */
1036        if (!(flag & IMB_INTR)) {
1037                dprintk("wd7000_intr: free outgoing mailbox\n");
1038                /*
1039                 * If sleep_on() and the "interrupt on free OGMB" command are
1040                 * used in mail_out(), wake_up() should correspondingly be called
1041                 * here.  For now, we don't need to do anything special.
1042                 */
1043                goto ack;
1044        }
1045
1046        /* The interrupt is for an incoming mailbox */
1047        icmb = flag & MB_MASK;
1048        icmb_status = icmbs[icmb].status;
1049        if (icmb_status & 0x80) {       /* unsolicited - result in ICMB */
1050                dprintk("wd7000_intr: unsolicited interrupt 0x%02x\n", icmb_status);
1051                goto ack;
1052        }
1053
1054        /* Aaaargh! (Zaga) */
1055        scb = isa_bus_to_virt(scsi2int((unchar *) icmbs[icmb].scbptr));
1056        icmbs[icmb].status = 0;
1057        if (scb->op & ICB_OP_MASK) {    /* an SCB is done */
1058                icb = (IcbAny *) scb;
1059                icb->status = icmb_status;
1060                icb->phase = 0;
1061                goto ack;
1062        }
1063
1064        SCpnt = scb->SCpnt;
1065        if (--(SCpnt->SCp.phase) <= 0) {        /* all scbs are done */
1066                host_error = scb->vue | (icmb_status << 8);
1067                scsi_error = scb->status;
1068                errstatus = make_code(host_error, scsi_error);
1069                SCpnt->result = errstatus;
1070
1071                free_scb(scb);
1072
1073                SCpnt->scsi_done(SCpnt);
1074        }
1075
1076 ack:
1077        dprintk("wd7000_intr: return from interrupt handler\n");
1078        wd7000_intr_ack(host);
1079
1080        spin_unlock_irqrestore(host->sh->host_lock, flags);
1081        return IRQ_HANDLED;
1082}
1083
1084static int wd7000_queuecommand_lck(struct scsi_cmnd *SCpnt,
1085                void (*done)(struct scsi_cmnd *))
1086{
1087        Scb *scb;
1088        Sgb *sgb;
1089        unchar *cdb = (unchar *) SCpnt->cmnd;
1090        unchar idlun;
1091        short cdblen;
1092        int nseg;
1093        Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
1094
1095        cdblen = SCpnt->cmd_len;
1096        idlun = ((SCpnt->device->id << 5) & 0xe0) | (SCpnt->device->lun & 7);
1097        SCpnt->scsi_done = done;
1098        SCpnt->SCp.phase = 1;
1099        scb = alloc_scbs(SCpnt->device->host, 1);
1100        scb->idlun = idlun;
1101        memcpy(scb->cdb, cdb, cdblen);
1102        scb->direc = 0x40;      /* Disable direction check */
1103
1104        scb->SCpnt = SCpnt;     /* so we can find stuff later */
1105        SCpnt->host_scribble = (unchar *) scb;
1106        scb->host = host;
1107
1108        nseg = scsi_sg_count(SCpnt);
1109        if (nseg > 1) {
1110                struct scatterlist *sg;
1111                unsigned i;
1112
1113                dprintk("Using scatter/gather with %d elements.\n", nseg);
1114
1115                sgb = scb->sgb;
1116                scb->op = 1;
1117                any2scsi(scb->dataptr, (int) sgb);
1118                any2scsi(scb->maxlen, nseg * sizeof(Sgb));
1119
1120                scsi_for_each_sg(SCpnt, sg, nseg, i) {
1121                        any2scsi(sgb[i].ptr, isa_page_to_bus(sg_page(sg)) + sg->offset);
1122                        any2scsi(sgb[i].len, sg->length);
1123                }
1124        } else {
1125                scb->op = 0;
1126                if (nseg) {
1127                        struct scatterlist *sg = scsi_sglist(SCpnt);
1128                        any2scsi(scb->dataptr, isa_page_to_bus(sg_page(sg)) + sg->offset);
1129                }
1130                any2scsi(scb->maxlen, scsi_bufflen(SCpnt));
1131        }
1132
1133        /* FIXME: drop lock and yield here ? */
1134
1135        while (!mail_out(host, scb))
1136                cpu_relax();    /* keep trying */
1137
1138        return 0;
1139}
1140
1141static DEF_SCSI_QCMD(wd7000_queuecommand)
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_lock_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
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.