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