|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.