Annotation of sys/dev/ic/gdtvar.h, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: gdtvar.h,v 1.13 2007/04/28 00:34:25 deraadt Exp $ */
2:
3: /*
4: * Copyright (c) 1999, 2000 Niklas Hallqvist. All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: * 1. Redistributions of source code must retain the above copyright
10: * notice, this list of conditions and the following disclaimer.
11: * 2. Redistributions in binary form must reproduce the above copyright
12: * notice, this list of conditions and the following disclaimer in the
13: * documentation and/or other materials provided with the distribution.
14: *
15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25: */
26:
27: /*
28: * This driver would not have written if it was not for the hardware donations
29: * from both ICP-Vortex and Öko.neT. I want to thank them for their support.
30: */
31:
32: #define DEVNAME(s) ((s)->sc_dev.dv_xname)
33: #define GDT_CMD_RESERVE 4 /* Internal driver cmd reserve. */
34:
35: #define GDT_IOCTL_DUMMY _IOWR('B', 32, struct gdt_dummy)
36: struct gdt_dummy {
37: void *cookie;
38: int x;
39: };
40:
41: /* XXX Is this pragma necessary? */
42: #pragma pack(1)
43:
44: #define GDT_SCRATCH_SZ 4096
45:
46: #define GDT_IOCTL_GENERAL _IOWR('B', 33, gdt_ucmd_t) /* general IOCTL */
47: typedef struct gdt_ucmd {
48: void *cookie;
49: u_int16_t io_node;
50: u_int16_t service;
51: u_int32_t timeout;
52: u_int16_t status;
53: u_int32_t info;
54:
55: u_int32_t BoardNode; /* board node (always 0) */
56: u_int32_t CommandIndex; /* command number */
57: u_int16_t OpCode; /* the command (READ,..) */
58: union {
59: struct {
60: u_int16_t DeviceNo; /* number of cache drive */
61: u_int32_t BlockNo; /* block number */
62: u_int32_t BlockCnt; /* block count */
63: void *DestAddr; /* data */
64: } cache; /* cache service cmd. str. */
65: struct {
66: u_int16_t param_size; /* size of p_param buffer */
67: u_int32_t subfunc; /* IOCTL function */
68: u_int32_t channel; /* device */
69: void *p_param; /* data */
70: } ioctl; /* IOCTL command structure */
71: struct {
72: u_int16_t reserved;
73: u_int32_t direction; /* data direction */
74: u_int32_t mdisc_time; /* disc. time (0: no timeout)*/
75: u_int32_t mcon_time; /* connect time(0: no to.) */
76: void *sdata; /* dest. addr. (if s/g: -1) */
77: u_int32_t sdlen; /* data length (bytes) */
78: u_int32_t clen; /* SCSI cmd. length(6,10,12) */
79: u_int8_t cmd[12]; /* SCSI command */
80: u_int8_t target; /* target ID */
81: u_int8_t lun; /* LUN */
82: u_int8_t bus; /* SCSI bus number */
83: u_int8_t priority; /* only 0 used */
84: u_int32_t sense_len; /* sense data length */
85: void *sense_data; /* sense data addr. */
86: u_int32_t link_p; /* linked cmds (not supp.) */
87: } raw; /* raw service cmd. struct. */
88: } u;
89: u_int8_t data[GDT_SCRATCH_SZ];
90: int complete_flag;
91: TAILQ_ENTRY(gdt_ucmd) links;
92: } gdt_ucmd_t;
93:
94: #define GDT_IOCTL_DRVERS _IOWR('B', 34, int) /* get driver version */
95: typedef struct gdt_drvers {
96: void *cookie;
97: int vers;
98: } gdt_drvers_t;
99:
100: #define GDT_IOCTL_CTRTYPE _IOR('B', 35, gdt_ctrt_t) /* get ctr. type */
101: typedef struct gdt_ctrt {
102: void *cookie;
103: u_int16_t io_node;
104: u_int16_t oem_id;
105: u_int16_t type;
106: u_int32_t info;
107: u_int8_t access;
108: u_int8_t remote;
109: u_int16_t ext_type;
110: u_int16_t device_id;
111: u_int16_t sub_device_id;
112: } gdt_ctrt_t;
113:
114: #define GDT_IOCTL_OSVERS _IOR('B', 36, gdt_osv_t) /* get OS version */
115: typedef struct gdt_osv {
116: void *cookie;
117: u_int8_t oscode;
118: u_int8_t version;
119: u_int8_t subversion;
120: u_int16_t revision;
121: char name[64];
122: } gdt_osv_t;
123:
124: #define GDT_IOCTL_CTRCNT _IOR('B', 37, int) /* get ctr. count */
125: typedef struct gdt_ctrcnt {
126: void *cookie;
127: int cnt;
128: } gdt_ctrcnt_t;
129:
130: #define GDT_IOCTL_EVENT _IOWR('B', 38, gdt_event_t) /* get event */
131:
132: typedef struct {
133: u_int16_t size; /* size of structure */
134: union {
135: char stream[16];
136: struct {
137: u_int16_t ionode;
138: u_int16_t service;
139: u_int32_t index;
140: } driver;
141: struct {
142: u_int16_t ionode;
143: u_int16_t service;
144: u_int16_t status;
145: u_int32_t info;
146: u_int8_t scsi_coord[3];
147: } async;
148: struct {
149: u_int16_t ionode;
150: u_int16_t service;
151: u_int16_t status;
152: u_int32_t info;
153: u_int16_t hostdrive;
154: u_int8_t scsi_coord[3];
155: u_int8_t sense_key;
156: } sync;
157: struct {
158: u_int32_t l1, l2, l3, l4;
159: } test;
160: } eu;
161: u_int32_t severity;
162: u_int8_t event_string[256];
163: } gdt_evt_data;
164: #define GDT_ES_ASYNC 1
165: #define GDT_ES_DRIVER 2
166: #define GDT_ES_TEST 3
167: #define GDT_ES_SYNC 4
168:
169: /* dvrevt structure */
170: typedef struct {
171: u_int32_t first_stamp;
172: u_int32_t last_stamp;
173: u_int16_t same_count;
174: u_int16_t event_source;
175: u_int16_t event_idx;
176: u_int8_t application;
177: u_int8_t reserved;
178: gdt_evt_data event_data;
179: } gdt_evt_str;
180:
181: typedef struct gdt_event {
182: void *cookie;
183: int erase;
184: int handle;
185: gdt_evt_str dvr;
186: } gdt_event_t;
187:
188: #define GDT_IOCTL_STATIST _IOR('B', 39, gdt_statist_t) /* get statistics */
189: typedef struct gdt_statist {
190: void *cookie;
191: u_int16_t io_count_act;
192: u_int16_t io_count_max;
193: u_int16_t req_queue_act;
194: u_int16_t req_queue_max;
195: u_int16_t cmd_index_act;
196: u_int16_t cmd_index_max;
197: u_int16_t sg_count_act;
198: u_int16_t sg_count_max;
199: } gdt_statist_t;
200:
201: #pragma pack()
202:
203: #ifdef _KERNEL
204:
205: /* Debugging */
206: /* #define GDT_DEBUG GDT_D_IOCTL | GDT_D_INFO */
207: #ifdef GDT_DEBUG
208: #define GDT_DPRINTF(mask, args) if (gdt_debug & (mask)) printf args
209: #define GDT_D_INTR 0x01
210: #define GDT_D_MISC 0x02
211: #define GDT_D_CMD 0x04
212: #define GDT_D_QUEUE 0x08
213: #define GDT_D_IO 0x10
214: #define GDT_D_IOCTL 0x20
215: #define GDT_D_INFO 0x40
216: extern int gdt_debug;
217: #else
218: #define GDT_DPRINTF(mask, args)
219: #endif
220:
221: /* Miscellaneous constants */
222: #define GDT_RETRIES 100000000 /* 100000 * 1us = 100s */
223: #define GDT_TIMEOUT 100000000 /* 100000 * 1us = 100s */
224: #define GDT_POLL_TIMEOUT 10000000 /* 10000 * 1us = 10s */
225: #define GDT_WATCH_TIMEOUT 10000 /* 10000 * 1ms = 10s */
226:
227: /* Context structure for interrupt services */
228: struct gdt_intr_ctx {
229: u_int32_t info, info2;
230: u_int16_t cmd_status, service;
231: u_int8_t istatus;
232: };
233:
234: /*
235: * A command contol block, one for each corresponding command index of the
236: * controller.
237: */
238: struct gdt_ccb {
239: TAILQ_ENTRY(gdt_ccb) gc_chain;
240: struct scsi_xfer *gc_xs;
241: struct gdt_ucmd *gc_ucmd;
242: bus_dmamap_t gc_dmamap_xfer;
243: int gc_timeout;
244: u_int32_t gc_info;
245: u_int32_t gc_blockno;
246: u_int32_t gc_blockcnt;
247: u_int16_t gc_status;
248: u_int8_t gc_service;
249: u_int8_t gc_cmd_index;
250: u_int8_t gc_flags;
251: #define GDT_GCF_CMD_MASK 0x3
252: #define GDT_GCF_UNUSED 0
253: #define GDT_GCF_INTERNAL 1
254: #define GDT_GCF_SCREEN 2
255: #define GDT_GCF_SCSI 3
256: #define GDT_GCF_WATCHDOG 0x4
257: };
258:
259: static __inline__ int gdt_ccb_set_cmd(struct gdt_ccb *, int);
260: static __inline__ int
261: gdt_ccb_set_cmd(ccb, flag)
262: struct gdt_ccb *ccb;
263: int flag;
264: {
265: int rv = ccb->gc_flags & GDT_GCF_CMD_MASK;
266:
267: ccb->gc_flags &= ~GDT_GCF_CMD_MASK;
268: ccb->gc_flags |= flag;
269: return (rv);
270: }
271:
272: struct gdt_softc {
273: struct device sc_dev;
274: void *sc_ih;
275: struct scsi_link sc_link; /* Virtual SCSI bus for cache devs */
276: struct scsi_link *sc_raw_link; /* Raw SCSI busses */
277:
278: int sc_class; /* Controller class */
279: #define GDT_ISA 0x01
280: #define GDT_EISA 0x02
281: #define GDT_PCI 0x03
282: #define GDT_PCINEW 0x04
283: #define GDT_MPR 0x05
284: #define GDT_CLASS_MASK 0x07
285: #define GDT_FC 0x10
286: #define GDT_CLASS(gdt) ((gdt)->sc_class & GDT_CLASS_MASK)
287:
288: bus_space_tag_t sc_dpmemt;
289: bus_space_handle_t sc_dpmemh;
290: bus_addr_t sc_dpmembase;
291: bus_dma_tag_t sc_dmat;
292:
293: /* XXX These could go into a class-dependent opaque struct instead */
294: bus_space_tag_t sc_iot;
295: bus_space_handle_t sc_ioh;
296: bus_addr_t sc_iobase;
297:
298: u_int16_t sc_ic_all_size;
299:
300: struct gdt_ccb sc_ccbs[GDT_MAXCMDS];
301: TAILQ_HEAD(, gdt_ccb) sc_free_ccb, sc_ccbq;
302: TAILQ_HEAD(, gdt_ucmd) sc_ucmdq;
303: LIST_HEAD(, scsi_xfer) sc_queue;
304: struct scsi_xfer *sc_queuelast;
305:
306: int sc_ndevs;
307:
308: u_int16_t sc_cmd_len;
309: u_int16_t sc_cmd_off;
310: u_int16_t sc_cmd_cnt;
311: u_int8_t sc_cmd[GDT_CMD_SZ];
312:
313: u_int32_t sc_info;
314: u_int32_t sc_info2;
315: bus_dma_segment_t sc_scratch_seg;
316: caddr_t sc_scratch;
317: u_int16_t sc_status;
318:
319: u_int8_t sc_bus_cnt;
320: u_int8_t sc_bus_id[GDT_MAXBUS];
321: u_int8_t sc_more_proc;
322:
323: u_int32_t sc_total_disks;
324:
325: struct {
326: u_int8_t hd_present;
327: u_int8_t hd_is_logdrv;
328: u_int8_t hd_is_arraydrv;
329: u_int8_t hd_is_master;
330: u_int8_t hd_is_parity;
331: u_int8_t hd_is_hotfix;
332: u_int8_t hd_master_no;
333: u_int8_t hd_lock;
334: u_int8_t hd_heads;
335: u_int8_t hd_secs;
336: u_int16_t hd_devtype;
337: u_int32_t hd_size;
338: u_int8_t hd_ldr_no;
339: u_int8_t hd_rw_attribs;
340: u_int32_t hd_start_sec;
341: } sc_hdr[GDT_MAX_HDRIVES];
342:
343: struct {
344: u_int8_t ra_lock; /* chan locked? (hot plug */
345: u_int8_t ra_phys_cnt; /* physical disk count */
346: u_int8_t ra_local_no; /* local channel number */
347: u_int8_t ra_io_cnt[GDT_MAXID]; /* current IO count */
348: u_int32_t ra_address; /* channel address */
349: u_int32_t ra_id_list[GDT_MAXID]; /* IDs of phys disks */
350: } sc_raw[GDT_MAXBUS]; /* SCSI channels */
351:
352: struct {
353: u_int32_t cp_version;
354: u_int16_t cp_state;
355: u_int16_t cp_strategy;
356: u_int16_t cp_write_back;
357: u_int16_t cp_block_size;
358: } sc_cpar;
359:
360: struct {
361: u_int32_t bi_ser_no; /* serial number */
362: u_int8_t bi_oem_id[2]; /* u_int8_t OEM ID */
363: u_int16_t bi_ep_flags; /* eprom flags */
364: u_int32_t bi_proc_id; /* processor ID */
365: u_int32_t bi_memsize; /* memory size (bytes) */
366: u_int8_t bi_mem_banks; /* memory banks */
367: u_int8_t bi_chan_type; /* channel type */
368: u_int8_t bi_chan_count; /* channel count */
369: u_int8_t bi_rdongle_pres; /* dongle present */
370: u_int32_t bi_epr_fw_ver; /* (eprom) firmware ver */
371: u_int32_t bi_upd_fw_ver; /* (update) firmware ver */
372: u_int32_t bi_upd_revision; /* update revision */
373: char bi_type_string[16]; /* char controller name */
374: char bi_raid_string[16]; /* char RAID firmware name */
375: u_int8_t bi_update_pres; /* update present? */
376: u_int8_t bi_xor_pres; /* XOR engine present */
377: u_int8_t bi_prom_type; /* ROM type (eprom/flash) */
378: u_int8_t bi_prom_count; /* number of ROM devices */
379: u_int32_t bi_dup_pres; /* duplexing module pres? */
380: u_int32_t bi_chan_pres; /* # of exp. channels */
381: u_int32_t bi_mem_pres; /* memory expansion inst? */
382: u_int8_t bi_ft_bus_system; /* fault bus supported? */
383: u_int8_t bi_subtype_valid; /* board_subtype valid */
384: u_int8_t bi_board_subtype; /* subtype/hardware level */
385: u_int8_t bi_rampar_pres; /* RAM parity check hw? */
386: } sc_binfo;
387:
388: struct {
389: u_int8_t bf_chaining; /* chaining supported */
390: u_int8_t bf_striping; /* striping (RAID-0) supported */
391: u_int8_t bf_mirroring; /* mirroring (RAID-1) supported */
392: u_int8_t bf_raid; /* RAID-4/5/10 supported */
393: } sc_bfeat;
394:
395: u_int16_t sc_raw_feat;
396: u_int16_t sc_cache_feat;
397:
398: void (*sc_copy_cmd)(struct gdt_softc *, struct gdt_ccb *);
399: u_int8_t (*sc_get_status)(struct gdt_softc *);
400: void (*sc_intr)(struct gdt_softc *, struct gdt_intr_ctx *);
401: void (*sc_release_event)(struct gdt_softc *, struct gdt_ccb *);
402: void (*sc_set_sema0)(struct gdt_softc *);
403: int (*sc_test_busy)(struct gdt_softc *);
404: };
405:
406: void gdtminphys(struct buf *);
407: int gdt_attach(struct gdt_softc *);
408: int gdt_intr(void *);
409:
410: #ifdef __GNUC__
411: /* These all require correctly aligned buffers */
412: static __inline__ void gdt_enc16(u_int8_t *, u_int16_t);
413: static __inline__ void gdt_enc32(u_int8_t *, u_int32_t);
414: static __inline__ u_int8_t gdt_dec8(u_int8_t *);
415: static __inline__ u_int16_t gdt_dec16(u_int8_t *);
416: static __inline__ u_int32_t gdt_dec32(u_int8_t *);
417:
418: static __inline__ void
419: gdt_enc16(addr, value)
420: u_int8_t *addr;
421: u_int16_t value;
422: {
423: *(u_int16_t *)addr = htole16(value);
424: }
425:
426: static __inline__ void
427: gdt_enc32(addr, value)
428: u_int8_t *addr;
429: u_int32_t value;
430: {
431: *(u_int32_t *)addr = htole32(value);
432: }
433:
434: static __inline__ u_int8_t
435: gdt_dec8(addr)
436: u_int8_t *addr;
437: {
438: return *(u_int8_t *)addr;
439: }
440:
441: static __inline__ u_int16_t
442: gdt_dec16(addr)
443: u_int8_t *addr;
444: {
445: return letoh16(*(u_int16_t *)addr);
446: }
447:
448: static __inline__ u_int32_t
449: gdt_dec32(addr)
450: u_int8_t *addr;
451: {
452: return letoh32(*(u_int32_t *)addr);
453: }
454: #endif
455:
456: extern u_int8_t gdt_polling;
457:
458: #endif
CVSweb