1 /* $OpenBSD: aac.c,v 1.76 2020/02/18 16:05:56 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 void aac_copy_internal_data(struct scsi_xfer *, u_int8_t *, size_t); 84 char *aac_describe_code(struct aac_code_lookup *, u_int32_t); 85 void aac_describe_controller(struct aac_softc *); 86 int aac_enqueue_fib(struct aac_softc *, int, struct aac_command *); 87 int aac_dequeue_fib(struct aac_softc *, int, u_int32_t *, 88 struct aac_fib **); 89 int aac_enqueue_response(struct aac_softc *sc, int queue, 90 struct aac_fib *fib); 91 92 void aac_eval_mapping(u_int32_t, int *, int *, int *); 93 void aac_print_printf(struct aac_softc *); 94 int aac_init(struct aac_softc *); 95 int aac_check_firmware(struct aac_softc *); 96 void aac_internal_cache_cmd(struct scsi_xfer *); 97 98 /* Command Processing */ 99 void aac_timeout(struct aac_softc *); 100 void aac_command_timeout(struct aac_command *); 101 int aac_map_command(struct aac_command *); 102 void aac_complete(void *); 103 int aac_bio_command(struct aac_softc *, struct aac_command **); 104 void aac_bio_complete(struct aac_command *); 105 int aac_wait_command(struct aac_command *, int); 106 void aac_create_thread(void *); 107 void aac_command_thread(void *); 108 109 /* Command Buffer Management */ 110 void aac_map_command_sg(void *, bus_dma_segment_t *, int, int); 111 int aac_alloc_commands(struct aac_softc *); 112 void aac_free_commands(struct aac_softc *); 113 void aac_unmap_command(struct aac_command *); 114 int aac_wait_command(struct aac_command *, int); 115 void * aac_alloc_command(void *); 116 void aac_scrub_command(struct aac_command *); 117 void aac_release_command(void *, void *); 118 int aac_alloc_sync_fib(struct aac_softc *, struct aac_fib **, int); 119 void aac_release_sync_fib(struct aac_softc *); 120 int aac_sync_fib(struct aac_softc *, u_int32_t, u_int32_t, 121 struct aac_fib *, u_int16_t); 122 123 void aac_scsi_cmd(struct scsi_xfer *); 124 void aac_startio(struct aac_softc *); 125 void aac_startup(struct aac_softc *); 126 int aac_sync_command(struct aac_softc *, u_int32_t, u_int32_t, 127 u_int32_t, u_int32_t, u_int32_t, u_int32_t *); 128 129 struct cfdriver aac_cd = { 130 NULL, "aac", DV_DULL 131 }; 132 133 struct scsi_adapter aac_switch = { 134 aac_scsi_cmd, NULL, NULL, NULL, NULL 135 }; 136 137 /* Falcon/PPC interface */ 138 int aac_fa_get_fwstatus(struct aac_softc *); 139 void aac_fa_qnotify(struct aac_softc *, int); 140 int aac_fa_get_istatus(struct aac_softc *); 141 void aac_fa_clear_istatus(struct aac_softc *, int); 142 void aac_fa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t, u_int32_t, 143 u_int32_t, u_int32_t); 144 int aac_fa_get_mailbox(struct aac_softc *, int); 145 void aac_fa_set_interrupts(struct aac_softc *, int); 146 147 struct aac_interface aac_fa_interface = { 148 aac_fa_get_fwstatus, 149 aac_fa_qnotify, 150 aac_fa_get_istatus, 151 aac_fa_clear_istatus, 152 aac_fa_set_mailbox, 153 aac_fa_get_mailbox, 154 aac_fa_set_interrupts 155 }; 156 157 /* StrongARM interface */ 158 int aac_sa_get_fwstatus(struct aac_softc *); 159 void aac_sa_qnotify(struct aac_softc *, int); 160 int aac_sa_get_istatus(struct aac_softc *); 161 void aac_sa_clear_istatus(struct aac_softc *, int); 162 void aac_sa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t, 163 u_int32_t, u_int32_t, u_int32_t); 164 int aac_sa_get_mailbox(struct aac_softc *, int); 165 void aac_sa_set_interrupts(struct aac_softc *, int); 166 167 struct aac_interface aac_sa_interface = { 168 aac_sa_get_fwstatus, 169 aac_sa_qnotify, 170 aac_sa_get_istatus, 171 aac_sa_clear_istatus, 172 aac_sa_set_mailbox, 173 aac_sa_get_mailbox, 174 aac_sa_set_interrupts 175 }; 176 177 /* i960Rx interface */ 178 int aac_rx_get_fwstatus(struct aac_softc *); 179 void aac_rx_qnotify(struct aac_softc *, int); 180 int aac_rx_get_istatus(struct aac_softc *); 181 void aac_rx_clear_istatus(struct aac_softc *, int); 182 void aac_rx_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t, 183 u_int32_t, u_int32_t, u_int32_t); 184 int aac_rx_get_mailbox(struct aac_softc *, int); 185 void aac_rx_set_interrupts(struct aac_softc *, int); 186 187 struct aac_interface aac_rx_interface = { 188 aac_rx_get_fwstatus, 189 aac_rx_qnotify, 190 aac_rx_get_istatus, 191 aac_rx_clear_istatus, 192 aac_rx_set_mailbox, 193 aac_rx_get_mailbox, 194 aac_rx_set_interrupts 195 }; 196 197 /* Rocket/MIPS interface */ 198 int aac_rkt_get_fwstatus(struct aac_softc *); 199 void aac_rkt_qnotify(struct aac_softc *, int); 200 int aac_rkt_get_istatus(struct aac_softc *); 201 void aac_rkt_clear_istatus(struct aac_softc *, int); 202 void aac_rkt_set_mailbox(struct aac_softc *, u_int32_t, 203 u_int32_t, u_int32_t, 204 u_int32_t, u_int32_t); 205 int aac_rkt_get_mailbox(struct aac_softc *, int); 206 void aac_rkt_set_interrupts(struct aac_softc *, int); 207 208 struct aac_interface aac_rkt_interface = { 209 aac_rkt_get_fwstatus, 210 aac_rkt_qnotify, 211 aac_rkt_get_istatus, 212 aac_rkt_clear_istatus, 213 aac_rkt_set_mailbox, 214 aac_rkt_get_mailbox, 215 aac_rkt_set_interrupts 216 }; 217 218 #ifdef AAC_DEBUG 219 int aac_debug = AAC_DEBUG; 220 #endif 221 222 int 223 aac_attach(struct aac_softc *sc) 224 { 225 struct scsibus_attach_args saa; 226 int error; 227 228 /* 229 * Initialise per-controller queues. 230 */ 231 mtx_init(&sc->aac_free_mtx, IPL_BIO); 232 aac_initq_free(sc); 233 aac_initq_ready(sc); 234 aac_initq_busy(sc); 235 aac_initq_bio(sc); 236 237 /* disable interrupts before we enable anything */ 238 AAC_MASK_INTERRUPTS(sc); 239 240 /* mark controller as suspended until we get ourselves organised */ 241 sc->aac_state |= AAC_STATE_SUSPEND; 242 243 /* 244 * Check that the firmware on the card is supported. 245 */ 246 error = aac_check_firmware(sc); 247 if (error) 248 return (error); 249 250 /* 251 * Initialize locks 252 */ 253 AAC_LOCK_INIT(&sc->aac_sync_lock, "AAC sync FIB lock"); 254 AAC_LOCK_INIT(&sc->aac_aifq_lock, "AAC AIF lock"); 255 AAC_LOCK_INIT(&sc->aac_io_lock, "AAC I/O lock"); 256 AAC_LOCK_INIT(&sc->aac_container_lock, "AAC container lock"); 257 TAILQ_INIT(&sc->aac_container_tqh); 258 259 /* Initialize the local AIF queue pointers */ 260 sc->aac_aifq_head = sc->aac_aifq_tail = AAC_AIFQ_LENGTH; 261 262 /* 263 * Initialise the adapter. 264 */ 265 error = aac_init(sc); 266 if (error) 267 return (error); 268 269 /* Fill in the prototype scsi_link. */ 270 sc->aac_link.adapter_softc = sc; 271 sc->aac_link.adapter = &aac_switch; 272 sc->aac_link.openings = (sc->total_fibs - 8) / 273 (sc->aac_container_count ? sc->aac_container_count : 1); 274 sc->aac_link.adapter_buswidth = AAC_MAX_CONTAINERS; 275 sc->aac_link.adapter_target = AAC_MAX_CONTAINERS; 276 sc->aac_link.pool = &sc->aac_iopool; 277 278 bzero(&saa, sizeof(saa)); 279 saa.saa_sc_link = &sc->aac_link; 280 281 config_found(&sc->aac_dev, &saa, scsiprint); 282 283 /* Create the AIF thread */ 284 sc->aifthread = 0; 285 sc->aifflags = 0; 286 kthread_create_deferred(aac_create_thread, sc); 287 288 return (0); 289 } 290 291 void 292 aac_create_thread(void *arg) 293 { 294 struct aac_softc *sc = arg; 295 296 if (kthread_create(aac_command_thread, sc, &sc->aifthread, 297 sc->aac_dev.dv_xname)) { 298 /* TODO disable aac */ 299 printf("%s: failed to create kernel thread, disabled", 300 sc->aac_dev.dv_xname); 301 } 302 AAC_DPRINTF(AAC_D_MISC, ("%s: aac_create_thread\n", 303 sc->aac_dev.dv_xname)); 304 305 } 306 307 /* 308 * Probe for containers, create disks. 309 */ 310 void 311 aac_startup(struct aac_softc *sc) 312 { 313 struct aac_fib *fib; 314 struct aac_mntinfo *mi; 315 struct aac_mntinforesp *mir = NULL; 316 int count = 0, i = 0; 317 318 319 aac_alloc_sync_fib(sc, &fib, 0); 320 mi = (struct aac_mntinfo *)&fib->data[0]; 321 322 AAC_DPRINTF(AAC_D_MISC, ("%s: aac startup\n", sc->aac_dev.dv_xname)); 323 324 sc->aac_container_count = 0; 325 /* loop over possible containers */ 326 do { 327 /* request information on this container */ 328 bzero(mi, sizeof(struct aac_mntinfo)); 329 mi->Command = VM_NameServe; 330 mi->MntType = FT_FILESYS; 331 mi->MntCount = i; 332 if (aac_sync_fib(sc, ContainerCommand, 0, fib, 333 sizeof(struct aac_mntinfo))) { 334 printf("%s: error probing container %d\n", 335 sc->aac_dev.dv_xname, i); 336 continue; 337 } 338 339 mir = (struct aac_mntinforesp *)&fib->data[0]; 340 /* XXX Need to check if count changed */ 341 count = mir->MntRespCount; 342 343 /* 344 * Check container volume type for validity. Note 345 * that many of the possible types may never show up. 346 */ 347 if (mir->Status == ST_OK && 348 mir->MntTable[0].VolType != CT_NONE) { 349 int drv_cyls, drv_hds, drv_secs; 350 351 AAC_DPRINTF(AAC_D_MISC, 352 ("%s: %d: id %x name '%.16s' size %u type %d\n", 353 sc->aac_dev.dv_xname, i, 354 mir->MntTable[0].ObjectId, 355 mir->MntTable[0].FileSystemName, 356 mir->MntTable[0].Capacity, 357 mir->MntTable[0].VolType)); 358 359 sc->aac_container_count++; 360 sc->aac_hdr[i].hd_present = 1; 361 sc->aac_hdr[i].hd_size = mir->MntTable[0].Capacity; 362 363 /* 364 * Evaluate mapping (sectors per head, heads per cyl) 365 */ 366 sc->aac_hdr[i].hd_size &= ~AAC_SECS32; 367 aac_eval_mapping(sc->aac_hdr[i].hd_size, &drv_cyls, 368 &drv_hds, &drv_secs); 369 sc->aac_hdr[i].hd_heads = drv_hds; 370 sc->aac_hdr[i].hd_secs = drv_secs; 371 /* Round the size */ 372 sc->aac_hdr[i].hd_size = drv_cyls * drv_hds * drv_secs; 373 374 sc->aac_hdr[i].hd_devtype = mir->MntTable[0].VolType; 375 376 /* XXX Save the name too for use in IDENTIFY later */ 377 } 378 379 i++; 380 } while ((i < count) && (i < AAC_MAX_CONTAINERS)); 381 382 aac_release_sync_fib(sc); 383 384 /* mark the controller up */ 385 sc->aac_state &= ~AAC_STATE_SUSPEND; 386 387 /* enable interrupts now */ 388 AAC_UNMASK_INTERRUPTS(sc); 389 } 390 391 /* 392 * Take an interrupt. 393 */ 394 int 395 aac_intr(void *arg) 396 { 397 struct aac_softc *sc = arg; 398 u_int16_t reason; 399 400 401 /* 402 * Read the status register directly. This is faster than taking the 403 * driver lock and reading the queues directly. It also saves having 404 * to turn parts of the driver lock into a spin mutex, which would be 405 * ugly. 406 */ 407 reason = AAC_GET_ISTATUS(sc); 408 AAC_CLEAR_ISTATUS(sc, reason); 409 (void)AAC_GET_ISTATUS(sc); 410 411 if (reason == 0) 412 return (0); 413 414 AAC_DPRINTF(AAC_D_INTR, ("%s: intr: sc=%p: reason=%#x\n", 415 sc->aac_dev.dv_xname, sc, reason)); 416 417 /* controller wants to talk to us */ 418 if (reason & (AAC_DB_PRINTF | AAC_DB_COMMAND_READY | 419 AAC_DB_RESPONSE_READY)) { 420 421 if (reason & AAC_DB_RESPONSE_READY) { 422 /* handle completion processing */ 423 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) { 424 sc->aifflags |= AAC_AIFFLAGS_COMPLETE; 425 } else { 426 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 427 aac_complete(sc); 428 AAC_LOCK_RELEASE(&sc->aac_io_lock); 429 } 430 } 431 432 433 /* 434 * XXX Make sure that we don't get fooled by strange messages 435 * that start with a NULL. 436 */ 437 if (reason & AAC_DB_PRINTF) 438 if (sc->aac_common->ac_printf[0] == 0) 439 sc->aac_common->ac_printf[0] = 32; 440 441 /* 442 * This might miss doing the actual wakeup. However, the 443 * msleep that this is waking up has a timeout, so it will 444 * wake up eventually. AIFs and printfs are low enough 445 * priority that they can handle hanging out for a few seconds 446 * if needed. 447 */ 448 if (sc->aifthread) 449 wakeup(sc->aifthread); 450 451 } 452 453 return (1); 454 } 455 456 /* 457 * Command Processing 458 */ 459 460 /* 461 * Start as much queued I/O as possible on the controller 462 */ 463 void 464 aac_startio(struct aac_softc *sc) 465 { 466 struct aac_command *cm; 467 468 AAC_DPRINTF(AAC_D_CMD, ("%s: start command", sc->aac_dev.dv_xname)); 469 470 if (sc->flags & AAC_QUEUE_FRZN) { 471 AAC_DPRINTF(AAC_D_CMD, (": queue frozen")); 472 return; 473 } 474 475 AAC_DPRINTF(AAC_D_CMD, ("\n")); 476 477 for (;;) { 478 /* 479 * Try to get a command that's been put off for lack of 480 * resources 481 */ 482 cm = aac_dequeue_ready(sc); 483 484 /* 485 * Try to build a command off the bio queue (ignore error 486 * return) 487 */ 488 if (cm == NULL) { 489 AAC_DPRINTF(AAC_D_CMD, ("\n")); 490 aac_bio_command(sc, &cm); 491 AAC_DPRINTF(AAC_D_CMD, ("%s: start done bio", 492 sc->aac_dev.dv_xname)); 493 } 494 495 /* nothing to do? */ 496 if (cm == NULL) 497 break; 498 499 /* 500 * Try to give the command to the controller. Any error is 501 * catastrophic since it means that bus_dmamap_load() failed. 502 */ 503 if (aac_map_command(cm) != 0) 504 panic("aac: error mapping command %p", cm); 505 506 AAC_DPRINTF(AAC_D_CMD, ("\n%s: another command", 507 sc->aac_dev.dv_xname)); 508 } 509 510 AAC_DPRINTF(AAC_D_CMD, ("\n")); 511 } 512 513 /* 514 * Deliver a command to the controller; allocate controller resources at the 515 * last moment when possible. 516 */ 517 int 518 aac_map_command(struct aac_command *cm) 519 { 520 struct aac_softc *sc = cm->cm_sc; 521 int error = 0; 522 523 AAC_DPRINTF(AAC_D_CMD, (": map command")); 524 525 /* don't map more than once */ 526 if (cm->cm_flags & AAC_CMD_MAPPED) 527 panic("aac: command %p already mapped", cm); 528 529 if (cm->cm_datalen != 0) { 530 error = bus_dmamap_load(sc->aac_dmat, cm->cm_datamap, 531 cm->cm_data, cm->cm_datalen, NULL, 532 BUS_DMA_NOWAIT); 533 if (error) 534 return (error); 535 536 aac_map_command_sg(cm, cm->cm_datamap->dm_segs, 537 cm->cm_datamap->dm_nsegs, 0); 538 } else { 539 aac_map_command_sg(cm, NULL, 0, 0); 540 } 541 542 return (error); 543 } 544 545 /* 546 * Handle notification of one or more FIBs coming from the controller. 547 */ 548 void 549 aac_command_thread(void *arg) 550 { 551 struct aac_softc *sc = arg; 552 struct aac_fib *fib; 553 u_int32_t fib_size; 554 int size, retval; 555 556 AAC_DPRINTF(AAC_D_THREAD, ("%s: aac_command_thread: starting\n", 557 sc->aac_dev.dv_xname)); 558 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 559 sc->aifflags = AAC_AIFFLAGS_RUNNING; 560 561 while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) { 562 563 AAC_DPRINTF(AAC_D_THREAD, 564 ("%s: aac_command_thread: aifflags=%#x\n", 565 sc->aac_dev.dv_xname, sc->aifflags)); 566 retval = 0; 567 568 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0) { 569 AAC_DPRINTF(AAC_D_THREAD, 570 ("%s: command thread sleeping\n", 571 sc->aac_dev.dv_xname)); 572 AAC_LOCK_RELEASE(&sc->aac_io_lock); 573 retval = tsleep_nsec(sc->aifthread, PRIBIO, "aifthd", 574 SEC_TO_NSEC(AAC_PERIODIC_INTERVAL)); 575 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 576 } 577 578 if ((sc->aifflags & AAC_AIFFLAGS_COMPLETE) != 0) { 579 aac_complete(sc); 580 sc->aifflags &= ~AAC_AIFFLAGS_COMPLETE; 581 } 582 583 /* 584 * While we're here, check to see if any commands are stuck. 585 * This is pretty low-priority, so it's ok if it doesn't 586 * always fire. 587 */ 588 if (retval == EWOULDBLOCK) 589 aac_timeout(sc); 590 591 /* Check the hardware printf message buffer */ 592 if (sc->aac_common->ac_printf[0] != 0) 593 aac_print_printf(sc); 594 595 /* Also check to see if the adapter has a command for us. */ 596 while (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, 597 &fib_size, &fib) == 0) { 598 599 AAC_PRINT_FIB(sc, fib); 600 601 switch (fib->Header.Command) { 602 case AifRequest: 603 //aac_handle_aif(sc, fib); 604 break; 605 default: 606 printf("%s: unknown command from controller\n", 607 sc->aac_dev.dv_xname); 608 break; 609 } 610 611 if ((fib->Header.XferState == 0) || 612 (fib->Header.StructType != AAC_FIBTYPE_TFIB)) 613 break; 614 615 /* Return the AIF to the controller. */ 616 if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) { 617 fib->Header.XferState |= AAC_FIBSTATE_DONEHOST; 618 *(AAC_FSAStatus*)fib->data = ST_OK; 619 620 /* XXX Compute the Size field? */ 621 size = fib->Header.Size; 622 if (size > sizeof(struct aac_fib)) { 623 size = sizeof(struct aac_fib); 624 fib->Header.Size = size; 625 } 626 627 /* 628 * Since we did not generate this command, it 629 * cannot go through the normal 630 * enqueue->startio chain. 631 */ 632 aac_enqueue_response(sc, 633 AAC_ADAP_NORM_RESP_QUEUE, 634 fib); 635 } 636 } 637 } 638 sc->aifflags &= ~AAC_AIFFLAGS_RUNNING; 639 AAC_LOCK_RELEASE(&sc->aac_io_lock); 640 641 AAC_DPRINTF(AAC_D_THREAD, ("%s: aac_command_thread: exiting\n", 642 sc->aac_dev.dv_xname)); 643 kthread_exit(0); 644 } 645 646 /* 647 * Process completed commands. 648 */ 649 void 650 aac_complete(void *context) 651 { 652 struct aac_softc *sc = (struct aac_softc *)context; 653 struct aac_command *cm; 654 struct aac_fib *fib; 655 u_int32_t fib_size; 656 657 AAC_DPRINTF(AAC_D_CMD, ("%s: complete", sc->aac_dev.dv_xname)); 658 659 /* pull completed commands off the queue */ 660 for (;;) { 661 /* look for completed FIBs on our queue */ 662 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size, 663 &fib)) 664 break; /* nothing to do */ 665 666 /* get the command, unmap and hand off for processing */ 667 cm = sc->aac_commands + fib->Header.SenderData; 668 if (cm == NULL) { 669 AAC_PRINT_FIB(sc, fib); 670 break; 671 } 672 673 aac_remove_busy(cm); 674 aac_unmap_command(cm); 675 cm->cm_flags |= AAC_CMD_COMPLETED; 676 677 /* is there a completion handler? */ 678 if (cm->cm_complete != NULL) { 679 cm->cm_complete(cm); 680 } else { 681 /* assume that someone is sleeping on this command */ 682 wakeup(cm); 683 } 684 } 685 686 AAC_DPRINTF(AAC_D_CMD, ("\n")); 687 /* see if we can start some more I/O */ 688 sc->flags &= ~AAC_QUEUE_FRZN; 689 aac_startio(sc); 690 } 691 692 /* 693 * Get a bio and build a command to go with it. 694 */ 695 int 696 aac_bio_command(struct aac_softc *sc, struct aac_command **cmp) 697 { 698 struct aac_command *cm; 699 struct aac_fib *fib; 700 struct scsi_xfer *xs; 701 u_int8_t opcode = 0; 702 703 AAC_DPRINTF(AAC_D_CMD, ("%s: bio command", sc->aac_dev.dv_xname)); 704 705 /* get the resources we will need */ 706 if ((cm = aac_dequeue_bio(sc)) == NULL) 707 goto fail; 708 xs = cm->cm_private; 709 710 /* build the FIB */ 711 fib = cm->cm_fib; 712 fib->Header.Size = sizeof(struct aac_fib_header); 713 fib->Header.XferState = 714 AAC_FIBSTATE_HOSTOWNED | 715 AAC_FIBSTATE_INITIALISED | 716 AAC_FIBSTATE_EMPTY | 717 AAC_FIBSTATE_FROMHOST | 718 AAC_FIBSTATE_REXPECTED | 719 AAC_FIBSTATE_NORM | 720 AAC_FIBSTATE_ASYNC | 721 AAC_FIBSTATE_FAST_RESPONSE; 722 723 switch(xs->cmd->opcode) { 724 case READ_COMMAND: 725 case READ_BIG: 726 opcode = READ_COMMAND; 727 break; 728 case WRITE_COMMAND: 729 case WRITE_BIG: 730 opcode = WRITE_COMMAND; 731 break; 732 default: 733 panic("%s: invalid opcode %#x", sc->aac_dev.dv_xname, 734 xs->cmd->opcode); 735 } 736 737 /* build the read/write request */ 738 if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) { 739 fib->Header.Command = ContainerCommand; 740 if (opcode == READ_COMMAND) { 741 struct aac_blockread *br; 742 br = (struct aac_blockread *)&fib->data[0]; 743 br->Command = VM_CtBlockRead; 744 br->ContainerId = xs->sc_link->target; 745 br->BlockNumber = cm->cm_blkno; 746 br->ByteCount = cm->cm_bcount * AAC_BLOCK_SIZE; 747 fib->Header.Size += sizeof(struct aac_blockread); 748 cm->cm_sgtable = &br->SgMap; 749 cm->cm_flags |= AAC_CMD_DATAIN; 750 } else { 751 struct aac_blockwrite *bw; 752 bw = (struct aac_blockwrite *)&fib->data[0]; 753 bw->Command = VM_CtBlockWrite; 754 bw->ContainerId = xs->sc_link->target; 755 bw->BlockNumber = cm->cm_blkno; 756 bw->ByteCount = cm->cm_bcount * AAC_BLOCK_SIZE; 757 bw->Stable = CUNSTABLE; 758 fib->Header.Size += sizeof(struct aac_blockwrite); 759 cm->cm_flags |= AAC_CMD_DATAOUT; 760 cm->cm_sgtable = &bw->SgMap; 761 } 762 } else { 763 fib->Header.Command = ContainerCommand64; 764 if (opcode == READ_COMMAND) { 765 struct aac_blockread64 *br; 766 br = (struct aac_blockread64 *)&fib->data[0]; 767 br->Command = VM_CtHostRead64; 768 br->ContainerId = xs->sc_link->target; 769 br->BlockNumber = cm->cm_blkno; 770 br->SectorCount = cm->cm_bcount; 771 br->Pad = 0; 772 br->Flags = 0; 773 fib->Header.Size += sizeof(struct aac_blockread64); 774 cm->cm_flags |= AAC_CMD_DATAOUT; 775 cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64; 776 } else { 777 struct aac_blockwrite64 *bw; 778 bw = (struct aac_blockwrite64 *)&fib->data[0]; 779 bw->Command = VM_CtHostWrite64; 780 bw->ContainerId = xs->sc_link->target; 781 bw->BlockNumber = cm->cm_blkno; 782 bw->SectorCount = cm->cm_bcount; 783 bw->Pad = 0; 784 bw->Flags = 0; 785 fib->Header.Size += sizeof(struct aac_blockwrite64); 786 cm->cm_flags |= AAC_CMD_DATAIN; 787 cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64; 788 } 789 } 790 791 *cmp = cm; 792 AAC_DPRINTF(AAC_D_CMD, ("\n")); 793 return(0); 794 795 fail: 796 AAC_DPRINTF(AAC_D_CMD, ("\n")); 797 return(ENOMEM); 798 } 799 800 /* 801 * Handle a bio-instigated command that has been completed. 802 */ 803 void 804 aac_bio_complete(struct aac_command *cm) 805 { 806 struct aac_blockread_response *brr; 807 struct aac_blockwrite_response *bwr; 808 struct scsi_xfer *xs = (struct scsi_xfer *)cm->cm_private; 809 AAC_FSAStatus status; 810 int s; 811 812 AAC_DPRINTF(AAC_D_CMD, 813 ("%s: bio complete\n", cm->cm_sc->aac_dev.dv_xname)); 814 815 /* fetch relevant status and then release the command */ 816 if (xs->flags & SCSI_DATA_IN) { 817 brr = (struct aac_blockread_response *)&cm->cm_fib->data[0]; 818 status = brr->Status; 819 } else { 820 bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0]; 821 status = bwr->Status; 822 } 823 824 xs->error = status == ST_OK? XS_NOERROR : XS_DRIVER_STUFFUP; 825 xs->resid = 0; 826 s = splbio(); 827 scsi_done(xs); 828 splx(s); 829 } 830 831 /* 832 * Submit a command to the controller, return when it completes. 833 * XXX This is very dangerous! If the card has gone out to lunch, we could 834 * be stuck here forever. At the same time, signals are not caught 835 * because there is a risk that a signal could wakeup the tsleep before 836 * the card has a chance to complete the command. The passed in timeout 837 * is ignored for the same reason. Since there is no way to cancel a 838 * command in progress, we should probably create a 'dead' queue where 839 * commands go that have been interrupted/timed-out/etc, that keeps them 840 * out of the free pool. That way, if the card is just slow, it won't 841 * spam the memory of a command that has been recycled. 842 */ 843 int 844 aac_wait_command(struct aac_command *cm, int msecs) 845 { 846 struct aac_softc *sc = cm->cm_sc; 847 int error = 0; 848 849 AAC_DPRINTF(AAC_D_CMD, (": wait for command")); 850 851 /* Put the command on the ready queue and get things going */ 852 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; 853 aac_enqueue_ready(cm); 854 AAC_DPRINTF(AAC_D_CMD, ("\n")); 855 aac_startio(sc); 856 while (!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) { 857 AAC_DPRINTF(AAC_D_MISC, ("%s: sleeping until command done\n", 858 sc->aac_dev.dv_xname)); 859 AAC_LOCK_RELEASE(&sc->aac_io_lock); 860 error = tsleep_nsec(cm, PRIBIO, "aacwait", MSEC_TO_NSEC(msecs)); 861 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 862 } 863 return (error); 864 } 865 866 /* 867 *Command Buffer Management 868 */ 869 870 /* 871 * Allocate a command. 872 */ 873 void * 874 aac_alloc_command(void *xsc) 875 { 876 struct aac_softc *sc = xsc; 877 struct aac_command *cm; 878 879 AAC_DPRINTF(AAC_D_CMD, (": allocate command")); 880 mtx_enter(&sc->aac_free_mtx); 881 cm = aac_dequeue_free(sc); 882 mtx_leave(&sc->aac_free_mtx); 883 884 return (cm); 885 } 886 887 void 888 aac_scrub_command(struct aac_command *cm) 889 { 890 cm->cm_sgtable = NULL; 891 cm->cm_flags = 0; 892 cm->cm_complete = NULL; 893 cm->cm_private = NULL; 894 cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY; 895 cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB; 896 cm->cm_fib->Header.Flags = 0; 897 cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib); 898 } 899 900 /* 901 * Release a command back to the freelist. 902 */ 903 void 904 aac_release_command(void *xsc, void *xcm) 905 { 906 struct aac_softc *sc = xsc; 907 struct aac_command *cm = xcm; 908 AAC_DPRINTF(AAC_D_CMD, (": release command")); 909 910 mtx_enter(&sc->aac_free_mtx); 911 aac_enqueue_free(cm); 912 mtx_leave(&sc->aac_free_mtx); 913 } 914 915 /* 916 * Allocate and initialise commands/FIBs for this adapter. 917 */ 918 int 919 aac_alloc_commands(struct aac_softc *sc) 920 { 921 struct aac_command *cm; 922 struct aac_fibmap *fm; 923 int i, error = ENOMEM; 924 925 if (sc->total_fibs + AAC_FIB_COUNT > sc->aac_max_fibs) 926 return (ENOMEM); 927 928 fm = malloc(sizeof(*fm), M_DEVBUF, M_NOWAIT | M_ZERO); 929 if (fm == NULL) 930 goto exit; 931 932 /* allocate the FIBs in DMAable memory and load them */ 933 if (bus_dmamem_alloc(sc->aac_dmat, AAC_FIBMAP_SIZE, PAGE_SIZE, 0, 934 &fm->aac_seg, 1, &fm->aac_nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)) { 935 printf("%s: can't alloc FIBs\n", sc->aac_dev.dv_xname); 936 error = ENOBUFS; 937 goto exit_alloc; 938 } 939 940 if (bus_dmamem_map(sc->aac_dmat, &fm->aac_seg, 1, 941 AAC_FIBMAP_SIZE, (caddr_t *)&fm->aac_fibs, BUS_DMA_NOWAIT)) { 942 printf("%s: can't map FIB structure\n", sc->aac_dev.dv_xname); 943 error = ENOBUFS; 944 goto exit_map; 945 } 946 947 if (bus_dmamap_create(sc->aac_dmat, AAC_FIBMAP_SIZE, 1, 948 AAC_FIBMAP_SIZE, 0, BUS_DMA_NOWAIT, &fm->aac_fibmap)) { 949 printf("%s: can't create dma map\n", sc->aac_dev.dv_xname); 950 error = ENOBUFS; 951 goto exit_create; 952 } 953 954 if (bus_dmamap_load(sc->aac_dmat, fm->aac_fibmap, fm->aac_fibs, 955 AAC_FIBMAP_SIZE, NULL, BUS_DMA_NOWAIT)) { 956 printf("%s: can't load dma map\n", sc->aac_dev.dv_xname); 957 error = ENOBUFS; 958 goto exit_load; 959 } 960 961 /* initialise constant fields in the command structure */ 962 AAC_LOCK_ACQUIRE(&sc->aac_io_lock); 963 for (i = 0; i < AAC_FIB_COUNT; i++) { 964 cm = sc->aac_commands + sc->total_fibs; 965 fm->aac_commands = cm; 966 cm->cm_sc = sc; 967 cm->cm_fib = fm->aac_fibs + i; 968 cm->cm_fibphys = fm->aac_fibmap->dm_segs[0].ds_addr + 969 (i * sizeof(struct aac_fib)); 970 cm->cm_index = sc->total_fibs; 971 972 if (bus_dmamap_create(sc->aac_dmat, MAXPHYS, AAC_MAXSGENTRIES, 973 MAXPHYS, 0, BUS_DMA_NOWAIT, &cm->cm_datamap)) { 974 break; 975 } 976 aac_release_command(sc, cm); 977 sc->total_fibs++; 978 } 979 980 if (i > 0) { 981 TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link); 982 AAC_DPRINTF(AAC_D_MISC, ("%s: total_fibs= %d\n", 983 sc->aac_dev.dv_xname, 984 sc->total_fibs)); 985 AAC_LOCK_RELEASE(&sc->aac_io_lock); 986 return (0); 987 } 988 989 exit_load: 990 bus_dmamap_destroy(sc->aac_dmat, fm->aac_fibmap); 991 exit_create: 992 bus_dmamem_unmap(sc->aac_dmat, (caddr_t)fm->aac_fibs, AAC_FIBMAP_SIZE); 993 exit_map: 994 bus_dmamem_free(sc->aac_dmat, &fm->aac_seg, fm->aac_nsegs); 995 exit_alloc: 996 free(fm, M_DEVBUF, sizeof *fm); 997 exit: 998 AAC_LOCK_RELEASE(&sc->aac_io_lock); 999 return (error); 1000 } 1001 1002 /* 1003 * Free FIBs owned by this adapter. 1004 */ 1005 void 1006 aac_free_commands(struct aac_softc *sc) 1007 { 1008 struct aac_fibmap *fm; 1009 struct aac_command *cm; 1010 int i; 1011 1012 while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) { 1013 1014 TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link); 1015 1016 /* 1017 * We check against total_fibs to handle partially 1018 * allocated blocks. 1019 */ 1020 for (i = 0; i < AAC_FIB_COUNT && sc->total_fibs--; i++) { 1021 cm = fm->aac_commands + i; 1022 bus_dmamap_destroy(sc->aac_dmat, cm->cm_datamap); 1023 } 1024 1025 bus_dmamap_unload(sc->aac_dmat, fm->aac_fibmap); 1026 bus_dmamap_destroy(sc->aac_dmat, fm->aac_fibmap); 1027 bus_dmamem_unmap(sc->aac_dmat, (caddr_t)fm->aac_fibs, 1028 AAC_FIBMAP_SIZE); 1029 bus_dmamem_free(sc->aac_dmat, &fm->aac_seg, fm->aac_nsegs); 1030 free(fm, M_DEVBUF, sizeof *fm); 1031 } 1032 } 1033 1034 1035 /* 1036 * Command-mapping helper function - populate this command's s/g table. 1037 */ 1038 void 1039 aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) 1040 { 1041 struct aac_command *cm = arg; 1042 struct aac_softc *sc = cm->cm_sc; 1043 struct aac_fib *fib = cm->cm_fib; 1044 int i; 1045 1046 /* copy into the FIB */ 1047 if (cm->cm_sgtable != NULL) { 1048 if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) { 1049 struct aac_sg_table *sg = cm->cm_sgtable; 1050 sg->SgCount = nseg; 1051 for (i = 0; i < nseg; i++) { 1052 sg->SgEntry[i].SgAddress = segs[i].ds_addr; 1053 sg->SgEntry[i].SgByteCount = segs[i].ds_len; 1054 } 1055 /* update the FIB size for the s/g count */ 1056 fib->Header.Size += nseg * sizeof(struct aac_sg_entry); 1057 } else { 1058 struct aac_sg_table64 *sg; 1059 sg = (struct aac_sg_table64 *)cm->cm_sgtable; 1060 sg->SgCount = nseg; 1061 for (i = 0; i < nseg; i++) { 1062 sg->SgEntry64[i].SgAddress = segs[i].ds_addr; 1063 sg->SgEntry64[i].SgByteCount = segs[i].ds_len; 1064 } 1065 /* update the FIB size for the s/g count */ 1066 fib->Header.Size += nseg*sizeof(struct aac_sg_entry64); 1067 } 1068 } 1069 1070 /* Fix up the address values in the FIB. Use the command array index 1071 * instead of a pointer since these fields are only 32 bits. Shift 1072 * the SenderFibAddress over to make room for the fast response bit. 1073 */ 1074 cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 1); 1075 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys; 1076 1077 /* save a pointer to the command for speedy reverse-lookup */ 1078 cm->cm_fib->Header.SenderData = cm->cm_index; 1079 1080 if (cm->cm_flags & AAC_CMD_DATAIN) 1081 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0, 1082 cm->cm_datamap->dm_mapsize, 1083 BUS_DMASYNC_PREREAD); 1084 if (cm->cm_flags & AAC_CMD_DATAOUT) 1085 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0, 1086 cm->cm_datamap->dm_mapsize, 1087 BUS_DMASYNC_PREWRITE); 1088 cm->cm_flags |= AAC_CMD_MAPPED; 1089 1090 /* put the FIB on the outbound queue */ 1091 if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) { 1092 aac_remove_busy(cm); 1093 aac_unmap_command(cm); 1094 aac_requeue_ready(cm); 1095 } 1096 } 1097 1098 /* 1099 * Unmap a command from controller-visible space. 1100 */ 1101 void 1102 aac_unmap_command(struct aac_command *cm) 1103 { 1104 struct aac_softc *sc = cm->cm_sc; 1105 1106 if (!(cm->cm_flags & AAC_CMD_MAPPED)) 1107 return; 1108 1109 if (cm->cm_datalen != 0) { 1110 if (cm->cm_flags & AAC_CMD_DATAIN) 1111 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0, 1112 cm->cm_datamap->dm_mapsize, 1113 BUS_DMASYNC_POSTREAD); 1114 if (cm->cm_flags & AAC_CMD_DATAOUT) 1115 bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0, 1116 cm->cm_datamap->dm_mapsize, 1117 BUS_DMASYNC_POSTWRITE); 1118 1119 bus_dmamap_unload(sc->aac_dmat, cm->cm_datamap); 1120 } 1121 cm->cm_flags &= ~AAC_CMD_MAPPED; 1122 } 1123 1124 /* 1125 * Hardware Interface 1126 */ 1127 1128 /* 1129 * Initialise the adapter. 1130 */ 1131 int 1132 aac_check_firmware(struct aac_softc *sc) 1133 { 1134 u_int32_t major, minor, options; 1135 1136 /* 1137 * Retrieve the firmware version numbers. Dell PERC2/QC cards with 1138 * firmware version 1.x are not compatible with this driver. 1139 */ 1140 if (sc->flags & AAC_FLAGS_PERC2QC) { 1141 if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0, 1142 NULL)) { 1143 printf("%s: Error reading firmware version\n", 1144 sc->aac_dev.dv_xname); 1145 return (EIO); 1146 } 1147 1148 /* These numbers are stored as ASCII! */ 1149 major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30; 1150 minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30; 1151 if (major == 1) { 1152 printf("%s: Firmware version %d.%d is not supported\n", 1153 sc->aac_dev.dv_xname, major, minor); 1154 return (EINVAL); 1155 } 1156 } 1157 1158 /* 1159 * Retrieve the capabilities/supported options word so we know what 1160 * work-arounds to enable. 1161 */ 1162 if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, NULL)) { 1163 printf("%s: RequestAdapterInfo failed\n", 1164 sc->aac_dev.dv_xname); 1165 return (EIO); 1166 } 1167 options = AAC_GET_MAILBOX(sc, 1); 1168 sc->supported_options = options; 1169 1170 if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 && 1171 (sc->flags & AAC_FLAGS_NO4GB) == 0) 1172 sc->flags |= AAC_FLAGS_4GB_WINDOW; 1173 if (options & AAC_SUPPORTED_NONDASD) 1174 sc->flags |= AAC_FLAGS_ENABLE_CAM; 1175 if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0 1176 && (sizeof(bus_addr_t) > 4)) { 1177 printf("%s: Enabling 64-bit address support\n", 1178 sc->aac_dev.dv_xname); 1179 sc->flags |= AAC_FLAGS_SG_64BIT; 1180 } 1181 1182 /* Check for broken hardware that does a lower number of commands */ 1183 if ((sc->flags & AAC_FLAGS_256FIBS) == 0) 1184 sc->aac_max_fibs = AAC_MAX_FIBS; 1185 else 1186 sc->aac_max_fibs = 256; 1187 1188 return (0); 1189 } 1190 1191 int 1192 aac_init(struct aac_softc *sc) 1193 { 1194 bus_dma_segment_t seg; 1195 int nsegs; 1196 int i, error; 1197 int state = 0; 1198 struct aac_adapter_init *ip; 1199 time_t then; 1200 u_int32_t code, qoffset; 1201 1202 /* 1203 * First wait for the adapter to come ready. 1204 */ 1205 then = time_uptime; 1206 for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) { 1207 code = AAC_GET_FWSTATUS(sc); 1208 if (code & AAC_SELF_TEST_FAILED) { 1209 printf("%s: FATAL: selftest failed\n", 1210 sc->aac_dev.dv_xname); 1211 return (ENXIO); 1212 } 1213 if (code & AAC_KERNEL_PANIC) { 1214 printf("%s: FATAL: controller kernel panic\n", 1215 sc->aac_dev.dv_xname); 1216 return (ENXIO); 1217 } 1218 if (code & AAC_UP_AND_RUNNING) 1219 break; 1220 DELAY(1000); 1221 } 1222 if (i == AAC_BOOT_TIMEOUT * 1000) { 1223 printf("%s: FATAL: controller not coming ready, status %x\n", 1224 sc->aac_dev.dv_xname, code); 1225 return (ENXIO); 1226 } 1227 1228 /* 1229 * Work around a bug in the 2120 and 2200 that cannot DMA commands 1230 * below address 8192 in physical memory. 1231 * XXX If the padding is not needed, can it be put to use instead 1232 * of ignored? 1233 */ 1234 if (bus_dmamem_alloc(sc->aac_dmat, AAC_COMMON_ALLOCSIZE, PAGE_SIZE, 0, 1235 &seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)) { 1236 printf("%s: can't allocate common structure\n", 1237 sc->aac_dev.dv_xname); 1238 return (ENOMEM); 1239 } 1240 state++; 1241 1242 if (bus_dmamem_map(sc->aac_dmat, &seg, nsegs, AAC_COMMON_ALLOCSIZE, 1243 (caddr_t *)&sc->aac_common, BUS_DMA_NOWAIT)) { 1244 printf("%s: can't map common structure\n", 1245 sc->aac_dev.dv_xname); 1246 error = ENOMEM; 1247 goto bail_out; 1248 } 1249 state++; 1250 1251 if (bus_dmamap_create(sc->aac_dmat, AAC_COMMON_ALLOCSIZE, 1, 1252 AAC_COMMON_ALLOCSIZE, 0, BUS_DMA_NOWAIT, &sc->aac_common_map)) { 1253 printf("%s: can't create dma map\n", sc->aac_dev.dv_xname); 1254 error = ENOBUFS; 1255 goto bail_out; 1256 } 1257 state++; 1258 1259 if (bus_dmamap_load(sc->aac_dmat, sc->aac_common_map, sc->aac_common, 1260 AAC_COMMON_ALLOCSIZE, NULL, BUS_DMA_NOWAIT)) { 1261 printf("%s: can't load dma map\n", sc->aac_dev.dv_xname); 1262 error = ENOBUFS; 1263 goto bail_out; 1264 } 1265 state++; 1266 1267 sc->aac_common_busaddr = sc->aac_common_map->dm_segs[0].ds_addr; 1268 1269 if (sc->aac_common_busaddr < 8192) { 1270 sc->aac_common = (struct aac_common *) 1271 ((uint8_t *)sc->aac_common + 8192); 1272 sc->aac_common_busaddr += 8192; 1273 } 1274 1275 /* Allocate some FIBs and associated command structs */ 1276 TAILQ_INIT(&sc->aac_fibmap_tqh); 1277 sc->aac_commands = malloc(AAC_MAX_FIBS * sizeof(struct aac_command), 1278 M_DEVBUF, M_WAITOK | M_ZERO); 1279 while (sc->total_fibs < AAC_MAX_FIBS) { 1280 if (aac_alloc_commands(sc) != 0) 1281 break; 1282 } 1283 if (sc->total_fibs == 0) 1284 goto out; 1285 1286 scsi_iopool_init(&sc->aac_iopool, sc, 1287 aac_alloc_command, aac_release_command); 1288 1289 /* 1290 * Fill in the init structure. This tells the adapter about the 1291 * physical location of various important shared data structures. 1292 */ 1293 ip = &sc->aac_common->ac_init; 1294 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION; 1295 ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION; 1296 1297 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr + 1298 offsetof(struct aac_common, ac_fibs); 1299 ip->AdapterFibsVirtualAddress = 0; 1300 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib); 1301 ip->AdapterFibAlign = sizeof(struct aac_fib); 1302 1303 ip->PrintfBufferAddress = sc->aac_common_busaddr + 1304 offsetof(struct aac_common, ac_printf); 1305 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE; 1306 1307 /* 1308 * The adapter assumes that pages are 4K in size, except on some 1309 * broken firmware versions that do the page->byte conversion twice, 1310 * therefore 'assuming' that this value is in 16MB units (2^24). 1311 * Round up since the granularity is so high. 1312 */ 1313 ip->HostPhysMemPages = ptoa(physmem) / AAC_PAGE_SIZE; 1314 if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) { 1315 ip->HostPhysMemPages = 1316 (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE; 1317 } 1318 ip->HostElapsedSeconds = time_uptime; /* reset later if invalid */ 1319 1320 /* 1321 * Initialise FIB queues. Note that it appears that the layout of the 1322 * indexes and the segmentation of the entries may be mandated by the 1323 * adapter, which is only told about the base of the queue index fields. 1324 * 1325 * The initial values of the indices are assumed to inform the adapter 1326 * of the sizes of the respective queues, and theoretically it could 1327 * work out the entire layout of the queue structures from this. We 1328 * take the easy route and just lay this area out like everyone else 1329 * does. 1330 * 1331 * The Linux driver uses a much more complex scheme whereby several 1332 * header records are kept for each queue. We use a couple of generic 1333 * list manipulation functions which 'know' the size of each list by 1334 * virtue of a table. 1335 */ 1336 qoffset = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN; 1337 qoffset &= ~(AAC_QUEUE_ALIGN - 1); 1338 sc->aac_queues = 1339 (struct aac_queue_table *)((caddr_t)sc->aac_common + qoffset); 1340 ip->CommHeaderAddress = sc->aac_common_busaddr + qoffset; 1341 1342 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1343 AAC_HOST_NORM_CMD_ENTRIES; 1344 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1345 AAC_HOST_NORM_CMD_ENTRIES; 1346 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1347 AAC_HOST_HIGH_CMD_ENTRIES; 1348 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1349 AAC_HOST_HIGH_CMD_ENTRIES; 1350 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1351 AAC_ADAP_NORM_CMD_ENTRIES; 1352 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1353 AAC_ADAP_NORM_CMD_ENTRIES; 1354 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 1355 AAC_ADAP_HIGH_CMD_ENTRIES; 1356 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 1357 AAC_ADAP_HIGH_CMD_ENTRIES; 1358 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1359 AAC_HOST_NORM_RESP_ENTRIES; 1360 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1361 AAC_HOST_NORM_RESP_ENTRIES; 1362 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1363 AAC_HOST_HIGH_RESP_ENTRIES; 1364 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1365 AAC_HOST_HIGH_RESP_ENTRIES; 1366 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1367 AAC_ADAP_NORM_RESP_ENTRIES; 1368 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1369 AAC_ADAP_NORM_RESP_ENTRIES; 1370 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]= 1371 AAC_ADAP_HIGH_RESP_ENTRIES; 1372 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]= 1373 AAC_ADAP_HIGH_RESP_ENTRIES; 1374 sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] = 1375 &sc->aac_queues->qt_HostNormCmdQueue[0]; 1376 sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] = 1377 &sc->aac_queues->qt_HostHighCmdQueue[0]; 1378 sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] = 1379 &sc->aac_queues->qt_AdapNormCmdQueue[0]; 1380 sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] = 1381 &sc->aac_queues->qt_AdapHighCmdQueue[0]; 1382 sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] = 1383 &sc->aac_queues->qt_HostNormRespQueue[0]; 1384 sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] = 1385 &sc->aac_queues->qt_HostHighRespQueue[0]; 1386 sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] = 1387 &sc->aac_queues->qt_AdapNormRespQueue[0]; 1388 sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] = 1389 &sc->aac_queues->qt_AdapHighRespQueue[0]; 1390 1391 /* 1392 * Do controller-type-specific initialisation 1393 */ 1394 switch (sc->aac_hwif) { 1395 case AAC_HWIF_I960RX: 1396 AAC_SETREG4(sc, AAC_RX_ODBR, ~0); 1397 break; 1398 case AAC_HWIF_RKT: 1399 AAC_SETREG4(sc, AAC_RKT_ODBR, ~0); 1400 break; 1401 default: 1402 break; 1403 } 1404 1405 /* 1406 * Give the init structure to the controller. 1407 */ 1408 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT, 1409 sc->aac_common_busaddr + 1410 offsetof(struct aac_common, ac_init), 0, 0, 0, 1411 NULL)) { 1412 printf("%s: error establishing init structure\n", 1413 sc->aac_dev.dv_xname); 1414 error = EIO; 1415 goto bail_out; 1416 } 1417 1418 aac_describe_controller(sc); 1419 aac_startup(sc); 1420 1421 return (0); 1422 1423 bail_out: 1424 if (state > 3) 1425 bus_dmamap_unload(sc->aac_dmat, sc->aac_common_map); 1426 if (state > 2) 1427 bus_dmamap_destroy(sc->aac_dmat, sc->aac_common_map); 1428 if (state > 1) 1429 bus_dmamem_unmap(sc->aac_dmat, (caddr_t)sc->aac_common, 1430 sizeof *sc->aac_common); 1431 if (state > 0) 1432 bus_dmamem_free(sc->aac_dmat, &seg, 1); 1433 1434 out: 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)(time_uptime - 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 = time_uptime - 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 void 2101 aac_copy_internal_data(struct scsi_xfer *xs, u_int8_t *data, size_t size) 2102 { 2103 struct aac_softc *sc = xs->sc_link->adapter_softc; 2104 size_t copy_cnt; 2105 2106 AAC_DPRINTF(AAC_D_MISC, ("%s: aac_copy_internal_data\n", 2107 sc->aac_dev.dv_xname)); 2108 2109 if (!xs->datalen) 2110 printf("%s: uio move not yet supported\n", 2111 sc->aac_dev.dv_xname); 2112 else { 2113 copy_cnt = MIN(size, xs->datalen); 2114 bcopy(data, xs->data, copy_cnt); 2115 } 2116 } 2117 2118 /* Emulated SCSI operation on cache device */ 2119 void 2120 aac_internal_cache_cmd(struct scsi_xfer *xs) 2121 { 2122 struct scsi_link *link = xs->sc_link; 2123 struct aac_softc *sc = link->adapter_softc; 2124 struct scsi_inquiry_data inq; 2125 struct scsi_sense_data sd; 2126 struct scsi_read_cap_data rcd; 2127 u_int8_t target = link->target; 2128 2129 AAC_DPRINTF(AAC_D_CMD, ("%s: aac_internal_cache_cmd: ", 2130 sc->aac_dev.dv_xname)); 2131 2132 switch (xs->cmd->opcode) { 2133 case TEST_UNIT_READY: 2134 case START_STOP: 2135 #if 0 2136 case VERIFY: 2137 #endif 2138 AAC_DPRINTF(AAC_D_CMD, ("opc %#x tgt %d ", xs->cmd->opcode, 2139 target)); 2140 break; 2141 2142 case REQUEST_SENSE: 2143 AAC_DPRINTF(AAC_D_CMD, ("REQUEST SENSE tgt %d ", target)); 2144 bzero(&sd, sizeof sd); 2145 sd.error_code = SSD_ERRCODE_CURRENT; 2146 sd.segment = 0; 2147 sd.flags = SKEY_NO_SENSE; 2148 aac_enc32(sd.info, 0); 2149 sd.extra_len = 0; 2150 aac_copy_internal_data(xs, (u_int8_t *)&sd, sizeof sd); 2151 break; 2152 2153 case INQUIRY: 2154 AAC_DPRINTF(AAC_D_CMD, ("INQUIRY tgt %d devtype %x ", target, 2155 sc->aac_hdr[target].hd_devtype)); 2156 bzero(&inq, sizeof inq); 2157 /* XXX How do we detect removable/CD-ROM devices? */ 2158 inq.device = T_DIRECT; 2159 inq.dev_qual2 = 0; 2160 inq.version = 2; 2161 inq.response_format = 2; 2162 inq.additional_length = 32; 2163 inq.flags |= SID_CmdQue; 2164 strlcpy(inq.vendor, "Adaptec", sizeof inq.vendor); 2165 snprintf(inq.product, sizeof inq.product, "Container #%02d", 2166 target); 2167 strlcpy(inq.revision, " ", sizeof inq.revision); 2168 aac_copy_internal_data(xs, (u_int8_t *)&inq, sizeof inq); 2169 break; 2170 2171 case READ_CAPACITY: 2172 AAC_DPRINTF(AAC_D_CMD, ("READ CAPACITY tgt %d ", target)); 2173 bzero(&rcd, sizeof rcd); 2174 _lto4b(sc->aac_hdr[target].hd_size - 1, rcd.addr); 2175 _lto4b(AAC_BLOCK_SIZE, rcd.length); 2176 aac_copy_internal_data(xs, (u_int8_t *)&rcd, sizeof rcd); 2177 break; 2178 2179 default: 2180 AAC_DPRINTF(AAC_D_CMD, ("\n")); 2181 printf("aac_internal_cache_cmd got bad opcode: %#x\n", 2182 xs->cmd->opcode); 2183 xs->error = XS_DRIVER_STUFFUP; 2184 return; 2185 } 2186 2187 xs->error = XS_NOERROR; 2188 } 2189 2190 void 2191 aac_scsi_cmd(struct scsi_xfer *xs) 2192 { 2193 struct scsi_link *link = xs->sc_link; 2194 struct aac_softc *sc = link->adapter_softc; 2195 u_int8_t target = link->target; 2196 struct aac_command *cm; 2197 u_int32_t blockno, blockcnt; 2198 struct scsi_rw *rw; 2199 struct scsi_rw_big *rwb; 2200 int s; 2201 2202 s = splbio(); 2203 2204 xs->error = XS_NOERROR; 2205 2206 if (target >= AAC_MAX_CONTAINERS || !sc->aac_hdr[target].hd_present || 2207 link->lun != 0) { 2208 /* 2209 * XXX Should be XS_SENSE but that would require setting up a 2210 * faked sense too. 2211 */ 2212 splx(s); 2213 xs->error = XS_DRIVER_STUFFUP; 2214 scsi_done(xs); 2215 return; 2216 } 2217 2218 AAC_DPRINTF(AAC_D_CMD, ("%s: aac_scsi_cmd: ", sc->aac_dev.dv_xname)); 2219 2220 xs->error = XS_NOERROR; 2221 cm = NULL; 2222 link = xs->sc_link; 2223 target = link->target; 2224 2225 switch (xs->cmd->opcode) { 2226 case TEST_UNIT_READY: 2227 case REQUEST_SENSE: 2228 case INQUIRY: 2229 case START_STOP: 2230 case READ_CAPACITY: 2231 #if 0 2232 case VERIFY: 2233 #endif 2234 aac_internal_cache_cmd(xs); 2235 scsi_done(xs); 2236 goto ready; 2237 2238 case PREVENT_ALLOW: 2239 AAC_DPRINTF(AAC_D_CMD, ("PREVENT/ALLOW ")); 2240 /* XXX Not yet implemented */ 2241 xs->error = XS_NOERROR; 2242 scsi_done(xs); 2243 goto ready; 2244 2245 case SYNCHRONIZE_CACHE: 2246 AAC_DPRINTF(AAC_D_CMD, ("SYNCHRONIZE_CACHE ")); 2247 /* XXX Not yet implemented */ 2248 xs->error = XS_NOERROR; 2249 scsi_done(xs); 2250 goto ready; 2251 2252 default: 2253 AAC_DPRINTF(AAC_D_CMD, ("unknown opc %#x ", xs->cmd->opcode)); 2254 /* XXX Not yet implemented */ 2255 xs->error = XS_DRIVER_STUFFUP; 2256 scsi_done(xs); 2257 goto ready; 2258 2259 case READ_COMMAND: 2260 case READ_BIG: 2261 case WRITE_COMMAND: 2262 case WRITE_BIG: 2263 AAC_DPRINTF(AAC_D_CMD, ("rw opc %#x ", xs->cmd->opcode)); 2264 2265 /* A read or write operation. */ 2266 if (xs->cmdlen == 6) { 2267 rw = (struct scsi_rw *)xs->cmd; 2268 blockno = _3btol(rw->addr) & 2269 (SRW_TOPADDR << 16 | 0xffff); 2270 blockcnt = rw->length ? rw->length : 0x100; 2271 } else { 2272 rwb = (struct scsi_rw_big *)xs->cmd; 2273 blockno = _4btol(rwb->addr); 2274 blockcnt = _2btol(rwb->length); 2275 } 2276 2277 AAC_DPRINTF(AAC_D_CMD, ("opcode=%d blkno=%d bcount=%d ", 2278 xs->cmd->opcode, blockno, blockcnt)); 2279 2280 if (blockno >= sc->aac_hdr[target].hd_size || 2281 blockno + blockcnt > sc->aac_hdr[target].hd_size) { 2282 AAC_DPRINTF(AAC_D_CMD, ("\n")); 2283 printf("%s: out of bounds %u-%u >= %u\n", 2284 sc->aac_dev.dv_xname, blockno, 2285 blockcnt, sc->aac_hdr[target].hd_size); 2286 /* 2287 * XXX Should be XS_SENSE but that 2288 * would require setting up a faked 2289 * sense too. 2290 */ 2291 xs->error = XS_DRIVER_STUFFUP; 2292 scsi_done(xs); 2293 goto ready; 2294 } 2295 2296 cm = xs->io; 2297 aac_scrub_command(cm); 2298 2299 /* fill out the command */ 2300 cm->cm_data = (void *)xs->data; 2301 cm->cm_datalen = xs->datalen; 2302 cm->cm_complete = aac_bio_complete; 2303 cm->cm_private = xs; 2304 cm->cm_timestamp = time_uptime; 2305 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; 2306 cm->cm_blkno = blockno; 2307 cm->cm_bcount = blockcnt; 2308 2309 AAC_DPRINTF(AAC_D_CMD, ("\n")); 2310 aac_enqueue_bio(cm); 2311 aac_startio(sc); 2312 2313 /* XXX what if enqueue did not start a transfer? */ 2314 if (xs->flags & SCSI_POLL) { 2315 if (!aac_wait_command(cm, xs->timeout)) 2316 { 2317 printf("%s: command timed out\n", 2318 sc->aac_dev.dv_xname); 2319 xs->error = XS_DRIVER_STUFFUP; 2320 scsi_done(xs); 2321 splx(s); 2322 return; 2323 } 2324 scsi_done(xs); 2325 } 2326 } 2327 2328 ready: 2329 splx(s); 2330 AAC_DPRINTF(AAC_D_CMD, ("%s: scsi_cmd complete\n", 2331 sc->aac_dev.dv_xname)); 2332 } 2333 2334 /* 2335 * Debugging and Diagnostics 2336 */ 2337 2338 /* 2339 * Print some information about the controller. 2340 */ 2341 void 2342 aac_describe_controller(struct aac_softc *sc) 2343 { 2344 struct aac_fib *fib; 2345 struct aac_adapter_info *info; 2346 2347 aac_alloc_sync_fib(sc, &fib, 0); 2348 2349 fib->data[0] = 0; 2350 if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) { 2351 printf("%s: RequestAdapterInfo failed 2\n", 2352 sc->aac_dev.dv_xname); 2353 aac_release_sync_fib(sc); 2354 return; 2355 } 2356 info = (struct aac_adapter_info *)&fib->data[0]; 2357 2358 printf("%s: %s %dMHz, %dMB cache memory, %s\n", sc->aac_dev.dv_xname, 2359 aac_describe_code(aac_cpu_variant, info->CpuVariant), 2360 info->ClockSpeed, info->BufferMem / (1024 * 1024), 2361 aac_describe_code(aac_battery_platform, info->batteryPlatform)); 2362 2363 /* save the kernel revision structure for later use */ 2364 sc->aac_revision = info->KernelRevision; 2365 printf("%s: Kernel %d.%d-%d, Build %d, S/N %6X\n", 2366 sc->aac_dev.dv_xname, 2367 info->KernelRevision.external.comp.major, 2368 info->KernelRevision.external.comp.minor, 2369 info->KernelRevision.external.comp.dash, 2370 info->KernelRevision.buildNumber, 2371 (u_int32_t)(info->SerialNumber & 0xffffff)); 2372 2373 aac_release_sync_fib(sc); 2374 } 2375 2376 /* 2377 * Look up a text description of a numeric error code and return a pointer to 2378 * same. 2379 */ 2380 char * 2381 aac_describe_code(struct aac_code_lookup *table, u_int32_t code) 2382 { 2383 int i; 2384 2385 for (i = 0; table[i].string != NULL; i++) 2386 if (table[i].code == code) 2387 return(table[i].string); 2388 return(table[i + 1].string); 2389 } 2390 2391 #ifdef AAC_DEBUG 2392 /* 2393 * Print a FIB 2394 */ 2395 void 2396 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller) 2397 { 2398 printf("%s: FIB @ %p\n", caller, fib); 2399 printf(" XferState %b\n", fib->Header.XferState, "\20" 2400 "\1HOSTOWNED" 2401 "\2ADAPTEROWNED" 2402 "\3INITIALISED" 2403 "\4EMPTY" 2404 "\5FROMPOOL" 2405 "\6FROMHOST" 2406 "\7FROMADAP" 2407 "\10REXPECTED" 2408 "\11RNOTEXPECTED" 2409 "\12DONEADAP" 2410 "\13DONEHOST" 2411 "\14HIGH" 2412 "\15NORM" 2413 "\16ASYNC" 2414 "\17PAGEFILEIO" 2415 "\20SHUTDOWN" 2416 "\21LAZYWRITE" 2417 "\22ADAPMICROFIB" 2418 "\23BIOSFIB" 2419 "\24FAST_RESPONSE" 2420 "\25APIFIB\n"); 2421 printf(" Command %d\n", fib->Header.Command); 2422 printf(" StructType %d\n", fib->Header.StructType); 2423 printf(" Flags 0x%x\n", fib->Header.Flags); 2424 printf(" Size %d\n", fib->Header.Size); 2425 printf(" SenderSize %d\n", fib->Header.SenderSize); 2426 printf(" SenderAddress 0x%x\n", fib->Header.SenderFibAddress); 2427 printf(" ReceiverAddress 0x%x\n", fib->Header.ReceiverFibAddress); 2428 printf(" SenderData 0x%x\n", fib->Header.SenderData); 2429 switch(fib->Header.Command) { 2430 case ContainerCommand: { 2431 struct aac_blockread *br = (struct aac_blockread *)fib->data; 2432 struct aac_blockwrite *bw = (struct aac_blockwrite *)fib->data; 2433 struct aac_sg_table *sg = NULL; 2434 int i; 2435 2436 if (br->Command == VM_CtBlockRead) { 2437 printf(" BlockRead: container %d 0x%x/%d\n", 2438 br->ContainerId, br->BlockNumber, br->ByteCount); 2439 sg = &br->SgMap; 2440 } 2441 if (bw->Command == VM_CtBlockWrite) { 2442 printf(" BlockWrite: container %d 0x%x/%d (%s)\n", 2443 bw->ContainerId, bw->BlockNumber, bw->ByteCount, 2444 bw->Stable == CSTABLE ? "stable" : "unstable"); 2445 sg = &bw->SgMap; 2446 } 2447 if (sg != NULL) { 2448 printf(" %d s/g entries\n", sg->SgCount); 2449 for (i = 0; i < sg->SgCount; i++) 2450 printf(" 0x%08x/%d\n", 2451 sg->SgEntry[i].SgAddress, 2452 sg->SgEntry[i].SgByteCount); 2453 } 2454 break; 2455 } 2456 default: 2457 printf(" %16D\n", fib->data, " "); 2458 printf(" %16D\n", fib->data + 16, " "); 2459 break; 2460 } 2461 } 2462 2463 /* 2464 * Describe an AIF we have received. 2465 */ 2466 void 2467 aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif) 2468 { 2469 printf("%s: print_aif: ", sc->aac_dev.dv_xname); 2470 2471 switch(aif->command) { 2472 case AifCmdEventNotify: 2473 printf("EventNotify(%d)\n", aif->seqNumber); 2474 2475 switch(aif->data.EN.type) { 2476 case AifEnGeneric: 2477 /* Generic notification */ 2478 printf("\t(Generic) %.*s\n", 2479 (int)sizeof(aif->data.EN.data.EG), 2480 aif->data.EN.data.EG.text); 2481 break; 2482 case AifEnTaskComplete: 2483 /* Task has completed */ 2484 printf("\t(TaskComplete)\n"); 2485 break; 2486 case AifEnConfigChange: 2487 /* Adapter configuration change occurred */ 2488 printf("\t(ConfigChange)\n"); 2489 break; 2490 case AifEnContainerChange: 2491 /* Adapter specific container configuration change */ 2492 printf("\t(ContainerChange) container %d,%d\n", 2493 aif->data.EN.data.ECC.container[0], 2494 aif->data.EN.data.ECC.container[1]); 2495 break; 2496 case AifEnDeviceFailure: 2497 /* SCSI device failed */ 2498 printf("\t(DeviceFailure) handle %d\n", 2499 aif->data.EN.data.EDF.deviceHandle); 2500 break; 2501 case AifEnMirrorFailover: 2502 /* Mirror failover started */ 2503 printf("\t(MirrorFailover) container %d failed, " 2504 "migrating from slice %d to %d\n", 2505 aif->data.EN.data.EMF.container, 2506 aif->data.EN.data.EMF.failedSlice, 2507 aif->data.EN.data.EMF.creatingSlice); 2508 break; 2509 case AifEnContainerEvent: 2510 /* Significant container event */ 2511 printf("\t(ContainerEvent) container %d event %d\n", 2512 aif->data.EN.data.ECE.container, 2513 aif->data.EN.data.ECE.eventType); 2514 break; 2515 case AifEnFileSystemChange: 2516 /* File system changed */ 2517 printf("\t(FileSystemChange)\n"); 2518 break; 2519 case AifEnConfigPause: 2520 /* Container pause event */ 2521 printf("\t(ConfigPause)\n"); 2522 break; 2523 case AifEnConfigResume: 2524 /* Container resume event */ 2525 printf("\t(ConfigResume)\n"); 2526 break; 2527 case AifEnFailoverChange: 2528 /* Failover space assignment changed */ 2529 printf("\t(FailoverChange)\n"); 2530 break; 2531 case AifEnRAID5RebuildDone: 2532 /* RAID5 rebuild finished */ 2533 printf("\t(RAID5RebuildDone)\n"); 2534 break; 2535 case AifEnEnclosureManagement: 2536 /* Enclosure management event */ 2537 printf("\t(EnclosureManagement) EMPID %d unit %d " 2538 "event %d\n", 2539 aif->data.EN.data.EEE.empID, 2540 aif->data.EN.data.EEE.unitID, 2541 aif->data.EN.data.EEE.eventType); 2542 break; 2543 case AifEnBatteryEvent: 2544 /* Significant NV battery event */ 2545 printf("\t(BatteryEvent) %d (state was %d, is %d\n", 2546 aif->data.EN.data.EBE.transition_type, 2547 aif->data.EN.data.EBE.current_state, 2548 aif->data.EN.data.EBE.prior_state); 2549 break; 2550 case AifEnAddContainer: 2551 /* A new container was created. */ 2552 printf("\t(AddContainer)\n"); 2553 break; 2554 case AifEnDeleteContainer: 2555 /* A container was deleted. */ 2556 printf("\t(DeleteContainer)\n"); 2557 break; 2558 case AifEnBatteryNeedsRecond: 2559 /* The battery needs reconditioning */ 2560 printf("\t(BatteryNeedsRecond)\n"); 2561 break; 2562 case AifEnClusterEvent: 2563 /* Some cluster event */ 2564 printf("\t(ClusterEvent) event %d\n", 2565 aif->data.EN.data.ECLE.eventType); 2566 break; 2567 case AifEnDiskSetEvent: 2568 /* A disk set event occured. */ 2569 printf("(DiskSetEvent) event %d " 2570 "diskset %lld creator %lld\n", 2571 aif->data.EN.data.EDS.eventType, 2572 aif->data.EN.data.EDS.DsNum, 2573 aif->data.EN.data.EDS.CreatorId); 2574 break; 2575 case AifDenMorphComplete: 2576 /* A morph operation completed */ 2577 printf("\t(MorphComplete)\n"); 2578 break; 2579 case AifDenVolumeExtendComplete: 2580 /* A volume expand operation completed */ 2581 printf("\t(VolumeExtendComplete)\n"); 2582 break; 2583 default: 2584 printf("\t(%d)\n", aif->data.EN.type); 2585 break; 2586 } 2587 break; 2588 case AifCmdJobProgress: 2589 { 2590 char *status; 2591 switch(aif->data.PR[0].status) { 2592 case AifJobStsSuccess: 2593 status = "success"; break; 2594 case AifJobStsFinished: 2595 status = "finished"; break; 2596 case AifJobStsAborted: 2597 status = "aborted"; break; 2598 case AifJobStsFailed: 2599 status = "failed"; break; 2600 case AifJobStsSuspended: 2601 status = "suspended"; break; 2602 case AifJobStsRunning: 2603 status = "running"; break; 2604 default: 2605 status = "unknown status"; break; 2606 } 2607 2608 printf("JobProgress (%d) - %s (%d, %d)\n", 2609 aif->seqNumber, status, 2610 aif->data.PR[0].currentTick, 2611 aif->data.PR[0].finalTick); 2612 2613 switch(aif->data.PR[0].jd.type) { 2614 case AifJobScsiZero: 2615 /* SCSI dev clear operation */ 2616 printf("\t(ScsiZero) handle %d\n", 2617 aif->data.PR[0].jd.client.scsi_dh); 2618 break; 2619 case AifJobScsiVerify: 2620 /* SCSI device Verify operation NO REPAIR */ 2621 printf("\t(ScsiVerify) handle %d\n", 2622 aif->data.PR[0].jd.client.scsi_dh); 2623 break; 2624 case AifJobScsiExercise: 2625 /* SCSI device Exercise operation */ 2626 printf("\t(ScsiExercise) handle %d\n", 2627 aif->data.PR[0].jd.client.scsi_dh); 2628 break; 2629 case AifJobScsiVerifyRepair: 2630 /* SCSI device Verify operation WITH repair */ 2631 printf("\t(ScsiVerifyRepair) handle %d\n", 2632 aif->data.PR[0].jd.client.scsi_dh); 2633 break; 2634 case AifJobCtrZero: 2635 /* Container clear operation */ 2636 printf("\t(ContainerZero) container %d\n", 2637 aif->data.PR[0].jd.client.container.src); 2638 break; 2639 case AifJobCtrCopy: 2640 /* Container copy operation */ 2641 printf("\t(ContainerCopy) container %d to %d\n", 2642 aif->data.PR[0].jd.client.container.src, 2643 aif->data.PR[0].jd.client.container.dst); 2644 break; 2645 case AifJobCtrCreateMirror: 2646 /* Container Create Mirror operation */ 2647 printf("\t(ContainerCreateMirror) container %d\n", 2648 aif->data.PR[0].jd.client.container.src); 2649 /* XXX two containers? */ 2650 break; 2651 case AifJobCtrMergeMirror: 2652 /* Container Merge Mirror operation */ 2653 printf("\t(ContainerMergeMirror) container %d\n", 2654 aif->data.PR[0].jd.client.container.src); 2655 /* XXX two containers? */ 2656 break; 2657 case AifJobCtrScrubMirror: 2658 /* Container Scrub Mirror operation */ 2659 printf("\t(ContainerScrubMirror) container %d\n", 2660 aif->data.PR[0].jd.client.container.src); 2661 break; 2662 case AifJobCtrRebuildRaid5: 2663 /* Container Rebuild Raid5 operation */ 2664 printf("\t(ContainerRebuildRaid5) container %d\n", 2665 aif->data.PR[0].jd.client.container.src); 2666 break; 2667 case AifJobCtrScrubRaid5: 2668 /* Container Scrub Raid5 operation */ 2669 printf("\t(ContainerScrubRaid5) container %d\n", 2670 aif->data.PR[0].jd.client.container.src); 2671 break; 2672 case AifJobCtrMorph: 2673 /* Container morph operation */ 2674 printf("\t(ContainerMorph) container %d\n", 2675 aif->data.PR[0].jd.client.container.src); 2676 /* XXX two containers? */ 2677 break; 2678 case AifJobCtrPartCopy: 2679 /* Container Partition copy operation */ 2680 printf("\t(ContainerPartCopy) container %d to %d\n", 2681 aif->data.PR[0].jd.client.container.src, 2682 aif->data.PR[0].jd.client.container.dst); 2683 break; 2684 case AifJobCtrRebuildMirror: 2685 /* Container Rebuild Mirror operation */ 2686 printf("\t(ContainerRebuildMirror) container %d\n", 2687 aif->data.PR[0].jd.client.container.src); 2688 break; 2689 case AifJobCtrCrazyCache: 2690 /* crazy cache */ 2691 printf("\t(ContainerCrazyCache) container %d\n", 2692 aif->data.PR[0].jd.client.container.src); 2693 /* XXX two containers? */ 2694 break; 2695 case AifJobFsCreate: 2696 /* File System Create operation */ 2697 printf("\t(FsCreate)\n"); 2698 break; 2699 case AifJobFsVerify: 2700 /* File System Verify operation */ 2701 printf("\t(FsVerivy)\n"); 2702 break; 2703 case AifJobFsExtend: 2704 /* File System Extend operation */ 2705 printf("\t(FsExtend)\n"); 2706 break; 2707 case AifJobApiFormatNTFS: 2708 /* Format a drive to NTFS */ 2709 printf("\t(FormatNTFS)\n"); 2710 break; 2711 case AifJobApiFormatFAT: 2712 /* Format a drive to FAT */ 2713 printf("\t(FormatFAT)\n"); 2714 break; 2715 case AifJobApiUpdateSnapshot: 2716 /* update the read/write half of a snapshot */ 2717 printf("\t(UpdateSnapshot)\n"); 2718 break; 2719 case AifJobApiFormatFAT32: 2720 /* Format a drive to FAT32 */ 2721 printf("\t(FormatFAT32)\n"); 2722 break; 2723 case AifJobCtlContinuousCtrVerify: 2724 /* Adapter operation */ 2725 printf("\t(ContinuousCtrVerify)\n"); 2726 break; 2727 default: 2728 printf("\t(%d)\n", aif->data.PR[0].jd.type); 2729 break; 2730 } 2731 break; 2732 } 2733 case AifCmdAPIReport: 2734 printf("APIReport (%d)\n", aif->seqNumber); 2735 break; 2736 case AifCmdDriverNotify: 2737 printf("DriverNotify (%d)\n", aif->seqNumber); 2738 break; 2739 default: 2740 printf("AIF %d (%d)\n", aif->command, aif->seqNumber); 2741 break; 2742 } 2743 } 2744 #endif 2745