1 /* $OpenBSD: aac.c,v 1.54 2011/07/17 22:46:48 matthew Exp $ */ 2 3 /*- 4 * Copyright (c) 2000 Michael Smith 5 * Copyright (c) 2001 Scott Long 6 * Copyright (c) 2000 BSDi 7 * Copyright (c) 2001 Adaptec, Inc. 8 * Copyright (c) 2000 Niklas Hallqvist 9 * Copyright (c) 2004 Nathan Binkert 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * $FreeBSD: /c/ncvs/src/sys/dev/aac/aac.c,v 1.1 2000/09/13 03:20:34 msmith Exp $ 34 */ 35 36 /* 37 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters. 38 */ 39 40 /* 41 * This driver would not have rewritten for OpenBSD if it was not for the 42 * hardware donation from Nocom. I want to thank them for their support. 43 * Of course, credit should go to Mike Smith for the original work he did 44 * in the FreeBSD driver where I found lots of reusable code and inspiration. 45 * - Niklas Hallqvist 46 */ 47 48 #include <sys/param.h> 49 #include <sys/systm.h> 50 #include <sys/buf.h> 51 #include <sys/device.h> 52 #include <sys/kernel.h> 53 #include <sys/kthread.h> 54 #include <sys/malloc.h> 55 #include <sys/rwlock.h> 56 #include <sys/time.h> 57 58 #include <machine/bus.h> 59 60 #include <uvm/uvm_extern.h> 61 62 #include <scsi/scsi_all.h> 63 #include <scsi/scsi_disk.h> 64 #include <scsi/scsiconf.h> 65 66 #include <dev/ic/aacreg.h> 67 #include <dev/ic/aacvar.h> 68 #include <dev/ic/aac_tables.h> 69 70 /* Geometry constants. */ 71 #define AAC_MAXCYLS 1024 72 #define AAC_HEADS 64 73 #define AAC_SECS 32 /* mapping 64*32 */ 74 #define AAC_MEDHEADS 127 75 #define AAC_MEDSECS 63 /* mapping 127*63 */ 76 #define AAC_BIGHEADS 255 77 #define AAC_BIGSECS 63 /* mapping 255*63 */ 78 #define AAC_SECS32 0x1f /* round capacity */ 79 80 struct scsi_xfer; 81 82 void aac_copy_internal_data(struct scsi_xfer *, u_int8_t *, size_t); 83 char *aac_describe_code(struct aac_code_lookup *, u_int32_t); 84 void aac_describe_controller(struct aac_softc *); 85 int aac_enqueue_fib(struct aac_softc *, int, struct aac_command *); 86 int aac_dequeue_fib(struct aac_softc *, int, u_int32_t *, 87 struct aac_fib **); 88 int aac_enqueue_response(struct aac_softc *sc, int queue, 89 struct aac_fib *fib); 90 91 void aac_eval_mapping(u_int32_t, int *, int *, int *); 92 void aac_print_printf(struct aac_softc *); 93 int aac_init(struct aac_softc *); 94 int aac_check_firmware(struct aac_softc *); 95 void aac_internal_cache_cmd(struct scsi_xfer *); 96 97 /* Command Processing */ 98 void aac_timeout(struct aac_softc *); 99 void aac_command_timeout(struct aac_command *); 100 int aac_map_command(struct aac_command *); 101 void aac_complete(void *); 102 int aac_bio_command(struct aac_softc *, struct aac_command **); 103 void aac_bio_complete(struct aac_command *); 104 int aac_wait_command(struct aac_command *, int); 105 void aac_create_thread(void *); 106 void aac_command_thread(void *); 107 108 /* Command Buffer Management */ 109 void aac_map_command_sg(void *, bus_dma_segment_t *, int, int); 110 int aac_alloc_commands(struct aac_softc *); 111 void aac_free_commands(struct aac_softc *); 112 void aac_unmap_command(struct aac_command *); 113 114 void aac_scsi_cmd(struct scsi_xfer *); 115 void aac_startio(struct aac_softc *); 116 void aac_startup(struct aac_softc *); 117 void aac_add_container(struct aac_softc *, struct aac_mntinforesp *, int); 118 void aac_shutdown(void *); 119 int aac_sync_command(struct aac_softc *, u_int32_t, u_int32_t, 120 u_int32_t, u_int32_t, u_int32_t, u_int32_t *); 121 122 struct cfdriver aac_cd = { 123 NULL, "aac", DV_DULL 124 }; 125 126 struct scsi_adapter aac_switch = { 127 aac_scsi_cmd, aacminphys, 0, 0, 128 }; 129 130 /* Falcon/PPC interface */ 131 int aac_fa_get_fwstatus(struct aac_softc *); 132 void aac_fa_qnotify(struct aac_softc *, int); 133 int aac_fa_get_istatus(struct aac_softc *); 134 void aac_fa_clear_istatus(struct aac_softc *, int); 135 void aac_fa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t, u_int32_t, 136 u_int32_t, u_int32_t); 137 int aac_fa_get_mailbox(struct aac_softc *, int); 138 void aac_fa_set_interrupts(struct aac_softc *, int); 139 140 struct aac_interface aac_fa_interface = { 141 aac_fa_get_fwstatus, 142 aac_fa_qnotify, 143 aac_fa_get_istatus, 144 aac_fa_clear_istatus, 145 aac_fa_set_mailbox, 146 aac_fa_get_mailbox, 147 aac_fa_set_interrupts 148 }; 149 150 /* StrongARM interface */ 151 int aac_sa_get_fwstatus(struct aac_softc *); 152 void aac_sa_qnotify(struct aac_softc *, int); 153 int aac_sa_get_istatus(struct aac_softc *); 154 void aac_sa_clear_istatus(struct aac_softc *, int); 155 void aac_sa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t, 156 u_int32_t, u_int32_t, u_int32_t); 157 int aac_sa_get_mailbox(struct aac_softc *, int); 158 void aac_sa_set_interrupts(struct aac_softc *, int); 159 160 struct aac_interface aac_sa_interface = { 161 aac_sa_get_fwstatus, 162 aac_sa_qnotify, 163 aac_sa_get_istatus, 164 aac_sa_clear_istatus, 165 aac_sa_set_mailbox, 166 aac_sa_get_mailbox, 167 aac_sa_set_interrupts 168 }; 169 170 /* i960Rx interface */ 171 int aac_rx_get_fwstatus(struct aac_softc *); 172 void aac_rx_qnotify(struct aac_softc *, int); 173 int aac_rx_get_istatus(struct aac_softc *); 174 void aac_rx_clear_istatus(struct aac_softc *, int); 175 void aac_rx_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t, 176 u_int32_t, u_int32_t, u_int32_t); 177 int aac_rx_get_mailbox(struct aac_softc *, int); 178 void aac_rx_set_interrupts(struct aac_softc *, int); 179 180 struct aac_interface aac_rx_interface = { 181 aac_rx_get_fwstatus, 182 aac_rx_qnotify, 183 aac_rx_get_istatus, 184 aac_rx_clear_istatus, 185 aac_rx_set_mailbox, 186 aac_rx_get_mailbox, 187 aac_rx_set_interrupts 188 }; 189 190 /* Rocket/MIPS interface */ 191 int aac_rkt_get_fwstatus(struct aac_softc *); 192 void aac_rkt_qnotify(struct aac_softc *, int); 193 int aac_rkt_get_istatus(struct aac_softc *); 194 void aac_rkt_clear_istatus(struct aac_softc *, int); 195 void aac_rkt_set_mailbox(struct aac_softc *, u_int32_t, 196 u_int32_t, u_int32_t, 197 u_int32_t, u_int32_t); 198 int aac_rkt_get_mailbox(struct aac_softc *, int); 199 void aac_rkt_set_interrupts(struct aac_softc *, int); 200 201 struct aac_interface aac_rkt_interface = { 202 aac_rkt_get_fwstatus, 203 aac_rkt_qnotify, 204 aac_rkt_get_istatus, 205 aac_rkt_clear_istatus, 206 aac_rkt_set_mailbox, 207 aac_rkt_get_mailbox, 208 aac_rkt_set_interrupts 209 }; 210 211 #ifdef AAC_DEBUG 212 int aac_debug = AAC_DEBUG; 213 #endif 214 215 int 216 aac_attach(struct aac_softc *sc) 217 { 218 struct scsibus_attach_args saa; 219 int error; 220 221 /* 222 * Initialise per-controller queues. 223 */ 224 aac_initq_free(sc); 225 aac_initq_ready(sc); 226 aac_initq_busy(sc); 227 aac_initq_bio(sc); 228 229 /* disable interrupts before we enable anything */ 230 AAC_MASK_INTERRUPTS(sc); 231 232 /* mark controller as suspended until we get ourselves organised */ 233 sc->aac_state |= AAC_STATE_SUSPEND; 234 235 /* 236 * Check that the firmware on the card is supported. 237 */ 238 error = aac_check_firmware(sc); 239 if (error) 240 return (error); 241 242 /* 243 * Initialize locks 244 */ 245 AAC_LOCK_INIT(&sc->aac_sync_lock, "AAC sync FIB lock"); 246 AAC_LOCK_INIT(&sc->aac_aifq_lock, "AAC AIF lock"); 247 AAC_LOCK_INIT(&sc->aac_io_lock, "AAC I/O lock"); 248 AAC_LOCK_INIT(&sc->aac_container_lock, "AAC container lock"); 249 TAILQ_INIT(&sc->aac_container_tqh); 250 251 /* Initialize the local AIF queue pointers */ 252 sc->aac_aifq_head = sc->aac_aifq_tail = AAC_AIFQ_LENGTH; 253 254 /* 255 * Initialise the adapter. 256 */ 257 error = aac_init(sc); 258 if (error) 259 return (error); 260 261 /* Fill in the prototype scsi_link. */ 262 sc->aac_link.adapter_softc = sc; 263 sc->aac_link.adapter = &aac_switch; 264 sc->aac_link.openings = (sc->total_fibs - 8) / 265 (sc->aac_container_count ? sc->aac_container_count : 1); 266 sc->aac_link.adapter_buswidth = AAC_MAX_CONTAINERS; 267 sc->aac_link.adapter_target = AAC_MAX_CONTAINERS; 268 269 bzero(&saa, sizeof(saa)); 270 saa.saa_sc_link = &sc->aac_link; 271 272 config_found(&sc->aac_dev, &saa, scsiprint); 273 274 /* Create the AIF thread */ 275 sc->aifthread = 0; 276 sc->aifflags = 0; 277 kthread_create_deferred(aac_create_thread, sc); 278 279 #if 0 280 /* Register the shutdown method to only be called post-dump */ 281 sc->aac_sdh = shutdownhook_establish(aac_shutdown, (void *)sc); 282 #endif 283 284 return (0); 285 } 286 287 void 288 aac_create_thread(void *arg) 289 { 290 struct aac_softc *sc = arg; 291 292 if (kthread_create(aac_command_thread, sc, &sc->aifthread, "%s", 293 sc->aac_dev.dv_xname)) { 294 /* TODO disable aac */ 295 printf("%s: failed to create kernel thread, disabled", 296 sc->aac_dev.dv_xname); 297 } 298 AAC_DPRINTF(AAC_D_MISC, ("%s: aac_create_thread\n", 299 sc->aac_dev.dv_xname)); 300 301 } 302 303 /* 304 * Probe for containers, create disks. 305 */ 306 void 307 aac_startup(struct aac_softc *sc) 308 { 309 struct aac_fib *fib; 310 struct aac_mntinfo *mi; 311 struct aac_mntinforesp *mir = NULL; 312 int count = 0, i = 0; 313 314 315 aac_alloc_sync_fib(sc, &fib, 0); 316 mi = (struct aac_mntinfo *)&fib->data[0]; 317 318 AAC_DPRINTF(AAC_D_MISC, ("%s: aac startup\n", sc->aac_dev.dv_xname)); 319 320 sc->aac_container_count = 0; 321 /* loop over possible containers */ 322 do { 323 /* request information on this container */ 324 bzero(mi, sizeof(struct aac_mntinfo)); 325 mi->Command = VM_NameServe; 326 mi->MntType = FT_FILESYS; 327 mi->MntCount = i; 328 if (aac_sync_fib(sc, ContainerCommand, 0, fib, 329 sizeof(struct aac_mntinfo))) { 330 printf("%s: error probing container %d\n", 331 sc->aac_dev.dv_xname, i); 332 continue; 333 } 334 335 mir = (struct aac_mntinforesp *)&fib->data[0]; 336 /* XXX Need to check if count changed */ 337 count = mir->MntRespCount; 338 339 #if 0 340 aac_add_container(sc, mir, 0); 341 #else 342 /* 343 * Check container volume type for validity. Note 344 * that many of the possible types may never show up. 345 */ 346 if (mir->Status == ST_OK && 347 mir->MntTable[0].VolType != CT_NONE) { 348 int drv_cyls, drv_hds, drv_secs; 349 350 AAC_DPRINTF(AAC_D_MISC, 351 ("%s: %d: id %x name '%.16s' size %u type %d\n", 352 sc->aac_dev.dv_xname, i, 353 mir->MntTable[0].ObjectId, 354 mir->MntTable[0].FileSystemName, 355 mir->MntTable[0].Capacity, 356 mir->MntTable[0].VolType)); 357 358 sc->aac_container_count++; 359 sc->aac_hdr[i].hd_present = 1; 360 sc->aac_hdr[i].hd_size = mir->MntTable[0].Capacity; 361 362 /* 363 * Evaluate mapping (sectors per head, heads per cyl) 364 */ 365 sc->aac_hdr[i].hd_size &= ~AAC_SECS32; 366 aac_eval_mapping(sc->aac_hdr[i].hd_size, &drv_cyls, 367 &drv_hds, &drv_secs); 368 sc->aac_hdr[i].hd_heads = drv_hds; 369 sc->aac_hdr[i].hd_secs = drv_secs; 370 /* Round the size */ 371 sc->aac_hdr[i].hd_size = drv_cyls * drv_hds * drv_secs; 372 373 sc->aac_hdr[i].hd_devtype = mir->MntTable[0].VolType; 374 375 /* XXX Save the name too for use in IDENTIFY later */ 376 } 377 #endif 378 379 i++; 380 } while ((i < count) && (i < AAC_MAX_CONTAINERS)); 381 382 aac_release_sync_fib(sc); 383 384 #if 0 385 /* poke the bus to actually attach the child devices */ 386 if (bus_generic_attach(sc->aac_dev)) 387 printf("%s: bus_generic_attach failed\n", 388 sc->aac_dev.dv_xname); 389 #endif 390 391 392 /* mark the controller up */ 393 sc->aac_state &= ~AAC_STATE_SUSPEND; 394 395 /* enable interrupts now */ 396 AAC_UNMASK_INTERRUPTS(sc); 397 } 398 399 #if 0 400 /* 401 * Create a device to respresent a new container 402 */ 403 void 404 aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f) 405 { 406 struct aac_container *co; 407 device_t child; 408 409 /* 410 * Check container volume type for validity. Note that many of 411 * the possible types may never show up. 412 */ 413 if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) { 414 co = (struct aac_container *)malloc(sizeof *co, M_DEVBUF, 415 M_NOWAIT); 416 if (co == NULL) 417 panic("Out of memory?!"); 418 bzero(co, sizeof *co); 419 AAC_DPRINTF(AAC_D_MISC, 420 ("%s: id %x name '%.16s' size %u type %d\n", 421 sc->aac_dev.dv_xname, 422 mir->MntTable[0].ObjectId, 423 mir->MntTable[0].FileSystemName, 424 mir->MntTable[0].Capacity, 425 mir->MntTable[0].VolType); 426 427 if ((child = device_add_child(sc->aac_dev, "aacd", -1)) == NULL) 428 printf("%s: device_add_child failed\n", 429 sc->aac_dev.dv_xname); 430 else 431 device_set_ivars(child, co); 432 device_set_desc(child, aac_describe_code(aac_container_types, 433 mir->MntTable[0].VolType)); 434 co->co_disk = child; 435 co->co_found = f; 436 bcopy(&mir->MntTable[0], &co->co_mntobj, 437 sizeof(struct aac_mntobj)); 438 AAC_LOCK_ACQUIRE(&sc->aac_container_lock); 439 TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link); 440 AAC_LOCK_RELEASE(&sc->aac_container_lock); 441 } 442 } 443 #endif 444 445 #if 0 446 /* 447 * Free all of the resources associated with (sc) 448 * 449 * Should not be called if the controller is active. 450 */ 451 void 452 aac_free(struct aac_softc *sc) 453 { 454 455 debug_called(1); 456 457 /* remove the control device */ 458 if (sc->aac_dev_t != NULL) 459 destroy_dev(sc->aac_dev_t); 460 461 /* throw away any FIB buffers, discard the FIB DMA tag */ 462 aac_free_commands(sc); 463 if (sc->aac_fib_dmat) 464 bus_dma_tag_destroy(sc->aac_fib_dmat); 465 466 free(sc->aac_commands, M_AACBUF); 467 468 /* destroy the common area */ 469 if (sc->aac_common) { 470 bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap); 471 bus_dmamem_free(sc->aac_common_dmat, sc->aac_common, 472 sc->aac_common_dmamap); 473 } 474 if (sc->aac_common_dmat) 475 bus_dma_tag_destroy(sc->aac_common_dmat); 476 477 /* disconnect the interrupt handler */ 478 if (sc->aac_intr) 479 bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr); 480 if (sc->aac_irq != NULL) 481 bus_release_resource(sc->aac_dev, SYS_RES_IRQ, sc->aac_irq_rid, 482 sc->aac_irq); 483 484 /* destroy data-transfer DMA tag */ 485 if (sc->aac_buffer_dmat) 486 bus_dma_tag_destroy(sc->aac_buffer_dmat); 487 488 /* destroy the parent DMA tag */ 489 if (sc->aac_parent_dmat) 490 bus_dma_tag_destroy(sc->aac_parent_dmat); 491 492 /* release the register window mapping */ 493 if (sc->aac_regs_resource != NULL) 494 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY, 495 sc->aac_regs_rid, sc->aac_regs_resource); 496 } 497 498 /* 499 * Disconnect from the controller completely, in preparation for unload. 500 */ 501 int 502 aac_detach(device_t dev) 503 { 504 struct aac_softc *sc; 505 struct aac_container *co; 506 struct aac_sim *sim; 507 int error; 508 509 debug_called(1); 510 511 sc = device_get_softc(dev); 512 513 if (sc->aac_state & AAC_STATE_OPEN) 514 return(EBUSY); 515 516 /* Remove the child containers */ 517 while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) { 518 error = device_delete_child(dev, co->co_disk); 519 if (error) 520 return (error); 521 TAILQ_REMOVE(&sc->aac_container_tqh, co, co_link); 522 free(co, M_AACBUF); 523 } 524 525 /* Remove the CAM SIMs */ 526 while ((sim = TAILQ_FIRST(&sc->aac_sim_tqh)) != NULL) { 527 TAILQ_REMOVE(&sc->aac_sim_tqh, sim, sim_link); 528 error = device_delete_child(dev, sim->sim_dev); 529 if (error) 530 return (error); 531 free(sim, M_AACBUF); 532 } 533 534 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) { 535 sc->aifflags |= AAC_AIFFLAGS_EXIT; 536 wakeup(sc->aifthread); 537 tsleep(sc->aac_dev, PUSER | PCATCH, "aacdch", 30 * hz); 538 } 539 540 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) 541 panic("Cannot shutdown AIF thread"); 542 543 if ((error = aac_shutdown(dev))) 544 return(error); 545 546 EVENTHANDLER_DEREGISTER(shutdown_final, sc->eh); 547 548 aac_free(sc); 549 550 return(0); 551 } 552 553 /* 554 * Bring the controller down to a dormant state and detach all child devices. 555 * 556 * This function is called before detach or system shutdown. 557 * 558 * Note that we can assume that the bioq on the controller is empty, as we won't 559 * allow shutdown if any device is open. 560 */ 561 int 562 aac_shutdown(device_t dev) 563 { 564 struct aac_softc *sc; 565 struct aac_fib *fib; 566 struct aac_close_command *cc; 567 568 debug_called(1); 569 570 sc = device_get_softc(dev); 571 572 sc->aac_state |= AAC_STATE_SUSPEND; 573 574 /* 575 * Send a Container shutdown followed by a HostShutdown FIB to the 576 * controller to convince it that we don't want to talk to it anymore. 577 * We've been closed and all I/O completed already 578 */ 579 device_printf(sc->aac_dev, "shutting down controller..."); 580 581 aac_alloc_sync_fib(sc, &fib, AAC_SYNC_LOCK_FORCE); 582 cc = (struct aac_close_command *)&fib->data[0]; 583 584 bzero(cc, sizeof(struct aac_close_command)); 585 cc->Command = VM_CloseAll; 586 cc->ContainerId = 0xffffffff; 587 if (aac_sync_fib(sc, ContainerCommand, 0, fib, 588 sizeof(struct aac_close_command))) 589 printf("FAILED.\n"); 590 else 591 printf("done\n"); 592 else { 593 fib->data[0] = 0; 594 /* 595 * XXX Issuing this command to the controller makes it 596 * shut down but also keeps it from coming back up 597 * without a reset of the PCI bus. This is not 598 * desirable if you are just unloading the driver 599 * module with the intent to reload it later. 600 */ 601 if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN, 602 fib, 1)) { 603 printf("FAILED.\n"); 604 } else { 605 printf("done.\n"); 606 } 607 } 608 609 AAC_MASK_INTERRUPTS(sc); 610 611 return(0); 612 } 613 614 /* 615 * Bring the controller to a quiescent state, ready for system suspend. 616 */ 617 int 618 aac_suspend(device_t dev) 619 { 620 struct aac_softc *sc; 621 622 debug_called(1); 623 624 sc = device_get_softc(dev); 625 626 sc->aac_state |= AAC_STATE_SUSPEND; 627 628 AAC_MASK_INTERRUPTS(sc); 629 return(0); 630 } 631 632 /* 633 * Bring the controller back to a state ready for operation. 634 */ 635 int 636 aac_resume(device_t dev) 637 { 638 struct aac_softc *sc; 639 640 debug_called(1); 641 642 sc = device_get_softc(dev); 643 644 sc->aac_state &= ~AAC_STATE_SUSPEND; 645 AAC_UNMASK_INTERRUPTS(sc); 646 return(0); 647 } 648 #endif 649 650 /* 651 * Take an interrupt. 652 */ 653 int 654 aac_intr(void *arg) 655 { 656 struct aac_softc *sc = arg; 657 u_int16_t reason; 658 659 660 /* 661 * Read the status register directly. This is faster than taking the 662 * driver lock and reading the queues directly. It also saves having 663 * to turn parts of the driver lock into a spin mutex, which would be 664 * ugly. 665 */ 666 reason = AAC_GET_ISTATUS(sc); 667 AAC_CLEAR_ISTATUS(sc, reason); 668 (void)AAC_GET_ISTATUS(sc); 669 670 if (reason == 0) 671 return (0); 672 673 AAC_DPRINTF(AAC_D_INTR, ("%s: intr: sc=%p: reason=%#x\n", 674 sc->aac_dev.dv_xname, sc, reason)); 675 676 /* controller wants to talk to us */ 677 if (reason & (AAC_DB_PRINTF | AAC_DB_COMMAND_READY | 678 AAC_DB_RESPONSE_READY)) { 679 680 if (reason & AAC_DB_RESPONSE_READY) { 681 /* handle completion processing */ 682 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) { 683 sc->aifflags |= AAC_AIFFLAGS_COMPLETE; 684 } else { 685 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 686 aac_complete(sc); 687 AAC_LOCK_RELEASE(&sc->aac_io_lock); 688 } 689 } 690 691 692 /* 693 * XXX Make sure that we don't get fooled by strange messages 694 * that start with a NULL. 695 */ 696 if (reason & AAC_DB_PRINTF) 697 if (sc->aac_common->ac_printf[0] == 0) 698 sc->aac_common->ac_printf[0] = 32; 699 700 /* 701 * This might miss doing the actual wakeup. However, the 702 * msleep that this is waking up has a timeout, so it will 703 * wake up eventually. AIFs and printfs are low enough 704 * priority that they can handle hanging out for a few seconds 705 * if needed. 706 */ 707 if (sc->aifthread) 708 wakeup(sc->aifthread); 709 710 } 711 712 return (1); 713 } 714 715 /* 716 * Command Processing 717 */ 718 719 /* 720 * Start as much queued I/O as possible on the controller 721 */ 722 void 723 aac_startio(struct aac_softc *sc) 724 { 725 struct aac_command *cm; 726 727 AAC_DPRINTF(AAC_D_CMD, ("%s: start command", sc->aac_dev.dv_xname)); 728 729 if (sc->flags & AAC_QUEUE_FRZN) { 730 AAC_DPRINTF(AAC_D_CMD, (": queue frozen")); 731 return; 732 } 733 734 AAC_DPRINTF(AAC_D_CMD, ("\n")); 735 736 for (;;) { 737 /* 738 * Try to get a command that's been put off for lack of 739 * resources 740 */ 741 cm = aac_dequeue_ready(sc); 742 743 /* 744 * Try to build a command off the bio queue (ignore error 745 * return) 746 */ 747 if (cm == NULL) { 748 AAC_DPRINTF(AAC_D_CMD, ("\n")); 749 aac_bio_command(sc, &cm); 750 AAC_DPRINTF(AAC_D_CMD, ("%s: start done bio", 751 sc->aac_dev.dv_xname)); 752 } 753 754 /* nothing to do? */ 755 if (cm == NULL) 756 break; 757 758 /* 759 * Try to give the command to the controller. Any error is 760 * catastrophic since it means that bus_dmamap_load() failed. 761 */ 762 if (aac_map_command(cm) != 0) 763 panic("aac: error mapping command %p", cm); 764 765 AAC_DPRINTF(AAC_D_CMD, ("\n%s: another command", 766 sc->aac_dev.dv_xname)); 767 } 768 769 AAC_DPRINTF(AAC_D_CMD, ("\n")); 770 } 771 772 /* 773 * Deliver a command to the controller; allocate controller resources at the 774 * last moment when possible. 775 */ 776 int 777 aac_map_command(struct aac_command *cm) 778 { 779 struct aac_softc *sc = cm->cm_sc; 780 int error = 0; 781 782 AAC_DPRINTF(AAC_D_CMD, (": map command")); 783 784 /* don't map more than once */ 785 if (cm->cm_flags & AAC_CMD_MAPPED) 786 panic("aac: command %p already mapped", cm); 787 788 if (cm->cm_datalen != 0) { 789 error = bus_dmamap_load(sc->aac_dmat, cm->cm_datamap, 790 cm->cm_data, cm->cm_datalen, NULL, 791 BUS_DMA_NOWAIT); 792 if (error) 793 return (error); 794 795 aac_map_command_sg(cm, cm->cm_datamap->dm_segs, 796 cm->cm_datamap->dm_nsegs, 0); 797 } else { 798 aac_map_command_sg(cm, NULL, 0, 0); 799 } 800 801 return (error); 802 } 803 804 /* 805 * Handle notification of one or more FIBs coming from the controller. 806 */ 807 void 808 aac_command_thread(void *arg) 809 { 810 struct aac_softc *sc = arg; 811 struct aac_fib *fib; 812 u_int32_t fib_size; 813 int size, retval; 814 815 AAC_DPRINTF(AAC_D_THREAD, ("%s: aac_command_thread: starting\n", 816 sc->aac_dev.dv_xname)); 817 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 818 sc->aifflags = AAC_AIFFLAGS_RUNNING; 819 820 while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) { 821 822 AAC_DPRINTF(AAC_D_THREAD, 823 ("%s: aac_command_thread: aifflags=%#x\n", 824 sc->aac_dev.dv_xname, sc->aifflags)); 825 retval = 0; 826 827 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0) { 828 AAC_DPRINTF(AAC_D_THREAD, 829 ("%s: command thread sleeping\n", 830 sc->aac_dev.dv_xname)); 831 AAC_LOCK_RELEASE(&sc->aac_io_lock); 832 retval = tsleep(sc->aifthread, PRIBIO, "aifthd", 833 AAC_PERIODIC_INTERVAL * hz); 834 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 835 } 836 837 if ((sc->aifflags & AAC_AIFFLAGS_COMPLETE) != 0) { 838 aac_complete(sc); 839 sc->aifflags &= ~AAC_AIFFLAGS_COMPLETE; 840 } 841 842 /* 843 * While we're here, check to see if any commands are stuck. 844 * This is pretty low-priority, so it's ok if it doesn't 845 * always fire. 846 */ 847 if (retval == EWOULDBLOCK) 848 aac_timeout(sc); 849 850 /* Check the hardware printf message buffer */ 851 if (sc->aac_common->ac_printf[0] != 0) 852 aac_print_printf(sc); 853 854 /* Also check to see if the adapter has a command for us. */ 855 while (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, 856 &fib_size, &fib) == 0) { 857 858 AAC_PRINT_FIB(sc, fib); 859 860 switch (fib->Header.Command) { 861 case AifRequest: 862 //aac_handle_aif(sc, fib); 863 break; 864 default: 865 printf("%s: unknown command from controller\n", 866 sc->aac_dev.dv_xname); 867 break; 868 } 869 870 if ((fib->Header.XferState == 0) || 871 (fib->Header.StructType != AAC_FIBTYPE_TFIB)) 872 break; 873 874 /* Return the AIF to the controller. */ 875 if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) { 876 fib->Header.XferState |= AAC_FIBSTATE_DONEHOST; 877 *(AAC_FSAStatus*)fib->data = ST_OK; 878 879 /* XXX Compute the Size field? */ 880 size = fib->Header.Size; 881 if (size > sizeof(struct aac_fib)) { 882 size = sizeof(struct aac_fib); 883 fib->Header.Size = size; 884 } 885 886 /* 887 * Since we did not generate this command, it 888 * cannot go through the normal 889 * enqueue->startio chain. 890 */ 891 aac_enqueue_response(sc, 892 AAC_ADAP_NORM_RESP_QUEUE, 893 fib); 894 } 895 } 896 } 897 sc->aifflags &= ~AAC_AIFFLAGS_RUNNING; 898 AAC_LOCK_RELEASE(&sc->aac_io_lock); 899 900 #if 0 901 /* 902 * if we ever implement detach, we should have detach tsleep 903 * to wait for this thread to finish 904 */ 905 wakeup(sc->aac_dev); 906 #endif 907 908 AAC_DPRINTF(AAC_D_THREAD, ("%s: aac_command_thread: exiting\n", 909 sc->aac_dev.dv_xname)); 910 kthread_exit(0); 911 } 912 913 /* 914 * Process completed commands. 915 */ 916 void 917 aac_complete(void *context) 918 { 919 struct aac_softc *sc = (struct aac_softc *)context; 920 struct aac_command *cm; 921 struct aac_fib *fib; 922 u_int32_t fib_size; 923 924 AAC_DPRINTF(AAC_D_CMD, ("%s: complete", sc->aac_dev.dv_xname)); 925 926 /* pull completed commands off the queue */ 927 for (;;) { 928 /* look for completed FIBs on our queue */ 929 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size, 930 &fib)) 931 break; /* nothing to do */ 932 933 /* get the command, unmap and hand off for processing */ 934 cm = sc->aac_commands + fib->Header.SenderData; 935 if (cm == NULL) { 936 AAC_PRINT_FIB(sc, fib); 937 break; 938 } 939 940 aac_remove_busy(cm); 941 aac_unmap_command(cm); 942 cm->cm_flags |= AAC_CMD_COMPLETED; 943 944 /* is there a completion handler? */ 945 if (cm->cm_complete != NULL) { 946 cm->cm_complete(cm); 947 } else { 948 /* assume that someone is sleeping on this command */ 949 wakeup(cm); 950 } 951 } 952 953 AAC_DPRINTF(AAC_D_CMD, ("\n")); 954 /* see if we can start some more I/O */ 955 sc->flags &= ~AAC_QUEUE_FRZN; 956 aac_startio(sc); 957 } 958 959 /* 960 * Get a bio and build a command to go with it. 961 */ 962 int 963 aac_bio_command(struct aac_softc *sc, struct aac_command **cmp) 964 { 965 struct aac_command *cm; 966 struct aac_fib *fib; 967 struct scsi_xfer *xs; 968 u_int8_t opcode = 0; 969 970 AAC_DPRINTF(AAC_D_CMD, ("%s: bio command", sc->aac_dev.dv_xname)); 971 972 /* get the resources we will need */ 973 if ((cm = aac_dequeue_bio(sc)) == NULL) 974 goto fail; 975 xs = cm->cm_private; 976 977 /* build the FIB */ 978 fib = cm->cm_fib; 979 fib->Header.Size = sizeof(struct aac_fib_header); 980 fib->Header.XferState = 981 AAC_FIBSTATE_HOSTOWNED | 982 AAC_FIBSTATE_INITIALISED | 983 AAC_FIBSTATE_EMPTY | 984 AAC_FIBSTATE_FROMHOST | 985 AAC_FIBSTATE_REXPECTED | 986 AAC_FIBSTATE_NORM | 987 AAC_FIBSTATE_ASYNC | 988 AAC_FIBSTATE_FAST_RESPONSE; 989 990 switch(xs->cmd->opcode) { 991 case READ_COMMAND: 992 case READ_BIG: 993 opcode = READ_COMMAND; 994 break; 995 case WRITE_COMMAND: 996 case WRITE_BIG: 997 opcode = WRITE_COMMAND; 998 break; 999 default: 1000 panic("%s: invalid opcode %#x", sc->aac_dev.dv_xname, 1001 xs->cmd->opcode); 1002 } 1003 1004 /* build the read/write request */ 1005 if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) { 1006 fib->Header.Command = ContainerCommand; 1007 if (opcode == READ_COMMAND) { 1008 struct aac_blockread *br; 1009 br = (struct aac_blockread *)&fib->data[0]; 1010 br->Command = VM_CtBlockRead; 1011 br->ContainerId = xs->sc_link->target; 1012 br->BlockNumber = cm->cm_blkno; 1013 br->ByteCount = cm->cm_bcount * AAC_BLOCK_SIZE; 1014 fib->Header.Size += sizeof(struct aac_blockread); 1015 cm->cm_sgtable = &br->SgMap; 1016 cm->cm_flags |= AAC_CMD_DATAIN; 1017 } else { 1018 struct aac_blockwrite *bw; 1019 bw = (struct aac_blockwrite *)&fib->data[0]; 1020 bw->Command = VM_CtBlockWrite; 1021 bw->ContainerId = xs->sc_link->target; 1022 bw->BlockNumber = cm->cm_blkno; 1023 bw->ByteCount = cm->cm_bcount * AAC_BLOCK_SIZE; 1024 bw->Stable = CUNSTABLE; 1025 fib->Header.Size += sizeof(struct aac_blockwrite); 1026 cm->cm_flags |= AAC_CMD_DATAOUT; 1027 cm->cm_sgtable = &bw->SgMap; 1028 } 1029 } else { 1030 fib->Header.Command = ContainerCommand64; 1031 if (opcode == READ_COMMAND) { 1032 struct aac_blockread64 *br; 1033 br = (struct aac_blockread64 *)&fib->data[0]; 1034 br->Command = VM_CtHostRead64; 1035 br->ContainerId = xs->sc_link->target; 1036 br->BlockNumber = cm->cm_blkno; 1037 br->SectorCount = cm->cm_bcount; 1038 br->Pad = 0; 1039 br->Flags = 0; 1040 fib->Header.Size += sizeof(struct aac_blockread64); 1041 cm->cm_flags |= AAC_CMD_DATAOUT; 1042 cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64; 1043 } else { 1044 struct aac_blockwrite64 *bw; 1045 bw = (struct aac_blockwrite64 *)&fib->data[0]; 1046 bw->Command = VM_CtHostWrite64; 1047 bw->ContainerId = xs->sc_link->target; 1048 bw->BlockNumber = cm->cm_blkno; 1049 bw->SectorCount = cm->cm_bcount; 1050 bw->Pad = 0; 1051 bw->Flags = 0; 1052 fib->Header.Size += sizeof(struct aac_blockwrite64); 1053 cm->cm_flags |= AAC_CMD_DATAIN; 1054 cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64; 1055 } 1056 } 1057 1058 *cmp = cm; 1059 AAC_DPRINTF(AAC_D_CMD, ("\n")); 1060 return(0); 1061 1062 fail: 1063 AAC_DPRINTF(AAC_D_CMD, ("\n")); 1064 return(ENOMEM); 1065 } 1066 1067 /* 1068 * Handle a bio-instigated command that has been completed. 1069 */ 1070 void 1071 aac_bio_complete(struct aac_command *cm) 1072 { 1073 struct aac_blockread_response *brr; 1074 struct aac_blockwrite_response *bwr; 1075 struct scsi_xfer *xs = (struct scsi_xfer *)cm->cm_private; 1076 AAC_FSAStatus status; 1077 int s; 1078 1079 AAC_DPRINTF(AAC_D_CMD, 1080 ("%s: bio complete\n", cm->cm_sc->aac_dev.dv_xname)); 1081 1082 /* fetch relevant status and then release the command */ 1083 if (xs->flags & SCSI_DATA_IN) { 1084 brr = (struct aac_blockread_response *)&cm->cm_fib->data[0]; 1085 status = brr->Status; 1086 } else { 1087 bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0]; 1088 status = bwr->Status; 1089 } 1090 1091 s = splbio(); 1092 aac_release_command(cm); 1093 1094 xs->error = status == ST_OK? XS_NOERROR : XS_DRIVER_STUFFUP; 1095 xs->resid = 0; 1096 scsi_done(xs); 1097 splx(s); 1098 } 1099 1100 /* 1101 * Submit a command to the controller, return when it completes. 1102 * XXX This is very dangerous! If the card has gone out to lunch, we could 1103 * be stuck here forever. At the same time, signals are not caught 1104 * because there is a risk that a signal could wakeup the tsleep before 1105 * the card has a chance to complete the command. The passed in timeout 1106 * is ignored for the same reason. Since there is no way to cancel a 1107 * command in progress, we should probably create a 'dead' queue where 1108 * commands go that have been interrupted/timed-out/etc, that keeps them 1109 * out of the free pool. That way, if the card is just slow, it won't 1110 * spam the memory of a command that has been recycled. 1111 */ 1112 int 1113 aac_wait_command(struct aac_command *cm, int timeout) 1114 { 1115 struct aac_softc *sc = cm->cm_sc; 1116 int error = 0; 1117 1118 AAC_DPRINTF(AAC_D_CMD, (": wait for command")); 1119 1120 /* Put the command on the ready queue and get things going */ 1121 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; 1122 aac_enqueue_ready(cm); 1123 AAC_DPRINTF(AAC_D_CMD, ("\n")); 1124 aac_startio(sc); 1125 while (!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) { 1126 AAC_DPRINTF(AAC_D_MISC, ("%s: sleeping until command done\n", 1127 sc->aac_dev.dv_xname)); 1128 AAC_LOCK_RELEASE(&sc->aac_io_lock); 1129 error = tsleep(cm, PRIBIO, "aacwait", timeout); 1130 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 1131 } 1132 return (error); 1133 } 1134 1135 /* 1136 *Command Buffer Management 1137 */ 1138 1139 /* 1140 * Allocate a command. 1141 */ 1142 int 1143 aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp) 1144 { 1145 struct aac_command *cm; 1146 1147 AAC_DPRINTF(AAC_D_CMD, (": allocate command")); 1148 if ((cm = aac_dequeue_free(sc)) == NULL) { 1149 AAC_DPRINTF(AAC_D_CMD, (" failed")); 1150 return (EBUSY); 1151 } 1152 1153 *cmp = cm; 1154 return(0); 1155 } 1156 1157 /* 1158 * Release a command back to the freelist. 1159 */ 1160 void 1161 aac_release_command(struct aac_command *cm) 1162 { 1163 AAC_DPRINTF(AAC_D_CMD, (": release command")); 1164 1165 /* (re)initialise the command/FIB */ 1166 cm->cm_sgtable = NULL; 1167 cm->cm_flags = 0; 1168 cm->cm_complete = NULL; 1169 cm->cm_private = NULL; 1170 cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY; 1171 cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB; 1172 cm->cm_fib->Header.Flags = 0; 1173 cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib); 1174 1175 /* 1176 * These are duplicated in aac_start to cover the case where an 1177 * intermediate stage may have destroyed them. They're left 1178 * initialised here for debugging purposes only. 1179 */ 1180 cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys; 1181 cm->cm_fib->Header.SenderData = 0; 1182 1183 aac_enqueue_free(cm); 1184 } 1185 1186 /* 1187 * Allocate and initialise commands/FIBs for this adapter. 1188 */ 1189 int 1190 aac_alloc_commands(struct aac_softc *sc) 1191 { 1192 struct aac_command *cm; 1193 struct aac_fibmap *fm; 1194 int i, error; 1195 1196 if (sc->total_fibs + AAC_FIB_COUNT > sc->aac_max_fibs) 1197 return (ENOMEM); 1198 1199 fm = malloc(sizeof(*fm), M_DEVBUF, M_NOWAIT | M_ZERO); 1200 if (fm == NULL) 1201 goto exit; 1202 1203 /* allocate the FIBs in DMAable memory and load them */ 1204 if (bus_dmamem_alloc(sc->aac_dmat, AAC_FIBMAP_SIZE, PAGE_SIZE, 0, 1205 &fm->aac_seg, 1, &fm->aac_nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)) { 1206 printf("%s: can't alloc FIBs\n", sc->aac_dev.dv_xname); 1207 error = ENOBUFS; 1208 goto exit_alloc; 1209 } 1210 1211 if (bus_dmamem_map(sc->aac_dmat, &fm->aac_seg, 1, 1212 AAC_FIBMAP_SIZE, (caddr_t *)&fm->aac_fibs, BUS_DMA_NOWAIT)) { 1213 printf("%s: can't map FIB structure\n", sc->aac_dev.dv_xname); 1214 error = ENOBUFS; 1215 goto exit_map; 1216 } 1217 1218 if (bus_dmamap_create(sc->aac_dmat, AAC_FIBMAP_SIZE, 1, 1219 AAC_FIBMAP_SIZE, 0, BUS_DMA_NOWAIT, &fm->aac_fibmap)) { 1220 printf("%s: can't create dma map\n", sc->aac_dev.dv_xname); 1221 error = ENOBUFS; 1222 goto exit_create; 1223 } 1224 1225 if (bus_dmamap_load(sc->aac_dmat, fm->aac_fibmap, fm->aac_fibs, 1226 AAC_FIBMAP_SIZE, NULL, BUS_DMA_NOWAIT)) { 1227 printf("%s: can't load dma map\n", sc->aac_dev.dv_xname); 1228 error = ENOBUFS; 1229 goto exit_load; 1230 } 1231 1232 /* initialise constant fields in the command structure */ 1233 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 1234 for (i = 0; i < AAC_FIB_COUNT; i++) { 1235 cm = sc->aac_commands + sc->total_fibs; 1236 fm->aac_commands = cm; 1237 cm->cm_sc = sc; 1238 cm->cm_fib = fm->aac_fibs + i; 1239 cm->cm_fibphys = fm->aac_fibmap->dm_segs[0].ds_addr + 1240 (i * sizeof(struct aac_fib)); 1241 cm->cm_index = sc->total_fibs; 1242 1243 if (bus_dmamap_create(sc->aac_dmat, MAXBSIZE, AAC_MAXSGENTRIES, 1244 MAXBSIZE, 0, BUS_DMA_NOWAIT, &cm->cm_datamap)) { 1245 break; 1246 } 1247 aac_release_command(cm); 1248 sc->total_fibs++; 1249 } 1250 1251 if (i > 0) { 1252 TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link); 1253 AAC_DPRINTF(AAC_D_MISC, ("%s: total_fibs= %d\n", 1254 sc->aac_dev.dv_xname, 1255 sc->total_fibs)); 1256 AAC_LOCK_RELEASE(&sc->aac_io_lock); 1257 return (0); 1258 } 1259 1260 exit_load: 1261 bus_dmamap_destroy(sc->aac_dmat, fm->aac_fibmap); 1262 exit_create: 1263 bus_dmamem_unmap(sc->aac_dmat, (caddr_t)fm->aac_fibs, AAC_FIBMAP_SIZE); 1264 exit_map: 1265 bus_dmamem_free(sc->aac_dmat, &fm->aac_seg, fm->aac_nsegs); 1266 exit_alloc: 1267 free(fm, M_DEVBUF); 1268 exit: 1269 AAC_LOCK_RELEASE(&sc->aac_io_lock); 1270 return (error); 1271 } 1272 1273 /* 1274 * Free FIBs owned by this adapter. 1275 */ 1276 void 1277 aac_free_commands(struct aac_softc *sc) 1278 { 1279 struct aac_fibmap *fm; 1280 struct aac_command *cm; 1281 int i; 1282 1283 while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) { 1284 1285 TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link); 1286 1287 /* 1288 * We check against total_fibs to handle partially 1289 * allocated blocks. 1290 */ 1291 for (i = 0; i < AAC_FIB_COUNT && sc->total_fibs--; i++) { 1292 cm = fm->aac_commands + i; 1293 bus_dmamap_destroy(sc->aac_dmat, cm->cm_datamap); 1294 } 1295 1296 bus_dmamap_unload(sc->aac_dmat, fm->aac_fibmap); 1297 bus_dmamap_destroy(sc->aac_dmat, fm->aac_fibmap); 1298 bus_dmamem_unmap(sc->aac_dmat, (caddr_t)fm->aac_fibs, 1299 AAC_FIBMAP_SIZE); 1300 bus_dmamem_free(sc->aac_dmat, &fm->aac_seg, fm->aac_nsegs); 1301 free(fm, M_DEVBUF); 1302 } 1303 } 1304 1305 1306 /* 1307 * Command-mapping helper function - populate this command's s/g table. 1308 */ 1309 void 1310 aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1311 { 1312 struct aac_command *cm = arg; 1313 struct aac_softc *sc = cm->cm_sc; 1314 struct aac_fib *fib = cm->cm_fib; 1315 int i; 1316 1317 /* copy into the FIB */ 1318 if (cm->cm_sgtable != NULL) { 1319 if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) { 1320 struct aac_sg_table *sg = cm->cm_sgtable; 1321 sg->SgCount = nseg; 1322 for (i = 0; i < nseg; i++) { 1323 sg->SgEntry[i].SgAddress = segs[i].ds_addr; 1324 sg->SgEntry[i].SgByteCount = segs[i].ds_len; 1325 } 1326 /* update the FIB size for the s/g count */ 1327 fib->Header.Size += nseg * sizeof(struct aac_sg_entry); 1328 } else { 1329 struct aac_sg_table64 *sg; 1330 sg = (struct aac_sg_table64 *)cm->cm_sgtable; 1331 sg->SgCount = nseg; 1332 for (i = 0; i < nseg; i++) { 1333 sg->SgEntry64[i].SgAddress = segs[i].ds_addr; 1334 sg->SgEntry64[i].SgByteCount = segs[i].ds_len; 1335 } 1336 /* update the FIB size for the s/g count */ 1337 fib->Header.Size += nseg*sizeof(struct aac_sg_entry64); 1338 } 1339 } 1340 1341 /* Fix up the address values in the FIB. Use the command array index 1342 * instead of a pointer since these fields are only 32 bits. Shift 1343 * the SenderFibAddress over to make room for the fast response bit. 1344 */ 1345 cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 1); 1346 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys; 1347 1348 /* save a pointer to the command for speedy reverse-lookup */ 1349 cm->cm_fib->Header.SenderData = cm->cm_index; 1350 1351 if (cm->cm_flags & AAC_CMD_DATAIN) 1352 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0, 1353 cm->cm_datamap->dm_mapsize, 1354 BUS_DMASYNC_PREREAD); 1355 if (cm->cm_flags & AAC_CMD_DATAOUT) 1356 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0, 1357 cm->cm_datamap->dm_mapsize, 1358 BUS_DMASYNC_PREWRITE); 1359 cm->cm_flags |= AAC_CMD_MAPPED; 1360 1361 /* put the FIB on the outbound queue */ 1362 if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) { 1363 aac_remove_busy(cm); 1364 aac_unmap_command(cm); 1365 aac_requeue_ready(cm); 1366 } 1367 } 1368 1369 /* 1370 * Unmap a command from controller-visible space. 1371 */ 1372 void 1373 aac_unmap_command(struct aac_command *cm) 1374 { 1375 struct aac_softc *sc = cm->cm_sc; 1376 1377 if (!(cm->cm_flags & AAC_CMD_MAPPED)) 1378 return; 1379 1380 if (cm->cm_datalen != 0) { 1381 if (cm->cm_flags & AAC_CMD_DATAIN) 1382 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0, 1383 cm->cm_datamap->dm_mapsize, 1384 BUS_DMASYNC_POSTREAD); 1385 if (cm->cm_flags & AAC_CMD_DATAOUT) 1386 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0, 1387 cm->cm_datamap->dm_mapsize, 1388 BUS_DMASYNC_POSTWRITE); 1389 1390 bus_dmamap_unload(sc->aac_dmat, cm->cm_datamap); 1391 } 1392 cm->cm_flags &= ~AAC_CMD_MAPPED; 1393 } 1394 1395 /* 1396 * Hardware Interface 1397 */ 1398 1399 /* 1400 * Initialise the adapter. 1401 */ 1402 int 1403 aac_check_firmware(struct aac_softc *sc) 1404 { 1405 u_int32_t major, minor, options; 1406 1407 /* 1408 * Retrieve the firmware version numbers. Dell PERC2/QC cards with 1409 * firmware version 1.x are not compatible with this driver. 1410 */ 1411 if (sc->flags & AAC_FLAGS_PERC2QC) { 1412 if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0, 1413 NULL)) { 1414 printf("%s: Error reading firmware version\n", 1415 sc->aac_dev.dv_xname); 1416 return (EIO); 1417 } 1418 1419 /* These numbers are stored as ASCII! */ 1420 major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30; 1421 minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30; 1422 if (major == 1) { 1423 printf("%s: Firmware version %d.%d is not supported\n", 1424 sc->aac_dev.dv_xname, major, minor); 1425 return (EINVAL); 1426 } 1427 } 1428 1429 /* 1430 * Retrieve the capabilities/supported options word so we know what 1431 * work-arounds to enable. 1432 */ 1433 if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, NULL)) { 1434 printf("%s: RequestAdapterInfo failed\n", 1435 sc->aac_dev.dv_xname); 1436 return (EIO); 1437 } 1438 options = AAC_GET_MAILBOX(sc, 1); 1439 sc->supported_options = options; 1440 1441 if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 && 1442 (sc->flags & AAC_FLAGS_NO4GB) == 0) 1443 sc->flags |= AAC_FLAGS_4GB_WINDOW; 1444 if (options & AAC_SUPPORTED_NONDASD) 1445 sc->flags |= AAC_FLAGS_ENABLE_CAM; 1446 if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0 1447 && (sizeof(bus_addr_t) > 4)) { 1448 printf("%s: Enabling 64-bit address support\n", 1449 sc->aac_dev.dv_xname); 1450 sc->flags |= AAC_FLAGS_SG_64BIT; 1451 } 1452 1453 /* Check for broken hardware that does a lower number of commands */ 1454 if ((sc->flags & AAC_FLAGS_256FIBS) == 0) 1455 sc->aac_max_fibs = AAC_MAX_FIBS; 1456 else 1457 sc->aac_max_fibs = 256; 1458 1459 return (0); 1460 } 1461 1462 int 1463 aac_init(struct aac_softc *sc) 1464 { 1465 bus_dma_segment_t seg; 1466 int nsegs; 1467 int i, error; 1468 int state = 0; 1469 struct aac_adapter_init *ip; 1470 time_t then; 1471 u_int32_t code, qoffset; 1472 1473 /* 1474 * First wait for the adapter to come ready. 1475 */ 1476 then = time_uptime; 1477 for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) { 1478 code = AAC_GET_FWSTATUS(sc); 1479 if (code & AAC_SELF_TEST_FAILED) { 1480 printf("%s: FATAL: selftest failed\n", 1481 sc->aac_dev.dv_xname); 1482 return (ENXIO); 1483 } 1484 if (code & AAC_KERNEL_PANIC) { 1485 printf("%s: FATAL: controller kernel panic\n", 1486 sc->aac_dev.dv_xname); 1487 return (ENXIO); 1488 } 1489 if (code & AAC_UP_AND_RUNNING) 1490 break; 1491 DELAY(1000); 1492 } 1493 if (i == AAC_BOOT_TIMEOUT * 1000) { 1494 printf("%s: FATAL: controller not coming ready, status %x\n", 1495 sc->aac_dev.dv_xname, code); 1496 return (ENXIO); 1497 } 1498 1499 /* 1500 * Work around a bug in the 2120 and 2200 that cannot DMA commands 1501 * below address 8192 in physical memory. 1502 * XXX If the padding is not needed, can it be put to use instead 1503 * of ignored? 1504 */ 1505 if (bus_dmamem_alloc(sc->aac_dmat, AAC_COMMON_ALLOCSIZE, PAGE_SIZE, 0, 1506 &seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)) { 1507 printf("%s: can't allocate common structure\n", 1508 sc->aac_dev.dv_xname); 1509 return (ENOMEM); 1510 } 1511 state++; 1512 1513 if (bus_dmamem_map(sc->aac_dmat, &seg, nsegs, AAC_COMMON_ALLOCSIZE, 1514 (caddr_t *)&sc->aac_common, BUS_DMA_NOWAIT)) { 1515 printf("%s: can't map common structure\n", 1516 sc->aac_dev.dv_xname); 1517 error = ENOMEM; 1518 goto bail_out; 1519 } 1520 state++; 1521 1522 if (bus_dmamap_create(sc->aac_dmat, AAC_COMMON_ALLOCSIZE, 1, 1523 AAC_COMMON_ALLOCSIZE, 0, BUS_DMA_NOWAIT, &sc->aac_common_map)) { 1524 printf("%s: can't create dma map\n", sc->aac_dev.dv_xname); 1525 error = ENOBUFS; 1526 goto bail_out; 1527 } 1528 state++; 1529 1530 if (bus_dmamap_load(sc->aac_dmat, sc->aac_common_map, sc->aac_common, 1531 AAC_COMMON_ALLOCSIZE, NULL, BUS_DMA_NOWAIT)) { 1532 printf("%s: can't load dma map\n", sc->aac_dev.dv_xname); 1533 error = ENOBUFS; 1534 goto bail_out; 1535 } 1536 state++; 1537 1538 sc->aac_common_busaddr = sc->aac_common_map->dm_segs[0].ds_addr; 1539 1540 if (sc->aac_common_busaddr < 8192) { 1541 sc->aac_common = (struct aac_common *) 1542 ((uint8_t *)sc->aac_common + 8192); 1543 sc->aac_common_busaddr += 8192; 1544 } 1545 1546 /* Allocate some FIBs and associated command structs */ 1547 TAILQ_INIT(&sc->aac_fibmap_tqh); 1548 sc->aac_commands = malloc(AAC_MAX_FIBS * sizeof(struct aac_command), 1549 M_DEVBUF, M_WAITOK | M_ZERO); 1550 while (sc->total_fibs < AAC_MAX_FIBS) { 1551 if (aac_alloc_commands(sc) != 0) 1552 break; 1553 } 1554 if (sc->total_fibs == 0) 1555 goto out; 1556 1557 /* 1558 * Fill in the init structure. This tells the adapter about the 1559 * physical location of various important shared data structures. 1560 */ 1561 ip = &sc->aac_common->ac_init; 1562 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION; 1563 ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION; 1564 1565 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr + 1566 offsetof(struct aac_common, ac_fibs); 1567 ip->AdapterFibsVirtualAddress = 0; 1568 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib); 1569 ip->AdapterFibAlign = sizeof(struct aac_fib); 1570 1571 ip->PrintfBufferAddress = sc->aac_common_busaddr + 1572 offsetof(struct aac_common, ac_printf); 1573 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE; 1574 1575 /* 1576 * The adapter assumes that pages are 4K in size, except on some 1577 * broken firmware versions that do the page->byte conversion twice, 1578 * therefore 'assuming' that this value is in 16MB units (2^24). 1579 * Round up since the granularity is so high. 1580 */ 1581 ip->HostPhysMemPages = ptoa(physmem) / AAC_PAGE_SIZE; 1582 if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) { 1583 ip->HostPhysMemPages = 1584 (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE; 1585 } 1586 ip->HostElapsedSeconds = time_uptime; /* reset later if invalid */ 1587 1588 /* 1589 * Initialise FIB queues. Note that it appears that the layout of the 1590 * indexes and the segmentation of the entries may be mandated by the 1591 * adapter, which is only told about the base of the queue index fields. 1592 * 1593 * The initial values of the indices are assumed to inform the adapter 1594 * of the sizes of the respective queues, and theoretically it could 1595 * work out the entire layout of the queue structures from this. We 1596 * take the easy route and just lay this area out like everyone else 1597 * does. 1598 * 1599 * The Linux driver uses a much more complex scheme whereby several 1600 * header records are kept for each queue. We use a couple of generic 1601 * list manipulation functions which 'know' the size of each list by 1602 * virtue of a table. 1603 */ 1604 qoffset = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN; 1605 qoffset &= ~(AAC_QUEUE_ALIGN - 1); 1606 sc->aac_queues = 1607 (struct aac_queue_table *)((caddr_t)sc->aac_common + qoffset); 1608 ip->CommHeaderAddress = sc->aac_common_busaddr + qoffset; 1609 1610 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1611 AAC_HOST_NORM_CMD_ENTRIES; 1612 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1613 AAC_HOST_NORM_CMD_ENTRIES; 1614 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1615 AAC_HOST_HIGH_CMD_ENTRIES; 1616 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1617 AAC_HOST_HIGH_CMD_ENTRIES; 1618 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1619 AAC_ADAP_NORM_CMD_ENTRIES; 1620 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1621 AAC_ADAP_NORM_CMD_ENTRIES; 1622 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1623 AAC_ADAP_HIGH_CMD_ENTRIES; 1624 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1625 AAC_ADAP_HIGH_CMD_ENTRIES; 1626 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1627 AAC_HOST_NORM_RESP_ENTRIES; 1628 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1629 AAC_HOST_NORM_RESP_ENTRIES; 1630 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1631 AAC_HOST_HIGH_RESP_ENTRIES; 1632 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1633 AAC_HOST_HIGH_RESP_ENTRIES; 1634 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1635 AAC_ADAP_NORM_RESP_ENTRIES; 1636 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1637 AAC_ADAP_NORM_RESP_ENTRIES; 1638 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1639 AAC_ADAP_HIGH_RESP_ENTRIES; 1640 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1641 AAC_ADAP_HIGH_RESP_ENTRIES; 1642 sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] = 1643 &sc->aac_queues->qt_HostNormCmdQueue[0]; 1644 sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] = 1645 &sc->aac_queues->qt_HostHighCmdQueue[0]; 1646 sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] = 1647 &sc->aac_queues->qt_AdapNormCmdQueue[0]; 1648 sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] = 1649 &sc->aac_queues->qt_AdapHighCmdQueue[0]; 1650 sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] = 1651 &sc->aac_queues->qt_HostNormRespQueue[0]; 1652 sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] = 1653 &sc->aac_queues->qt_HostHighRespQueue[0]; 1654 sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] = 1655 &sc->aac_queues->qt_AdapNormRespQueue[0]; 1656 sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] = 1657 &sc->aac_queues->qt_AdapHighRespQueue[0]; 1658 1659 /* 1660 * Do controller-type-specific initialisation 1661 */ 1662 switch (sc->aac_hwif) { 1663 case AAC_HWIF_I960RX: 1664 AAC_SETREG4(sc, AAC_RX_ODBR, ~0); 1665 break; 1666 case AAC_HWIF_RKT: 1667 AAC_SETREG4(sc, AAC_RKT_ODBR, ~0); 1668 break; 1669 default: 1670 break; 1671 } 1672 1673 /* 1674 * Give the init structure to the controller. 1675 */ 1676 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT, 1677 sc->aac_common_busaddr + 1678 offsetof(struct aac_common, ac_init), 0, 0, 0, 1679 NULL)) { 1680 printf("%s: error establishing init structure\n", 1681 sc->aac_dev.dv_xname); 1682 error = EIO; 1683 goto bail_out; 1684 } 1685 1686 aac_describe_controller(sc); 1687 aac_startup(sc); 1688 1689 return (0); 1690 1691 bail_out: 1692 if (state > 3) 1693 bus_dmamap_unload(sc->aac_dmat, sc->aac_common_map); 1694 if (state > 2) 1695 bus_dmamap_destroy(sc->aac_dmat, sc->aac_common_map); 1696 if (state > 1) 1697 bus_dmamem_unmap(sc->aac_dmat, (caddr_t)sc->aac_common, 1698 sizeof *sc->aac_common); 1699 if (state > 0) 1700 bus_dmamem_free(sc->aac_dmat, &seg, 1); 1701 1702 out: 1703 return (error); 1704 } 1705 1706 /* 1707 * Send a synchronous command to the controller and wait for a result. 1708 */ 1709 int 1710 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 1711 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp) 1712 { 1713 // time_t then; 1714 int i; 1715 u_int32_t status; 1716 u_int16_t reason; 1717 1718 /* populate the mailbox */ 1719 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3); 1720 1721 /* ensure the sync command doorbell flag is cleared */ 1722 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1723 1724 /* then set it to signal the adapter */ 1725 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND); 1726 1727 #if 0 1728 /* spin waiting for the command to complete */ 1729 then = time_uptime; 1730 do { 1731 if (time_uptime > (then + AAC_IMMEDIATE_TIMEOUT)) { 1732 AAC_DPRINTF(AAC_D_MISC, ("timed out")); 1733 return(EIO); 1734 } 1735 } while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND)); 1736 #else 1737 DELAY(AAC_SYNC_DELAY); 1738 1739 /* spin waiting for the command to complete */ 1740 for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) { 1741 reason = AAC_GET_ISTATUS(sc); 1742 if (reason & AAC_DB_SYNC_COMMAND) 1743 break; 1744 reason = AAC_GET_ISTATUS(sc); 1745 if (reason & AAC_DB_SYNC_COMMAND) 1746 break; 1747 reason = AAC_GET_ISTATUS(sc); 1748 if (reason & AAC_DB_SYNC_COMMAND) 1749 break; 1750 DELAY(1000); 1751 } 1752 if (i == AAC_IMMEDIATE_TIMEOUT * 1000) { 1753 printf("aac_sync_command: failed, reason=%#x\n", reason); 1754 return (EIO); 1755 } 1756 #endif 1757 1758 /* clear the completion flag */ 1759 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1760 1761 /* get the command status */ 1762 status = AAC_GET_MAILBOX(sc, 0); 1763 1764 if (sp != NULL) 1765 *sp = status; 1766 1767 return(0); 1768 } 1769 1770 /* 1771 * Grab the sync fib area. 1772 */ 1773 int 1774 aac_alloc_sync_fib(struct aac_softc *sc, struct aac_fib **fib, int flags) 1775 { 1776 1777 /* 1778 * If the force flag is set, the system is shutting down, or in 1779 * trouble. Ignore the mutex. 1780 */ 1781 if (!(flags & AAC_SYNC_LOCK_FORCE)) 1782 AAC_LOCK_ACQUIRE(&sc->aac_sync_lock); 1783 1784 *fib = &sc->aac_common->ac_sync_fib; 1785 1786 return (1); 1787 } 1788 1789 /* 1790 * Release the sync fib area. 1791 */ 1792 void 1793 aac_release_sync_fib(struct aac_softc *sc) 1794 { 1795 AAC_LOCK_RELEASE(&sc->aac_sync_lock); 1796 } 1797 1798 /* 1799 * Send a synchronous FIB to the controller and wait for a result. 1800 */ 1801 int 1802 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate, 1803 struct aac_fib *fib, u_int16_t datasize) 1804 { 1805 1806 if (datasize > AAC_FIB_DATASIZE) { 1807 printf("aac_sync_fib 1: datasize=%d AAC_FIB_DATASIZE %lu\n", 1808 datasize, AAC_FIB_DATASIZE); 1809 return(EINVAL); 1810 } 1811 1812 /* 1813 * Set up the sync FIB 1814 */ 1815 fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED | 1816 AAC_FIBSTATE_INITIALISED | 1817 AAC_FIBSTATE_EMPTY; 1818 fib->Header.XferState |= xferstate; 1819 fib->Header.Command = command; 1820 fib->Header.StructType = AAC_FIBTYPE_TFIB; 1821 fib->Header.Size = sizeof(struct aac_fib) + datasize; 1822 fib->Header.SenderSize = sizeof(struct aac_fib); 1823 fib->Header.SenderFibAddress = 0; /* Not needed */ 1824 fib->Header.ReceiverFibAddress = sc->aac_common_busaddr + 1825 offsetof(struct aac_common, 1826 ac_sync_fib); 1827 1828 /* 1829 * Give the FIB to the controller, wait for a response. 1830 */ 1831 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, 1832 fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) { 1833 AAC_DPRINTF(AAC_D_IO, ("%s: aac_sync_fib: IO error\n", 1834 sc->aac_dev.dv_xname)); 1835 printf("aac_sync_fib 2\n"); 1836 return(EIO); 1837 } 1838 1839 return (0); 1840 } 1841 1842 /***************************************************************************** 1843 * Adapter-space FIB queue manipulation 1844 * 1845 * Note that the queue implementation here is a little funky; neither the PI or 1846 * CI will ever be zero. This behaviour is a controller feature. 1847 */ 1848 static struct { 1849 int size; 1850 int notify; 1851 } aac_qinfo[] = { 1852 { AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL }, 1853 { AAC_HOST_HIGH_CMD_ENTRIES, 0 }, 1854 { AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY }, 1855 { AAC_ADAP_HIGH_CMD_ENTRIES, 0 }, 1856 { AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL }, 1857 { AAC_HOST_HIGH_RESP_ENTRIES, 0 }, 1858 { AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY }, 1859 { AAC_ADAP_HIGH_RESP_ENTRIES, 0 } 1860 }; 1861 1862 /* 1863 * Atomically insert an entry into the nominated queue, returns 0 on success 1864 * or EBUSY if the queue is full. 1865 * 1866 * Note: it would be more efficient to defer notifying the controller in 1867 * the case where we may be inserting several entries in rapid 1868 * succession, but implementing this usefully may be difficult 1869 * (it would involve a separate queue/notify interface). 1870 */ 1871 int 1872 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm) 1873 { 1874 u_int32_t pi, ci; 1875 int error; 1876 u_int32_t fib_size; 1877 u_int32_t fib_addr; 1878 1879 fib_size = cm->cm_fib->Header.Size; 1880 fib_addr = cm->cm_fib->Header.ReceiverFibAddress; 1881 1882 /* get the producer/consumer indices */ 1883 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1884 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1885 1886 /* wrap the queue? */ 1887 if (pi >= aac_qinfo[queue].size) 1888 pi = 0; 1889 1890 /* check for queue full */ 1891 if ((pi + 1) == ci) { 1892 error = EBUSY; 1893 goto out; 1894 } 1895 1896 /* populate queue entry */ 1897 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size; 1898 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr; 1899 1900 /* update producer index */ 1901 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1; 1902 1903 /* 1904 * To avoid a race with its completion interrupt, place this command on 1905 * the busy queue prior to advertising it to the controller. 1906 */ 1907 aac_enqueue_busy(cm); 1908 1909 /* notify the adapter if we know how */ 1910 if (aac_qinfo[queue].notify != 0) 1911 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1912 1913 error = 0; 1914 1915 out: 1916 return (error); 1917 } 1918 1919 /* 1920 * Atomically remove one entry from the nominated queue, returns 0 on success 1921 * or ENOENT if the queue is empty. 1922 */ 1923 int 1924 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size, 1925 struct aac_fib **fib_addr) 1926 { 1927 u_int32_t pi, ci; 1928 u_int32_t fib_index; 1929 int notify; 1930 int error; 1931 1932 /* get the producer/consumer indices */ 1933 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1934 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1935 1936 /* check for queue empty */ 1937 if (ci == pi) { 1938 error = ENOENT; 1939 goto out; 1940 } 1941 1942 /* wrap the pi so the following test works */ 1943 if (pi >= aac_qinfo[queue].size) 1944 pi = 0; 1945 1946 notify = 0; 1947 if (ci == pi + 1) 1948 notify++; 1949 1950 /* wrap the queue? */ 1951 if (ci >= aac_qinfo[queue].size) 1952 ci = 0; 1953 1954 /* fetch the entry */ 1955 *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size; 1956 1957 switch (queue) { 1958 case AAC_HOST_NORM_CMD_QUEUE: 1959 case AAC_HOST_HIGH_CMD_QUEUE: 1960 /* 1961 * The aq_fib_addr is only 32 bits wide so it can't be counted 1962 * on to hold an address. For AIF's, the adapter assumes 1963 * that it's giving us an address into the array of AIF fibs. 1964 * Therefore, we have to convert it to an index. 1965 */ 1966 fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr / 1967 sizeof(struct aac_fib); 1968 *fib_addr = &sc->aac_common->ac_fibs[fib_index]; 1969 break; 1970 1971 case AAC_HOST_NORM_RESP_QUEUE: 1972 case AAC_HOST_HIGH_RESP_QUEUE: 1973 { 1974 struct aac_command *cm; 1975 1976 /* 1977 * As above, an index is used instead of an actual address. 1978 * Gotta shift the index to account for the fast response 1979 * bit. No other correction is needed since this value was 1980 * originally provided by the driver via the SenderFibAddress 1981 * field. 1982 */ 1983 fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr; 1984 cm = sc->aac_commands + (fib_index >> 1); 1985 *fib_addr = cm->cm_fib; 1986 1987 /* 1988 * Is this a fast response? If it is, update the fib fields in 1989 * local memory since the whole fib isn't DMA'd back up. 1990 */ 1991 if (fib_index & 0x01) { 1992 (*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP; 1993 *((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL; 1994 } 1995 break; 1996 } 1997 default: 1998 panic("Invalid queue in aac_dequeue_fib()"); 1999 break; 2000 } 2001 2002 2003 /* update consumer index */ 2004 sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1; 2005 2006 /* if we have made the queue un-full, notify the adapter */ 2007 if (notify && (aac_qinfo[queue].notify != 0)) 2008 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 2009 error = 0; 2010 2011 out: 2012 return (error); 2013 } 2014 2015 /* 2016 * Put our response to an Adapter Initialed Fib on the response queue 2017 */ 2018 int 2019 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib) 2020 { 2021 u_int32_t pi, ci; 2022 int error; 2023 u_int32_t fib_size; 2024 u_int32_t fib_addr; 2025 2026 /* Tell the adapter where the FIB is */ 2027 fib_size = fib->Header.Size; 2028 fib_addr = fib->Header.SenderFibAddress; 2029 fib->Header.ReceiverFibAddress = fib_addr; 2030 2031 /* get the producer/consumer indices */ 2032 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 2033 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 2034 2035 /* wrap the queue? */ 2036 if (pi >= aac_qinfo[queue].size) 2037 pi = 0; 2038 2039 /* check for queue full */ 2040 if ((pi + 1) == ci) { 2041 error = EBUSY; 2042 goto out; 2043 } 2044 2045 /* populate queue entry */ 2046 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size; 2047 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr; 2048 2049 /* update producer index */ 2050 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1; 2051 2052 /* notify the adapter if we know how */ 2053 if (aac_qinfo[queue].notify != 0) 2054 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 2055 2056 error = 0; 2057 2058 out: 2059 return(error); 2060 } 2061 2062 void 2063 aac_command_timeout(struct aac_command *cm) 2064 { 2065 struct aac_softc *sc = cm->cm_sc; 2066 2067 printf("%s: COMMAND %p (flags=%#x) TIMEOUT AFTER %d SECONDS\n", 2068 sc->aac_dev.dv_xname, cm, cm->cm_flags, 2069 (int)(time_uptime - cm->cm_timestamp)); 2070 2071 if (cm->cm_flags & AAC_CMD_TIMEDOUT) 2072 return; 2073 2074 cm->cm_flags |= AAC_CMD_TIMEDOUT; 2075 2076 AAC_PRINT_FIB(sc, cm->cm_fib); 2077 2078 if (cm->cm_flags & AAC_ON_AACQ_BIO) { 2079 struct scsi_xfer *xs = cm->cm_private; 2080 int s = splbio(); 2081 xs->error = XS_DRIVER_STUFFUP; 2082 splx(s); 2083 scsi_done(xs); 2084 2085 aac_remove_bio(cm); 2086 aac_unmap_command(cm); 2087 } 2088 } 2089 2090 void 2091 aac_timeout(struct aac_softc *sc) 2092 { 2093 struct aac_command *cm; 2094 time_t deadline; 2095 2096 /* 2097 * Traverse the busy command list and timeout any commands 2098 * that are past their deadline. 2099 */ 2100 deadline = time_uptime - AAC_CMD_TIMEOUT; 2101 TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) { 2102 if (cm->cm_timestamp < deadline) 2103 aac_command_timeout(cm); 2104 } 2105 } 2106 2107 /* 2108 * Interface Function Vectors 2109 */ 2110 2111 /* 2112 * Read the current firmware status word. 2113 */ 2114 int 2115 aac_sa_get_fwstatus(struct aac_softc *sc) 2116 { 2117 return (AAC_GETREG4(sc, AAC_SA_FWSTATUS)); 2118 } 2119 2120 int 2121 aac_rx_get_fwstatus(struct aac_softc *sc) 2122 { 2123 return (AAC_GETREG4(sc, AAC_RX_FWSTATUS)); 2124 } 2125 2126 int 2127 aac_fa_get_fwstatus(struct aac_softc *sc) 2128 { 2129 return (AAC_GETREG4(sc, AAC_FA_FWSTATUS)); 2130 } 2131 2132 int 2133 aac_rkt_get_fwstatus(struct aac_softc *sc) 2134 { 2135 return(AAC_GETREG4(sc, AAC_RKT_FWSTATUS)); 2136 } 2137 2138 /* 2139 * Notify the controller of a change in a given queue 2140 */ 2141 2142 void 2143 aac_sa_qnotify(struct aac_softc *sc, int qbit) 2144 { 2145 AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit); 2146 } 2147 2148 void 2149 aac_rx_qnotify(struct aac_softc *sc, int qbit) 2150 { 2151 AAC_SETREG4(sc, AAC_RX_IDBR, qbit); 2152 } 2153 2154 void 2155 aac_fa_qnotify(struct aac_softc *sc, int qbit) 2156 { 2157 AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit); 2158 AAC_FA_HACK(sc); 2159 } 2160 2161 void 2162 aac_rkt_qnotify(struct aac_softc *sc, int qbit) 2163 { 2164 AAC_SETREG4(sc, AAC_RKT_IDBR, qbit); 2165 } 2166 2167 /* 2168 * Get the interrupt reason bits 2169 */ 2170 int 2171 aac_sa_get_istatus(struct aac_softc *sc) 2172 { 2173 return (AAC_GETREG2(sc, AAC_SA_DOORBELL0)); 2174 } 2175 2176 int 2177 aac_rx_get_istatus(struct aac_softc *sc) 2178 { 2179 return (AAC_GETREG4(sc, AAC_RX_ODBR)); 2180 } 2181 2182 int 2183 aac_fa_get_istatus(struct aac_softc *sc) 2184 { 2185 return (AAC_GETREG2(sc, AAC_FA_DOORBELL0)); 2186 } 2187 2188 int 2189 aac_rkt_get_istatus(struct aac_softc *sc) 2190 { 2191 return(AAC_GETREG4(sc, AAC_RKT_ODBR)); 2192 } 2193 2194 /* 2195 * Clear some interrupt reason bits 2196 */ 2197 void 2198 aac_sa_clear_istatus(struct aac_softc *sc, int mask) 2199 { 2200 AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask); 2201 } 2202 2203 void 2204 aac_rx_clear_istatus(struct aac_softc *sc, int mask) 2205 { 2206 AAC_SETREG4(sc, AAC_RX_ODBR, mask); 2207 } 2208 2209 void 2210 aac_fa_clear_istatus(struct aac_softc *sc, int mask) 2211 { 2212 AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask); 2213 AAC_FA_HACK(sc); 2214 } 2215 2216 void 2217 aac_rkt_clear_istatus(struct aac_softc *sc, int mask) 2218 { 2219 AAC_SETREG4(sc, AAC_RKT_ODBR, mask); 2220 } 2221 2222 /* 2223 * Populate the mailbox and set the command word 2224 */ 2225 void 2226 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 2227 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 2228 { 2229 AAC_SETREG4(sc, AAC_SA_MAILBOX, command); 2230 AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0); 2231 AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1); 2232 AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2); 2233 AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3); 2234 } 2235 2236 void 2237 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 2238 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 2239 { 2240 AAC_SETREG4(sc, AAC_RX_MAILBOX, command); 2241 AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0); 2242 AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1); 2243 AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2); 2244 AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3); 2245 } 2246 2247 void 2248 aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 2249 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 2250 { 2251 AAC_SETREG4(sc, AAC_FA_MAILBOX, command); 2252 AAC_FA_HACK(sc); 2253 AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0); 2254 AAC_FA_HACK(sc); 2255 AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1); 2256 AAC_FA_HACK(sc); 2257 AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2); 2258 AAC_FA_HACK(sc); 2259 AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3); 2260 AAC_FA_HACK(sc); 2261 } 2262 2263 void 2264 aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 2265 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 2266 { 2267 AAC_SETREG4(sc, AAC_RKT_MAILBOX, command); 2268 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0); 2269 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1); 2270 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2); 2271 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3); 2272 } 2273 2274 /* 2275 * Fetch the immediate command status word 2276 */ 2277 int 2278 aac_sa_get_mailbox(struct aac_softc *sc, int mb) 2279 { 2280 return (AAC_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4))); 2281 } 2282 2283 int 2284 aac_rx_get_mailbox(struct aac_softc *sc, int mb) 2285 { 2286 return (AAC_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4))); 2287 } 2288 2289 int 2290 aac_fa_get_mailbox(struct aac_softc *sc, int mb) 2291 { 2292 return (AAC_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4))); 2293 } 2294 2295 int 2296 aac_rkt_get_mailbox(struct aac_softc *sc, int mb) 2297 { 2298 return(AAC_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4))); 2299 } 2300 2301 /* 2302 * Set/clear interrupt masks 2303 */ 2304 void 2305 aac_sa_set_interrupts(struct aac_softc *sc, int enable) 2306 { 2307 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts\n", 2308 sc->aac_dev.dv_xname, enable ? "en" : "dis")); 2309 2310 if (enable) 2311 AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS); 2312 else 2313 AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0); 2314 } 2315 2316 void 2317 aac_rx_set_interrupts(struct aac_softc *sc, int enable) 2318 { 2319 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts", 2320 sc->aac_dev.dv_xname, enable ? "en" : "dis")); 2321 2322 if (enable) 2323 AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS); 2324 else 2325 AAC_SETREG4(sc, AAC_RX_OIMR, ~0); 2326 } 2327 2328 void 2329 aac_fa_set_interrupts(struct aac_softc *sc, int enable) 2330 { 2331 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts", 2332 sc->aac_dev.dv_xname, enable ? "en" : "dis")); 2333 2334 if (enable) { 2335 AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS); 2336 AAC_FA_HACK(sc); 2337 } else { 2338 AAC_SETREG2((sc), AAC_FA_MASK0, ~0); 2339 AAC_FA_HACK(sc); 2340 } 2341 } 2342 2343 void 2344 aac_rkt_set_interrupts(struct aac_softc *sc, int enable) 2345 { 2346 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts", 2347 sc->aac_dev.dv_xname, enable ? "en" : "dis")); 2348 2349 if (enable) 2350 AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS); 2351 else 2352 AAC_SETREG4(sc, AAC_RKT_OIMR, ~0); 2353 } 2354 2355 void 2356 aac_eval_mapping(size, cyls, heads, secs) 2357 u_int32_t size; 2358 int *cyls, *heads, *secs; 2359 { 2360 *cyls = size / AAC_HEADS / AAC_SECS; 2361 if (*cyls < AAC_MAXCYLS) { 2362 *heads = AAC_HEADS; 2363 *secs = AAC_SECS; 2364 } else { 2365 /* Too high for 64 * 32 */ 2366 *cyls = size / AAC_MEDHEADS / AAC_MEDSECS; 2367 if (*cyls < AAC_MAXCYLS) { 2368 *heads = AAC_MEDHEADS; 2369 *secs = AAC_MEDSECS; 2370 } else { 2371 /* Too high for 127 * 63 */ 2372 *cyls = size / AAC_BIGHEADS / AAC_BIGSECS; 2373 *heads = AAC_BIGHEADS; 2374 *secs = AAC_BIGSECS; 2375 } 2376 } 2377 } 2378 2379 void 2380 aac_copy_internal_data(struct scsi_xfer *xs, u_int8_t *data, size_t size) 2381 { 2382 struct aac_softc *sc = xs->sc_link->adapter_softc; 2383 size_t copy_cnt; 2384 2385 AAC_DPRINTF(AAC_D_MISC, ("%s: aac_copy_internal_data\n", 2386 sc->aac_dev.dv_xname)); 2387 2388 if (!xs->datalen) 2389 printf("%s: uio move not yet supported\n", 2390 sc->aac_dev.dv_xname); 2391 else { 2392 copy_cnt = MIN(size, xs->datalen); 2393 bcopy(data, xs->data, copy_cnt); 2394 } 2395 } 2396 2397 /* Emulated SCSI operation on cache device */ 2398 void 2399 aac_internal_cache_cmd(struct scsi_xfer *xs) 2400 { 2401 struct scsi_link *link = xs->sc_link; 2402 struct aac_softc *sc = link->adapter_softc; 2403 struct scsi_inquiry_data inq; 2404 struct scsi_sense_data sd; 2405 struct scsi_read_cap_data rcd; 2406 u_int8_t target = link->target; 2407 2408 AAC_DPRINTF(AAC_D_CMD, ("aac_internal_cache_cmd: ", 2409 sc->aac_dev.dv_xname)); 2410 2411 switch (xs->cmd->opcode) { 2412 case TEST_UNIT_READY: 2413 case START_STOP: 2414 #if 0 2415 case VERIFY: 2416 #endif 2417 AAC_DPRINTF(AAC_D_CMD, ("opc %#x tgt %d ", xs->cmd->opcode, 2418 target)); 2419 break; 2420 2421 case REQUEST_SENSE: 2422 AAC_DPRINTF(AAC_D_CMD, ("REQUEST SENSE tgt %d ", target)); 2423 bzero(&sd, sizeof sd); 2424 sd.error_code = SSD_ERRCODE_CURRENT; 2425 sd.segment = 0; 2426 sd.flags = SKEY_NO_SENSE; 2427 aac_enc32(sd.info, 0); 2428 sd.extra_len = 0; 2429 aac_copy_internal_data(xs, (u_int8_t *)&sd, sizeof sd); 2430 break; 2431 2432 case INQUIRY: 2433 AAC_DPRINTF(AAC_D_CMD, ("INQUIRY tgt %d devtype %x ", target, 2434 sc->aac_hdr[target].hd_devtype)); 2435 bzero(&inq, sizeof inq); 2436 /* XXX How do we detect removable/CD-ROM devices? */ 2437 inq.device = T_DIRECT; 2438 inq.dev_qual2 = 0; 2439 inq.version = 2; 2440 inq.response_format = 2; 2441 inq.additional_length = 32; 2442 inq.flags |= SID_CmdQue; 2443 strlcpy(inq.vendor, "Adaptec", sizeof inq.vendor); 2444 snprintf(inq.product, sizeof inq.product, "Container #%02d", 2445 target); 2446 strlcpy(inq.revision, " ", sizeof inq.revision); 2447 aac_copy_internal_data(xs, (u_int8_t *)&inq, sizeof inq); 2448 break; 2449 2450 case READ_CAPACITY: 2451 AAC_DPRINTF(AAC_D_CMD, ("READ CAPACITY tgt %d ", target)); 2452 bzero(&rcd, sizeof rcd); 2453 _lto4b(sc->aac_hdr[target].hd_size - 1, rcd.addr); 2454 _lto4b(AAC_BLOCK_SIZE, rcd.length); 2455 aac_copy_internal_data(xs, (u_int8_t *)&rcd, sizeof rcd); 2456 break; 2457 2458 default: 2459 AAC_DPRINTF(AAC_D_CMD, ("\n")); 2460 printf("aac_internal_cache_cmd got bad opcode: %#x\n", 2461 xs->cmd->opcode); 2462 xs->error = XS_DRIVER_STUFFUP; 2463 return; 2464 } 2465 2466 xs->error = XS_NOERROR; 2467 } 2468 2469 void 2470 aacminphys(struct buf *bp, struct scsi_link *sl) 2471 { 2472 AAC_DPRINTF(AAC_D_MISC, ("aacminphys(0x%x)\n", bp)); 2473 2474 #if 0 /* As this is way more than MAXPHYS it's really not necessary. */ 2475 if (bp->b_bcount > ((AAC_MAXOFFSETS - 1) * PAGE_SIZE)) 2476 bp->b_bcount = ((AAC_MAXOFFSETS - 1) * PAGE_SIZE); 2477 #endif 2478 2479 minphys(bp); 2480 } 2481 2482 void 2483 aac_scsi_cmd(struct scsi_xfer *xs) 2484 { 2485 struct scsi_link *link = xs->sc_link; 2486 struct aac_softc *sc = link->adapter_softc; 2487 u_int8_t target = link->target; 2488 struct aac_command *cm; 2489 u_int32_t blockno, blockcnt; 2490 struct scsi_rw *rw; 2491 struct scsi_rw_big *rwb; 2492 int s; 2493 2494 s = splbio(); 2495 2496 xs->error = XS_NOERROR; 2497 2498 if (target >= AAC_MAX_CONTAINERS || !sc->aac_hdr[target].hd_present || 2499 link->lun != 0) { 2500 /* 2501 * XXX Should be XS_SENSE but that would require setting up a 2502 * faked sense too. 2503 */ 2504 splx(s); 2505 xs->error = XS_DRIVER_STUFFUP; 2506 scsi_done(xs); 2507 return; 2508 } 2509 2510 AAC_DPRINTF(AAC_D_CMD, ("%s: aac_scsi_cmd: ", sc->aac_dev.dv_xname)); 2511 2512 xs->error = XS_NOERROR; 2513 cm = NULL; 2514 link = xs->sc_link; 2515 target = link->target; 2516 2517 switch (xs->cmd->opcode) { 2518 case TEST_UNIT_READY: 2519 case REQUEST_SENSE: 2520 case INQUIRY: 2521 case START_STOP: 2522 case READ_CAPACITY: 2523 #if 0 2524 case VERIFY: 2525 #endif 2526 aac_internal_cache_cmd(xs); 2527 scsi_done(xs); 2528 goto ready; 2529 2530 case PREVENT_ALLOW: 2531 AAC_DPRINTF(AAC_D_CMD, ("PREVENT/ALLOW ")); 2532 /* XXX Not yet implemented */ 2533 xs->error = XS_NOERROR; 2534 scsi_done(xs); 2535 goto ready; 2536 2537 case SYNCHRONIZE_CACHE: 2538 AAC_DPRINTF(AAC_D_CMD, ("SYNCHRONIZE_CACHE ")); 2539 /* XXX Not yet implemented */ 2540 xs->error = XS_NOERROR; 2541 scsi_done(xs); 2542 goto ready; 2543 2544 default: 2545 AAC_DPRINTF(AAC_D_CMD, ("unknown opc %#x ", xs->cmd->opcode)); 2546 /* XXX Not yet implemented */ 2547 xs->error = XS_DRIVER_STUFFUP; 2548 scsi_done(xs); 2549 goto ready; 2550 2551 case READ_COMMAND: 2552 case READ_BIG: 2553 case WRITE_COMMAND: 2554 case WRITE_BIG: 2555 AAC_DPRINTF(AAC_D_CMD, ("rw opc %#x ", xs->cmd->opcode)); 2556 2557 /* A read or write operation. */ 2558 if (xs->cmdlen == 6) { 2559 rw = (struct scsi_rw *)xs->cmd; 2560 blockno = _3btol(rw->addr) & 2561 (SRW_TOPADDR << 16 | 0xffff); 2562 blockcnt = rw->length ? rw->length : 0x100; 2563 } else { 2564 rwb = (struct scsi_rw_big *)xs->cmd; 2565 blockno = _4btol(rwb->addr); 2566 blockcnt = _2btol(rwb->length); 2567 } 2568 2569 AAC_DPRINTF(AAC_D_CMD, ("blkno=%d bcount=%d ", 2570 xs->cmd->opcode, blockno, blockcnt)); 2571 2572 if (blockno >= sc->aac_hdr[target].hd_size || 2573 blockno + blockcnt > sc->aac_hdr[target].hd_size) { 2574 AAC_DPRINTF(AAC_D_CMD, ("\n")); 2575 printf("%s: out of bounds %u-%u >= %u\n", 2576 sc->aac_dev.dv_xname, blockno, 2577 blockcnt, sc->aac_hdr[target].hd_size); 2578 /* 2579 * XXX Should be XS_SENSE but that 2580 * would require setting up a faked 2581 * sense too. 2582 */ 2583 xs->error = XS_DRIVER_STUFFUP; 2584 scsi_done(xs); 2585 goto ready; 2586 } 2587 2588 if (aac_alloc_command(sc, &cm)) { 2589 AAC_DPRINTF(AAC_D_CMD, 2590 (": out of commands, try later\n")); 2591 /* 2592 * We are out of commands, try again 2593 * in a little while. 2594 */ 2595 xs->error = XS_NO_CCB; 2596 scsi_done(xs); 2597 splx(s); 2598 return; 2599 } 2600 2601 /* fill out the command */ 2602 cm->cm_data = (void *)xs->data; 2603 cm->cm_datalen = xs->datalen; 2604 cm->cm_complete = aac_bio_complete; 2605 cm->cm_private = xs; 2606 cm->cm_timestamp = time_uptime; 2607 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; 2608 cm->cm_blkno = blockno; 2609 cm->cm_bcount = blockcnt; 2610 2611 AAC_DPRINTF(AAC_D_CMD, ("\n")); 2612 aac_enqueue_bio(cm); 2613 aac_startio(sc); 2614 2615 /* XXX what if enqueue did not start a transfer? */ 2616 if (xs->flags & SCSI_POLL) { 2617 if (!aac_wait_command(cm, xs->timeout)) 2618 { 2619 printf("%s: command timed out\n", 2620 sc->aac_dev.dv_xname); 2621 xs->error = XS_NO_CCB; 2622 scsi_done(xs); 2623 splx(s); 2624 return; 2625 } 2626 scsi_done(xs); 2627 } 2628 } 2629 2630 ready: 2631 splx(s); 2632 AAC_DPRINTF(AAC_D_CMD, ("%s: scsi_cmd complete\n", 2633 sc->aac_dev.dv_xname)); 2634 } 2635 2636 /* 2637 * Debugging and Diagnostics 2638 */ 2639 2640 /* 2641 * Print some information about the controller. 2642 */ 2643 void 2644 aac_describe_controller(struct aac_softc *sc) 2645 { 2646 struct aac_fib *fib; 2647 struct aac_adapter_info *info; 2648 2649 aac_alloc_sync_fib(sc, &fib, 0); 2650 2651 fib->data[0] = 0; 2652 if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) { 2653 printf("%s: RequestAdapterInfo failed 2\n", 2654 sc->aac_dev.dv_xname); 2655 aac_release_sync_fib(sc); 2656 return; 2657 } 2658 info = (struct aac_adapter_info *)&fib->data[0]; 2659 2660 printf("%s: %s %dMHz, %dMB cache memory, %s\n", sc->aac_dev.dv_xname, 2661 aac_describe_code(aac_cpu_variant, info->CpuVariant), 2662 info->ClockSpeed, info->BufferMem / (1024 * 1024), 2663 aac_describe_code(aac_battery_platform, info->batteryPlatform)); 2664 2665 /* save the kernel revision structure for later use */ 2666 sc->aac_revision = info->KernelRevision; 2667 printf("%s: Kernel %d.%d-%d, Build %d, S/N %6X\n", 2668 sc->aac_dev.dv_xname, 2669 info->KernelRevision.external.comp.major, 2670 info->KernelRevision.external.comp.minor, 2671 info->KernelRevision.external.comp.dash, 2672 info->KernelRevision.buildNumber, 2673 (u_int32_t)(info->SerialNumber & 0xffffff)); 2674 2675 aac_release_sync_fib(sc); 2676 2677 #if 0 2678 if (1 || bootverbose) { 2679 device_printf(sc->aac_dev, "Supported Options=%b\n", 2680 sc->supported_options, 2681 "\20" 2682 "\1SNAPSHOT" 2683 "\2CLUSTERS" 2684 "\3WCACHE" 2685 "\4DATA64" 2686 "\5HOSTTIME" 2687 "\6RAID50" 2688 "\7WINDOW4GB" 2689 "\10SCSIUPGD" 2690 "\11SOFTERR" 2691 "\12NORECOND" 2692 "\13SGMAP64" 2693 "\14ALARM" 2694 "\15NONDASD"); 2695 } 2696 #endif 2697 } 2698 2699 /* 2700 * Look up a text description of a numeric error code and return a pointer to 2701 * same. 2702 */ 2703 char * 2704 aac_describe_code(struct aac_code_lookup *table, u_int32_t code) 2705 { 2706 int i; 2707 2708 for (i = 0; table[i].string != NULL; i++) 2709 if (table[i].code == code) 2710 return(table[i].string); 2711 return(table[i + 1].string); 2712 } 2713 2714 #ifdef AAC_DEBUG 2715 /* 2716 * Print a FIB 2717 */ 2718 void 2719 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller) 2720 { 2721 printf("%s: FIB @ %p\n", caller, fib); 2722 printf(" XferState %b\n", fib->Header.XferState, "\20" 2723 "\1HOSTOWNED" 2724 "\2ADAPTEROWNED" 2725 "\3INITIALISED" 2726 "\4EMPTY" 2727 "\5FROMPOOL" 2728 "\6FROMHOST" 2729 "\7FROMADAP" 2730 "\10REXPECTED" 2731 "\11RNOTEXPECTED" 2732 "\12DONEADAP" 2733 "\13DONEHOST" 2734 "\14HIGH" 2735 "\15NORM" 2736 "\16ASYNC" 2737 "\17PAGEFILEIO" 2738 "\20SHUTDOWN" 2739 "\21LAZYWRITE" 2740 "\22ADAPMICROFIB" 2741 "\23BIOSFIB" 2742 "\24FAST_RESPONSE" 2743 "\25APIFIB\n"); 2744 printf(" Command %d\n", fib->Header.Command); 2745 printf(" StructType %d\n", fib->Header.StructType); 2746 printf(" Flags 0x%x\n", fib->Header.Flags); 2747 printf(" Size %d\n", fib->Header.Size); 2748 printf(" SenderSize %d\n", fib->Header.SenderSize); 2749 printf(" SenderAddress 0x%x\n", fib->Header.SenderFibAddress); 2750 printf(" ReceiverAddress 0x%x\n", fib->Header.ReceiverFibAddress); 2751 printf(" SenderData 0x%x\n", fib->Header.SenderData); 2752 switch(fib->Header.Command) { 2753 case ContainerCommand: { 2754 struct aac_blockread *br = (struct aac_blockread *)fib->data; 2755 struct aac_blockwrite *bw = (struct aac_blockwrite *)fib->data; 2756 struct aac_sg_table *sg = NULL; 2757 int i; 2758 2759 if (br->Command == VM_CtBlockRead) { 2760 printf(" BlockRead: container %d 0x%x/%d\n", 2761 br->ContainerId, br->BlockNumber, br->ByteCount); 2762 sg = &br->SgMap; 2763 } 2764 if (bw->Command == VM_CtBlockWrite) { 2765 printf(" BlockWrite: container %d 0x%x/%d (%s)\n", 2766 bw->ContainerId, bw->BlockNumber, bw->ByteCount, 2767 bw->Stable == CSTABLE ? "stable" : "unstable"); 2768 sg = &bw->SgMap; 2769 } 2770 if (sg != NULL) { 2771 printf(" %d s/g entries\n", sg->SgCount); 2772 for (i = 0; i < sg->SgCount; i++) 2773 printf(" 0x%08x/%d\n", 2774 sg->SgEntry[i].SgAddress, 2775 sg->SgEntry[i].SgByteCount); 2776 } 2777 break; 2778 } 2779 default: 2780 printf(" %16D\n", fib->data, " "); 2781 printf(" %16D\n", fib->data + 16, " "); 2782 break; 2783 } 2784 } 2785 2786 /* 2787 * Describe an AIF we have received. 2788 */ 2789 void 2790 aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif) 2791 { 2792 printf("%s: print_aif: ", sc->aac_dev.dv_xname); 2793 2794 switch(aif->command) { 2795 case AifCmdEventNotify: 2796 printf("EventNotify(%d)\n", aif->seqNumber); 2797 2798 switch(aif->data.EN.type) { 2799 case AifEnGeneric: 2800 /* Generic notification */ 2801 printf("\t(Generic) %.*s\n", 2802 (int)sizeof(aif->data.EN.data.EG), 2803 aif->data.EN.data.EG.text); 2804 break; 2805 case AifEnTaskComplete: 2806 /* Task has completed */ 2807 printf("\t(TaskComplete)\n"); 2808 break; 2809 case AifEnConfigChange: 2810 /* Adapter configuration change occurred */ 2811 printf("\t(ConfigChange)\n"); 2812 break; 2813 case AifEnContainerChange: 2814 /* Adapter specific container configuration change */ 2815 printf("\t(ContainerChange) container %d,%d\n", 2816 aif->data.EN.data.ECC.container[0], 2817 aif->data.EN.data.ECC.container[1]); 2818 break; 2819 case AifEnDeviceFailure: 2820 /* SCSI device failed */ 2821 printf("\t(DeviceFailure) handle %d\n", 2822 aif->data.EN.data.EDF.deviceHandle); 2823 break; 2824 case AifEnMirrorFailover: 2825 /* Mirror failover started */ 2826 printf("\t(MirrorFailover) container %d failed, " 2827 "migrating from slice %d to %d\n", 2828 aif->data.EN.data.EMF.container, 2829 aif->data.EN.data.EMF.failedSlice, 2830 aif->data.EN.data.EMF.creatingSlice); 2831 break; 2832 case AifEnContainerEvent: 2833 /* Significant container event */ 2834 printf("\t(ContainerEvent) container %d event %d\n", 2835 aif->data.EN.data.ECE.container, 2836 aif->data.EN.data.ECE.eventType); 2837 break; 2838 case AifEnFileSystemChange: 2839 /* File system changed */ 2840 printf("\t(FileSystemChange)\n"); 2841 break; 2842 case AifEnConfigPause: 2843 /* Container pause event */ 2844 printf("\t(ConfigPause)\n"); 2845 break; 2846 case AifEnConfigResume: 2847 /* Container resume event */ 2848 printf("\t(ConfigResume)\n"); 2849 break; 2850 case AifEnFailoverChange: 2851 /* Failover space assignment changed */ 2852 printf("\t(FailoverChange)\n"); 2853 break; 2854 case AifEnRAID5RebuildDone: 2855 /* RAID5 rebuild finished */ 2856 printf("\t(RAID5RebuildDone)\n"); 2857 break; 2858 case AifEnEnclosureManagement: 2859 /* Enclosure management event */ 2860 printf("\t(EnclosureManagement) EMPID %d unit %d " 2861 "event %d\n", 2862 aif->data.EN.data.EEE.empID, 2863 aif->data.EN.data.EEE.unitID, 2864 aif->data.EN.data.EEE.eventType); 2865 break; 2866 case AifEnBatteryEvent: 2867 /* Significant NV battery event */ 2868 printf("\t(BatteryEvent) %d (state was %d, is %d\n", 2869 aif->data.EN.data.EBE.transition_type, 2870 aif->data.EN.data.EBE.current_state, 2871 aif->data.EN.data.EBE.prior_state); 2872 break; 2873 case AifEnAddContainer: 2874 /* A new container was created. */ 2875 printf("\t(AddContainer)\n"); 2876 break; 2877 case AifEnDeleteContainer: 2878 /* A container was deleted. */ 2879 printf("\t(DeleteContainer)\n"); 2880 break; 2881 case AifEnBatteryNeedsRecond: 2882 /* The battery needs reconditioning */ 2883 printf("\t(BatteryNeedsRecond)\n"); 2884 break; 2885 case AifEnClusterEvent: 2886 /* Some cluster event */ 2887 printf("\t(ClusterEvent) event %d\n", 2888 aif->data.EN.data.ECLE.eventType); 2889 break; 2890 case AifEnDiskSetEvent: 2891 /* A disk set event occured. */ 2892 printf("(DiskSetEvent) event %d " 2893 "diskset %lld creator %lld\n", 2894 aif->data.EN.data.EDS.eventType, 2895 aif->data.EN.data.EDS.DsNum, 2896 aif->data.EN.data.EDS.CreatorId); 2897 break; 2898 case AifDenMorphComplete: 2899 /* A morph operation completed */ 2900 printf("\t(MorphComplete)\n"); 2901 break; 2902 case AifDenVolumeExtendComplete: 2903 /* A volume expand operation completed */ 2904 printf("\t(VolumeExtendComplete)\n"); 2905 break; 2906 default: 2907 printf("\t(%d)\n", aif->data.EN.type); 2908 break; 2909 } 2910 break; 2911 case AifCmdJobProgress: 2912 { 2913 char *status; 2914 switch(aif->data.PR[0].status) { 2915 case AifJobStsSuccess: 2916 status = "success"; break; 2917 case AifJobStsFinished: 2918 status = "finished"; break; 2919 case AifJobStsAborted: 2920 status = "aborted"; break; 2921 case AifJobStsFailed: 2922 status = "failed"; break; 2923 case AifJobStsSuspended: 2924 status = "suspended"; break; 2925 case AifJobStsRunning: 2926 status = "running"; break; 2927 default: 2928 status = "unknown status"; break; 2929 } 2930 2931 printf("JobProgress (%d) - %s (%d, %d)\n", 2932 aif->seqNumber, status, 2933 aif->data.PR[0].currentTick, 2934 aif->data.PR[0].finalTick); 2935 2936 switch(aif->data.PR[0].jd.type) { 2937 case AifJobScsiZero: 2938 /* SCSI dev clear operation */ 2939 printf("\t(ScsiZero) handle %d\n", 2940 aif->data.PR[0].jd.client.scsi_dh); 2941 break; 2942 case AifJobScsiVerify: 2943 /* SCSI device Verify operation NO REPAIR */ 2944 printf("\t(ScsiVerify) handle %d\n", 2945 aif->data.PR[0].jd.client.scsi_dh); 2946 break; 2947 case AifJobScsiExercise: 2948 /* SCSI device Exercise operation */ 2949 printf("\t(ScsiExercise) handle %d\n", 2950 aif->data.PR[0].jd.client.scsi_dh); 2951 break; 2952 case AifJobScsiVerifyRepair: 2953 /* SCSI device Verify operation WITH repair */ 2954 printf("\t(ScsiVerifyRepair) handle %d\n", 2955 aif->data.PR[0].jd.client.scsi_dh); 2956 break; 2957 case AifJobCtrZero: 2958 /* Container clear operation */ 2959 printf("\t(ContainerZero) container %d\n", 2960 aif->data.PR[0].jd.client.container.src); 2961 break; 2962 case AifJobCtrCopy: 2963 /* Container copy operation */ 2964 printf("\t(ContainerCopy) container %d to %d\n", 2965 aif->data.PR[0].jd.client.container.src, 2966 aif->data.PR[0].jd.client.container.dst); 2967 break; 2968 case AifJobCtrCreateMirror: 2969 /* Container Create Mirror operation */ 2970 printf("\t(ContainerCreateMirror) container %d\n", 2971 aif->data.PR[0].jd.client.container.src); 2972 /* XXX two containers? */ 2973 break; 2974 case AifJobCtrMergeMirror: 2975 /* Container Merge Mirror operation */ 2976 printf("\t(ContainerMergeMirror) container %d\n", 2977 aif->data.PR[0].jd.client.container.src); 2978 /* XXX two containers? */ 2979 break; 2980 case AifJobCtrScrubMirror: 2981 /* Container Scrub Mirror operation */ 2982 printf("\t(ContainerScrubMirror) container %d\n", 2983 aif->data.PR[0].jd.client.container.src); 2984 break; 2985 case AifJobCtrRebuildRaid5: 2986 /* Container Rebuild Raid5 operation */ 2987 printf("\t(ContainerRebuildRaid5) container %d\n", 2988 aif->data.PR[0].jd.client.container.src); 2989 break; 2990 case AifJobCtrScrubRaid5: 2991 /* Container Scrub Raid5 operation */ 2992 printf("\t(ContainerScrubRaid5) container %d\n", 2993 aif->data.PR[0].jd.client.container.src); 2994 break; 2995 case AifJobCtrMorph: 2996 /* Container morph operation */ 2997 printf("\t(ContainerMorph) container %d\n", 2998 aif->data.PR[0].jd.client.container.src); 2999 /* XXX two containers? */ 3000 break; 3001 case AifJobCtrPartCopy: 3002 /* Container Partition copy operation */ 3003 printf("\t(ContainerPartCopy) container %d to %d\n", 3004 aif->data.PR[0].jd.client.container.src, 3005 aif->data.PR[0].jd.client.container.dst); 3006 break; 3007 case AifJobCtrRebuildMirror: 3008 /* Container Rebuild Mirror operation */ 3009 printf("\t(ContainerRebuildMirror) container %d\n", 3010 aif->data.PR[0].jd.client.container.src); 3011 break; 3012 case AifJobCtrCrazyCache: 3013 /* crazy cache */ 3014 printf("\t(ContainerCrazyCache) container %d\n", 3015 aif->data.PR[0].jd.client.container.src); 3016 /* XXX two containers? */ 3017 break; 3018 case AifJobFsCreate: 3019 /* File System Create operation */ 3020 printf("\t(FsCreate)\n"); 3021 break; 3022 case AifJobFsVerify: 3023 /* File System Verify operation */ 3024 printf("\t(FsVerivy)\n"); 3025 break; 3026 case AifJobFsExtend: 3027 /* File System Extend operation */ 3028 printf("\t(FsExtend)\n"); 3029 break; 3030 case AifJobApiFormatNTFS: 3031 /* Format a drive to NTFS */ 3032 printf("\t(FormatNTFS)\n"); 3033 break; 3034 case AifJobApiFormatFAT: 3035 /* Format a drive to FAT */ 3036 printf("\t(FormatFAT)\n"); 3037 break; 3038 case AifJobApiUpdateSnapshot: 3039 /* update the read/write half of a snapshot */ 3040 printf("\t(UpdateSnapshot)\n"); 3041 break; 3042 case AifJobApiFormatFAT32: 3043 /* Format a drive to FAT32 */ 3044 printf("\t(FormatFAT32)\n"); 3045 break; 3046 case AifJobCtlContinuousCtrVerify: 3047 /* Adapter operation */ 3048 printf("\t(ContinuousCtrVerify)\n"); 3049 break; 3050 default: 3051 printf("\t(%d)\n", aif->data.PR[0].jd.type); 3052 break; 3053 } 3054 break; 3055 } 3056 case AifCmdAPIReport: 3057 printf("APIReport (%d)\n", aif->seqNumber); 3058 break; 3059 case AifCmdDriverNotify: 3060 printf("DriverNotify (%d)\n", aif->seqNumber); 3061 break; 3062 default: 3063 printf("AIF %d (%d)\n", aif->command, aif->seqNumber); 3064 break; 3065 } 3066 } 3067 #endif 3068