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