1 /* $OpenBSD: aac.c,v 1.94 2022/04/16 19:19:58 naddy Exp $ */ 2 3 /*- 4 * Copyright (c) 2000 Michael Smith 5 * Copyright (c) 2001 Scott Long 6 * Copyright (c) 2000 BSDi 7 * Copyright (c) 2001 Adaptec, Inc. 8 * Copyright (c) 2000 Niklas Hallqvist 9 * Copyright (c) 2004 Nathan Binkert 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * $FreeBSD: /c/ncvs/src/sys/dev/aac/aac.c,v 1.1 2000/09/13 03:20:34 msmith Exp $ 34 */ 35 36 /* 37 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters. 38 */ 39 40 /* 41 * This driver would not have rewritten for OpenBSD if it was not for the 42 * hardware donation from Nocom. I want to thank them for their support. 43 * Of course, credit should go to Mike Smith for the original work he did 44 * in the FreeBSD driver where I found lots of reusable code and inspiration. 45 * - Niklas Hallqvist 46 */ 47 48 #include <sys/param.h> 49 #include <sys/systm.h> 50 #include <sys/buf.h> 51 #include <sys/device.h> 52 #include <sys/kernel.h> 53 #include <sys/kthread.h> 54 #include <sys/malloc.h> 55 #include <sys/rwlock.h> 56 #include <sys/selinfo.h> 57 #include <sys/time.h> 58 59 #include <machine/bus.h> 60 61 #include <uvm/uvm_extern.h> 62 63 #include <scsi/scsi_all.h> 64 #include <scsi/scsi_disk.h> 65 #include <scsi/scsiconf.h> 66 67 #include <dev/ic/aacreg.h> 68 #include <dev/ic/aacvar.h> 69 #include <dev/ic/aac_tables.h> 70 71 /* Geometry constants. */ 72 #define AAC_MAXCYLS 1024 73 #define AAC_HEADS 64 74 #define AAC_SECS 32 /* mapping 64*32 */ 75 #define AAC_MEDHEADS 127 76 #define AAC_MEDSECS 63 /* mapping 127*63 */ 77 #define AAC_BIGHEADS 255 78 #define AAC_BIGSECS 63 /* mapping 255*63 */ 79 #define AAC_SECS32 0x1f /* round capacity */ 80 81 struct scsi_xfer; 82 83 char *aac_describe_code(struct aac_code_lookup *, u_int32_t); 84 void aac_describe_controller(struct aac_softc *); 85 int aac_enqueue_fib(struct aac_softc *, int, struct aac_command *); 86 int aac_dequeue_fib(struct aac_softc *, int, u_int32_t *, 87 struct aac_fib **); 88 int aac_enqueue_response(struct aac_softc *sc, int queue, 89 struct aac_fib *fib); 90 91 void aac_eval_mapping(u_int32_t, int *, int *, int *); 92 void aac_print_printf(struct aac_softc *); 93 int aac_init(struct aac_softc *); 94 int aac_check_firmware(struct aac_softc *); 95 void aac_internal_cache_cmd(struct scsi_xfer *); 96 97 /* Command Processing */ 98 void aac_timeout(struct aac_softc *); 99 void aac_command_timeout(struct aac_command *); 100 int aac_map_command(struct aac_command *); 101 void aac_complete(void *); 102 int aac_bio_command(struct aac_softc *, struct aac_command **); 103 void aac_bio_complete(struct aac_command *); 104 int aac_wait_command(struct aac_command *, int); 105 void aac_create_thread(void *); 106 void aac_command_thread(void *); 107 108 /* Command Buffer Management */ 109 void aac_map_command_sg(void *, bus_dma_segment_t *, int, int); 110 int aac_alloc_commands(struct aac_softc *); 111 void aac_free_commands(struct aac_softc *); 112 void aac_unmap_command(struct aac_command *); 113 int aac_wait_command(struct aac_command *, int); 114 void * aac_alloc_command(void *); 115 void aac_scrub_command(struct aac_command *); 116 void aac_release_command(void *, void *); 117 int aac_alloc_sync_fib(struct aac_softc *, struct aac_fib **, int); 118 void aac_release_sync_fib(struct aac_softc *); 119 int aac_sync_fib(struct aac_softc *, u_int32_t, u_int32_t, 120 struct aac_fib *, u_int16_t); 121 122 void aac_scsi_cmd(struct scsi_xfer *); 123 void aac_startio(struct aac_softc *); 124 void aac_startup(struct aac_softc *); 125 int aac_sync_command(struct aac_softc *, u_int32_t, u_int32_t, 126 u_int32_t, u_int32_t, u_int32_t, u_int32_t *); 127 128 struct cfdriver aac_cd = { 129 NULL, "aac", DV_DULL 130 }; 131 132 const struct scsi_adapter aac_switch = { 133 aac_scsi_cmd, NULL, NULL, NULL, NULL 134 }; 135 136 /* Falcon/PPC interface */ 137 int aac_fa_get_fwstatus(struct aac_softc *); 138 void aac_fa_qnotify(struct aac_softc *, int); 139 int aac_fa_get_istatus(struct aac_softc *); 140 void aac_fa_clear_istatus(struct aac_softc *, int); 141 void aac_fa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t, u_int32_t, 142 u_int32_t, u_int32_t); 143 int aac_fa_get_mailbox(struct aac_softc *, int); 144 void aac_fa_set_interrupts(struct aac_softc *, int); 145 146 struct aac_interface aac_fa_interface = { 147 aac_fa_get_fwstatus, 148 aac_fa_qnotify, 149 aac_fa_get_istatus, 150 aac_fa_clear_istatus, 151 aac_fa_set_mailbox, 152 aac_fa_get_mailbox, 153 aac_fa_set_interrupts 154 }; 155 156 /* StrongARM interface */ 157 int aac_sa_get_fwstatus(struct aac_softc *); 158 void aac_sa_qnotify(struct aac_softc *, int); 159 int aac_sa_get_istatus(struct aac_softc *); 160 void aac_sa_clear_istatus(struct aac_softc *, int); 161 void aac_sa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t, 162 u_int32_t, u_int32_t, u_int32_t); 163 int aac_sa_get_mailbox(struct aac_softc *, int); 164 void aac_sa_set_interrupts(struct aac_softc *, int); 165 166 struct aac_interface aac_sa_interface = { 167 aac_sa_get_fwstatus, 168 aac_sa_qnotify, 169 aac_sa_get_istatus, 170 aac_sa_clear_istatus, 171 aac_sa_set_mailbox, 172 aac_sa_get_mailbox, 173 aac_sa_set_interrupts 174 }; 175 176 /* i960Rx interface */ 177 int aac_rx_get_fwstatus(struct aac_softc *); 178 void aac_rx_qnotify(struct aac_softc *, int); 179 int aac_rx_get_istatus(struct aac_softc *); 180 void aac_rx_clear_istatus(struct aac_softc *, int); 181 void aac_rx_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t, 182 u_int32_t, u_int32_t, u_int32_t); 183 int aac_rx_get_mailbox(struct aac_softc *, int); 184 void aac_rx_set_interrupts(struct aac_softc *, int); 185 186 struct aac_interface aac_rx_interface = { 187 aac_rx_get_fwstatus, 188 aac_rx_qnotify, 189 aac_rx_get_istatus, 190 aac_rx_clear_istatus, 191 aac_rx_set_mailbox, 192 aac_rx_get_mailbox, 193 aac_rx_set_interrupts 194 }; 195 196 /* Rocket/MIPS interface */ 197 int aac_rkt_get_fwstatus(struct aac_softc *); 198 void aac_rkt_qnotify(struct aac_softc *, int); 199 int aac_rkt_get_istatus(struct aac_softc *); 200 void aac_rkt_clear_istatus(struct aac_softc *, int); 201 void aac_rkt_set_mailbox(struct aac_softc *, u_int32_t, 202 u_int32_t, u_int32_t, 203 u_int32_t, u_int32_t); 204 int aac_rkt_get_mailbox(struct aac_softc *, int); 205 void aac_rkt_set_interrupts(struct aac_softc *, int); 206 207 struct aac_interface aac_rkt_interface = { 208 aac_rkt_get_fwstatus, 209 aac_rkt_qnotify, 210 aac_rkt_get_istatus, 211 aac_rkt_clear_istatus, 212 aac_rkt_set_mailbox, 213 aac_rkt_get_mailbox, 214 aac_rkt_set_interrupts 215 }; 216 217 #ifdef AAC_DEBUG 218 int aac_debug = AAC_DEBUG; 219 #endif 220 221 int 222 aac_attach(struct aac_softc *sc) 223 { 224 struct scsibus_attach_args saa; 225 int error; 226 227 /* 228 * Initialise per-controller queues. 229 */ 230 mtx_init(&sc->aac_free_mtx, IPL_BIO); 231 aac_initq_free(sc); 232 aac_initq_ready(sc); 233 aac_initq_busy(sc); 234 aac_initq_bio(sc); 235 236 /* disable interrupts before we enable anything */ 237 AAC_MASK_INTERRUPTS(sc); 238 239 /* mark controller as suspended until we get ourselves organised */ 240 sc->aac_state |= AAC_STATE_SUSPEND; 241 242 /* 243 * Check that the firmware on the card is supported. 244 */ 245 error = aac_check_firmware(sc); 246 if (error) 247 return (error); 248 249 /* 250 * Initialize locks 251 */ 252 AAC_LOCK_INIT(&sc->aac_sync_lock, "AAC sync FIB lock"); 253 AAC_LOCK_INIT(&sc->aac_aifq_lock, "AAC AIF lock"); 254 AAC_LOCK_INIT(&sc->aac_io_lock, "AAC I/O lock"); 255 AAC_LOCK_INIT(&sc->aac_container_lock, "AAC container lock"); 256 TAILQ_INIT(&sc->aac_container_tqh); 257 258 /* Initialize the local AIF queue pointers */ 259 sc->aac_aifq_head = sc->aac_aifq_tail = AAC_AIFQ_LENGTH; 260 261 /* 262 * Initialise the adapter. 263 */ 264 error = aac_init(sc); 265 if (error) 266 return (error); 267 268 269 saa.saa_adapter_softc = sc; 270 saa.saa_adapter = &aac_switch; 271 saa.saa_adapter_buswidth = AAC_MAX_CONTAINERS; 272 saa.saa_adapter_target = SDEV_NO_ADAPTER_TARGET; 273 saa.saa_luns = 8; 274 saa.saa_openings = (sc->total_fibs - 8) / 275 (sc->aac_container_count ? sc->aac_container_count : 1); 276 saa.saa_pool = &sc->aac_iopool; 277 saa.saa_wwpn = saa.saa_wwnn = 0; 278 saa.saa_quirks = saa.saa_flags = 0; 279 280 config_found(&sc->aac_dev, &saa, scsiprint); 281 282 /* Create the AIF thread */ 283 sc->aifthread = 0; 284 sc->aifflags = 0; 285 kthread_create_deferred(aac_create_thread, sc); 286 287 return (0); 288 } 289 290 void 291 aac_create_thread(void *arg) 292 { 293 struct aac_softc *sc = arg; 294 295 if (kthread_create(aac_command_thread, sc, &sc->aifthread, 296 sc->aac_dev.dv_xname)) { 297 /* TODO disable aac */ 298 printf("%s: failed to create kernel thread, disabled", 299 sc->aac_dev.dv_xname); 300 } 301 AAC_DPRINTF(AAC_D_MISC, ("%s: aac_create_thread\n", 302 sc->aac_dev.dv_xname)); 303 304 } 305 306 /* 307 * Probe for containers, create disks. 308 */ 309 void 310 aac_startup(struct aac_softc *sc) 311 { 312 struct aac_fib *fib; 313 struct aac_mntinfo *mi; 314 struct aac_mntinforesp *mir = NULL; 315 int count = 0, i = 0; 316 317 318 aac_alloc_sync_fib(sc, &fib, 0); 319 mi = (struct aac_mntinfo *)&fib->data[0]; 320 321 AAC_DPRINTF(AAC_D_MISC, ("%s: aac startup\n", sc->aac_dev.dv_xname)); 322 323 sc->aac_container_count = 0; 324 /* loop over possible containers */ 325 do { 326 /* request information on this container */ 327 bzero(mi, sizeof(struct aac_mntinfo)); 328 mi->Command = VM_NameServe; 329 mi->MntType = FT_FILESYS; 330 mi->MntCount = i; 331 if (aac_sync_fib(sc, ContainerCommand, 0, fib, 332 sizeof(struct aac_mntinfo))) { 333 printf("%s: error probing container %d\n", 334 sc->aac_dev.dv_xname, i); 335 continue; 336 } 337 338 mir = (struct aac_mntinforesp *)&fib->data[0]; 339 /* XXX Need to check if count changed */ 340 count = mir->MntRespCount; 341 342 /* 343 * Check container volume type for validity. Note 344 * that many of the possible types may never show up. 345 */ 346 if (mir->Status == ST_OK && 347 mir->MntTable[0].VolType != CT_NONE) { 348 int drv_cyls, drv_hds, drv_secs; 349 350 AAC_DPRINTF(AAC_D_MISC, 351 ("%s: %d: id %x name '%.16s' size %u type %d\n", 352 sc->aac_dev.dv_xname, i, 353 mir->MntTable[0].ObjectId, 354 mir->MntTable[0].FileSystemName, 355 mir->MntTable[0].Capacity, 356 mir->MntTable[0].VolType)); 357 358 sc->aac_container_count++; 359 sc->aac_hdr[i].hd_present = 1; 360 sc->aac_hdr[i].hd_size = mir->MntTable[0].Capacity; 361 362 /* 363 * Evaluate mapping (sectors per head, heads per cyl) 364 */ 365 sc->aac_hdr[i].hd_size &= ~AAC_SECS32; 366 aac_eval_mapping(sc->aac_hdr[i].hd_size, &drv_cyls, 367 &drv_hds, &drv_secs); 368 sc->aac_hdr[i].hd_heads = drv_hds; 369 sc->aac_hdr[i].hd_secs = drv_secs; 370 /* Round the size */ 371 sc->aac_hdr[i].hd_size = drv_cyls * drv_hds * drv_secs; 372 373 sc->aac_hdr[i].hd_devtype = mir->MntTable[0].VolType; 374 375 /* XXX Save the name too for use in IDENTIFY later */ 376 } 377 378 i++; 379 } while ((i < count) && (i < AAC_MAX_CONTAINERS)); 380 381 aac_release_sync_fib(sc); 382 383 /* mark the controller up */ 384 sc->aac_state &= ~AAC_STATE_SUSPEND; 385 386 /* enable interrupts now */ 387 AAC_UNMASK_INTERRUPTS(sc); 388 } 389 390 /* 391 * Take an interrupt. 392 */ 393 int 394 aac_intr(void *arg) 395 { 396 struct aac_softc *sc = arg; 397 u_int16_t reason; 398 399 400 /* 401 * Read the status register directly. This is faster than taking the 402 * driver lock and reading the queues directly. It also saves having 403 * to turn parts of the driver lock into a spin mutex, which would be 404 * ugly. 405 */ 406 reason = AAC_GET_ISTATUS(sc); 407 AAC_CLEAR_ISTATUS(sc, reason); 408 (void)AAC_GET_ISTATUS(sc); 409 410 if (reason == 0) 411 return (0); 412 413 AAC_DPRINTF(AAC_D_INTR, ("%s: intr: sc=%p: reason=%#x\n", 414 sc->aac_dev.dv_xname, sc, reason)); 415 416 /* controller wants to talk to us */ 417 if (reason & (AAC_DB_PRINTF | AAC_DB_COMMAND_READY | 418 AAC_DB_RESPONSE_READY)) { 419 420 if (reason & AAC_DB_RESPONSE_READY) { 421 /* handle completion processing */ 422 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) { 423 sc->aifflags |= AAC_AIFFLAGS_COMPLETE; 424 } else { 425 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 426 aac_complete(sc); 427 AAC_LOCK_RELEASE(&sc->aac_io_lock); 428 } 429 } 430 431 432 /* 433 * XXX Make sure that we don't get fooled by strange messages 434 * that start with a NULL. 435 */ 436 if (reason & AAC_DB_PRINTF) 437 if (sc->aac_common->ac_printf[0] == 0) 438 sc->aac_common->ac_printf[0] = 32; 439 440 /* 441 * This might miss doing the actual wakeup. However, the 442 * msleep that this is waking up has a timeout, so it will 443 * wake up eventually. AIFs and printfs are low enough 444 * priority that they can handle hanging out for a few seconds 445 * if needed. 446 */ 447 if (sc->aifthread) 448 wakeup(sc->aifthread); 449 450 } 451 452 return (1); 453 } 454 455 /* 456 * Command Processing 457 */ 458 459 /* 460 * Start as much queued I/O as possible on the controller 461 */ 462 void 463 aac_startio(struct aac_softc *sc) 464 { 465 struct aac_command *cm; 466 467 AAC_DPRINTF(AAC_D_CMD, ("%s: start command", sc->aac_dev.dv_xname)); 468 469 if (sc->flags & AAC_QUEUE_FRZN) { 470 AAC_DPRINTF(AAC_D_CMD, (": queue frozen")); 471 return; 472 } 473 474 AAC_DPRINTF(AAC_D_CMD, ("\n")); 475 476 for (;;) { 477 /* 478 * Try to get a command that's been put off for lack of 479 * resources 480 */ 481 cm = aac_dequeue_ready(sc); 482 483 /* 484 * Try to build a command off the bio queue (ignore error 485 * return) 486 */ 487 if (cm == NULL) { 488 AAC_DPRINTF(AAC_D_CMD, ("\n")); 489 aac_bio_command(sc, &cm); 490 AAC_DPRINTF(AAC_D_CMD, ("%s: start done bio", 491 sc->aac_dev.dv_xname)); 492 } 493 494 /* nothing to do? */ 495 if (cm == NULL) 496 break; 497 498 /* 499 * Try to give the command to the controller. Any error is 500 * catastrophic since it means that bus_dmamap_load() failed. 501 */ 502 if (aac_map_command(cm) != 0) 503 panic("aac: error mapping command %p", cm); 504 505 AAC_DPRINTF(AAC_D_CMD, ("\n%s: another command", 506 sc->aac_dev.dv_xname)); 507 } 508 509 AAC_DPRINTF(AAC_D_CMD, ("\n")); 510 } 511 512 /* 513 * Deliver a command to the controller; allocate controller resources at the 514 * last moment when possible. 515 */ 516 int 517 aac_map_command(struct aac_command *cm) 518 { 519 struct aac_softc *sc = cm->cm_sc; 520 int error = 0; 521 522 AAC_DPRINTF(AAC_D_CMD, (": map command")); 523 524 /* don't map more than once */ 525 if (cm->cm_flags & AAC_CMD_MAPPED) 526 panic("aac: command %p already mapped", cm); 527 528 if (cm->cm_datalen != 0) { 529 error = bus_dmamap_load(sc->aac_dmat, cm->cm_datamap, 530 cm->cm_data, cm->cm_datalen, NULL, 531 BUS_DMA_NOWAIT); 532 if (error) 533 return (error); 534 535 aac_map_command_sg(cm, cm->cm_datamap->dm_segs, 536 cm->cm_datamap->dm_nsegs, 0); 537 } else { 538 aac_map_command_sg(cm, NULL, 0, 0); 539 } 540 541 return (error); 542 } 543 544 /* 545 * Handle notification of one or more FIBs coming from the controller. 546 */ 547 void 548 aac_command_thread(void *arg) 549 { 550 struct aac_softc *sc = arg; 551 struct aac_fib *fib; 552 u_int32_t fib_size; 553 int size, retval; 554 555 AAC_DPRINTF(AAC_D_THREAD, ("%s: aac_command_thread: starting\n", 556 sc->aac_dev.dv_xname)); 557 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 558 sc->aifflags = AAC_AIFFLAGS_RUNNING; 559 560 while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) { 561 562 AAC_DPRINTF(AAC_D_THREAD, 563 ("%s: aac_command_thread: aifflags=%#x\n", 564 sc->aac_dev.dv_xname, sc->aifflags)); 565 retval = 0; 566 567 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0) { 568 AAC_DPRINTF(AAC_D_THREAD, 569 ("%s: command thread sleeping\n", 570 sc->aac_dev.dv_xname)); 571 AAC_LOCK_RELEASE(&sc->aac_io_lock); 572 retval = tsleep_nsec(sc->aifthread, PRIBIO, "aifthd", 573 SEC_TO_NSEC(AAC_PERIODIC_INTERVAL)); 574 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 575 } 576 577 if ((sc->aifflags & AAC_AIFFLAGS_COMPLETE) != 0) { 578 aac_complete(sc); 579 sc->aifflags &= ~AAC_AIFFLAGS_COMPLETE; 580 } 581 582 /* 583 * While we're here, check to see if any commands are stuck. 584 * This is pretty low-priority, so it's ok if it doesn't 585 * always fire. 586 */ 587 if (retval == EWOULDBLOCK) 588 aac_timeout(sc); 589 590 /* Check the hardware printf message buffer */ 591 if (sc->aac_common->ac_printf[0] != 0) 592 aac_print_printf(sc); 593 594 /* Also check to see if the adapter has a command for us. */ 595 while (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, 596 &fib_size, &fib) == 0) { 597 598 AAC_PRINT_FIB(sc, fib); 599 600 switch (fib->Header.Command) { 601 case AifRequest: 602 //aac_handle_aif(sc, fib); 603 break; 604 default: 605 printf("%s: unknown command from controller\n", 606 sc->aac_dev.dv_xname); 607 break; 608 } 609 610 if ((fib->Header.XferState == 0) || 611 (fib->Header.StructType != AAC_FIBTYPE_TFIB)) 612 break; 613 614 /* Return the AIF to the controller. */ 615 if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) { 616 fib->Header.XferState |= AAC_FIBSTATE_DONEHOST; 617 *(AAC_FSAStatus*)fib->data = ST_OK; 618 619 /* XXX Compute the Size field? */ 620 size = fib->Header.Size; 621 if (size > sizeof(struct aac_fib)) { 622 size = sizeof(struct aac_fib); 623 fib->Header.Size = size; 624 } 625 626 /* 627 * Since we did not generate this command, it 628 * cannot go through the normal 629 * enqueue->startio chain. 630 */ 631 aac_enqueue_response(sc, 632 AAC_ADAP_NORM_RESP_QUEUE, 633 fib); 634 } 635 } 636 } 637 sc->aifflags &= ~AAC_AIFFLAGS_RUNNING; 638 AAC_LOCK_RELEASE(&sc->aac_io_lock); 639 640 AAC_DPRINTF(AAC_D_THREAD, ("%s: aac_command_thread: exiting\n", 641 sc->aac_dev.dv_xname)); 642 kthread_exit(0); 643 } 644 645 /* 646 * Process completed commands. 647 */ 648 void 649 aac_complete(void *context) 650 { 651 struct aac_softc *sc = (struct aac_softc *)context; 652 struct aac_command *cm; 653 struct aac_fib *fib; 654 u_int32_t fib_size; 655 656 AAC_DPRINTF(AAC_D_CMD, ("%s: complete", sc->aac_dev.dv_xname)); 657 658 /* pull completed commands off the queue */ 659 for (;;) { 660 /* look for completed FIBs on our queue */ 661 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size, 662 &fib)) 663 break; /* nothing to do */ 664 665 /* get the command, unmap and hand off for processing */ 666 cm = sc->aac_commands + fib->Header.SenderData; 667 if (cm == NULL) { 668 AAC_PRINT_FIB(sc, fib); 669 break; 670 } 671 672 aac_remove_busy(cm); 673 aac_unmap_command(cm); 674 cm->cm_flags |= AAC_CMD_COMPLETED; 675 676 /* is there a completion handler? */ 677 if (cm->cm_complete != NULL) { 678 cm->cm_complete(cm); 679 } else { 680 /* assume that someone is sleeping on this command */ 681 wakeup(cm); 682 } 683 } 684 685 AAC_DPRINTF(AAC_D_CMD, ("\n")); 686 /* see if we can start some more I/O */ 687 sc->flags &= ~AAC_QUEUE_FRZN; 688 aac_startio(sc); 689 } 690 691 /* 692 * Get a bio and build a command to go with it. 693 */ 694 int 695 aac_bio_command(struct aac_softc *sc, struct aac_command **cmp) 696 { 697 struct aac_command *cm; 698 struct aac_fib *fib; 699 struct scsi_xfer *xs; 700 u_int8_t opcode = 0; 701 702 AAC_DPRINTF(AAC_D_CMD, ("%s: bio command", sc->aac_dev.dv_xname)); 703 704 /* get the resources we will need */ 705 if ((cm = aac_dequeue_bio(sc)) == NULL) 706 goto fail; 707 xs = cm->cm_private; 708 709 /* build the FIB */ 710 fib = cm->cm_fib; 711 fib->Header.Size = sizeof(struct aac_fib_header); 712 fib->Header.XferState = 713 AAC_FIBSTATE_HOSTOWNED | 714 AAC_FIBSTATE_INITIALISED | 715 AAC_FIBSTATE_EMPTY | 716 AAC_FIBSTATE_FROMHOST | 717 AAC_FIBSTATE_REXPECTED | 718 AAC_FIBSTATE_NORM | 719 AAC_FIBSTATE_ASYNC | 720 AAC_FIBSTATE_FAST_RESPONSE; 721 722 switch(xs->cmd.opcode) { 723 case READ_COMMAND: 724 case READ_10: 725 opcode = READ_COMMAND; 726 break; 727 case WRITE_COMMAND: 728 case WRITE_10: 729 opcode = WRITE_COMMAND; 730 break; 731 default: 732 panic("%s: invalid opcode %#x", sc->aac_dev.dv_xname, 733 xs->cmd.opcode); 734 } 735 736 /* build the read/write request */ 737 if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) { 738 fib->Header.Command = ContainerCommand; 739 if (opcode == READ_COMMAND) { 740 struct aac_blockread *br; 741 br = (struct aac_blockread *)&fib->data[0]; 742 br->Command = VM_CtBlockRead; 743 br->ContainerId = xs->sc_link->target; 744 br->BlockNumber = cm->cm_blkno; 745 br->ByteCount = cm->cm_bcount * AAC_BLOCK_SIZE; 746 fib->Header.Size += sizeof(struct aac_blockread); 747 cm->cm_sgtable = &br->SgMap; 748 cm->cm_flags |= AAC_CMD_DATAIN; 749 } else { 750 struct aac_blockwrite *bw; 751 bw = (struct aac_blockwrite *)&fib->data[0]; 752 bw->Command = VM_CtBlockWrite; 753 bw->ContainerId = xs->sc_link->target; 754 bw->BlockNumber = cm->cm_blkno; 755 bw->ByteCount = cm->cm_bcount * AAC_BLOCK_SIZE; 756 bw->Stable = CUNSTABLE; 757 fib->Header.Size += sizeof(struct aac_blockwrite); 758 cm->cm_flags |= AAC_CMD_DATAOUT; 759 cm->cm_sgtable = &bw->SgMap; 760 } 761 } else { 762 fib->Header.Command = ContainerCommand64; 763 if (opcode == READ_COMMAND) { 764 struct aac_blockread64 *br; 765 br = (struct aac_blockread64 *)&fib->data[0]; 766 br->Command = VM_CtHostRead64; 767 br->ContainerId = xs->sc_link->target; 768 br->BlockNumber = cm->cm_blkno; 769 br->SectorCount = cm->cm_bcount; 770 br->Pad = 0; 771 br->Flags = 0; 772 fib->Header.Size += sizeof(struct aac_blockread64); 773 cm->cm_flags |= AAC_CMD_DATAOUT; 774 cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64; 775 } else { 776 struct aac_blockwrite64 *bw; 777 bw = (struct aac_blockwrite64 *)&fib->data[0]; 778 bw->Command = VM_CtHostWrite64; 779 bw->ContainerId = xs->sc_link->target; 780 bw->BlockNumber = cm->cm_blkno; 781 bw->SectorCount = cm->cm_bcount; 782 bw->Pad = 0; 783 bw->Flags = 0; 784 fib->Header.Size += sizeof(struct aac_blockwrite64); 785 cm->cm_flags |= AAC_CMD_DATAIN; 786 cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64; 787 } 788 } 789 790 *cmp = cm; 791 AAC_DPRINTF(AAC_D_CMD, ("\n")); 792 return(0); 793 794 fail: 795 AAC_DPRINTF(AAC_D_CMD, ("\n")); 796 return(ENOMEM); 797 } 798 799 /* 800 * Handle a bio-instigated command that has been completed. 801 */ 802 void 803 aac_bio_complete(struct aac_command *cm) 804 { 805 struct aac_blockread_response *brr; 806 struct aac_blockwrite_response *bwr; 807 struct scsi_xfer *xs = (struct scsi_xfer *)cm->cm_private; 808 AAC_FSAStatus status; 809 int s; 810 811 AAC_DPRINTF(AAC_D_CMD, 812 ("%s: bio complete\n", cm->cm_sc->aac_dev.dv_xname)); 813 814 /* fetch relevant status and then release the command */ 815 if (xs->flags & SCSI_DATA_IN) { 816 brr = (struct aac_blockread_response *)&cm->cm_fib->data[0]; 817 status = brr->Status; 818 } else { 819 bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0]; 820 status = bwr->Status; 821 } 822 823 xs->error = status == ST_OK? XS_NOERROR : XS_DRIVER_STUFFUP; 824 xs->resid = 0; 825 s = splbio(); 826 scsi_done(xs); 827 splx(s); 828 } 829 830 /* 831 * Submit a command to the controller, return when it completes. 832 * XXX This is very dangerous! If the card has gone out to lunch, we could 833 * be stuck here forever. At the same time, signals are not caught 834 * because there is a risk that a signal could wakeup the tsleep before 835 * the card has a chance to complete the command. The passed in timeout 836 * is ignored for the same reason. Since there is no way to cancel a 837 * command in progress, we should probably create a 'dead' queue where 838 * commands go that have been interrupted/timed-out/etc, that keeps them 839 * out of the free pool. That way, if the card is just slow, it won't 840 * spam the memory of a command that has been recycled. 841 */ 842 int 843 aac_wait_command(struct aac_command *cm, int msecs) 844 { 845 struct aac_softc *sc = cm->cm_sc; 846 int error = 0; 847 848 AAC_DPRINTF(AAC_D_CMD, (": wait for command")); 849 850 /* Put the command on the ready queue and get things going */ 851 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; 852 aac_enqueue_ready(cm); 853 AAC_DPRINTF(AAC_D_CMD, ("\n")); 854 aac_startio(sc); 855 while (!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) { 856 AAC_DPRINTF(AAC_D_MISC, ("%s: sleeping until command done\n", 857 sc->aac_dev.dv_xname)); 858 AAC_LOCK_RELEASE(&sc->aac_io_lock); 859 error = tsleep_nsec(cm, PRIBIO, "aacwait", MSEC_TO_NSEC(msecs)); 860 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 861 } 862 return (error); 863 } 864 865 /* 866 *Command Buffer Management 867 */ 868 869 /* 870 * Allocate a command. 871 */ 872 void * 873 aac_alloc_command(void *xsc) 874 { 875 struct aac_softc *sc = xsc; 876 struct aac_command *cm; 877 878 AAC_DPRINTF(AAC_D_CMD, (": allocate command")); 879 mtx_enter(&sc->aac_free_mtx); 880 cm = aac_dequeue_free(sc); 881 mtx_leave(&sc->aac_free_mtx); 882 883 return (cm); 884 } 885 886 void 887 aac_scrub_command(struct aac_command *cm) 888 { 889 cm->cm_sgtable = NULL; 890 cm->cm_flags = 0; 891 cm->cm_complete = NULL; 892 cm->cm_private = NULL; 893 cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY; 894 cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB; 895 cm->cm_fib->Header.Flags = 0; 896 cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib); 897 } 898 899 /* 900 * Release a command back to the freelist. 901 */ 902 void 903 aac_release_command(void *xsc, void *xcm) 904 { 905 struct aac_softc *sc = xsc; 906 struct aac_command *cm = xcm; 907 AAC_DPRINTF(AAC_D_CMD, (": release command")); 908 909 mtx_enter(&sc->aac_free_mtx); 910 aac_enqueue_free(cm); 911 mtx_leave(&sc->aac_free_mtx); 912 } 913 914 /* 915 * Allocate and initialise commands/FIBs for this adapter. 916 */ 917 int 918 aac_alloc_commands(struct aac_softc *sc) 919 { 920 struct aac_command *cm; 921 struct aac_fibmap *fm; 922 int i, error = ENOMEM; 923 924 if (sc->total_fibs + AAC_FIB_COUNT > sc->aac_max_fibs) 925 return (ENOMEM); 926 927 fm = malloc(sizeof(*fm), M_DEVBUF, M_NOWAIT | M_ZERO); 928 if (fm == NULL) 929 goto exit; 930 931 /* allocate the FIBs in DMAable memory and load them */ 932 if (bus_dmamem_alloc(sc->aac_dmat, AAC_FIBMAP_SIZE, PAGE_SIZE, 0, 933 &fm->aac_seg, 1, &fm->aac_nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)) { 934 printf("%s: can't alloc FIBs\n", sc->aac_dev.dv_xname); 935 error = ENOBUFS; 936 goto exit_alloc; 937 } 938 939 if (bus_dmamem_map(sc->aac_dmat, &fm->aac_seg, 1, 940 AAC_FIBMAP_SIZE, (caddr_t *)&fm->aac_fibs, BUS_DMA_NOWAIT)) { 941 printf("%s: can't map FIB structure\n", sc->aac_dev.dv_xname); 942 error = ENOBUFS; 943 goto exit_map; 944 } 945 946 if (bus_dmamap_create(sc->aac_dmat, AAC_FIBMAP_SIZE, 1, 947 AAC_FIBMAP_SIZE, 0, BUS_DMA_NOWAIT, &fm->aac_fibmap)) { 948 printf("%s: can't create dma map\n", sc->aac_dev.dv_xname); 949 error = ENOBUFS; 950 goto exit_create; 951 } 952 953 if (bus_dmamap_load(sc->aac_dmat, fm->aac_fibmap, fm->aac_fibs, 954 AAC_FIBMAP_SIZE, NULL, BUS_DMA_NOWAIT)) { 955 printf("%s: can't load dma map\n", sc->aac_dev.dv_xname); 956 error = ENOBUFS; 957 goto exit_load; 958 } 959 960 /* initialise constant fields in the command structure */ 961 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 962 for (i = 0; i < AAC_FIB_COUNT; i++) { 963 cm = sc->aac_commands + sc->total_fibs; 964 fm->aac_commands = cm; 965 cm->cm_sc = sc; 966 cm->cm_fib = fm->aac_fibs + i; 967 cm->cm_fibphys = fm->aac_fibmap->dm_segs[0].ds_addr + 968 (i * sizeof(struct aac_fib)); 969 cm->cm_index = sc->total_fibs; 970 971 if (bus_dmamap_create(sc->aac_dmat, MAXPHYS, AAC_MAXSGENTRIES, 972 MAXPHYS, 0, BUS_DMA_NOWAIT, &cm->cm_datamap)) { 973 break; 974 } 975 aac_release_command(sc, cm); 976 sc->total_fibs++; 977 } 978 979 if (i > 0) { 980 TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link); 981 AAC_DPRINTF(AAC_D_MISC, ("%s: total_fibs= %d\n", 982 sc->aac_dev.dv_xname, 983 sc->total_fibs)); 984 AAC_LOCK_RELEASE(&sc->aac_io_lock); 985 return (0); 986 } 987 988 exit_load: 989 bus_dmamap_destroy(sc->aac_dmat, fm->aac_fibmap); 990 exit_create: 991 bus_dmamem_unmap(sc->aac_dmat, (caddr_t)fm->aac_fibs, AAC_FIBMAP_SIZE); 992 exit_map: 993 bus_dmamem_free(sc->aac_dmat, &fm->aac_seg, fm->aac_nsegs); 994 exit_alloc: 995 free(fm, M_DEVBUF, sizeof *fm); 996 exit: 997 AAC_LOCK_RELEASE(&sc->aac_io_lock); 998 return (error); 999 } 1000 1001 /* 1002 * Free FIBs owned by this adapter. 1003 */ 1004 void 1005 aac_free_commands(struct aac_softc *sc) 1006 { 1007 struct aac_fibmap *fm; 1008 struct aac_command *cm; 1009 int i; 1010 1011 while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) { 1012 1013 TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link); 1014 1015 /* 1016 * We check against total_fibs to handle partially 1017 * allocated blocks. 1018 */ 1019 for (i = 0; i < AAC_FIB_COUNT && sc->total_fibs--; i++) { 1020 cm = fm->aac_commands + i; 1021 bus_dmamap_destroy(sc->aac_dmat, cm->cm_datamap); 1022 } 1023 1024 bus_dmamap_unload(sc->aac_dmat, fm->aac_fibmap); 1025 bus_dmamap_destroy(sc->aac_dmat, fm->aac_fibmap); 1026 bus_dmamem_unmap(sc->aac_dmat, (caddr_t)fm->aac_fibs, 1027 AAC_FIBMAP_SIZE); 1028 bus_dmamem_free(sc->aac_dmat, &fm->aac_seg, fm->aac_nsegs); 1029 free(fm, M_DEVBUF, sizeof *fm); 1030 } 1031 } 1032 1033 1034 /* 1035 * Command-mapping helper function - populate this command's s/g table. 1036 */ 1037 void 1038 aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1039 { 1040 struct aac_command *cm = arg; 1041 struct aac_softc *sc = cm->cm_sc; 1042 struct aac_fib *fib = cm->cm_fib; 1043 int i; 1044 1045 /* copy into the FIB */ 1046 if (cm->cm_sgtable != NULL) { 1047 if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) { 1048 struct aac_sg_table *sg = cm->cm_sgtable; 1049 sg->SgCount = nseg; 1050 for (i = 0; i < nseg; i++) { 1051 sg->SgEntry[i].SgAddress = segs[i].ds_addr; 1052 sg->SgEntry[i].SgByteCount = segs[i].ds_len; 1053 } 1054 /* update the FIB size for the s/g count */ 1055 fib->Header.Size += nseg * sizeof(struct aac_sg_entry); 1056 } else { 1057 struct aac_sg_table64 *sg; 1058 sg = (struct aac_sg_table64 *)cm->cm_sgtable; 1059 sg->SgCount = nseg; 1060 for (i = 0; i < nseg; i++) { 1061 sg->SgEntry64[i].SgAddress = segs[i].ds_addr; 1062 sg->SgEntry64[i].SgByteCount = segs[i].ds_len; 1063 } 1064 /* update the FIB size for the s/g count */ 1065 fib->Header.Size += nseg*sizeof(struct aac_sg_entry64); 1066 } 1067 } 1068 1069 /* Fix up the address values in the FIB. Use the command array index 1070 * instead of a pointer since these fields are only 32 bits. Shift 1071 * the SenderFibAddress over to make room for the fast response bit. 1072 */ 1073 cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 1); 1074 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys; 1075 1076 /* save a pointer to the command for speedy reverse-lookup */ 1077 cm->cm_fib->Header.SenderData = cm->cm_index; 1078 1079 if (cm->cm_flags & AAC_CMD_DATAIN) 1080 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0, 1081 cm->cm_datamap->dm_mapsize, 1082 BUS_DMASYNC_PREREAD); 1083 if (cm->cm_flags & AAC_CMD_DATAOUT) 1084 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0, 1085 cm->cm_datamap->dm_mapsize, 1086 BUS_DMASYNC_PREWRITE); 1087 cm->cm_flags |= AAC_CMD_MAPPED; 1088 1089 /* put the FIB on the outbound queue */ 1090 if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) { 1091 aac_remove_busy(cm); 1092 aac_unmap_command(cm); 1093 aac_requeue_ready(cm); 1094 } 1095 } 1096 1097 /* 1098 * Unmap a command from controller-visible space. 1099 */ 1100 void 1101 aac_unmap_command(struct aac_command *cm) 1102 { 1103 struct aac_softc *sc = cm->cm_sc; 1104 1105 if (!(cm->cm_flags & AAC_CMD_MAPPED)) 1106 return; 1107 1108 if (cm->cm_datalen != 0) { 1109 if (cm->cm_flags & AAC_CMD_DATAIN) 1110 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0, 1111 cm->cm_datamap->dm_mapsize, 1112 BUS_DMASYNC_POSTREAD); 1113 if (cm->cm_flags & AAC_CMD_DATAOUT) 1114 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0, 1115 cm->cm_datamap->dm_mapsize, 1116 BUS_DMASYNC_POSTWRITE); 1117 1118 bus_dmamap_unload(sc->aac_dmat, cm->cm_datamap); 1119 } 1120 cm->cm_flags &= ~AAC_CMD_MAPPED; 1121 } 1122 1123 /* 1124 * Hardware Interface 1125 */ 1126 1127 /* 1128 * Initialise the adapter. 1129 */ 1130 int 1131 aac_check_firmware(struct aac_softc *sc) 1132 { 1133 u_int32_t major, minor, options; 1134 1135 /* 1136 * Retrieve the firmware version numbers. Dell PERC2/QC cards with 1137 * firmware version 1.x are not compatible with this driver. 1138 */ 1139 if (sc->flags & AAC_FLAGS_PERC2QC) { 1140 if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0, 1141 NULL)) { 1142 printf("%s: Error reading firmware version\n", 1143 sc->aac_dev.dv_xname); 1144 return (EIO); 1145 } 1146 1147 /* These numbers are stored as ASCII! */ 1148 major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30; 1149 minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30; 1150 if (major == 1) { 1151 printf("%s: Firmware version %d.%d is not supported\n", 1152 sc->aac_dev.dv_xname, major, minor); 1153 return (EINVAL); 1154 } 1155 } 1156 1157 /* 1158 * Retrieve the capabilities/supported options word so we know what 1159 * work-arounds to enable. 1160 */ 1161 if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, NULL)) { 1162 printf("%s: RequestAdapterInfo failed\n", 1163 sc->aac_dev.dv_xname); 1164 return (EIO); 1165 } 1166 options = AAC_GET_MAILBOX(sc, 1); 1167 sc->supported_options = options; 1168 1169 if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 && 1170 (sc->flags & AAC_FLAGS_NO4GB) == 0) 1171 sc->flags |= AAC_FLAGS_4GB_WINDOW; 1172 if (options & AAC_SUPPORTED_NONDASD) 1173 sc->flags |= AAC_FLAGS_ENABLE_CAM; 1174 if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0 1175 && (sizeof(bus_addr_t) > 4)) { 1176 printf("%s: Enabling 64-bit address support\n", 1177 sc->aac_dev.dv_xname); 1178 sc->flags |= AAC_FLAGS_SG_64BIT; 1179 } 1180 1181 /* Check for broken hardware that does a lower number of commands */ 1182 if ((sc->flags & AAC_FLAGS_256FIBS) == 0) 1183 sc->aac_max_fibs = AAC_MAX_FIBS; 1184 else 1185 sc->aac_max_fibs = 256; 1186 1187 return (0); 1188 } 1189 1190 int 1191 aac_init(struct aac_softc *sc) 1192 { 1193 bus_dma_segment_t seg; 1194 int nsegs; 1195 int i, error; 1196 int state = 0; 1197 struct aac_adapter_init *ip; 1198 time_t then; 1199 u_int32_t code, qoffset; 1200 1201 /* 1202 * First wait for the adapter to come ready. 1203 */ 1204 then = getuptime(); 1205 for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) { 1206 code = AAC_GET_FWSTATUS(sc); 1207 if (code & AAC_SELF_TEST_FAILED) { 1208 printf("%s: FATAL: selftest failed\n", 1209 sc->aac_dev.dv_xname); 1210 return (ENXIO); 1211 } 1212 if (code & AAC_KERNEL_PANIC) { 1213 printf("%s: FATAL: controller kernel panic\n", 1214 sc->aac_dev.dv_xname); 1215 return (ENXIO); 1216 } 1217 if (code & AAC_UP_AND_RUNNING) 1218 break; 1219 DELAY(1000); 1220 } 1221 if (i == AAC_BOOT_TIMEOUT * 1000) { 1222 printf("%s: FATAL: controller not coming ready, status %x\n", 1223 sc->aac_dev.dv_xname, code); 1224 return (ENXIO); 1225 } 1226 1227 /* 1228 * Work around a bug in the 2120 and 2200 that cannot DMA commands 1229 * below address 8192 in physical memory. 1230 * XXX If the padding is not needed, can it be put to use instead 1231 * of ignored? 1232 */ 1233 if (bus_dmamem_alloc(sc->aac_dmat, AAC_COMMON_ALLOCSIZE, PAGE_SIZE, 0, 1234 &seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)) { 1235 printf("%s: can't allocate common structure\n", 1236 sc->aac_dev.dv_xname); 1237 return (ENOMEM); 1238 } 1239 state++; 1240 1241 if (bus_dmamem_map(sc->aac_dmat, &seg, nsegs, AAC_COMMON_ALLOCSIZE, 1242 (caddr_t *)&sc->aac_common, BUS_DMA_NOWAIT)) { 1243 printf("%s: can't map common structure\n", 1244 sc->aac_dev.dv_xname); 1245 error = ENOMEM; 1246 goto bail_out; 1247 } 1248 state++; 1249 1250 if (bus_dmamap_create(sc->aac_dmat, AAC_COMMON_ALLOCSIZE, 1, 1251 AAC_COMMON_ALLOCSIZE, 0, BUS_DMA_NOWAIT, &sc->aac_common_map)) { 1252 printf("%s: can't create dma map\n", sc->aac_dev.dv_xname); 1253 error = ENOBUFS; 1254 goto bail_out; 1255 } 1256 state++; 1257 1258 if (bus_dmamap_load(sc->aac_dmat, sc->aac_common_map, sc->aac_common, 1259 AAC_COMMON_ALLOCSIZE, NULL, BUS_DMA_NOWAIT)) { 1260 printf("%s: can't load dma map\n", sc->aac_dev.dv_xname); 1261 error = ENOBUFS; 1262 goto bail_out; 1263 } 1264 state++; 1265 1266 sc->aac_common_busaddr = sc->aac_common_map->dm_segs[0].ds_addr; 1267 1268 if (sc->aac_common_busaddr < 8192) { 1269 sc->aac_common = (struct aac_common *) 1270 ((uint8_t *)sc->aac_common + 8192); 1271 sc->aac_common_busaddr += 8192; 1272 } 1273 1274 /* Allocate some FIBs and associated command structs */ 1275 TAILQ_INIT(&sc->aac_fibmap_tqh); 1276 sc->aac_commands = malloc(AAC_MAX_FIBS * sizeof(struct aac_command), 1277 M_DEVBUF, M_WAITOK | M_ZERO); 1278 while (sc->total_fibs < AAC_MAX_FIBS) { 1279 if (aac_alloc_commands(sc) != 0) 1280 break; 1281 } 1282 if (sc->total_fibs == 0) { 1283 error = ENOMEM; 1284 goto bail_out; 1285 } 1286 1287 scsi_iopool_init(&sc->aac_iopool, sc, 1288 aac_alloc_command, aac_release_command); 1289 1290 /* 1291 * Fill in the init structure. This tells the adapter about the 1292 * physical location of various important shared data structures. 1293 */ 1294 ip = &sc->aac_common->ac_init; 1295 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION; 1296 ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION; 1297 1298 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr + 1299 offsetof(struct aac_common, ac_fibs); 1300 ip->AdapterFibsVirtualAddress = 0; 1301 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib); 1302 ip->AdapterFibAlign = sizeof(struct aac_fib); 1303 1304 ip->PrintfBufferAddress = sc->aac_common_busaddr + 1305 offsetof(struct aac_common, ac_printf); 1306 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE; 1307 1308 /* 1309 * The adapter assumes that pages are 4K in size, except on some 1310 * broken firmware versions that do the page->byte conversion twice, 1311 * therefore 'assuming' that this value is in 16MB units (2^24). 1312 * Round up since the granularity is so high. 1313 */ 1314 ip->HostPhysMemPages = ptoa(physmem) / AAC_PAGE_SIZE; 1315 if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) { 1316 ip->HostPhysMemPages = 1317 (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE; 1318 } 1319 ip->HostElapsedSeconds = getuptime(); /* reset later if invalid */ 1320 1321 /* 1322 * Initialise FIB queues. Note that it appears that the layout of the 1323 * indexes and the segmentation of the entries may be mandated by the 1324 * adapter, which is only told about the base of the queue index fields. 1325 * 1326 * The initial values of the indices are assumed to inform the adapter 1327 * of the sizes of the respective queues, and theoretically it could 1328 * work out the entire layout of the queue structures from this. We 1329 * take the easy route and just lay this area out like everyone else 1330 * does. 1331 * 1332 * The Linux driver uses a much more complex scheme whereby several 1333 * header records are kept for each queue. We use a couple of generic 1334 * list manipulation functions which 'know' the size of each list by 1335 * virtue of a table. 1336 */ 1337 qoffset = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN; 1338 qoffset &= ~(AAC_QUEUE_ALIGN - 1); 1339 sc->aac_queues = 1340 (struct aac_queue_table *)((caddr_t)sc->aac_common + qoffset); 1341 ip->CommHeaderAddress = sc->aac_common_busaddr + qoffset; 1342 1343 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1344 AAC_HOST_NORM_CMD_ENTRIES; 1345 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1346 AAC_HOST_NORM_CMD_ENTRIES; 1347 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1348 AAC_HOST_HIGH_CMD_ENTRIES; 1349 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1350 AAC_HOST_HIGH_CMD_ENTRIES; 1351 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1352 AAC_ADAP_NORM_CMD_ENTRIES; 1353 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1354 AAC_ADAP_NORM_CMD_ENTRIES; 1355 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1356 AAC_ADAP_HIGH_CMD_ENTRIES; 1357 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1358 AAC_ADAP_HIGH_CMD_ENTRIES; 1359 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1360 AAC_HOST_NORM_RESP_ENTRIES; 1361 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1362 AAC_HOST_NORM_RESP_ENTRIES; 1363 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1364 AAC_HOST_HIGH_RESP_ENTRIES; 1365 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1366 AAC_HOST_HIGH_RESP_ENTRIES; 1367 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1368 AAC_ADAP_NORM_RESP_ENTRIES; 1369 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1370 AAC_ADAP_NORM_RESP_ENTRIES; 1371 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1372 AAC_ADAP_HIGH_RESP_ENTRIES; 1373 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1374 AAC_ADAP_HIGH_RESP_ENTRIES; 1375 sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] = 1376 &sc->aac_queues->qt_HostNormCmdQueue[0]; 1377 sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] = 1378 &sc->aac_queues->qt_HostHighCmdQueue[0]; 1379 sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] = 1380 &sc->aac_queues->qt_AdapNormCmdQueue[0]; 1381 sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] = 1382 &sc->aac_queues->qt_AdapHighCmdQueue[0]; 1383 sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] = 1384 &sc->aac_queues->qt_HostNormRespQueue[0]; 1385 sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] = 1386 &sc->aac_queues->qt_HostHighRespQueue[0]; 1387 sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] = 1388 &sc->aac_queues->qt_AdapNormRespQueue[0]; 1389 sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] = 1390 &sc->aac_queues->qt_AdapHighRespQueue[0]; 1391 1392 /* 1393 * Do controller-type-specific initialisation 1394 */ 1395 switch (sc->aac_hwif) { 1396 case AAC_HWIF_I960RX: 1397 AAC_SETREG4(sc, AAC_RX_ODBR, ~0); 1398 break; 1399 case AAC_HWIF_RKT: 1400 AAC_SETREG4(sc, AAC_RKT_ODBR, ~0); 1401 break; 1402 default: 1403 break; 1404 } 1405 1406 /* 1407 * Give the init structure to the controller. 1408 */ 1409 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT, 1410 sc->aac_common_busaddr + 1411 offsetof(struct aac_common, ac_init), 0, 0, 0, 1412 NULL)) { 1413 printf("%s: error establishing init structure\n", 1414 sc->aac_dev.dv_xname); 1415 error = EIO; 1416 goto bail_out; 1417 } 1418 1419 aac_describe_controller(sc); 1420 aac_startup(sc); 1421 1422 return (0); 1423 1424 bail_out: 1425 if (state > 3) 1426 bus_dmamap_unload(sc->aac_dmat, sc->aac_common_map); 1427 if (state > 2) 1428 bus_dmamap_destroy(sc->aac_dmat, sc->aac_common_map); 1429 if (state > 1) 1430 bus_dmamem_unmap(sc->aac_dmat, (caddr_t)sc->aac_common, 1431 sizeof *sc->aac_common); 1432 if (state > 0) 1433 bus_dmamem_free(sc->aac_dmat, &seg, 1); 1434 1435 return (error); 1436 } 1437 1438 /* 1439 * Send a synchronous command to the controller and wait for a result. 1440 */ 1441 int 1442 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 1443 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp) 1444 { 1445 // time_t then; 1446 int i; 1447 u_int32_t status; 1448 u_int16_t reason; 1449 1450 /* populate the mailbox */ 1451 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3); 1452 1453 /* ensure the sync command doorbell flag is cleared */ 1454 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1455 1456 /* then set it to signal the adapter */ 1457 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND); 1458 1459 DELAY(AAC_SYNC_DELAY); 1460 1461 /* spin waiting for the command to complete */ 1462 for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) { 1463 reason = AAC_GET_ISTATUS(sc); 1464 if (reason & AAC_DB_SYNC_COMMAND) 1465 break; 1466 reason = AAC_GET_ISTATUS(sc); 1467 if (reason & AAC_DB_SYNC_COMMAND) 1468 break; 1469 reason = AAC_GET_ISTATUS(sc); 1470 if (reason & AAC_DB_SYNC_COMMAND) 1471 break; 1472 DELAY(1000); 1473 } 1474 if (i == AAC_IMMEDIATE_TIMEOUT * 1000) { 1475 printf("aac_sync_command: failed, reason=%#x\n", reason); 1476 return (EIO); 1477 } 1478 1479 /* clear the completion flag */ 1480 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1481 1482 /* get the command status */ 1483 status = AAC_GET_MAILBOX(sc, 0); 1484 1485 if (sp != NULL) 1486 *sp = status; 1487 1488 return(0); 1489 } 1490 1491 /* 1492 * Grab the sync fib area. 1493 */ 1494 int 1495 aac_alloc_sync_fib(struct aac_softc *sc, struct aac_fib **fib, int flags) 1496 { 1497 1498 /* 1499 * If the force flag is set, the system is shutting down, or in 1500 * trouble. Ignore the mutex. 1501 */ 1502 if (!(flags & AAC_SYNC_LOCK_FORCE)) 1503 AAC_LOCK_ACQUIRE(&sc->aac_sync_lock); 1504 1505 *fib = &sc->aac_common->ac_sync_fib; 1506 1507 return (1); 1508 } 1509 1510 /* 1511 * Release the sync fib area. 1512 */ 1513 void 1514 aac_release_sync_fib(struct aac_softc *sc) 1515 { 1516 AAC_LOCK_RELEASE(&sc->aac_sync_lock); 1517 } 1518 1519 /* 1520 * Send a synchronous FIB to the controller and wait for a result. 1521 */ 1522 int 1523 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate, 1524 struct aac_fib *fib, u_int16_t datasize) 1525 { 1526 1527 if (datasize > AAC_FIB_DATASIZE) { 1528 printf("aac_sync_fib 1: datasize=%d AAC_FIB_DATASIZE %lu\n", 1529 datasize, AAC_FIB_DATASIZE); 1530 return(EINVAL); 1531 } 1532 1533 /* 1534 * Set up the sync FIB 1535 */ 1536 fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED | 1537 AAC_FIBSTATE_INITIALISED | 1538 AAC_FIBSTATE_EMPTY; 1539 fib->Header.XferState |= xferstate; 1540 fib->Header.Command = command; 1541 fib->Header.StructType = AAC_FIBTYPE_TFIB; 1542 fib->Header.Size = sizeof(struct aac_fib) + datasize; 1543 fib->Header.SenderSize = sizeof(struct aac_fib); 1544 fib->Header.SenderFibAddress = 0; /* Not needed */ 1545 fib->Header.ReceiverFibAddress = sc->aac_common_busaddr + 1546 offsetof(struct aac_common, 1547 ac_sync_fib); 1548 1549 /* 1550 * Give the FIB to the controller, wait for a response. 1551 */ 1552 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, 1553 fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) { 1554 AAC_DPRINTF(AAC_D_IO, ("%s: aac_sync_fib: IO error\n", 1555 sc->aac_dev.dv_xname)); 1556 printf("aac_sync_fib 2\n"); 1557 return(EIO); 1558 } 1559 1560 return (0); 1561 } 1562 1563 /***************************************************************************** 1564 * Adapter-space FIB queue manipulation 1565 * 1566 * Note that the queue implementation here is a little funky; neither the PI or 1567 * CI will ever be zero. This behaviour is a controller feature. 1568 */ 1569 static struct { 1570 int size; 1571 int notify; 1572 } aac_qinfo[] = { 1573 { AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL }, 1574 { AAC_HOST_HIGH_CMD_ENTRIES, 0 }, 1575 { AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY }, 1576 { AAC_ADAP_HIGH_CMD_ENTRIES, 0 }, 1577 { AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL }, 1578 { AAC_HOST_HIGH_RESP_ENTRIES, 0 }, 1579 { AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY }, 1580 { AAC_ADAP_HIGH_RESP_ENTRIES, 0 } 1581 }; 1582 1583 /* 1584 * Atomically insert an entry into the nominated queue, returns 0 on success 1585 * or EBUSY if the queue is full. 1586 * 1587 * Note: it would be more efficient to defer notifying the controller in 1588 * the case where we may be inserting several entries in rapid 1589 * succession, but implementing this usefully may be difficult 1590 * (it would involve a separate queue/notify interface). 1591 */ 1592 int 1593 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm) 1594 { 1595 u_int32_t pi, ci; 1596 int error; 1597 u_int32_t fib_size; 1598 u_int32_t fib_addr; 1599 1600 fib_size = cm->cm_fib->Header.Size; 1601 fib_addr = cm->cm_fib->Header.ReceiverFibAddress; 1602 1603 /* get the producer/consumer indices */ 1604 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1605 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1606 1607 /* wrap the queue? */ 1608 if (pi >= aac_qinfo[queue].size) 1609 pi = 0; 1610 1611 /* check for queue full */ 1612 if ((pi + 1) == ci) { 1613 error = EBUSY; 1614 goto out; 1615 } 1616 1617 /* populate queue entry */ 1618 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size; 1619 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr; 1620 1621 /* update producer index */ 1622 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1; 1623 1624 /* 1625 * To avoid a race with its completion interrupt, place this command on 1626 * the busy queue prior to advertising it to the controller. 1627 */ 1628 aac_enqueue_busy(cm); 1629 1630 /* notify the adapter if we know how */ 1631 if (aac_qinfo[queue].notify != 0) 1632 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1633 1634 error = 0; 1635 1636 out: 1637 return (error); 1638 } 1639 1640 /* 1641 * Atomically remove one entry from the nominated queue, returns 0 on success 1642 * or ENOENT if the queue is empty. 1643 */ 1644 int 1645 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size, 1646 struct aac_fib **fib_addr) 1647 { 1648 u_int32_t pi, ci; 1649 u_int32_t fib_index; 1650 int notify; 1651 int error; 1652 1653 /* get the producer/consumer indices */ 1654 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1655 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1656 1657 /* check for queue empty */ 1658 if (ci == pi) { 1659 error = ENOENT; 1660 goto out; 1661 } 1662 1663 /* wrap the pi so the following test works */ 1664 if (pi >= aac_qinfo[queue].size) 1665 pi = 0; 1666 1667 notify = 0; 1668 if (ci == pi + 1) 1669 notify++; 1670 1671 /* wrap the queue? */ 1672 if (ci >= aac_qinfo[queue].size) 1673 ci = 0; 1674 1675 /* fetch the entry */ 1676 *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size; 1677 1678 switch (queue) { 1679 case AAC_HOST_NORM_CMD_QUEUE: 1680 case AAC_HOST_HIGH_CMD_QUEUE: 1681 /* 1682 * The aq_fib_addr is only 32 bits wide so it can't be counted 1683 * on to hold an address. For AIF's, the adapter assumes 1684 * that it's giving us an address into the array of AIF fibs. 1685 * Therefore, we have to convert it to an index. 1686 */ 1687 fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr / 1688 sizeof(struct aac_fib); 1689 *fib_addr = &sc->aac_common->ac_fibs[fib_index]; 1690 break; 1691 1692 case AAC_HOST_NORM_RESP_QUEUE: 1693 case AAC_HOST_HIGH_RESP_QUEUE: 1694 { 1695 struct aac_command *cm; 1696 1697 /* 1698 * As above, an index is used instead of an actual address. 1699 * Gotta shift the index to account for the fast response 1700 * bit. No other correction is needed since this value was 1701 * originally provided by the driver via the SenderFibAddress 1702 * field. 1703 */ 1704 fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr; 1705 cm = sc->aac_commands + (fib_index >> 1); 1706 *fib_addr = cm->cm_fib; 1707 1708 /* 1709 * Is this a fast response? If it is, update the fib fields in 1710 * local memory since the whole fib isn't DMA'd back up. 1711 */ 1712 if (fib_index & 0x01) { 1713 (*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP; 1714 *((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL; 1715 } 1716 break; 1717 } 1718 default: 1719 panic("Invalid queue in aac_dequeue_fib()"); 1720 break; 1721 } 1722 1723 1724 /* update consumer index */ 1725 sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1; 1726 1727 /* if we have made the queue un-full, notify the adapter */ 1728 if (notify && (aac_qinfo[queue].notify != 0)) 1729 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1730 error = 0; 1731 1732 out: 1733 return (error); 1734 } 1735 1736 /* 1737 * Put our response to an Adapter Initialed Fib on the response queue 1738 */ 1739 int 1740 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib) 1741 { 1742 u_int32_t pi, ci; 1743 int error; 1744 u_int32_t fib_size; 1745 u_int32_t fib_addr; 1746 1747 /* Tell the adapter where the FIB is */ 1748 fib_size = fib->Header.Size; 1749 fib_addr = fib->Header.SenderFibAddress; 1750 fib->Header.ReceiverFibAddress = fib_addr; 1751 1752 /* get the producer/consumer indices */ 1753 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1754 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1755 1756 /* wrap the queue? */ 1757 if (pi >= aac_qinfo[queue].size) 1758 pi = 0; 1759 1760 /* check for queue full */ 1761 if ((pi + 1) == ci) { 1762 error = EBUSY; 1763 goto out; 1764 } 1765 1766 /* populate queue entry */ 1767 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size; 1768 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr; 1769 1770 /* update producer index */ 1771 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1; 1772 1773 /* notify the adapter if we know how */ 1774 if (aac_qinfo[queue].notify != 0) 1775 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1776 1777 error = 0; 1778 1779 out: 1780 return(error); 1781 } 1782 1783 void 1784 aac_command_timeout(struct aac_command *cm) 1785 { 1786 struct aac_softc *sc = cm->cm_sc; 1787 1788 printf("%s: COMMAND %p (flags=%#x) TIMEOUT AFTER %d SECONDS\n", 1789 sc->aac_dev.dv_xname, cm, cm->cm_flags, 1790 (int)(getuptime() - cm->cm_timestamp)); 1791 1792 if (cm->cm_flags & AAC_CMD_TIMEDOUT) 1793 return; 1794 1795 cm->cm_flags |= AAC_CMD_TIMEDOUT; 1796 1797 AAC_PRINT_FIB(sc, cm->cm_fib); 1798 1799 if (cm->cm_flags & AAC_ON_AACQ_BIO) { 1800 struct scsi_xfer *xs = cm->cm_private; 1801 int s = splbio(); 1802 xs->error = XS_DRIVER_STUFFUP; 1803 splx(s); 1804 scsi_done(xs); 1805 1806 aac_remove_bio(cm); 1807 aac_unmap_command(cm); 1808 } 1809 } 1810 1811 void 1812 aac_timeout(struct aac_softc *sc) 1813 { 1814 struct aac_command *cm; 1815 time_t deadline; 1816 1817 /* 1818 * Traverse the busy command list and timeout any commands 1819 * that are past their deadline. 1820 */ 1821 deadline = getuptime() - AAC_CMD_TIMEOUT; 1822 TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) { 1823 if (cm->cm_timestamp < deadline) 1824 aac_command_timeout(cm); 1825 } 1826 } 1827 1828 /* 1829 * Interface Function Vectors 1830 */ 1831 1832 /* 1833 * Read the current firmware status word. 1834 */ 1835 int 1836 aac_sa_get_fwstatus(struct aac_softc *sc) 1837 { 1838 return (AAC_GETREG4(sc, AAC_SA_FWSTATUS)); 1839 } 1840 1841 int 1842 aac_rx_get_fwstatus(struct aac_softc *sc) 1843 { 1844 return (AAC_GETREG4(sc, AAC_RX_FWSTATUS)); 1845 } 1846 1847 int 1848 aac_fa_get_fwstatus(struct aac_softc *sc) 1849 { 1850 return (AAC_GETREG4(sc, AAC_FA_FWSTATUS)); 1851 } 1852 1853 int 1854 aac_rkt_get_fwstatus(struct aac_softc *sc) 1855 { 1856 return(AAC_GETREG4(sc, AAC_RKT_FWSTATUS)); 1857 } 1858 1859 /* 1860 * Notify the controller of a change in a given queue 1861 */ 1862 1863 void 1864 aac_sa_qnotify(struct aac_softc *sc, int qbit) 1865 { 1866 AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit); 1867 } 1868 1869 void 1870 aac_rx_qnotify(struct aac_softc *sc, int qbit) 1871 { 1872 AAC_SETREG4(sc, AAC_RX_IDBR, qbit); 1873 } 1874 1875 void 1876 aac_fa_qnotify(struct aac_softc *sc, int qbit) 1877 { 1878 AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit); 1879 AAC_FA_HACK(sc); 1880 } 1881 1882 void 1883 aac_rkt_qnotify(struct aac_softc *sc, int qbit) 1884 { 1885 AAC_SETREG4(sc, AAC_RKT_IDBR, qbit); 1886 } 1887 1888 /* 1889 * Get the interrupt reason bits 1890 */ 1891 int 1892 aac_sa_get_istatus(struct aac_softc *sc) 1893 { 1894 return (AAC_GETREG2(sc, AAC_SA_DOORBELL0)); 1895 } 1896 1897 int 1898 aac_rx_get_istatus(struct aac_softc *sc) 1899 { 1900 return (AAC_GETREG4(sc, AAC_RX_ODBR)); 1901 } 1902 1903 int 1904 aac_fa_get_istatus(struct aac_softc *sc) 1905 { 1906 return (AAC_GETREG2(sc, AAC_FA_DOORBELL0)); 1907 } 1908 1909 int 1910 aac_rkt_get_istatus(struct aac_softc *sc) 1911 { 1912 return(AAC_GETREG4(sc, AAC_RKT_ODBR)); 1913 } 1914 1915 /* 1916 * Clear some interrupt reason bits 1917 */ 1918 void 1919 aac_sa_clear_istatus(struct aac_softc *sc, int mask) 1920 { 1921 AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask); 1922 } 1923 1924 void 1925 aac_rx_clear_istatus(struct aac_softc *sc, int mask) 1926 { 1927 AAC_SETREG4(sc, AAC_RX_ODBR, mask); 1928 } 1929 1930 void 1931 aac_fa_clear_istatus(struct aac_softc *sc, int mask) 1932 { 1933 AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask); 1934 AAC_FA_HACK(sc); 1935 } 1936 1937 void 1938 aac_rkt_clear_istatus(struct aac_softc *sc, int mask) 1939 { 1940 AAC_SETREG4(sc, AAC_RKT_ODBR, mask); 1941 } 1942 1943 /* 1944 * Populate the mailbox and set the command word 1945 */ 1946 void 1947 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 1948 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 1949 { 1950 AAC_SETREG4(sc, AAC_SA_MAILBOX, command); 1951 AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0); 1952 AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1); 1953 AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2); 1954 AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3); 1955 } 1956 1957 void 1958 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 1959 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 1960 { 1961 AAC_SETREG4(sc, AAC_RX_MAILBOX, command); 1962 AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0); 1963 AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1); 1964 AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2); 1965 AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3); 1966 } 1967 1968 void 1969 aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 1970 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 1971 { 1972 AAC_SETREG4(sc, AAC_FA_MAILBOX, command); 1973 AAC_FA_HACK(sc); 1974 AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0); 1975 AAC_FA_HACK(sc); 1976 AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1); 1977 AAC_FA_HACK(sc); 1978 AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2); 1979 AAC_FA_HACK(sc); 1980 AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3); 1981 AAC_FA_HACK(sc); 1982 } 1983 1984 void 1985 aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 1986 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 1987 { 1988 AAC_SETREG4(sc, AAC_RKT_MAILBOX, command); 1989 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0); 1990 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1); 1991 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2); 1992 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3); 1993 } 1994 1995 /* 1996 * Fetch the immediate command status word 1997 */ 1998 int 1999 aac_sa_get_mailbox(struct aac_softc *sc, int mb) 2000 { 2001 return (AAC_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4))); 2002 } 2003 2004 int 2005 aac_rx_get_mailbox(struct aac_softc *sc, int mb) 2006 { 2007 return (AAC_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4))); 2008 } 2009 2010 int 2011 aac_fa_get_mailbox(struct aac_softc *sc, int mb) 2012 { 2013 return (AAC_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4))); 2014 } 2015 2016 int 2017 aac_rkt_get_mailbox(struct aac_softc *sc, int mb) 2018 { 2019 return(AAC_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4))); 2020 } 2021 2022 /* 2023 * Set/clear interrupt masks 2024 */ 2025 void 2026 aac_sa_set_interrupts(struct aac_softc *sc, int enable) 2027 { 2028 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts\n", 2029 sc->aac_dev.dv_xname, enable ? "en" : "dis")); 2030 2031 if (enable) 2032 AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS); 2033 else 2034 AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0); 2035 } 2036 2037 void 2038 aac_rx_set_interrupts(struct aac_softc *sc, int enable) 2039 { 2040 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts", 2041 sc->aac_dev.dv_xname, enable ? "en" : "dis")); 2042 2043 if (enable) 2044 AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS); 2045 else 2046 AAC_SETREG4(sc, AAC_RX_OIMR, ~0); 2047 } 2048 2049 void 2050 aac_fa_set_interrupts(struct aac_softc *sc, int enable) 2051 { 2052 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts", 2053 sc->aac_dev.dv_xname, enable ? "en" : "dis")); 2054 2055 if (enable) { 2056 AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS); 2057 AAC_FA_HACK(sc); 2058 } else { 2059 AAC_SETREG2((sc), AAC_FA_MASK0, ~0); 2060 AAC_FA_HACK(sc); 2061 } 2062 } 2063 2064 void 2065 aac_rkt_set_interrupts(struct aac_softc *sc, int enable) 2066 { 2067 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts", 2068 sc->aac_dev.dv_xname, enable ? "en" : "dis")); 2069 2070 if (enable) 2071 AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS); 2072 else 2073 AAC_SETREG4(sc, AAC_RKT_OIMR, ~0); 2074 } 2075 2076 void 2077 aac_eval_mapping(size, cyls, heads, secs) 2078 u_int32_t size; 2079 int *cyls, *heads, *secs; 2080 { 2081 *cyls = size / AAC_HEADS / AAC_SECS; 2082 if (*cyls < AAC_MAXCYLS) { 2083 *heads = AAC_HEADS; 2084 *secs = AAC_SECS; 2085 } else { 2086 /* Too high for 64 * 32 */ 2087 *cyls = size / AAC_MEDHEADS / AAC_MEDSECS; 2088 if (*cyls < AAC_MAXCYLS) { 2089 *heads = AAC_MEDHEADS; 2090 *secs = AAC_MEDSECS; 2091 } else { 2092 /* Too high for 127 * 63 */ 2093 *cyls = size / AAC_BIGHEADS / AAC_BIGSECS; 2094 *heads = AAC_BIGHEADS; 2095 *secs = AAC_BIGSECS; 2096 } 2097 } 2098 } 2099 2100 /* Emulated SCSI operation on cache device */ 2101 void 2102 aac_internal_cache_cmd(struct scsi_xfer *xs) 2103 { 2104 struct scsi_link *link = xs->sc_link; 2105 struct aac_softc *sc = link->bus->sb_adapter_softc; 2106 struct scsi_inquiry_data inq; 2107 struct scsi_sense_data sd; 2108 struct scsi_read_cap_data rcd; 2109 u_int8_t target = link->target; 2110 2111 AAC_DPRINTF(AAC_D_CMD, ("%s: aac_internal_cache_cmd: ", 2112 sc->aac_dev.dv_xname)); 2113 2114 switch (xs->cmd.opcode) { 2115 case TEST_UNIT_READY: 2116 case START_STOP: 2117 #if 0 2118 case VERIFY: 2119 #endif 2120 AAC_DPRINTF(AAC_D_CMD, ("opc %#x tgt %d ", xs->cmd.opcode, 2121 target)); 2122 break; 2123 2124 case REQUEST_SENSE: 2125 AAC_DPRINTF(AAC_D_CMD, ("REQUEST SENSE tgt %d ", target)); 2126 bzero(&sd, sizeof sd); 2127 sd.error_code = SSD_ERRCODE_CURRENT; 2128 sd.segment = 0; 2129 sd.flags = SKEY_NO_SENSE; 2130 aac_enc32(sd.info, 0); 2131 sd.extra_len = 0; 2132 scsi_copy_internal_data(xs, &sd, sizeof(sd)); 2133 break; 2134 2135 case INQUIRY: 2136 AAC_DPRINTF(AAC_D_CMD, ("INQUIRY tgt %d devtype %x ", target, 2137 sc->aac_hdr[target].hd_devtype)); 2138 bzero(&inq, sizeof inq); 2139 /* XXX How do we detect removable/CD-ROM devices? */ 2140 inq.device = T_DIRECT; 2141 inq.dev_qual2 = 0; 2142 inq.version = SCSI_REV_2; 2143 inq.response_format = SID_SCSI2_RESPONSE; 2144 inq.additional_length = SID_SCSI2_ALEN; 2145 inq.flags |= SID_CmdQue; 2146 strlcpy(inq.vendor, "Adaptec", sizeof inq.vendor); 2147 snprintf(inq.product, sizeof inq.product, "Container #%02d", 2148 target); 2149 strlcpy(inq.revision, " ", sizeof inq.revision); 2150 scsi_copy_internal_data(xs, &inq, sizeof(inq)); 2151 break; 2152 2153 case READ_CAPACITY: 2154 AAC_DPRINTF(AAC_D_CMD, ("READ CAPACITY tgt %d ", target)); 2155 bzero(&rcd, sizeof rcd); 2156 _lto4b(sc->aac_hdr[target].hd_size - 1, rcd.addr); 2157 _lto4b(AAC_BLOCK_SIZE, rcd.length); 2158 scsi_copy_internal_data(xs, (u_int8_t *)&rcd, sizeof rcd); 2159 break; 2160 2161 default: 2162 AAC_DPRINTF(AAC_D_CMD, ("\n")); 2163 printf("aac_internal_cache_cmd got bad opcode: %#x\n", 2164 xs->cmd.opcode); 2165 xs->error = XS_DRIVER_STUFFUP; 2166 return; 2167 } 2168 2169 xs->error = XS_NOERROR; 2170 } 2171 2172 void 2173 aac_scsi_cmd(struct scsi_xfer *xs) 2174 { 2175 struct scsi_link *link = xs->sc_link; 2176 struct aac_softc *sc = link->bus->sb_adapter_softc; 2177 u_int8_t target = link->target; 2178 struct aac_command *cm; 2179 u_int32_t blockno, blockcnt; 2180 struct scsi_rw *rw; 2181 struct scsi_rw_10 *rw10; 2182 int s; 2183 2184 s = splbio(); 2185 2186 xs->error = XS_NOERROR; 2187 2188 if (target >= AAC_MAX_CONTAINERS || !sc->aac_hdr[target].hd_present || 2189 link->lun != 0) { 2190 /* 2191 * XXX Should be XS_SENSE but that would require setting up a 2192 * faked sense too. 2193 */ 2194 splx(s); 2195 xs->error = XS_DRIVER_STUFFUP; 2196 scsi_done(xs); 2197 return; 2198 } 2199 2200 AAC_DPRINTF(AAC_D_CMD, ("%s: aac_scsi_cmd: ", sc->aac_dev.dv_xname)); 2201 2202 xs->error = XS_NOERROR; 2203 cm = NULL; 2204 link = xs->sc_link; 2205 target = link->target; 2206 2207 switch (xs->cmd.opcode) { 2208 case TEST_UNIT_READY: 2209 case REQUEST_SENSE: 2210 case INQUIRY: 2211 case START_STOP: 2212 case READ_CAPACITY: 2213 #if 0 2214 case VERIFY: 2215 #endif 2216 aac_internal_cache_cmd(xs); 2217 scsi_done(xs); 2218 goto ready; 2219 2220 case PREVENT_ALLOW: 2221 AAC_DPRINTF(AAC_D_CMD, ("PREVENT/ALLOW ")); 2222 /* XXX Not yet implemented */ 2223 xs->error = XS_NOERROR; 2224 scsi_done(xs); 2225 goto ready; 2226 2227 case SYNCHRONIZE_CACHE: 2228 AAC_DPRINTF(AAC_D_CMD, ("SYNCHRONIZE_CACHE ")); 2229 /* XXX Not yet implemented */ 2230 xs->error = XS_NOERROR; 2231 scsi_done(xs); 2232 goto ready; 2233 2234 default: 2235 AAC_DPRINTF(AAC_D_CMD, ("unknown opc %#x ", xs->cmd.opcode)); 2236 /* XXX Not yet implemented */ 2237 xs->error = XS_DRIVER_STUFFUP; 2238 scsi_done(xs); 2239 goto ready; 2240 2241 case READ_COMMAND: 2242 case READ_10: 2243 case WRITE_COMMAND: 2244 case WRITE_10: 2245 AAC_DPRINTF(AAC_D_CMD, ("rw opc %#x ", xs->cmd.opcode)); 2246 2247 /* A read or write operation. */ 2248 if (xs->cmdlen == 6) { 2249 rw = (struct scsi_rw *)&xs->cmd; 2250 blockno = _3btol(rw->addr) & 2251 (SRW_TOPADDR << 16 | 0xffff); 2252 blockcnt = rw->length ? rw->length : 0x100; 2253 } else { 2254 rw10 = (struct scsi_rw_10 *)&xs->cmd; 2255 blockno = _4btol(rw10->addr); 2256 blockcnt = _2btol(rw10->length); 2257 } 2258 2259 AAC_DPRINTF(AAC_D_CMD, ("opcode=%d blkno=%d bcount=%d ", 2260 xs->cmd.opcode, blockno, blockcnt)); 2261 2262 if (blockno >= sc->aac_hdr[target].hd_size || 2263 blockno + blockcnt > sc->aac_hdr[target].hd_size) { 2264 AAC_DPRINTF(AAC_D_CMD, ("\n")); 2265 printf("%s: out of bounds %u-%u >= %u\n", 2266 sc->aac_dev.dv_xname, blockno, 2267 blockcnt, sc->aac_hdr[target].hd_size); 2268 /* 2269 * XXX Should be XS_SENSE but that 2270 * would require setting up a faked 2271 * sense too. 2272 */ 2273 xs->error = XS_DRIVER_STUFFUP; 2274 scsi_done(xs); 2275 goto ready; 2276 } 2277 2278 cm = xs->io; 2279 aac_scrub_command(cm); 2280 2281 /* fill out the command */ 2282 cm->cm_data = (void *)xs->data; 2283 cm->cm_datalen = xs->datalen; 2284 cm->cm_complete = aac_bio_complete; 2285 cm->cm_private = xs; 2286 cm->cm_timestamp = getuptime(); 2287 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; 2288 cm->cm_blkno = blockno; 2289 cm->cm_bcount = blockcnt; 2290 2291 AAC_DPRINTF(AAC_D_CMD, ("\n")); 2292 aac_enqueue_bio(cm); 2293 aac_startio(sc); 2294 2295 /* XXX what if enqueue did not start a transfer? */ 2296 if (xs->flags & SCSI_POLL) { 2297 if (!aac_wait_command(cm, xs->timeout)) 2298 { 2299 printf("%s: command timed out\n", 2300 sc->aac_dev.dv_xname); 2301 xs->error = XS_DRIVER_STUFFUP; 2302 scsi_done(xs); 2303 splx(s); 2304 return; 2305 } 2306 scsi_done(xs); 2307 } 2308 } 2309 2310 ready: 2311 splx(s); 2312 AAC_DPRINTF(AAC_D_CMD, ("%s: scsi_cmd complete\n", 2313 sc->aac_dev.dv_xname)); 2314 } 2315 2316 /* 2317 * Debugging and Diagnostics 2318 */ 2319 2320 /* 2321 * Print some information about the controller. 2322 */ 2323 void 2324 aac_describe_controller(struct aac_softc *sc) 2325 { 2326 struct aac_fib *fib; 2327 struct aac_adapter_info *info; 2328 2329 aac_alloc_sync_fib(sc, &fib, 0); 2330 2331 fib->data[0] = 0; 2332 if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) { 2333 printf("%s: RequestAdapterInfo failed 2\n", 2334 sc->aac_dev.dv_xname); 2335 aac_release_sync_fib(sc); 2336 return; 2337 } 2338 info = (struct aac_adapter_info *)&fib->data[0]; 2339 2340 printf("%s: %s %dMHz, %dMB cache memory, %s\n", sc->aac_dev.dv_xname, 2341 aac_describe_code(aac_cpu_variant, info->CpuVariant), 2342 info->ClockSpeed, info->BufferMem / (1024 * 1024), 2343 aac_describe_code(aac_battery_platform, info->batteryPlatform)); 2344 2345 /* save the kernel revision structure for later use */ 2346 sc->aac_revision = info->KernelRevision; 2347 printf("%s: Kernel %d.%d-%d, Build %d, S/N %6X\n", 2348 sc->aac_dev.dv_xname, 2349 info->KernelRevision.external.comp.major, 2350 info->KernelRevision.external.comp.minor, 2351 info->KernelRevision.external.comp.dash, 2352 info->KernelRevision.buildNumber, 2353 (u_int32_t)(info->SerialNumber & 0xffffff)); 2354 2355 aac_release_sync_fib(sc); 2356 } 2357 2358 /* 2359 * Look up a text description of a numeric error code and return a pointer to 2360 * same. 2361 */ 2362 char * 2363 aac_describe_code(struct aac_code_lookup *table, u_int32_t code) 2364 { 2365 int i; 2366 2367 for (i = 0; table[i].string != NULL; i++) 2368 if (table[i].code == code) 2369 return(table[i].string); 2370 return(table[i + 1].string); 2371 } 2372 2373 #ifdef AAC_DEBUG 2374 /* 2375 * Print a FIB 2376 */ 2377 void 2378 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller) 2379 { 2380 printf("%s: FIB @ %p\n", caller, fib); 2381 printf(" XferState %b\n", fib->Header.XferState, "\20" 2382 "\1HOSTOWNED" 2383 "\2ADAPTEROWNED" 2384 "\3INITIALISED" 2385 "\4EMPTY" 2386 "\5FROMPOOL" 2387 "\6FROMHOST" 2388 "\7FROMADAP" 2389 "\10REXPECTED" 2390 "\11RNOTEXPECTED" 2391 "\12DONEADAP" 2392 "\13DONEHOST" 2393 "\14HIGH" 2394 "\15NORM" 2395 "\16ASYNC" 2396 "\17PAGEFILEIO" 2397 "\20SHUTDOWN" 2398 "\21LAZYWRITE" 2399 "\22ADAPMICROFIB" 2400 "\23BIOSFIB" 2401 "\24FAST_RESPONSE" 2402 "\25APIFIB\n"); 2403 printf(" Command %d\n", fib->Header.Command); 2404 printf(" StructType %d\n", fib->Header.StructType); 2405 printf(" Flags 0x%x\n", fib->Header.Flags); 2406 printf(" Size %d\n", fib->Header.Size); 2407 printf(" SenderSize %d\n", fib->Header.SenderSize); 2408 printf(" SenderAddress 0x%x\n", fib->Header.SenderFibAddress); 2409 printf(" ReceiverAddress 0x%x\n", fib->Header.ReceiverFibAddress); 2410 printf(" SenderData 0x%x\n", fib->Header.SenderData); 2411 switch(fib->Header.Command) { 2412 case ContainerCommand: { 2413 struct aac_blockread *br = (struct aac_blockread *)fib->data; 2414 struct aac_blockwrite *bw = (struct aac_blockwrite *)fib->data; 2415 struct aac_sg_table *sg = NULL; 2416 int i; 2417 2418 if (br->Command == VM_CtBlockRead) { 2419 printf(" BlockRead: container %d 0x%x/%d\n", 2420 br->ContainerId, br->BlockNumber, br->ByteCount); 2421 sg = &br->SgMap; 2422 } 2423 if (bw->Command == VM_CtBlockWrite) { 2424 printf(" BlockWrite: container %d 0x%x/%d (%s)\n", 2425 bw->ContainerId, bw->BlockNumber, bw->ByteCount, 2426 bw->Stable == CSTABLE ? "stable" : "unstable"); 2427 sg = &bw->SgMap; 2428 } 2429 if (sg != NULL) { 2430 printf(" %d s/g entries\n", sg->SgCount); 2431 for (i = 0; i < sg->SgCount; i++) 2432 printf(" 0x%08x/%d\n", 2433 sg->SgEntry[i].SgAddress, 2434 sg->SgEntry[i].SgByteCount); 2435 } 2436 break; 2437 } 2438 default: 2439 printf(" %16D\n", fib->data, " "); 2440 printf(" %16D\n", fib->data + 16, " "); 2441 break; 2442 } 2443 } 2444 2445 /* 2446 * Describe an AIF we have received. 2447 */ 2448 void 2449 aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif) 2450 { 2451 printf("%s: print_aif: ", sc->aac_dev.dv_xname); 2452 2453 switch(aif->command) { 2454 case AifCmdEventNotify: 2455 printf("EventNotify(%d)\n", aif->seqNumber); 2456 2457 switch(aif->data.EN.type) { 2458 case AifEnGeneric: 2459 /* Generic notification */ 2460 printf("\t(Generic) %.*s\n", 2461 (int)sizeof(aif->data.EN.data.EG), 2462 aif->data.EN.data.EG.text); 2463 break; 2464 case AifEnTaskComplete: 2465 /* Task has completed */ 2466 printf("\t(TaskComplete)\n"); 2467 break; 2468 case AifEnConfigChange: 2469 /* Adapter configuration change occurred */ 2470 printf("\t(ConfigChange)\n"); 2471 break; 2472 case AifEnContainerChange: 2473 /* Adapter specific container configuration change */ 2474 printf("\t(ContainerChange) container %d,%d\n", 2475 aif->data.EN.data.ECC.container[0], 2476 aif->data.EN.data.ECC.container[1]); 2477 break; 2478 case AifEnDeviceFailure: 2479 /* SCSI device failed */ 2480 printf("\t(DeviceFailure) handle %d\n", 2481 aif->data.EN.data.EDF.deviceHandle); 2482 break; 2483 case AifEnMirrorFailover: 2484 /* Mirror failover started */ 2485 printf("\t(MirrorFailover) container %d failed, " 2486 "migrating from slice %d to %d\n", 2487 aif->data.EN.data.EMF.container, 2488 aif->data.EN.data.EMF.failedSlice, 2489 aif->data.EN.data.EMF.creatingSlice); 2490 break; 2491 case AifEnContainerEvent: 2492 /* Significant container event */ 2493 printf("\t(ContainerEvent) container %d event %d\n", 2494 aif->data.EN.data.ECE.container, 2495 aif->data.EN.data.ECE.eventType); 2496 break; 2497 case AifEnFileSystemChange: 2498 /* File system changed */ 2499 printf("\t(FileSystemChange)\n"); 2500 break; 2501 case AifEnConfigPause: 2502 /* Container pause event */ 2503 printf("\t(ConfigPause)\n"); 2504 break; 2505 case AifEnConfigResume: 2506 /* Container resume event */ 2507 printf("\t(ConfigResume)\n"); 2508 break; 2509 case AifEnFailoverChange: 2510 /* Failover space assignment changed */ 2511 printf("\t(FailoverChange)\n"); 2512 break; 2513 case AifEnRAID5RebuildDone: 2514 /* RAID5 rebuild finished */ 2515 printf("\t(RAID5RebuildDone)\n"); 2516 break; 2517 case AifEnEnclosureManagement: 2518 /* Enclosure management event */ 2519 printf("\t(EnclosureManagement) EMPID %d unit %d " 2520 "event %d\n", 2521 aif->data.EN.data.EEE.empID, 2522 aif->data.EN.data.EEE.unitID, 2523 aif->data.EN.data.EEE.eventType); 2524 break; 2525 case AifEnBatteryEvent: 2526 /* Significant NV battery event */ 2527 printf("\t(BatteryEvent) %d (state was %d, is %d\n", 2528 aif->data.EN.data.EBE.transition_type, 2529 aif->data.EN.data.EBE.current_state, 2530 aif->data.EN.data.EBE.prior_state); 2531 break; 2532 case AifEnAddContainer: 2533 /* A new container was created. */ 2534 printf("\t(AddContainer)\n"); 2535 break; 2536 case AifEnDeleteContainer: 2537 /* A container was deleted. */ 2538 printf("\t(DeleteContainer)\n"); 2539 break; 2540 case AifEnBatteryNeedsRecond: 2541 /* The battery needs reconditioning */ 2542 printf("\t(BatteryNeedsRecond)\n"); 2543 break; 2544 case AifEnClusterEvent: 2545 /* Some cluster event */ 2546 printf("\t(ClusterEvent) event %d\n", 2547 aif->data.EN.data.ECLE.eventType); 2548 break; 2549 case AifEnDiskSetEvent: 2550 /* A disk set event occurred. */ 2551 printf("(DiskSetEvent) event %d " 2552 "diskset %lld creator %lld\n", 2553 aif->data.EN.data.EDS.eventType, 2554 aif->data.EN.data.EDS.DsNum, 2555 aif->data.EN.data.EDS.CreatorId); 2556 break; 2557 case AifDenMorphComplete: 2558 /* A morph operation completed */ 2559 printf("\t(MorphComplete)\n"); 2560 break; 2561 case AifDenVolumeExtendComplete: 2562 /* A volume expand operation completed */ 2563 printf("\t(VolumeExtendComplete)\n"); 2564 break; 2565 default: 2566 printf("\t(%d)\n", aif->data.EN.type); 2567 break; 2568 } 2569 break; 2570 case AifCmdJobProgress: 2571 { 2572 char *status; 2573 switch(aif->data.PR[0].status) { 2574 case AifJobStsSuccess: 2575 status = "success"; break; 2576 case AifJobStsFinished: 2577 status = "finished"; break; 2578 case AifJobStsAborted: 2579 status = "aborted"; break; 2580 case AifJobStsFailed: 2581 status = "failed"; break; 2582 case AifJobStsSuspended: 2583 status = "suspended"; break; 2584 case AifJobStsRunning: 2585 status = "running"; break; 2586 default: 2587 status = "unknown status"; break; 2588 } 2589 2590 printf("JobProgress (%d) - %s (%d, %d)\n", 2591 aif->seqNumber, status, 2592 aif->data.PR[0].currentTick, 2593 aif->data.PR[0].finalTick); 2594 2595 switch(aif->data.PR[0].jd.type) { 2596 case AifJobScsiZero: 2597 /* SCSI dev clear operation */ 2598 printf("\t(ScsiZero) handle %d\n", 2599 aif->data.PR[0].jd.client.scsi_dh); 2600 break; 2601 case AifJobScsiVerify: 2602 /* SCSI device Verify operation NO REPAIR */ 2603 printf("\t(ScsiVerify) handle %d\n", 2604 aif->data.PR[0].jd.client.scsi_dh); 2605 break; 2606 case AifJobScsiExercise: 2607 /* SCSI device Exercise operation */ 2608 printf("\t(ScsiExercise) handle %d\n", 2609 aif->data.PR[0].jd.client.scsi_dh); 2610 break; 2611 case AifJobScsiVerifyRepair: 2612 /* SCSI device Verify operation WITH repair */ 2613 printf("\t(ScsiVerifyRepair) handle %d\n", 2614 aif->data.PR[0].jd.client.scsi_dh); 2615 break; 2616 case AifJobCtrZero: 2617 /* Container clear operation */ 2618 printf("\t(ContainerZero) container %d\n", 2619 aif->data.PR[0].jd.client.container.src); 2620 break; 2621 case AifJobCtrCopy: 2622 /* Container copy operation */ 2623 printf("\t(ContainerCopy) container %d to %d\n", 2624 aif->data.PR[0].jd.client.container.src, 2625 aif->data.PR[0].jd.client.container.dst); 2626 break; 2627 case AifJobCtrCreateMirror: 2628 /* Container Create Mirror operation */ 2629 printf("\t(ContainerCreateMirror) container %d\n", 2630 aif->data.PR[0].jd.client.container.src); 2631 /* XXX two containers? */ 2632 break; 2633 case AifJobCtrMergeMirror: 2634 /* Container Merge Mirror operation */ 2635 printf("\t(ContainerMergeMirror) container %d\n", 2636 aif->data.PR[0].jd.client.container.src); 2637 /* XXX two containers? */ 2638 break; 2639 case AifJobCtrScrubMirror: 2640 /* Container Scrub Mirror operation */ 2641 printf("\t(ContainerScrubMirror) container %d\n", 2642 aif->data.PR[0].jd.client.container.src); 2643 break; 2644 case AifJobCtrRebuildRaid5: 2645 /* Container Rebuild Raid5 operation */ 2646 printf("\t(ContainerRebuildRaid5) container %d\n", 2647 aif->data.PR[0].jd.client.container.src); 2648 break; 2649 case AifJobCtrScrubRaid5: 2650 /* Container Scrub Raid5 operation */ 2651 printf("\t(ContainerScrubRaid5) container %d\n", 2652 aif->data.PR[0].jd.client.container.src); 2653 break; 2654 case AifJobCtrMorph: 2655 /* Container morph operation */ 2656 printf("\t(ContainerMorph) container %d\n", 2657 aif->data.PR[0].jd.client.container.src); 2658 /* XXX two containers? */ 2659 break; 2660 case AifJobCtrPartCopy: 2661 /* Container Partition copy operation */ 2662 printf("\t(ContainerPartCopy) container %d to %d\n", 2663 aif->data.PR[0].jd.client.container.src, 2664 aif->data.PR[0].jd.client.container.dst); 2665 break; 2666 case AifJobCtrRebuildMirror: 2667 /* Container Rebuild Mirror operation */ 2668 printf("\t(ContainerRebuildMirror) container %d\n", 2669 aif->data.PR[0].jd.client.container.src); 2670 break; 2671 case AifJobCtrCrazyCache: 2672 /* crazy cache */ 2673 printf("\t(ContainerCrazyCache) container %d\n", 2674 aif->data.PR[0].jd.client.container.src); 2675 /* XXX two containers? */ 2676 break; 2677 case AifJobFsCreate: 2678 /* File System Create operation */ 2679 printf("\t(FsCreate)\n"); 2680 break; 2681 case AifJobFsVerify: 2682 /* File System Verify operation */ 2683 printf("\t(FsVerivy)\n"); 2684 break; 2685 case AifJobFsExtend: 2686 /* File System Extend operation */ 2687 printf("\t(FsExtend)\n"); 2688 break; 2689 case AifJobApiFormatNTFS: 2690 /* Format a drive to NTFS */ 2691 printf("\t(FormatNTFS)\n"); 2692 break; 2693 case AifJobApiFormatFAT: 2694 /* Format a drive to FAT */ 2695 printf("\t(FormatFAT)\n"); 2696 break; 2697 case AifJobApiUpdateSnapshot: 2698 /* update the read/write half of a snapshot */ 2699 printf("\t(UpdateSnapshot)\n"); 2700 break; 2701 case AifJobApiFormatFAT32: 2702 /* Format a drive to FAT32 */ 2703 printf("\t(FormatFAT32)\n"); 2704 break; 2705 case AifJobCtlContinuousCtrVerify: 2706 /* Adapter operation */ 2707 printf("\t(ContinuousCtrVerify)\n"); 2708 break; 2709 default: 2710 printf("\t(%d)\n", aif->data.PR[0].jd.type); 2711 break; 2712 } 2713 break; 2714 } 2715 case AifCmdAPIReport: 2716 printf("APIReport (%d)\n", aif->seqNumber); 2717 break; 2718 case AifCmdDriverNotify: 2719 printf("DriverNotify (%d)\n", aif->seqNumber); 2720 break; 2721 default: 2722 printf("AIF %d (%d)\n", aif->command, aif->seqNumber); 2723 break; 2724 } 2725 } 2726 #endif 2727