| #ifndef _WD7000_H |
| |
| /* $Id: $ |
| * |
| * Header file for the WD-7000 driver for Linux |
| * |
| * $Log: $ |
| * Revision 1.1 1992/07/24 06:27:38 root |
| * Initial revision |
| * |
| * Revision 1.1 1992/07/05 08:32:32 root |
| * Initial revision |
| * |
| * Revision 1.1 1992/05/15 18:38:05 root |
| * Initial revision |
| * |
| * Revision 1.1 1992/04/02 03:23:13 drew |
| * Initial revision |
| * |
| * Revision 1.3 1992/01/27 14:46:29 tthorn |
| * *** empty log message *** |
| * |
| */ |
| |
| #include <linux/types.h> |
| |
| #undef STATMASK |
| #undef CONTROL |
| |
| #define IO_BASE 0x350 |
| #define IRQ_LVL 15 |
| #define DMA_CH 6 |
| #define OGMB_CNT 8 |
| #define ICMB_CNT 16 |
| |
| /* I/O Port interface 4.2 */ |
| /* READ */ |
| #define ASC_STAT IO_BASE |
| #define INT_IM 0x80 /* Interrupt Image Flag */ |
| #define CMD_RDY 0x40 /* Command Port Ready */ |
| #define CMD_REJ 0x20 /* Command Port Byte Rejected */ |
| #define ASC_INI 0x10 /* ASC Initialized Flag */ |
| #define STATMASK 0xf0 /* The lower 4 Bytes are reserved */ |
| |
| /* This register serves two purposes |
| * Diagnostics error code |
| * Interrupt Status |
| */ |
| #define INTR_STAT ASC_STAT+1 |
| #define ANYINTR 0x80 /* Mailbox Service possible/required */ |
| #define IMB 0x40 /* 1 Incoming / 0 Outgoing */ |
| #define MBMASK 0x3f |
| /* if MSb is zero, the lower bits are diagnostic status * |
| * Diagnostics: |
| * 01 No diagnostic error occurred |
| * 02 RAM failure |
| * 03 FIFO R/W failed |
| * 04 SBIC register read/write failed |
| * 05 Initialization D-FF failed |
| * 06 Host IRQ D-FF failed |
| * 07 ROM checksum error |
| * Interrupt status (bitwise): |
| * 10NNNNNN outgoing mailbox NNNNNN is free |
| * 11NNNNNN incoming mailbox NNNNNN needs service |
| */ |
| |
| /* WRITE */ |
| #define COMMAND ASC_STAT |
| /* |
| * COMMAND opcodes |
| */ |
| #define NO_OP 0 |
| #define INITIALIZATION 1 /* initialization after reset (10 bytes) */ |
| #define DISABLE_UNS_INTR 2 /* disable unsolicited interrupts */ |
| #define ENABLE_UNS_INTR 3 /* enable unsolicited interrupts */ |
| #define INTR_ON_FREE_OGMB 4 /* interrupt on free OGMB */ |
| #define SCSI_SOFT_RESET 5 /* SCSI soft reset */ |
| #define SCSI_HARD_RESET 6 /* SCSI hard reset acknowledge */ |
| #define START_OGMB 0x80 /* start command in OGMB (n) */ |
| #define SCAN_OGMBS 0xc0 /* start multiple commands, signature (n) */ |
| /* where (n) = lower 6 bits */ |
| /* |
| * For INITIALIZATION: |
| */ |
| #define BUS_ON 48 /* x 125ns, 48 = 6000ns, BIOS uses 8000ns */ |
| #define BUS_OFF 24 /* x 125ns, 24 = 3000ns, BIOS uses 1875ns */ |
| |
| #define INTR_ACK ASC_STAT+1 |
| |
| |
| #define CONTROL ASC_STAT+2 |
| #define INT_EN 0x08 /* Interrupt Enable */ |
| #define DMA_EN 0x04 /* DMA Enable */ |
| #define SCSI_RES 0x02 /* SCSI Reset */ |
| #define ASC_RES 0x01 /* ASC Reset */ |
| |
| /* Mailbox Definition */ |
| |
| struct wd_mailbox{ |
| unchar status; |
| unchar scbptr[3]; |
| }; |
| |
| |
| /* These belong in scsi.h also */ |
| #undef any2scsi |
| #define any2scsi(up, p) \ |
| (up)[0] = (((long)(p)) >> 16); \ |
| (up)[1] = ((long)(p)) >> 8; \ |
| (up)[2] = ((long)(p)); |
| |
| #define scsi2int(up) ( (((long)*(up)) << 16) + (((long)(up)[1]) << 8) + ((long)(up)[2]) ) |
| |
| #define xany2scsi(up, p) \ |
| (up)[0] = ((long)(p)) >> 24; \ |
| (up)[1] = ((long)(p)) >> 16; \ |
| (up)[2] = ((long)(p)) >> 8; \ |
| (up)[3] = ((long)(p)); |
| |
| #define xscsi2int(up) ( (((long)(up)[0]) << 24) + (((long)(up)[1]) << 16) \ |
| + (((long)(up)[2]) << 8) + ((long)(up)[3]) ) |
| |
| #define MAX_CDB 12 |
| #define MAX_SENSE 14 |
| |
| typedef struct scb { /* Command Control Block 5.4.1 */ |
| unchar op; /* Command Control Block Operation Code */ |
| unchar idlun; /* op=0,2:Target Id, op=1:Initiator Id */ |
| /* Outbound data transfer, length is checked*/ |
| /* Inbound data transfer, length is checked */ |
| /* Logical Unit Number */ |
| unchar cdb[12]; /* SCSI Command Block */ |
| unchar status; /* SCSI Return Status */ |
| unchar vue; /* Vendor Unique Error Code */ |
| unchar maxlen[3]; /* Maximum Data Transfer Length */ |
| unchar dataptr[3]; /* SCSI Data Block Pointer */ |
| unchar linkptr[3]; /* Next Command Link Pointer */ |
| unchar direc; /* Transfer Direction */ |
| unchar reserved2[6]; /* SCSI Command Descriptor Block */ |
| /* end of hardware SCB */ |
| Scsi_Cmnd *SCpnt; /* Scsi_Cmnd using this SCB */ |
| struct scb *next; /* for lists of scbs */ |
| } Scb; |
| |
| /* |
| * WD7000-specific scatter/gather element structure |
| */ |
| typedef struct sgb { |
| unchar len[3]; |
| unchar ptr[3]; |
| } Sgb; |
| |
| /* |
| * Note: MAX_SCBS _must_ be defined large enough to keep ahead of the |
| * demand for SCBs, which will be at most WD7000_Q * WD7000_SG. 1 is |
| * added to each because they can be 0. |
| */ |
| #define MAX_SCBS ((WD7000_Q+1) * (WD7000_SG+1)) |
| |
| /* |
| * The driver is written to allow host-only commands to be executed. These |
| * use a 16-byte block called an ICB. |
| * |
| * (Currently, only wd7000_info uses this, to get the firmware rev. level.) |
| */ |
| #define ICB_STATUS 16 /* set to icmb status by wd7000_intr_handle */ |
| #define ICB_PHASE 17 /* set to 0 by wd7000_intr_handle */ |
| #define ICB_LEN 18 /* actually 16; this includes the above */ |
| |
| int wd7000_detect(int); |
| int wd7000_command(Scsi_Cmnd *); |
| int wd7000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); |
| int wd7000_abort(Scsi_Cmnd *, int); |
| const char *wd7000_info(void); |
| int wd7000_reset(void); |
| int wd7000_biosparam(int, int, int*); |
| |
| #ifndef NULL |
| #define NULL 0 |
| #endif |
| |
| /* |
| * Define WD7000_SG to be the number of Sgbs that will fit in a block of |
| * size WD7000_SCRIBBLE. WD7000_SCRIBBLE must be 512, 1024, 2048, or 4096. |
| * |
| * The sg_tablesize value will default to SG_NONE for older boards (before |
| * rev 7.0), but will be changed to WD7000_SG when a newer board is |
| * detected. |
| */ |
| #define WD7000_SCRIBBLE 512 |
| |
| #define WD7000_Q OGMB_CNT |
| #define WD7000_SG (WD7000_SCRIBBLE / sizeof(Sgb)) |
| |
| #define WD7000 {\ |
| "Western Digital WD-7000", \ |
| wd7000_detect, \ |
| wd7000_info, wd7000_command, \ |
| wd7000_queuecommand, \ |
| wd7000_abort, \ |
| wd7000_reset, \ |
| NULL, \ |
| wd7000_biosparam, \ |
| WD7000_Q, 7, SG_NONE, 1, 0, 1} |
| #endif |