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