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