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