wd7000.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:54k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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