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