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