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