1 #ifndef _WD7000_H 2 3 /* $Id: $ 4 * 5 * Header file for the WD-7000 driver for Linux 6 * 7 * $Log: $ 8 * Revision 1.1 1992/07/24 06:27:38 root 9 * Initial revision 10 * 11 * Revision 1.1 1992/07/05 08:32:32 root 12 * Initial revision 13 * 14 * Revision 1.1 1992/05/15 18:38:05 root 15 * Initial revision 16 * 17 * Revision 1.1 1992/04/02 03:23:13 drew 18 * Initial revision 19 * 20 * Revision 1.3 1992/01/27 14:46:29 tthorn 21 * *** empty log message *** 22 * 23 */ 24 25 #include <linux/types.h> 26 27 #undef STATMASK 28 #undef CONTROL 29 30 #define IO_BASE 0x350 31 #define IRQ_LVL 15 32 #define DMA_CH 6 33 #define OGMB_CNT 8 34 #define ICMB_CNT 16 35 36 /* I/O Port interface 4.2 */ 37 /* READ */ 38 #define ASC_STAT IO_BASE 39 #define INT_IM 0x80 /* Interrupt Image Flag */ 40 #define CMD_RDY 0x40 /* Command Port Ready */ 41 #define CMD_REJ 0x20 /* Command Port Byte Rejected */ 42 #define ASC_INI 0x10 /* ASC Initialized Flag */ 43 #define STATMASK 0xf0 /* The lower 4 Bytes are reserved */ 44 45 /* This register serves two purposes 46 * Diagnostics error code 47 * Interrupt Status 48 */ 49 #define INTR_STAT ASC_STAT+1 50 #define ANYINTR 0x80 /* Mailbox Service possible/required */ 51 #define IMB 0x40 /* 1 Incoming / 0 Outgoing */ 52 #define MBMASK 0x3f 53 /* if MSb is zero, the lower bits are diagnostic status * 54 * Diagnostics: 55 * 01 No diagnostic error occurred 56 * 02 RAM failure 57 * 03 FIFO R/W failed 58 * 04 SBIC register read/write failed 59 * 05 Initialization D-FF failed 60 * 06 Host IRQ D-FF failed 61 * 07 ROM checksum error 62 * Interrupt status (bitwise): 63 * 10NNNNNN outgoing mailbox NNNNNN is free 64 * 11NNNNNN incoming mailbox NNNNNN needs service 65 */ 66 67 /* WRITE */ 68 #define COMMAND ASC_STAT 69 /* 70 * COMMAND opcodes 71 */ 72 #define NO_OP 0 73 #define INITIALIZATION 1 /* initialization after reset (10 bytes) */ 74 #define DISABLE_UNS_INTR 2 /* disable unsolicited interrupts */ 75 #define ENABLE_UNS_INTR 3 /* enable unsolicited interrupts */ 76 #define INTR_ON_FREE_OGMB 4 /* interrupt on free OGMB */ 77 #define SCSI_SOFT_RESET 5 /* SCSI soft reset */ 78 #define SCSI_HARD_RESET 6 /* SCSI hard reset acknowledge */ 79 #define START_OGMB 0x80 /* start command in OGMB (n) */ 80 #define SCAN_OGMBS 0xc0 /* start multiple commands, signature (n) */ 81 /* where (n) = lower 6 bits */ 82 /* 83 * For INITIALIZATION: 84 */ 85 #define BUS_ON 48 /* x 125ns, 48 = 6000ns, BIOS uses 8000ns */ 86 #define BUS_OFF 24 /* x 125ns, 24 = 3000ns, BIOS uses 1875ns */ 87 88 #define INTR_ACK ASC_STAT+1 89 90 91 #define CONTROL ASC_STAT+2 92 #define INT_EN 0x08 /* Interrupt Enable */ 93 #define DMA_EN 0x04 /* DMA Enable */ 94 #define SCSI_RES 0x02 /* SCSI Reset */ 95 #define ASC_RES 0x01 /* ASC Reset */ 96 97 /* Mailbox Definition */ 98 99 struct wd_mailbox{ 100 unchar status; 101 unchar scbptr[3]; 102 }; 103 104 105 /* These belong in scsi.h also */ 106 #undef any2scsi 107 #define any2scsi(up, p) \ 108 (up)[0] = (((long)(p)) >> 16); \ 109 (up)[1] = ((long)(p)) >> 8; \ 110 (up)[2] = ((long)(p)); 111 112 #define scsi2int(up) ( (((long)*(up)) << 16) + (((long)(up)[1]) << 8) + ((long)(up)[2]) ) 113 114 #define xany2scsi(up, p) \ 115 (up)[0] = ((long)(p)) >> 24; \ 116 (up)[1] = ((long)(p)) >> 16; \ 117 (up)[2] = ((long)(p)) >> 8; \ 118 (up)[3] = ((long)(p)); 119 120 #define xscsi2int(up) ( (((long)(up)[0]) << 24) + (((long)(up)[1]) << 16) \ 121 + (((long)(up)[2]) << 8) + ((long)(up)[3]) ) 122 123 #define MAX_CDB 12 124 #define MAX_SENSE 14 125 126 typedef struct scb { /* Command Control Block 5.4.1 */ 127 unchar op; /* Command Control Block Operation Code */ 128 unchar idlun; /* op=0,2:Target Id, op=1:Initiator Id */ 129 /* Outbound data transfer, length is checked*/ 130 /* Inbound data transfer, length is checked */ 131 /* Logical Unit Number */ 132 unchar cdb[12]; /* SCSI Command Block */ 133 unchar status; /* SCSI Return Status */ 134 unchar vue; /* Vendor Unique Error Code */ 135 unchar maxlen[3]; /* Maximum Data Transfer Length */ 136 unchar dataptr[3]; /* SCSI Data Block Pointer */ 137 unchar linkptr[3]; /* Next Command Link Pointer */ 138 unchar direc; /* Transfer Direction */ 139 unchar reserved2[6]; /* SCSI Command Descriptor Block */ 140 /* end of hardware SCB */ 141 Scsi_Cmnd *SCpnt; /* Scsi_Cmnd using this SCB */ 142 struct scb *next; /* for lists of scbs */ 143 } Scb; 144 145 /* 146 * WD7000-specific scatter/gather element structure 147 */ 148 typedef struct sgb { 149 unchar len[3]; 150 unchar ptr[3]; 151 } Sgb; 152 153 /* 154 * Note: MAX_SCBS _must_ be defined large enough to keep ahead of the 155 * demand for SCBs, which will be at most WD7000_Q * WD7000_SG. 1 is 156 * added to each because they can be 0. 157 */ 158 #define MAX_SCBS ((WD7000_Q+1) * (WD7000_SG+1)) 159 160 /* 161 * The driver is written to allow host-only commands to be executed. These 162 * use a 16-byte block called an ICB. 163 * 164 * (Currently, only wd7000_info uses this, to get the firmware rev. level.) 165 */ 166 #define ICB_STATUS 16 /* set to icmb status by wd7000_intr_handle */ 167 #define ICB_PHASE 17 /* set to 0 by wd7000_intr_handle */ 168 #define ICB_LEN 18 /* actually 16; this includes the above */ 169 170 int wd7000_detect(int); 171 int wd7000_command(Scsi_Cmnd *); 172 int wd7000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); 173 int wd7000_abort(Scsi_Cmnd *, int); 174 const char *wd7000_info(void); 175 int wd7000_reset(void); 176 int wd7000_biosparam(int, int, int*); 177 178 #ifndef NULL 179 #define NULL 0 180 #endif 181 182 /* 183 * Define WD7000_SG to be the number of Sgbs that will fit in a block of 184 * size WD7000_SCRIBBLE. WD7000_SCRIBBLE must be 512, 1024, 2048, or 4096. 185 * 186 * The sg_tablesize value will default to SG_NONE for older boards (before 187 * rev 7.0), but will be changed to WD7000_SG when a newer board is 188 * detected. 189 */ 190 #define WD7000_SCRIBBLE 512 191 192 #define WD7000_Q OGMB_CNT 193 #define WD7000_SG (WD7000_SCRIBBLE / sizeof(Sgb)) 194 195 #define WD7000 {\ 196 "Western Digital WD-7000", \ 197 wd7000_detect, \ 198 wd7000_info, wd7000_command, \ 199 wd7000_queuecommand, \ 200 wd7000_abort, \ 201 wd7000_reset, \ 202 NULL, \ 203 wd7000_biosparam, \ 204 WD7000_Q, 7, SG_NONE, 1, 0, 1} 205 #endif