OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [scsi/] [wd7000.h] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* $Id: wd7000.h,v 1.1 2005-12-20 10:17:46 jcastillo Exp $
2
 *
3
 * Header file for the WD-7000 driver for Linux
4
 *
5
 * John Boyd <boyd@cis.ohio-state.edu>  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 <zaga@fly.cc.fer.hr>  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 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.