1 /*- 2 * Copyright (c) 2000 Michael Smith 3 * Copyright (c) 2001 Scott Long 4 * Copyright (c) 2000 BSDi 5 * Copyright (c) 2001 Adaptec, Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 /* 33 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters. 34 */ 35 36 #include "opt_aac.h" 37 38 /* #include <stddef.h> */ 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/malloc.h> 42 #include <sys/kernel.h> 43 #include <sys/kthread.h> 44 #include <sys/sysctl.h> 45 #include <sys/poll.h> 46 #include <sys/selinfo.h> 47 48 #include <dev/aac/aac_compat.h> 49 50 #include <sys/bus.h> 51 #include <sys/conf.h> 52 #include <sys/devicestat.h> 53 #include <sys/disk.h> 54 #include <sys/file.h> 55 #include <sys/signalvar.h> 56 #include <sys/time.h> 57 #include <sys/eventhandler.h> 58 59 #include <machine/bus_memio.h> 60 #include <machine/bus.h> 61 #include <machine/resource.h> 62 63 #include <dev/aac/aacreg.h> 64 #include <dev/aac/aac_ioctl.h> 65 #include <dev/aac/aacvar.h> 66 #include <dev/aac/aac_tables.h> 67 68 devclass_t aac_devclass; 69 70 static void aac_startup(void *arg); 71 static void aac_add_container(struct aac_softc *sc, 72 struct aac_mntinforesponse *mir, int f); 73 74 /* Command Processing */ 75 static void aac_startio(struct aac_softc *sc); 76 static void aac_timeout(struct aac_softc *sc); 77 static int aac_start(struct aac_command *cm); 78 static void aac_complete(void *context, int pending); 79 static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp); 80 static void aac_bio_complete(struct aac_command *cm); 81 static int aac_wait_command(struct aac_command *cm, int timeout); 82 static void aac_host_command(struct aac_softc *sc); 83 static void aac_host_response(struct aac_softc *sc); 84 85 /* Command Buffer Management */ 86 static int aac_alloc_command(struct aac_softc *sc, 87 struct aac_command **cmp); 88 static void aac_release_command(struct aac_command *cm); 89 static void aac_map_command_helper(void *arg, bus_dma_segment_t *segs, 90 int nseg, int error); 91 static int aac_alloc_commands(struct aac_softc *sc); 92 static void aac_free_commands(struct aac_softc *sc); 93 static void aac_map_command(struct aac_command *cm); 94 static void aac_unmap_command(struct aac_command *cm); 95 96 /* Hardware Interface */ 97 static void aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, 98 int error); 99 static int aac_init(struct aac_softc *sc); 100 static int aac_sync_command(struct aac_softc *sc, u_int32_t command, 101 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, 102 u_int32_t arg3, u_int32_t *sp); 103 static int aac_sync_fib(struct aac_softc *sc, u_int32_t command, 104 u_int32_t xferstate, void *data, 105 u_int16_t datasize, void *result, 106 u_int16_t *resultsize); 107 static int aac_enqueue_fib(struct aac_softc *sc, int queue, 108 struct aac_command *cm); 109 static int aac_dequeue_fib(struct aac_softc *sc, int queue, 110 u_int32_t *fib_size, struct aac_fib **fib_addr); 111 static int aac_enqueue_response(struct aac_softc *sc, int queue, 112 struct aac_fib *fib); 113 114 /* Falcon/PPC interface */ 115 static int aac_fa_get_fwstatus(struct aac_softc *sc); 116 static void aac_fa_qnotify(struct aac_softc *sc, int qbit); 117 static int aac_fa_get_istatus(struct aac_softc *sc); 118 static void aac_fa_clear_istatus(struct aac_softc *sc, int mask); 119 static void aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command, 120 u_int32_t arg0, u_int32_t arg1, 121 u_int32_t arg2, u_int32_t arg3); 122 static int aac_fa_get_mailboxstatus(struct aac_softc *sc); 123 static void aac_fa_set_interrupts(struct aac_softc *sc, int enable); 124 125 struct aac_interface aac_fa_interface = { 126 aac_fa_get_fwstatus, 127 aac_fa_qnotify, 128 aac_fa_get_istatus, 129 aac_fa_clear_istatus, 130 aac_fa_set_mailbox, 131 aac_fa_get_mailboxstatus, 132 aac_fa_set_interrupts 133 }; 134 135 /* StrongARM interface */ 136 static int aac_sa_get_fwstatus(struct aac_softc *sc); 137 static void aac_sa_qnotify(struct aac_softc *sc, int qbit); 138 static int aac_sa_get_istatus(struct aac_softc *sc); 139 static void aac_sa_clear_istatus(struct aac_softc *sc, int mask); 140 static void aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command, 141 u_int32_t arg0, u_int32_t arg1, 142 u_int32_t arg2, u_int32_t arg3); 143 static int aac_sa_get_mailboxstatus(struct aac_softc *sc); 144 static void aac_sa_set_interrupts(struct aac_softc *sc, int enable); 145 146 struct aac_interface aac_sa_interface = { 147 aac_sa_get_fwstatus, 148 aac_sa_qnotify, 149 aac_sa_get_istatus, 150 aac_sa_clear_istatus, 151 aac_sa_set_mailbox, 152 aac_sa_get_mailboxstatus, 153 aac_sa_set_interrupts 154 }; 155 156 /* i960Rx interface */ 157 static int aac_rx_get_fwstatus(struct aac_softc *sc); 158 static void aac_rx_qnotify(struct aac_softc *sc, int qbit); 159 static int aac_rx_get_istatus(struct aac_softc *sc); 160 static void aac_rx_clear_istatus(struct aac_softc *sc, int mask); 161 static void aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command, 162 u_int32_t arg0, u_int32_t arg1, 163 u_int32_t arg2, u_int32_t arg3); 164 static int aac_rx_get_mailboxstatus(struct aac_softc *sc); 165 static void aac_rx_set_interrupts(struct aac_softc *sc, int enable); 166 167 struct aac_interface aac_rx_interface = { 168 aac_rx_get_fwstatus, 169 aac_rx_qnotify, 170 aac_rx_get_istatus, 171 aac_rx_clear_istatus, 172 aac_rx_set_mailbox, 173 aac_rx_get_mailboxstatus, 174 aac_rx_set_interrupts 175 }; 176 177 /* Debugging and Diagnostics */ 178 static void aac_describe_controller(struct aac_softc *sc); 179 static char *aac_describe_code(struct aac_code_lookup *table, 180 u_int32_t code); 181 182 /* Management Interface */ 183 static d_open_t aac_open; 184 static d_close_t aac_close; 185 static d_ioctl_t aac_ioctl; 186 static d_poll_t aac_poll; 187 static int aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib); 188 static void aac_handle_aif(struct aac_softc *sc, 189 struct aac_fib *fib); 190 static int aac_rev_check(struct aac_softc *sc, caddr_t udata); 191 static int aac_getnext_aif(struct aac_softc *sc, caddr_t arg); 192 static int aac_return_aif(struct aac_softc *sc, caddr_t uptr); 193 static int aac_query_disk(struct aac_softc *sc, caddr_t uptr); 194 195 #define AAC_CDEV_MAJOR 150 196 197 static struct cdevsw aac_cdevsw = { 198 aac_open, /* open */ 199 aac_close, /* close */ 200 noread, /* read */ 201 nowrite, /* write */ 202 aac_ioctl, /* ioctl */ 203 aac_poll, /* poll */ 204 nommap, /* mmap */ 205 nostrategy, /* strategy */ 206 "aac", /* name */ 207 AAC_CDEV_MAJOR, /* major */ 208 nodump, /* dump */ 209 nopsize, /* psize */ 210 0, /* flags */ 211 #if __FreeBSD_version < 500005 212 -1, /* bmaj */ 213 #endif 214 }; 215 216 MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for the AAC driver"); 217 218 /* sysctl node */ 219 SYSCTL_NODE(_hw, OID_AUTO, aac, CTLFLAG_RD, 0, "AAC driver parameters"); 220 221 /* 222 * Device Interface 223 */ 224 225 /* 226 * Initialise the controller and softc 227 */ 228 int 229 aac_attach(struct aac_softc *sc) 230 { 231 int error, unit; 232 233 debug_called(1); 234 235 /* 236 * Initialise per-controller queues. 237 */ 238 aac_initq_free(sc); 239 aac_initq_ready(sc); 240 aac_initq_busy(sc); 241 aac_initq_complete(sc); 242 aac_initq_bio(sc); 243 244 #if __FreeBSD_version >= 500005 245 /* 246 * Initialise command-completion task. 247 */ 248 TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc); 249 #endif 250 251 /* disable interrupts before we enable anything */ 252 AAC_MASK_INTERRUPTS(sc); 253 254 /* mark controller as suspended until we get ourselves organised */ 255 sc->aac_state |= AAC_STATE_SUSPEND; 256 257 /* 258 * Allocate command structures. 259 */ 260 if ((error = aac_alloc_commands(sc)) != 0) 261 return(error); 262 263 /* 264 * Initialise the adapter. 265 */ 266 if ((error = aac_init(sc)) != 0) 267 return(error); 268 269 /* 270 * Print a little information about the controller. 271 */ 272 aac_describe_controller(sc); 273 274 /* 275 * Register to probe our containers later. 276 */ 277 TAILQ_INIT(&sc->aac_container_tqh); 278 AAC_LOCK_INIT(&sc->aac_container_lock, "AAC container lock"); 279 280 /* 281 * Lock for the AIF queue 282 */ 283 AAC_LOCK_INIT(&sc->aac_aifq_lock, "AAC AIF lock"); 284 285 sc->aac_ich.ich_func = aac_startup; 286 sc->aac_ich.ich_arg = sc; 287 if (config_intrhook_establish(&sc->aac_ich) != 0) { 288 device_printf(sc->aac_dev, 289 "can't establish configuration hook\n"); 290 return(ENXIO); 291 } 292 293 /* 294 * Make the control device. 295 */ 296 unit = device_get_unit(sc->aac_dev); 297 sc->aac_dev_t = make_dev(&aac_cdevsw, unit, UID_ROOT, GID_WHEEL, 0644, 298 "aac%d", unit); 299 #if __FreeBSD_version > 500005 300 (void)make_dev_alias(sc->aac_dev_t, "afa%d", unit); 301 (void)make_dev_alias(sc->aac_dev_t, "hpn%d", unit); 302 #endif 303 sc->aac_dev_t->si_drv1 = sc; 304 305 /* Create the AIF thread */ 306 #if __FreeBSD_version > 500005 307 if (kthread_create((void(*)(void *))aac_host_command, sc, 308 &sc->aifthread, 0, "aac%daif", unit)) 309 #else 310 if (kthread_create((void(*)(void *))aac_host_command, sc, 311 &sc->aifthread, "aac%daif", unit)) 312 #endif 313 panic("Could not create AIF thread\n"); 314 315 /* Register the shutdown method to only be called post-dump */ 316 if ((EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown, sc->aac_dev, 317 SHUTDOWN_PRI_DEFAULT)) == NULL) 318 device_printf(sc->aac_dev, "shutdown event registration failed\n"); 319 320 return(0); 321 } 322 323 /* 324 * Probe for containers, create disks. 325 */ 326 static void 327 aac_startup(void *arg) 328 { 329 struct aac_softc *sc; 330 struct aac_mntinfo mi; 331 struct aac_mntinforesponse mir; 332 u_int16_t rsize; 333 int i = 0; 334 335 debug_called(1); 336 337 sc = (struct aac_softc *)arg; 338 339 /* disconnect ourselves from the intrhook chain */ 340 config_intrhook_disestablish(&sc->aac_ich); 341 342 /* loop over possible containers */ 343 mi.Command = VM_NameServe; 344 mi.MntType = FT_FILESYS; 345 do { 346 /* request information on this container */ 347 mi.MntCount = i; 348 rsize = sizeof(mir); 349 if (aac_sync_fib(sc, ContainerCommand, 0, &mi, 350 sizeof(struct aac_mntinfo), &mir, &rsize)) { 351 debug(2, "error probing container %d", i); 352 continue; 353 } 354 /* check response size */ 355 if (rsize != sizeof(mir)) { 356 debug(2, "container info response wrong size " 357 "(%d should be %d)", rsize, sizeof(mir)); 358 continue; 359 } 360 361 aac_add_container(sc, &mir, 0); 362 i++; 363 } while ((i < mir.MntRespCount) && (i < AAC_MAX_CONTAINERS)); 364 365 /* poke the bus to actually attach the child devices */ 366 if (bus_generic_attach(sc->aac_dev)) 367 device_printf(sc->aac_dev, "bus_generic_attach failed\n"); 368 369 /* mark the controller up */ 370 sc->aac_state &= ~AAC_STATE_SUSPEND; 371 372 /* enable interrupts now */ 373 AAC_UNMASK_INTERRUPTS(sc); 374 375 /* enable the timeout watchdog */ 376 timeout((timeout_t*)aac_timeout, sc, AAC_PERIODIC_INTERVAL * hz); 377 } 378 379 /* 380 * Create a device to respresent a new container 381 */ 382 static void 383 aac_add_container(struct aac_softc *sc, struct aac_mntinforesponse *mir, int f) 384 { 385 struct aac_container *co; 386 device_t child; 387 388 /* 389 * Check container volume type for validity. Note that many of 390 * the possible types may never show up. 391 */ 392 if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) { 393 MALLOC(co, struct aac_container *, sizeof *co, M_AACBUF, 394 M_NOWAIT); 395 if (co == NULL) 396 panic("Out of memory?!\n"); 397 debug(1, "id %x name '%.16s' size %u type %d", 398 mir->MntTable[0].ObjectId, 399 mir->MntTable[0].FileSystemName, 400 mir->MntTable[0].Capacity, mir->MntTable[0].VolType); 401 402 if ((child = device_add_child(sc->aac_dev, NULL, -1)) == NULL) 403 device_printf(sc->aac_dev, "device_add_child failed\n"); 404 else 405 device_set_ivars(child, co); 406 device_set_desc(child, aac_describe_code(aac_container_types, 407 mir->MntTable[0].VolType)); 408 co->co_disk = child; 409 co->co_found = f; 410 bcopy(&mir->MntTable[0], &co->co_mntobj, 411 sizeof(struct aac_mntobj)); 412 AAC_LOCK_AQUIRE(&sc->aac_container_lock); 413 TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link); 414 AAC_LOCK_RELEASE(&sc->aac_container_lock); 415 } 416 } 417 418 /* 419 * Free all of the resources associated with (sc) 420 * 421 * Should not be called if the controller is active. 422 */ 423 void 424 aac_free(struct aac_softc *sc) 425 { 426 debug_called(1); 427 428 /* remove the control device */ 429 if (sc->aac_dev_t != NULL) 430 destroy_dev(sc->aac_dev_t); 431 432 /* throw away any FIB buffers, discard the FIB DMA tag */ 433 if (sc->aac_fibs != NULL) 434 aac_free_commands(sc); 435 if (sc->aac_fib_dmat) 436 bus_dma_tag_destroy(sc->aac_fib_dmat); 437 438 /* destroy the common area */ 439 if (sc->aac_common) { 440 bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap); 441 bus_dmamem_free(sc->aac_common_dmat, sc->aac_common, 442 sc->aac_common_dmamap); 443 } 444 if (sc->aac_common_dmat) 445 bus_dma_tag_destroy(sc->aac_common_dmat); 446 447 /* disconnect the interrupt handler */ 448 if (sc->aac_intr) 449 bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr); 450 if (sc->aac_irq != NULL) 451 bus_release_resource(sc->aac_dev, SYS_RES_IRQ, sc->aac_irq_rid, 452 sc->aac_irq); 453 454 /* destroy data-transfer DMA tag */ 455 if (sc->aac_buffer_dmat) 456 bus_dma_tag_destroy(sc->aac_buffer_dmat); 457 458 /* destroy the parent DMA tag */ 459 if (sc->aac_parent_dmat) 460 bus_dma_tag_destroy(sc->aac_parent_dmat); 461 462 /* release the register window mapping */ 463 if (sc->aac_regs_resource != NULL) 464 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY, 465 sc->aac_regs_rid, sc->aac_regs_resource); 466 } 467 468 /* 469 * Disconnect from the controller completely, in preparation for unload. 470 */ 471 int 472 aac_detach(device_t dev) 473 { 474 struct aac_softc *sc; 475 #if AAC_BROKEN 476 int error; 477 #endif 478 479 debug_called(1); 480 481 sc = device_get_softc(dev); 482 483 if (sc->aac_state & AAC_STATE_OPEN) 484 return(EBUSY); 485 486 #if AAC_BROKEN 487 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) { 488 sc->aifflags |= AAC_AIFFLAGS_EXIT; 489 wakeup(sc->aifthread); 490 tsleep(sc->aac_dev, PUSER | PCATCH, "aacdch", 30 * hz); 491 } 492 493 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) 494 panic("Cannot shutdown AIF thread\n"); 495 496 if ((error = aac_shutdown(dev))) 497 return(error); 498 499 aac_free(sc); 500 501 return(0); 502 #else 503 return (EBUSY); 504 #endif 505 } 506 507 /* 508 * Bring the controller down to a dormant state and detach all child devices. 509 * 510 * This function is called before detach or system shutdown. 511 * 512 * Note that we can assume that the bioq on the controller is empty, as we won't 513 * allow shutdown if any device is open. 514 */ 515 int 516 aac_shutdown(device_t dev) 517 { 518 struct aac_softc *sc; 519 struct aac_close_command cc; 520 int s, i; 521 522 debug_called(1); 523 524 sc = device_get_softc(dev); 525 526 s = splbio(); 527 528 sc->aac_state |= AAC_STATE_SUSPEND; 529 530 /* 531 * Send a Container shutdown followed by a HostShutdown FIB to the 532 * controller to convince it that we don't want to talk to it anymore. 533 * We've been closed and all I/O completed already 534 */ 535 device_printf(sc->aac_dev, "shutting down controller..."); 536 537 cc.Command = VM_CloseAll; 538 cc.ContainerId = 0xffffffff; 539 if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc), NULL, NULL)) 540 printf("FAILED.\n"); 541 else { 542 i = 0; 543 /* 544 * XXX Issuing this command to the controller makes it shut down 545 * but also keeps it from coming back up without a reset of the 546 * PCI bus. This is not desirable if you are just unloading the 547 * driver module with the intent to reload it later. 548 */ 549 if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN, &i, 550 sizeof(i), NULL, NULL)) { 551 printf("FAILED.\n"); 552 } else { 553 printf("done.\n"); 554 } 555 } 556 557 AAC_MASK_INTERRUPTS(sc); 558 559 splx(s); 560 return(0); 561 } 562 563 /* 564 * Bring the controller to a quiescent state, ready for system suspend. 565 */ 566 int 567 aac_suspend(device_t dev) 568 { 569 struct aac_softc *sc; 570 int s; 571 572 debug_called(1); 573 574 sc = device_get_softc(dev); 575 576 s = splbio(); 577 578 sc->aac_state |= AAC_STATE_SUSPEND; 579 580 AAC_MASK_INTERRUPTS(sc); 581 splx(s); 582 return(0); 583 } 584 585 /* 586 * Bring the controller back to a state ready for operation. 587 */ 588 int 589 aac_resume(device_t dev) 590 { 591 struct aac_softc *sc; 592 593 debug_called(1); 594 595 sc = device_get_softc(dev); 596 597 sc->aac_state &= ~AAC_STATE_SUSPEND; 598 AAC_UNMASK_INTERRUPTS(sc); 599 return(0); 600 } 601 602 /* 603 * Take an interrupt. 604 */ 605 void 606 aac_intr(void *arg) 607 { 608 struct aac_softc *sc; 609 u_int16_t reason; 610 611 debug_called(2); 612 613 sc = (struct aac_softc *)arg; 614 615 reason = AAC_GET_ISTATUS(sc); 616 617 /* controller wants to talk to the log */ 618 if (reason & AAC_DB_PRINTF) { 619 AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF); 620 aac_print_printf(sc); 621 } 622 623 /* controller has a message for us? */ 624 if (reason & AAC_DB_COMMAND_READY) { 625 AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_READY); 626 /* XXX What happens if the thread is already awake? */ 627 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) { 628 sc->aifflags |= AAC_AIFFLAGS_PENDING; 629 wakeup(sc->aifthread); 630 } 631 } 632 633 /* controller has a response for us? */ 634 if (reason & AAC_DB_RESPONSE_READY) { 635 AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY); 636 aac_host_response(sc); 637 } 638 639 /* 640 * spurious interrupts that we don't use - reset the mask and clear the 641 * interrupts 642 */ 643 if (reason & (AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL)) { 644 AAC_UNMASK_INTERRUPTS(sc); 645 AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_NOT_FULL | 646 AAC_DB_RESPONSE_NOT_FULL); 647 } 648 }; 649 650 /* 651 * Command Processing 652 */ 653 654 /* 655 * Start as much queued I/O as possible on the controller 656 */ 657 static void 658 aac_startio(struct aac_softc *sc) 659 { 660 struct aac_command *cm; 661 662 debug_called(2); 663 664 for (;;) { 665 /* 666 * Try to get a command that's been put off for lack of 667 * resources 668 */ 669 cm = aac_dequeue_ready(sc); 670 671 /* 672 * Try to build a command off the bio queue (ignore error 673 * return) 674 */ 675 if (cm == NULL) 676 aac_bio_command(sc, &cm); 677 678 /* nothing to do? */ 679 if (cm == NULL) 680 break; 681 682 /* try to give the command to the controller */ 683 if (aac_start(cm) == EBUSY) { 684 /* put it on the ready queue for later */ 685 aac_requeue_ready(cm); 686 break; 687 } 688 } 689 } 690 691 /* 692 * Deliver a command to the controller; allocate controller resources at the 693 * last moment when possible. 694 */ 695 static int 696 aac_start(struct aac_command *cm) 697 { 698 struct aac_softc *sc; 699 int error; 700 701 debug_called(2); 702 703 sc = cm->cm_sc; 704 705 /* get the command mapped */ 706 aac_map_command(cm); 707 708 /* fix up the address values in the FIB */ 709 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib; 710 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys; 711 712 /* save a pointer to the command for speedy reverse-lookup */ 713 cm->cm_fib->Header.SenderData = (u_int32_t)cm; /* XXX 64-bit physical 714 * address issue */ 715 716 /* put the FIB on the outbound queue */ 717 error = aac_enqueue_fib(sc, cm->cm_queue, cm); 718 return(error); 719 } 720 721 /* 722 * Handle notification of one or more FIBs coming from the controller. 723 */ 724 static void 725 aac_host_command(struct aac_softc *sc) 726 { 727 struct aac_fib *fib; 728 u_int32_t fib_size; 729 int size; 730 731 debug_called(2); 732 733 sc->aifflags |= AAC_AIFFLAGS_RUNNING; 734 735 while (!(sc->aifflags & AAC_AIFFLAGS_EXIT)) { 736 if (!(sc->aifflags & AAC_AIFFLAGS_PENDING)) 737 tsleep(sc->aifthread, PRIBIO, "aifthd", 15 * hz); 738 739 sc->aifflags &= ~AAC_AIFFLAGS_PENDING; 740 for (;;) { 741 if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, 742 &fib_size, &fib)) 743 break; /* nothing to do */ 744 745 AAC_PRINT_FIB(sc, fib); 746 747 switch (fib->Header.Command) { 748 case AifRequest: 749 aac_handle_aif(sc, fib); 750 break; 751 default: 752 device_printf(sc->aac_dev, "unknown command " 753 "from controller\n"); 754 break; 755 } 756 757 /* Return the AIF to the controller. */ 758 if ((fib->Header.XferState == 0) || 759 (fib->Header.StructType != AAC_FIBTYPE_TFIB)) 760 break; 761 762 if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) { 763 fib->Header.XferState |= AAC_FIBSTATE_DONEHOST; 764 *(AAC_FSAStatus*)fib->data = ST_OK; 765 766 /* XXX Compute the Size field? */ 767 size = fib->Header.Size; 768 if (size > sizeof(struct aac_fib)) { 769 size = sizeof(struct aac_fib); 770 fib->Header.Size = size; 771 } 772 /* 773 * Since we did not generate this command, it 774 * cannot go through the normal 775 * enqueue->startio chain. 776 */ 777 aac_enqueue_response(sc, 778 AAC_ADAP_NORM_RESP_QUEUE, 779 fib); 780 } 781 } 782 } 783 sc->aifflags &= ~AAC_AIFFLAGS_RUNNING; 784 wakeup(sc->aac_dev); 785 786 #if __FreeBSD_version > 500005 787 mtx_lock(&Giant); 788 #endif 789 kthread_exit(0); 790 } 791 792 /* 793 * Handle notification of one or more FIBs completed by the controller 794 */ 795 static void 796 aac_host_response(struct aac_softc *sc) 797 { 798 struct aac_command *cm; 799 struct aac_fib *fib; 800 u_int32_t fib_size; 801 802 debug_called(2); 803 804 for (;;) { 805 /* look for completed FIBs on our queue */ 806 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size, 807 &fib)) 808 break; /* nothing to do */ 809 810 /* get the command, unmap and queue for later processing */ 811 cm = (struct aac_command *)fib->Header.SenderData; 812 if (cm == NULL) { 813 AAC_PRINT_FIB(sc, fib); 814 } else { 815 aac_remove_busy(cm); 816 aac_unmap_command(cm); /* XXX defer? */ 817 aac_enqueue_complete(cm); 818 } 819 } 820 821 /* handle completion processing */ 822 #if __FreeBSD_version >= 500005 823 taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete); 824 #else 825 aac_complete(sc, 0); 826 #endif 827 } 828 829 /* 830 * Process completed commands. 831 */ 832 static void 833 aac_complete(void *context, int pending) 834 { 835 struct aac_softc *sc; 836 struct aac_command *cm; 837 838 debug_called(2); 839 840 sc = (struct aac_softc *)context; 841 842 /* pull completed commands off the queue */ 843 for (;;) { 844 cm = aac_dequeue_complete(sc); 845 if (cm == NULL) 846 break; 847 cm->cm_flags |= AAC_CMD_COMPLETED; 848 849 /* is there a completion handler? */ 850 if (cm->cm_complete != NULL) { 851 cm->cm_complete(cm); 852 } else { 853 /* assume that someone is sleeping on this command */ 854 wakeup(cm); 855 } 856 } 857 858 /* see if we can start some more I/O */ 859 aac_startio(sc); 860 } 861 862 /* 863 * Handle a bio submitted from a disk device. 864 */ 865 void 866 aac_submit_bio(struct bio *bp) 867 { 868 struct aac_disk *ad; 869 struct aac_softc *sc; 870 871 debug_called(2); 872 873 ad = (struct aac_disk *)bp->bio_dev->si_drv1; 874 sc = ad->ad_controller; 875 876 /* queue the BIO and try to get some work done */ 877 aac_enqueue_bio(sc, bp); 878 aac_startio(sc); 879 } 880 881 /* 882 * Get a bio and build a command to go with it. 883 */ 884 static int 885 aac_bio_command(struct aac_softc *sc, struct aac_command **cmp) 886 { 887 struct aac_command *cm; 888 struct aac_fib *fib; 889 struct aac_blockread *br; 890 struct aac_blockwrite *bw; 891 struct aac_disk *ad; 892 struct bio *bp; 893 894 debug_called(2); 895 896 /* get the resources we will need */ 897 cm = NULL; 898 if ((bp = aac_dequeue_bio(sc)) == NULL) 899 goto fail; 900 if (aac_alloc_command(sc, &cm)) /* get a command */ 901 goto fail; 902 903 /* fill out the command */ 904 cm->cm_data = (void *)bp->bio_data; 905 cm->cm_datalen = bp->bio_bcount; 906 cm->cm_complete = aac_bio_complete; 907 cm->cm_private = bp; 908 cm->cm_timestamp = time_second; 909 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; 910 911 /* build the FIB */ 912 fib = cm->cm_fib; 913 fib->Header.XferState = 914 AAC_FIBSTATE_HOSTOWNED | 915 AAC_FIBSTATE_INITIALISED | 916 AAC_FIBSTATE_FROMHOST | 917 AAC_FIBSTATE_REXPECTED | 918 AAC_FIBSTATE_NORM; 919 fib->Header.Command = ContainerCommand; 920 fib->Header.Size = sizeof(struct aac_fib_header); 921 922 /* build the read/write request */ 923 ad = (struct aac_disk *)bp->bio_dev->si_drv1; 924 if (BIO_IS_READ(bp)) { 925 br = (struct aac_blockread *)&fib->data[0]; 926 br->Command = VM_CtBlockRead; 927 br->ContainerId = ad->ad_container->co_mntobj.ObjectId; 928 br->BlockNumber = bp->bio_pblkno; 929 br->ByteCount = bp->bio_bcount; 930 fib->Header.Size += sizeof(struct aac_blockread); 931 cm->cm_sgtable = &br->SgMap; 932 cm->cm_flags |= AAC_CMD_DATAIN; 933 } else { 934 bw = (struct aac_blockwrite *)&fib->data[0]; 935 bw->Command = VM_CtBlockWrite; 936 bw->ContainerId = ad->ad_container->co_mntobj.ObjectId; 937 bw->BlockNumber = bp->bio_pblkno; 938 bw->ByteCount = bp->bio_bcount; 939 bw->Stable = CUNSTABLE; /* XXX what's appropriate here? */ 940 fib->Header.Size += sizeof(struct aac_blockwrite); 941 cm->cm_flags |= AAC_CMD_DATAOUT; 942 cm->cm_sgtable = &bw->SgMap; 943 } 944 945 *cmp = cm; 946 return(0); 947 948 fail: 949 if (bp != NULL) 950 aac_enqueue_bio(sc, bp); 951 if (cm != NULL) 952 aac_release_command(cm); 953 return(ENOMEM); 954 } 955 956 /* 957 * Handle a bio-instigated command that has been completed. 958 */ 959 static void 960 aac_bio_complete(struct aac_command *cm) 961 { 962 struct aac_blockread_response *brr; 963 struct aac_blockwrite_response *bwr; 964 struct bio *bp; 965 AAC_FSAStatus status; 966 967 /* fetch relevant status and then release the command */ 968 bp = (struct bio *)cm->cm_private; 969 if (BIO_IS_READ(bp)) { 970 brr = (struct aac_blockread_response *)&cm->cm_fib->data[0]; 971 status = brr->Status; 972 } else { 973 bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0]; 974 status = bwr->Status; 975 } 976 aac_release_command(cm); 977 978 /* fix up the bio based on status */ 979 if (status == ST_OK) { 980 bp->bio_resid = 0; 981 } else { 982 bp->bio_error = EIO; 983 bp->bio_flags |= BIO_ERROR; 984 /* pass an error string out to the disk layer */ 985 bp->bio_driver1 = aac_describe_code(aac_command_status_table, 986 status); 987 } 988 aac_biodone(bp); 989 } 990 991 /* 992 * Dump a block of data to the controller. If the queue is full, tell the 993 * caller to hold off and wait for the queue to drain. 994 */ 995 int 996 aac_dump_enqueue(struct aac_disk *ad, u_int32_t lba, void *data, int dumppages) 997 { 998 struct aac_softc *sc; 999 struct aac_command *cm; 1000 struct aac_fib *fib; 1001 struct aac_blockwrite *bw; 1002 1003 sc = ad->ad_controller; 1004 cm = NULL; 1005 1006 if (aac_alloc_command(sc, &cm)) 1007 return (EBUSY); 1008 1009 /* fill out the command */ 1010 cm->cm_data = data; 1011 cm->cm_datalen = dumppages * PAGE_SIZE; 1012 cm->cm_complete = NULL; 1013 cm->cm_private = NULL; 1014 cm->cm_timestamp = time_second; 1015 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; 1016 1017 /* build the FIB */ 1018 fib = cm->cm_fib; 1019 fib->Header.XferState = 1020 AAC_FIBSTATE_HOSTOWNED | 1021 AAC_FIBSTATE_INITIALISED | 1022 AAC_FIBSTATE_FROMHOST | 1023 AAC_FIBSTATE_REXPECTED | 1024 AAC_FIBSTATE_NORM; 1025 fib->Header.Command = ContainerCommand; 1026 fib->Header.Size = sizeof(struct aac_fib_header); 1027 1028 bw = (struct aac_blockwrite *)&fib->data[0]; 1029 bw->Command = VM_CtBlockWrite; 1030 bw->ContainerId = ad->ad_container->co_mntobj.ObjectId; 1031 bw->BlockNumber = lba; 1032 bw->ByteCount = dumppages * PAGE_SIZE; 1033 bw->Stable = CUNSTABLE; /* XXX what's appropriate here? */ 1034 fib->Header.Size += sizeof(struct aac_blockwrite); 1035 cm->cm_flags |= AAC_CMD_DATAOUT; 1036 cm->cm_sgtable = &bw->SgMap; 1037 1038 return (aac_start(cm)); 1039 } 1040 1041 /* 1042 * Wait for the card's queue to drain when dumping. Also check for monitor 1043 * printf's 1044 */ 1045 void 1046 aac_dump_complete(struct aac_softc *sc) 1047 { 1048 struct aac_fib *fib; 1049 struct aac_command *cm; 1050 u_int16_t reason; 1051 u_int32_t pi, ci, fib_size; 1052 1053 do { 1054 reason = AAC_GET_ISTATUS(sc); 1055 if (reason & AAC_DB_RESPONSE_READY) { 1056 AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY); 1057 for (;;) { 1058 if (aac_dequeue_fib(sc, 1059 AAC_HOST_NORM_RESP_QUEUE, 1060 &fib_size, &fib)) 1061 break; 1062 cm = (struct aac_command *) 1063 fib->Header.SenderData; 1064 if (cm == NULL) 1065 AAC_PRINT_FIB(sc, fib); 1066 else { 1067 aac_remove_busy(cm); 1068 aac_unmap_command(cm); 1069 aac_enqueue_complete(cm); 1070 aac_release_command(cm); 1071 } 1072 } 1073 } 1074 if (reason & AAC_DB_PRINTF) { 1075 AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF); 1076 aac_print_printf(sc); 1077 } 1078 pi = sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][ 1079 AAC_PRODUCER_INDEX]; 1080 ci = sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][ 1081 AAC_CONSUMER_INDEX]; 1082 } while (ci != pi); 1083 1084 return; 1085 } 1086 1087 /* 1088 * Submit a command to the controller, return when it completes. 1089 * XXX This is very dangerous! If the card has gone out to lunch, we could 1090 * be stuck here forever. At the same time, signals are not caught 1091 * because there is a risk that a signal could wakeup the tsleep before 1092 * the card has a chance to complete the command. The passed in timeout 1093 * is ignored for the same reason. Since there is no way to cancel a 1094 * command in progress, we should probably create a 'dead' queue where 1095 * commands go that have been interrupted/timed-out/etc, that keeps them 1096 * out of the free pool. That way, if the card is just slow, it won't 1097 * spam the memory of a command that has been recycled. 1098 */ 1099 static int 1100 aac_wait_command(struct aac_command *cm, int timeout) 1101 { 1102 int s, error = 0; 1103 1104 debug_called(2); 1105 1106 /* Put the command on the ready queue and get things going */ 1107 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; 1108 aac_enqueue_ready(cm); 1109 aac_startio(cm->cm_sc); 1110 s = splbio(); 1111 while (!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) { 1112 error = tsleep(cm, PRIBIO, "aacwait", 0); 1113 } 1114 splx(s); 1115 return(error); 1116 } 1117 1118 /* 1119 *Command Buffer Management 1120 */ 1121 1122 /* 1123 * Allocate a command. 1124 */ 1125 static int 1126 aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp) 1127 { 1128 struct aac_command *cm; 1129 1130 debug_called(3); 1131 1132 if ((cm = aac_dequeue_free(sc)) == NULL) 1133 return(ENOMEM); 1134 1135 *cmp = cm; 1136 return(0); 1137 } 1138 1139 /* 1140 * Release a command back to the freelist. 1141 */ 1142 static void 1143 aac_release_command(struct aac_command *cm) 1144 { 1145 debug_called(3); 1146 1147 /* (re)initialise the command/FIB */ 1148 cm->cm_sgtable = NULL; 1149 cm->cm_flags = 0; 1150 cm->cm_complete = NULL; 1151 cm->cm_private = NULL; 1152 cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY; 1153 cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB; 1154 cm->cm_fib->Header.Flags = 0; 1155 cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib); 1156 1157 /* 1158 * These are duplicated in aac_start to cover the case where an 1159 * intermediate stage may have destroyed them. They're left 1160 * initialised here for debugging purposes only. 1161 */ 1162 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib; 1163 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys; 1164 1165 aac_enqueue_free(cm); 1166 } 1167 1168 /* 1169 * Map helper for command/FIB allocation. 1170 */ 1171 static void 1172 aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1173 { 1174 struct aac_softc *sc; 1175 1176 sc = (struct aac_softc *)arg; 1177 1178 debug_called(3); 1179 1180 sc->aac_fibphys = segs[0].ds_addr; 1181 } 1182 1183 /* 1184 * Allocate and initialise commands/FIBs for this adapter. 1185 */ 1186 static int 1187 aac_alloc_commands(struct aac_softc *sc) 1188 { 1189 struct aac_command *cm; 1190 int i; 1191 1192 debug_called(1); 1193 1194 /* allocate the FIBs in DMAable memory and load them */ 1195 if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&sc->aac_fibs, 1196 BUS_DMA_NOWAIT, &sc->aac_fibmap)) { 1197 return(ENOMEM); 1198 } 1199 bus_dmamap_load(sc->aac_fib_dmat, sc->aac_fibmap, sc->aac_fibs, 1200 AAC_FIB_COUNT * sizeof(struct aac_fib), 1201 aac_map_command_helper, sc, 0); 1202 1203 /* initialise constant fields in the command structure */ 1204 for (i = 0; i < AAC_FIB_COUNT; i++) { 1205 cm = &sc->aac_command[i]; 1206 cm->cm_sc = sc; 1207 cm->cm_fib = sc->aac_fibs + i; 1208 cm->cm_fibphys = sc->aac_fibphys + (i * sizeof(struct aac_fib)); 1209 1210 if (!bus_dmamap_create(sc->aac_buffer_dmat, 0, &cm->cm_datamap)) 1211 aac_release_command(cm); 1212 } 1213 return(0); 1214 } 1215 1216 /* 1217 * Free FIBs owned by this adapter. 1218 */ 1219 static void 1220 aac_free_commands(struct aac_softc *sc) 1221 { 1222 int i; 1223 1224 debug_called(1); 1225 1226 for (i = 0; i < AAC_FIB_COUNT; i++) 1227 bus_dmamap_destroy(sc->aac_buffer_dmat, 1228 sc->aac_command[i].cm_datamap); 1229 1230 bus_dmamap_unload(sc->aac_fib_dmat, sc->aac_fibmap); 1231 bus_dmamem_free(sc->aac_fib_dmat, sc->aac_fibs, sc->aac_fibmap); 1232 } 1233 1234 /* 1235 * Command-mapping helper function - populate this command's s/g table. 1236 */ 1237 static void 1238 aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1239 { 1240 struct aac_command *cm; 1241 struct aac_fib *fib; 1242 struct aac_sg_table *sg; 1243 int i; 1244 1245 debug_called(3); 1246 1247 cm = (struct aac_command *)arg; 1248 fib = cm->cm_fib; 1249 1250 /* find the s/g table */ 1251 sg = cm->cm_sgtable; 1252 1253 /* copy into the FIB */ 1254 if (sg != NULL) { 1255 sg->SgCount = nseg; 1256 for (i = 0; i < nseg; i++) { 1257 sg->SgEntry[i].SgAddress = segs[i].ds_addr; 1258 sg->SgEntry[i].SgByteCount = segs[i].ds_len; 1259 } 1260 /* update the FIB size for the s/g count */ 1261 fib->Header.Size += nseg * sizeof(struct aac_sg_entry); 1262 } 1263 1264 } 1265 1266 /* 1267 * Map a command into controller-visible space. 1268 */ 1269 static void 1270 aac_map_command(struct aac_command *cm) 1271 { 1272 struct aac_softc *sc; 1273 1274 debug_called(2); 1275 1276 sc = cm->cm_sc; 1277 1278 /* don't map more than once */ 1279 if (cm->cm_flags & AAC_CMD_MAPPED) 1280 return; 1281 1282 if (cm->cm_datalen != 0) { 1283 bus_dmamap_load(sc->aac_buffer_dmat, cm->cm_datamap, 1284 cm->cm_data, cm->cm_datalen, 1285 aac_map_command_sg, cm, 0); 1286 1287 if (cm->cm_flags & AAC_CMD_DATAIN) 1288 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, 1289 BUS_DMASYNC_PREREAD); 1290 if (cm->cm_flags & AAC_CMD_DATAOUT) 1291 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, 1292 BUS_DMASYNC_PREWRITE); 1293 } 1294 cm->cm_flags |= AAC_CMD_MAPPED; 1295 } 1296 1297 /* 1298 * Unmap a command from controller-visible space. 1299 */ 1300 static void 1301 aac_unmap_command(struct aac_command *cm) 1302 { 1303 struct aac_softc *sc; 1304 1305 debug_called(2); 1306 1307 sc = cm->cm_sc; 1308 1309 if (!(cm->cm_flags & AAC_CMD_MAPPED)) 1310 return; 1311 1312 if (cm->cm_datalen != 0) { 1313 if (cm->cm_flags & AAC_CMD_DATAIN) 1314 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, 1315 BUS_DMASYNC_POSTREAD); 1316 if (cm->cm_flags & AAC_CMD_DATAOUT) 1317 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, 1318 BUS_DMASYNC_POSTWRITE); 1319 1320 bus_dmamap_unload(sc->aac_buffer_dmat, cm->cm_datamap); 1321 } 1322 cm->cm_flags &= ~AAC_CMD_MAPPED; 1323 } 1324 1325 /* 1326 * Hardware Interface 1327 */ 1328 1329 /* 1330 * Initialise the adapter. 1331 */ 1332 static void 1333 aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1334 { 1335 struct aac_softc *sc; 1336 1337 debug_called(1); 1338 1339 sc = (struct aac_softc *)arg; 1340 1341 sc->aac_common_busaddr = segs[0].ds_addr; 1342 } 1343 1344 static int 1345 aac_init(struct aac_softc *sc) 1346 { 1347 struct aac_adapter_init *ip; 1348 time_t then; 1349 u_int32_t code; 1350 u_int8_t *qaddr; 1351 1352 debug_called(1); 1353 1354 /* 1355 * First wait for the adapter to come ready. 1356 */ 1357 then = time_second; 1358 do { 1359 code = AAC_GET_FWSTATUS(sc); 1360 if (code & AAC_SELF_TEST_FAILED) { 1361 device_printf(sc->aac_dev, "FATAL: selftest failed\n"); 1362 return(ENXIO); 1363 } 1364 if (code & AAC_KERNEL_PANIC) { 1365 device_printf(sc->aac_dev, 1366 "FATAL: controller kernel panic\n"); 1367 return(ENXIO); 1368 } 1369 if (time_second > (then + AAC_BOOT_TIMEOUT)) { 1370 device_printf(sc->aac_dev, 1371 "FATAL: controller not coming ready, " 1372 "status %x\n", code); 1373 return(ENXIO); 1374 } 1375 } while (!(code & AAC_UP_AND_RUNNING)); 1376 1377 /* 1378 * Create DMA tag for the common structure and allocate it. 1379 */ 1380 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */ 1381 1, 0, /* algnmnt, boundary */ 1382 BUS_SPACE_MAXADDR, /* lowaddr */ 1383 BUS_SPACE_MAXADDR, /* highaddr */ 1384 NULL, NULL, /* filter, filterarg */ 1385 sizeof(struct aac_common), /* maxsize */ 1386 1, /* nsegments */ 1387 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 1388 0, /* flags */ 1389 &sc->aac_common_dmat)) { 1390 device_printf(sc->aac_dev, 1391 "can't allocate common structure DMA tag\n"); 1392 return(ENOMEM); 1393 } 1394 if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common, 1395 BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) { 1396 device_printf(sc->aac_dev, "can't allocate common structure\n"); 1397 return(ENOMEM); 1398 } 1399 bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap, 1400 sc->aac_common, sizeof(*sc->aac_common), aac_common_map, 1401 sc, 0); 1402 bzero(sc->aac_common, sizeof(*sc->aac_common)); 1403 1404 /* 1405 * Fill in the init structure. This tells the adapter about the 1406 * physical location of various important shared data structures. 1407 */ 1408 ip = &sc->aac_common->ac_init; 1409 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION; 1410 1411 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr + 1412 offsetof(struct aac_common, ac_fibs); 1413 ip->AdapterFibsVirtualAddress = &sc->aac_common->ac_fibs[0]; 1414 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib); 1415 ip->AdapterFibAlign = sizeof(struct aac_fib); 1416 1417 ip->PrintfBufferAddress = sc->aac_common_busaddr + 1418 offsetof(struct aac_common, ac_printf); 1419 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE; 1420 1421 ip->HostPhysMemPages = 0; /* not used? */ 1422 ip->HostElapsedSeconds = time_second; /* reset later if invalid */ 1423 1424 /* 1425 * Initialise FIB queues. Note that it appears that the layout of the 1426 * indexes and the segmentation of the entries may be mandated by the 1427 * adapter, which is only told about the base of the queue index fields. 1428 * 1429 * The initial values of the indices are assumed to inform the adapter 1430 * of the sizes of the respective queues, and theoretically it could 1431 * work out the entire layout of the queue structures from this. We 1432 * take the easy route and just lay this area out like everyone else 1433 * does. 1434 * 1435 * The Linux driver uses a much more complex scheme whereby several 1436 * header records are kept for each queue. We use a couple of generic 1437 * list manipulation functions which 'know' the size of each list by 1438 * virtue of a table. 1439 */ 1440 qaddr = &sc->aac_common->ac_qbuf[0] + AAC_QUEUE_ALIGN; 1441 qaddr -= (u_int32_t)qaddr % AAC_QUEUE_ALIGN; 1442 sc->aac_queues = (struct aac_queue_table *)qaddr; 1443 ip->CommHeaderAddress = sc->aac_common_busaddr + 1444 ((u_int32_t)sc->aac_queues - 1445 (u_int32_t)sc->aac_common); 1446 bzero(sc->aac_queues, sizeof(struct aac_queue_table)); 1447 1448 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1449 AAC_HOST_NORM_CMD_ENTRIES; 1450 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1451 AAC_HOST_NORM_CMD_ENTRIES; 1452 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1453 AAC_HOST_HIGH_CMD_ENTRIES; 1454 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1455 AAC_HOST_HIGH_CMD_ENTRIES; 1456 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1457 AAC_ADAP_NORM_CMD_ENTRIES; 1458 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1459 AAC_ADAP_NORM_CMD_ENTRIES; 1460 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1461 AAC_ADAP_HIGH_CMD_ENTRIES; 1462 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1463 AAC_ADAP_HIGH_CMD_ENTRIES; 1464 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1465 AAC_HOST_NORM_RESP_ENTRIES; 1466 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1467 AAC_HOST_NORM_RESP_ENTRIES; 1468 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1469 AAC_HOST_HIGH_RESP_ENTRIES; 1470 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1471 AAC_HOST_HIGH_RESP_ENTRIES; 1472 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1473 AAC_ADAP_NORM_RESP_ENTRIES; 1474 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1475 AAC_ADAP_NORM_RESP_ENTRIES; 1476 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1477 AAC_ADAP_HIGH_RESP_ENTRIES; 1478 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1479 AAC_ADAP_HIGH_RESP_ENTRIES; 1480 sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] = 1481 &sc->aac_queues->qt_HostNormCmdQueue[0]; 1482 sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] = 1483 &sc->aac_queues->qt_HostHighCmdQueue[0]; 1484 sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] = 1485 &sc->aac_queues->qt_AdapNormCmdQueue[0]; 1486 sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] = 1487 &sc->aac_queues->qt_AdapHighCmdQueue[0]; 1488 sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] = 1489 &sc->aac_queues->qt_HostNormRespQueue[0]; 1490 sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] = 1491 &sc->aac_queues->qt_HostHighRespQueue[0]; 1492 sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] = 1493 &sc->aac_queues->qt_AdapNormRespQueue[0]; 1494 sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] = 1495 &sc->aac_queues->qt_AdapHighRespQueue[0]; 1496 1497 /* 1498 * Do controller-type-specific initialisation 1499 */ 1500 switch (sc->aac_hwif) { 1501 case AAC_HWIF_I960RX: 1502 AAC_SETREG4(sc, AAC_RX_ODBR, ~0); 1503 break; 1504 } 1505 1506 /* 1507 * Give the init structure to the controller. 1508 */ 1509 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT, 1510 sc->aac_common_busaddr + 1511 offsetof(struct aac_common, ac_init), 0, 0, 0, 1512 NULL)) { 1513 device_printf(sc->aac_dev, 1514 "error establishing init structure\n"); 1515 return(EIO); 1516 } 1517 1518 return(0); 1519 } 1520 1521 /* 1522 * Send a synchronous command to the controller and wait for a result. 1523 */ 1524 static int 1525 aac_sync_command(struct aac_softc *sc, u_int32_t command, 1526 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, 1527 u_int32_t *sp) 1528 { 1529 time_t then; 1530 u_int32_t status; 1531 1532 debug_called(3); 1533 1534 /* populate the mailbox */ 1535 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3); 1536 1537 /* ensure the sync command doorbell flag is cleared */ 1538 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1539 1540 /* then set it to signal the adapter */ 1541 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND); 1542 1543 /* spin waiting for the command to complete */ 1544 then = time_second; 1545 do { 1546 if (time_second > (then + AAC_IMMEDIATE_TIMEOUT)) { 1547 debug(2, "timed out"); 1548 return(EIO); 1549 } 1550 } while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND)); 1551 1552 /* clear the completion flag */ 1553 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1554 1555 /* get the command status */ 1556 status = AAC_GET_MAILBOXSTATUS(sc); 1557 if (sp != NULL) 1558 *sp = status; 1559 return(0); 1560 } 1561 1562 /* 1563 * Send a synchronous FIB to the controller and wait for a result. 1564 */ 1565 static int 1566 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate, 1567 void *data, u_int16_t datasize, 1568 void *result, u_int16_t *resultsize) 1569 { 1570 struct aac_fib *fib; 1571 1572 debug_called(3); 1573 1574 fib = &sc->aac_common->ac_sync_fib; 1575 1576 if (datasize > AAC_FIB_DATASIZE) 1577 return(EINVAL); 1578 1579 /* 1580 * Set up the sync FIB 1581 */ 1582 fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED | 1583 AAC_FIBSTATE_INITIALISED | 1584 AAC_FIBSTATE_EMPTY; 1585 fib->Header.XferState |= xferstate; 1586 fib->Header.Command = command; 1587 fib->Header.StructType = AAC_FIBTYPE_TFIB; 1588 fib->Header.Size = sizeof(struct aac_fib) + datasize; 1589 fib->Header.SenderSize = sizeof(struct aac_fib); 1590 fib->Header.SenderFibAddress = (u_int32_t)fib; 1591 fib->Header.ReceiverFibAddress = sc->aac_common_busaddr + 1592 offsetof(struct aac_common, 1593 ac_sync_fib); 1594 1595 /* 1596 * Copy in data. 1597 */ 1598 if (data != NULL) { 1599 KASSERT(datasize <= sizeof(fib->data), 1600 ("aac_sync_fib: datasize to large")); 1601 bcopy(data, fib->data, datasize); 1602 fib->Header.XferState |= AAC_FIBSTATE_FROMHOST | 1603 AAC_FIBSTATE_NORM; 1604 } 1605 1606 /* 1607 * Give the FIB to the controller, wait for a response. 1608 */ 1609 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, 1610 fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) { 1611 debug(2, "IO error"); 1612 return(EIO); 1613 } 1614 1615 /* 1616 * Copy out the result 1617 */ 1618 if (result != NULL) { 1619 u_int copysize; 1620 1621 copysize = fib->Header.Size - sizeof(struct aac_fib_header); 1622 if (copysize > *resultsize) 1623 copysize = *resultsize; 1624 *resultsize = fib->Header.Size - sizeof(struct aac_fib_header); 1625 bcopy(fib->data, result, copysize); 1626 } 1627 return(0); 1628 } 1629 1630 /* 1631 * Adapter-space FIB queue manipulation 1632 * 1633 * Note that the queue implementation here is a little funky; neither the PI or 1634 * CI will ever be zero. This behaviour is a controller feature. 1635 */ 1636 static struct { 1637 int size; 1638 int notify; 1639 } aac_qinfo[] = { 1640 {AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL}, 1641 {AAC_HOST_HIGH_CMD_ENTRIES, 0}, 1642 {AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY}, 1643 {AAC_ADAP_HIGH_CMD_ENTRIES, 0}, 1644 {AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL}, 1645 {AAC_HOST_HIGH_RESP_ENTRIES, 0}, 1646 {AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY}, 1647 {AAC_ADAP_HIGH_RESP_ENTRIES, 0} 1648 }; 1649 1650 /* 1651 * Atomically insert an entry into the nominated queue, returns 0 on success or 1652 * EBUSY if the queue is full. 1653 * 1654 * Note: it would be more efficient to defer notifying the controller in 1655 * the case where we may be inserting several entries in rapid succession, 1656 * but implementing this usefully may be difficult (it would involve a 1657 * separate queue/notify interface). 1658 */ 1659 static int 1660 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm) 1661 { 1662 u_int32_t pi, ci; 1663 int s, error; 1664 u_int32_t fib_size; 1665 u_int32_t fib_addr; 1666 1667 debug_called(3); 1668 1669 fib_size = cm->cm_fib->Header.Size; 1670 fib_addr = cm->cm_fib->Header.ReceiverFibAddress; 1671 1672 s = splbio(); 1673 1674 /* get the producer/consumer indices */ 1675 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1676 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1677 1678 /* wrap the queue? */ 1679 if (pi >= aac_qinfo[queue].size) 1680 pi = 0; 1681 1682 /* check for queue full */ 1683 if ((pi + 1) == ci) { 1684 error = EBUSY; 1685 goto out; 1686 } 1687 1688 /* populate queue entry */ 1689 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size; 1690 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr; 1691 1692 /* update producer index */ 1693 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1; 1694 1695 /* 1696 * To avoid a race with its completion interrupt, place this command on 1697 * the busy queue prior to advertising it to the controller. 1698 */ 1699 aac_enqueue_busy(cm); 1700 1701 /* notify the adapter if we know how */ 1702 if (aac_qinfo[queue].notify != 0) 1703 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1704 1705 error = 0; 1706 1707 out: 1708 splx(s); 1709 return(error); 1710 } 1711 1712 /* 1713 * Atomically remove one entry from the nominated queue, returns 0 on 1714 * success or ENOENT if the queue is empty. 1715 */ 1716 static int 1717 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size, 1718 struct aac_fib **fib_addr) 1719 { 1720 u_int32_t pi, ci; 1721 int s, error; 1722 int notify; 1723 1724 debug_called(3); 1725 1726 s = splbio(); 1727 1728 /* get the producer/consumer indices */ 1729 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1730 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1731 1732 /* check for queue empty */ 1733 if (ci == pi) { 1734 error = ENOENT; 1735 goto out; 1736 } 1737 1738 notify = 0; 1739 if (ci == pi + 1) 1740 notify++; 1741 1742 /* wrap the queue? */ 1743 if (ci >= aac_qinfo[queue].size) 1744 ci = 0; 1745 1746 /* fetch the entry */ 1747 *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size; 1748 *fib_addr = (struct aac_fib *)(sc->aac_qentries[queue] + 1749 ci)->aq_fib_addr; 1750 1751 /* update consumer index */ 1752 sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1; 1753 1754 /* if we have made the queue un-full, notify the adapter */ 1755 if (notify && (aac_qinfo[queue].notify != 0)) 1756 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1757 error = 0; 1758 1759 out: 1760 splx(s); 1761 return(error); 1762 } 1763 1764 /* 1765 * Put our response to an Adapter Initialed Fib on the response queue 1766 */ 1767 static int 1768 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib) 1769 { 1770 u_int32_t pi, ci; 1771 int s, error; 1772 u_int32_t fib_size; 1773 u_int32_t fib_addr; 1774 1775 debug_called(1); 1776 1777 /* Tell the adapter where the FIB is */ 1778 fib_size = fib->Header.Size; 1779 fib_addr = fib->Header.SenderFibAddress; 1780 fib->Header.ReceiverFibAddress = fib_addr; 1781 1782 s = splbio(); 1783 1784 /* get the producer/consumer indices */ 1785 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1786 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1787 1788 /* wrap the queue? */ 1789 if (pi >= aac_qinfo[queue].size) 1790 pi = 0; 1791 1792 /* check for queue full */ 1793 if ((pi + 1) == ci) { 1794 error = EBUSY; 1795 goto out; 1796 } 1797 1798 /* populate queue entry */ 1799 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size; 1800 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr; 1801 1802 /* update producer index */ 1803 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1; 1804 1805 /* notify the adapter if we know how */ 1806 if (aac_qinfo[queue].notify != 0) 1807 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1808 1809 error = 0; 1810 1811 out: 1812 splx(s); 1813 return(error); 1814 } 1815 1816 /* 1817 * Check for commands that have been outstanding for a suspiciously long time, 1818 * and complain about them. 1819 */ 1820 static void 1821 aac_timeout(struct aac_softc *sc) 1822 { 1823 int s; 1824 struct aac_command *cm; 1825 time_t deadline; 1826 1827 #if 0 1828 /* simulate an interrupt to handle possibly-missed interrupts */ 1829 /* 1830 * XXX This was done to work around another bug which has since been 1831 * fixed. It is dangerous anyways because you don't want multiple 1832 * threads in the interrupt handler at the same time! If calling 1833 * is deamed neccesary in the future, proper mutexes must be used. 1834 */ 1835 s = splbio(); 1836 aac_intr(sc); 1837 splx(s); 1838 1839 /* kick the I/O queue to restart it in the case of deadlock */ 1840 aac_startio(sc); 1841 #endif 1842 1843 /* 1844 * traverse the busy command list, bitch about late commands once 1845 * only. 1846 */ 1847 deadline = time_second - AAC_CMD_TIMEOUT; 1848 s = splbio(); 1849 TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) { 1850 if ((cm->cm_timestamp < deadline) 1851 /* && !(cm->cm_flags & AAC_CMD_TIMEDOUT) */) { 1852 cm->cm_flags |= AAC_CMD_TIMEDOUT; 1853 device_printf(sc->aac_dev, 1854 "COMMAND %p TIMEOUT AFTER %d SECONDS\n", 1855 cm, (int)(time_second-cm->cm_timestamp)); 1856 AAC_PRINT_FIB(sc, cm->cm_fib); 1857 } 1858 } 1859 splx(s); 1860 1861 /* reset the timer for next time */ 1862 timeout((timeout_t*)aac_timeout, sc, AAC_PERIODIC_INTERVAL * hz); 1863 return; 1864 } 1865 1866 /* 1867 * Interface Function Vectors 1868 */ 1869 1870 /* 1871 * Read the current firmware status word. 1872 */ 1873 static int 1874 aac_sa_get_fwstatus(struct aac_softc *sc) 1875 { 1876 debug_called(3); 1877 1878 return(AAC_GETREG4(sc, AAC_SA_FWSTATUS)); 1879 } 1880 1881 static int 1882 aac_rx_get_fwstatus(struct aac_softc *sc) 1883 { 1884 debug_called(3); 1885 1886 return(AAC_GETREG4(sc, AAC_RX_FWSTATUS)); 1887 } 1888 1889 static int 1890 aac_fa_get_fwstatus(struct aac_softc *sc) 1891 { 1892 int val; 1893 1894 debug_called(3); 1895 1896 val = AAC_GETREG4(sc, AAC_FA_FWSTATUS); 1897 return (val); 1898 } 1899 1900 /* 1901 * Notify the controller of a change in a given queue 1902 */ 1903 1904 static void 1905 aac_sa_qnotify(struct aac_softc *sc, int qbit) 1906 { 1907 debug_called(3); 1908 1909 AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit); 1910 } 1911 1912 static void 1913 aac_rx_qnotify(struct aac_softc *sc, int qbit) 1914 { 1915 debug_called(3); 1916 1917 AAC_SETREG4(sc, AAC_RX_IDBR, qbit); 1918 } 1919 1920 static void 1921 aac_fa_qnotify(struct aac_softc *sc, int qbit) 1922 { 1923 debug_called(3); 1924 1925 AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit); 1926 AAC_FA_HACK(sc); 1927 } 1928 1929 /* 1930 * Get the interrupt reason bits 1931 */ 1932 static int 1933 aac_sa_get_istatus(struct aac_softc *sc) 1934 { 1935 debug_called(3); 1936 1937 return(AAC_GETREG2(sc, AAC_SA_DOORBELL0)); 1938 } 1939 1940 static int 1941 aac_rx_get_istatus(struct aac_softc *sc) 1942 { 1943 debug_called(3); 1944 1945 return(AAC_GETREG4(sc, AAC_RX_ODBR)); 1946 } 1947 1948 static int 1949 aac_fa_get_istatus(struct aac_softc *sc) 1950 { 1951 int val; 1952 1953 debug_called(3); 1954 1955 val = AAC_GETREG2(sc, AAC_FA_DOORBELL0); 1956 return (val); 1957 } 1958 1959 /* 1960 * Clear some interrupt reason bits 1961 */ 1962 static void 1963 aac_sa_clear_istatus(struct aac_softc *sc, int mask) 1964 { 1965 debug_called(3); 1966 1967 AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask); 1968 } 1969 1970 static void 1971 aac_rx_clear_istatus(struct aac_softc *sc, int mask) 1972 { 1973 debug_called(3); 1974 1975 AAC_SETREG4(sc, AAC_RX_ODBR, mask); 1976 } 1977 1978 static void 1979 aac_fa_clear_istatus(struct aac_softc *sc, int mask) 1980 { 1981 debug_called(3); 1982 1983 AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask); 1984 AAC_FA_HACK(sc); 1985 } 1986 1987 /* 1988 * Populate the mailbox and set the command word 1989 */ 1990 static void 1991 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command, 1992 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 1993 { 1994 debug_called(4); 1995 1996 AAC_SETREG4(sc, AAC_SA_MAILBOX, command); 1997 AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0); 1998 AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1); 1999 AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2); 2000 AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3); 2001 } 2002 2003 static void 2004 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command, 2005 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 2006 { 2007 debug_called(4); 2008 2009 AAC_SETREG4(sc, AAC_RX_MAILBOX, command); 2010 AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0); 2011 AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1); 2012 AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2); 2013 AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3); 2014 } 2015 2016 static void 2017 aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command, 2018 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 2019 { 2020 debug_called(4); 2021 2022 AAC_SETREG4(sc, AAC_FA_MAILBOX, command); 2023 AAC_FA_HACK(sc); 2024 AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0); 2025 AAC_FA_HACK(sc); 2026 AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1); 2027 AAC_FA_HACK(sc); 2028 AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2); 2029 AAC_FA_HACK(sc); 2030 AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3); 2031 AAC_FA_HACK(sc); 2032 } 2033 2034 /* 2035 * Fetch the immediate command status word 2036 */ 2037 static int 2038 aac_sa_get_mailboxstatus(struct aac_softc *sc) 2039 { 2040 debug_called(4); 2041 2042 return(AAC_GETREG4(sc, AAC_SA_MAILBOX)); 2043 } 2044 2045 static int 2046 aac_rx_get_mailboxstatus(struct aac_softc *sc) 2047 { 2048 debug_called(4); 2049 2050 return(AAC_GETREG4(sc, AAC_RX_MAILBOX)); 2051 } 2052 2053 static int 2054 aac_fa_get_mailboxstatus(struct aac_softc *sc) 2055 { 2056 int val; 2057 2058 debug_called(4); 2059 2060 val = AAC_GETREG4(sc, AAC_FA_MAILBOX); 2061 return (val); 2062 } 2063 2064 /* 2065 * Set/clear interrupt masks 2066 */ 2067 static void 2068 aac_sa_set_interrupts(struct aac_softc *sc, int enable) 2069 { 2070 debug(2, "%sable interrupts", enable ? "en" : "dis"); 2071 2072 if (enable) { 2073 AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS); 2074 } else { 2075 AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0); 2076 } 2077 } 2078 2079 static void 2080 aac_rx_set_interrupts(struct aac_softc *sc, int enable) 2081 { 2082 debug(2, "%sable interrupts", enable ? "en" : "dis"); 2083 2084 if (enable) { 2085 AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS); 2086 } else { 2087 AAC_SETREG4(sc, AAC_RX_OIMR, ~0); 2088 } 2089 } 2090 2091 static void 2092 aac_fa_set_interrupts(struct aac_softc *sc, int enable) 2093 { 2094 debug(2, "%sable interrupts", enable ? "en" : "dis"); 2095 2096 if (enable) { 2097 AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS); 2098 AAC_FA_HACK(sc); 2099 } else { 2100 AAC_SETREG2((sc), AAC_FA_MASK0, ~0); 2101 AAC_FA_HACK(sc); 2102 } 2103 } 2104 2105 /* 2106 * Debugging and Diagnostics 2107 */ 2108 2109 /* 2110 * Print some information about the controller. 2111 */ 2112 static void 2113 aac_describe_controller(struct aac_softc *sc) 2114 { 2115 u_int8_t buf[AAC_FIB_DATASIZE]; /* XXX really a bit big 2116 * for the stack */ 2117 u_int16_t bufsize; 2118 struct aac_adapter_info *info; 2119 u_int8_t arg; 2120 2121 debug_called(2); 2122 2123 arg = 0; 2124 bufsize = sizeof(buf); 2125 if (aac_sync_fib(sc, RequestAdapterInfo, 0, &arg, sizeof(arg), &buf, 2126 &bufsize)) { 2127 device_printf(sc->aac_dev, "RequestAdapterInfo failed\n"); 2128 return; 2129 } 2130 if (bufsize != sizeof(*info)) { 2131 device_printf(sc->aac_dev, 2132 "RequestAdapterInfo returned wrong data size " 2133 "(%d != %d)\n", bufsize, sizeof(*info)); 2134 /*return;*/ 2135 } 2136 info = (struct aac_adapter_info *)&buf[0]; 2137 2138 device_printf(sc->aac_dev, "%s %dMHz, %dMB cache memory, %s\n", 2139 aac_describe_code(aac_cpu_variant, info->CpuVariant), 2140 info->ClockSpeed, info->BufferMem / (1024 * 1024), 2141 aac_describe_code(aac_battery_platform, 2142 info->batteryPlatform)); 2143 2144 /* save the kernel revision structure for later use */ 2145 sc->aac_revision = info->KernelRevision; 2146 device_printf(sc->aac_dev, "Kernel %d.%d-%d, Build %d, S/N %6X\n", 2147 info->KernelRevision.external.comp.major, 2148 info->KernelRevision.external.comp.minor, 2149 info->KernelRevision.external.comp.dash, 2150 info->KernelRevision.buildNumber, 2151 (u_int32_t)(info->SerialNumber & 0xffffff)); 2152 } 2153 2154 /* 2155 * Look up a text description of a numeric error code and return a pointer to 2156 * same. 2157 */ 2158 static char * 2159 aac_describe_code(struct aac_code_lookup *table, u_int32_t code) 2160 { 2161 int i; 2162 2163 for (i = 0; table[i].string != NULL; i++) 2164 if (table[i].code == code) 2165 return(table[i].string); 2166 return(table[i + 1].string); 2167 } 2168 2169 /* 2170 * Management Interface 2171 */ 2172 2173 static int 2174 aac_open(dev_t dev, int flags, int fmt, struct thread *td) 2175 { 2176 struct aac_softc *sc; 2177 2178 debug_called(2); 2179 2180 sc = dev->si_drv1; 2181 2182 /* Check to make sure the device isn't already open */ 2183 if (sc->aac_state & AAC_STATE_OPEN) { 2184 return EBUSY; 2185 } 2186 sc->aac_state |= AAC_STATE_OPEN; 2187 2188 return 0; 2189 } 2190 2191 static int 2192 aac_close(dev_t dev, int flags, int fmt, struct thread *td) 2193 { 2194 struct aac_softc *sc; 2195 2196 debug_called(2); 2197 2198 sc = dev->si_drv1; 2199 2200 /* Mark this unit as no longer open */ 2201 sc->aac_state &= ~AAC_STATE_OPEN; 2202 2203 return 0; 2204 } 2205 2206 static int 2207 aac_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct thread *td) 2208 { 2209 union aac_statrequest *as; 2210 struct aac_softc *sc; 2211 int error = 0; 2212 int i; 2213 2214 debug_called(2); 2215 2216 as = (union aac_statrequest *)arg; 2217 sc = dev->si_drv1; 2218 2219 switch (cmd) { 2220 case AACIO_STATS: 2221 switch (as->as_item) { 2222 case AACQ_FREE: 2223 case AACQ_BIO: 2224 case AACQ_READY: 2225 case AACQ_BUSY: 2226 case AACQ_COMPLETE: 2227 bcopy(&sc->aac_qstat[as->as_item], &as->as_qstat, 2228 sizeof(struct aac_qstat)); 2229 break; 2230 default: 2231 error = ENOENT; 2232 break; 2233 } 2234 break; 2235 2236 case FSACTL_SENDFIB: 2237 arg = *(caddr_t*)arg; 2238 case FSACTL_LNX_SENDFIB: 2239 debug(1, "FSACTL_SENDFIB"); 2240 error = aac_ioctl_sendfib(sc, arg); 2241 break; 2242 case FSACTL_AIF_THREAD: 2243 case FSACTL_LNX_AIF_THREAD: 2244 debug(1, "FSACTL_AIF_THREAD"); 2245 error = EINVAL; 2246 break; 2247 case FSACTL_OPEN_GET_ADAPTER_FIB: 2248 arg = *(caddr_t*)arg; 2249 case FSACTL_LNX_OPEN_GET_ADAPTER_FIB: 2250 debug(1, "FSACTL_OPEN_GET_ADAPTER_FIB"); 2251 /* 2252 * Pass the caller out an AdapterFibContext. 2253 * 2254 * Note that because we only support one opener, we 2255 * basically ignore this. Set the caller's context to a magic 2256 * number just in case. 2257 * 2258 * The Linux code hands the driver a pointer into kernel space, 2259 * and then trusts it when the caller hands it back. Aiee! 2260 * Here, we give it the proc pointer of the per-adapter aif 2261 * thread. It's only used as a sanity check in other calls. 2262 */ 2263 i = (int)sc->aifthread; 2264 error = copyout(&i, arg, sizeof(i)); 2265 break; 2266 case FSACTL_GET_NEXT_ADAPTER_FIB: 2267 arg = *(caddr_t*)arg; 2268 case FSACTL_LNX_GET_NEXT_ADAPTER_FIB: 2269 debug(1, "FSACTL_GET_NEXT_ADAPTER_FIB"); 2270 error = aac_getnext_aif(sc, arg); 2271 break; 2272 case FSACTL_CLOSE_GET_ADAPTER_FIB: 2273 case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB: 2274 debug(1, "FSACTL_CLOSE_GET_ADAPTER_FIB"); 2275 /* don't do anything here */ 2276 break; 2277 case FSACTL_MINIPORT_REV_CHECK: 2278 arg = *(caddr_t*)arg; 2279 case FSACTL_LNX_MINIPORT_REV_CHECK: 2280 debug(1, "FSACTL_MINIPORT_REV_CHECK"); 2281 error = aac_rev_check(sc, arg); 2282 break; 2283 case FSACTL_QUERY_DISK: 2284 arg = *(caddr_t*)arg; 2285 case FSACTL_LNX_QUERY_DISK: 2286 debug(1, "FSACTL_QUERY_DISK"); 2287 error = aac_query_disk(sc, arg); 2288 break; 2289 case FSACTL_DELETE_DISK: 2290 case FSACTL_LNX_DELETE_DISK: 2291 /* 2292 * We don't trust the underland to tell us when to delete a 2293 * container, rather we rely on an AIF coming from the 2294 * controller 2295 */ 2296 error = 0; 2297 break; 2298 default: 2299 debug(1, "unsupported cmd 0x%lx\n", cmd); 2300 error = EINVAL; 2301 break; 2302 } 2303 return(error); 2304 } 2305 2306 static int 2307 aac_poll(dev_t dev, int poll_events, struct thread *td) 2308 { 2309 struct aac_softc *sc; 2310 int revents; 2311 2312 sc = dev->si_drv1; 2313 revents = 0; 2314 2315 AAC_LOCK_AQUIRE(&sc->aac_aifq_lock); 2316 if ((poll_events & (POLLRDNORM | POLLIN)) != 0) { 2317 if (sc->aac_aifq_tail != sc->aac_aifq_head) 2318 revents |= poll_events & (POLLIN | POLLRDNORM); 2319 } 2320 AAC_LOCK_RELEASE(&sc->aac_aifq_lock); 2321 2322 if (revents == 0) { 2323 if (poll_events & (POLLIN | POLLRDNORM)) 2324 selrecord(td, &sc->rcv_select); 2325 } 2326 2327 return (revents); 2328 } 2329 2330 /* 2331 * Send a FIB supplied from userspace 2332 */ 2333 static int 2334 aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib) 2335 { 2336 struct aac_command *cm; 2337 int size, error; 2338 2339 debug_called(2); 2340 2341 cm = NULL; 2342 2343 /* 2344 * Get a command 2345 */ 2346 if (aac_alloc_command(sc, &cm)) { 2347 error = EBUSY; 2348 goto out; 2349 } 2350 2351 /* 2352 * Fetch the FIB header, then re-copy to get data as well. 2353 */ 2354 if ((error = copyin(ufib, cm->cm_fib, 2355 sizeof(struct aac_fib_header))) != 0) 2356 goto out; 2357 size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header); 2358 if (size > sizeof(struct aac_fib)) { 2359 device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n", 2360 size, sizeof(struct aac_fib)); 2361 size = sizeof(struct aac_fib); 2362 } 2363 if ((error = copyin(ufib, cm->cm_fib, size)) != 0) 2364 goto out; 2365 cm->cm_fib->Header.Size = size; 2366 cm->cm_timestamp = time_second; 2367 2368 /* 2369 * Pass the FIB to the controller, wait for it to complete. 2370 */ 2371 if ((error = aac_wait_command(cm, 30)) != 0) { /* XXX user timeout? */ 2372 printf("aac_wait_command return %d\n", error); 2373 goto out; 2374 } 2375 2376 /* 2377 * Copy the FIB and data back out to the caller. 2378 */ 2379 size = cm->cm_fib->Header.Size; 2380 if (size > sizeof(struct aac_fib)) { 2381 device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n", 2382 size, sizeof(struct aac_fib)); 2383 size = sizeof(struct aac_fib); 2384 } 2385 error = copyout(cm->cm_fib, ufib, size); 2386 2387 out: 2388 if (cm != NULL) { 2389 aac_release_command(cm); 2390 } 2391 return(error); 2392 } 2393 2394 /* 2395 * Handle an AIF sent to us by the controller; queue it for later reference. 2396 * If the queue fills up, then drop the older entries. 2397 */ 2398 static void 2399 aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib) 2400 { 2401 struct aac_aif_command *aif; 2402 struct aac_container *co, *co_next; 2403 struct aac_mntinfo mi; 2404 struct aac_mntinforesponse mir; 2405 u_int16_t rsize; 2406 int next, found; 2407 int added = 0, i = 0; 2408 2409 debug_called(2); 2410 2411 aif = (struct aac_aif_command*)&fib->data[0]; 2412 aac_print_aif(sc, aif); 2413 2414 /* Is it an event that we should care about? */ 2415 switch (aif->command) { 2416 case AifCmdEventNotify: 2417 switch (aif->data.EN.type) { 2418 case AifEnAddContainer: 2419 case AifEnDeleteContainer: 2420 /* 2421 * A container was added or deleted, but the message 2422 * doesn't tell us anything else! Re-enumerate the 2423 * containers and sort things out. 2424 */ 2425 mi.Command = VM_NameServe; 2426 mi.MntType = FT_FILESYS; 2427 do { 2428 /* 2429 * Ask the controller for its containers one at 2430 * a time. 2431 * XXX What if the controller's list changes 2432 * midway through this enumaration? 2433 * XXX This should be done async. 2434 */ 2435 mi.MntCount = i; 2436 rsize = sizeof(mir); 2437 if (aac_sync_fib(sc, ContainerCommand, 0, &mi, 2438 sizeof(mi), &mir, &rsize)) { 2439 debug(2, "Error probing container %d\n", 2440 i); 2441 continue; 2442 } 2443 if (rsize != sizeof(mir)) { 2444 debug(2, "Container response size too " 2445 "large\n"); 2446 continue; 2447 } 2448 /* 2449 * Check the container against our list. 2450 * co->co_found was already set to 0 in a 2451 * previous run. 2452 */ 2453 if ((mir.Status == ST_OK) && 2454 (mir.MntTable[0].VolType != CT_NONE)) { 2455 found = 0; 2456 TAILQ_FOREACH(co, 2457 &sc->aac_container_tqh, 2458 co_link) { 2459 if (co->co_mntobj.ObjectId == 2460 mir.MntTable[0].ObjectId) { 2461 co->co_found = 1; 2462 found = 1; 2463 break; 2464 } 2465 } 2466 /* 2467 * If the container matched, continue 2468 * in the list. 2469 */ 2470 if (found) { 2471 i++; 2472 continue; 2473 } 2474 2475 /* 2476 * This is a new container. Do all the 2477 * appropriate things to set it up. */ 2478 aac_add_container(sc, &mir, 1); 2479 added = 1; 2480 } 2481 i++; 2482 } while ((i < mir.MntRespCount) && 2483 (i < AAC_MAX_CONTAINERS)); 2484 2485 /* 2486 * Go through our list of containers and see which ones 2487 * were not marked 'found'. Since the controller didn't 2488 * list them they must have been deleted. Do the 2489 * appropriate steps to destroy the device. Also reset 2490 * the co->co_found field. 2491 */ 2492 co = TAILQ_FIRST(&sc->aac_container_tqh); 2493 while (co != NULL) { 2494 if (co->co_found == 0) { 2495 device_delete_child(sc->aac_dev, 2496 co->co_disk); 2497 co_next = TAILQ_NEXT(co, co_link); 2498 AAC_LOCK_AQUIRE(&sc-> 2499 aac_container_lock); 2500 TAILQ_REMOVE(&sc->aac_container_tqh, co, 2501 co_link); 2502 AAC_LOCK_RELEASE(&sc-> 2503 aac_container_lock); 2504 FREE(co, M_AACBUF); 2505 co = co_next; 2506 } else { 2507 co->co_found = 0; 2508 co = TAILQ_NEXT(co, co_link); 2509 } 2510 } 2511 2512 /* Attach the newly created containers */ 2513 if (added) 2514 bus_generic_attach(sc->aac_dev); 2515 2516 break; 2517 2518 default: 2519 break; 2520 } 2521 2522 default: 2523 break; 2524 } 2525 2526 /* Copy the AIF data to the AIF queue for ioctl retrieval */ 2527 AAC_LOCK_AQUIRE(&sc->aac_aifq_lock); 2528 next = (sc->aac_aifq_head + 1) % AAC_AIFQ_LENGTH; 2529 if (next != sc->aac_aifq_tail) { 2530 bcopy(aif, &sc->aac_aifq[next], sizeof(struct aac_aif_command)); 2531 sc->aac_aifq_head = next; 2532 2533 /* On the off chance that someone is sleeping for an aif... */ 2534 if (sc->aac_state & AAC_STATE_AIF_SLEEPER) 2535 wakeup(sc->aac_aifq); 2536 /* Wakeup any poll()ers */ 2537 selwakeup(&sc->rcv_select); 2538 } 2539 AAC_LOCK_RELEASE(&sc->aac_aifq_lock); 2540 2541 return; 2542 } 2543 2544 /* 2545 * Linux Management Interface 2546 * This is soon to be removed! 2547 */ 2548 2549 #ifdef AAC_COMPAT_LINUX 2550 2551 #include <sys/proc.h> 2552 #include <machine/../linux/linux.h> 2553 #include <machine/../linux/linux_proto.h> 2554 #include <compat/linux/linux_ioctl.h> 2555 2556 /* There are multiple ioctl number ranges that need to be handled */ 2557 #define AAC_LINUX_IOCTL_MIN 0x0000 2558 #define AAC_LINUX_IOCTL_MAX 0x21ff 2559 2560 static linux_ioctl_function_t aac_linux_ioctl; 2561 static struct linux_ioctl_handler aac_handler = {aac_linux_ioctl, 2562 AAC_LINUX_IOCTL_MIN, 2563 AAC_LINUX_IOCTL_MAX}; 2564 2565 SYSINIT (aac_register, SI_SUB_KLD, SI_ORDER_MIDDLE, 2566 linux_ioctl_register_handler, &aac_handler); 2567 SYSUNINIT(aac_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE, 2568 linux_ioctl_unregister_handler, &aac_handler); 2569 2570 MODULE_DEPEND(aac, linux, 1, 1, 1); 2571 2572 static int 2573 aac_linux_ioctl(struct thread *td, struct linux_ioctl_args *args) 2574 { 2575 struct file *fp; 2576 u_long cmd; 2577 2578 debug_called(2); 2579 2580 fp = td->td_proc->p_fd->fd_ofiles[args->fd]; 2581 cmd = args->cmd; 2582 2583 /* 2584 * Pass the ioctl off to our standard handler. 2585 */ 2586 return(fo_ioctl(fp, cmd, (caddr_t)args->arg, td)); 2587 } 2588 2589 #endif 2590 2591 /* 2592 * Return the Revision of the driver to userspace and check to see if the 2593 * userspace app is possibly compatible. This is extremely bogus since 2594 * our driver doesn't follow Adaptec's versioning system. Cheat by just 2595 * returning what the card reported. 2596 */ 2597 static int 2598 aac_rev_check(struct aac_softc *sc, caddr_t udata) 2599 { 2600 struct aac_rev_check rev_check; 2601 struct aac_rev_check_resp rev_check_resp; 2602 int error = 0; 2603 2604 debug_called(2); 2605 2606 /* 2607 * Copyin the revision struct from userspace 2608 */ 2609 if ((error = copyin(udata, (caddr_t)&rev_check, 2610 sizeof(struct aac_rev_check))) != 0) { 2611 return error; 2612 } 2613 2614 debug(2, "Userland revision= %d\n", 2615 rev_check.callingRevision.buildNumber); 2616 2617 /* 2618 * Doctor up the response struct. 2619 */ 2620 rev_check_resp.possiblyCompatible = 1; 2621 rev_check_resp.adapterSWRevision.external.ul = 2622 sc->aac_revision.external.ul; 2623 rev_check_resp.adapterSWRevision.buildNumber = 2624 sc->aac_revision.buildNumber; 2625 2626 return(copyout((caddr_t)&rev_check_resp, udata, 2627 sizeof(struct aac_rev_check_resp))); 2628 } 2629 2630 /* 2631 * Pass the caller the next AIF in their queue 2632 */ 2633 static int 2634 aac_getnext_aif(struct aac_softc *sc, caddr_t arg) 2635 { 2636 struct get_adapter_fib_ioctl agf; 2637 int error, s; 2638 2639 debug_called(2); 2640 2641 if ((error = copyin(arg, &agf, sizeof(agf))) == 0) { 2642 2643 /* 2644 * Check the magic number that we gave the caller. 2645 */ 2646 if (agf.AdapterFibContext != (int)sc->aifthread) { 2647 error = EFAULT; 2648 } else { 2649 2650 s = splbio(); 2651 error = aac_return_aif(sc, agf.AifFib); 2652 2653 if ((error == EAGAIN) && (agf.Wait)) { 2654 sc->aac_state |= AAC_STATE_AIF_SLEEPER; 2655 while (error == EAGAIN) { 2656 error = tsleep(sc->aac_aifq, PRIBIO | 2657 PCATCH, "aacaif", 0); 2658 if (error == 0) 2659 error = aac_return_aif(sc, 2660 agf.AifFib); 2661 } 2662 sc->aac_state &= ~AAC_STATE_AIF_SLEEPER; 2663 } 2664 splx(s); 2665 } 2666 } 2667 return(error); 2668 } 2669 2670 /* 2671 * Hand the next AIF off the top of the queue out to userspace. 2672 */ 2673 static int 2674 aac_return_aif(struct aac_softc *sc, caddr_t uptr) 2675 { 2676 int error; 2677 2678 debug_called(2); 2679 2680 AAC_LOCK_AQUIRE(&sc->aac_aifq_lock); 2681 if (sc->aac_aifq_tail == sc->aac_aifq_head) { 2682 error = EAGAIN; 2683 } else { 2684 error = copyout(&sc->aac_aifq[sc->aac_aifq_tail], uptr, 2685 sizeof(struct aac_aif_command)); 2686 if (error) 2687 printf("aac_return_aif: copyout returned %d\n", error); 2688 if (!error) 2689 sc->aac_aifq_tail = (sc->aac_aifq_tail + 1) % 2690 AAC_AIFQ_LENGTH; 2691 } 2692 AAC_LOCK_RELEASE(&sc->aac_aifq_lock); 2693 return(error); 2694 } 2695 2696 /* 2697 * Give the userland some information about the container. The AAC arch 2698 * expects the driver to be a SCSI passthrough type driver, so it expects 2699 * the containers to have b:t:l numbers. Fake it. 2700 */ 2701 static int 2702 aac_query_disk(struct aac_softc *sc, caddr_t uptr) 2703 { 2704 struct aac_query_disk query_disk; 2705 struct aac_container *co; 2706 struct aac_disk *disk; 2707 int error, id; 2708 2709 debug_called(2); 2710 2711 disk = NULL; 2712 2713 error = copyin(uptr, (caddr_t)&query_disk, 2714 sizeof(struct aac_query_disk)); 2715 if (error) 2716 return (error); 2717 2718 id = query_disk.ContainerNumber; 2719 if (id == -1) 2720 return (EINVAL); 2721 2722 AAC_LOCK_AQUIRE(&sc->aac_container_lock); 2723 TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) { 2724 if (co->co_mntobj.ObjectId == id) 2725 break; 2726 } 2727 2728 if (co == NULL) { 2729 query_disk.Valid = 0; 2730 query_disk.Locked = 0; 2731 query_disk.Deleted = 1; /* XXX is this right? */ 2732 } else { 2733 disk = device_get_softc(co->co_disk); 2734 query_disk.Valid = 1; 2735 query_disk.Locked = 2736 (disk->ad_flags & AAC_DISK_OPEN) ? 1 : 0; 2737 query_disk.Deleted = 0; 2738 query_disk.Bus = device_get_unit(sc->aac_dev); 2739 query_disk.Target = disk->unit; 2740 query_disk.Lun = 0; 2741 query_disk.UnMapped = 0; 2742 bcopy(disk->ad_dev_t->si_name, 2743 &query_disk.diskDeviceName[0], 10); 2744 } 2745 AAC_LOCK_RELEASE(&sc->aac_container_lock); 2746 2747 error = copyout((caddr_t)&query_disk, uptr, 2748 sizeof(struct aac_query_disk)); 2749 2750 return (error); 2751 } 2752 2753