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