1 /* $NetBSD: aac.c,v 1.46 2017/10/28 04:53:55 riastradh 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.46 2017/10/28 04:53:55 riastradh 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_NOWAIT | M_ZERO); 594 if (sc->sc_aif_fib == NULL) { 595 aprint_error_dev(sc->sc_dv, "cannot alloc fib structure\n"); 596 return (ENOMEM); 597 } 598 if ((rv = bus_dmamap_create(sc->sc_dmat, sizeof(*sc->sc_common), 1, 599 sizeof(*sc->sc_common), 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, 600 &sc->sc_common_dmamap)) != 0) { 601 aprint_error_dev(sc->sc_dv, "cannot create common dmamap\n"); 602 goto bail_out; 603 } 604 state++; 605 if ((rv = bus_dmamem_alloc(sc->sc_dmat, sizeof(*sc->sc_common), 606 PAGE_SIZE, 0, &sc->sc_common_seg, 1, &nsegs, 607 BUS_DMA_NOWAIT)) != 0) { 608 aprint_error_dev(sc->sc_dv, "can't allocate common structure\n"); 609 goto bail_out; 610 } 611 state++; 612 if ((rv = bus_dmamem_map(sc->sc_dmat, &sc->sc_common_seg, nsegs, 613 sizeof(*sc->sc_common), (void **)&sc->sc_common, 0)) != 0) { 614 aprint_error_dev(sc->sc_dv, "can't map common structure\n"); 615 goto bail_out; 616 } 617 state++; 618 if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_common_dmamap, 619 sc->sc_common, sizeof(*sc->sc_common), NULL, 620 BUS_DMA_NOWAIT)) != 0) { 621 aprint_error_dev(sc->sc_dv, "cannot load common dmamap\n"); 622 goto bail_out; 623 } 624 state++; 625 626 memset(sc->sc_common, 0, sizeof(*sc->sc_common)); 627 628 TAILQ_INIT(&sc->sc_fibmap_tqh); 629 sc->sc_ccbs = malloc(sizeof(struct aac_ccb) * sc->sc_max_fibs, M_AACBUF, 630 M_NOWAIT | M_ZERO); 631 if (sc->sc_ccbs == NULL) { 632 aprint_error_dev(sc->sc_dv, "memory allocation failure getting ccbs\n"); 633 rv = ENOMEM; 634 goto bail_out; 635 } 636 state++; 637 while (sc->sc_total_fibs < AAC_PREALLOCATE_FIBS(sc)) { 638 if (aac_alloc_commands(sc) != 0) 639 break; 640 } 641 if (sc->sc_total_fibs == 0) 642 goto bail_out; 643 644 /* 645 * Fill in the init structure. This tells the adapter about the 646 * physical location of various important shared data structures. 647 */ 648 ip = &sc->sc_common->ac_init; 649 ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION); 650 if (sc->sc_quirks & AAC_QUIRK_RAW_IO) 651 ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION_4); 652 ip->MiniPortRevision = htole32(AAC_INIT_STRUCT_MINIPORT_REVISION); 653 654 ip->AdapterFibsPhysicalAddress = htole32(sc->sc_common_seg.ds_addr + 655 offsetof(struct aac_common, ac_fibs)); 656 ip->AdapterFibsVirtualAddress = 0; 657 ip->AdapterFibsSize = 658 htole32(AAC_ADAPTER_FIBS * sizeof(struct aac_fib)); 659 ip->AdapterFibAlign = htole32(sizeof(struct aac_fib)); 660 661 ip->PrintfBufferAddress = htole32(sc->sc_common_seg.ds_addr + 662 offsetof(struct aac_common, ac_printf)); 663 ip->PrintfBufferSize = htole32(AAC_PRINTF_BUFSIZE); 664 665 /* 666 * The adapter assumes that pages are 4K in size, except on some 667 * broken firmware versions that do the page->byte conversion twice, 668 * therefore 'assuming' that this value is in 16MB units (2^24). 669 * Round up since the granularity is so high. 670 */ 671 ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE; 672 if (sc->sc_quirks & AAC_QUIRK_BROKEN_MMAP) { 673 ip->HostPhysMemPages = 674 (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE; 675 } 676 ip->HostElapsedSeconds = 0; /* reset later if invalid */ 677 678 ip->InitFlags = 0; 679 if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) { 680 ip->InitFlags = htole32(AAC_INITFLAGS_NEW_COMM_SUPPORTED); 681 aprint_normal_dev(sc->sc_dv, "New comm. interface enabled\n"); 682 } 683 684 ip->MaxIoCommands = htole32(sc->sc_max_fibs); 685 ip->MaxIoSize = htole32(sc->sc_max_sectors << 9); 686 ip->MaxFibSize = htole32(sc->sc_max_fib_size); 687 688 /* 689 * Initialise FIB queues. Note that it appears that the layout of 690 * the indexes and the segmentation of the entries is mandated by 691 * the adapter, which is only told about the base of the queue index 692 * fields. 693 * 694 * The initial values of the indices are assumed to inform the 695 * adapter of the sizes of the respective queues. 696 * 697 * The Linux driver uses a much more complex scheme whereby several 698 * header records are kept for each queue. We use a couple of 699 * generic list manipulation functions which 'know' the size of each 700 * list by virtue of a table. 701 */ 702 qoff = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN; 703 qoff &= ~(AAC_QUEUE_ALIGN - 1); 704 sc->sc_queues = (struct aac_queue_table *)((uintptr_t)sc->sc_common + qoff); 705 ip->CommHeaderAddress = htole32(sc->sc_common_seg.ds_addr + 706 ((char *)sc->sc_queues - (char *)sc->sc_common)); 707 memset(sc->sc_queues, 0, sizeof(struct aac_queue_table)); 708 709 norm = htole32(AAC_HOST_NORM_CMD_ENTRIES); 710 high = htole32(AAC_HOST_HIGH_CMD_ENTRIES); 711 712 sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 713 norm; 714 sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 715 norm; 716 sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 717 high; 718 sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 719 high; 720 721 norm = htole32(AAC_ADAP_NORM_CMD_ENTRIES); 722 high = htole32(AAC_ADAP_HIGH_CMD_ENTRIES); 723 724 sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 725 norm; 726 sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 727 norm; 728 sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 729 high; 730 sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 731 high; 732 733 norm = htole32(AAC_HOST_NORM_RESP_ENTRIES); 734 high = htole32(AAC_HOST_HIGH_RESP_ENTRIES); 735 736 sc->sc_queues-> 737 qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm; 738 sc->sc_queues-> 739 qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm; 740 sc->sc_queues-> 741 qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high; 742 sc->sc_queues-> 743 qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high; 744 745 norm = htole32(AAC_ADAP_NORM_RESP_ENTRIES); 746 high = htole32(AAC_ADAP_HIGH_RESP_ENTRIES); 747 748 sc->sc_queues-> 749 qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm; 750 sc->sc_queues-> 751 qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm; 752 sc->sc_queues-> 753 qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high; 754 sc->sc_queues-> 755 qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high; 756 757 sc->sc_qentries[AAC_HOST_NORM_CMD_QUEUE] = 758 &sc->sc_queues->qt_HostNormCmdQueue[0]; 759 sc->sc_qentries[AAC_HOST_HIGH_CMD_QUEUE] = 760 &sc->sc_queues->qt_HostHighCmdQueue[0]; 761 sc->sc_qentries[AAC_ADAP_NORM_CMD_QUEUE] = 762 &sc->sc_queues->qt_AdapNormCmdQueue[0]; 763 sc->sc_qentries[AAC_ADAP_HIGH_CMD_QUEUE] = 764 &sc->sc_queues->qt_AdapHighCmdQueue[0]; 765 sc->sc_qentries[AAC_HOST_NORM_RESP_QUEUE] = 766 &sc->sc_queues->qt_HostNormRespQueue[0]; 767 sc->sc_qentries[AAC_HOST_HIGH_RESP_QUEUE] = 768 &sc->sc_queues->qt_HostHighRespQueue[0]; 769 sc->sc_qentries[AAC_ADAP_NORM_RESP_QUEUE] = 770 &sc->sc_queues->qt_AdapNormRespQueue[0]; 771 sc->sc_qentries[AAC_ADAP_HIGH_RESP_QUEUE] = 772 &sc->sc_queues->qt_AdapHighRespQueue[0]; 773 774 /* 775 * Do controller-type-specific initialisation 776 */ 777 switch (sc->sc_hwif) { 778 case AAC_HWIF_I960RX: 779 AAC_SETREG4(sc, AAC_RX_ODBR, ~0); 780 break; 781 } 782 783 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 0, 784 sizeof(*sc->sc_common), 785 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 786 787 /* 788 * Give the init structure to the controller. 789 */ 790 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT, 791 sc->sc_common_seg.ds_addr + offsetof(struct aac_common, ac_init), 792 0, 0, 0, NULL)) { 793 aprint_error_dev(sc->sc_dv, "error establishing init structure\n"); 794 rv = EIO; 795 goto bail_out; 796 } 797 798 return (0); 799 800 bail_out: 801 if (state > 4) 802 free(sc->sc_ccbs, M_AACBUF); 803 if (state > 3) 804 bus_dmamap_unload(sc->sc_dmat, sc->sc_common_dmamap); 805 if (state > 2) 806 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_common, 807 sizeof(*sc->sc_common)); 808 if (state > 1) 809 bus_dmamem_free(sc->sc_dmat, &sc->sc_common_seg, 1); 810 if (state > 0) 811 bus_dmamap_destroy(sc->sc_dmat, sc->sc_common_dmamap); 812 813 free(sc->sc_aif_fib, M_AACBUF); 814 815 return (rv); 816 } 817 818 /* 819 * Probe for containers, create disks. 820 */ 821 static void 822 aac_startup(struct aac_softc *sc) 823 { 824 struct aac_mntinfo mi; 825 struct aac_mntinforesponse mir; 826 struct aac_drive *hd; 827 u_int16_t rsize; 828 size_t ersize; 829 int i; 830 831 /* 832 * Loop over possible containers. 833 */ 834 hd = sc->sc_hdr; 835 836 for (i = 0; i < AAC_MAX_CONTAINERS; i++, hd++) { 837 /* 838 * Request information on this container. 839 */ 840 memset(&mi, 0, sizeof(mi)); 841 /* use 64-bit LBA if enabled */ 842 if (sc->sc_quirks & AAC_QUIRK_LBA_64BIT) { 843 mi.Command = htole32(VM_NameServe64); 844 ersize = sizeof(mir); 845 } else { 846 mi.Command = htole32(VM_NameServe); 847 ersize = sizeof(mir) - sizeof(mir.MntTable[0].CapacityHigh); 848 } 849 mi.MntType = htole32(FT_FILESYS); 850 mi.MntCount = htole32(i); 851 if (aac_sync_fib(sc, ContainerCommand, 0, &mi, sizeof(mi), &mir, 852 &rsize)) { 853 aprint_error_dev(sc->sc_dv, "error probing container %d\n", i); 854 continue; 855 } 856 if (rsize != ersize) { 857 aprint_error_dev(sc->sc_dv, "container info response wrong size " 858 "(%d should be %zu)\n", rsize, ersize); 859 continue; 860 } 861 862 /* 863 * Check container volume type for validity. Note that many 864 * of the possible types may never show up. 865 */ 866 if (le32toh(mir.Status) != ST_OK || 867 le32toh(mir.MntTable[0].VolType) == CT_NONE) 868 continue; 869 870 hd->hd_present = 1; 871 hd->hd_size = le32toh(mir.MntTable[0].Capacity); 872 if (sc->sc_quirks & AAC_QUIRK_LBA_64BIT) 873 hd->hd_size += (u_int64_t) 874 le32toh(mir.MntTable[0].CapacityHigh) << 32; 875 hd->hd_devtype = le32toh(mir.MntTable[0].VolType); 876 hd->hd_size &= ~0x1f; 877 sc->sc_nunits++; 878 } 879 } 880 881 static void 882 aac_shutdown(void *cookie) 883 { 884 struct aac_softc *sc; 885 struct aac_close_command cc; 886 u_int32_t i; 887 888 for (i = 0; i < aac_cd.cd_ndevs; i++) { 889 if ((sc = device_lookup_private(&aac_cd, i)) == NULL) 890 continue; 891 if ((sc->sc_flags & AAC_ONLINE) == 0) 892 continue; 893 894 AAC_MASK_INTERRUPTS(sc); 895 896 /* 897 * Send a Container shutdown followed by a HostShutdown FIB 898 * to the controller to convince it that we don't want to 899 * talk to it anymore. We've been closed and all I/O 900 * completed already 901 */ 902 memset(&cc, 0, sizeof(cc)); 903 cc.Command = htole32(VM_CloseAll); 904 cc.ContainerId = 0xffffffff; 905 if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc), 906 NULL, NULL)) { 907 aprint_error_dev(sc->sc_dv, "unable to halt controller\n"); 908 continue; 909 } 910 911 /* 912 * Note that issuing this command to the controller makes it 913 * shut down but also keeps it from coming back up without a 914 * reset of the PCI bus. 915 */ 916 if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN, 917 &i, sizeof(i), NULL, NULL)) 918 aprint_error_dev(sc->sc_dv, "unable to halt controller\n"); 919 920 sc->sc_flags &= ~AAC_ONLINE; 921 } 922 } 923 924 static int 925 aac_new_intr(void *cookie) 926 { 927 struct aac_softc *sc; 928 u_int32_t index, fast; 929 struct aac_ccb *ac; 930 struct aac_fib *fib; 931 struct aac_fibmap *fm; 932 int i; 933 934 sc = (struct aac_softc *) cookie; 935 936 for (;;) { 937 index = AAC_GET_OUTB_QUEUE(sc); 938 if (index == 0xffffffff) 939 index = AAC_GET_OUTB_QUEUE(sc); 940 if (index == 0xffffffff) 941 break; 942 if (index & 2) { 943 if (index == 0xfffffffe) { 944 /* XXX This means that the controller wants 945 * more work. Ignore it for now. 946 */ 947 continue; 948 } 949 /* AIF */ 950 index &= ~2; 951 fib = sc->sc_aif_fib; 952 for (i = 0; i < sizeof(struct aac_fib)/4; i++) { 953 ((u_int32_t*)fib)[i] = 954 AAC_GETREG4(sc, index + i*4); 955 } 956 #ifdef notyet 957 aac_handle_aif(sc, &fib); 958 #endif 959 960 AAC_SET_OUTB_QUEUE(sc, index); 961 AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY); 962 } else { 963 fast = index & 1; 964 ac = sc->sc_ccbs + (index >> 2); 965 fib = ac->ac_fib; 966 fm = ac->ac_fibmap; 967 if (fast) { 968 bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap, 969 (char *)fib - (char *)fm->fm_fibs, 970 sc->sc_max_fib_size, 971 BUS_DMASYNC_POSTWRITE | 972 BUS_DMASYNC_POSTREAD); 973 fib->Header.XferState |= 974 htole32(AAC_FIBSTATE_DONEADAP); 975 *((u_int32_t *)(fib->data)) = 976 htole32(AAC_ERROR_NORMAL); 977 } 978 ac->ac_flags |= AAC_CCB_COMPLETED; 979 980 if (ac->ac_intr != NULL) 981 (*ac->ac_intr)(ac); 982 else 983 wakeup(ac); 984 } 985 } 986 987 /* 988 * Try to submit more commands. 989 */ 990 if (! SIMPLEQ_EMPTY(&sc->sc_ccb_queue)) 991 aac_ccb_enqueue(sc, NULL); 992 993 return 1; 994 } 995 996 /* 997 * Take an interrupt. 998 */ 999 int 1000 aac_intr(void *cookie) 1001 { 1002 struct aac_softc *sc; 1003 u_int16_t reason; 1004 int claimed; 1005 1006 sc = cookie; 1007 claimed = 0; 1008 1009 AAC_DPRINTF(AAC_D_INTR, ("aac_intr(%p) ", sc)); 1010 1011 reason = AAC_GET_ISTATUS(sc); 1012 AAC_CLEAR_ISTATUS(sc, reason); 1013 1014 AAC_DPRINTF(AAC_D_INTR, ("istatus 0x%04x ", reason)); 1015 1016 /* 1017 * Controller wants to talk to the log. XXX Should we defer this? 1018 */ 1019 if ((reason & AAC_DB_PRINTF) != 0) { 1020 if (sc->sc_common->ac_printf[0] == '\0') 1021 sc->sc_common->ac_printf[0] = ' '; 1022 printf("%s: WARNING: adapter logged message:\n", 1023 device_xname(sc->sc_dv)); 1024 printf("%s: %.*s", device_xname(sc->sc_dv), 1025 AAC_PRINTF_BUFSIZE, sc->sc_common->ac_printf); 1026 sc->sc_common->ac_printf[0] = '\0'; 1027 AAC_QNOTIFY(sc, AAC_DB_PRINTF); 1028 claimed = 1; 1029 } 1030 1031 /* 1032 * Controller has a message for us? 1033 */ 1034 if ((reason & AAC_DB_COMMAND_READY) != 0) { 1035 aac_host_command(sc); 1036 claimed = 1; 1037 } 1038 1039 /* 1040 * Controller has a response for us? 1041 */ 1042 if ((reason & AAC_DB_RESPONSE_READY) != 0) { 1043 aac_host_response(sc); 1044 claimed = 1; 1045 } 1046 1047 /* 1048 * Spurious interrupts that we don't use - reset the mask and clear 1049 * the interrupts. 1050 */ 1051 if ((reason & (AAC_DB_SYNC_COMMAND | AAC_DB_COMMAND_NOT_FULL | 1052 AAC_DB_RESPONSE_NOT_FULL)) != 0) { 1053 AAC_UNMASK_INTERRUPTS(sc); 1054 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND | 1055 AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL); 1056 claimed = 1; 1057 } 1058 1059 return (claimed); 1060 } 1061 1062 /* 1063 * Handle notification of one or more FIBs coming from the controller. 1064 */ 1065 static void 1066 aac_host_command(struct aac_softc *sc) 1067 { 1068 struct aac_fib *fib; 1069 u_int32_t fib_size; 1070 1071 for (;;) { 1072 if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, &fib_size, 1073 &fib)) 1074 break; /* nothing to do */ 1075 1076 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1077 (char *)fib - (char *)sc->sc_common, sizeof(*fib), 1078 BUS_DMASYNC_POSTREAD); 1079 1080 switch (le16toh(fib->Header.Command)) { 1081 case AifRequest: 1082 #ifdef notyet 1083 aac_handle_aif(sc, 1084 (struct aac_aif_command *)&fib->data[0]); 1085 #endif 1086 AAC_PRINT_FIB(sc, fib); 1087 break; 1088 default: 1089 aprint_error_dev(sc->sc_dv, "unknown command from controller\n"); 1090 AAC_PRINT_FIB(sc, fib); 1091 break; 1092 } 1093 1094 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1095 (char *)fib - (char *)sc->sc_common, sizeof(*fib), 1096 BUS_DMASYNC_PREREAD); 1097 1098 if ((fib->Header.XferState == 0) || 1099 (fib->Header.StructType != AAC_FIBTYPE_TFIB)) { 1100 break; // continue; ??? 1101 } 1102 1103 /* XXX reply to FIBs requesting responses ?? */ 1104 1105 /* Return the AIF/FIB to the controller */ 1106 if (le32toh(fib->Header.XferState) & AAC_FIBSTATE_FROMADAP) { 1107 u_int16_t size; 1108 1109 fib->Header.XferState |= 1110 htole32(AAC_FIBSTATE_DONEHOST); 1111 *(u_int32_t*)fib->data = htole32(ST_OK); 1112 1113 /* XXX Compute the Size field? */ 1114 size = le16toh(fib->Header.Size); 1115 if (size > sizeof(struct aac_fib)) { 1116 size = sizeof(struct aac_fib); 1117 fib->Header.Size = htole16(size); 1118 } 1119 1120 /* 1121 * Since we didn't generate this command, it can't 1122 * go through the normal process. 1123 */ 1124 aac_enqueue_response(sc, 1125 AAC_ADAP_NORM_RESP_QUEUE, fib); 1126 } 1127 } 1128 } 1129 1130 /* 1131 * Handle notification of one or more FIBs completed by the controller 1132 */ 1133 static void 1134 aac_host_response(struct aac_softc *sc) 1135 { 1136 struct aac_ccb *ac; 1137 struct aac_fib *fib; 1138 u_int32_t fib_size; 1139 1140 /* 1141 * Look for completed FIBs on our queue. 1142 */ 1143 for (;;) { 1144 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size, 1145 &fib)) 1146 break; /* nothing to do */ 1147 1148 if ((fib->Header.SenderData & 0x80000000) == 0) { 1149 /* Not valid; not sent by us. */ 1150 AAC_PRINT_FIB(sc, fib); 1151 } else { 1152 ac = (struct aac_ccb *)(sc->sc_ccbs + 1153 (fib->Header.SenderData & 0x7fffffff)); 1154 fib->Header.SenderData = 0; 1155 SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_complete, ac, ac_chain); 1156 } 1157 } 1158 1159 /* 1160 * Deal with any completed commands. 1161 */ 1162 while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_complete)) != NULL) { 1163 SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_complete, ac_chain); 1164 ac->ac_flags |= AAC_CCB_COMPLETED; 1165 1166 if (ac->ac_intr != NULL) 1167 (*ac->ac_intr)(ac); 1168 else 1169 wakeup(ac); 1170 } 1171 1172 /* 1173 * Try to submit more commands. 1174 */ 1175 if (! SIMPLEQ_EMPTY(&sc->sc_ccb_queue)) 1176 aac_ccb_enqueue(sc, NULL); 1177 } 1178 1179 /* 1180 * Send a synchronous command to the controller and wait for a result. 1181 */ 1182 static int 1183 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 1184 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp) 1185 { 1186 int i; 1187 u_int32_t status; 1188 int s; 1189 1190 s = splbio(); 1191 1192 /* Populate the mailbox. */ 1193 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3); 1194 1195 /* Ensure the sync command doorbell flag is cleared. */ 1196 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1197 1198 /* ... then set it to signal the adapter. */ 1199 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND); 1200 DELAY(AAC_SYNC_DELAY); 1201 1202 /* Spin waiting for the command to complete. */ 1203 for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) { 1204 if (AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND) 1205 break; 1206 DELAY(1000); 1207 } 1208 if (i == AAC_IMMEDIATE_TIMEOUT * 1000) { 1209 splx(s); 1210 return (EIO); 1211 } 1212 1213 /* Clear the completion flag. */ 1214 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1215 1216 /* Get the command status. */ 1217 status = AAC_GET_MAILBOXSTATUS(sc); 1218 splx(s); 1219 if (sp != NULL) 1220 *sp = status; 1221 1222 return (0); /* XXX Check command return status? */ 1223 } 1224 1225 /* 1226 * Send a synchronous FIB to the controller and wait for a result. 1227 */ 1228 static int 1229 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate, 1230 void *data, u_int16_t datasize, void *result, 1231 u_int16_t *resultsize) 1232 { 1233 struct aac_fib *fib; 1234 u_int32_t fibpa, status; 1235 1236 fib = &sc->sc_common->ac_sync_fib; 1237 fibpa = sc->sc_common_seg.ds_addr + 1238 offsetof(struct aac_common, ac_sync_fib); 1239 1240 if (datasize > AAC_FIB_DATASIZE) 1241 return (EINVAL); 1242 1243 /* 1244 * Set up the sync FIB. 1245 */ 1246 fib->Header.XferState = htole32(AAC_FIBSTATE_HOSTOWNED | 1247 AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_EMPTY | xferstate); 1248 fib->Header.Command = htole16(command); 1249 fib->Header.StructType = AAC_FIBTYPE_TFIB; 1250 fib->Header.Size = htole16(sizeof(*fib) + datasize); 1251 fib->Header.SenderSize = htole16(sizeof(*fib)); 1252 fib->Header.SenderFibAddress = 0; /* not needed */ 1253 fib->Header.ReceiverFibAddress = htole32(fibpa); 1254 1255 /* 1256 * Copy in data. 1257 */ 1258 if (data != NULL) { 1259 memcpy(fib->data, data, datasize); 1260 fib->Header.XferState |= 1261 htole32(AAC_FIBSTATE_FROMHOST | AAC_FIBSTATE_NORM); 1262 } 1263 1264 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1265 (char *)fib - (char *)sc->sc_common, sizeof(*fib), 1266 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1267 1268 /* 1269 * Give the FIB to the controller, wait for a response. 1270 */ 1271 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, fibpa, 0, 0, 0, &status)) 1272 return (EIO); 1273 if (status != 1) { 1274 printf("%s: syncfib command %04x status %08x\n", 1275 device_xname(sc->sc_dv), command, status); 1276 } 1277 1278 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1279 (char *)fib - (char *)sc->sc_common, sizeof(*fib), 1280 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1281 1282 /* 1283 * Copy out the result 1284 */ 1285 if (result != NULL) { 1286 *resultsize = le16toh(fib->Header.Size) - sizeof(fib->Header); 1287 memcpy(result, fib->data, *resultsize); 1288 } 1289 1290 return (0); 1291 } 1292 1293 struct aac_ccb * 1294 aac_ccb_alloc(struct aac_softc *sc, int flags) 1295 { 1296 struct aac_ccb *ac; 1297 int s; 1298 1299 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_alloc(%p, 0x%x) ", sc, flags)); 1300 1301 s = splbio(); 1302 ac = SIMPLEQ_FIRST(&sc->sc_ccb_free); 1303 if (ac == NULL) { 1304 if (aac_alloc_commands(sc)) { 1305 splx(s); 1306 return NULL; 1307 } 1308 ac = SIMPLEQ_FIRST(&sc->sc_ccb_free); 1309 } 1310 #ifdef DIAGNOSTIC 1311 if (ac == NULL) 1312 panic("aac_ccb_get: no free CCBS"); 1313 #endif 1314 SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, ac_chain); 1315 splx(s); 1316 1317 ac->ac_flags = flags; 1318 return (ac); 1319 } 1320 1321 void 1322 aac_ccb_free(struct aac_softc *sc, struct aac_ccb *ac) 1323 { 1324 int s; 1325 1326 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_free(%p, %p) ", sc, ac)); 1327 1328 ac->ac_flags = 0; 1329 ac->ac_intr = NULL; 1330 ac->ac_fib->Header.XferState = htole32(AAC_FIBSTATE_EMPTY); 1331 ac->ac_fib->Header.StructType = AAC_FIBTYPE_TFIB; 1332 ac->ac_fib->Header.Flags = 0; 1333 ac->ac_fib->Header.SenderSize = htole16(sc->sc_max_fib_size); 1334 1335 #ifdef AAC_DEBUG 1336 /* 1337 * These are duplicated in aac_ccb_submit() to cover the case where 1338 * an intermediate stage may have destroyed them. They're left 1339 * initialised here for debugging purposes only. 1340 */ 1341 ac->ac_fib->Header.SenderFibAddress = 1342 htole32(((u_int32_t) (ac - sc->sc_ccbs)) << 2); 1343 ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys); 1344 #endif 1345 1346 s = splbio(); 1347 SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ac, ac_chain); 1348 splx(s); 1349 } 1350 1351 int 1352 aac_ccb_map(struct aac_softc *sc, struct aac_ccb *ac) 1353 { 1354 int error; 1355 1356 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_map(%p, %p) ", sc, ac)); 1357 1358 #ifdef DIAGNOSTIC 1359 if ((ac->ac_flags & AAC_CCB_MAPPED) != 0) 1360 panic("aac_ccb_map: already mapped"); 1361 #endif 1362 1363 error = bus_dmamap_load(sc->sc_dmat, ac->ac_dmamap_xfer, ac->ac_data, 1364 ac->ac_datalen, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING | 1365 ((ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMA_READ : BUS_DMA_WRITE)); 1366 if (error) { 1367 printf("%s: aac_ccb_map: ", device_xname(sc->sc_dv)); 1368 if (error == EFBIG) 1369 printf("more than %d DMA segs\n", sc->sc_max_sgs); 1370 else 1371 printf("error %d loading DMA map\n", error); 1372 return (error); 1373 } 1374 1375 bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen, 1376 (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_PREREAD : 1377 BUS_DMASYNC_PREWRITE); 1378 1379 #ifdef DIAGNOSTIC 1380 ac->ac_flags |= AAC_CCB_MAPPED; 1381 #endif 1382 return (0); 1383 } 1384 1385 void 1386 aac_ccb_unmap(struct aac_softc *sc, struct aac_ccb *ac) 1387 { 1388 1389 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_unmap(%p, %p) ", sc, ac)); 1390 1391 #ifdef DIAGNOSTIC 1392 if ((ac->ac_flags & AAC_CCB_MAPPED) == 0) 1393 panic("aac_ccb_unmap: not mapped"); 1394 #endif 1395 1396 bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen, 1397 (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_POSTREAD : 1398 BUS_DMASYNC_POSTWRITE); 1399 bus_dmamap_unload(sc->sc_dmat, ac->ac_dmamap_xfer); 1400 1401 #ifdef DIAGNOSTIC 1402 ac->ac_flags &= ~AAC_CCB_MAPPED; 1403 #endif 1404 } 1405 1406 void 1407 aac_ccb_enqueue(struct aac_softc *sc, struct aac_ccb *ac) 1408 { 1409 int s; 1410 1411 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_enqueue(%p, %p) ", sc, ac)); 1412 1413 s = splbio(); 1414 1415 if (ac != NULL) 1416 SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_queue, ac, ac_chain); 1417 1418 while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_queue)) != NULL) { 1419 if (aac_ccb_submit(sc, ac)) 1420 break; 1421 SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_queue, ac_chain); 1422 } 1423 1424 splx(s); 1425 } 1426 1427 int 1428 aac_ccb_submit(struct aac_softc *sc, struct aac_ccb *ac) 1429 { 1430 struct aac_fibmap *fm; 1431 u_int32_t acidx; 1432 1433 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_submit(%p, %p) ", sc, ac)); 1434 1435 acidx = (u_int32_t) (ac - sc->sc_ccbs); 1436 /* Fix up the address values. */ 1437 ac->ac_fib->Header.SenderFibAddress = htole32(acidx << 2); 1438 ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys); 1439 1440 /* Save a pointer to the command for speedy reverse-lookup. */ 1441 ac->ac_fib->Header.SenderData = acidx | 0x80000000; 1442 1443 fm = ac->ac_fibmap; 1444 bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap, 1445 (char *)ac->ac_fib - (char *)fm->fm_fibs, sc->sc_max_fib_size, 1446 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1447 1448 /* Put the FIB on the outbound queue. */ 1449 if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) { 1450 int count = 10000000L; 1451 while (AAC_SEND_COMMAND(sc, ac) != 0) { 1452 if (--count == 0) { 1453 panic("aac: fixme!"); 1454 return EAGAIN; 1455 } 1456 DELAY(5); 1457 } 1458 return 0; 1459 } else { 1460 return (aac_enqueue_fib(sc, AAC_ADAP_NORM_CMD_QUEUE, ac)); 1461 } 1462 } 1463 1464 int 1465 aac_ccb_poll(struct aac_softc *sc, struct aac_ccb *ac, int timo) 1466 { 1467 int rv, s; 1468 1469 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_poll(%p, %p, %d) ", sc, ac, timo)); 1470 1471 s = splbio(); 1472 1473 if ((rv = aac_ccb_submit(sc, ac)) != 0) { 1474 splx(s); 1475 return (rv); 1476 } 1477 1478 for (timo *= 1000; timo != 0; timo--) { 1479 if (sc->sc_quirks & AAC_QUIRK_NEW_COMM) 1480 aac_new_intr(sc); 1481 else 1482 aac_intr(sc); 1483 if ((ac->ac_flags & AAC_CCB_COMPLETED) != 0) 1484 break; 1485 DELAY(100); 1486 } 1487 1488 splx(s); 1489 return (timo == 0); 1490 } 1491 1492 /* 1493 * Atomically insert an entry into the nominated queue, returns 0 on success 1494 * or EBUSY if the queue is full. 1495 * 1496 * XXX Note that it would be more efficient to defer notifying the 1497 * controller in the case where we may be inserting several entries in rapid 1498 * succession, but implementing this usefully is difficult. 1499 */ 1500 static int 1501 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_ccb *ac) 1502 { 1503 u_int32_t fib_size, fib_addr, pi, ci; 1504 1505 fib_size = le16toh(ac->ac_fib->Header.Size); 1506 fib_addr = le32toh(ac->ac_fib->Header.ReceiverFibAddress); 1507 1508 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1509 (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common, 1510 sizeof(sc->sc_common->ac_qbuf), 1511 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1512 1513 /* Get the producer/consumer indices. */ 1514 pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]); 1515 ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]); 1516 1517 /* Wrap the queue? */ 1518 if (pi >= aac_qinfo[queue].size) 1519 pi = 0; 1520 1521 /* Check for queue full. */ 1522 if ((pi + 1) == ci) 1523 return (EAGAIN); 1524 1525 /* Populate queue entry. */ 1526 (sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size); 1527 (sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr); 1528 1529 /* Update producer index. */ 1530 sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1); 1531 1532 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1533 (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common, 1534 sizeof(sc->sc_common->ac_qbuf), 1535 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1536 1537 /* Notify the adapter if we know how. */ 1538 if (aac_qinfo[queue].notify != 0) 1539 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1540 1541 return (0); 1542 } 1543 1544 /* 1545 * Atomically remove one entry from the nominated queue, returns 0 on success 1546 * or ENOENT if the queue is empty. 1547 */ 1548 static int 1549 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size, 1550 struct aac_fib **fib_addr) 1551 { 1552 struct aac_fibmap *fm; 1553 struct aac_ccb *ac; 1554 u_int32_t pi, ci, idx; 1555 int notify; 1556 1557 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1558 (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common, 1559 sizeof(sc->sc_common->ac_qbuf), 1560 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1561 1562 /* Get the producer/consumer indices. */ 1563 pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]); 1564 ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]); 1565 1566 /* Check for queue empty. */ 1567 if (ci == pi) 1568 return (ENOENT); 1569 1570 notify = 0; 1571 if (ci == pi + 1) 1572 notify = 1; 1573 1574 /* Wrap the queue? */ 1575 if (ci >= aac_qinfo[queue].size) 1576 ci = 0; 1577 1578 /* Fetch the entry. */ 1579 *fib_size = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_size); 1580 1581 switch (queue) { 1582 case AAC_HOST_NORM_CMD_QUEUE: 1583 case AAC_HOST_HIGH_CMD_QUEUE: 1584 idx = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_addr); 1585 idx /= sizeof(struct aac_fib); 1586 *fib_addr = &sc->sc_common->ac_fibs[idx]; 1587 break; 1588 case AAC_HOST_NORM_RESP_QUEUE: 1589 case AAC_HOST_HIGH_RESP_QUEUE: 1590 idx = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_addr); 1591 ac = sc->sc_ccbs + (idx >> 2); 1592 *fib_addr = ac->ac_fib; 1593 if (idx & 0x01) { 1594 fm = ac->ac_fibmap; 1595 bus_dmamap_sync(sc->sc_dmat, fm->fm_fibmap, 1596 (char *)ac->ac_fib - (char *)fm->fm_fibs, 1597 sc->sc_max_fib_size, 1598 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1599 ac->ac_fib->Header.XferState |= 1600 htole32(AAC_FIBSTATE_DONEADAP); 1601 *((u_int32_t*)(ac->ac_fib->data)) = 1602 htole32(AAC_ERROR_NORMAL); 1603 } 1604 break; 1605 default: 1606 panic("Invalid queue in aac_dequeue_fib()"); 1607 break; 1608 } 1609 1610 /* Update consumer index. */ 1611 sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1; 1612 1613 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1614 (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common, 1615 sizeof(sc->sc_common->ac_qbuf), 1616 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1617 1618 /* If we have made the queue un-full, notify the adapter. */ 1619 if (notify && (aac_qinfo[queue].notify != 0)) 1620 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1621 1622 return (0); 1623 } 1624 1625 /* 1626 * Put our response to an adapter-initiated fib (AIF) on the response queue. 1627 */ 1628 static int 1629 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib) 1630 { 1631 u_int32_t fib_size, fib_addr, pi, ci; 1632 1633 fib_size = le16toh(fib->Header.Size); 1634 fib_addr = fib->Header.SenderFibAddress; 1635 fib->Header.ReceiverFibAddress = fib_addr; 1636 1637 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1638 (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common, 1639 sizeof(sc->sc_common->ac_qbuf), 1640 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1641 1642 /* Get the producer/consumer indices. */ 1643 pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]); 1644 ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]); 1645 1646 /* Wrap the queue? */ 1647 if (pi >= aac_qinfo[queue].size) 1648 pi = 0; 1649 1650 /* Check for queue full. */ 1651 if ((pi + 1) == ci) 1652 return (EAGAIN); 1653 1654 /* Populate queue entry. */ 1655 (sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size); 1656 (sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr); 1657 1658 /* Update producer index. */ 1659 sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1); 1660 1661 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1662 (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common, 1663 sizeof(sc->sc_common->ac_qbuf), 1664 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1665 1666 /* Notify the adapter if we know how. */ 1667 if (aac_qinfo[queue].notify != 0) 1668 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1669 1670 return (0); 1671 } 1672 1673 #ifdef AAC_DEBUG 1674 /* 1675 * Print a FIB 1676 */ 1677 static void 1678 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, 1679 const char *caller) 1680 { 1681 struct aac_blockread *br; 1682 struct aac_blockwrite *bw; 1683 struct aac_sg_table *sg; 1684 char tbuf[512]; 1685 int i; 1686 1687 printf("%s: FIB @ %p\n", caller, fib); 1688 snprintb(tbuf, sizeof(tbuf), 1689 "\20" 1690 "\1HOSTOWNED" 1691 "\2ADAPTEROWNED" 1692 "\3INITIALISED" 1693 "\4EMPTY" 1694 "\5FROMPOOL" 1695 "\6FROMHOST" 1696 "\7FROMADAP" 1697 "\10REXPECTED" 1698 "\11RNOTEXPECTED" 1699 "\12DONEADAP" 1700 "\13DONEHOST" 1701 "\14HIGH" 1702 "\15NORM" 1703 "\16ASYNC" 1704 "\17PAGEFILEIO" 1705 "\20SHUTDOWN" 1706 "\21LAZYWRITE" 1707 "\22ADAPMICROFIB" 1708 "\23BIOSFIB" 1709 "\24FAST_RESPONSE" 1710 "\25APIFIB\n", le32toh(fib->Header.XferState)); 1711 1712 printf(" XferState %s\n", tbuf); 1713 printf(" Command %d\n", le16toh(fib->Header.Command)); 1714 printf(" StructType %d\n", fib->Header.StructType); 1715 printf(" Flags 0x%x\n", fib->Header.Flags); 1716 printf(" Size %d\n", le16toh(fib->Header.Size)); 1717 printf(" SenderSize %d\n", le16toh(fib->Header.SenderSize)); 1718 printf(" SenderAddress 0x%x\n", 1719 le32toh(fib->Header.SenderFibAddress)); 1720 printf(" ReceiverAddress 0x%x\n", 1721 le32toh(fib->Header.ReceiverFibAddress)); 1722 printf(" SenderData 0x%x\n", fib->Header.SenderData); 1723 1724 switch (fib->Header.Command) { 1725 case ContainerCommand: { 1726 br = (struct aac_blockread *)fib->data; 1727 bw = (struct aac_blockwrite *)fib->data; 1728 sg = NULL; 1729 1730 if (le32toh(br->Command) == VM_CtBlockRead) { 1731 printf(" BlockRead: container %d 0x%x/%d\n", 1732 le32toh(br->ContainerId), le32toh(br->BlockNumber), 1733 le32toh(br->ByteCount)); 1734 sg = &br->SgMap; 1735 } 1736 if (le32toh(bw->Command) == VM_CtBlockWrite) { 1737 printf(" BlockWrite: container %d 0x%x/%d (%s)\n", 1738 le32toh(bw->ContainerId), le32toh(bw->BlockNumber), 1739 le32toh(bw->ByteCount), 1740 le32toh(bw->Stable) == CSTABLE ? 1741 "stable" : "unstable"); 1742 sg = &bw->SgMap; 1743 } 1744 if (sg != NULL) { 1745 printf(" %d s/g entries\n", le32toh(sg->SgCount)); 1746 for (i = 0; i < le32toh(sg->SgCount); i++) 1747 printf(" 0x%08x/%d\n", 1748 le32toh(sg->SgEntry[i].SgAddress), 1749 le32toh(sg->SgEntry[i].SgByteCount)); 1750 } 1751 break; 1752 } 1753 default: 1754 // dump first 32 bytes of fib->data 1755 printf(" Raw data:"); 1756 for (i = 0; i < 32; i++) 1757 printf(" %02x", fib->data[i]); 1758 printf("\n"); 1759 break; 1760 } 1761 } 1762 #endif /* AAC_DEBUG */ 1763 1764 MODULE(MODULE_CLASS_DRIVER, aac, "pci"); 1765 1766 #ifdef _MODULE 1767 #include "ioconf.c" 1768 #endif 1769 1770 static int 1771 aac_modcmd(modcmd_t cmd, void *opaque) 1772 { 1773 int error = 0; 1774 1775 #ifdef _MODULE 1776 switch (cmd) { 1777 case MODULE_CMD_INIT: 1778 error = config_init_component(cfdriver_ioconf_aac, 1779 cfattach_ioconf_aac, cfdata_ioconf_aac); 1780 break; 1781 case MODULE_CMD_FINI: 1782 error = config_fini_component(cfdriver_ioconf_aac, 1783 cfattach_ioconf_aac, cfdata_ioconf_aac); 1784 break; 1785 default: 1786 error = ENOTTY; 1787 break; 1788 } 1789 #endif 1790 1791 return error; 1792 } 1793