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