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