Annotation of Gnu-Mach/linux/src/drivers/scsi/wd7000.h, revision 1.1.1.1

1.1       root        1: /* $Id: wd7000.h,v 1.1 1999/04/26 05:55:19 tb Exp $
                      2:  *
                      3:  * Header file for the WD-7000 driver for Linux
                      4:  *
                      5:  * John Boyd <[email protected]>  Jan 1994:
                      6:  * This file has been reduced to only the definitions needed for the
                      7:  * WD7000 host structure.
                      8:  *
                      9:  * Revision by Miroslav Zagorac <[email protected]>  Jun 1997.
                     10:  */
                     11: #ifndef _WD7000_H
                     12: 
                     13: #include <linux/version.h>
                     14: #include <linux/types.h>
                     15: #include <linux/kdev_t.h>
                     16: 
                     17: #ifndef NULL
                     18: #define NULL 0L
                     19: #endif
                     20: 
                     21: /*
                     22:  *  In this version, sg_tablesize now defaults to WD7000_SG, and will
                     23:  *  be set to SG_NONE for older boards.  This is the reverse of the
                     24:  *  previous default, and was changed so that the driver-level
                     25:  *  Scsi_Host_Template would reflect the driver's support for scatter/
                     26:  *  gather.
                     27:  *
                     28:  *  Also, it has been reported that boards at Revision 6 support scatter/
                     29:  *  gather, so the new definition of an "older" board has been changed
                     30:  *  accordingly.
                     31:  */
                     32: #define WD7000_Q    16
                     33: #define WD7000_SG   16
                     34: 
                     35: #ifdef WD7000_DEFINES
                     36: /*
                     37:  *  Mailbox structure sizes.
                     38:  *  I prefer to keep the number of ICMBs much larger than the number of
                     39:  *  OGMBs.  OGMBs are used very quickly by the driver to start one or
                     40:  *  more commands, while ICMBs are used by the host adapter per command.
                     41:  */
                     42: #define OGMB_CNT       16
                     43: #define ICMB_CNT       32
                     44: 
                     45: /*
                     46:  *  Scb's are shared by all active adapters.  If you'd rather conserve
                     47:  *  memory, use a smaller number (> 0, of course) - things will should
                     48:  *  still work OK.
                     49:  */
                     50: #define MAX_SCBS       (4 * WD7000_Q)
                     51: 
                     52: /*
                     53:  *  WD7000-specific mailbox structure
                     54:  */
                     55: typedef volatile struct {
                     56:     unchar status;
                     57:     unchar scbptr[3];          /* SCSI-style - MSB first (big endian) */
                     58: } Mailbox;
                     59: 
                     60: /*
                     61:  *  This structure should contain all per-adapter global data.  I.e., any
                     62:  *  new global per-adapter data should put in here.
                     63:  */
                     64: typedef struct {
                     65:     struct Scsi_Host *sh;      /* Pointer to Scsi_Host structure    */
                     66:     int iobase;                        /* This adapter's I/O base address   */
                     67:     int irq;                   /* This adapter's IRQ level          */
                     68:     int dma;                   /* This adapter's DMA channel        */
                     69:     int int_counter;           /* This adapter's interrupt counter  */
                     70:     int bus_on;                        /* This adapter's BUS_ON time        */
                     71:     int bus_off;               /* This adapter's BUS_OFF time       */
                     72:     struct {                   /* This adapter's mailboxes          */
                     73:        Mailbox ogmb[OGMB_CNT]; /* Outgoing mailboxes                */
                     74:        Mailbox icmb[ICMB_CNT]; /* Incoming mailboxes                */
                     75:     } mb;
                     76:     int next_ogmb;             /* to reduce contention at mailboxes */
                     77:     unchar control;            /* shadows CONTROL port value        */
                     78:     unchar rev1;               /* filled in by wd7000_revision      */
                     79:     unchar rev2;
                     80: } Adapter;
                     81: 
                     82: 
                     83: /*
                     84:  * possible irq range
                     85:  */
                     86: #define IRQ_MIN                3
                     87: #define IRQ_MAX                15
                     88: #define IRQS           (IRQ_MAX - IRQ_MIN + 1)
                     89: 
                     90: #define BUS_ON         64      /* x 125ns = 8000ns (BIOS default) */
                     91: #define BUS_OFF                15      /* x 125ns = 1875ns (BIOS default) */
                     92: 
                     93: /*
                     94:  *  Standard Adapter Configurations - used by wd7000_detect
                     95:  */
                     96: typedef struct {
                     97:     short irq;         /* IRQ level                                  */
                     98:     short dma;         /* DMA channel                                */
                     99:     uint iobase;       /* I/O base address                           */
                    100:     short bus_on;      /* Time that WD7000 spends on the AT-bus when */
                    101:                        /* transferring data. BIOS default is 8000ns. */
                    102:     short bus_off;     /* Time that WD7000 spends OFF THE BUS after  */
                    103:                        /* while it is transferring data.             */
                    104:                        /* BIOS default is 1875ns                     */
                    105: } Config;
                    106: 
                    107: 
                    108: /*
                    109:  *  The following list defines strings to look for in the BIOS that identify
                    110:  *  it as the WD7000-FASST2 SST BIOS.  I suspect that something should be
                    111:  *  added for the Future Domain version.
                    112:  */
                    113: typedef struct {
                    114:     const char *sig;           /* String to look for            */
                    115:     ulong ofs;                 /* offset from BIOS base address */
                    116:     uint len;                  /* length of string              */
                    117: } Signature;
                    118: 
                    119: /*
                    120:  *  I/O Port Offsets and Bit Definitions
                    121:  *  4 addresses are used.  Those not defined here are reserved.
                    122:  */
                    123: #define ASC_STAT       0       /* Status,  Read          */
                    124: #define ASC_COMMAND    0       /* Command, Write         */
                    125: #define ASC_INTR_STAT  1       /* Interrupt Status, Read */
                    126: #define ASC_INTR_ACK   1       /* Acknowledge, Write     */
                    127: #define ASC_CONTROL    2       /* Control, Write         */
                    128: 
                    129: /*
                    130:  * ASC Status Port
                    131:  */
                    132: #define INT_IM         0x80    /* Interrupt Image Flag           */
                    133: #define CMD_RDY                0x40    /* Command Port Ready             */
                    134: #define CMD_REJ                0x20    /* Command Port Byte Rejected     */
                    135: #define ASC_INIT        0x10   /* ASC Initialized Flag           */
                    136: #define ASC_STATMASK    0xf0   /* The lower 4 Bytes are reserved */
                    137: 
                    138: /*
                    139:  * COMMAND opcodes
                    140:  *
                    141:  *  Unfortunately, I have no idea how to properly use some of these commands,
                    142:  *  as the OEM manual does not make it clear.  I have not been able to use
                    143:  *  enable/disable unsolicited interrupts or the reset commands with any
                    144:  *  discernible effect whatsoever.  I think they may be related to certain
                    145:  *  ICB commands, but again, the OEM manual doesn't make that clear.
                    146:  */
                    147: #define NO_OP                  0       /* NO-OP toggles CMD_RDY bit in ASC_STAT  */
                    148: #define INITIALIZATION         1       /* initialization (10 bytes)              */
                    149: #define DISABLE_UNS_INTR       2       /* disable unsolicited interrupts         */
                    150: #define ENABLE_UNS_INTR                3       /* enable unsolicited interrupts          */
                    151: #define INTR_ON_FREE_OGMB      4       /* interrupt on free OGMB                 */
                    152: #define SOFT_RESET             5       /* SCSI bus soft reset                    */
                    153: #define HARD_RESET_ACK         6       /* SCSI bus hard reset acknowledge        */
                    154: #define START_OGMB             0x80    /* start command in OGMB (n)              */
                    155: #define SCAN_OGMBS             0xc0    /* start multiple commands, signature (n) */
                    156:                                        /*    where (n) = lower 6 bits            */
                    157: /*
                    158:  * For INITIALIZATION:
                    159:  */
                    160: typedef struct {
                    161:     unchar op;                 /* command opcode (= 1)                    */
                    162:     unchar ID;                 /* Adapter's SCSI ID                       */
                    163:     unchar bus_on;             /* Bus on time, x 125ns (see below)        */
                    164:     unchar bus_off;            /* Bus off time, ""         ""             */
                    165:     unchar rsvd;               /* Reserved                                */
                    166:     unchar mailboxes[3];       /* Address of Mailboxes, MSB first         */
                    167:     unchar ogmbs;              /* Number of outgoing MBs, max 64, 0,1 = 1 */
                    168:     unchar icmbs;              /* Number of incoming MBs,   ""       ""   */
                    169: } InitCmd;
                    170: 
                    171: /*
                    172:  * Interrupt Status Port - also returns diagnostic codes at ASC reset
                    173:  *
                    174:  * if msb is zero, the lower bits are diagnostic status
                    175:  * Diagnostics:
                    176:  * 01   No diagnostic error occurred
                    177:  * 02   RAM failure
                    178:  * 03   FIFO R/W failed
                    179:  * 04   SBIC register read/write failed
                    180:  * 05   Initialization D-FF failed
                    181:  * 06   Host IRQ D-FF failed
                    182:  * 07   ROM checksum error
                    183:  * Interrupt status (bitwise):
                    184:  * 10NNNNNN   outgoing mailbox NNNNNN is free
                    185:  * 11NNNNNN   incoming mailbox NNNNNN needs service
                    186:  */
                    187: #define MB_INTR                0xC0    /* Mailbox Service possible/required */
                    188: #define IMB_INTR       0x40    /* 1 Incoming / 0 Outgoing           */
                    189: #define MB_MASK                0x3f    /* mask for mailbox number           */
                    190: 
                    191: /*
                    192:  * CONTROL port bits
                    193:  */
                    194: #define INT_EN         0x08    /* Interrupt Enable */
                    195: #define DMA_EN         0x04    /* DMA Enable       */
                    196: #define SCSI_RES       0x02    /* SCSI Reset       */
                    197: #define ASC_RES                0x01    /* ASC Reset        */
                    198: 
                    199: /*
                    200:  * Driver data structures:
                    201:  *   - mb and scbs are required for interfacing with the host adapter.
                    202:  *     An SCB has extra fields not visible to the adapter; mb's
                    203:  *     _cannot_ do this, since the adapter assumes they are contiguous in
                    204:  *     memory, 4 bytes each, with ICMBs following OGMBs, and uses this fact
                    205:  *     to access them.
                    206:  *   - An icb is for host-only (non-SCSI) commands.  ICBs are 16 bytes each;
                    207:  *     the additional bytes are used only by the driver.
                    208:  *   - For now, a pool of SCBs are kept in global storage by this driver,
                    209:  *     and are allocated and freed as needed.
                    210:  *
                    211:  *  The 7000-FASST2 marks OGMBs empty as soon as it has _started_ a command,
                    212:  *  not when it has finished.  Since the SCB must be around for completion,
                    213:  *  problems arise when SCBs correspond to OGMBs, which may be reallocated
                    214:  *  earlier (or delayed unnecessarily until a command completes).
                    215:  *  Mailboxes are used as transient data structures, simply for
                    216:  *  carrying SCB addresses to/from the 7000-FASST2.
                    217:  *
                    218:  *  Note also since SCBs are not "permanently" associated with mailboxes,
                    219:  *  there is no need to keep a global list of Scsi_Cmnd pointers indexed
                    220:  *  by OGMB.   Again, SCBs reference their Scsi_Cmnds directly, so mailbox
                    221:  *  indices need not be involved.
                    222:  */
                    223: 
                    224: /*
                    225:  *  WD7000-specific scatter/gather element structure
                    226:  */
                    227: typedef struct {
                    228:     unchar len[3];
                    229:     unchar ptr[3];             /* Also SCSI-style - MSB first */
                    230: } Sgb;
                    231: 
                    232: typedef struct {               /* Command Control Block 5.4.1               */
                    233:     unchar op;                 /* Command Control Block Operation Code      */
                    234:     unchar idlun;              /* op=0,2:Target Id, op=1:Initiator Id       */
                    235:                                /* Outbound data transfer, length is checked */
                    236:                                /* Inbound data transfer, length is checked  */
                    237:                                /* Logical Unit Number                       */
                    238:     unchar cdb[12];            /* SCSI Command Block                        */
                    239:     volatile unchar status;    /* SCSI Return Status                        */
                    240:     volatile unchar vue;       /* Vendor Unique Error Code                  */
                    241:     unchar maxlen[3];          /* Maximum Data Transfer Length              */
                    242:     unchar dataptr[3];         /* SCSI Data Block Pointer                   */
                    243:     unchar linkptr[3];         /* Next Command Link Pointer                 */
                    244:     unchar direc;              /* Transfer Direction                        */
                    245:     unchar reserved2[6];       /* SCSI Command Descriptor Block             */
                    246:                                /* end of hardware SCB                       */
                    247:     Scsi_Cmnd *SCpnt;          /* Scsi_Cmnd using this SCB                  */
                    248:     Sgb sgb[WD7000_SG];                /* Scatter/gather list for this SCB          */
                    249:     Adapter *host;             /* host adapter                              */
                    250:     unchar used;               /* flag                                      */
                    251: } Scb;
                    252: 
                    253: /*
                    254:  *  This driver is written to allow host-only commands to be executed.
                    255:  *  These use a 16-byte block called an ICB.  The format is extended by the
                    256:  *  driver to 18 bytes, to support the status returned in the ICMB and
                    257:  *  an execution phase code.
                    258:  *
                    259:  *  There are other formats besides these; these are the ones I've tried
                    260:  *  to use.  Formats for some of the defined ICB opcodes are not defined
                    261:  *  (notably, get/set unsolicited interrupt status) in my copy of the OEM
                    262:  *  manual, and others are ambiguous/hard to follow.
                    263:  */
                    264: #define ICB_OP_MASK            0x80    /* distinguishes scbs from icbs        */
                    265: #define ICB_OP_OPEN_RBUF       0x80    /* open receive buffer                 */
                    266: #define ICB_OP_RECV_CMD                0x81    /* receive command from initiator      */
                    267: #define ICB_OP_RECV_DATA       0x82    /* receive data from initiator         */
                    268: #define ICB_OP_RECV_SDATA      0x83    /* receive data with status from init. */
                    269: #define ICB_OP_SEND_DATA       0x84    /* send data with status to initiator  */
                    270: #define ICB_OP_SEND_STAT       0x86    /* send command status to initiator    */
                    271:                                        /* 0x87 is reserved                    */
                    272: #define ICB_OP_READ_INIT       0x88    /* read initialization bytes           */
                    273: #define ICB_OP_READ_ID         0x89    /* read adapter's SCSI ID              */
                    274: #define ICB_OP_SET_UMASK       0x8A    /* set unsolicited interrupt mask      */
                    275: #define ICB_OP_GET_UMASK       0x8B    /* read unsolicited interrupt mask     */
                    276: #define ICB_OP_GET_REVISION    0x8C    /* read firmware revision level        */
                    277: #define ICB_OP_DIAGNOSTICS     0x8D    /* execute diagnostics                 */
                    278: #define ICB_OP_SET_EPARMS      0x8E    /* set execution parameters            */
                    279: #define ICB_OP_GET_EPARMS      0x8F    /* read execution parameters           */
                    280: 
                    281: typedef struct {
                    282:     unchar op;
                    283:     unchar IDlun;              /* Initiator SCSI ID/lun     */
                    284:     unchar len[3];             /* command buffer length     */
                    285:     unchar ptr[3];             /* command buffer address    */
                    286:     unchar rsvd[7];            /* reserved                  */
                    287:     volatile unchar vue;       /* vendor-unique error code  */
                    288:     volatile unchar status;    /* returned (icmb) status    */
                    289:     volatile unchar phase;     /* used by interrupt handler */
                    290: } IcbRecvCmd;
                    291: 
                    292: typedef struct {
                    293:     unchar op;
                    294:     unchar IDlun;              /* Target SCSI ID/lun                  */
                    295:     unchar stat;               /* (outgoing) completion status byte 1 */
                    296:     unchar rsvd[12];           /* reserved                            */
                    297:     volatile unchar vue;       /* vendor-unique error code            */
                    298:     volatile unchar status;    /* returned (icmb) status              */
                    299:     volatile unchar phase;     /* used by interrupt handler           */
                    300: } IcbSendStat;
                    301: 
                    302: typedef struct {
                    303:     unchar op;
                    304:     volatile unchar primary;   /* primary revision level (returned)   */
                    305:     volatile unchar secondary; /* secondary revision level (returned) */
                    306:     unchar rsvd[12];           /* reserved                            */
                    307:     volatile unchar vue;       /* vendor-unique error code            */
                    308:     volatile unchar status;    /* returned (icmb) status              */
                    309:     volatile unchar phase;     /* used by interrupt handler           */
                    310: } IcbRevLvl;
                    311: 
                    312: typedef struct {       /* I'm totally guessing here */
                    313:     unchar op;
                    314:     volatile unchar mask[14];  /* mask bits                 */
                    315: #if 0
                    316:     unchar rsvd[12];           /* reserved                  */
                    317: #endif
                    318:     volatile unchar vue;       /* vendor-unique error code  */
                    319:     volatile unchar status;    /* returned (icmb) status    */
                    320:     volatile unchar phase;     /* used by interrupt handler */
                    321: } IcbUnsMask;
                    322: 
                    323: typedef struct {
                    324:     unchar op;
                    325:     unchar type;               /* diagnostics type code (0-3) */
                    326:     unchar len[3];             /* buffer length               */
                    327:     unchar ptr[3];             /* buffer address              */
                    328:     unchar rsvd[7];            /* reserved                    */
                    329:     volatile unchar vue;       /* vendor-unique error code    */
                    330:     volatile unchar status;    /* returned (icmb) status      */
                    331:     volatile unchar phase;     /* used by interrupt handler   */
                    332: } IcbDiag;
                    333: 
                    334: #define ICB_DIAG_POWERUP       0       /* Power-up diags only       */
                    335: #define ICB_DIAG_WALKING       1       /* walking 1's pattern       */
                    336: #define ICB_DIAG_DMA           2       /* DMA - system memory diags */
                    337: #define ICB_DIAG_FULL          3       /* do both 1 & 2             */
                    338: 
                    339: typedef struct {
                    340:     unchar op;
                    341:     unchar rsvd1;              /* reserved                  */
                    342:     unchar len[3];             /* parms buffer length       */
                    343:     unchar ptr[3];             /* parms buffer address      */
                    344:     unchar idx[2];             /* index (MSB-LSB)           */
                    345:     unchar rsvd2[5];           /* reserved                  */
                    346:     volatile unchar vue;       /* vendor-unique error code  */
                    347:     volatile unchar status;    /* returned (icmb) status    */
                    348:     volatile unchar phase;     /* used by interrupt handler */
                    349: } IcbParms;
                    350: 
                    351: typedef struct {
                    352:     unchar op;
                    353:     unchar data[14];           /* format-specific data      */
                    354:     volatile unchar vue;       /* vendor-unique error code  */
                    355:     volatile unchar status;    /* returned (icmb) status    */
                    356:     volatile unchar phase;     /* used by interrupt handler */
                    357: } IcbAny;
                    358: 
                    359: typedef union {
                    360:     unchar op;                 /* ICB opcode                     */
                    361:     IcbRecvCmd recv_cmd;       /* format for receive command     */
                    362:     IcbSendStat send_stat;     /* format for send status         */
                    363:     IcbRevLvl rev_lvl;         /* format for get revision level  */
                    364:     IcbDiag diag;              /* format for execute diagnostics */
                    365:     IcbParms eparms;           /* format for get/set exec parms  */
                    366:     IcbAny icb;                        /* generic format                 */
                    367:     unchar data[18];
                    368: } Icb;
                    369: 
                    370: #define WAITnexttimeout                200     /* 2 seconds */
                    371: 
                    372: typedef union {                        /* let's cheat... */
                    373:     int i;
                    374:     unchar u[sizeof (int)];    /* the sizeof(int) makes it more portable */
                    375: } i_u;
                    376: 
                    377: #endif /* WD7000_DEFINES */
                    378: 
                    379: 
                    380: #if (LINUX_VERSION_CODE >= 0x020100)
                    381: 
                    382: #define WD7000 {                                       \
                    383:     proc_dir:          &proc_scsi_wd7000,              \
                    384:     proc_info:         wd7000_proc_info,               \
                    385:     name:              "Western Digital WD-7000",      \
                    386:     detect:            wd7000_detect,                  \
                    387:     command:           wd7000_command,                 \
                    388:     queuecommand:      wd7000_queuecommand,            \
                    389:     abort:             wd7000_abort,                   \
                    390:     reset:             wd7000_reset,                   \
                    391:     bios_param:                wd7000_biosparam,               \
                    392:     can_queue:         WD7000_Q,                       \
                    393:     this_id:           7,                              \
                    394:     sg_tablesize:      WD7000_SG,                      \
                    395:     cmd_per_lun:       1,                              \
                    396:     unchecked_isa_dma: 1,                              \
                    397:     use_clustering:    ENABLE_CLUSTERING,              \
                    398:     use_new_eh_code:   0                               \
                    399: }
                    400: 
                    401: #else /* Use old scsi code */
                    402: 
                    403: #define WD7000 {                                       \
                    404:     proc_dir:          &proc_scsi_wd7000,              \
                    405:     proc_info:         wd7000_proc_info,               \
                    406:     name:              "Western Digital WD-7000",      \
                    407:     detect:            wd7000_detect,                  \
                    408:     command:           wd7000_command,                 \
                    409:     queuecommand:      wd7000_queuecommand,            \
                    410:     abort:             wd7000_abort,                   \
                    411:     reset:             wd7000_reset,                   \
                    412:     bios_param:                wd7000_biosparam,               \
                    413:     can_queue:         WD7000_Q,                       \
                    414:     this_id:           7,                              \
                    415:     sg_tablesize:      WD7000_SG,                      \
                    416:     cmd_per_lun:       1,                              \
                    417:     unchecked_isa_dma: 1,                              \
                    418:     use_clustering:    ENABLE_CLUSTERING,              \
                    419: }
                    420: 
                    421: #endif /* LINUX_VERSION_CODE */
                    422: 
                    423: 
                    424: extern struct proc_dir_entry proc_scsi_wd7000;
                    425: 
                    426: 
                    427: #ifdef WD7000_DEFINES
                    428: int  wd7000_diagnostics    (Adapter *, int);
                    429: int  wd7000_init           (Adapter *);
                    430: void wd7000_revision       (Adapter *);
                    431: #endif /* WD7000_DEFINES */
                    432: 
                    433: void wd7000_setup          (char *, int *);
                    434: int  make_code             (uint, uint);
                    435: void wd7000_intr_handle    (int, void *, struct pt_regs *);
                    436: void do_wd7000_intr_handle (int, void *, struct pt_regs *);
                    437: int  wd7000_queuecommand   (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
                    438: int  wd7000_command        (Scsi_Cmnd *);
                    439: int  wd7000_set_info       (char *, int, struct Scsi_Host *);
                    440: int  wd7000_proc_info      (char *, char **, off_t, int, int, int);
                    441: int  wd7000_detect         (Scsi_Host_Template *);
                    442: int  wd7000_abort          (Scsi_Cmnd *);
                    443: int  wd7000_reset          (Scsi_Cmnd *, uint);
                    444: int  wd7000_biosparam      (Disk *, kdev_t, int *);
                    445: 
                    446: #endif /* _WD7000_H */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.