1 /* $OpenBSD: aac.c,v 1.91 2020/10/15 00:01:24 krw 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 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 goto out; 1284 1285 scsi_iopool_init(&sc->aac_iopool, sc, 1286 aac_alloc_command, aac_release_command); 1287 1288 /* 1289 * Fill in the init structure. This tells the adapter about the 1290 * physical location of various important shared data structures. 1291 */ 1292 ip = &sc->aac_common->ac_init; 1293 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION; 1294 ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION; 1295 1296 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr + 1297 offsetof(struct aac_common, ac_fibs); 1298 ip->AdapterFibsVirtualAddress = 0; 1299 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib); 1300 ip->AdapterFibAlign = sizeof(struct aac_fib); 1301 1302 ip->PrintfBufferAddress = sc->aac_common_busaddr + 1303 offsetof(struct aac_common, ac_printf); 1304 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE; 1305 1306 /* 1307 * The adapter assumes that pages are 4K in size, except on some 1308 * broken firmware versions that do the page->byte conversion twice, 1309 * therefore 'assuming' that this value is in 16MB units (2^24). 1310 * Round up since the granularity is so high. 1311 */ 1312 ip->HostPhysMemPages = ptoa(physmem) / AAC_PAGE_SIZE; 1313 if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) { 1314 ip->HostPhysMemPages = 1315 (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE; 1316 } 1317 ip->HostElapsedSeconds = getuptime(); /* reset later if invalid */ 1318 1319 /* 1320 * Initialise FIB queues. Note that it appears that the layout of the 1321 * indexes and the segmentation of the entries may be mandated by the 1322 * adapter, which is only told about the base of the queue index fields. 1323 * 1324 * The initial values of the indices are assumed to inform the adapter 1325 * of the sizes of the respective queues, and theoretically it could 1326 * work out the entire layout of the queue structures from this. We 1327 * take the easy route and just lay this area out like everyone else 1328 * does. 1329 * 1330 * The Linux driver uses a much more complex scheme whereby several 1331 * header records are kept for each queue. We use a couple of generic 1332 * list manipulation functions which 'know' the size of each list by 1333 * virtue of a table. 1334 */ 1335 qoffset = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN; 1336 qoffset &= ~(AAC_QUEUE_ALIGN - 1); 1337 sc->aac_queues = 1338 (struct aac_queue_table *)((caddr_t)sc->aac_common + qoffset); 1339 ip->CommHeaderAddress = sc->aac_common_busaddr + qoffset; 1340 1341 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1342 AAC_HOST_NORM_CMD_ENTRIES; 1343 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1344 AAC_HOST_NORM_CMD_ENTRIES; 1345 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1346 AAC_HOST_HIGH_CMD_ENTRIES; 1347 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1348 AAC_HOST_HIGH_CMD_ENTRIES; 1349 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1350 AAC_ADAP_NORM_CMD_ENTRIES; 1351 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1352 AAC_ADAP_NORM_CMD_ENTRIES; 1353 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1354 AAC_ADAP_HIGH_CMD_ENTRIES; 1355 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1356 AAC_ADAP_HIGH_CMD_ENTRIES; 1357 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1358 AAC_HOST_NORM_RESP_ENTRIES; 1359 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1360 AAC_HOST_NORM_RESP_ENTRIES; 1361 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1362 AAC_HOST_HIGH_RESP_ENTRIES; 1363 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1364 AAC_HOST_HIGH_RESP_ENTRIES; 1365 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1366 AAC_ADAP_NORM_RESP_ENTRIES; 1367 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1368 AAC_ADAP_NORM_RESP_ENTRIES; 1369 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1370 AAC_ADAP_HIGH_RESP_ENTRIES; 1371 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1372 AAC_ADAP_HIGH_RESP_ENTRIES; 1373 sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] = 1374 &sc->aac_queues->qt_HostNormCmdQueue[0]; 1375 sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] = 1376 &sc->aac_queues->qt_HostHighCmdQueue[0]; 1377 sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] = 1378 &sc->aac_queues->qt_AdapNormCmdQueue[0]; 1379 sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] = 1380 &sc->aac_queues->qt_AdapHighCmdQueue[0]; 1381 sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] = 1382 &sc->aac_queues->qt_HostNormRespQueue[0]; 1383 sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] = 1384 &sc->aac_queues->qt_HostHighRespQueue[0]; 1385 sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] = 1386 &sc->aac_queues->qt_AdapNormRespQueue[0]; 1387 sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] = 1388 &sc->aac_queues->qt_AdapHighRespQueue[0]; 1389 1390 /* 1391 * Do controller-type-specific initialisation 1392 */ 1393 switch (sc->aac_hwif) { 1394 case AAC_HWIF_I960RX: 1395 AAC_SETREG4(sc, AAC_RX_ODBR, ~0); 1396 break; 1397 case AAC_HWIF_RKT: 1398 AAC_SETREG4(sc, AAC_RKT_ODBR, ~0); 1399 break; 1400 default: 1401 break; 1402 } 1403 1404 /* 1405 * Give the init structure to the controller. 1406 */ 1407 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT, 1408 sc->aac_common_busaddr + 1409 offsetof(struct aac_common, ac_init), 0, 0, 0, 1410 NULL)) { 1411 printf("%s: error establishing init structure\n", 1412 sc->aac_dev.dv_xname); 1413 error = EIO; 1414 goto bail_out; 1415 } 1416 1417 aac_describe_controller(sc); 1418 aac_startup(sc); 1419 1420 return (0); 1421 1422 bail_out: 1423 if (state > 3) 1424 bus_dmamap_unload(sc->aac_dmat, sc->aac_common_map); 1425 if (state > 2) 1426 bus_dmamap_destroy(sc->aac_dmat, sc->aac_common_map); 1427 if (state > 1) 1428 bus_dmamem_unmap(sc->aac_dmat, (caddr_t)sc->aac_common, 1429 sizeof *sc->aac_common); 1430 if (state > 0) 1431 bus_dmamem_free(sc->aac_dmat, &seg, 1); 1432 1433 out: 1434 return (error); 1435 } 1436 1437 /* 1438 * Send a synchronous command to the controller and wait for a result. 1439 */ 1440 int 1441 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 1442 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp) 1443 { 1444 // time_t then; 1445 int i; 1446 u_int32_t status; 1447 u_int16_t reason; 1448 1449 /* populate the mailbox */ 1450 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3); 1451 1452 /* ensure the sync command doorbell flag is cleared */ 1453 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1454 1455 /* then set it to signal the adapter */ 1456 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND); 1457 1458 DELAY(AAC_SYNC_DELAY); 1459 1460 /* spin waiting for the command to complete */ 1461 for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) { 1462 reason = AAC_GET_ISTATUS(sc); 1463 if (reason & AAC_DB_SYNC_COMMAND) 1464 break; 1465 reason = AAC_GET_ISTATUS(sc); 1466 if (reason & AAC_DB_SYNC_COMMAND) 1467 break; 1468 reason = AAC_GET_ISTATUS(sc); 1469 if (reason & AAC_DB_SYNC_COMMAND) 1470 break; 1471 DELAY(1000); 1472 } 1473 if (i == AAC_IMMEDIATE_TIMEOUT * 1000) { 1474 printf("aac_sync_command: failed, reason=%#x\n", reason); 1475 return (EIO); 1476 } 1477 1478 /* clear the completion flag */ 1479 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1480 1481 /* get the command status */ 1482 status = AAC_GET_MAILBOX(sc, 0); 1483 1484 if (sp != NULL) 1485 *sp = status; 1486 1487 return(0); 1488 } 1489 1490 /* 1491 * Grab the sync fib area. 1492 */ 1493 int 1494 aac_alloc_sync_fib(struct aac_softc *sc, struct aac_fib **fib, int flags) 1495 { 1496 1497 /* 1498 * If the force flag is set, the system is shutting down, or in 1499 * trouble. Ignore the mutex. 1500 */ 1501 if (!(flags & AAC_SYNC_LOCK_FORCE)) 1502 AAC_LOCK_ACQUIRE(&sc->aac_sync_lock); 1503 1504 *fib = &sc->aac_common->ac_sync_fib; 1505 1506 return (1); 1507 } 1508 1509 /* 1510 * Release the sync fib area. 1511 */ 1512 void 1513 aac_release_sync_fib(struct aac_softc *sc) 1514 { 1515 AAC_LOCK_RELEASE(&sc->aac_sync_lock); 1516 } 1517 1518 /* 1519 * Send a synchronous FIB to the controller and wait for a result. 1520 */ 1521 int 1522 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate, 1523 struct aac_fib *fib, u_int16_t datasize) 1524 { 1525 1526 if (datasize > AAC_FIB_DATASIZE) { 1527 printf("aac_sync_fib 1: datasize=%d AAC_FIB_DATASIZE %lu\n", 1528 datasize, AAC_FIB_DATASIZE); 1529 return(EINVAL); 1530 } 1531 1532 /* 1533 * Set up the sync FIB 1534 */ 1535 fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED | 1536 AAC_FIBSTATE_INITIALISED | 1537 AAC_FIBSTATE_EMPTY; 1538 fib->Header.XferState |= xferstate; 1539 fib->Header.Command = command; 1540 fib->Header.StructType = AAC_FIBTYPE_TFIB; 1541 fib->Header.Size = sizeof(struct aac_fib) + datasize; 1542 fib->Header.SenderSize = sizeof(struct aac_fib); 1543 fib->Header.SenderFibAddress = 0; /* Not needed */ 1544 fib->Header.ReceiverFibAddress = sc->aac_common_busaddr + 1545 offsetof(struct aac_common, 1546 ac_sync_fib); 1547 1548 /* 1549 * Give the FIB to the controller, wait for a response. 1550 */ 1551 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, 1552 fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) { 1553 AAC_DPRINTF(AAC_D_IO, ("%s: aac_sync_fib: IO error\n", 1554 sc->aac_dev.dv_xname)); 1555 printf("aac_sync_fib 2\n"); 1556 return(EIO); 1557 } 1558 1559 return (0); 1560 } 1561 1562 /***************************************************************************** 1563 * Adapter-space FIB queue manipulation 1564 * 1565 * Note that the queue implementation here is a little funky; neither the PI or 1566 * CI will ever be zero. This behaviour is a controller feature. 1567 */ 1568 static struct { 1569 int size; 1570 int notify; 1571 } aac_qinfo[] = { 1572 { AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL }, 1573 { AAC_HOST_HIGH_CMD_ENTRIES, 0 }, 1574 { AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY }, 1575 { AAC_ADAP_HIGH_CMD_ENTRIES, 0 }, 1576 { AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL }, 1577 { AAC_HOST_HIGH_RESP_ENTRIES, 0 }, 1578 { AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY }, 1579 { AAC_ADAP_HIGH_RESP_ENTRIES, 0 } 1580 }; 1581 1582 /* 1583 * Atomically insert an entry into the nominated queue, returns 0 on success 1584 * or EBUSY if the queue is full. 1585 * 1586 * Note: it would be more efficient to defer notifying the controller in 1587 * the case where we may be inserting several entries in rapid 1588 * succession, but implementing this usefully may be difficult 1589 * (it would involve a separate queue/notify interface). 1590 */ 1591 int 1592 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm) 1593 { 1594 u_int32_t pi, ci; 1595 int error; 1596 u_int32_t fib_size; 1597 u_int32_t fib_addr; 1598 1599 fib_size = cm->cm_fib->Header.Size; 1600 fib_addr = cm->cm_fib->Header.ReceiverFibAddress; 1601 1602 /* get the producer/consumer indices */ 1603 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1604 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1605 1606 /* wrap the queue? */ 1607 if (pi >= aac_qinfo[queue].size) 1608 pi = 0; 1609 1610 /* check for queue full */ 1611 if ((pi + 1) == ci) { 1612 error = EBUSY; 1613 goto out; 1614 } 1615 1616 /* populate queue entry */ 1617 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size; 1618 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr; 1619 1620 /* update producer index */ 1621 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1; 1622 1623 /* 1624 * To avoid a race with its completion interrupt, place this command on 1625 * the busy queue prior to advertising it to the controller. 1626 */ 1627 aac_enqueue_busy(cm); 1628 1629 /* notify the adapter if we know how */ 1630 if (aac_qinfo[queue].notify != 0) 1631 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1632 1633 error = 0; 1634 1635 out: 1636 return (error); 1637 } 1638 1639 /* 1640 * Atomically remove one entry from the nominated queue, returns 0 on success 1641 * or ENOENT if the queue is empty. 1642 */ 1643 int 1644 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size, 1645 struct aac_fib **fib_addr) 1646 { 1647 u_int32_t pi, ci; 1648 u_int32_t fib_index; 1649 int notify; 1650 int error; 1651 1652 /* get the producer/consumer indices */ 1653 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1654 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1655 1656 /* check for queue empty */ 1657 if (ci == pi) { 1658 error = ENOENT; 1659 goto out; 1660 } 1661 1662 /* wrap the pi so the following test works */ 1663 if (pi >= aac_qinfo[queue].size) 1664 pi = 0; 1665 1666 notify = 0; 1667 if (ci == pi + 1) 1668 notify++; 1669 1670 /* wrap the queue? */ 1671 if (ci >= aac_qinfo[queue].size) 1672 ci = 0; 1673 1674 /* fetch the entry */ 1675 *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size; 1676 1677 switch (queue) { 1678 case AAC_HOST_NORM_CMD_QUEUE: 1679 case AAC_HOST_HIGH_CMD_QUEUE: 1680 /* 1681 * The aq_fib_addr is only 32 bits wide so it can't be counted 1682 * on to hold an address. For AIF's, the adapter assumes 1683 * that it's giving us an address into the array of AIF fibs. 1684 * Therefore, we have to convert it to an index. 1685 */ 1686 fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr / 1687 sizeof(struct aac_fib); 1688 *fib_addr = &sc->aac_common->ac_fibs[fib_index]; 1689 break; 1690 1691 case AAC_HOST_NORM_RESP_QUEUE: 1692 case AAC_HOST_HIGH_RESP_QUEUE: 1693 { 1694 struct aac_command *cm; 1695 1696 /* 1697 * As above, an index is used instead of an actual address. 1698 * Gotta shift the index to account for the fast response 1699 * bit. No other correction is needed since this value was 1700 * originally provided by the driver via the SenderFibAddress 1701 * field. 1702 */ 1703 fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr; 1704 cm = sc->aac_commands + (fib_index >> 1); 1705 *fib_addr = cm->cm_fib; 1706 1707 /* 1708 * Is this a fast response? If it is, update the fib fields in 1709 * local memory since the whole fib isn't DMA'd back up. 1710 */ 1711 if (fib_index & 0x01) { 1712 (*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP; 1713 *((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL; 1714 } 1715 break; 1716 } 1717 default: 1718 panic("Invalid queue in aac_dequeue_fib()"); 1719 break; 1720 } 1721 1722 1723 /* update consumer index */ 1724 sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1; 1725 1726 /* if we have made the queue un-full, notify the adapter */ 1727 if (notify && (aac_qinfo[queue].notify != 0)) 1728 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1729 error = 0; 1730 1731 out: 1732 return (error); 1733 } 1734 1735 /* 1736 * Put our response to an Adapter Initialed Fib on the response queue 1737 */ 1738 int 1739 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib) 1740 { 1741 u_int32_t pi, ci; 1742 int error; 1743 u_int32_t fib_size; 1744 u_int32_t fib_addr; 1745 1746 /* Tell the adapter where the FIB is */ 1747 fib_size = fib->Header.Size; 1748 fib_addr = fib->Header.SenderFibAddress; 1749 fib->Header.ReceiverFibAddress = fib_addr; 1750 1751 /* get the producer/consumer indices */ 1752 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1753 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1754 1755 /* wrap the queue? */ 1756 if (pi >= aac_qinfo[queue].size) 1757 pi = 0; 1758 1759 /* check for queue full */ 1760 if ((pi + 1) == ci) { 1761 error = EBUSY; 1762 goto out; 1763 } 1764 1765 /* populate queue entry */ 1766 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size; 1767 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr; 1768 1769 /* update producer index */ 1770 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1; 1771 1772 /* notify the adapter if we know how */ 1773 if (aac_qinfo[queue].notify != 0) 1774 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1775 1776 error = 0; 1777 1778 out: 1779 return(error); 1780 } 1781 1782 void 1783 aac_command_timeout(struct aac_command *cm) 1784 { 1785 struct aac_softc *sc = cm->cm_sc; 1786 1787 printf("%s: COMMAND %p (flags=%#x) TIMEOUT AFTER %d SECONDS\n", 1788 sc->aac_dev.dv_xname, cm, cm->cm_flags, 1789 (int)(getuptime() - cm->cm_timestamp)); 1790 1791 if (cm->cm_flags & AAC_CMD_TIMEDOUT) 1792 return; 1793 1794 cm->cm_flags |= AAC_CMD_TIMEDOUT; 1795 1796 AAC_PRINT_FIB(sc, cm->cm_fib); 1797 1798 if (cm->cm_flags & AAC_ON_AACQ_BIO) { 1799 struct scsi_xfer *xs = cm->cm_private; 1800 int s = splbio(); 1801 xs->error = XS_DRIVER_STUFFUP; 1802 splx(s); 1803 scsi_done(xs); 1804 1805 aac_remove_bio(cm); 1806 aac_unmap_command(cm); 1807 } 1808 } 1809 1810 void 1811 aac_timeout(struct aac_softc *sc) 1812 { 1813 struct aac_command *cm; 1814 time_t deadline; 1815 1816 /* 1817 * Traverse the busy command list and timeout any commands 1818 * that are past their deadline. 1819 */ 1820 deadline = getuptime() - AAC_CMD_TIMEOUT; 1821 TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) { 1822 if (cm->cm_timestamp < deadline) 1823 aac_command_timeout(cm); 1824 } 1825 } 1826 1827 /* 1828 * Interface Function Vectors 1829 */ 1830 1831 /* 1832 * Read the current firmware status word. 1833 */ 1834 int 1835 aac_sa_get_fwstatus(struct aac_softc *sc) 1836 { 1837 return (AAC_GETREG4(sc, AAC_SA_FWSTATUS)); 1838 } 1839 1840 int 1841 aac_rx_get_fwstatus(struct aac_softc *sc) 1842 { 1843 return (AAC_GETREG4(sc, AAC_RX_FWSTATUS)); 1844 } 1845 1846 int 1847 aac_fa_get_fwstatus(struct aac_softc *sc) 1848 { 1849 return (AAC_GETREG4(sc, AAC_FA_FWSTATUS)); 1850 } 1851 1852 int 1853 aac_rkt_get_fwstatus(struct aac_softc *sc) 1854 { 1855 return(AAC_GETREG4(sc, AAC_RKT_FWSTATUS)); 1856 } 1857 1858 /* 1859 * Notify the controller of a change in a given queue 1860 */ 1861 1862 void 1863 aac_sa_qnotify(struct aac_softc *sc, int qbit) 1864 { 1865 AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit); 1866 } 1867 1868 void 1869 aac_rx_qnotify(struct aac_softc *sc, int qbit) 1870 { 1871 AAC_SETREG4(sc, AAC_RX_IDBR, qbit); 1872 } 1873 1874 void 1875 aac_fa_qnotify(struct aac_softc *sc, int qbit) 1876 { 1877 AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit); 1878 AAC_FA_HACK(sc); 1879 } 1880 1881 void 1882 aac_rkt_qnotify(struct aac_softc *sc, int qbit) 1883 { 1884 AAC_SETREG4(sc, AAC_RKT_IDBR, qbit); 1885 } 1886 1887 /* 1888 * Get the interrupt reason bits 1889 */ 1890 int 1891 aac_sa_get_istatus(struct aac_softc *sc) 1892 { 1893 return (AAC_GETREG2(sc, AAC_SA_DOORBELL0)); 1894 } 1895 1896 int 1897 aac_rx_get_istatus(struct aac_softc *sc) 1898 { 1899 return (AAC_GETREG4(sc, AAC_RX_ODBR)); 1900 } 1901 1902 int 1903 aac_fa_get_istatus(struct aac_softc *sc) 1904 { 1905 return (AAC_GETREG2(sc, AAC_FA_DOORBELL0)); 1906 } 1907 1908 int 1909 aac_rkt_get_istatus(struct aac_softc *sc) 1910 { 1911 return(AAC_GETREG4(sc, AAC_RKT_ODBR)); 1912 } 1913 1914 /* 1915 * Clear some interrupt reason bits 1916 */ 1917 void 1918 aac_sa_clear_istatus(struct aac_softc *sc, int mask) 1919 { 1920 AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask); 1921 } 1922 1923 void 1924 aac_rx_clear_istatus(struct aac_softc *sc, int mask) 1925 { 1926 AAC_SETREG4(sc, AAC_RX_ODBR, mask); 1927 } 1928 1929 void 1930 aac_fa_clear_istatus(struct aac_softc *sc, int mask) 1931 { 1932 AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask); 1933 AAC_FA_HACK(sc); 1934 } 1935 1936 void 1937 aac_rkt_clear_istatus(struct aac_softc *sc, int mask) 1938 { 1939 AAC_SETREG4(sc, AAC_RKT_ODBR, mask); 1940 } 1941 1942 /* 1943 * Populate the mailbox and set the command word 1944 */ 1945 void 1946 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 1947 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 1948 { 1949 AAC_SETREG4(sc, AAC_SA_MAILBOX, command); 1950 AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0); 1951 AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1); 1952 AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2); 1953 AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3); 1954 } 1955 1956 void 1957 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 1958 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 1959 { 1960 AAC_SETREG4(sc, AAC_RX_MAILBOX, command); 1961 AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0); 1962 AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1); 1963 AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2); 1964 AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3); 1965 } 1966 1967 void 1968 aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 1969 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 1970 { 1971 AAC_SETREG4(sc, AAC_FA_MAILBOX, command); 1972 AAC_FA_HACK(sc); 1973 AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0); 1974 AAC_FA_HACK(sc); 1975 AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1); 1976 AAC_FA_HACK(sc); 1977 AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2); 1978 AAC_FA_HACK(sc); 1979 AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3); 1980 AAC_FA_HACK(sc); 1981 } 1982 1983 void 1984 aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 1985 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3) 1986 { 1987 AAC_SETREG4(sc, AAC_RKT_MAILBOX, command); 1988 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0); 1989 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1); 1990 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2); 1991 AAC_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3); 1992 } 1993 1994 /* 1995 * Fetch the immediate command status word 1996 */ 1997 int 1998 aac_sa_get_mailbox(struct aac_softc *sc, int mb) 1999 { 2000 return (AAC_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4))); 2001 } 2002 2003 int 2004 aac_rx_get_mailbox(struct aac_softc *sc, int mb) 2005 { 2006 return (AAC_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4))); 2007 } 2008 2009 int 2010 aac_fa_get_mailbox(struct aac_softc *sc, int mb) 2011 { 2012 return (AAC_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4))); 2013 } 2014 2015 int 2016 aac_rkt_get_mailbox(struct aac_softc *sc, int mb) 2017 { 2018 return(AAC_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4))); 2019 } 2020 2021 /* 2022 * Set/clear interrupt masks 2023 */ 2024 void 2025 aac_sa_set_interrupts(struct aac_softc *sc, int enable) 2026 { 2027 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts\n", 2028 sc->aac_dev.dv_xname, enable ? "en" : "dis")); 2029 2030 if (enable) 2031 AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS); 2032 else 2033 AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0); 2034 } 2035 2036 void 2037 aac_rx_set_interrupts(struct aac_softc *sc, int enable) 2038 { 2039 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts", 2040 sc->aac_dev.dv_xname, enable ? "en" : "dis")); 2041 2042 if (enable) 2043 AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS); 2044 else 2045 AAC_SETREG4(sc, AAC_RX_OIMR, ~0); 2046 } 2047 2048 void 2049 aac_fa_set_interrupts(struct aac_softc *sc, int enable) 2050 { 2051 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts", 2052 sc->aac_dev.dv_xname, enable ? "en" : "dis")); 2053 2054 if (enable) { 2055 AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS); 2056 AAC_FA_HACK(sc); 2057 } else { 2058 AAC_SETREG2((sc), AAC_FA_MASK0, ~0); 2059 AAC_FA_HACK(sc); 2060 } 2061 } 2062 2063 void 2064 aac_rkt_set_interrupts(struct aac_softc *sc, int enable) 2065 { 2066 AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts", 2067 sc->aac_dev.dv_xname, enable ? "en" : "dis")); 2068 2069 if (enable) 2070 AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS); 2071 else 2072 AAC_SETREG4(sc, AAC_RKT_OIMR, ~0); 2073 } 2074 2075 void 2076 aac_eval_mapping(size, cyls, heads, secs) 2077 u_int32_t size; 2078 int *cyls, *heads, *secs; 2079 { 2080 *cyls = size / AAC_HEADS / AAC_SECS; 2081 if (*cyls < AAC_MAXCYLS) { 2082 *heads = AAC_HEADS; 2083 *secs = AAC_SECS; 2084 } else { 2085 /* Too high for 64 * 32 */ 2086 *cyls = size / AAC_MEDHEADS / AAC_MEDSECS; 2087 if (*cyls < AAC_MAXCYLS) { 2088 *heads = AAC_MEDHEADS; 2089 *secs = AAC_MEDSECS; 2090 } else { 2091 /* Too high for 127 * 63 */ 2092 *cyls = size / AAC_BIGHEADS / AAC_BIGSECS; 2093 *heads = AAC_BIGHEADS; 2094 *secs = AAC_BIGSECS; 2095 } 2096 } 2097 } 2098 2099 /* Emulated SCSI operation on cache device */ 2100 void 2101 aac_internal_cache_cmd(struct scsi_xfer *xs) 2102 { 2103 struct scsi_link *link = xs->sc_link; 2104 struct aac_softc *sc = link->bus->sb_adapter_softc; 2105 struct scsi_inquiry_data inq; 2106 struct scsi_sense_data sd; 2107 struct scsi_read_cap_data rcd; 2108 u_int8_t target = link->target; 2109 2110 AAC_DPRINTF(AAC_D_CMD, ("%s: aac_internal_cache_cmd: ", 2111 sc->aac_dev.dv_xname)); 2112 2113 switch (xs->cmd.opcode) { 2114 case TEST_UNIT_READY: 2115 case START_STOP: 2116 #if 0 2117 case VERIFY: 2118 #endif 2119 AAC_DPRINTF(AAC_D_CMD, ("opc %#x tgt %d ", xs->cmd.opcode, 2120 target)); 2121 break; 2122 2123 case REQUEST_SENSE: 2124 AAC_DPRINTF(AAC_D_CMD, ("REQUEST SENSE tgt %d ", target)); 2125 bzero(&sd, sizeof sd); 2126 sd.error_code = SSD_ERRCODE_CURRENT; 2127 sd.segment = 0; 2128 sd.flags = SKEY_NO_SENSE; 2129 aac_enc32(sd.info, 0); 2130 sd.extra_len = 0; 2131 scsi_copy_internal_data(xs, &sd, sizeof(sd)); 2132 break; 2133 2134 case INQUIRY: 2135 AAC_DPRINTF(AAC_D_CMD, ("INQUIRY tgt %d devtype %x ", target, 2136 sc->aac_hdr[target].hd_devtype)); 2137 bzero(&inq, sizeof inq); 2138 /* XXX How do we detect removable/CD-ROM devices? */ 2139 inq.device = T_DIRECT; 2140 inq.dev_qual2 = 0; 2141 inq.version = SCSI_REV_2; 2142 inq.response_format = SID_SCSI2_RESPONSE; 2143 inq.additional_length = SID_SCSI2_ALEN; 2144 inq.flags |= SID_CmdQue; 2145 strlcpy(inq.vendor, "Adaptec", sizeof inq.vendor); 2146 snprintf(inq.product, sizeof inq.product, "Container #%02d", 2147 target); 2148 strlcpy(inq.revision, " ", sizeof inq.revision); 2149 scsi_copy_internal_data(xs, &inq, sizeof(inq)); 2150 break; 2151 2152 case READ_CAPACITY: 2153 AAC_DPRINTF(AAC_D_CMD, ("READ CAPACITY tgt %d ", target)); 2154 bzero(&rcd, sizeof rcd); 2155 _lto4b(sc->aac_hdr[target].hd_size - 1, rcd.addr); 2156 _lto4b(AAC_BLOCK_SIZE, rcd.length); 2157 scsi_copy_internal_data(xs, (u_int8_t *)&rcd, sizeof rcd); 2158 break; 2159 2160 default: 2161 AAC_DPRINTF(AAC_D_CMD, ("\n")); 2162 printf("aac_internal_cache_cmd got bad opcode: %#x\n", 2163 xs->cmd.opcode); 2164 xs->error = XS_DRIVER_STUFFUP; 2165 return; 2166 } 2167 2168 xs->error = XS_NOERROR; 2169 } 2170 2171 void 2172 aac_scsi_cmd(struct scsi_xfer *xs) 2173 { 2174 struct scsi_link *link = xs->sc_link; 2175 struct aac_softc *sc = link->bus->sb_adapter_softc; 2176 u_int8_t target = link->target; 2177 struct aac_command *cm; 2178 u_int32_t blockno, blockcnt; 2179 struct scsi_rw *rw; 2180 struct scsi_rw_10 *rw10; 2181 int s; 2182 2183 s = splbio(); 2184 2185 xs->error = XS_NOERROR; 2186 2187 if (target >= AAC_MAX_CONTAINERS || !sc->aac_hdr[target].hd_present || 2188 link->lun != 0) { 2189 /* 2190 * XXX Should be XS_SENSE but that would require setting up a 2191 * faked sense too. 2192 */ 2193 splx(s); 2194 xs->error = XS_DRIVER_STUFFUP; 2195 scsi_done(xs); 2196 return; 2197 } 2198 2199 AAC_DPRINTF(AAC_D_CMD, ("%s: aac_scsi_cmd: ", sc->aac_dev.dv_xname)); 2200 2201 xs->error = XS_NOERROR; 2202 cm = NULL; 2203 link = xs->sc_link; 2204 target = link->target; 2205 2206 switch (xs->cmd.opcode) { 2207 case TEST_UNIT_READY: 2208 case REQUEST_SENSE: 2209 case INQUIRY: 2210 case START_STOP: 2211 case READ_CAPACITY: 2212 #if 0 2213 case VERIFY: 2214 #endif 2215 aac_internal_cache_cmd(xs); 2216 scsi_done(xs); 2217 goto ready; 2218 2219 case PREVENT_ALLOW: 2220 AAC_DPRINTF(AAC_D_CMD, ("PREVENT/ALLOW ")); 2221 /* XXX Not yet implemented */ 2222 xs->error = XS_NOERROR; 2223 scsi_done(xs); 2224 goto ready; 2225 2226 case SYNCHRONIZE_CACHE: 2227 AAC_DPRINTF(AAC_D_CMD, ("SYNCHRONIZE_CACHE ")); 2228 /* XXX Not yet implemented */ 2229 xs->error = XS_NOERROR; 2230 scsi_done(xs); 2231 goto ready; 2232 2233 default: 2234 AAC_DPRINTF(AAC_D_CMD, ("unknown opc %#x ", xs->cmd.opcode)); 2235 /* XXX Not yet implemented */ 2236 xs->error = XS_DRIVER_STUFFUP; 2237 scsi_done(xs); 2238 goto ready; 2239 2240 case READ_COMMAND: 2241 case READ_10: 2242 case WRITE_COMMAND: 2243 case WRITE_10: 2244 AAC_DPRINTF(AAC_D_CMD, ("rw opc %#x ", xs->cmd.opcode)); 2245 2246 /* A read or write operation. */ 2247 if (xs->cmdlen == 6) { 2248 rw = (struct scsi_rw *)&xs->cmd; 2249 blockno = _3btol(rw->addr) & 2250 (SRW_TOPADDR << 16 | 0xffff); 2251 blockcnt = rw->length ? rw->length : 0x100; 2252 } else { 2253 rw10 = (struct scsi_rw_10 *)&xs->cmd; 2254 blockno = _4btol(rw10->addr); 2255 blockcnt = _2btol(rw10->length); 2256 } 2257 2258 AAC_DPRINTF(AAC_D_CMD, ("opcode=%d blkno=%d bcount=%d ", 2259 xs->cmd.opcode, blockno, blockcnt)); 2260 2261 if (blockno >= sc->aac_hdr[target].hd_size || 2262 blockno + blockcnt > sc->aac_hdr[target].hd_size) { 2263 AAC_DPRINTF(AAC_D_CMD, ("\n")); 2264 printf("%s: out of bounds %u-%u >= %u\n", 2265 sc->aac_dev.dv_xname, blockno, 2266 blockcnt, sc->aac_hdr[target].hd_size); 2267 /* 2268 * XXX Should be XS_SENSE but that 2269 * would require setting up a faked 2270 * sense too. 2271 */ 2272 xs->error = XS_DRIVER_STUFFUP; 2273 scsi_done(xs); 2274 goto ready; 2275 } 2276 2277 cm = xs->io; 2278 aac_scrub_command(cm); 2279 2280 /* fill out the command */ 2281 cm->cm_data = (void *)xs->data; 2282 cm->cm_datalen = xs->datalen; 2283 cm->cm_complete = aac_bio_complete; 2284 cm->cm_private = xs; 2285 cm->cm_timestamp = getuptime(); 2286 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; 2287 cm->cm_blkno = blockno; 2288 cm->cm_bcount = blockcnt; 2289 2290 AAC_DPRINTF(AAC_D_CMD, ("\n")); 2291 aac_enqueue_bio(cm); 2292 aac_startio(sc); 2293 2294 /* XXX what if enqueue did not start a transfer? */ 2295 if (xs->flags & SCSI_POLL) { 2296 if (!aac_wait_command(cm, xs->timeout)) 2297 { 2298 printf("%s: command timed out\n", 2299 sc->aac_dev.dv_xname); 2300 xs->error = XS_DRIVER_STUFFUP; 2301 scsi_done(xs); 2302 splx(s); 2303 return; 2304 } 2305 scsi_done(xs); 2306 } 2307 } 2308 2309 ready: 2310 splx(s); 2311 AAC_DPRINTF(AAC_D_CMD, ("%s: scsi_cmd complete\n", 2312 sc->aac_dev.dv_xname)); 2313 } 2314 2315 /* 2316 * Debugging and Diagnostics 2317 */ 2318 2319 /* 2320 * Print some information about the controller. 2321 */ 2322 void 2323 aac_describe_controller(struct aac_softc *sc) 2324 { 2325 struct aac_fib *fib; 2326 struct aac_adapter_info *info; 2327 2328 aac_alloc_sync_fib(sc, &fib, 0); 2329 2330 fib->data[0] = 0; 2331 if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) { 2332 printf("%s: RequestAdapterInfo failed 2\n", 2333 sc->aac_dev.dv_xname); 2334 aac_release_sync_fib(sc); 2335 return; 2336 } 2337 info = (struct aac_adapter_info *)&fib->data[0]; 2338 2339 printf("%s: %s %dMHz, %dMB cache memory, %s\n", sc->aac_dev.dv_xname, 2340 aac_describe_code(aac_cpu_variant, info->CpuVariant), 2341 info->ClockSpeed, info->BufferMem / (1024 * 1024), 2342 aac_describe_code(aac_battery_platform, info->batteryPlatform)); 2343 2344 /* save the kernel revision structure for later use */ 2345 sc->aac_revision = info->KernelRevision; 2346 printf("%s: Kernel %d.%d-%d, Build %d, S/N %6X\n", 2347 sc->aac_dev.dv_xname, 2348 info->KernelRevision.external.comp.major, 2349 info->KernelRevision.external.comp.minor, 2350 info->KernelRevision.external.comp.dash, 2351 info->KernelRevision.buildNumber, 2352 (u_int32_t)(info->SerialNumber & 0xffffff)); 2353 2354 aac_release_sync_fib(sc); 2355 } 2356 2357 /* 2358 * Look up a text description of a numeric error code and return a pointer to 2359 * same. 2360 */ 2361 char * 2362 aac_describe_code(struct aac_code_lookup *table, u_int32_t code) 2363 { 2364 int i; 2365 2366 for (i = 0; table[i].string != NULL; i++) 2367 if (table[i].code == code) 2368 return(table[i].string); 2369 return(table[i + 1].string); 2370 } 2371 2372 #ifdef AAC_DEBUG 2373 /* 2374 * Print a FIB 2375 */ 2376 void 2377 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller) 2378 { 2379 printf("%s: FIB @ %p\n", caller, fib); 2380 printf(" XferState %b\n", fib->Header.XferState, "\20" 2381 "\1HOSTOWNED" 2382 "\2ADAPTEROWNED" 2383 "\3INITIALISED" 2384 "\4EMPTY" 2385 "\5FROMPOOL" 2386 "\6FROMHOST" 2387 "\7FROMADAP" 2388 "\10REXPECTED" 2389 "\11RNOTEXPECTED" 2390 "\12DONEADAP" 2391 "\13DONEHOST" 2392 "\14HIGH" 2393 "\15NORM" 2394 "\16ASYNC" 2395 "\17PAGEFILEIO" 2396 "\20SHUTDOWN" 2397 "\21LAZYWRITE" 2398 "\22ADAPMICROFIB" 2399 "\23BIOSFIB" 2400 "\24FAST_RESPONSE" 2401 "\25APIFIB\n"); 2402 printf(" Command %d\n", fib->Header.Command); 2403 printf(" StructType %d\n", fib->Header.StructType); 2404 printf(" Flags 0x%x\n", fib->Header.Flags); 2405 printf(" Size %d\n", fib->Header.Size); 2406 printf(" SenderSize %d\n", fib->Header.SenderSize); 2407 printf(" SenderAddress 0x%x\n", fib->Header.SenderFibAddress); 2408 printf(" ReceiverAddress 0x%x\n", fib->Header.ReceiverFibAddress); 2409 printf(" SenderData 0x%x\n", fib->Header.SenderData); 2410 switch(fib->Header.Command) { 2411 case ContainerCommand: { 2412 struct aac_blockread *br = (struct aac_blockread *)fib->data; 2413 struct aac_blockwrite *bw = (struct aac_blockwrite *)fib->data; 2414 struct aac_sg_table *sg = NULL; 2415 int i; 2416 2417 if (br->Command == VM_CtBlockRead) { 2418 printf(" BlockRead: container %d 0x%x/%d\n", 2419 br->ContainerId, br->BlockNumber, br->ByteCount); 2420 sg = &br->SgMap; 2421 } 2422 if (bw->Command == VM_CtBlockWrite) { 2423 printf(" BlockWrite: container %d 0x%x/%d (%s)\n", 2424 bw->ContainerId, bw->BlockNumber, bw->ByteCount, 2425 bw->Stable == CSTABLE ? "stable" : "unstable"); 2426 sg = &bw->SgMap; 2427 } 2428 if (sg != NULL) { 2429 printf(" %d s/g entries\n", sg->SgCount); 2430 for (i = 0; i < sg->SgCount; i++) 2431 printf(" 0x%08x/%d\n", 2432 sg->SgEntry[i].SgAddress, 2433 sg->SgEntry[i].SgByteCount); 2434 } 2435 break; 2436 } 2437 default: 2438 printf(" %16D\n", fib->data, " "); 2439 printf(" %16D\n", fib->data + 16, " "); 2440 break; 2441 } 2442 } 2443 2444 /* 2445 * Describe an AIF we have received. 2446 */ 2447 void 2448 aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif) 2449 { 2450 printf("%s: print_aif: ", sc->aac_dev.dv_xname); 2451 2452 switch(aif->command) { 2453 case AifCmdEventNotify: 2454 printf("EventNotify(%d)\n", aif->seqNumber); 2455 2456 switch(aif->data.EN.type) { 2457 case AifEnGeneric: 2458 /* Generic notification */ 2459 printf("\t(Generic) %.*s\n", 2460 (int)sizeof(aif->data.EN.data.EG), 2461 aif->data.EN.data.EG.text); 2462 break; 2463 case AifEnTaskComplete: 2464 /* Task has completed */ 2465 printf("\t(TaskComplete)\n"); 2466 break; 2467 case AifEnConfigChange: 2468 /* Adapter configuration change occurred */ 2469 printf("\t(ConfigChange)\n"); 2470 break; 2471 case AifEnContainerChange: 2472 /* Adapter specific container configuration change */ 2473 printf("\t(ContainerChange) container %d,%d\n", 2474 aif->data.EN.data.ECC.container[0], 2475 aif->data.EN.data.ECC.container[1]); 2476 break; 2477 case AifEnDeviceFailure: 2478 /* SCSI device failed */ 2479 printf("\t(DeviceFailure) handle %d\n", 2480 aif->data.EN.data.EDF.deviceHandle); 2481 break; 2482 case AifEnMirrorFailover: 2483 /* Mirror failover started */ 2484 printf("\t(MirrorFailover) container %d failed, " 2485 "migrating from slice %d to %d\n", 2486 aif->data.EN.data.EMF.container, 2487 aif->data.EN.data.EMF.failedSlice, 2488 aif->data.EN.data.EMF.creatingSlice); 2489 break; 2490 case AifEnContainerEvent: 2491 /* Significant container event */ 2492 printf("\t(ContainerEvent) container %d event %d\n", 2493 aif->data.EN.data.ECE.container, 2494 aif->data.EN.data.ECE.eventType); 2495 break; 2496 case AifEnFileSystemChange: 2497 /* File system changed */ 2498 printf("\t(FileSystemChange)\n"); 2499 break; 2500 case AifEnConfigPause: 2501 /* Container pause event */ 2502 printf("\t(ConfigPause)\n"); 2503 break; 2504 case AifEnConfigResume: 2505 /* Container resume event */ 2506 printf("\t(ConfigResume)\n"); 2507 break; 2508 case AifEnFailoverChange: 2509 /* Failover space assignment changed */ 2510 printf("\t(FailoverChange)\n"); 2511 break; 2512 case AifEnRAID5RebuildDone: 2513 /* RAID5 rebuild finished */ 2514 printf("\t(RAID5RebuildDone)\n"); 2515 break; 2516 case AifEnEnclosureManagement: 2517 /* Enclosure management event */ 2518 printf("\t(EnclosureManagement) EMPID %d unit %d " 2519 "event %d\n", 2520 aif->data.EN.data.EEE.empID, 2521 aif->data.EN.data.EEE.unitID, 2522 aif->data.EN.data.EEE.eventType); 2523 break; 2524 case AifEnBatteryEvent: 2525 /* Significant NV battery event */ 2526 printf("\t(BatteryEvent) %d (state was %d, is %d\n", 2527 aif->data.EN.data.EBE.transition_type, 2528 aif->data.EN.data.EBE.current_state, 2529 aif->data.EN.data.EBE.prior_state); 2530 break; 2531 case AifEnAddContainer: 2532 /* A new container was created. */ 2533 printf("\t(AddContainer)\n"); 2534 break; 2535 case AifEnDeleteContainer: 2536 /* A container was deleted. */ 2537 printf("\t(DeleteContainer)\n"); 2538 break; 2539 case AifEnBatteryNeedsRecond: 2540 /* The battery needs reconditioning */ 2541 printf("\t(BatteryNeedsRecond)\n"); 2542 break; 2543 case AifEnClusterEvent: 2544 /* Some cluster event */ 2545 printf("\t(ClusterEvent) event %d\n", 2546 aif->data.EN.data.ECLE.eventType); 2547 break; 2548 case AifEnDiskSetEvent: 2549 /* A disk set event occured. */ 2550 printf("(DiskSetEvent) event %d " 2551 "diskset %lld creator %lld\n", 2552 aif->data.EN.data.EDS.eventType, 2553 aif->data.EN.data.EDS.DsNum, 2554 aif->data.EN.data.EDS.CreatorId); 2555 break; 2556 case AifDenMorphComplete: 2557 /* A morph operation completed */ 2558 printf("\t(MorphComplete)\n"); 2559 break; 2560 case AifDenVolumeExtendComplete: 2561 /* A volume expand operation completed */ 2562 printf("\t(VolumeExtendComplete)\n"); 2563 break; 2564 default: 2565 printf("\t(%d)\n", aif->data.EN.type); 2566 break; 2567 } 2568 break; 2569 case AifCmdJobProgress: 2570 { 2571 char *status; 2572 switch(aif->data.PR[0].status) { 2573 case AifJobStsSuccess: 2574 status = "success"; break; 2575 case AifJobStsFinished: 2576 status = "finished"; break; 2577 case AifJobStsAborted: 2578 status = "aborted"; break; 2579 case AifJobStsFailed: 2580 status = "failed"; break; 2581 case AifJobStsSuspended: 2582 status = "suspended"; break; 2583 case AifJobStsRunning: 2584 status = "running"; break; 2585 default: 2586 status = "unknown status"; break; 2587 } 2588 2589 printf("JobProgress (%d) - %s (%d, %d)\n", 2590 aif->seqNumber, status, 2591 aif->data.PR[0].currentTick, 2592 aif->data.PR[0].finalTick); 2593 2594 switch(aif->data.PR[0].jd.type) { 2595 case AifJobScsiZero: 2596 /* SCSI dev clear operation */ 2597 printf("\t(ScsiZero) handle %d\n", 2598 aif->data.PR[0].jd.client.scsi_dh); 2599 break; 2600 case AifJobScsiVerify: 2601 /* SCSI device Verify operation NO REPAIR */ 2602 printf("\t(ScsiVerify) handle %d\n", 2603 aif->data.PR[0].jd.client.scsi_dh); 2604 break; 2605 case AifJobScsiExercise: 2606 /* SCSI device Exercise operation */ 2607 printf("\t(ScsiExercise) handle %d\n", 2608 aif->data.PR[0].jd.client.scsi_dh); 2609 break; 2610 case AifJobScsiVerifyRepair: 2611 /* SCSI device Verify operation WITH repair */ 2612 printf("\t(ScsiVerifyRepair) handle %d\n", 2613 aif->data.PR[0].jd.client.scsi_dh); 2614 break; 2615 case AifJobCtrZero: 2616 /* Container clear operation */ 2617 printf("\t(ContainerZero) container %d\n", 2618 aif->data.PR[0].jd.client.container.src); 2619 break; 2620 case AifJobCtrCopy: 2621 /* Container copy operation */ 2622 printf("\t(ContainerCopy) container %d to %d\n", 2623 aif->data.PR[0].jd.client.container.src, 2624 aif->data.PR[0].jd.client.container.dst); 2625 break; 2626 case AifJobCtrCreateMirror: 2627 /* Container Create Mirror operation */ 2628 printf("\t(ContainerCreateMirror) container %d\n", 2629 aif->data.PR[0].jd.client.container.src); 2630 /* XXX two containers? */ 2631 break; 2632 case AifJobCtrMergeMirror: 2633 /* Container Merge Mirror operation */ 2634 printf("\t(ContainerMergeMirror) container %d\n", 2635 aif->data.PR[0].jd.client.container.src); 2636 /* XXX two containers? */ 2637 break; 2638 case AifJobCtrScrubMirror: 2639 /* Container Scrub Mirror operation */ 2640 printf("\t(ContainerScrubMirror) container %d\n", 2641 aif->data.PR[0].jd.client.container.src); 2642 break; 2643 case AifJobCtrRebuildRaid5: 2644 /* Container Rebuild Raid5 operation */ 2645 printf("\t(ContainerRebuildRaid5) container %d\n", 2646 aif->data.PR[0].jd.client.container.src); 2647 break; 2648 case AifJobCtrScrubRaid5: 2649 /* Container Scrub Raid5 operation */ 2650 printf("\t(ContainerScrubRaid5) container %d\n", 2651 aif->data.PR[0].jd.client.container.src); 2652 break; 2653 case AifJobCtrMorph: 2654 /* Container morph operation */ 2655 printf("\t(ContainerMorph) container %d\n", 2656 aif->data.PR[0].jd.client.container.src); 2657 /* XXX two containers? */ 2658 break; 2659 case AifJobCtrPartCopy: 2660 /* Container Partition copy operation */ 2661 printf("\t(ContainerPartCopy) container %d to %d\n", 2662 aif->data.PR[0].jd.client.container.src, 2663 aif->data.PR[0].jd.client.container.dst); 2664 break; 2665 case AifJobCtrRebuildMirror: 2666 /* Container Rebuild Mirror operation */ 2667 printf("\t(ContainerRebuildMirror) container %d\n", 2668 aif->data.PR[0].jd.client.container.src); 2669 break; 2670 case AifJobCtrCrazyCache: 2671 /* crazy cache */ 2672 printf("\t(ContainerCrazyCache) container %d\n", 2673 aif->data.PR[0].jd.client.container.src); 2674 /* XXX two containers? */ 2675 break; 2676 case AifJobFsCreate: 2677 /* File System Create operation */ 2678 printf("\t(FsCreate)\n"); 2679 break; 2680 case AifJobFsVerify: 2681 /* File System Verify operation */ 2682 printf("\t(FsVerivy)\n"); 2683 break; 2684 case AifJobFsExtend: 2685 /* File System Extend operation */ 2686 printf("\t(FsExtend)\n"); 2687 break; 2688 case AifJobApiFormatNTFS: 2689 /* Format a drive to NTFS */ 2690 printf("\t(FormatNTFS)\n"); 2691 break; 2692 case AifJobApiFormatFAT: 2693 /* Format a drive to FAT */ 2694 printf("\t(FormatFAT)\n"); 2695 break; 2696 case AifJobApiUpdateSnapshot: 2697 /* update the read/write half of a snapshot */ 2698 printf("\t(UpdateSnapshot)\n"); 2699 break; 2700 case AifJobApiFormatFAT32: 2701 /* Format a drive to FAT32 */ 2702 printf("\t(FormatFAT32)\n"); 2703 break; 2704 case AifJobCtlContinuousCtrVerify: 2705 /* Adapter operation */ 2706 printf("\t(ContinuousCtrVerify)\n"); 2707 break; 2708 default: 2709 printf("\t(%d)\n", aif->data.PR[0].jd.type); 2710 break; 2711 } 2712 break; 2713 } 2714 case AifCmdAPIReport: 2715 printf("APIReport (%d)\n", aif->seqNumber); 2716 break; 2717 case AifCmdDriverNotify: 2718 printf("DriverNotify (%d)\n", aif->seqNumber); 2719 break; 2720 default: 2721 printf("AIF %d (%d)\n", aif->command, aif->seqNumber); 2722 break; 2723 } 2724 } 2725 #endif 2726