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