mlxvar.h revision 1.16 1 1.16 pgoyette /* $NetBSD: mlxvar.h,v 1.16 2016/09/27 03:33:32 pgoyette Exp $ */
2 1.1 ad
3 1.1 ad /*-
4 1.1 ad * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 1.1 ad * All rights reserved.
6 1.1 ad *
7 1.1 ad * This code is derived from software contributed to The NetBSD Foundation
8 1.1 ad * by Andrew Doran.
9 1.1 ad *
10 1.1 ad * Redistribution and use in source and binary forms, with or without
11 1.1 ad * modification, are permitted provided that the following conditions
12 1.1 ad * are met:
13 1.1 ad * 1. Redistributions of source code must retain the above copyright
14 1.1 ad * notice, this list of conditions and the following disclaimer.
15 1.1 ad * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 ad * notice, this list of conditions and the following disclaimer in the
17 1.1 ad * documentation and/or other materials provided with the distribution.
18 1.1 ad *
19 1.1 ad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 ad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 ad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 ad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 ad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 ad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 ad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 ad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 ad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 ad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 ad * POSSIBILITY OF SUCH DAMAGE.
30 1.1 ad */
31 1.1 ad
32 1.1 ad /*-
33 1.1 ad * Copyright (c) 1999 Michael Smith
34 1.1 ad * All rights reserved.
35 1.1 ad *
36 1.1 ad * Redistribution and use in source and binary forms, with or without
37 1.1 ad * modification, are permitted provided that the following conditions
38 1.1 ad * are met:
39 1.1 ad * 1. Redistributions of source code must retain the above copyright
40 1.1 ad * notice, this list of conditions and the following disclaimer.
41 1.1 ad * 2. Redistributions in binary form must reproduce the above copyright
42 1.1 ad * notice, this list of conditions and the following disclaimer in the
43 1.1 ad * documentation and/or other materials provided with the distribution.
44 1.1 ad *
45 1.1 ad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
46 1.1 ad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 1.1 ad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 1.1 ad * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49 1.1 ad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 1.1 ad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 1.1 ad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 1.1 ad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 1.1 ad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 1.1 ad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 1.1 ad * SUCH DAMAGE.
56 1.1 ad *
57 1.1 ad * from FreeBSD: mlxvar.h,v 1.5.2.2 2000/04/24 19:40:50 msmith Exp
58 1.1 ad */
59 1.1 ad
60 1.1 ad #ifndef _IC_MLXVAR_H_
61 1.1 ad #define _IC_MLXVAR_H_
62 1.1 ad
63 1.1 ad /* Older boards allow up to 17 segments and 64kB transfers. */
64 1.1 ad #define MLX_MAX_SEGS 17
65 1.1 ad #define MLX_MAX_XFER 65536
66 1.1 ad #define MLX_SGL_SIZE (sizeof(struct mlx_sgentry) * MLX_MAX_SEGS)
67 1.1 ad
68 1.1 ad /* This shouldn't be ajusted lightly... */
69 1.1 ad #define MLX_MAX_DRIVES 32
70 1.1 ad
71 1.1 ad /* Maximum queue depth, matching the older controllers. */
72 1.1 ad #define MLX_MAX_QUEUECNT 63
73 1.1 ad
74 1.7 ad /* Number of CCBs to reserve for control operations. */
75 1.7 ad #define MLX_NCCBS_CONTROL 7
76 1.1 ad
77 1.1 ad /* Structure describing a system drive as attached to the controller. */
78 1.1 ad struct mlx_sysdrive {
79 1.1 ad u_int32_t ms_size;
80 1.1 ad u_short ms_state;
81 1.1 ad u_short ms_raidlevel;
82 1.15 chs device_t ms_dv;
83 1.1 ad };
84 1.1 ad
85 1.1 ad /* Optional per-CCB context. */
86 1.1 ad struct mlx_ccb;
87 1.1 ad struct mlx_context {
88 1.1 ad void (*mx_handler)(struct mlx_ccb *);
89 1.1 ad void *mx_context;
90 1.15 chs device_t mx_dv;
91 1.1 ad };
92 1.1 ad
93 1.1 ad /* Command control block. */
94 1.1 ad struct mlx_ccb {
95 1.1 ad union {
96 1.1 ad SIMPLEQ_ENTRY(mlx_ccb) simpleq;
97 1.1 ad SLIST_ENTRY(mlx_ccb) slist;
98 1.1 ad TAILQ_ENTRY(mlx_ccb) tailq;
99 1.1 ad } mc_chain;
100 1.1 ad u_int mc_flags;
101 1.1 ad u_int mc_status;
102 1.1 ad u_int mc_ident;
103 1.1 ad time_t mc_expiry;
104 1.1 ad u_int mc_nsgent;
105 1.1 ad u_int mc_xfer_size;
106 1.1 ad bus_addr_t mc_xfer_phys;
107 1.1 ad bus_dmamap_t mc_xfer_map;
108 1.1 ad struct mlx_context mc_mx;
109 1.1 ad u_int8_t mc_mbox[16];
110 1.1 ad };
111 1.1 ad #define MC_XFER_IN MU_XFER_IN /* Map describes inbound xfer */
112 1.1 ad #define MC_XFER_OUT MU_XFER_OUT /* Map describes outbound xfer */
113 1.1 ad #define MC_WAITING 0x0400 /* We have waiters */
114 1.7 ad #define MC_CONTROL 0x0800 /* Control operation */
115 1.1 ad
116 1.1 ad /*
117 1.1 ad * Per-controller state.
118 1.1 ad */
119 1.1 ad struct mlx_softc {
120 1.15 chs device_t mlx_dv;
121 1.1 ad bus_space_tag_t mlx_iot;
122 1.1 ad bus_space_handle_t mlx_ioh;
123 1.1 ad bus_dma_tag_t mlx_dmat;
124 1.1 ad bus_dmamap_t mlx_dmamap;
125 1.1 ad void *mlx_ih;
126 1.1 ad
127 1.1 ad SLIST_HEAD(, mlx_ccb) mlx_ccb_freelist;
128 1.1 ad TAILQ_HEAD(, mlx_ccb) mlx_ccb_worklist;
129 1.1 ad SIMPLEQ_HEAD(, mlx_ccb) mlx_ccb_queue;
130 1.1 ad struct mlx_ccb *mlx_ccbs;
131 1.1 ad int mlx_nccbs;
132 1.7 ad int mlx_nccbs_ctrl;
133 1.1 ad
134 1.13 christos void * mlx_sgls;
135 1.1 ad bus_addr_t mlx_sgls_paddr;
136 1.1 ad
137 1.1 ad int (*mlx_submit)(struct mlx_softc *, struct mlx_ccb *);
138 1.1 ad int (*mlx_findcomplete)(struct mlx_softc *, u_int *, u_int *);
139 1.1 ad void (*mlx_intaction)(struct mlx_softc *, int);
140 1.1 ad int (*mlx_fw_handshake)(struct mlx_softc *, int *, int *, int *);
141 1.2 ad int (*mlx_reset)(struct mlx_softc *);
142 1.1 ad
143 1.1 ad int mlx_max_queuecnt;
144 1.6 ad struct mlx_cinfo mlx_ci;
145 1.1 ad
146 1.1 ad time_t mlx_lastpoll;
147 1.1 ad u_int mlx_lastevent;
148 1.1 ad u_int mlx_currevent;
149 1.1 ad u_int mlx_bg;
150 1.1 ad struct mlx_rebuild_status mlx_rebuildstat;
151 1.1 ad struct mlx_pause mlx_pause;
152 1.1 ad int mlx_flags;
153 1.1 ad
154 1.1 ad struct mlx_sysdrive mlx_sysdrive[MLX_MAX_DRIVES];
155 1.3 ad int mlx_numsysdrives;
156 1.1 ad };
157 1.1 ad
158 1.1 ad #define MLX_BG_CHECK 1 /* we started a check */
159 1.1 ad #define MLX_BG_REBUILD 2 /* we started a rebuild */
160 1.1 ad #define MLX_BG_SPONTANEOUS 3 /* it just happened somehow */
161 1.1 ad
162 1.1 ad #define MLXF_SPINUP_REPORTED 0x0001 /* "spinning up drives" displayed */
163 1.1 ad #define MLXF_EVENTLOG_BUSY 0x0002 /* currently reading event log */
164 1.1 ad #define MLXF_FW_INITTED 0x0004 /* firmware init crap done */
165 1.1 ad #define MLXF_PAUSEWORKS 0x0008 /* channel pause works as expected */
166 1.1 ad #define MLXF_OPEN 0x0010 /* control device is open */
167 1.5 wiz #define MLXF_INITOK 0x0020 /* controller initialised OK */
168 1.1 ad #define MLXF_PERIODIC_CTLR 0x0040 /* periodic check running */
169 1.1 ad #define MLXF_PERIODIC_DRIVE 0x0080 /* periodic check running */
170 1.1 ad #define MLXF_PERIODIC_REBUILD 0x0100 /* periodic check running */
171 1.4 ad #define MLXF_RESCANNING 0x0400 /* rescanning drive table */
172 1.1 ad
173 1.1 ad struct mlx_attach_args {
174 1.1 ad int mlxa_unit;
175 1.1 ad };
176 1.1 ad
177 1.1 ad int mlx_flush(struct mlx_softc *, int);
178 1.1 ad void mlx_init(struct mlx_softc *, const char *);
179 1.1 ad int mlx_intr(void *);
180 1.16 pgoyette int mlx_configure(struct mlx_softc *, int);
181 1.1 ad
182 1.1 ad int mlx_ccb_alloc(struct mlx_softc *, struct mlx_ccb **, int);
183 1.1 ad const char *mlx_ccb_diagnose(struct mlx_ccb *);
184 1.1 ad void mlx_ccb_enqueue(struct mlx_softc *, struct mlx_ccb *);
185 1.1 ad void mlx_ccb_free(struct mlx_softc *, struct mlx_ccb *);
186 1.1 ad int mlx_ccb_map(struct mlx_softc *, struct mlx_ccb *, void *, int, int);
187 1.1 ad int mlx_ccb_poll(struct mlx_softc *, struct mlx_ccb *, int);
188 1.1 ad void mlx_ccb_unmap(struct mlx_softc *, struct mlx_ccb *);
189 1.1 ad int mlx_ccb_wait(struct mlx_softc *, struct mlx_ccb *);
190 1.1 ad
191 1.12 perry static __inline void mlx_make_type1(struct mlx_ccb *, u_int8_t, u_int16_t,
192 1.1 ad u_int32_t, u_int8_t, u_int32_t,
193 1.1 ad u_int8_t);
194 1.12 perry static __inline void mlx_make_type2(struct mlx_ccb *, u_int8_t, u_int8_t,
195 1.1 ad u_int8_t, u_int8_t, u_int8_t,
196 1.1 ad u_int8_t, u_int8_t, u_int32_t,
197 1.1 ad u_int8_t);
198 1.12 perry static __inline void mlx_make_type3(struct mlx_ccb *, u_int8_t, u_int8_t,
199 1.1 ad u_int8_t, u_int16_t, u_int8_t,
200 1.1 ad u_int8_t, u_int32_t, u_int8_t);
201 1.12 perry static __inline void mlx_make_type4(struct mlx_ccb *, u_int8_t, u_int16_t,
202 1.1 ad u_int32_t, u_int32_t, u_int8_t);
203 1.12 perry static __inline void mlx_make_type5(struct mlx_ccb *, u_int8_t, u_int8_t,
204 1.1 ad u_int8_t, u_int32_t, u_int32_t,
205 1.1 ad u_int8_t);
206 1.1 ad
207 1.12 perry static __inline u_int8_t mlx_inb(struct mlx_softc *, int);
208 1.12 perry static __inline u_int16_t mlx_inw(struct mlx_softc *, int);
209 1.12 perry static __inline u_int32_t mlx_inl(struct mlx_softc *, int);
210 1.12 perry static __inline void mlx_outb(struct mlx_softc *, int, u_int8_t);
211 1.12 perry static __inline void mlx_outw(struct mlx_softc *, int, u_int16_t);
212 1.12 perry static __inline void mlx_outl(struct mlx_softc *, int, u_int32_t);
213 1.1 ad
214 1.12 perry static __inline void
215 1.1 ad mlx_make_type1(struct mlx_ccb *mc, u_int8_t code, u_int16_t f1, u_int32_t f2,
216 1.9 perry u_int8_t f3, u_int32_t f4, u_int8_t f5)
217 1.1 ad {
218 1.1 ad
219 1.1 ad mc->mc_mbox[0x0] = code;
220 1.1 ad mc->mc_mbox[0x2] = f1;
221 1.7 ad mc->mc_mbox[0x3] = ((f2 >> 18) & 0xc0) | ((f1 >> 8) & 0x3f);
222 1.1 ad mc->mc_mbox[0x4] = f2;
223 1.1 ad mc->mc_mbox[0x5] = (f2 >> 8);
224 1.1 ad mc->mc_mbox[0x6] = (f2 >> 16);
225 1.1 ad mc->mc_mbox[0x7] = f3;
226 1.1 ad mc->mc_mbox[0x8] = f4;
227 1.1 ad mc->mc_mbox[0x9] = (f4 >> 8);
228 1.1 ad mc->mc_mbox[0xa] = (f4 >> 16);
229 1.1 ad mc->mc_mbox[0xb] = (f4 >> 24);
230 1.1 ad mc->mc_mbox[0xc] = f5;
231 1.1 ad }
232 1.1 ad
233 1.12 perry static __inline void
234 1.1 ad mlx_make_type2(struct mlx_ccb *mc, u_int8_t code, u_int8_t f1, u_int8_t f2,
235 1.1 ad u_int8_t f3, u_int8_t f4, u_int8_t f5, u_int8_t f6,
236 1.1 ad u_int32_t f7, u_int8_t f8)
237 1.1 ad {
238 1.1 ad
239 1.1 ad mc->mc_mbox[0x0] = code;
240 1.1 ad mc->mc_mbox[0x2] = f1;
241 1.1 ad mc->mc_mbox[0x3] = f2;
242 1.1 ad mc->mc_mbox[0x4] = f3;
243 1.1 ad mc->mc_mbox[0x5] = f4;
244 1.1 ad mc->mc_mbox[0x6] = f5;
245 1.1 ad mc->mc_mbox[0x7] = f6;
246 1.1 ad mc->mc_mbox[0x8] = f7;
247 1.1 ad mc->mc_mbox[0x9] = (f7 >> 8);
248 1.1 ad mc->mc_mbox[0xa] = (f7 >> 16);
249 1.1 ad mc->mc_mbox[0xb] = (f7 >> 24);
250 1.1 ad mc->mc_mbox[0xc] = f8;
251 1.1 ad }
252 1.1 ad
253 1.12 perry static __inline void
254 1.1 ad mlx_make_type3(struct mlx_ccb *mc, u_int8_t code, u_int8_t f1, u_int8_t f2,
255 1.1 ad u_int16_t f3, u_int8_t f4, u_int8_t f5, u_int32_t f6,
256 1.1 ad u_int8_t f7)
257 1.1 ad {
258 1.1 ad
259 1.1 ad mc->mc_mbox[0x0] = code;
260 1.1 ad mc->mc_mbox[0x2] = f1;
261 1.1 ad mc->mc_mbox[0x3] = f2;
262 1.1 ad mc->mc_mbox[0x4] = f3;
263 1.1 ad mc->mc_mbox[0x5] = (f3 >> 8);
264 1.1 ad mc->mc_mbox[0x6] = f4;
265 1.1 ad mc->mc_mbox[0x7] = f5;
266 1.1 ad mc->mc_mbox[0x8] = f6;
267 1.1 ad mc->mc_mbox[0x9] = (f6 >> 8);
268 1.1 ad mc->mc_mbox[0xa] = (f6 >> 16);
269 1.1 ad mc->mc_mbox[0xb] = (f6 >> 24);
270 1.1 ad mc->mc_mbox[0xc] = f7;
271 1.1 ad }
272 1.1 ad
273 1.12 perry static __inline void
274 1.1 ad mlx_make_type4(struct mlx_ccb *mc, u_int8_t code, u_int16_t f1, u_int32_t f2,
275 1.1 ad u_int32_t f3, u_int8_t f4)
276 1.1 ad {
277 1.1 ad
278 1.1 ad mc->mc_mbox[0x0] = code;
279 1.1 ad mc->mc_mbox[0x2] = f1;
280 1.1 ad mc->mc_mbox[0x3] = (f1 >> 8);
281 1.1 ad mc->mc_mbox[0x4] = f2;
282 1.1 ad mc->mc_mbox[0x5] = (f2 >> 8);
283 1.1 ad mc->mc_mbox[0x6] = (f2 >> 16);
284 1.1 ad mc->mc_mbox[0x7] = (f2 >> 24);
285 1.1 ad mc->mc_mbox[0x8] = f3;
286 1.1 ad mc->mc_mbox[0x9] = (f3 >> 8);
287 1.1 ad mc->mc_mbox[0xa] = (f3 >> 16);
288 1.1 ad mc->mc_mbox[0xb] = (f3 >> 24);
289 1.1 ad mc->mc_mbox[0xc] = f4;
290 1.1 ad }
291 1.1 ad
292 1.12 perry static __inline void
293 1.1 ad mlx_make_type5(struct mlx_ccb *mc, u_int8_t code, u_int8_t f1, u_int8_t f2,
294 1.1 ad u_int32_t f3, u_int32_t f4, u_int8_t f5)
295 1.1 ad {
296 1.1 ad
297 1.1 ad mc->mc_mbox[0x0] = code;
298 1.1 ad mc->mc_mbox[0x2] = f1;
299 1.1 ad mc->mc_mbox[0x3] = f2;
300 1.1 ad mc->mc_mbox[0x4] = f3;
301 1.1 ad mc->mc_mbox[0x5] = (f3 >> 8);
302 1.1 ad mc->mc_mbox[0x6] = (f3 >> 16);
303 1.1 ad mc->mc_mbox[0x7] = (f3 >> 24);
304 1.1 ad mc->mc_mbox[0x8] = f4;
305 1.1 ad mc->mc_mbox[0x9] = (f4 >> 8);
306 1.1 ad mc->mc_mbox[0xa] = (f4 >> 16);
307 1.1 ad mc->mc_mbox[0xb] = (f4 >> 24);
308 1.1 ad mc->mc_mbox[0xc] = f5;
309 1.1 ad }
310 1.1 ad
311 1.12 perry static __inline u_int8_t
312 1.1 ad mlx_inb(struct mlx_softc *mlx, int off)
313 1.1 ad {
314 1.1 ad
315 1.1 ad bus_space_barrier(mlx->mlx_iot, mlx->mlx_ioh, off, 1,
316 1.1 ad BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ);
317 1.1 ad return (bus_space_read_1(mlx->mlx_iot, mlx->mlx_ioh, off));
318 1.1 ad }
319 1.1 ad
320 1.12 perry static __inline u_int16_t
321 1.1 ad mlx_inw(struct mlx_softc *mlx, int off)
322 1.1 ad {
323 1.1 ad
324 1.1 ad bus_space_barrier(mlx->mlx_iot, mlx->mlx_ioh, off, 2,
325 1.1 ad BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ);
326 1.1 ad return (bus_space_read_2(mlx->mlx_iot, mlx->mlx_ioh, off));
327 1.1 ad }
328 1.1 ad
329 1.12 perry static __inline u_int32_t
330 1.1 ad mlx_inl(struct mlx_softc *mlx, int off)
331 1.1 ad {
332 1.1 ad
333 1.1 ad bus_space_barrier(mlx->mlx_iot, mlx->mlx_ioh, off, 4,
334 1.1 ad BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ);
335 1.1 ad return (bus_space_read_4(mlx->mlx_iot, mlx->mlx_ioh, off));
336 1.1 ad }
337 1.1 ad
338 1.12 perry static __inline void
339 1.1 ad mlx_outb(struct mlx_softc *mlx, int off, u_int8_t val)
340 1.1 ad {
341 1.1 ad
342 1.1 ad bus_space_write_1(mlx->mlx_iot, mlx->mlx_ioh, off, val);
343 1.1 ad bus_space_barrier(mlx->mlx_iot, mlx->mlx_ioh, off, 1,
344 1.1 ad BUS_SPACE_BARRIER_WRITE);
345 1.1 ad }
346 1.1 ad
347 1.12 perry static __inline void
348 1.1 ad mlx_outw(struct mlx_softc *mlx, int off, u_int16_t val)
349 1.1 ad {
350 1.1 ad
351 1.1 ad bus_space_write_2(mlx->mlx_iot, mlx->mlx_ioh, off, val);
352 1.1 ad bus_space_barrier(mlx->mlx_iot, mlx->mlx_ioh, off, 2,
353 1.1 ad BUS_SPACE_BARRIER_WRITE);
354 1.1 ad }
355 1.1 ad
356 1.12 perry static __inline void
357 1.1 ad mlx_outl(struct mlx_softc *mlx, int off, u_int32_t val)
358 1.1 ad {
359 1.1 ad
360 1.1 ad bus_space_write_4(mlx->mlx_iot, mlx->mlx_ioh, off, val);
361 1.1 ad bus_space_barrier(mlx->mlx_iot, mlx->mlx_ioh, off, 4,
362 1.1 ad BUS_SPACE_BARRIER_WRITE);
363 1.1 ad }
364 1.1 ad
365 1.1 ad #endif /* !_IC_MLXVAR_H_ */
366