1 1.49 thorpej /* $NetBSD: aac.c,v 1.49 2021/08/07 16:19:11 thorpej Exp $ */ 2 1.1 ad 3 1.1 ad /*- 4 1.31 briggs * Copyright (c) 2002, 2007 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) 2001 Scott Long 34 1.1 ad * Copyright (c) 2001 Adaptec, Inc. 35 1.1 ad * Copyright (c) 2000 Michael Smith 36 1.1 ad * Copyright (c) 2000 BSDi 37 1.1 ad * Copyright (c) 2000 Niklas Hallqvist 38 1.1 ad * All rights reserved. 39 1.1 ad * 40 1.1 ad * Redistribution and use in source and binary forms, with or without 41 1.1 ad * modification, are permitted provided that the following conditions 42 1.1 ad * are met: 43 1.1 ad * 1. Redistributions of source code must retain the above copyright 44 1.1 ad * notice, this list of conditions and the following disclaimer. 45 1.1 ad * 2. Redistributions in binary form must reproduce the above copyright 46 1.1 ad * notice, this list of conditions and the following disclaimer in the 47 1.1 ad * documentation and/or other materials provided with the distribution. 48 1.1 ad * 49 1.1 ad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 50 1.1 ad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 1.1 ad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 1.1 ad * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 53 1.1 ad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 1.1 ad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 1.1 ad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 1.1 ad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 1.1 ad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 1.1 ad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 1.1 ad * SUCH DAMAGE. 60 1.1 ad */ 61 1.1 ad 62 1.1 ad /* 63 1.1 ad * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters. 64 1.1 ad * 65 1.1 ad * TODO: 66 1.1 ad * 67 1.1 ad * o Management interface. 68 1.1 ad * o Look again at some of the portability issues. 69 1.1 ad * o Handle various AIFs (e.g., notification that a container is going away). 70 1.1 ad */ 71 1.1 ad 72 1.1 ad #include <sys/cdefs.h> 73 1.49 thorpej __KERNEL_RCSID(0, "$NetBSD: aac.c,v 1.49 2021/08/07 16:19:11 thorpej Exp $"); 74 1.1 ad 75 1.1 ad #include <sys/param.h> 76 1.1 ad #include <sys/systm.h> 77 1.1 ad #include <sys/buf.h> 78 1.1 ad #include <sys/device.h> 79 1.1 ad #include <sys/kernel.h> 80 1.1 ad #include <sys/malloc.h> 81 1.35 ad #include <sys/proc.h> 82 1.45 pgoyette #include <sys/module.h> 83 1.1 ad 84 1.36 ad #include <sys/bus.h> 85 1.1 ad 86 1.1 ad #include <dev/ic/aacreg.h> 87 1.1 ad #include <dev/ic/aacvar.h> 88 1.1 ad #include <dev/ic/aac_tables.h> 89 1.1 ad 90 1.13 drochner #include "locators.h" 91 1.13 drochner 92 1.45 pgoyette #include "ioconf.h" 93 1.45 pgoyette 94 1.34 briggs static int aac_new_intr(void *); 95 1.34 briggs static int aac_alloc_commands(struct aac_softc *); 96 1.34 briggs #ifdef notyet 97 1.34 briggs static void aac_free_commands(struct aac_softc *); 98 1.34 briggs #endif 99 1.12 thorpej static int aac_check_firmware(struct aac_softc *); 100 1.12 thorpej static void aac_describe_controller(struct aac_softc *); 101 1.12 thorpej static int aac_dequeue_fib(struct aac_softc *, int, u_int32_t *, 102 1.12 thorpej struct aac_fib **); 103 1.34 briggs static int aac_enqueue_fib(struct aac_softc *, int, struct aac_ccb *); 104 1.31 briggs static int aac_enqueue_response(struct aac_softc *, int, struct aac_fib *); 105 1.12 thorpej static void aac_host_command(struct aac_softc *); 106 1.12 thorpej static void aac_host_response(struct aac_softc *); 107 1.12 thorpej static int aac_init(struct aac_softc *); 108 1.12 thorpej static int aac_print(void *, const char *); 109 1.12 thorpej static void aac_shutdown(void *); 110 1.12 thorpej static void aac_startup(struct aac_softc *); 111 1.12 thorpej static int aac_sync_command(struct aac_softc *, u_int32_t, u_int32_t, 112 1.12 thorpej u_int32_t, u_int32_t, u_int32_t, u_int32_t *); 113 1.12 thorpej static int aac_sync_fib(struct aac_softc *, u_int32_t, u_int32_t, void *, 114 1.12 thorpej u_int16_t, void *, u_int16_t *); 115 1.1 ad 116 1.1 ad #ifdef AAC_DEBUG 117 1.24 jdolecek static void aac_print_fib(struct aac_softc *, struct aac_fib *, const char *); 118 1.1 ad #endif 119 1.1 ad 120 1.1 ad /* 121 1.1 ad * Adapter-space FIB queue manipulation. 122 1.1 ad * 123 1.1 ad * Note that the queue implementation here is a little funky; neither the PI or 124 1.1 ad * CI will ever be zero. This behaviour is a controller feature. 125 1.1 ad */ 126 1.1 ad static struct { 127 1.1 ad int size; 128 1.1 ad int notify; 129 1.1 ad } const aac_qinfo[] = { 130 1.1 ad { AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL }, 131 1.1 ad { AAC_HOST_HIGH_CMD_ENTRIES, 0 }, 132 1.1 ad { AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY }, 133 1.1 ad { AAC_ADAP_HIGH_CMD_ENTRIES, 0 }, 134 1.1 ad { AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL }, 135 1.1 ad { AAC_HOST_HIGH_RESP_ENTRIES, 0 }, 136 1.1 ad { AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY }, 137 1.1 ad { AAC_ADAP_HIGH_RESP_ENTRIES, 0 } 138 1.1 ad }; 139 1.1 ad 140 1.1 ad #ifdef AAC_DEBUG 141 1.1 ad int aac_debug = AAC_DEBUG; 142 1.1 ad #endif 143 1.1 ad 144 1.34 briggs MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for aac(4)"); 145 1.34 briggs 146 1.12 thorpej static void *aac_sdh; 147 1.1 ad 148 1.1 ad int 149 1.1 ad aac_attach(struct aac_softc *sc) 150 1.1 ad { 151 1.45 pgoyette int rv; 152 1.1 ad 153 1.1 ad SIMPLEQ_INIT(&sc->sc_ccb_free); 154 1.1 ad SIMPLEQ_INIT(&sc->sc_ccb_queue); 155 1.1 ad SIMPLEQ_INIT(&sc->sc_ccb_complete); 156 1.1 ad 157 1.1 ad /* 158 1.1 ad * Disable interrupts before we do anything. 159 1.1 ad */ 160 1.1 ad AAC_MASK_INTERRUPTS(sc); 161 1.1 ad 162 1.1 ad /* 163 1.1 ad * Initialise the adapter. 164 1.1 ad */ 165 1.1 ad if (aac_check_firmware(sc)) 166 1.1 ad return (EINVAL); 167 1.1 ad 168 1.1 ad if ((rv = aac_init(sc)) != 0) 169 1.1 ad return (rv); 170 1.34 briggs 171 1.34 briggs if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) { 172 1.34 briggs rv = sc->sc_intr_set(sc, aac_new_intr, sc); 173 1.34 briggs if (rv) 174 1.34 briggs return (rv); 175 1.34 briggs } 176 1.34 briggs 177 1.1 ad aac_startup(sc); 178 1.1 ad 179 1.16 perry /* 180 1.1 ad * Print a little information about the controller. 181 1.1 ad */ 182 1.1 ad aac_describe_controller(sc); 183 1.1 ad 184 1.1 ad /* 185 1.45 pgoyette * Attach devices 186 1.45 pgoyette */ 187 1.45 pgoyette aac_devscan(sc); 188 1.45 pgoyette 189 1.45 pgoyette /* 190 1.45 pgoyette * Enable interrupts, and register our shutdown hook. 191 1.1 ad */ 192 1.45 pgoyette sc->sc_flags |= AAC_ONLINE; 193 1.45 pgoyette AAC_UNMASK_INTERRUPTS(sc); 194 1.45 pgoyette if (aac_sdh != NULL) 195 1.45 pgoyette shutdownhook_establish(aac_shutdown, NULL); 196 1.45 pgoyette return (0); 197 1.45 pgoyette } 198 1.45 pgoyette 199 1.45 pgoyette int 200 1.45 pgoyette aac_devscan(struct aac_softc *sc) 201 1.45 pgoyette { 202 1.45 pgoyette struct aac_attach_args aaca; 203 1.45 pgoyette int i; 204 1.45 pgoyette int locs[AACCF_NLOCS]; 205 1.45 pgoyette 206 1.34 briggs for (i = 0; i < AAC_MAX_CONTAINERS; i++) { 207 1.34 briggs if (!sc->sc_hdr[i].hd_present) 208 1.34 briggs continue; 209 1.34 briggs aaca.aaca_unit = i; 210 1.34 briggs 211 1.34 briggs locs[AACCF_UNIT] = i; 212 1.34 briggs 213 1.48 thorpej config_found(sc->sc_dv, &aaca, aac_print, 214 1.49 thorpej CFARGS(.submatch = config_stdsubmatch, 215 1.49 thorpej .locators = locs)); 216 1.1 ad } 217 1.45 pgoyette return 0; 218 1.34 briggs } 219 1.34 briggs 220 1.34 briggs static int 221 1.34 briggs aac_alloc_commands(struct aac_softc *sc) 222 1.34 briggs { 223 1.34 briggs struct aac_fibmap *fm; 224 1.34 briggs struct aac_ccb *ac; 225 1.34 briggs bus_addr_t fibpa; 226 1.34 briggs int size, nsegs; 227 1.34 briggs int i, error; 228 1.34 briggs int state; 229 1.34 briggs 230 1.34 briggs if (sc->sc_total_fibs + sc->sc_max_fibs_alloc > sc->sc_max_fibs) 231 1.34 briggs return ENOMEM; 232 1.34 briggs 233 1.34 briggs fm = malloc(sizeof(struct aac_fibmap), M_AACBUF, M_NOWAIT|M_ZERO); 234 1.34 briggs if (fm == NULL) 235 1.34 briggs return ENOMEM; 236 1.34 briggs 237 1.34 briggs size = sc->sc_max_fibs_alloc * sc->sc_max_fib_size; 238 1.34 briggs 239 1.1 ad state = 0; 240 1.34 briggs error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 241 1.34 briggs 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &fm->fm_fibmap); 242 1.34 briggs if (error != 0) { 243 1.44 chs aprint_error_dev(sc->sc_dv, "cannot create fibs dmamap (%d)\n", 244 1.38 cegger error); 245 1.1 ad goto bail_out; 246 1.1 ad } 247 1.1 ad state++; 248 1.34 briggs error = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, 249 1.34 briggs &fm->fm_fibseg, 1, &nsegs, BUS_DMA_NOWAIT); 250 1.34 briggs if (error != 0) { 251 1.44 chs aprint_error_dev(sc->sc_dv, "can't allocate fibs structure (%d)\n", 252 1.38 cegger error); 253 1.1 ad goto bail_out; 254 1.1 ad } 255 1.1 ad state++; 256 1.34 briggs error = bus_dmamem_map(sc->sc_dmat, &fm->fm_fibseg, nsegs, size, 257 1.34 briggs (void **)&fm->fm_fibs, 0); 258 1.34 briggs if (error != 0) { 259 1.44 chs aprint_error_dev(sc->sc_dv, "can't map fibs structure (%d)\n", 260 1.38 cegger error); 261 1.1 ad goto bail_out; 262 1.1 ad } 263 1.1 ad state++; 264 1.34 briggs error = bus_dmamap_load(sc->sc_dmat, fm->fm_fibmap, fm->fm_fibs, 265 1.34 briggs size, NULL, BUS_DMA_NOWAIT); 266 1.34 briggs if (error != 0) { 267 1.44 chs aprint_error_dev(sc->sc_dv, "cannot load fibs dmamap (%d)\n", 268 1.38 cegger error); 269 1.1 ad goto bail_out; 270 1.1 ad } 271 1.1 ad 272 1.34 briggs fm->fm_ccbs = sc->sc_ccbs + sc->sc_total_fibs; 273 1.34 briggs fibpa = fm->fm_fibseg.ds_addr; 274 1.34 briggs 275 1.34 briggs memset(fm->fm_fibs, 0, size); 276 1.34 briggs for (i = 0; i < sc->sc_max_fibs_alloc; i++) { 277 1.34 briggs ac = fm->fm_ccbs + i; 278 1.34 briggs 279 1.34 briggs error = bus_dmamap_create(sc->sc_dmat, AAC_MAX_XFER(sc), 280 1.34 briggs sc->sc_max_sgs, AAC_MAX_XFER(sc), 0, 281 1.1 ad BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ac->ac_dmamap_xfer); 282 1.34 briggs if (error) { 283 1.34 briggs while (--i >= 0) { 284 1.34 briggs ac = fm->fm_ccbs + i; 285 1.1 ad bus_dmamap_destroy(sc->sc_dmat, 286 1.1 ad ac->ac_dmamap_xfer); 287 1.34 briggs sc->sc_total_fibs--; 288 1.34 briggs } 289 1.44 chs aprint_error_dev(sc->sc_dv, "cannot create ccb dmamap (%d)", 290 1.38 cegger error); 291 1.1 ad goto bail_out; 292 1.1 ad } 293 1.1 ad 294 1.34 briggs ac->ac_fibmap = fm; 295 1.34 briggs ac->ac_fib = (struct aac_fib *) 296 1.34 briggs ((char *) fm->fm_fibs + i * sc->sc_max_fib_size); 297 1.34 briggs ac->ac_fibphys = fibpa + i * sc->sc_max_fib_size; 298 1.1 ad aac_ccb_free(sc, ac); 299 1.34 briggs sc->sc_total_fibs++; 300 1.1 ad } 301 1.1 ad 302 1.34 briggs TAILQ_INSERT_TAIL(&sc->sc_fibmap_tqh, fm, fm_link); 303 1.13 drochner 304 1.34 briggs return 0; 305 1.34 briggs bail_out: 306 1.34 briggs if (state > 3) 307 1.34 briggs bus_dmamap_unload(sc->sc_dmat, fm->fm_fibmap); 308 1.34 briggs if (state > 2) 309 1.34 briggs bus_dmamem_unmap(sc->sc_dmat, (void *) fm->fm_fibs, size); 310 1.34 briggs if (state > 1) 311 1.34 briggs bus_dmamem_free(sc->sc_dmat, &fm->fm_fibseg, 1); 312 1.1 ad 313 1.34 briggs bus_dmamap_destroy(sc->sc_dmat, fm->fm_fibmap); 314 1.1 ad 315 1.34 briggs free(fm, M_AACBUF); 316 1.1 ad 317 1.34 briggs return error; 318 1.34 briggs } 319 1.1 ad 320 1.34 briggs #ifdef notyet 321 1.34 briggs static void 322 1.34 briggs aac_free_commands(struct aac_softc *sc) 323 1.34 briggs { 324 1.1 ad } 325 1.34 briggs #endif 326 1.1 ad 327 1.1 ad /* 328 1.1 ad * Print autoconfiguration message for a sub-device. 329 1.1 ad */ 330 1.12 thorpej static int 331 1.1 ad aac_print(void *aux, const char *pnp) 332 1.1 ad { 333 1.1 ad struct aac_attach_args *aaca; 334 1.1 ad 335 1.1 ad aaca = aux; 336 1.1 ad 337 1.1 ad if (pnp != NULL) 338 1.7 thorpej aprint_normal("block device at %s", pnp); 339 1.7 thorpej aprint_normal(" unit %d", aaca->aaca_unit); 340 1.1 ad return (UNCONF); 341 1.1 ad } 342 1.1 ad 343 1.1 ad /* 344 1.1 ad * Look up a text description of a numeric error code and return a pointer to 345 1.1 ad * same. 346 1.1 ad */ 347 1.1 ad const char * 348 1.1 ad aac_describe_code(const struct aac_code_lookup *table, u_int32_t code) 349 1.1 ad { 350 1.1 ad int i; 351 1.1 ad 352 1.1 ad for (i = 0; table[i].string != NULL; i++) 353 1.1 ad if (table[i].code == code) 354 1.1 ad return (table[i].string); 355 1.1 ad 356 1.1 ad return (table[i + 1].string); 357 1.1 ad } 358 1.1 ad 359 1.17 briggs /* 360 1.42 christos * snprintb(3) format string for the adapter options. 361 1.17 briggs */ 362 1.19 christos static const char *optfmt = 363 1.17 briggs "\20\1SNAPSHOT\2CLUSTERS\3WCACHE\4DATA64\5HOSTTIME\6RAID50" 364 1.17 briggs "\7WINDOW4GB" 365 1.17 briggs "\10SCSIUPGD\11SOFTERR\12NORECOND\13SGMAP64\14ALARM\15NONDASD"; 366 1.17 briggs 367 1.12 thorpej static void 368 1.1 ad aac_describe_controller(struct aac_softc *sc) 369 1.1 ad { 370 1.17 briggs u_int8_t fmtbuf[256]; 371 1.19 christos u_int8_t tbuf[AAC_FIB_DATASIZE]; 372 1.1 ad u_int16_t bufsize; 373 1.1 ad struct aac_adapter_info *info; 374 1.1 ad u_int8_t arg; 375 1.1 ad 376 1.1 ad arg = 0; 377 1.19 christos if (aac_sync_fib(sc, RequestAdapterInfo, 0, &arg, sizeof(arg), &tbuf, 378 1.1 ad &bufsize)) { 379 1.44 chs aprint_error_dev(sc->sc_dv, "RequestAdapterInfo failed\n"); 380 1.1 ad return; 381 1.1 ad } 382 1.1 ad if (bufsize != sizeof(*info)) { 383 1.44 chs aprint_error_dev(sc->sc_dv, 384 1.26 chs "RequestAdapterInfo returned wrong data size (%d != %zu)\n", 385 1.38 cegger bufsize, sizeof(*info)); 386 1.1 ad return; 387 1.1 ad } 388 1.19 christos info = (struct aac_adapter_info *)&tbuf[0]; 389 1.1 ad 390 1.44 chs aprint_normal_dev(sc->sc_dv, "%s at %dMHz, %dMB mem (%dMB cache), %s\n", 391 1.1 ad aac_describe_code(aac_cpu_variant, le32toh(info->CpuVariant)), 392 1.1 ad le32toh(info->ClockSpeed), 393 1.15 briggs le32toh(info->TotalMem) / (1024 * 1024), 394 1.1 ad le32toh(info->BufferMem) / (1024 * 1024), 395 1.1 ad aac_describe_code(aac_battery_platform, 396 1.15 briggs le32toh(info->batteryPlatform))); 397 1.15 briggs 398 1.44 chs aprint_verbose_dev(sc->sc_dv, "Kernel %d.%d-%d [Build %d], ", 399 1.1 ad info->KernelRevision.external.comp.major, 400 1.1 ad info->KernelRevision.external.comp.minor, 401 1.15 briggs info->KernelRevision.external.comp.dash, 402 1.15 briggs info->KernelRevision.buildNumber); 403 1.15 briggs 404 1.15 briggs aprint_verbose("Monitor %d.%d-%d [Build %d], S/N %6X\n", 405 1.15 briggs info->MonitorRevision.external.comp.major, 406 1.15 briggs info->MonitorRevision.external.comp.minor, 407 1.15 briggs info->MonitorRevision.external.comp.dash, 408 1.15 briggs info->MonitorRevision.buildNumber, 409 1.15 briggs ((u_int32_t)info->SerialNumber & 0xffffff)); 410 1.1 ad 411 1.42 christos snprintb(fmtbuf, sizeof(fmtbuf), optfmt, sc->sc_supported_options); 412 1.44 chs aprint_verbose_dev(sc->sc_dv, "Controller supports: %s\n", fmtbuf); 413 1.17 briggs 414 1.1 ad /* Save the kernel revision structure for later use. */ 415 1.1 ad sc->sc_revision = info->KernelRevision; 416 1.1 ad } 417 1.1 ad 418 1.1 ad /* 419 1.1 ad * Retrieve the firmware version numbers. Dell PERC2/QC cards with firmware 420 1.1 ad * version 1.x are not compatible with this driver. 421 1.1 ad */ 422 1.12 thorpej static int 423 1.1 ad aac_check_firmware(struct aac_softc *sc) 424 1.1 ad { 425 1.34 briggs u_int32_t major, minor, opts, atusize = 0, status = 0; 426 1.34 briggs u_int32_t calcsgs; 427 1.1 ad 428 1.1 ad if ((sc->sc_quirks & AAC_QUIRK_PERC2QC) != 0) { 429 1.1 ad if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0, 430 1.1 ad NULL)) { 431 1.44 chs aprint_error_dev(sc->sc_dv, "error reading firmware version\n"); 432 1.1 ad return (1); 433 1.1 ad } 434 1.1 ad 435 1.1 ad /* These numbers are stored as ASCII! */ 436 1.17 briggs major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30; 437 1.17 briggs minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30; 438 1.1 ad if (major == 1) { 439 1.44 chs aprint_error_dev(sc->sc_dv, 440 1.38 cegger "firmware version %d.%d not supported.\n", 441 1.38 cegger major, minor); 442 1.1 ad return (1); 443 1.1 ad } 444 1.1 ad } 445 1.1 ad 446 1.34 briggs if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, &status)) { 447 1.34 briggs if (status != AAC_SRB_STS_INVALID_REQUEST) { 448 1.44 chs aprint_error_dev(sc->sc_dv, "GETINFO failed, status 0x%08x\n", status); 449 1.34 briggs return (1); 450 1.34 briggs } 451 1.34 briggs } else { 452 1.34 briggs opts = AAC_GET_MAILBOX(sc, 1); 453 1.34 briggs atusize = AAC_GET_MAILBOX(sc, 2); 454 1.34 briggs sc->sc_supported_options = opts; 455 1.34 briggs 456 1.34 briggs if (((opts & AAC_SUPPORTED_4GB_WINDOW) != 0) && 457 1.34 briggs ((sc->sc_quirks & AAC_QUIRK_NO4GB) == 0) ) 458 1.34 briggs sc->sc_quirks |= AAC_QUIRK_4GB_WINDOW; 459 1.34 briggs 460 1.34 briggs if (((opts & AAC_SUPPORTED_SGMAP_HOST64) != 0) && 461 1.34 briggs (sizeof(bus_addr_t) > 4)) { 462 1.44 chs aprint_normal_dev(sc->sc_dv, "Enabling 64-bit address support\n"); 463 1.34 briggs sc->sc_quirks |= AAC_QUIRK_SG_64BIT; 464 1.34 briggs } 465 1.34 briggs if ((opts & AAC_SUPPORTED_NEW_COMM) && 466 1.34 briggs (sc->sc_if.aif_send_command != NULL)) { 467 1.34 briggs sc->sc_quirks |= AAC_QUIRK_NEW_COMM; 468 1.34 briggs } 469 1.34 briggs if (opts & AAC_SUPPORTED_64BIT_ARRAYSIZE) 470 1.34 briggs sc->sc_quirks |= AAC_QUIRK_ARRAY_64BIT; 471 1.17 briggs } 472 1.17 briggs 473 1.34 briggs sc->sc_max_fibs = (sc->sc_quirks & AAC_QUIRK_256FIBS) ? 256 : 512; 474 1.34 briggs 475 1.34 briggs if ( (sc->sc_quirks & AAC_QUIRK_NEW_COMM) 476 1.34 briggs && (sc->sc_regsize < atusize)) { 477 1.44 chs aprint_error_dev(sc->sc_dv, "Not enabling new comm i/f -- " 478 1.34 briggs "atusize 0x%08x, regsize 0x%08x\n", 479 1.38 cegger atusize, 480 1.38 cegger (uint32_t) sc->sc_regsize); 481 1.34 briggs sc->sc_quirks &= ~AAC_QUIRK_NEW_COMM; 482 1.34 briggs } 483 1.34 briggs #if 0 484 1.34 briggs if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) { 485 1.44 chs aprint_error_dev(sc->sc_dv, "Not enabling new comm i/f -- " 486 1.38 cegger "driver not ready yet\n"); 487 1.34 briggs sc->sc_quirks &= ~AAC_QUIRK_NEW_COMM; 488 1.34 briggs } 489 1.34 briggs #endif 490 1.34 briggs 491 1.34 briggs sc->sc_max_fib_size = sizeof(struct aac_fib); 492 1.34 briggs sc->sc_max_sectors = 128; /* 64KB */ 493 1.34 briggs if (sc->sc_quirks & AAC_QUIRK_SG_64BIT) 494 1.34 briggs sc->sc_max_sgs = (sc->sc_max_fib_size 495 1.34 briggs - sizeof(struct aac_blockwrite64) 496 1.34 briggs + sizeof(struct aac_sg_table64)) 497 1.34 briggs / sizeof(struct aac_sg_table64); 498 1.34 briggs else 499 1.34 briggs sc->sc_max_sgs = (sc->sc_max_fib_size 500 1.34 briggs - sizeof(struct aac_blockwrite) 501 1.34 briggs + sizeof(struct aac_sg_table)) 502 1.34 briggs / sizeof(struct aac_sg_table); 503 1.34 briggs 504 1.34 briggs if (!aac_sync_command(sc, AAC_MONKER_GETCOMMPREF, 0, 0, 0, 0, NULL)) { 505 1.34 briggs u_int32_t opt1, opt2, opt3; 506 1.34 briggs u_int32_t tmpval; 507 1.34 briggs 508 1.34 briggs opt1 = AAC_GET_MAILBOX(sc, 1); 509 1.34 briggs opt2 = AAC_GET_MAILBOX(sc, 2); 510 1.34 briggs opt3 = AAC_GET_MAILBOX(sc, 3); 511 1.34 briggs if (!opt1 || !opt2 || !opt3) { 512 1.44 chs aprint_verbose_dev(sc->sc_dv, "GETCOMMPREF appears untrustworthy." 513 1.38 cegger " Ignoring.\n"); 514 1.34 briggs } else { 515 1.34 briggs sc->sc_max_fib_size = le32toh(opt1) & 0xffff; 516 1.34 briggs sc->sc_max_sectors = (le32toh(opt1) >> 16) << 1; 517 1.34 briggs tmpval = (le32toh(opt2) >> 16); 518 1.34 briggs if (tmpval < sc->sc_max_sgs) { 519 1.34 briggs sc->sc_max_sgs = tmpval; 520 1.34 briggs } 521 1.34 briggs tmpval = (le32toh(opt3) & 0xffff); 522 1.34 briggs if (tmpval < sc->sc_max_fibs) { 523 1.34 briggs sc->sc_max_fibs = tmpval; 524 1.34 briggs } 525 1.34 briggs } 526 1.34 briggs } 527 1.34 briggs if (sc->sc_max_fib_size > PAGE_SIZE) 528 1.34 briggs sc->sc_max_fib_size = PAGE_SIZE; 529 1.34 briggs 530 1.34 briggs if (sc->sc_quirks & AAC_QUIRK_SG_64BIT) 531 1.34 briggs calcsgs = (sc->sc_max_fib_size 532 1.34 briggs - sizeof(struct aac_blockwrite64) 533 1.34 briggs + sizeof(struct aac_sg_table64)) 534 1.34 briggs / sizeof(struct aac_sg_table64); 535 1.34 briggs else 536 1.34 briggs calcsgs = (sc->sc_max_fib_size 537 1.34 briggs - sizeof(struct aac_blockwrite) 538 1.34 briggs + sizeof(struct aac_sg_table)) 539 1.34 briggs / sizeof(struct aac_sg_table); 540 1.34 briggs 541 1.34 briggs if (calcsgs < sc->sc_max_sgs) { 542 1.34 briggs sc->sc_max_sgs = calcsgs; 543 1.34 briggs } 544 1.34 briggs 545 1.34 briggs sc->sc_max_fibs_alloc = PAGE_SIZE / sc->sc_max_fib_size; 546 1.17 briggs 547 1.41 sborrill if (sc->sc_max_fib_size > sizeof(struct aac_fib)) { 548 1.41 sborrill sc->sc_quirks |= AAC_QUIRK_RAW_IO; 549 1.44 chs aprint_debug_dev(sc->sc_dv, "Enable raw I/O\n"); 550 1.41 sborrill } 551 1.41 sborrill if ((sc->sc_quirks & AAC_QUIRK_RAW_IO) && 552 1.41 sborrill (sc->sc_quirks & AAC_QUIRK_ARRAY_64BIT)) { 553 1.41 sborrill sc->sc_quirks |= AAC_QUIRK_LBA_64BIT; 554 1.44 chs aprint_normal_dev(sc->sc_dv, "Enable 64-bit array support\n"); 555 1.41 sborrill } 556 1.41 sborrill 557 1.1 ad return (0); 558 1.1 ad } 559 1.1 ad 560 1.12 thorpej static int 561 1.1 ad aac_init(struct aac_softc *sc) 562 1.1 ad { 563 1.1 ad int nsegs, i, rv, state, norm, high; 564 1.1 ad struct aac_adapter_init *ip; 565 1.21 darcy u_int32_t code, qoff; 566 1.1 ad 567 1.1 ad state = 0; 568 1.1 ad 569 1.1 ad /* 570 1.1 ad * First wait for the adapter to come ready. 571 1.1 ad */ 572 1.1 ad for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) { 573 1.1 ad code = AAC_GET_FWSTATUS(sc); 574 1.1 ad if ((code & AAC_SELF_TEST_FAILED) != 0) { 575 1.44 chs aprint_error_dev(sc->sc_dv, "FATAL: selftest failed\n"); 576 1.1 ad return (ENXIO); 577 1.1 ad } 578 1.1 ad if ((code & AAC_KERNEL_PANIC) != 0) { 579 1.44 chs aprint_error_dev(sc->sc_dv, "FATAL: controller kernel panic\n"); 580 1.1 ad return (ENXIO); 581 1.1 ad } 582 1.1 ad if ((code & AAC_UP_AND_RUNNING) != 0) 583 1.1 ad break; 584 1.1 ad DELAY(1000); 585 1.1 ad } 586 1.1 ad if (i == AAC_BOOT_TIMEOUT * 1000) { 587 1.44 chs aprint_error_dev(sc->sc_dv, 588 1.38 cegger "FATAL: controller not coming ready, status %x\n", 589 1.38 cegger code); 590 1.1 ad return (ENXIO); 591 1.1 ad } 592 1.1 ad 593 1.34 briggs sc->sc_aif_fib = malloc(sizeof(struct aac_fib), M_AACBUF, 594 1.47 chs M_WAITOK | M_ZERO); 595 1.1 ad if ((rv = bus_dmamap_create(sc->sc_dmat, sizeof(*sc->sc_common), 1, 596 1.1 ad sizeof(*sc->sc_common), 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, 597 1.1 ad &sc->sc_common_dmamap)) != 0) { 598 1.44 chs aprint_error_dev(sc->sc_dv, "cannot create common dmamap\n"); 599 1.34 briggs goto bail_out; 600 1.1 ad } 601 1.34 briggs state++; 602 1.1 ad if ((rv = bus_dmamem_alloc(sc->sc_dmat, sizeof(*sc->sc_common), 603 1.1 ad PAGE_SIZE, 0, &sc->sc_common_seg, 1, &nsegs, 604 1.1 ad BUS_DMA_NOWAIT)) != 0) { 605 1.44 chs aprint_error_dev(sc->sc_dv, "can't allocate common structure\n"); 606 1.1 ad goto bail_out; 607 1.1 ad } 608 1.1 ad state++; 609 1.1 ad if ((rv = bus_dmamem_map(sc->sc_dmat, &sc->sc_common_seg, nsegs, 610 1.30 christos sizeof(*sc->sc_common), (void **)&sc->sc_common, 0)) != 0) { 611 1.44 chs aprint_error_dev(sc->sc_dv, "can't map common structure\n"); 612 1.1 ad goto bail_out; 613 1.1 ad } 614 1.1 ad state++; 615 1.1 ad if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_common_dmamap, 616 1.1 ad sc->sc_common, sizeof(*sc->sc_common), NULL, 617 1.1 ad BUS_DMA_NOWAIT)) != 0) { 618 1.44 chs aprint_error_dev(sc->sc_dv, "cannot load common dmamap\n"); 619 1.1 ad goto bail_out; 620 1.1 ad } 621 1.1 ad state++; 622 1.1 ad 623 1.1 ad memset(sc->sc_common, 0, sizeof(*sc->sc_common)); 624 1.1 ad 625 1.34 briggs TAILQ_INIT(&sc->sc_fibmap_tqh); 626 1.34 briggs sc->sc_ccbs = malloc(sizeof(struct aac_ccb) * sc->sc_max_fibs, M_AACBUF, 627 1.47 chs M_WAITOK | M_ZERO); 628 1.34 briggs state++; 629 1.37 briggs while (sc->sc_total_fibs < AAC_PREALLOCATE_FIBS(sc)) { 630 1.34 briggs if (aac_alloc_commands(sc) != 0) 631 1.34 briggs break; 632 1.34 briggs } 633 1.34 briggs if (sc->sc_total_fibs == 0) 634 1.34 briggs goto bail_out; 635 1.34 briggs 636 1.1 ad /* 637 1.1 ad * Fill in the init structure. This tells the adapter about the 638 1.1 ad * physical location of various important shared data structures. 639 1.1 ad */ 640 1.1 ad ip = &sc->sc_common->ac_init; 641 1.1 ad ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION); 642 1.41 sborrill if (sc->sc_quirks & AAC_QUIRK_RAW_IO) 643 1.34 briggs ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION_4); 644 1.34 briggs ip->MiniPortRevision = htole32(AAC_INIT_STRUCT_MINIPORT_REVISION); 645 1.1 ad 646 1.1 ad ip->AdapterFibsPhysicalAddress = htole32(sc->sc_common_seg.ds_addr + 647 1.1 ad offsetof(struct aac_common, ac_fibs)); 648 1.31 briggs ip->AdapterFibsVirtualAddress = 0; 649 1.1 ad ip->AdapterFibsSize = 650 1.1 ad htole32(AAC_ADAPTER_FIBS * sizeof(struct aac_fib)); 651 1.1 ad ip->AdapterFibAlign = htole32(sizeof(struct aac_fib)); 652 1.1 ad 653 1.1 ad ip->PrintfBufferAddress = htole32(sc->sc_common_seg.ds_addr + 654 1.1 ad offsetof(struct aac_common, ac_printf)); 655 1.1 ad ip->PrintfBufferSize = htole32(AAC_PRINTF_BUFSIZE); 656 1.1 ad 657 1.32 briggs /* 658 1.32 briggs * The adapter assumes that pages are 4K in size, except on some 659 1.32 briggs * broken firmware versions that do the page->byte conversion twice, 660 1.32 briggs * therefore 'assuming' that this value is in 16MB units (2^24). 661 1.32 briggs * Round up since the granularity is so high. 662 1.32 briggs */ 663 1.32 briggs ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE; 664 1.32 briggs if (sc->sc_quirks & AAC_QUIRK_BROKEN_MMAP) { 665 1.32 briggs ip->HostPhysMemPages = 666 1.32 briggs (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE; 667 1.32 briggs } 668 1.1 ad ip->HostElapsedSeconds = 0; /* reset later if invalid */ 669 1.1 ad 670 1.34 briggs ip->InitFlags = 0; 671 1.34 briggs if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) { 672 1.34 briggs ip->InitFlags = htole32(AAC_INITFLAGS_NEW_COMM_SUPPORTED); 673 1.44 chs aprint_normal_dev(sc->sc_dv, "New comm. interface enabled\n"); 674 1.34 briggs } 675 1.34 briggs 676 1.34 briggs ip->MaxIoCommands = htole32(sc->sc_max_fibs); 677 1.34 briggs ip->MaxIoSize = htole32(sc->sc_max_sectors << 9); 678 1.34 briggs ip->MaxFibSize = htole32(sc->sc_max_fib_size); 679 1.34 briggs 680 1.1 ad /* 681 1.1 ad * Initialise FIB queues. Note that it appears that the layout of 682 1.1 ad * the indexes and the segmentation of the entries is mandated by 683 1.1 ad * the adapter, which is only told about the base of the queue index 684 1.1 ad * fields. 685 1.1 ad * 686 1.1 ad * The initial values of the indices are assumed to inform the 687 1.1 ad * adapter of the sizes of the respective queues. 688 1.1 ad * 689 1.1 ad * The Linux driver uses a much more complex scheme whereby several 690 1.1 ad * header records are kept for each queue. We use a couple of 691 1.1 ad * generic list manipulation functions which 'know' the size of each 692 1.1 ad * list by virtue of a table. 693 1.1 ad */ 694 1.21 darcy qoff = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN; 695 1.21 darcy qoff &= ~(AAC_QUEUE_ALIGN - 1); 696 1.21 darcy sc->sc_queues = (struct aac_queue_table *)((uintptr_t)sc->sc_common + qoff); 697 1.1 ad ip->CommHeaderAddress = htole32(sc->sc_common_seg.ds_addr + 698 1.30 christos ((char *)sc->sc_queues - (char *)sc->sc_common)); 699 1.1 ad memset(sc->sc_queues, 0, sizeof(struct aac_queue_table)); 700 1.1 ad 701 1.1 ad norm = htole32(AAC_HOST_NORM_CMD_ENTRIES); 702 1.1 ad high = htole32(AAC_HOST_HIGH_CMD_ENTRIES); 703 1.1 ad 704 1.1 ad sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 705 1.1 ad norm; 706 1.1 ad sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 707 1.1 ad norm; 708 1.1 ad sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 709 1.1 ad high; 710 1.1 ad sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 711 1.1 ad high; 712 1.1 ad 713 1.1 ad norm = htole32(AAC_ADAP_NORM_CMD_ENTRIES); 714 1.1 ad high = htole32(AAC_ADAP_HIGH_CMD_ENTRIES); 715 1.1 ad 716 1.1 ad sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 717 1.1 ad norm; 718 1.1 ad sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 719 1.1 ad norm; 720 1.1 ad sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 721 1.1 ad high; 722 1.1 ad sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 723 1.1 ad high; 724 1.1 ad 725 1.1 ad norm = htole32(AAC_HOST_NORM_RESP_ENTRIES); 726 1.1 ad high = htole32(AAC_HOST_HIGH_RESP_ENTRIES); 727 1.1 ad 728 1.1 ad sc->sc_queues-> 729 1.1 ad qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm; 730 1.1 ad sc->sc_queues-> 731 1.1 ad qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm; 732 1.1 ad sc->sc_queues-> 733 1.1 ad qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high; 734 1.1 ad sc->sc_queues-> 735 1.1 ad qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high; 736 1.1 ad 737 1.1 ad norm = htole32(AAC_ADAP_NORM_RESP_ENTRIES); 738 1.1 ad high = htole32(AAC_ADAP_HIGH_RESP_ENTRIES); 739 1.1 ad 740 1.1 ad sc->sc_queues-> 741 1.1 ad qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm; 742 1.1 ad sc->sc_queues-> 743 1.1 ad qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm; 744 1.1 ad sc->sc_queues-> 745 1.1 ad qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high; 746 1.1 ad sc->sc_queues-> 747 1.1 ad qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high; 748 1.1 ad 749 1.1 ad sc->sc_qentries[AAC_HOST_NORM_CMD_QUEUE] = 750 1.1 ad &sc->sc_queues->qt_HostNormCmdQueue[0]; 751 1.1 ad sc->sc_qentries[AAC_HOST_HIGH_CMD_QUEUE] = 752 1.1 ad &sc->sc_queues->qt_HostHighCmdQueue[0]; 753 1.1 ad sc->sc_qentries[AAC_ADAP_NORM_CMD_QUEUE] = 754 1.1 ad &sc->sc_queues->qt_AdapNormCmdQueue[0]; 755 1.1 ad sc->sc_qentries[AAC_ADAP_HIGH_CMD_QUEUE] = 756 1.1 ad &sc->sc_queues->qt_AdapHighCmdQueue[0]; 757 1.1 ad sc->sc_qentries[AAC_HOST_NORM_RESP_QUEUE] = 758 1.1 ad &sc->sc_queues->qt_HostNormRespQueue[0]; 759 1.1 ad sc->sc_qentries[AAC_HOST_HIGH_RESP_QUEUE] = 760 1.1 ad &sc->sc_queues->qt_HostHighRespQueue[0]; 761 1.1 ad sc->sc_qentries[AAC_ADAP_NORM_RESP_QUEUE] = 762 1.1 ad &sc->sc_queues->qt_AdapNormRespQueue[0]; 763 1.1 ad sc->sc_qentries[AAC_ADAP_HIGH_RESP_QUEUE] = 764 1.1 ad &sc->sc_queues->qt_AdapHighRespQueue[0]; 765 1.1 ad 766 1.1 ad /* 767 1.1 ad * Do controller-type-specific initialisation 768 1.1 ad */ 769 1.1 ad switch (sc->sc_hwif) { 770 1.1 ad case AAC_HWIF_I960RX: 771 1.1 ad AAC_SETREG4(sc, AAC_RX_ODBR, ~0); 772 1.1 ad break; 773 1.1 ad } 774 1.1 ad 775 1.1 ad bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 0, 776 1.1 ad sizeof(*sc->sc_common), 777 1.1 ad BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 778 1.1 ad 779 1.1 ad /* 780 1.1 ad * Give the init structure to the controller. 781 1.1 ad */ 782 1.16 perry if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT, 783 1.1 ad sc->sc_common_seg.ds_addr + offsetof(struct aac_common, ac_init), 784 1.1 ad 0, 0, 0, NULL)) { 785 1.44 chs aprint_error_dev(sc->sc_dv, "error establishing init structure\n"); 786 1.1 ad rv = EIO; 787 1.1 ad goto bail_out; 788 1.1 ad } 789 1.1 ad 790 1.1 ad return (0); 791 1.1 ad 792 1.1 ad bail_out: 793 1.34 briggs if (state > 4) 794 1.34 briggs free(sc->sc_ccbs, M_AACBUF); 795 1.34 briggs if (state > 3) 796 1.1 ad bus_dmamap_unload(sc->sc_dmat, sc->sc_common_dmamap); 797 1.34 briggs if (state > 2) 798 1.30 christos bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_common, 799 1.1 ad sizeof(*sc->sc_common)); 800 1.34 briggs if (state > 1) 801 1.34 briggs bus_dmamem_free(sc->sc_dmat, &sc->sc_common_seg, 1); 802 1.1 ad if (state > 0) 803 1.34 briggs bus_dmamap_destroy(sc->sc_dmat, sc->sc_common_dmamap); 804 1.34 briggs 805 1.34 briggs free(sc->sc_aif_fib, M_AACBUF); 806 1.1 ad 807 1.1 ad return (rv); 808 1.1 ad } 809 1.1 ad 810 1.1 ad /* 811 1.1 ad * Probe for containers, create disks. 812 1.1 ad */ 813 1.12 thorpej static void 814 1.1 ad aac_startup(struct aac_softc *sc) 815 1.1 ad { 816 1.1 ad struct aac_mntinfo mi; 817 1.1 ad struct aac_mntinforesponse mir; 818 1.1 ad struct aac_drive *hd; 819 1.1 ad u_int16_t rsize; 820 1.41 sborrill size_t ersize; 821 1.1 ad int i; 822 1.1 ad 823 1.1 ad /* 824 1.1 ad * Loop over possible containers. 825 1.1 ad */ 826 1.1 ad hd = sc->sc_hdr; 827 1.1 ad 828 1.1 ad for (i = 0; i < AAC_MAX_CONTAINERS; i++, hd++) { 829 1.1 ad /* 830 1.1 ad * Request information on this container. 831 1.1 ad */ 832 1.10 ad memset(&mi, 0, sizeof(mi)); 833 1.41 sborrill /* use 64-bit LBA if enabled */ 834 1.41 sborrill if (sc->sc_quirks & AAC_QUIRK_LBA_64BIT) { 835 1.41 sborrill mi.Command = htole32(VM_NameServe64); 836 1.41 sborrill ersize = sizeof(mir); 837 1.41 sborrill } else { 838 1.41 sborrill mi.Command = htole32(VM_NameServe); 839 1.41 sborrill ersize = sizeof(mir) - sizeof(mir.MntTable[0].CapacityHigh); 840 1.41 sborrill } 841 1.10 ad mi.MntType = htole32(FT_FILESYS); 842 1.1 ad mi.MntCount = htole32(i); 843 1.1 ad if (aac_sync_fib(sc, ContainerCommand, 0, &mi, sizeof(mi), &mir, 844 1.1 ad &rsize)) { 845 1.44 chs aprint_error_dev(sc->sc_dv, "error probing container %d\n", i); 846 1.1 ad continue; 847 1.1 ad } 848 1.41 sborrill if (rsize != ersize) { 849 1.44 chs aprint_error_dev(sc->sc_dv, "container info response wrong size " 850 1.41 sborrill "(%d should be %zu)\n", rsize, ersize); 851 1.1 ad continue; 852 1.1 ad } 853 1.1 ad 854 1.16 perry /* 855 1.1 ad * Check container volume type for validity. Note that many 856 1.1 ad * of the possible types may never show up. 857 1.1 ad */ 858 1.1 ad if (le32toh(mir.Status) != ST_OK || 859 1.1 ad le32toh(mir.MntTable[0].VolType) == CT_NONE) 860 1.1 ad continue; 861 1.1 ad 862 1.1 ad hd->hd_present = 1; 863 1.1 ad hd->hd_size = le32toh(mir.MntTable[0].Capacity); 864 1.41 sborrill if (sc->sc_quirks & AAC_QUIRK_LBA_64BIT) 865 1.41 sborrill hd->hd_size += (u_int64_t) 866 1.41 sborrill le32toh(mir.MntTable[0].CapacityHigh) << 32; 867 1.1 ad hd->hd_devtype = le32toh(mir.MntTable[0].VolType); 868 1.1 ad hd->hd_size &= ~0x1f; 869 1.1 ad sc->sc_nunits++; 870 1.1 ad } 871 1.1 ad } 872 1.1 ad 873 1.12 thorpej static void 874 1.29 christos aac_shutdown(void *cookie) 875 1.1 ad { 876 1.1 ad struct aac_softc *sc; 877 1.1 ad struct aac_close_command cc; 878 1.1 ad u_int32_t i; 879 1.1 ad 880 1.1 ad for (i = 0; i < aac_cd.cd_ndevs; i++) { 881 1.40 tsutsui if ((sc = device_lookup_private(&aac_cd, i)) == NULL) 882 1.1 ad continue; 883 1.1 ad if ((sc->sc_flags & AAC_ONLINE) == 0) 884 1.1 ad continue; 885 1.1 ad 886 1.1 ad AAC_MASK_INTERRUPTS(sc); 887 1.1 ad 888 1.16 perry /* 889 1.1 ad * Send a Container shutdown followed by a HostShutdown FIB 890 1.1 ad * to the controller to convince it that we don't want to 891 1.1 ad * talk to it anymore. We've been closed and all I/O 892 1.1 ad * completed already 893 1.1 ad */ 894 1.10 ad memset(&cc, 0, sizeof(cc)); 895 1.1 ad cc.Command = htole32(VM_CloseAll); 896 1.1 ad cc.ContainerId = 0xffffffff; 897 1.1 ad if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc), 898 1.1 ad NULL, NULL)) { 899 1.44 chs aprint_error_dev(sc->sc_dv, "unable to halt controller\n"); 900 1.1 ad continue; 901 1.1 ad } 902 1.1 ad 903 1.1 ad /* 904 1.1 ad * Note that issuing this command to the controller makes it 905 1.1 ad * shut down but also keeps it from coming back up without a 906 1.1 ad * reset of the PCI bus. 907 1.1 ad */ 908 1.1 ad if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN, 909 1.1 ad &i, sizeof(i), NULL, NULL)) 910 1.44 chs aprint_error_dev(sc->sc_dv, "unable to halt controller\n"); 911 1.17 briggs 912 1.17 briggs sc->sc_flags &= ~AAC_ONLINE; 913 1.1 ad } 914 1.1 ad } 915 1.1 ad 916 1.34 briggs static int 917 1.34 briggs aac_new_intr(void *cookie) 918 1.34 briggs { 919 1.34 briggs struct aac_softc *sc; 920 1.34 briggs u_int32_t index, fast; 921 1.34 briggs struct aac_ccb *ac; 922 1.34 briggs struct aac_fib *fib; 923 1.34 briggs struct aac_fibmap *fm; 924 1.34 briggs int i; 925 1.34 briggs 926 1.34 briggs sc = (struct aac_softc *) cookie; 927 1.34 briggs 928 1.34 briggs for (;;) { 929 1.34 briggs index = AAC_GET_OUTB_QUEUE(sc); 930 1.34 briggs if (index == 0xffffffff) 931 1.34 briggs index = AAC_GET_OUTB_QUEUE(sc); 932 1.34 briggs if (index == 0xffffffff) 933 1.34 briggs break; 934 1.34 briggs if (index & 2) { 935 1.34 briggs if (index == 0xfffffffe) { 936 1.34 briggs /* XXX This means that the controller wants 937 1.34 briggs * more work. Ignore it for now. 938 1.34 briggs */ 939 1.34 briggs continue; 940 1.34 briggs } 941 1.34 briggs /* AIF */ 942 1.34 briggs index &= ~2; 943 1.34 briggs fib = sc->sc_aif_fib; 944 1.34 briggs for (i = 0; i < sizeof(struct aac_fib)/4; i++) { 945 1.34 briggs ((u_int32_t*)fib)[i] = 946 1.34 briggs AAC_GETREG4(sc, index + i*4); 947 1.34 briggs } 948 1.34 briggs #ifdef notyet 949 1.34 briggs aac_handle_aif(sc, &fib); 950 1.34 briggs #endif 951 1.34 briggs 952 1.34 briggs AAC_SET_OUTB_QUEUE(sc, index); 953 1.34 briggs AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY); 954 1.34 briggs } else { 955 1.34 briggs fast = index & 1; 956 1.34 briggs ac = sc->sc_ccbs + (index >> 2); 957 1.34 briggs fib = ac->ac_fib; 958 1.34 briggs fm = ac->ac_fibmap; 959 1.34 briggs if (fast) { 960 1.34 briggs bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap, 961 1.34 briggs (char *)fib - (char *)fm->fm_fibs, 962 1.34 briggs sc->sc_max_fib_size, 963 1.34 briggs BUS_DMASYNC_POSTWRITE | 964 1.34 briggs BUS_DMASYNC_POSTREAD); 965 1.34 briggs fib->Header.XferState |= 966 1.34 briggs htole32(AAC_FIBSTATE_DONEADAP); 967 1.34 briggs *((u_int32_t *)(fib->data)) = 968 1.34 briggs htole32(AAC_ERROR_NORMAL); 969 1.34 briggs } 970 1.34 briggs ac->ac_flags |= AAC_CCB_COMPLETED; 971 1.34 briggs 972 1.34 briggs if (ac->ac_intr != NULL) 973 1.34 briggs (*ac->ac_intr)(ac); 974 1.34 briggs else 975 1.34 briggs wakeup(ac); 976 1.34 briggs } 977 1.34 briggs } 978 1.34 briggs 979 1.34 briggs /* 980 1.34 briggs * Try to submit more commands. 981 1.34 briggs */ 982 1.34 briggs if (! SIMPLEQ_EMPTY(&sc->sc_ccb_queue)) 983 1.34 briggs aac_ccb_enqueue(sc, NULL); 984 1.34 briggs 985 1.34 briggs return 1; 986 1.34 briggs } 987 1.34 briggs 988 1.1 ad /* 989 1.1 ad * Take an interrupt. 990 1.1 ad */ 991 1.1 ad int 992 1.1 ad aac_intr(void *cookie) 993 1.1 ad { 994 1.1 ad struct aac_softc *sc; 995 1.1 ad u_int16_t reason; 996 1.1 ad int claimed; 997 1.1 ad 998 1.1 ad sc = cookie; 999 1.1 ad claimed = 0; 1000 1.1 ad 1001 1.1 ad AAC_DPRINTF(AAC_D_INTR, ("aac_intr(%p) ", sc)); 1002 1.1 ad 1003 1.1 ad reason = AAC_GET_ISTATUS(sc); 1004 1.33 briggs AAC_CLEAR_ISTATUS(sc, reason); 1005 1.33 briggs 1006 1.1 ad AAC_DPRINTF(AAC_D_INTR, ("istatus 0x%04x ", reason)); 1007 1.1 ad 1008 1.1 ad /* 1009 1.1 ad * Controller wants to talk to the log. XXX Should we defer this? 1010 1.1 ad */ 1011 1.1 ad if ((reason & AAC_DB_PRINTF) != 0) { 1012 1.31 briggs if (sc->sc_common->ac_printf[0] == '\0') 1013 1.31 briggs sc->sc_common->ac_printf[0] = ' '; 1014 1.31 briggs printf("%s: WARNING: adapter logged message:\n", 1015 1.44 chs device_xname(sc->sc_dv)); 1016 1.44 chs printf("%s: %.*s", device_xname(sc->sc_dv), 1017 1.31 briggs AAC_PRINTF_BUFSIZE, sc->sc_common->ac_printf); 1018 1.31 briggs sc->sc_common->ac_printf[0] = '\0'; 1019 1.1 ad AAC_QNOTIFY(sc, AAC_DB_PRINTF); 1020 1.1 ad claimed = 1; 1021 1.1 ad } 1022 1.1 ad 1023 1.1 ad /* 1024 1.1 ad * Controller has a message for us? 1025 1.1 ad */ 1026 1.1 ad if ((reason & AAC_DB_COMMAND_READY) != 0) { 1027 1.1 ad aac_host_command(sc); 1028 1.1 ad claimed = 1; 1029 1.1 ad } 1030 1.1 ad 1031 1.1 ad /* 1032 1.1 ad * Controller has a response for us? 1033 1.1 ad */ 1034 1.1 ad if ((reason & AAC_DB_RESPONSE_READY) != 0) { 1035 1.1 ad aac_host_response(sc); 1036 1.1 ad claimed = 1; 1037 1.1 ad } 1038 1.1 ad 1039 1.1 ad /* 1040 1.1 ad * Spurious interrupts that we don't use - reset the mask and clear 1041 1.1 ad * the interrupts. 1042 1.1 ad */ 1043 1.1 ad if ((reason & (AAC_DB_SYNC_COMMAND | AAC_DB_COMMAND_NOT_FULL | 1044 1.1 ad AAC_DB_RESPONSE_NOT_FULL)) != 0) { 1045 1.1 ad AAC_UNMASK_INTERRUPTS(sc); 1046 1.1 ad AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND | 1047 1.1 ad AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL); 1048 1.1 ad claimed = 1; 1049 1.1 ad } 1050 1.1 ad 1051 1.1 ad return (claimed); 1052 1.1 ad } 1053 1.1 ad 1054 1.1 ad /* 1055 1.1 ad * Handle notification of one or more FIBs coming from the controller. 1056 1.1 ad */ 1057 1.12 thorpej static void 1058 1.1 ad aac_host_command(struct aac_softc *sc) 1059 1.1 ad { 1060 1.1 ad struct aac_fib *fib; 1061 1.1 ad u_int32_t fib_size; 1062 1.1 ad 1063 1.1 ad for (;;) { 1064 1.1 ad if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, &fib_size, 1065 1.1 ad &fib)) 1066 1.1 ad break; /* nothing to do */ 1067 1.1 ad 1068 1.1 ad bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1069 1.30 christos (char *)fib - (char *)sc->sc_common, sizeof(*fib), 1070 1.1 ad BUS_DMASYNC_POSTREAD); 1071 1.1 ad 1072 1.1 ad switch (le16toh(fib->Header.Command)) { 1073 1.1 ad case AifRequest: 1074 1.1 ad #ifdef notyet 1075 1.1 ad aac_handle_aif(sc, 1076 1.1 ad (struct aac_aif_command *)&fib->data[0]); 1077 1.1 ad #endif 1078 1.31 briggs AAC_PRINT_FIB(sc, fib); 1079 1.1 ad break; 1080 1.1 ad default: 1081 1.44 chs aprint_error_dev(sc->sc_dv, "unknown command from controller\n"); 1082 1.1 ad AAC_PRINT_FIB(sc, fib); 1083 1.1 ad break; 1084 1.1 ad } 1085 1.1 ad 1086 1.1 ad bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1087 1.30 christos (char *)fib - (char *)sc->sc_common, sizeof(*fib), 1088 1.1 ad BUS_DMASYNC_PREREAD); 1089 1.1 ad 1090 1.31 briggs if ((fib->Header.XferState == 0) || 1091 1.31 briggs (fib->Header.StructType != AAC_FIBTYPE_TFIB)) { 1092 1.31 briggs break; // continue; ??? 1093 1.31 briggs } 1094 1.31 briggs 1095 1.1 ad /* XXX reply to FIBs requesting responses ?? */ 1096 1.31 briggs 1097 1.31 briggs /* Return the AIF/FIB to the controller */ 1098 1.31 briggs if (le32toh(fib->Header.XferState) & AAC_FIBSTATE_FROMADAP) { 1099 1.31 briggs u_int16_t size; 1100 1.31 briggs 1101 1.31 briggs fib->Header.XferState |= 1102 1.31 briggs htole32(AAC_FIBSTATE_DONEHOST); 1103 1.31 briggs *(u_int32_t*)fib->data = htole32(ST_OK); 1104 1.31 briggs 1105 1.31 briggs /* XXX Compute the Size field? */ 1106 1.31 briggs size = le16toh(fib->Header.Size); 1107 1.31 briggs if (size > sizeof(struct aac_fib)) { 1108 1.31 briggs size = sizeof(struct aac_fib); 1109 1.31 briggs fib->Header.Size = htole16(size); 1110 1.31 briggs } 1111 1.31 briggs 1112 1.31 briggs /* 1113 1.31 briggs * Since we didn't generate this command, it can't 1114 1.31 briggs * go through the normal process. 1115 1.31 briggs */ 1116 1.31 briggs aac_enqueue_response(sc, 1117 1.31 briggs AAC_ADAP_NORM_RESP_QUEUE, fib); 1118 1.31 briggs } 1119 1.1 ad } 1120 1.1 ad } 1121 1.1 ad 1122 1.1 ad /* 1123 1.1 ad * Handle notification of one or more FIBs completed by the controller 1124 1.1 ad */ 1125 1.12 thorpej static void 1126 1.1 ad aac_host_response(struct aac_softc *sc) 1127 1.1 ad { 1128 1.1 ad struct aac_ccb *ac; 1129 1.1 ad struct aac_fib *fib; 1130 1.1 ad u_int32_t fib_size; 1131 1.1 ad 1132 1.1 ad /* 1133 1.1 ad * Look for completed FIBs on our queue. 1134 1.1 ad */ 1135 1.1 ad for (;;) { 1136 1.1 ad if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size, 1137 1.1 ad &fib)) 1138 1.1 ad break; /* nothing to do */ 1139 1.1 ad 1140 1.1 ad if ((fib->Header.SenderData & 0x80000000) == 0) { 1141 1.1 ad /* Not valid; not sent by us. */ 1142 1.1 ad AAC_PRINT_FIB(sc, fib); 1143 1.1 ad } else { 1144 1.34 briggs ac = (struct aac_ccb *)(sc->sc_ccbs + 1145 1.1 ad (fib->Header.SenderData & 0x7fffffff)); 1146 1.1 ad fib->Header.SenderData = 0; 1147 1.1 ad SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_complete, ac, ac_chain); 1148 1.1 ad } 1149 1.1 ad } 1150 1.1 ad 1151 1.1 ad /* 1152 1.1 ad * Deal with any completed commands. 1153 1.1 ad */ 1154 1.1 ad while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_complete)) != NULL) { 1155 1.3 lukem SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_complete, ac_chain); 1156 1.1 ad ac->ac_flags |= AAC_CCB_COMPLETED; 1157 1.1 ad 1158 1.1 ad if (ac->ac_intr != NULL) 1159 1.1 ad (*ac->ac_intr)(ac); 1160 1.34 briggs else 1161 1.34 briggs wakeup(ac); 1162 1.1 ad } 1163 1.1 ad 1164 1.1 ad /* 1165 1.1 ad * Try to submit more commands. 1166 1.1 ad */ 1167 1.3 lukem if (! SIMPLEQ_EMPTY(&sc->sc_ccb_queue)) 1168 1.1 ad aac_ccb_enqueue(sc, NULL); 1169 1.1 ad } 1170 1.1 ad 1171 1.1 ad /* 1172 1.1 ad * Send a synchronous command to the controller and wait for a result. 1173 1.1 ad */ 1174 1.12 thorpej static int 1175 1.1 ad aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 1176 1.1 ad u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp) 1177 1.1 ad { 1178 1.1 ad int i; 1179 1.1 ad u_int32_t status; 1180 1.1 ad int s; 1181 1.1 ad 1182 1.1 ad s = splbio(); 1183 1.1 ad 1184 1.1 ad /* Populate the mailbox. */ 1185 1.1 ad AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3); 1186 1.1 ad 1187 1.1 ad /* Ensure the sync command doorbell flag is cleared. */ 1188 1.1 ad AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1189 1.1 ad 1190 1.1 ad /* ... then set it to signal the adapter. */ 1191 1.1 ad AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND); 1192 1.1 ad DELAY(AAC_SYNC_DELAY); 1193 1.1 ad 1194 1.1 ad /* Spin waiting for the command to complete. */ 1195 1.1 ad for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) { 1196 1.11 christos if (AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND) 1197 1.1 ad break; 1198 1.1 ad DELAY(1000); 1199 1.1 ad } 1200 1.1 ad if (i == AAC_IMMEDIATE_TIMEOUT * 1000) { 1201 1.1 ad splx(s); 1202 1.1 ad return (EIO); 1203 1.1 ad } 1204 1.1 ad 1205 1.1 ad /* Clear the completion flag. */ 1206 1.1 ad AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1207 1.1 ad 1208 1.1 ad /* Get the command status. */ 1209 1.1 ad status = AAC_GET_MAILBOXSTATUS(sc); 1210 1.1 ad splx(s); 1211 1.1 ad if (sp != NULL) 1212 1.1 ad *sp = status; 1213 1.1 ad 1214 1.1 ad return (0); /* XXX Check command return status? */ 1215 1.1 ad } 1216 1.1 ad 1217 1.1 ad /* 1218 1.1 ad * Send a synchronous FIB to the controller and wait for a result. 1219 1.1 ad */ 1220 1.12 thorpej static int 1221 1.1 ad aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate, 1222 1.1 ad void *data, u_int16_t datasize, void *result, 1223 1.1 ad u_int16_t *resultsize) 1224 1.1 ad { 1225 1.1 ad struct aac_fib *fib; 1226 1.1 ad u_int32_t fibpa, status; 1227 1.1 ad 1228 1.1 ad fib = &sc->sc_common->ac_sync_fib; 1229 1.1 ad fibpa = sc->sc_common_seg.ds_addr + 1230 1.1 ad offsetof(struct aac_common, ac_sync_fib); 1231 1.1 ad 1232 1.1 ad if (datasize > AAC_FIB_DATASIZE) 1233 1.1 ad return (EINVAL); 1234 1.1 ad 1235 1.1 ad /* 1236 1.1 ad * Set up the sync FIB. 1237 1.1 ad */ 1238 1.1 ad fib->Header.XferState = htole32(AAC_FIBSTATE_HOSTOWNED | 1239 1.1 ad AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_EMPTY | xferstate); 1240 1.1 ad fib->Header.Command = htole16(command); 1241 1.1 ad fib->Header.StructType = AAC_FIBTYPE_TFIB; 1242 1.1 ad fib->Header.Size = htole16(sizeof(*fib) + datasize); 1243 1.1 ad fib->Header.SenderSize = htole16(sizeof(*fib)); 1244 1.31 briggs fib->Header.SenderFibAddress = 0; /* not needed */ 1245 1.1 ad fib->Header.ReceiverFibAddress = htole32(fibpa); 1246 1.1 ad 1247 1.1 ad /* 1248 1.1 ad * Copy in data. 1249 1.1 ad */ 1250 1.1 ad if (data != NULL) { 1251 1.1 ad memcpy(fib->data, data, datasize); 1252 1.1 ad fib->Header.XferState |= 1253 1.1 ad htole32(AAC_FIBSTATE_FROMHOST | AAC_FIBSTATE_NORM); 1254 1.1 ad } 1255 1.1 ad 1256 1.1 ad bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1257 1.30 christos (char *)fib - (char *)sc->sc_common, sizeof(*fib), 1258 1.1 ad BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1259 1.1 ad 1260 1.1 ad /* 1261 1.1 ad * Give the FIB to the controller, wait for a response. 1262 1.1 ad */ 1263 1.1 ad if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, fibpa, 0, 0, 0, &status)) 1264 1.1 ad return (EIO); 1265 1.17 briggs if (status != 1) { 1266 1.17 briggs printf("%s: syncfib command %04x status %08x\n", 1267 1.44 chs device_xname(sc->sc_dv), command, status); 1268 1.17 briggs } 1269 1.1 ad 1270 1.1 ad bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1271 1.30 christos (char *)fib - (char *)sc->sc_common, sizeof(*fib), 1272 1.1 ad BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1273 1.1 ad 1274 1.16 perry /* 1275 1.1 ad * Copy out the result 1276 1.1 ad */ 1277 1.1 ad if (result != NULL) { 1278 1.1 ad *resultsize = le16toh(fib->Header.Size) - sizeof(fib->Header); 1279 1.1 ad memcpy(result, fib->data, *resultsize); 1280 1.1 ad } 1281 1.1 ad 1282 1.1 ad return (0); 1283 1.1 ad } 1284 1.1 ad 1285 1.1 ad struct aac_ccb * 1286 1.1 ad aac_ccb_alloc(struct aac_softc *sc, int flags) 1287 1.1 ad { 1288 1.1 ad struct aac_ccb *ac; 1289 1.1 ad int s; 1290 1.1 ad 1291 1.1 ad AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_alloc(%p, 0x%x) ", sc, flags)); 1292 1.1 ad 1293 1.1 ad s = splbio(); 1294 1.1 ad ac = SIMPLEQ_FIRST(&sc->sc_ccb_free); 1295 1.34 briggs if (ac == NULL) { 1296 1.34 briggs if (aac_alloc_commands(sc)) { 1297 1.34 briggs splx(s); 1298 1.34 briggs return NULL; 1299 1.34 briggs } 1300 1.34 briggs ac = SIMPLEQ_FIRST(&sc->sc_ccb_free); 1301 1.34 briggs } 1302 1.1 ad #ifdef DIAGNOSTIC 1303 1.1 ad if (ac == NULL) 1304 1.1 ad panic("aac_ccb_get: no free CCBS"); 1305 1.1 ad #endif 1306 1.3 lukem SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, ac_chain); 1307 1.1 ad splx(s); 1308 1.1 ad 1309 1.1 ad ac->ac_flags = flags; 1310 1.1 ad return (ac); 1311 1.1 ad } 1312 1.1 ad 1313 1.1 ad void 1314 1.1 ad aac_ccb_free(struct aac_softc *sc, struct aac_ccb *ac) 1315 1.1 ad { 1316 1.1 ad int s; 1317 1.1 ad 1318 1.1 ad AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_free(%p, %p) ", sc, ac)); 1319 1.1 ad 1320 1.1 ad ac->ac_flags = 0; 1321 1.1 ad ac->ac_intr = NULL; 1322 1.1 ad ac->ac_fib->Header.XferState = htole32(AAC_FIBSTATE_EMPTY); 1323 1.1 ad ac->ac_fib->Header.StructType = AAC_FIBTYPE_TFIB; 1324 1.1 ad ac->ac_fib->Header.Flags = 0; 1325 1.34 briggs ac->ac_fib->Header.SenderSize = htole16(sc->sc_max_fib_size); 1326 1.1 ad 1327 1.1 ad #ifdef AAC_DEBUG 1328 1.16 perry /* 1329 1.1 ad * These are duplicated in aac_ccb_submit() to cover the case where 1330 1.1 ad * an intermediate stage may have destroyed them. They're left 1331 1.1 ad * initialised here for debugging purposes only. 1332 1.1 ad */ 1333 1.34 briggs ac->ac_fib->Header.SenderFibAddress = 1334 1.34 briggs htole32(((u_int32_t) (ac - sc->sc_ccbs)) << 2); 1335 1.1 ad ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys); 1336 1.1 ad #endif 1337 1.1 ad 1338 1.1 ad s = splbio(); 1339 1.1 ad SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ac, ac_chain); 1340 1.1 ad splx(s); 1341 1.1 ad } 1342 1.1 ad 1343 1.1 ad int 1344 1.1 ad aac_ccb_map(struct aac_softc *sc, struct aac_ccb *ac) 1345 1.1 ad { 1346 1.1 ad int error; 1347 1.1 ad 1348 1.1 ad AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_map(%p, %p) ", sc, ac)); 1349 1.1 ad 1350 1.1 ad #ifdef DIAGNOSTIC 1351 1.1 ad if ((ac->ac_flags & AAC_CCB_MAPPED) != 0) 1352 1.1 ad panic("aac_ccb_map: already mapped"); 1353 1.1 ad #endif 1354 1.1 ad 1355 1.1 ad error = bus_dmamap_load(sc->sc_dmat, ac->ac_dmamap_xfer, ac->ac_data, 1356 1.1 ad ac->ac_datalen, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING | 1357 1.1 ad ((ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMA_READ : BUS_DMA_WRITE)); 1358 1.1 ad if (error) { 1359 1.44 chs printf("%s: aac_ccb_map: ", device_xname(sc->sc_dv)); 1360 1.1 ad if (error == EFBIG) 1361 1.34 briggs printf("more than %d DMA segs\n", sc->sc_max_sgs); 1362 1.1 ad else 1363 1.9 wiz printf("error %d loading DMA map\n", error); 1364 1.1 ad return (error); 1365 1.1 ad } 1366 1.1 ad 1367 1.1 ad bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen, 1368 1.1 ad (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_PREREAD : 1369 1.1 ad BUS_DMASYNC_PREWRITE); 1370 1.1 ad 1371 1.1 ad #ifdef DIAGNOSTIC 1372 1.1 ad ac->ac_flags |= AAC_CCB_MAPPED; 1373 1.1 ad #endif 1374 1.1 ad return (0); 1375 1.1 ad } 1376 1.1 ad 1377 1.1 ad void 1378 1.1 ad aac_ccb_unmap(struct aac_softc *sc, struct aac_ccb *ac) 1379 1.1 ad { 1380 1.1 ad 1381 1.1 ad AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_unmap(%p, %p) ", sc, ac)); 1382 1.1 ad 1383 1.1 ad #ifdef DIAGNOSTIC 1384 1.1 ad if ((ac->ac_flags & AAC_CCB_MAPPED) == 0) 1385 1.1 ad panic("aac_ccb_unmap: not mapped"); 1386 1.1 ad #endif 1387 1.1 ad 1388 1.1 ad bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen, 1389 1.1 ad (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_POSTREAD : 1390 1.1 ad BUS_DMASYNC_POSTWRITE); 1391 1.1 ad bus_dmamap_unload(sc->sc_dmat, ac->ac_dmamap_xfer); 1392 1.1 ad 1393 1.1 ad #ifdef DIAGNOSTIC 1394 1.1 ad ac->ac_flags &= ~AAC_CCB_MAPPED; 1395 1.1 ad #endif 1396 1.1 ad } 1397 1.1 ad 1398 1.1 ad void 1399 1.1 ad aac_ccb_enqueue(struct aac_softc *sc, struct aac_ccb *ac) 1400 1.1 ad { 1401 1.1 ad int s; 1402 1.1 ad 1403 1.1 ad AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_enqueue(%p, %p) ", sc, ac)); 1404 1.1 ad 1405 1.1 ad s = splbio(); 1406 1.1 ad 1407 1.1 ad if (ac != NULL) 1408 1.1 ad SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_queue, ac, ac_chain); 1409 1.1 ad 1410 1.1 ad while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_queue)) != NULL) { 1411 1.1 ad if (aac_ccb_submit(sc, ac)) 1412 1.1 ad break; 1413 1.3 lukem SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_queue, ac_chain); 1414 1.1 ad } 1415 1.1 ad 1416 1.1 ad splx(s); 1417 1.1 ad } 1418 1.1 ad 1419 1.1 ad int 1420 1.1 ad aac_ccb_submit(struct aac_softc *sc, struct aac_ccb *ac) 1421 1.1 ad { 1422 1.34 briggs struct aac_fibmap *fm; 1423 1.34 briggs u_int32_t acidx; 1424 1.1 ad 1425 1.1 ad AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_submit(%p, %p) ", sc, ac)); 1426 1.1 ad 1427 1.34 briggs acidx = (u_int32_t) (ac - sc->sc_ccbs); 1428 1.1 ad /* Fix up the address values. */ 1429 1.31 briggs ac->ac_fib->Header.SenderFibAddress = htole32(acidx << 2); 1430 1.1 ad ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys); 1431 1.1 ad 1432 1.1 ad /* Save a pointer to the command for speedy reverse-lookup. */ 1433 1.31 briggs ac->ac_fib->Header.SenderData = acidx | 0x80000000; 1434 1.1 ad 1435 1.34 briggs fm = ac->ac_fibmap; 1436 1.34 briggs bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap, 1437 1.34 briggs (char *)ac->ac_fib - (char *)fm->fm_fibs, sc->sc_max_fib_size, 1438 1.1 ad BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1439 1.1 ad 1440 1.1 ad /* Put the FIB on the outbound queue. */ 1441 1.34 briggs if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) { 1442 1.34 briggs int count = 10000000L; 1443 1.34 briggs while (AAC_SEND_COMMAND(sc, ac) != 0) { 1444 1.34 briggs if (--count == 0) { 1445 1.34 briggs panic("aac: fixme!"); 1446 1.34 briggs return EAGAIN; 1447 1.34 briggs } 1448 1.34 briggs DELAY(5); 1449 1.34 briggs } 1450 1.34 briggs return 0; 1451 1.34 briggs } else { 1452 1.34 briggs return (aac_enqueue_fib(sc, AAC_ADAP_NORM_CMD_QUEUE, ac)); 1453 1.34 briggs } 1454 1.1 ad } 1455 1.1 ad 1456 1.1 ad int 1457 1.1 ad aac_ccb_poll(struct aac_softc *sc, struct aac_ccb *ac, int timo) 1458 1.1 ad { 1459 1.1 ad int rv, s; 1460 1.1 ad 1461 1.1 ad AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_poll(%p, %p, %d) ", sc, ac, timo)); 1462 1.1 ad 1463 1.1 ad s = splbio(); 1464 1.1 ad 1465 1.1 ad if ((rv = aac_ccb_submit(sc, ac)) != 0) { 1466 1.1 ad splx(s); 1467 1.1 ad return (rv); 1468 1.1 ad } 1469 1.1 ad 1470 1.1 ad for (timo *= 1000; timo != 0; timo--) { 1471 1.34 briggs if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) 1472 1.34 briggs aac_new_intr(sc); 1473 1.34 briggs else 1474 1.34 briggs aac_intr(sc); 1475 1.1 ad if ((ac->ac_flags & AAC_CCB_COMPLETED) != 0) 1476 1.1 ad break; 1477 1.1 ad DELAY(100); 1478 1.1 ad } 1479 1.1 ad 1480 1.1 ad splx(s); 1481 1.1 ad return (timo == 0); 1482 1.1 ad } 1483 1.1 ad 1484 1.1 ad /* 1485 1.1 ad * Atomically insert an entry into the nominated queue, returns 0 on success 1486 1.1 ad * or EBUSY if the queue is full. 1487 1.1 ad * 1488 1.1 ad * XXX Note that it would be more efficient to defer notifying the 1489 1.1 ad * controller in the case where we may be inserting several entries in rapid 1490 1.1 ad * succession, but implementing this usefully is difficult. 1491 1.1 ad */ 1492 1.12 thorpej static int 1493 1.34 briggs aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_ccb *ac) 1494 1.1 ad { 1495 1.1 ad u_int32_t fib_size, fib_addr, pi, ci; 1496 1.1 ad 1497 1.34 briggs fib_size = le16toh(ac->ac_fib->Header.Size); 1498 1.34 briggs fib_addr = le32toh(ac->ac_fib->Header.ReceiverFibAddress); 1499 1.1 ad 1500 1.1 ad bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1501 1.30 christos (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common, 1502 1.1 ad sizeof(sc->sc_common->ac_qbuf), 1503 1.1 ad BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1504 1.1 ad 1505 1.1 ad /* Get the producer/consumer indices. */ 1506 1.1 ad pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]); 1507 1.1 ad ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]); 1508 1.1 ad 1509 1.1 ad /* Wrap the queue? */ 1510 1.1 ad if (pi >= aac_qinfo[queue].size) 1511 1.1 ad pi = 0; 1512 1.1 ad 1513 1.1 ad /* Check for queue full. */ 1514 1.1 ad if ((pi + 1) == ci) 1515 1.1 ad return (EAGAIN); 1516 1.1 ad 1517 1.1 ad /* Populate queue entry. */ 1518 1.1 ad (sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size); 1519 1.1 ad (sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr); 1520 1.1 ad 1521 1.1 ad /* Update producer index. */ 1522 1.1 ad sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1); 1523 1.1 ad 1524 1.1 ad bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1525 1.30 christos (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common, 1526 1.1 ad sizeof(sc->sc_common->ac_qbuf), 1527 1.1 ad BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1528 1.1 ad 1529 1.1 ad /* Notify the adapter if we know how. */ 1530 1.1 ad if (aac_qinfo[queue].notify != 0) 1531 1.1 ad AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1532 1.1 ad 1533 1.1 ad return (0); 1534 1.1 ad } 1535 1.1 ad 1536 1.1 ad /* 1537 1.1 ad * Atomically remove one entry from the nominated queue, returns 0 on success 1538 1.1 ad * or ENOENT if the queue is empty. 1539 1.1 ad */ 1540 1.12 thorpej static int 1541 1.1 ad aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size, 1542 1.1 ad struct aac_fib **fib_addr) 1543 1.1 ad { 1544 1.34 briggs struct aac_fibmap *fm; 1545 1.31 briggs struct aac_ccb *ac; 1546 1.31 briggs u_int32_t pi, ci, idx; 1547 1.1 ad int notify; 1548 1.1 ad 1549 1.1 ad bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1550 1.30 christos (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common, 1551 1.1 ad sizeof(sc->sc_common->ac_qbuf), 1552 1.1 ad BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1553 1.1 ad 1554 1.1 ad /* Get the producer/consumer indices. */ 1555 1.1 ad pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]); 1556 1.1 ad ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]); 1557 1.1 ad 1558 1.1 ad /* Check for queue empty. */ 1559 1.1 ad if (ci == pi) 1560 1.1 ad return (ENOENT); 1561 1.1 ad 1562 1.1 ad notify = 0; 1563 1.1 ad if (ci == pi + 1) 1564 1.1 ad notify = 1; 1565 1.1 ad 1566 1.1 ad /* Wrap the queue? */ 1567 1.1 ad if (ci >= aac_qinfo[queue].size) 1568 1.1 ad ci = 0; 1569 1.1 ad 1570 1.1 ad /* Fetch the entry. */ 1571 1.1 ad *fib_size = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_size); 1572 1.31 briggs 1573 1.31 briggs switch (queue) { 1574 1.31 briggs case AAC_HOST_NORM_CMD_QUEUE: 1575 1.31 briggs case AAC_HOST_HIGH_CMD_QUEUE: 1576 1.31 briggs idx = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_addr); 1577 1.31 briggs idx /= sizeof(struct aac_fib); 1578 1.31 briggs *fib_addr = &sc->sc_common->ac_fibs[idx]; 1579 1.31 briggs break; 1580 1.31 briggs case AAC_HOST_NORM_RESP_QUEUE: 1581 1.31 briggs case AAC_HOST_HIGH_RESP_QUEUE: 1582 1.31 briggs idx = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_addr); 1583 1.34 briggs ac = sc->sc_ccbs + (idx >> 2); 1584 1.31 briggs *fib_addr = ac->ac_fib; 1585 1.33 briggs if (idx & 0x01) { 1586 1.34 briggs fm = ac->ac_fibmap; 1587 1.34 briggs bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap, 1588 1.34 briggs (char *)ac->ac_fib - (char *)fm->fm_fibs, 1589 1.34 briggs sc->sc_max_fib_size, 1590 1.34 briggs BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1591 1.33 briggs ac->ac_fib->Header.XferState |= 1592 1.33 briggs htole32(AAC_FIBSTATE_DONEADAP); 1593 1.33 briggs *((u_int32_t*)(ac->ac_fib->data)) = 1594 1.33 briggs htole32(AAC_ERROR_NORMAL); 1595 1.33 briggs } 1596 1.31 briggs break; 1597 1.31 briggs default: 1598 1.31 briggs panic("Invalid queue in aac_dequeue_fib()"); 1599 1.31 briggs break; 1600 1.31 briggs } 1601 1.1 ad 1602 1.1 ad /* Update consumer index. */ 1603 1.1 ad sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1; 1604 1.1 ad 1605 1.1 ad bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1606 1.30 christos (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common, 1607 1.1 ad sizeof(sc->sc_common->ac_qbuf), 1608 1.1 ad BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1609 1.1 ad 1610 1.1 ad /* If we have made the queue un-full, notify the adapter. */ 1611 1.1 ad if (notify && (aac_qinfo[queue].notify != 0)) 1612 1.1 ad AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1613 1.1 ad 1614 1.1 ad return (0); 1615 1.1 ad } 1616 1.1 ad 1617 1.31 briggs /* 1618 1.31 briggs * Put our response to an adapter-initiated fib (AIF) on the response queue. 1619 1.31 briggs */ 1620 1.31 briggs static int 1621 1.31 briggs aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib) 1622 1.31 briggs { 1623 1.31 briggs u_int32_t fib_size, fib_addr, pi, ci; 1624 1.31 briggs 1625 1.31 briggs fib_size = le16toh(fib->Header.Size); 1626 1.31 briggs fib_addr = fib->Header.SenderFibAddress; 1627 1.31 briggs fib->Header.ReceiverFibAddress = fib_addr; 1628 1.31 briggs 1629 1.31 briggs bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1630 1.31 briggs (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common, 1631 1.31 briggs sizeof(sc->sc_common->ac_qbuf), 1632 1.31 briggs BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1633 1.31 briggs 1634 1.31 briggs /* Get the producer/consumer indices. */ 1635 1.31 briggs pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]); 1636 1.31 briggs ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]); 1637 1.31 briggs 1638 1.31 briggs /* Wrap the queue? */ 1639 1.31 briggs if (pi >= aac_qinfo[queue].size) 1640 1.31 briggs pi = 0; 1641 1.31 briggs 1642 1.31 briggs /* Check for queue full. */ 1643 1.31 briggs if ((pi + 1) == ci) 1644 1.31 briggs return (EAGAIN); 1645 1.31 briggs 1646 1.31 briggs /* Populate queue entry. */ 1647 1.31 briggs (sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size); 1648 1.31 briggs (sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr); 1649 1.31 briggs 1650 1.31 briggs /* Update producer index. */ 1651 1.31 briggs sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1); 1652 1.31 briggs 1653 1.31 briggs bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1654 1.31 briggs (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common, 1655 1.31 briggs sizeof(sc->sc_common->ac_qbuf), 1656 1.31 briggs BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1657 1.31 briggs 1658 1.31 briggs /* Notify the adapter if we know how. */ 1659 1.31 briggs if (aac_qinfo[queue].notify != 0) 1660 1.31 briggs AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1661 1.31 briggs 1662 1.31 briggs return (0); 1663 1.31 briggs } 1664 1.31 briggs 1665 1.1 ad #ifdef AAC_DEBUG 1666 1.1 ad /* 1667 1.1 ad * Print a FIB 1668 1.1 ad */ 1669 1.12 thorpej static void 1670 1.29 christos aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, 1671 1.28 christos const char *caller) 1672 1.1 ad { 1673 1.1 ad struct aac_blockread *br; 1674 1.1 ad struct aac_blockwrite *bw; 1675 1.1 ad struct aac_sg_table *sg; 1676 1.19 christos char tbuf[512]; 1677 1.1 ad int i; 1678 1.1 ad 1679 1.1 ad printf("%s: FIB @ %p\n", caller, fib); 1680 1.42 christos snprintb(tbuf, sizeof(tbuf), 1681 1.1 ad "\20" 1682 1.1 ad "\1HOSTOWNED" 1683 1.1 ad "\2ADAPTEROWNED" 1684 1.1 ad "\3INITIALISED" 1685 1.1 ad "\4EMPTY" 1686 1.1 ad "\5FROMPOOL" 1687 1.1 ad "\6FROMHOST" 1688 1.1 ad "\7FROMADAP" 1689 1.1 ad "\10REXPECTED" 1690 1.1 ad "\11RNOTEXPECTED" 1691 1.1 ad "\12DONEADAP" 1692 1.1 ad "\13DONEHOST" 1693 1.1 ad "\14HIGH" 1694 1.1 ad "\15NORM" 1695 1.1 ad "\16ASYNC" 1696 1.1 ad "\17PAGEFILEIO" 1697 1.1 ad "\20SHUTDOWN" 1698 1.1 ad "\21LAZYWRITE" 1699 1.1 ad "\22ADAPMICROFIB" 1700 1.1 ad "\23BIOSFIB" 1701 1.1 ad "\24FAST_RESPONSE" 1702 1.42 christos "\25APIFIB\n", le32toh(fib->Header.XferState)); 1703 1.1 ad 1704 1.19 christos printf(" XferState %s\n", tbuf); 1705 1.1 ad printf(" Command %d\n", le16toh(fib->Header.Command)); 1706 1.1 ad printf(" StructType %d\n", fib->Header.StructType); 1707 1.1 ad printf(" Flags 0x%x\n", fib->Header.Flags); 1708 1.1 ad printf(" Size %d\n", le16toh(fib->Header.Size)); 1709 1.1 ad printf(" SenderSize %d\n", le16toh(fib->Header.SenderSize)); 1710 1.1 ad printf(" SenderAddress 0x%x\n", 1711 1.1 ad le32toh(fib->Header.SenderFibAddress)); 1712 1.1 ad printf(" ReceiverAddress 0x%x\n", 1713 1.1 ad le32toh(fib->Header.ReceiverFibAddress)); 1714 1.1 ad printf(" SenderData 0x%x\n", fib->Header.SenderData); 1715 1.1 ad 1716 1.1 ad switch (fib->Header.Command) { 1717 1.1 ad case ContainerCommand: { 1718 1.1 ad br = (struct aac_blockread *)fib->data; 1719 1.1 ad bw = (struct aac_blockwrite *)fib->data; 1720 1.1 ad sg = NULL; 1721 1.1 ad 1722 1.1 ad if (le32toh(br->Command) == VM_CtBlockRead) { 1723 1.16 perry printf(" BlockRead: container %d 0x%x/%d\n", 1724 1.1 ad le32toh(br->ContainerId), le32toh(br->BlockNumber), 1725 1.1 ad le32toh(br->ByteCount)); 1726 1.1 ad sg = &br->SgMap; 1727 1.1 ad } 1728 1.1 ad if (le32toh(bw->Command) == VM_CtBlockWrite) { 1729 1.16 perry printf(" BlockWrite: container %d 0x%x/%d (%s)\n", 1730 1.1 ad le32toh(bw->ContainerId), le32toh(bw->BlockNumber), 1731 1.1 ad le32toh(bw->ByteCount), 1732 1.1 ad le32toh(bw->Stable) == CSTABLE ? 1733 1.1 ad "stable" : "unstable"); 1734 1.1 ad sg = &bw->SgMap; 1735 1.1 ad } 1736 1.1 ad if (sg != NULL) { 1737 1.1 ad printf(" %d s/g entries\n", le32toh(sg->SgCount)); 1738 1.1 ad for (i = 0; i < le32toh(sg->SgCount); i++) 1739 1.1 ad printf(" 0x%08x/%d\n", 1740 1.1 ad le32toh(sg->SgEntry[i].SgAddress), 1741 1.1 ad le32toh(sg->SgEntry[i].SgByteCount)); 1742 1.1 ad } 1743 1.1 ad break; 1744 1.1 ad } 1745 1.1 ad default: 1746 1.24 jdolecek // dump first 32 bytes of fib->data 1747 1.24 jdolecek printf(" Raw data:"); 1748 1.24 jdolecek for (i = 0; i < 32; i++) 1749 1.24 jdolecek printf(" %02x", fib->data[i]); 1750 1.24 jdolecek printf("\n"); 1751 1.1 ad break; 1752 1.1 ad } 1753 1.1 ad } 1754 1.12 thorpej #endif /* AAC_DEBUG */ 1755 1.45 pgoyette 1756 1.45 pgoyette MODULE(MODULE_CLASS_DRIVER, aac, "pci"); 1757 1.45 pgoyette 1758 1.45 pgoyette #ifdef _MODULE 1759 1.45 pgoyette #include "ioconf.c" 1760 1.45 pgoyette #endif 1761 1.45 pgoyette 1762 1.45 pgoyette static int 1763 1.45 pgoyette aac_modcmd(modcmd_t cmd, void *opaque) 1764 1.45 pgoyette { 1765 1.45 pgoyette int error = 0; 1766 1.45 pgoyette 1767 1.45 pgoyette #ifdef _MODULE 1768 1.45 pgoyette switch (cmd) { 1769 1.45 pgoyette case MODULE_CMD_INIT: 1770 1.45 pgoyette error = config_init_component(cfdriver_ioconf_aac, 1771 1.45 pgoyette cfattach_ioconf_aac, cfdata_ioconf_aac); 1772 1.45 pgoyette break; 1773 1.45 pgoyette case MODULE_CMD_FINI: 1774 1.45 pgoyette error = config_fini_component(cfdriver_ioconf_aac, 1775 1.45 pgoyette cfattach_ioconf_aac, cfdata_ioconf_aac); 1776 1.45 pgoyette break; 1777 1.45 pgoyette default: 1778 1.45 pgoyette error = ENOTTY; 1779 1.45 pgoyette break; 1780 1.45 pgoyette } 1781 1.45 pgoyette #endif 1782 1.45 pgoyette 1783 1.45 pgoyette return error; 1784 1.45 pgoyette } 1785