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