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