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