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