Line data Source code
1 : /* $OpenBSD: gdtvar.h,v 1.22 2013/03/04 00:41:54 dlg 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_SCRATCH_SZ 4096
36 :
37 : #ifdef _KERNEL
38 :
39 : /* Debugging */
40 : /* #define GDT_DEBUG GDT_D_IOCTL | GDT_D_INFO */
41 : #ifdef GDT_DEBUG
42 : #define GDT_DPRINTF(mask, args) if (gdt_debug & (mask)) printf args
43 : #define GDT_D_INTR 0x01
44 : #define GDT_D_MISC 0x02
45 : #define GDT_D_CMD 0x04
46 : #define GDT_D_QUEUE 0x08
47 : #define GDT_D_IO 0x10
48 : #define GDT_D_IOCTL 0x20
49 : #define GDT_D_INFO 0x40
50 : extern int gdt_debug;
51 : #else
52 : #define GDT_DPRINTF(mask, args)
53 : #endif
54 :
55 : /* Miscellaneous constants */
56 : #define GDT_RETRIES 100000000 /* 100000 * 1us = 100s */
57 : #define GDT_TIMEOUT 100000000 /* 100000 * 1us = 100s */
58 : #define GDT_POLL_TIMEOUT 10000 /* 10000 * 1ms = 10s */
59 : #define GDT_WATCH_TIMEOUT 10000 /* 10000 * 1ms = 10s */
60 :
61 : /* Context structure for interrupt services */
62 : struct gdt_intr_ctx {
63 : u_int32_t info, info2;
64 : u_int16_t cmd_status, service;
65 : u_int8_t istatus;
66 : };
67 :
68 : /*
69 : * A command contol block, one for each corresponding command index of the
70 : * controller.
71 : */
72 : struct gdt_ccb {
73 : TAILQ_ENTRY(gdt_ccb) gc_chain;
74 : struct scsi_xfer *gc_xs;
75 : struct gdt_ucmd *gc_ucmd;
76 : bus_dmamap_t gc_dmamap_xfer;
77 : int gc_timeout;
78 : u_int32_t gc_info;
79 : u_int32_t gc_blockno;
80 : u_int32_t gc_blockcnt;
81 : u_int16_t gc_status;
82 : u_int8_t gc_service;
83 : u_int8_t gc_cmd_index;
84 : u_int8_t gc_flags;
85 : #define GDT_GCF_CMD_MASK 0x3
86 : #define GDT_GCF_UNUSED 0
87 : #define GDT_GCF_INTERNAL 1
88 : #define GDT_GCF_SCREEN 2
89 : #define GDT_GCF_SCSI 3
90 : #define GDT_GCF_WATCHDOG 0x4
91 : };
92 :
93 : static inline int gdt_ccb_set_cmd(struct gdt_ccb *, int);
94 : static inline int
95 0 : gdt_ccb_set_cmd(struct gdt_ccb *ccb, int flag)
96 : {
97 0 : int rv = ccb->gc_flags & GDT_GCF_CMD_MASK;
98 :
99 0 : ccb->gc_flags &= ~GDT_GCF_CMD_MASK;
100 0 : ccb->gc_flags |= flag;
101 0 : return (rv);
102 : }
103 :
104 : struct gdt_softc {
105 : struct device sc_dev;
106 : void *sc_ih;
107 : struct scsi_link sc_link; /* Virtual SCSI bus for cache devs */
108 :
109 : int sc_class; /* Controller class */
110 : #define GDT_ISA 0x01
111 : #define GDT_EISA 0x02
112 : #define GDT_PCI 0x03
113 : #define GDT_PCINEW 0x04
114 : #define GDT_MPR 0x05
115 : #define GDT_CLASS_MASK 0x07
116 : #define GDT_FC 0x10
117 : #define GDT_CLASS(gdt) ((gdt)->sc_class & GDT_CLASS_MASK)
118 :
119 : bus_space_tag_t sc_dpmemt;
120 : bus_space_handle_t sc_dpmemh;
121 : bus_addr_t sc_dpmembase;
122 : bus_dma_tag_t sc_dmat;
123 :
124 : /* XXX These could go into a class-dependent opaque struct instead */
125 : bus_space_tag_t sc_iot;
126 : bus_space_handle_t sc_ioh;
127 : bus_addr_t sc_iobase;
128 :
129 : u_int16_t sc_ic_all_size;
130 :
131 : struct gdt_ccb sc_ccbs[GDT_MAXCMDS];
132 : TAILQ_HEAD(, gdt_ccb) sc_free_ccb, sc_ccbq;
133 : TAILQ_HEAD(, gdt_ucmd) sc_ucmdq;
134 : struct scsi_xfer_list sc_queue;
135 :
136 : struct mutex sc_ccb_mtx;
137 : struct scsi_iopool sc_iopool;
138 :
139 : int sc_ndevs;
140 :
141 : u_int16_t sc_cmd_len;
142 : u_int16_t sc_cmd_off;
143 : u_int16_t sc_cmd_cnt;
144 : u_int8_t sc_cmd[GDT_CMD_SZ];
145 :
146 : u_int32_t sc_info;
147 : u_int32_t sc_info2;
148 : bus_dma_segment_t sc_scratch_seg;
149 : caddr_t sc_scratch;
150 : u_int16_t sc_status;
151 :
152 : u_int8_t sc_bus_cnt;
153 : u_int8_t sc_bus_id[GDT_MAXBUS];
154 : u_int8_t sc_more_proc;
155 :
156 : u_int32_t sc_total_disks;
157 :
158 : struct {
159 : u_int8_t hd_present;
160 : u_int8_t hd_is_logdrv;
161 : u_int8_t hd_is_arraydrv;
162 : u_int8_t hd_is_master;
163 : u_int8_t hd_is_parity;
164 : u_int8_t hd_is_hotfix;
165 : u_int8_t hd_master_no;
166 : u_int8_t hd_lock;
167 : u_int8_t hd_heads;
168 : u_int8_t hd_secs;
169 : u_int16_t hd_devtype;
170 : u_int32_t hd_size;
171 : u_int8_t hd_ldr_no;
172 : u_int8_t hd_rw_attribs;
173 : u_int32_t hd_start_sec;
174 : } sc_hdr[GDT_MAX_HDRIVES];
175 :
176 : struct {
177 : u_int8_t ra_lock; /* chan locked? (hot plug */
178 : u_int8_t ra_phys_cnt; /* physical disk count */
179 : u_int8_t ra_local_no; /* local channel number */
180 : u_int8_t ra_io_cnt[GDT_MAXID]; /* current IO count */
181 : u_int32_t ra_address; /* channel address */
182 : u_int32_t ra_id_list[GDT_MAXID]; /* IDs of phys disks */
183 : } sc_raw[GDT_MAXBUS]; /* SCSI channels */
184 :
185 : struct {
186 : u_int32_t cp_version;
187 : u_int16_t cp_state;
188 : u_int16_t cp_strategy;
189 : u_int16_t cp_write_back;
190 : u_int16_t cp_block_size;
191 : } sc_cpar;
192 :
193 : struct {
194 : u_int32_t bi_ser_no; /* serial number */
195 : u_int8_t bi_oem_id[2]; /* u_int8_t OEM ID */
196 : u_int16_t bi_ep_flags; /* eprom flags */
197 : u_int32_t bi_proc_id; /* processor ID */
198 : u_int32_t bi_memsize; /* memory size (bytes) */
199 : u_int8_t bi_mem_banks; /* memory banks */
200 : u_int8_t bi_chan_type; /* channel type */
201 : u_int8_t bi_chan_count; /* channel count */
202 : u_int8_t bi_rdongle_pres; /* dongle present */
203 : u_int32_t bi_epr_fw_ver; /* (eprom) firmware ver */
204 : u_int32_t bi_upd_fw_ver; /* (update) firmware ver */
205 : u_int32_t bi_upd_revision; /* update revision */
206 : char bi_type_string[16]; /* char controller name */
207 : char bi_raid_string[16]; /* char RAID firmware name */
208 : u_int8_t bi_update_pres; /* update present? */
209 : u_int8_t bi_xor_pres; /* XOR engine present */
210 : u_int8_t bi_prom_type; /* ROM type (eprom/flash) */
211 : u_int8_t bi_prom_count; /* number of ROM devices */
212 : u_int32_t bi_dup_pres; /* duplexing module pres? */
213 : u_int32_t bi_chan_pres; /* # of exp. channels */
214 : u_int32_t bi_mem_pres; /* memory expansion inst? */
215 : u_int8_t bi_ft_bus_system; /* fault bus supported? */
216 : u_int8_t bi_subtype_valid; /* board_subtype valid */
217 : u_int8_t bi_board_subtype; /* subtype/hardware level */
218 : u_int8_t bi_rampar_pres; /* RAM parity check hw? */
219 : } sc_binfo;
220 :
221 : struct {
222 : u_int8_t bf_chaining; /* chaining supported */
223 : u_int8_t bf_striping; /* striping (RAID-0) supported */
224 : u_int8_t bf_mirroring; /* mirroring (RAID-1) supported */
225 : u_int8_t bf_raid; /* RAID-4/5/10 supported */
226 : } sc_bfeat;
227 :
228 : u_int16_t sc_raw_feat;
229 : u_int16_t sc_cache_feat;
230 :
231 : void (*sc_copy_cmd)(struct gdt_softc *, struct gdt_ccb *);
232 : u_int8_t (*sc_get_status)(struct gdt_softc *);
233 : void (*sc_intr)(struct gdt_softc *, struct gdt_intr_ctx *);
234 : void (*sc_release_event)(struct gdt_softc *, struct gdt_ccb *);
235 : void (*sc_set_sema0)(struct gdt_softc *);
236 : int (*sc_test_busy)(struct gdt_softc *);
237 : };
238 :
239 : void gdtminphys(struct buf *, struct scsi_link *);
240 : int gdt_attach(struct gdt_softc *);
241 : int gdt_intr(void *);
242 :
243 : /* These all require correctly aligned buffers */
244 : static inline void gdt_enc16(u_int8_t *, u_int16_t);
245 : static inline void gdt_enc32(u_int8_t *, u_int32_t);
246 : static inline u_int8_t gdt_dec8(u_int8_t *);
247 : static inline u_int16_t gdt_dec16(u_int8_t *);
248 : static inline u_int32_t gdt_dec32(u_int8_t *);
249 :
250 : static inline void
251 0 : gdt_enc16(u_int8_t *addr, u_int16_t value)
252 : {
253 0 : *(u_int16_t *)addr = htole16(value);
254 0 : }
255 :
256 : static inline void
257 0 : gdt_enc32(u_int8_t *addr, u_int32_t value)
258 : {
259 0 : *(u_int32_t *)addr = htole32(value);
260 0 : }
261 :
262 : static inline u_int8_t
263 0 : gdt_dec8(u_int8_t *addr)
264 : {
265 0 : return *(u_int8_t *)addr;
266 : }
267 :
268 : static inline u_int16_t
269 0 : gdt_dec16(u_int8_t *addr)
270 : {
271 0 : return letoh16(*(u_int16_t *)addr);
272 : }
273 :
274 : static inline u_int32_t
275 0 : gdt_dec32(u_int8_t *addr)
276 : {
277 0 : return letoh32(*(u_int32_t *)addr);
278 : }
279 :
280 : extern u_int8_t gdt_polling;
281 :
282 : #endif
|