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