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