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