1 /*- 2 * Copyright (c) 2000 Michael Smith 3 * Copyright (c) 2000 BSDi 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD$ 28 */ 29 30 /* 31 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters. 32 */ 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/malloc.h> 37 #include <sys/kernel.h> 38 39 #include <dev/aac/aac_compat.h> 40 41 #include <sys/bus.h> 42 #include <sys/conf.h> 43 #include <sys/devicestat.h> 44 #include <sys/disk.h> 45 #include <sys/file.h> 46 #include <sys/signalvar.h> 47 48 #include <machine/bus_memio.h> 49 #include <machine/bus.h> 50 #include <machine/clock.h> 51 #include <machine/resource.h> 52 53 #include <dev/aac/aacreg.h> 54 #include <dev/aac/aacvar.h> 55 #include <dev/aac/aac_tables.h> 56 #include <dev/aac/aac_ioctl.h> 57 58 devclass_t aac_devclass; 59 60 static void aac_startup(void *arg); 61 62 /* Command Processing */ 63 static void aac_startio(struct aac_softc *sc); 64 static int aac_start(struct aac_command *cm); 65 static void aac_complete(void *context, int pending); 66 static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp); 67 static void aac_bio_complete(struct aac_command *cm); 68 static int aac_wait_command(struct aac_command *cm, int timeout); 69 static void aac_host_command(struct aac_softc *sc); 70 static void aac_host_response(struct aac_softc *sc); 71 72 /* Command Buffer Management */ 73 static int aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp); 74 static void aac_release_command(struct aac_command *cm); 75 static void aac_map_command_cluster(void *arg, bus_dma_segment_t *segs, int nseg, int error); 76 static void aac_alloc_command_cluster(struct aac_softc *sc); 77 static void aac_free_command_cluster(struct aac_command_cluster *cmc); 78 static void aac_map_command(struct aac_command *cm); 79 static void aac_unmap_command(struct aac_command *cm); 80 81 /* Hardware Interface */ 82 static void aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error); 83 static int aac_init(struct aac_softc *sc); 84 static int aac_sync_command(struct aac_softc *sc, u_int32_t command, 85 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, 86 u_int32_t *sp); 87 static int aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate, 88 void *data, u_int16_t datasize, 89 void *result, u_int16_t *resultsize); 90 static int aac_enqueue_fib(struct aac_softc *sc, int queue, u_int32_t fib_size, u_int32_t fib_addr); 91 static int aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size, struct aac_fib **fib_addr); 92 93 /* StrongARM interface */ 94 static int aac_sa_get_fwstatus(struct aac_softc *sc); 95 static void aac_sa_qnotify(struct aac_softc *sc, int qbit); 96 static int aac_sa_get_istatus(struct aac_softc *sc); 97 static void aac_sa_clear_istatus(struct aac_softc *sc, int mask); 98 static void aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command, 99 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3); 100 static int aac_sa_get_mailboxstatus(struct aac_softc *sc); 101 static void aac_sa_set_interrupts(struct aac_softc *sc, int enable); 102 103 struct aac_interface aac_sa_interface = { 104 aac_sa_get_fwstatus, 105 aac_sa_qnotify, 106 aac_sa_get_istatus, 107 aac_sa_clear_istatus, 108 aac_sa_set_mailbox, 109 aac_sa_get_mailboxstatus, 110 aac_sa_set_interrupts 111 }; 112 113 /* i960Rx interface */ 114 static int aac_rx_get_fwstatus(struct aac_softc *sc); 115 static void aac_rx_qnotify(struct aac_softc *sc, int qbit); 116 static int aac_rx_get_istatus(struct aac_softc *sc); 117 static void aac_rx_clear_istatus(struct aac_softc *sc, int mask); 118 static void aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command, 119 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3); 120 static int aac_rx_get_mailboxstatus(struct aac_softc *sc); 121 static void aac_rx_set_interrupts(struct aac_softc *sc, int enable); 122 123 struct aac_interface aac_rx_interface = { 124 aac_rx_get_fwstatus, 125 aac_rx_qnotify, 126 aac_rx_get_istatus, 127 aac_rx_clear_istatus, 128 aac_rx_set_mailbox, 129 aac_rx_get_mailboxstatus, 130 aac_rx_set_interrupts 131 }; 132 133 /* Debugging and Diagnostics */ 134 static void aac_describe_controller(struct aac_softc *sc); 135 static char *aac_describe_code(struct aac_code_lookup *table, u_int32_t code); 136 137 /* Management Interface */ 138 static d_open_t aac_open; 139 static d_close_t aac_close; 140 static d_ioctl_t aac_ioctl; 141 static int aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib); 142 static void aac_handle_aif(struct aac_softc *sc, struct aac_aif_command *aif); 143 static int aac_return_aif(struct aac_softc *sc, caddr_t uptr); 144 #ifdef AAC_COMPAT_LINUX 145 static int aac_linux_rev_check(struct aac_softc *sc, caddr_t udata); 146 static int aac_linux_getnext_aif(struct aac_softc *sc, caddr_t arg); 147 #endif 148 149 #define AAC_CDEV_MAJOR 150 150 151 static struct cdevsw aac_cdevsw = { 152 aac_open, /* open */ 153 aac_close, /* close */ 154 noread, /* read */ 155 nowrite, /* write */ 156 aac_ioctl, /* ioctl */ 157 nopoll, /* poll */ 158 nommap, /* mmap */ 159 nostrategy, /* strategy */ 160 "aac", /* name */ 161 AAC_CDEV_MAJOR, /* major */ 162 nodump, /* dump */ 163 nopsize, /* psize */ 164 0, /* flags */ 165 -1, /* bmaj */ 166 }; 167 168 /******************************************************************************** 169 ******************************************************************************** 170 Device Interface 171 ******************************************************************************** 172 ********************************************************************************/ 173 174 /******************************************************************************** 175 * Initialise the controller and softc 176 */ 177 int 178 aac_attach(struct aac_softc *sc) 179 { 180 int error, unit; 181 182 debug_called(1); 183 184 /* 185 * Initialise per-controller queues. 186 */ 187 TAILQ_INIT(&sc->aac_freecmds); 188 TAILQ_INIT(&sc->aac_ready); 189 TAILQ_INIT(&sc->aac_completed); 190 TAILQ_INIT(&sc->aac_clusters); 191 bioq_init(&sc->aac_bioq); 192 193 #if __FreeBSD_version >= 500005 194 /* 195 * Initialise command-completion task. 196 */ 197 TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc); 198 #endif 199 200 /* disable interrupts before we enable anything */ 201 AAC_MASK_INTERRUPTS(sc); 202 203 /* mark controller as suspended until we get ourselves organised */ 204 sc->aac_state |= AAC_STATE_SUSPEND; 205 206 /* 207 * Initialise the adapter. 208 */ 209 if ((error = aac_init(sc))) 210 return(error); 211 212 /* 213 * Print a little information about the controller. 214 */ 215 aac_describe_controller(sc); 216 217 /* 218 * Register to probe our containers later. 219 */ 220 bzero(&sc->aac_ich, sizeof(struct intr_config_hook)); 221 sc->aac_ich.ich_func = aac_startup; 222 sc->aac_ich.ich_arg = sc; 223 if (config_intrhook_establish(&sc->aac_ich) != 0) { 224 device_printf(sc->aac_dev, "can't establish configuration hook\n"); 225 return(ENXIO); 226 } 227 228 /* 229 * Make the control device. 230 */ 231 unit = device_get_unit(sc->aac_dev); 232 sc->aac_dev_t = make_dev(&aac_cdevsw, unit, UID_ROOT, GID_WHEEL, 0644, "aac%d", unit); 233 sc->aac_dev_t->si_drv1 = sc; 234 235 return(0); 236 } 237 238 /******************************************************************************** 239 * Probe for containers, create disks. 240 */ 241 static void 242 aac_startup(void *arg) 243 { 244 struct aac_softc *sc = (struct aac_softc *)arg; 245 struct aac_mntinfo mi; 246 struct aac_mntinforesponse mir; 247 device_t child; 248 u_int16_t rsize; 249 int i; 250 251 debug_called(1); 252 253 /* disconnect ourselves from the intrhook chain */ 254 config_intrhook_disestablish(&sc->aac_ich); 255 256 /* loop over possible containers */ 257 mi.Command = VM_NameServe; 258 mi.MntType = FT_FILESYS; 259 for (i = 0; i < AAC_MAX_CONTAINERS; i++) { 260 /* request information on this container */ 261 mi.MntCount = i; 262 if (aac_sync_fib(sc, ContainerCommand, 0, &mi, sizeof(struct aac_mntinfo), &mir, &rsize)) { 263 debug(2, "error probing container %d", i); 264 continue; 265 } 266 /* check response size */ 267 if (rsize != sizeof(mir)) { 268 debug(2, "container info response wrong size (%d should be %d)", rsize, sizeof(mir)); 269 continue; 270 } 271 /* 272 * Check container volume type for validity. Note that many of the possible types 273 * may never show up. 274 */ 275 if ((mir.Status == ST_OK) && (mir.MntTable[0].VolType != CT_NONE)) { 276 debug(1, "%d: id %x name '%.16s' size %u type %d", 277 i, mir.MntTable[0].ObjectId, 278 mir.MntTable[0].FileSystemName, mir.MntTable[0].Capacity, 279 mir.MntTable[0].VolType); 280 281 if ((child = device_add_child(sc->aac_dev, NULL, -1)) == NULL) { 282 device_printf(sc->aac_dev, "device_add_child failed\n"); 283 } else { 284 device_set_ivars(child, &sc->aac_container[i]); 285 } 286 device_set_desc(child, aac_describe_code(aac_container_types, mir.MntTable[0].VolType)); 287 sc->aac_container[i].co_disk = child; 288 sc->aac_container[i].co_mntobj = mir.MntTable[0]; 289 } 290 } 291 292 /* poke the bus to actually attach the child devices */ 293 if (bus_generic_attach(sc->aac_dev)) 294 device_printf(sc->aac_dev, "bus_generic_attach failed\n"); 295 296 /* mark the controller up */ 297 sc->aac_state &= ~AAC_STATE_SUSPEND; 298 299 /* enable interrupts now */ 300 AAC_UNMASK_INTERRUPTS(sc); 301 } 302 303 /******************************************************************************** 304 * Free all of the resources associated with (sc) 305 * 306 * Should not be called if the controller is active. 307 * 308 * XXX verify that we are freeing all our resources here... 309 */ 310 void 311 aac_free(struct aac_softc *sc) 312 { 313 struct aac_command_cluster *cmc; 314 315 debug_called(1); 316 317 /* remove the control device */ 318 if (sc->aac_dev_t != NULL) 319 destroy_dev(sc->aac_dev_t); 320 321 /* throw away any command buffers */ 322 while ((cmc = aac_dequeue_cluster(sc)) != NULL) 323 aac_free_command_cluster(cmc); 324 325 /* destroy the common area */ 326 if (sc->aac_common) { 327 bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap); 328 bus_dmamem_free(sc->aac_common_dmat, sc->aac_common, sc->aac_common_dmamap); 329 bus_dma_tag_destroy(sc->aac_common_dmat); 330 } 331 332 /* disconnect the interrupt handler */ 333 if (sc->aac_intr) 334 bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr); 335 if (sc->aac_irq != NULL) 336 bus_release_resource(sc->aac_dev, SYS_RES_IRQ, sc->aac_irq_rid, sc->aac_irq); 337 338 /* destroy data-transfer DMA tag */ 339 if (sc->aac_buffer_dmat) 340 bus_dma_tag_destroy(sc->aac_buffer_dmat); 341 342 /* destroy FIB DMA tag */ 343 if (sc->aac_buffer_dmat) 344 bus_dma_tag_destroy(sc->aac_fib_dmat); 345 346 /* destroy the parent DMA tag */ 347 if (sc->aac_parent_dmat) 348 bus_dma_tag_destroy(sc->aac_parent_dmat); 349 350 /* release the register window mapping */ 351 if (sc->aac_regs_resource != NULL) 352 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY, sc->aac_regs_rid, sc->aac_regs_resource); 353 } 354 355 /******************************************************************************** 356 * Disconnect from the controller completely, in preparation for unload. 357 */ 358 int 359 aac_detach(device_t dev) 360 { 361 struct aac_softc *sc = device_get_softc(dev); 362 int error; 363 364 debug_called(1); 365 366 if (sc->aac_state & AAC_STATE_OPEN) 367 return(EBUSY); 368 369 if ((error = aac_shutdown(dev))) 370 return(error); 371 372 aac_free(sc); 373 374 return(0); 375 } 376 377 /******************************************************************************** 378 * Bring the controller down to a dormant state and detach all child devices. 379 * 380 * This function is called before detach or system shutdown. 381 * 382 * Note that we can assume that the camq on the controller is empty, as we won't 383 * allow shutdown if any device is open. 384 */ 385 int 386 aac_shutdown(device_t dev) 387 { 388 struct aac_softc *sc = device_get_softc(dev); 389 struct aac_close_command cc; 390 int s, i; 391 392 debug_called(1); 393 394 s = splbio(); 395 396 sc->aac_state |= AAC_STATE_SUSPEND; 397 398 /* 399 * Send a Container shutdown followed by a HostShutdown FIB to the 400 * controller to convince it that we don't want to talk to it anymore. 401 * We've been closed and all I/O completed already 402 */ 403 device_printf(sc->aac_dev, "shutting down controller..."); 404 405 cc.Command = VM_CloseAll; 406 cc.ContainerId = 0xffffffff; 407 if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc), NULL, NULL)) { 408 printf("FAILED.\n"); 409 } else { 410 i = 0; 411 if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN, &i, sizeof(i), NULL, NULL)) { 412 printf("FAILED.\n"); 413 } else { 414 printf("done.\n"); 415 } 416 } 417 418 AAC_MASK_INTERRUPTS(sc); 419 420 splx(s); 421 return(0); 422 } 423 424 /******************************************************************************** 425 * Bring the controller to a quiescent state, ready for system suspend. 426 */ 427 int 428 aac_suspend(device_t dev) 429 { 430 struct aac_softc *sc = device_get_softc(dev); 431 int s; 432 433 debug_called(1); 434 s = splbio(); 435 436 sc->aac_state |= AAC_STATE_SUSPEND; 437 438 AAC_MASK_INTERRUPTS(sc); 439 splx(s); 440 return(0); 441 } 442 443 /******************************************************************************** 444 * Bring the controller back to a state ready for operation. 445 */ 446 int 447 aac_resume(device_t dev) 448 { 449 struct aac_softc *sc = device_get_softc(dev); 450 451 debug_called(1); 452 sc->aac_state &= ~AAC_STATE_SUSPEND; 453 AAC_UNMASK_INTERRUPTS(sc); 454 return(0); 455 } 456 457 /******************************************************************************* 458 * Take an interrupt. 459 */ 460 void 461 aac_intr(void *arg) 462 { 463 struct aac_softc *sc = (struct aac_softc *)arg; 464 u_int16_t reason; 465 466 debug_called(2); 467 468 reason = AAC_GET_ISTATUS(sc); 469 470 /* controller wants to talk to the log? XXX should we defer this? */ 471 if (reason & AAC_DB_PRINTF) { 472 if (sc->aac_common->ac_printf[0]) { 473 device_printf(sc->aac_dev, "** %.*s", AAC_PRINTF_BUFSIZE, sc->aac_common->ac_printf); 474 sc->aac_common->ac_printf[0] = 0; 475 } 476 AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF); 477 AAC_QNOTIFY(sc, AAC_DB_PRINTF); 478 } 479 480 /* controller has a message for us? */ 481 if (reason & AAC_DB_COMMAND_READY) { 482 aac_host_command(sc); 483 AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_READY); 484 } 485 486 /* controller has a response for us? */ 487 if (reason & AAC_DB_RESPONSE_READY) { 488 aac_host_response(sc); 489 AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY); 490 } 491 492 /* spurious interrupts that we don't use - reset the mask and clear the interrupts */ 493 if (reason & (AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL)) { 494 AAC_UNMASK_INTERRUPTS(sc); 495 AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL); 496 } 497 }; 498 499 /******************************************************************************** 500 ******************************************************************************** 501 Command Processing 502 ******************************************************************************** 503 ********************************************************************************/ 504 505 /******************************************************************************** 506 * Start as much queued I/O as possible on the controller 507 */ 508 static void 509 aac_startio(struct aac_softc *sc) 510 { 511 struct aac_command *cm; 512 513 debug_called(2); 514 515 for(;;) { 516 /* try to get a command that's been put off for lack of resources */ 517 cm = aac_dequeue_ready(sc); 518 519 /* try to build a command off the bio queue (ignore error return) */ 520 aac_bio_command(sc, &cm); 521 522 /* nothing to do? */ 523 if (cm == NULL) 524 break; 525 526 /* try to give the command to the controller */ 527 if (aac_start(cm) == EBUSY) { 528 /* put it on the ready queue for later */ 529 aac_requeue_ready(cm); 530 break; 531 } 532 } 533 } 534 535 /******************************************************************************** 536 * Deliver a command to the controller; allocate controller resources at the 537 * last moment when possible. 538 */ 539 static int 540 aac_start(struct aac_command *cm) 541 { 542 struct aac_softc *sc = cm->cm_sc; 543 544 debug_called(2); 545 546 /* get the command mapped */ 547 aac_map_command(cm); 548 549 /* fix up the address values */ 550 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib; 551 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys; 552 553 /* save a pointer to the command for speedy reverse-lookup */ 554 cm->cm_fib->Header.SenderData = (u_int32_t)cm; /* XXX ack, sizing */ 555 556 /* put the FIB on the outbound queue */ 557 if (aac_enqueue_fib(sc, AAC_ADAP_NORM_CMD_QUEUE, cm->cm_fib->Header.Size, 558 cm->cm_fib->Header.ReceiverFibAddress)) 559 return(EBUSY); 560 561 return(0); 562 } 563 564 /******************************************************************************** 565 * Handle notification of one or more FIBs coming from the controller. 566 */ 567 static void 568 aac_host_command(struct aac_softc *sc) 569 { 570 struct aac_fib *fib; 571 u_int32_t fib_size; 572 573 debug_called(1); 574 575 for (;;) { 576 if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, &fib_size, &fib)) 577 break; /* nothing to do */ 578 579 switch(fib->Header.Command) { 580 case AifRequest: 581 aac_handle_aif(sc, (struct aac_aif_command *)&fib->data[0]); 582 break; 583 default: 584 device_printf(sc->aac_dev, "unknown command from controller\n"); 585 AAC_PRINT_FIB(sc, fib); 586 break; 587 } 588 589 /* XXX reply to FIBs requesting responses ?? */ 590 /* XXX how do we return these FIBs to the controller? */ 591 } 592 } 593 594 /******************************************************************************** 595 * Handle notification of one or more FIBs completed by the controller 596 */ 597 static void 598 aac_host_response(struct aac_softc *sc) 599 { 600 struct aac_command *cm; 601 struct aac_fib *fib; 602 u_int32_t fib_size; 603 604 debug_called(2); 605 606 for (;;) { 607 /* look for completed FIBs on our queue */ 608 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size, &fib)) 609 break; /* nothing to do */ 610 611 /* get the command, unmap and queue for later processing */ 612 cm = (struct aac_command *)fib->Header.SenderData; 613 if (cm == NULL) { 614 AAC_PRINT_FIB(sc, fib); 615 } else { 616 aac_unmap_command(cm); /* XXX defer? */ 617 aac_enqueue_completed(cm); 618 } 619 } 620 621 /* handle completion processing */ 622 #if __FreeBSD_version >= 500005 623 taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete); 624 #else 625 aac_complete(sc, 0); 626 #endif 627 } 628 629 /******************************************************************************** 630 * Process completed commands. 631 */ 632 static void 633 aac_complete(void *context, int pending) 634 { 635 struct aac_softc *sc = (struct aac_softc *)context; 636 struct aac_command *cm; 637 638 debug_called(2); 639 640 /* pull completed commands off the queue */ 641 for (;;) { 642 cm = aac_dequeue_completed(sc); 643 if (cm == NULL) 644 return; 645 cm->cm_flags |= AAC_CMD_COMPLETED; 646 647 /* is there a completion handler? */ 648 if (cm->cm_complete != NULL) { 649 cm->cm_complete(cm); 650 } else { 651 /* assume that someone is sleeping on this command */ 652 wakeup(cm); 653 } 654 } 655 } 656 657 /******************************************************************************** 658 * Handle a bio submitted from a disk device. 659 */ 660 void 661 aac_submit_bio(struct bio *bp) 662 { 663 struct aac_disk *ad = (struct aac_disk *)bp->bio_dev->si_drv1; 664 struct aac_softc *sc = ad->ad_controller; 665 666 debug_called(2); 667 668 /* queue the BIO and try to get some work done */ 669 bioq_insert_tail(&sc->aac_bioq, bp); 670 aac_startio(sc); 671 } 672 673 /******************************************************************************** 674 * Get a bio and build a command to go with it. 675 */ 676 static int 677 aac_bio_command(struct aac_softc *sc, struct aac_command **cmp) 678 { 679 struct aac_command *cm; 680 struct aac_fib *fib; 681 struct aac_blockread *br; 682 struct aac_blockwrite *bw; 683 struct aac_disk *ad; 684 struct bio *bp; 685 int s; 686 687 debug_called(2); 688 689 /* get the resources we will need */ 690 cm = NULL; 691 s = splbio(); 692 if ((bp = bioq_first(&sc->aac_bioq))) 693 bioq_remove(&sc->aac_bioq, bp); 694 splx(s); 695 if (bp == NULL) /* no work? */ 696 goto fail; 697 if (aac_alloc_command(sc, &cm)) /* get a command */ 698 goto fail; 699 700 /* fill out the command */ 701 cm->cm_private = bp; 702 703 /* build the FIB */ 704 fib = cm->cm_fib; 705 fib->Header.XferState = 706 AAC_FIBSTATE_HOSTOWNED | 707 AAC_FIBSTATE_INITIALISED | 708 AAC_FIBSTATE_FROMHOST | 709 AAC_FIBSTATE_REXPECTED | 710 AAC_FIBSTATE_NORM; 711 fib->Header.Command = ContainerCommand; 712 fib->Header.Size = sizeof(struct aac_fib_header); 713 714 /* build the read/write request */ 715 ad = (struct aac_disk *)bp->bio_dev->si_drv1; 716 cm->cm_data = (void *)bp->bio_data; 717 cm->cm_datalen = bp->bio_bcount; 718 cm->cm_complete = aac_bio_complete; 719 if (BIO_IS_READ(bp)) { 720 br = (struct aac_blockread *)&fib->data[0]; 721 br->Command = VM_CtBlockRead; 722 br->ContainerId = ad->ad_container->co_mntobj.ObjectId; 723 br->BlockNumber = bp->bio_pblkno; 724 br->ByteCount = bp->bio_bcount; 725 fib->Header.Size += sizeof(struct aac_blockread); 726 cm->cm_sgtable = &br->SgMap; 727 cm->cm_flags |= AAC_CMD_DATAIN; 728 } else { 729 bw = (struct aac_blockwrite *)&fib->data[0]; 730 bw->Command = VM_CtBlockWrite; 731 bw->ContainerId = ad->ad_container->co_mntobj.ObjectId; 732 bw->BlockNumber = bp->bio_pblkno; 733 bw->ByteCount = bp->bio_bcount; 734 bw->Stable = CUNSTABLE; /* XXX what's appropriate here? */ 735 fib->Header.Size += sizeof(struct aac_blockwrite); 736 cm->cm_flags |= AAC_CMD_DATAOUT; 737 cm->cm_sgtable = &bw->SgMap; 738 } 739 740 *cmp = cm; 741 return(0); 742 743 fail: 744 if (bp != NULL) 745 bioq_insert_tail(&sc->aac_bioq, bp); 746 if (cm != NULL) 747 aac_release_command(cm); 748 return(ENOMEM); 749 } 750 751 /******************************************************************************** 752 * Handle a bio-instigated command that has been completed. 753 */ 754 static void 755 aac_bio_complete(struct aac_command *cm) 756 { 757 struct aac_softc *sc = cm->cm_sc; 758 struct aac_blockread_response *brr; 759 struct aac_blockwrite_response *bwr; 760 struct bio *bp; 761 AAC_FSAStatus status; 762 763 /* fetch relevant status and then release the command */ 764 bp = (struct bio *)cm->cm_private; 765 if (BIO_IS_READ(bp)) { 766 brr = (struct aac_blockread_response *)&cm->cm_fib->data[0]; 767 status = brr->Status; 768 } else { 769 bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0]; 770 status = bwr->Status; 771 } 772 aac_release_command(cm); 773 774 /* fix up the bio based on status */ 775 if (status == ST_OK) { 776 bp->bio_resid = 0; 777 } else { 778 bp->bio_error = EIO; 779 bp->bio_flags |= BIO_ERROR; 780 781 /* XXX be more verbose? */ 782 device_printf(sc->aac_dev, "I/O error %d (%s)\n", status, AAC_COMMAND_STATUS(status)); 783 } 784 aac_complete_bio(bp); /* XXX rename one of these functions! */ 785 } 786 787 /******************************************************************************** 788 * Submit a command to the controller, return when it completes. 789 */ 790 static int 791 aac_wait_command(struct aac_command *cm, int timeout) 792 { 793 int s, error = 0; 794 795 debug_called(2); 796 797 /* Put the command on the ready queue and get things going */ 798 aac_enqueue_ready(cm); 799 aac_startio(cm->cm_sc); 800 s = splbio(); 801 while(!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) { 802 error = tsleep(cm, PRIBIO, "aacwait", timeout * hz); 803 } 804 splx(s); 805 return(error); 806 } 807 808 /******************************************************************************** 809 ******************************************************************************** 810 Command Buffer Management 811 ******************************************************************************** 812 ********************************************************************************/ 813 814 /******************************************************************************** 815 * Allocate a command. 816 */ 817 static int 818 aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp) 819 { 820 struct aac_command *cm; 821 822 debug_called(3); 823 824 cm = aac_dequeue_free(sc); 825 if (cm == NULL) { 826 aac_alloc_command_cluster(sc); 827 cm = aac_dequeue_free(sc); 828 } 829 if (cm == NULL) 830 return(ENOMEM); 831 832 /* initialise the command/FIB */ 833 cm->cm_sgtable = NULL; 834 cm->cm_flags = 0; 835 cm->cm_complete = NULL; 836 cm->cm_private = NULL; 837 cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY; 838 cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB; 839 cm->cm_fib->Header.Flags = 0; 840 cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib); 841 842 /* 843 * These are duplicated in aac_start to cover the case where an 844 * intermediate stage may have destroyed them. They're left 845 * initialised here for debugging purposes only. 846 */ 847 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib; 848 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys; 849 850 *cmp = cm; 851 return(0); 852 } 853 854 /******************************************************************************** 855 * Release a command back to the freelist. 856 */ 857 static void 858 aac_release_command(struct aac_command *cm) 859 { 860 debug_called(3); 861 862 aac_enqueue_free(cm); 863 } 864 865 /******************************************************************************** 866 * Map helper for command cluster allocation. Tell each of the FIBs what its 867 * address in the adapter's space is, fill in a few other fields. 868 */ 869 static void 870 aac_map_command_cluster(void *arg, bus_dma_segment_t *segs, int nseg, int error) 871 { 872 struct aac_command_cluster *cmc = (struct aac_command_cluster *)arg; 873 874 debug_called(3); 875 876 cmc->cmc_fibphys = segs[0].ds_addr; 877 } 878 879 /******************************************************************************** 880 * Allocate and initialise a cluster of commands. 881 */ 882 static void 883 aac_alloc_command_cluster(struct aac_softc *sc) 884 { 885 struct aac_command_cluster *cmc; 886 struct aac_command *cm; 887 int i; 888 889 debug_called(1); 890 891 cmc = malloc(sizeof(struct aac_command_cluster), M_DEVBUF, M_NOWAIT); 892 if (cmc != NULL) { 893 bzero(cmc, sizeof(*cmc)); 894 895 /* allocate the FIB cluster in DMAable memory and load it */ 896 if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&cmc->cmc_fibs, BUS_DMA_NOWAIT, &cmc->cmc_fibmap)) { 897 free(cmc, M_DEVBUF); 898 return; 899 } 900 bus_dmamap_load(sc->aac_fib_dmat, cmc->cmc_fibmap, cmc->cmc_fibs, 901 AAC_CLUSTER_COUNT * sizeof(struct aac_fib), aac_map_command_cluster, cmc, 0); 902 903 aac_enqueue_cluster(sc, cmc); 904 for (i = 0; i < AAC_CLUSTER_COUNT; i++) { 905 cm = &cmc->cmc_command[i]; 906 cm->cm_sc = sc; 907 cm->cm_fib = cmc->cmc_fibs + i; 908 cm->cm_fibphys = cmc->cmc_fibphys + (i * sizeof(struct aac_fib)); 909 910 if (!bus_dmamap_create(sc->aac_buffer_dmat, 0, &cm->cm_datamap)) 911 aac_release_command(cm); 912 } 913 } else { 914 debug(2, "can't allocate memeory for command cluster"); 915 } 916 } 917 918 /******************************************************************************** 919 * Free a command cluster. 920 */ 921 static void 922 aac_free_command_cluster(struct aac_command_cluster *cmc) 923 { 924 struct aac_softc *sc = cmc->cmc_command[0].cm_sc; 925 int i; 926 927 debug_called(1); 928 929 for (i = 0; i < AAC_CLUSTER_COUNT; i++) 930 bus_dmamap_destroy(sc->aac_buffer_dmat, cmc->cmc_command[i].cm_datamap); 931 bus_dmamap_unload(sc->aac_fib_dmat, cmc->cmc_fibmap); 932 bus_dmamem_free(sc->aac_fib_dmat, cmc->cmc_fibs, cmc->cmc_fibmap); 933 934 free(cmc, M_DEVBUF); 935 } 936 937 /******************************************************************************** 938 * Command-mapping helper function - populate this command's s/g table. 939 */ 940 static void 941 aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) 942 { 943 struct aac_command *cm = (struct aac_command *)arg; 944 struct aac_fib *fib = cm->cm_fib; 945 struct aac_sg_table *sg; 946 int i; 947 948 debug_called(3); 949 950 /* find the s/g table */ 951 sg = cm->cm_sgtable; 952 953 /* copy into the FIB */ 954 if (sg != NULL) { 955 sg->SgCount = nseg; 956 for (i = 0; i < nseg; i++) { 957 sg->SgEntry[i].SgAddress = segs[i].ds_addr; 958 sg->SgEntry[i].SgByteCount = segs[i].ds_len; 959 } 960 /* update the FIB size for the s/g count */ 961 fib->Header.Size += nseg * sizeof(struct aac_sg_entry); 962 } 963 964 } 965 966 /******************************************************************************** 967 * Map a command into controller-visible space. 968 */ 969 static void 970 aac_map_command(struct aac_command *cm) 971 { 972 struct aac_softc *sc = cm->cm_sc; 973 974 debug_called(2); 975 976 /* don't map more than once */ 977 if (cm->cm_flags & AAC_CMD_MAPPED) 978 return; 979 980 if (cm->cm_datalen != 0) { 981 bus_dmamap_load(sc->aac_buffer_dmat, cm->cm_datamap, cm->cm_data, 982 cm->cm_datalen, aac_map_command_sg, cm, 0); 983 984 if (cm->cm_flags & AAC_CMD_DATAIN) 985 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, BUS_DMASYNC_PREREAD); 986 if (cm->cm_flags & AAC_CMD_DATAOUT) 987 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, BUS_DMASYNC_PREWRITE); 988 } 989 cm->cm_flags |= AAC_CMD_MAPPED; 990 } 991 992 /******************************************************************************** 993 * Unmap a command from controller-visible space. 994 */ 995 static void 996 aac_unmap_command(struct aac_command *cm) 997 { 998 struct aac_softc *sc = cm->cm_sc; 999 1000 debug_called(2); 1001 1002 if (!(cm->cm_flags & AAC_CMD_MAPPED)) 1003 return; 1004 1005 if (cm->cm_datalen != 0) { 1006 if (cm->cm_flags & AAC_CMD_DATAIN) 1007 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, BUS_DMASYNC_POSTREAD); 1008 if (cm->cm_flags & AAC_CMD_DATAOUT) 1009 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, BUS_DMASYNC_POSTWRITE); 1010 1011 bus_dmamap_unload(sc->aac_buffer_dmat, cm->cm_datamap); 1012 } 1013 cm->cm_flags &= ~AAC_CMD_MAPPED; 1014 } 1015 1016 /******************************************************************************** 1017 ******************************************************************************** 1018 Hardware Interface 1019 ******************************************************************************** 1020 ********************************************************************************/ 1021 1022 /******************************************************************************** 1023 * Initialise the adapter. 1024 */ 1025 static void 1026 aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1027 { 1028 struct aac_softc *sc = (struct aac_softc *)arg; 1029 1030 debug_called(1); 1031 1032 sc->aac_common_busaddr = segs[0].ds_addr; 1033 } 1034 1035 static int 1036 aac_init(struct aac_softc *sc) 1037 { 1038 struct aac_adapter_init *ip; 1039 time_t then; 1040 u_int32_t code; 1041 u_int8_t *qaddr; 1042 1043 debug_called(1); 1044 1045 /* 1046 * First wait for the adapter to come ready. 1047 */ 1048 then = time_second; 1049 do { 1050 code = AAC_GET_FWSTATUS(sc); 1051 if (code & AAC_SELF_TEST_FAILED) { 1052 device_printf(sc->aac_dev, "FATAL: selftest failed\n"); 1053 return(ENXIO); 1054 } 1055 if (code & AAC_KERNEL_PANIC) { 1056 device_printf(sc->aac_dev, "FATAL: controller kernel panic\n"); 1057 return(ENXIO); 1058 } 1059 if (time_second > (then + AAC_BOOT_TIMEOUT)) { 1060 device_printf(sc->aac_dev, "FATAL: controller not coming ready, status %x\n", code); 1061 return(ENXIO); 1062 } 1063 } while (!(code & AAC_UP_AND_RUNNING)); 1064 1065 /* 1066 * Create DMA tag for the common structure and allocate it. 1067 */ 1068 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */ 1069 1, 0, /* alignment, boundary */ 1070 BUS_SPACE_MAXADDR, /* lowaddr */ 1071 BUS_SPACE_MAXADDR, /* highaddr */ 1072 NULL, NULL, /* filter, filterarg */ 1073 sizeof(struct aac_common), 1,/* maxsize, nsegments */ 1074 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 1075 0, /* flags */ 1076 &sc->aac_common_dmat)) { 1077 device_printf(sc->aac_dev, "can't allocate common structure DMA tag\n"); 1078 return(ENOMEM); 1079 } 1080 if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common, BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) { 1081 device_printf(sc->aac_dev, "can't allocate common structure\n"); 1082 return(ENOMEM); 1083 } 1084 bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap, sc->aac_common, sizeof(*sc->aac_common), 1085 aac_common_map, sc, 0); 1086 bzero(sc->aac_common, sizeof(*sc->aac_common)); 1087 1088 /* 1089 * Fill in the init structure. This tells the adapter about the physical location 1090 * of various important shared data structures. 1091 */ 1092 ip = &sc->aac_common->ac_init; 1093 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION; 1094 1095 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr + fldoff(aac_common, ac_fibs); 1096 ip->AdapterFibsVirtualAddress = &sc->aac_common->ac_fibs[0]; 1097 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib); 1098 ip->AdapterFibAlign = sizeof(struct aac_fib); 1099 1100 ip->PrintfBufferAddress = sc->aac_common_busaddr + fldoff(aac_common, ac_printf); 1101 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE; 1102 1103 ip->HostPhysMemPages = 0; /* not used? */ 1104 ip->HostElapsedSeconds = time_second; /* reset later if invalid */ 1105 1106 /* 1107 * Initialise FIB queues. Note that it appears that the layout of the indexes 1108 * and the segmentation of the entries is mandated by the adapter, which is 1109 * only told about the base of the queue index fields. 1110 * 1111 * The initial values of the indices are assumed to inform the adapter 1112 * of the sizes of the respective queues. 1113 * 1114 * The Linux driver uses a much more complex scheme whereby several header 1115 * records are kept for each queue. We use a couple of generic list manipulation 1116 * functions which 'know' the size of each list by virtue of a table. 1117 */ 1118 qaddr = &sc->aac_common->ac_qbuf[0] + AAC_QUEUE_ALIGN; 1119 qaddr -= (u_int32_t)qaddr % AAC_QUEUE_ALIGN; 1120 sc->aac_queues = (struct aac_queue_table *)qaddr; 1121 ip->CommHeaderAddress = sc->aac_common_busaddr + ((u_int32_t)sc->aac_queues - (u_int32_t)sc->aac_common); 1122 bzero(sc->aac_queues, sizeof(struct aac_queue_table)); 1123 1124 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = AAC_HOST_NORM_CMD_ENTRIES; 1125 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = AAC_HOST_NORM_CMD_ENTRIES; 1126 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = AAC_HOST_HIGH_CMD_ENTRIES; 1127 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = AAC_HOST_HIGH_CMD_ENTRIES; 1128 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = AAC_ADAP_NORM_CMD_ENTRIES; 1129 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = AAC_ADAP_NORM_CMD_ENTRIES; 1130 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = AAC_ADAP_HIGH_CMD_ENTRIES; 1131 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = AAC_ADAP_HIGH_CMD_ENTRIES; 1132 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = AAC_HOST_NORM_RESP_ENTRIES; 1133 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = AAC_HOST_NORM_RESP_ENTRIES; 1134 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = AAC_HOST_HIGH_RESP_ENTRIES; 1135 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = AAC_HOST_HIGH_RESP_ENTRIES; 1136 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = AAC_ADAP_NORM_RESP_ENTRIES; 1137 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = AAC_ADAP_NORM_RESP_ENTRIES; 1138 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = AAC_ADAP_HIGH_RESP_ENTRIES; 1139 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = AAC_ADAP_HIGH_RESP_ENTRIES; 1140 sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] = &sc->aac_queues->qt_HostNormCmdQueue[0]; 1141 sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] = &sc->aac_queues->qt_HostHighCmdQueue[0]; 1142 sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] = &sc->aac_queues->qt_AdapNormCmdQueue[0]; 1143 sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] = &sc->aac_queues->qt_AdapHighCmdQueue[0]; 1144 sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] = &sc->aac_queues->qt_HostNormRespQueue[0]; 1145 sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] = &sc->aac_queues->qt_HostHighRespQueue[0]; 1146 sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] = &sc->aac_queues->qt_AdapNormRespQueue[0]; 1147 sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] = &sc->aac_queues->qt_AdapHighRespQueue[0]; 1148 1149 /* 1150 * Do controller-type-specific initialisation 1151 */ 1152 switch (sc->aac_hwif) { 1153 case AAC_HWIF_I960RX: 1154 AAC_SETREG4(sc, AAC_RX_ODBR, ~0); 1155 break; 1156 } 1157 1158 /* 1159 * Give the init structure to the controller. 1160 */ 1161 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT, 1162 sc->aac_common_busaddr + fldoff(aac_common, ac_init), 1163 0, 0, 0, NULL)) { 1164 device_printf(sc->aac_dev, "error establishing init structure\n"); 1165 return(EIO); 1166 } 1167 1168 return(0); 1169 } 1170 1171 /******************************************************************************** 1172 * Send a synchronous command to the controller and wait for a result. 1173 */ 1174 static int 1175 aac_sync_command(struct aac_softc *sc, u_int32_t command, 1176 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, 1177 u_int32_t *sp) 1178 { 1179 time_t then; 1180 u_int32_t status; 1181 1182 debug_called(3); 1183 1184 /* populate the mailbox */ 1185 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3); 1186 1187 /* ensure the sync command doorbell flag is cleared */ 1188 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1189 1190 /* then set it to signal the adapter */ 1191 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND); 1192 1193 /* spin waiting for the command to complete */ 1194 then = time_second; 1195 do { 1196 if (time_second > (then + AAC_IMMEDIATE_TIMEOUT)) { 1197 debug(2, "timed out"); 1198 return(EIO); 1199 } 1200 } while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND)); 1201 1202 /* clear the completion flag */ 1203 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1204 1205 /* get the command status */ 1206 status = AAC_GET_MAILBOXSTATUS(sc); 1207 if (sp != NULL) 1208 *sp = status; 1209 return(0); /* check command return status? */ 1210 } 1211 1212 /******************************************************************************** 1213 * Send a synchronous FIB to the controller and wait for a result. 1214 */ 1215 static int 1216 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate, 1217 void *data, u_int16_t datasize, 1218 void *result, u_int16_t *resultsize) 1219 { 1220 struct aac_fib *fib = &sc->aac_common->ac_sync_fib; 1221 1222 debug_called(3); 1223 1224 if (datasize > AAC_FIB_DATASIZE) 1225 return(EINVAL); 1226 1227 /* 1228 * Set up the sync FIB 1229 */ 1230 fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED | AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_EMPTY; 1231 fib->Header.XferState |= xferstate; 1232 fib->Header.Command = command; 1233 fib->Header.StructType = AAC_FIBTYPE_TFIB; 1234 fib->Header.Size = sizeof(struct aac_fib) + datasize; 1235 fib->Header.SenderSize = sizeof(struct aac_fib); 1236 fib->Header.SenderFibAddress = (u_int32_t)fib; 1237 fib->Header.ReceiverFibAddress = sc->aac_common_busaddr + fldoff(aac_common, ac_sync_fib); 1238 1239 /* 1240 * Copy in data. 1241 */ 1242 if (data != NULL) { 1243 bcopy(data, fib->data, datasize); 1244 fib->Header.XferState |= AAC_FIBSTATE_FROMHOST | AAC_FIBSTATE_NORM; 1245 } 1246 1247 /* 1248 * Give the FIB to the controller, wait for a response. 1249 */ 1250 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, fib->Header.ReceiverFibAddress, 1251 0, 0, 0, NULL)) { 1252 debug(2, "IO error"); 1253 return(EIO); 1254 } 1255 1256 /* 1257 * Copy out the result 1258 */ 1259 if (result != NULL) { 1260 *resultsize = fib->Header.Size - sizeof(struct aac_fib_header); 1261 bcopy(fib->data, result, *resultsize); 1262 } 1263 return(0); 1264 } 1265 1266 /******************************************************************************** 1267 * Adapter-space FIB queue manipulation 1268 * 1269 * Note that the queue implementation here is a little funky; neither the PI or 1270 * CI will ever be zero. This behaviour is a controller feature. 1271 */ 1272 static struct { 1273 int size; 1274 int notify; 1275 } aac_qinfo[] = { 1276 {AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL}, 1277 {AAC_HOST_HIGH_CMD_ENTRIES, 0}, 1278 {AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY}, 1279 {AAC_ADAP_HIGH_CMD_ENTRIES, 0}, 1280 {AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL}, 1281 {AAC_HOST_HIGH_RESP_ENTRIES, 0}, 1282 {AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY}, 1283 {AAC_ADAP_HIGH_RESP_ENTRIES, 0} 1284 }; 1285 1286 /* 1287 * Atomically insert an entry into the nominated queue, returns 0 on success or EBUSY 1288 * if the queue is full. 1289 * 1290 * XXX note that it would be more efficient to defer notifying the controller in 1291 * the case where we may be inserting several entries in rapid succession, but 1292 * implementing this usefully is difficult. 1293 */ 1294 static int 1295 aac_enqueue_fib(struct aac_softc *sc, int queue, u_int32_t fib_size, u_int32_t fib_addr) 1296 { 1297 u_int32_t pi, ci; 1298 int s, error; 1299 1300 debug_called(3); 1301 1302 s = splbio(); 1303 1304 /* get the producer/consumer indices */ 1305 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1306 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1307 1308 /* wrap the queue? */ 1309 if (pi >= aac_qinfo[queue].size) 1310 pi = 0; 1311 1312 /* check for queue full */ 1313 if ((pi + 1) == ci) { 1314 error = EBUSY; 1315 goto out; 1316 } 1317 1318 /* populate queue entry */ 1319 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size; 1320 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr; 1321 1322 /* update producer index */ 1323 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1; 1324 1325 /* notify the adapter if we know how */ 1326 if (aac_qinfo[queue].notify != 0) 1327 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1328 1329 error = 0; 1330 1331 out: 1332 splx(s); 1333 return(error); 1334 } 1335 1336 /* 1337 * Atomically remove one entry from the nominated queue, returns 0 on success or ENOENT 1338 * if the queue is empty. 1339 */ 1340 static int 1341 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size, struct aac_fib **fib_addr) 1342 { 1343 u_int32_t pi, ci; 1344 int s, error; 1345 1346 debug_called(3); 1347 1348 s = splbio(); 1349 1350 /* get the producer/consumer indices */ 1351 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1352 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1353 1354 /* check for queue empty */ 1355 if (ci == pi) { 1356 error = ENOENT; 1357 goto out; 1358 } 1359 1360 /* wrap the queue? */ 1361 if (ci >= aac_qinfo[queue].size) 1362 ci = 0; 1363 1364 /* fetch the entry */ 1365 *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size; 1366 *fib_addr = (struct aac_fib *)(sc->aac_qentries[queue] + ci)->aq_fib_addr; 1367 1368 /* update consumer index */ 1369 sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1; 1370 1371 /* if we have made the queue un-full, notify the adapter */ 1372 if (((pi + 1) == ci) && (aac_qinfo[queue].notify != 0)) 1373 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1374 error = 0; 1375 1376 out: 1377 splx(s); 1378 return(error); 1379 } 1380 1381 /******************************************************************************** 1382 ******************************************************************************** 1383 Interface Function Vectors 1384 ******************************************************************************** 1385 ********************************************************************************/ 1386 1387 /******************************************************************************** 1388 * Read the current firmware status word. 1389 */ 1390 static int 1391 aac_sa_get_fwstatus(struct aac_softc *sc) 1392 { 1393 debug_called(3); 1394 1395 return(AAC_GETREG4(sc, AAC_SA_FWSTATUS)); 1396 } 1397 1398 static int 1399 aac_rx_get_fwstatus(struct aac_softc *sc) 1400 { 1401 debug_called(3); 1402 1403 return(AAC_GETREG4(sc, AAC_RX_FWSTATUS)); 1404 } 1405 1406 /******************************************************************************** 1407 * Notify the controller of a change in a given queue 1408 */ 1409 1410 static void 1411 aac_sa_qnotify(struct aac_softc *sc, int qbit) 1412 { 1413 debug_called(3); 1414 1415 AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit); 1416 } 1417 1418 static void 1419 aac_rx_qnotify(struct aac_softc *sc, int qbit) 1420 { 1421 debug_called(3); 1422 1423 AAC_SETREG4(sc, AAC_RX_IDBR, qbit); 1424 } 1425 1426 /******************************************************************************** 1427 * Get the interrupt reason bits 1428 */ 1429 static int 1430 aac_sa_get_istatus(struct aac_softc *sc) 1431 { 1432 debug_called(3); 1433 1434 return(AAC_GETREG2(sc, AAC_SA_DOORBELL0)); 1435 } 1436 1437 static int 1438 aac_rx_get_istatus(struct aac_softc *sc) 1439 { 1440 debug_called(3); 1441 1442 return(AAC_GETREG4(sc, AAC_RX_ODBR)); 1443 } 1444 1445 /******************************************************************************** 1446 * Clear some interrupt reason bits 1447 */ 1448 static void 1449 aac_sa_clear_istatus(struct aac_softc *sc, int mask) 1450 { 1451 debug_called(3); 1452 1453 AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask); 1454 } 1455 1456 static void 1457 aac_rx_clear_istatus(struct aac_softc *sc, int mask) 1458 { 1459 debug_called(3); 1460 1461 AAC_SETREG4(sc, AAC_RX_ODBR, mask); 1462 } 1463 1464 /******************************************************************************** 1465 * Populate the mailbox and set the command word 1466 */ 1467 static void 1468 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command, 1469 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 1470 { 1471 debug_called(4); 1472 1473 AAC_SETREG4(sc, AAC_SA_MAILBOX, command); 1474 AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0); 1475 AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1); 1476 AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2); 1477 AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3); 1478 } 1479 1480 static void 1481 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command, 1482 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 1483 { 1484 debug_called(4); 1485 1486 AAC_SETREG4(sc, AAC_RX_MAILBOX, command); 1487 AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0); 1488 AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1); 1489 AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2); 1490 AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3); 1491 } 1492 1493 /******************************************************************************** 1494 * Fetch the immediate command status word 1495 */ 1496 static int 1497 aac_sa_get_mailboxstatus(struct aac_softc *sc) 1498 { 1499 debug_called(4); 1500 1501 return(AAC_GETREG4(sc, AAC_SA_MAILBOX)); 1502 } 1503 1504 static int 1505 aac_rx_get_mailboxstatus(struct aac_softc *sc) 1506 { 1507 debug_called(4); 1508 1509 return(AAC_GETREG4(sc, AAC_RX_MAILBOX)); 1510 } 1511 1512 /******************************************************************************** 1513 * Set/clear interrupt masks 1514 */ 1515 static void 1516 aac_sa_set_interrupts(struct aac_softc *sc, int enable) 1517 { 1518 debug(2, "%sable interrupts", enable ? "en" : "dis"); 1519 1520 if (enable) { 1521 AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS); 1522 } else { 1523 AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0); 1524 } 1525 } 1526 1527 static void 1528 aac_rx_set_interrupts(struct aac_softc *sc, int enable) 1529 { 1530 debug(2, "%sable interrupts", enable ? "en" : "dis"); 1531 1532 if (enable) { 1533 AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS); 1534 } else { 1535 AAC_SETREG4(sc, AAC_RX_OIMR, ~0); 1536 } 1537 } 1538 1539 /******************************************************************************** 1540 ******************************************************************************** 1541 Debugging and Diagnostics 1542 ******************************************************************************** 1543 ********************************************************************************/ 1544 1545 /******************************************************************************** 1546 * Print some information about the controller. 1547 */ 1548 static void 1549 aac_describe_controller(struct aac_softc *sc) 1550 { 1551 u_int8_t buf[AAC_FIB_DATASIZE]; /* XXX really a bit big for the stack */ 1552 u_int16_t bufsize; 1553 struct aac_adapter_info *info; 1554 u_int8_t arg; 1555 1556 debug_called(2); 1557 1558 arg = 0; 1559 if (aac_sync_fib(sc, RequestAdapterInfo, 0, &arg, sizeof(arg), &buf, &bufsize)) { 1560 device_printf(sc->aac_dev, "RequestAdapterInfo failed\n"); 1561 return; 1562 } 1563 if (bufsize != sizeof(*info)) { 1564 device_printf(sc->aac_dev, "RequestAdapterInfo returned wrong data size (%d != %d)\n", 1565 bufsize, sizeof(*info)); 1566 return; 1567 } 1568 info = (struct aac_adapter_info *)&buf[0]; 1569 1570 device_printf(sc->aac_dev, "%s %dMHz, %dMB total memory, %s (%d)\n", 1571 aac_describe_code(aac_cpu_variant, info->CpuVariant), info->ClockSpeed, 1572 info->TotalMem / (1024 * 1024), 1573 aac_describe_code(aac_battery_platform, info->batteryPlatform), info->batteryPlatform); 1574 1575 /* save the kernel revision structure for later use */ 1576 sc->aac_revision = info->KernelRevision; 1577 device_printf(sc->aac_dev, "Kernel %d.%d-%d, S/N %llx\n", 1578 info->KernelRevision.external.comp.major, 1579 info->KernelRevision.external.comp.minor, 1580 info->KernelRevision.external.comp.dash, 1581 info->SerialNumber); /* XXX how is this meant to be formatted? */ 1582 } 1583 1584 /******************************************************************************** 1585 * Look up a text description of a numeric error code and return a pointer to 1586 * same. 1587 */ 1588 static char * 1589 aac_describe_code(struct aac_code_lookup *table, u_int32_t code) 1590 { 1591 int i; 1592 1593 for (i = 0; table[i].string != NULL; i++) 1594 if (table[i].code == code) 1595 return(table[i].string); 1596 return(table[i+1].string); 1597 } 1598 1599 /***************************************************************************** 1600 ***************************************************************************** 1601 Management Interface 1602 ***************************************************************************** 1603 *****************************************************************************/ 1604 1605 static int 1606 aac_open(dev_t dev, int flags, int fmt, struct proc *p) 1607 { 1608 struct aac_softc *sc = dev->si_drv1; 1609 1610 debug_called(2); 1611 1612 /* Check to make sure the device isn't already open */ 1613 if (sc->aac_state & AAC_STATE_OPEN) { 1614 return EBUSY; 1615 } 1616 sc->aac_state |= AAC_STATE_OPEN; 1617 1618 return 0; 1619 } 1620 1621 static int 1622 aac_close(dev_t dev, int flags, int fmt, struct proc *p) 1623 { 1624 struct aac_softc *sc = dev->si_drv1; 1625 1626 debug_called(2); 1627 1628 /* Mark this unit as no longer open */ 1629 sc->aac_state &= ~AAC_STATE_OPEN; 1630 1631 return 0; 1632 } 1633 1634 static int 1635 aac_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p) 1636 { 1637 struct aac_softc *sc = dev->si_drv1; 1638 int error = 0, i; 1639 1640 debug_called(2); 1641 1642 switch (cmd) { 1643 #ifdef AAC_COMPAT_LINUX 1644 case FSACTL_SENDFIB: 1645 debug(0, "FSACTL_SENDFIB"); 1646 error = aac_ioctl_sendfib(sc, arg); 1647 break; 1648 case FSACTL_AIF_THREAD: 1649 debug(0, "FSACTL_AIF_THREAD"); 1650 error = EINVAL; 1651 break; 1652 case FSACTL_OPEN_GET_ADAPTER_FIB: 1653 debug(0, "FSACTL_OPEN_GET_ADAPTER_FIB"); 1654 /* 1655 * Pass the caller out an AdapterFibContext. 1656 * 1657 * Note that because we only support one opener, we 1658 * basically ignore this. Set the caller's context to a magic 1659 * number just in case. 1660 */ 1661 i = AAC_AIF_SILLYMAGIC; 1662 error = copyout(&i, arg, sizeof(i)); 1663 break; 1664 case FSACTL_GET_NEXT_ADAPTER_FIB: 1665 debug(0, "FSACTL_GET_NEXT_ADAPTER_FIB"); 1666 error = aac_linux_getnext_aif(sc, arg); 1667 break; 1668 case FSACTL_CLOSE_GET_ADAPTER_FIB: 1669 debug(0, "FSACTL_CLOSE_GET_ADAPTER_FIB"); 1670 /* don't do anything here */ 1671 break; 1672 case FSACTL_MINIPORT_REV_CHECK: 1673 debug(0, "FSACTL_MINIPORT_REV_CHECK"); 1674 error = aac_linux_rev_check(sc, arg); 1675 break; 1676 #endif 1677 default: 1678 device_printf(sc->aac_dev, "unsupported cmd 0x%lx\n", cmd); 1679 error = EINVAL; 1680 break; 1681 } 1682 return(error); 1683 } 1684 1685 /******************************************************************************** 1686 * Send a FIB supplied from userspace 1687 */ 1688 static int 1689 aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib) 1690 { 1691 struct aac_command *cm; 1692 int size, error; 1693 1694 debug_called(2); 1695 1696 cm = NULL; 1697 1698 /* 1699 * Get a command 1700 */ 1701 if (aac_alloc_command(sc, &cm)) { 1702 error = EBUSY; 1703 goto out; 1704 } 1705 1706 /* 1707 * Fetch the FIB header, then re-copy to get data as well. 1708 */ 1709 if ((error = copyin(ufib, cm->cm_fib, sizeof(struct aac_fib_header))) != 0) 1710 goto out; 1711 size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header); 1712 if (size > sizeof(struct aac_fib)) { 1713 device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n", size, sizeof(struct aac_fib)); 1714 size = sizeof(struct aac_fib); 1715 } 1716 if ((error = copyin(ufib, cm->cm_fib, size)) != 0) 1717 goto out; 1718 cm->cm_fib->Header.Size = size; 1719 1720 /* 1721 * Pass the FIB to the controller, wait for it to complete. 1722 */ 1723 if ((error = aac_wait_command(cm, 30)) != 0) /* XXX user timeout? */ 1724 goto out; 1725 1726 /* 1727 * Copy the FIB and data back out to the caller. 1728 */ 1729 size = cm->cm_fib->Header.Size; 1730 if (size > sizeof(struct aac_fib)) { 1731 device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n", size, sizeof(struct aac_fib)); 1732 size = sizeof(struct aac_fib); 1733 } 1734 error = copyout(cm->cm_fib, ufib, size); 1735 1736 out: 1737 if (cm != NULL) 1738 aac_release_command(cm); 1739 return(error); 1740 } 1741 1742 /******************************************************************************** 1743 * Handle an AIF sent to us by the controller; queue it for later reference. 1744 * 1745 * XXX what's the right thing to do here when the queue is full? Drop the older 1746 * or newer entries? 1747 */ 1748 static void 1749 aac_handle_aif(struct aac_softc *sc, struct aac_aif_command *aif) 1750 { 1751 int next, s; 1752 1753 debug_called(2); 1754 1755 s = splbio(); 1756 next = (sc->aac_aifq_head + 1) % AAC_AIFQ_LENGTH; 1757 if (next != sc->aac_aifq_tail) { 1758 bcopy(aif, &sc->aac_aifq[next], sizeof(struct aac_aif_command)); 1759 sc->aac_aifq_head = next; 1760 if (sc->aac_state & AAC_STATE_AIF_SLEEPER) 1761 wakeup(sc->aac_aifq); 1762 } 1763 splx(s); 1764 aac_print_aif(sc, aif); 1765 } 1766 1767 /******************************************************************************** 1768 * Hand the next AIF off the top of the queue out to userspace. 1769 */ 1770 static int 1771 aac_return_aif(struct aac_softc *sc, caddr_t uptr) 1772 { 1773 int error, s; 1774 1775 debug_called(2); 1776 1777 s = splbio(); 1778 if (sc->aac_aifq_tail == sc->aac_aifq_head) { 1779 error = EAGAIN; 1780 } else { 1781 error = copyout(&sc->aac_aifq[sc->aac_aifq_tail], uptr, sizeof(struct aac_aif_command)); 1782 if (!error) 1783 sc->aac_aifq_tail = (sc->aac_aifq_tail + 1) % AAC_AIFQ_LENGTH; 1784 } 1785 splx(s); 1786 return(error); 1787 } 1788 1789 /******************************************************************************** 1790 ******************************************************************************** 1791 Linux Management Interface 1792 ******************************************************************************** 1793 ********************************************************************************/ 1794 1795 #ifdef AAC_COMPAT_LINUX 1796 1797 #include <sys/proc.h> 1798 #include <machine/../linux/linux.h> 1799 #include <machine/../linux/linux_proto.h> 1800 #include <compat/linux/linux_ioctl.h> 1801 1802 #define AAC_LINUX_IOCTL_MIN 0x2000 1803 #define AAC_LINUX_IOCTL_MAX 0x21ff 1804 1805 static linux_ioctl_function_t aac_linux_ioctl; 1806 static struct linux_ioctl_handler aac_handler = {aac_linux_ioctl, AAC_LINUX_IOCTL_MIN, AAC_LINUX_IOCTL_MAX}; 1807 1808 SYSINIT (aac_register, SI_SUB_KLD, SI_ORDER_MIDDLE, linux_ioctl_register_handler, &aac_handler); 1809 SYSUNINIT(aac_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE, linux_ioctl_unregister_handler, &aac_handler); 1810 1811 MODULE_DEPEND(aac, linux, 1, 1, 1); 1812 1813 static int 1814 aac_linux_ioctl(struct proc *p, struct linux_ioctl_args *args) 1815 { 1816 struct file *fp = p->p_fd->fd_ofiles[args->fd]; 1817 u_long cmd = args->cmd; 1818 1819 /* 1820 * Pass the ioctl off to our standard handler. 1821 */ 1822 return(fo_ioctl(fp, cmd, (caddr_t)args->arg, p)); 1823 } 1824 1825 /******************************************************************************** 1826 * Return the Revision of the driver to the userspace and check to see if the 1827 * userspace app is possibly compatible. This is extremely bogus right now 1828 * because I have no idea how to handle the versioning of this driver. It is 1829 * needed, though, to get aaccli working. 1830 */ 1831 static int 1832 aac_linux_rev_check(struct aac_softc *sc, caddr_t udata) 1833 { 1834 struct aac_rev_check rev_check; 1835 struct aac_rev_check_resp rev_check_resp; 1836 int error = 0; 1837 1838 debug_called(2); 1839 1840 /* 1841 * Copyin the revision struct from userspace 1842 */ 1843 if ((error = copyin(udata, (caddr_t)&rev_check, sizeof(struct aac_rev_check))) != 0) { 1844 return error; 1845 } 1846 1847 debug(2, "Userland revision= %d\n", rev_check.callingRevision.buildNumber); 1848 1849 /* 1850 * Doctor up the response struct. 1851 */ 1852 rev_check_resp.possiblyCompatible = 1; 1853 rev_check_resp.adapterSWRevision.external.ul = sc->aac_revision.external.ul; 1854 rev_check_resp.adapterSWRevision.buildNumber = sc->aac_revision.buildNumber; 1855 1856 return(copyout((caddr_t)&rev_check_resp, udata, sizeof(struct aac_rev_check_resp))); 1857 } 1858 1859 /******************************************************************************** 1860 * Pass the caller the next AIF in their queue 1861 */ 1862 static int 1863 aac_linux_getnext_aif(struct aac_softc *sc, caddr_t arg) 1864 { 1865 struct get_adapter_fib_ioctl agf; 1866 int error, s; 1867 1868 debug_called(2); 1869 1870 if ((error = copyin(arg, &agf, sizeof(agf))) == 0) { 1871 1872 /* 1873 * Check the magic number that we gave the caller. 1874 */ 1875 if (agf.AdapterFibContext != AAC_AIF_SILLYMAGIC) { 1876 error = EFAULT; 1877 } else { 1878 1879 s = splbio(); 1880 error = aac_return_aif(sc, agf.AifFib); 1881 1882 if ((error == EAGAIN) && (agf.Wait)) { 1883 sc->aac_state |= AAC_STATE_AIF_SLEEPER; 1884 while (error == EAGAIN) { 1885 error = tsleep(sc->aac_aifq, PRIBIO | PCATCH, "aacaif", 0); 1886 if (error == 0) 1887 error = aac_return_aif(sc, agf.AifFib); 1888 } 1889 sc->aac_state &= ~AAC_STATE_AIF_SLEEPER; 1890 } 1891 splx(s); 1892 } 1893 } 1894 return(error); 1895 } 1896 1897 #endif /* AAC_COMPAT_LINUX */ 1898