1 /* $OpenBSD: aac.c,v 1.15 2003/04/27 11:22:52 ho Exp $ */ 2 3 /*- 4 * Copyright (c) 2000 Michael Smith 5 * Copyright (c) 2000 BSDi 6 * Copyright (c) 2000 Niklas Hallqvist 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * $FreeBSD: /c/ncvs/src/sys/dev/aac/aac.c,v 1.1 2000/09/13 03:20:34 msmith Exp $ 31 */ 32 33 /* 34 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters. 35 */ 36 37 /* 38 * This driver would not have rewritten for OpenBSD if it was not for the 39 * hardware donation from Nocom. I want to thank them for their support. 40 * Of course, credit should go to Mike Smith for the original work he did 41 * in the FreeBSD driver where I found lots of reusable code and inspiration. 42 * - Niklas Hallqvist 43 */ 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/buf.h> 48 #include <sys/device.h> 49 #include <sys/kernel.h> 50 #include <sys/malloc.h> 51 52 #include <machine/bus.h> 53 54 #include <uvm/uvm_extern.h> 55 56 #include <scsi/scsi_all.h> 57 #include <scsi/scsi_disk.h> 58 #include <scsi/scsiconf.h> 59 60 #include <dev/ic/aacreg.h> 61 #include <dev/ic/aacvar.h> 62 #include <dev/ic/aac_tables.h> 63 64 /* Geometry constants. */ 65 #define AAC_MAXCYLS 1024 66 #define AAC_HEADS 64 67 #define AAC_SECS 32 /* mapping 64*32 */ 68 #define AAC_MEDHEADS 127 69 #define AAC_MEDSECS 63 /* mapping 127*63 */ 70 #define AAC_BIGHEADS 255 71 #define AAC_BIGSECS 63 /* mapping 255*63 */ 72 #define AAC_SECS32 0x1f /* round capacity */ 73 74 void aac_bio_complete(struct aac_ccb *); 75 void aac_complete(void *, int); 76 void aac_copy_internal_data(struct scsi_xfer *, u_int8_t *, size_t); 77 struct scsi_xfer *aac_dequeue(struct aac_softc *); 78 int aac_dequeue_fib(struct aac_softc *, int, u_int32_t *, 79 struct aac_fib **); 80 char *aac_describe_code(struct aac_code_lookup *, u_int32_t); 81 void aac_describe_controller(struct aac_softc *); 82 void aac_enqueue(struct aac_softc *, struct scsi_xfer *, int); 83 void aac_enqueue_ccb(struct aac_softc *, struct aac_ccb *); 84 int aac_enqueue_fib(struct aac_softc *, int, struct aac_ccb *); 85 void aac_eval_mapping(u_int32_t, int *, int *, int *); 86 int aac_exec_ccb(struct aac_ccb *); 87 void aac_free_ccb(struct aac_softc *, struct aac_ccb *); 88 struct aac_ccb *aac_get_ccb(struct aac_softc *, int); 89 #if 0 90 void aac_handle_aif(struct aac_softc *, struct aac_aif_command *); 91 #endif 92 void aac_host_command(struct aac_softc *); 93 void aac_host_response(struct aac_softc *); 94 int aac_init(struct aac_softc *); 95 int aac_internal_cache_cmd(struct scsi_xfer *); 96 int aac_map_command(struct aac_ccb *); 97 #ifdef AAC_DEBUG 98 void aac_print_fib(struct aac_softc *, struct aac_fib *, char *); 99 #endif 100 int aac_raw_scsi_cmd(struct scsi_xfer *); 101 int aac_scsi_cmd(struct scsi_xfer *); 102 int aac_start(struct aac_ccb *); 103 void aac_start_ccbs(struct aac_softc *); 104 void aac_startup(struct aac_softc *); 105 int aac_sync_command(struct aac_softc *, u_int32_t, u_int32_t, 106 u_int32_t, u_int32_t, u_int32_t, u_int32_t *); 107 int aac_sync_fib(struct aac_softc *, u_int32_t, u_int32_t, void *, 108 u_int16_t, void *, u_int16_t *); 109 void aac_timeout(void *); 110 void aac_unmap_command(struct aac_ccb *); 111 void aac_watchdog(void *); 112 113 struct cfdriver aac_cd = { 114 NULL, "aac", DV_DULL 115 }; 116 117 struct scsi_adapter aac_switch = { 118 aac_scsi_cmd, aacminphys, 0, 0, 119 }; 120 121 struct scsi_adapter aac_raw_switch = { 122 aac_raw_scsi_cmd, aacminphys, 0, 0, 123 }; 124 125 struct scsi_device aac_dev = { 126 NULL, NULL, NULL, NULL 127 }; 128 129 /* i960Rx interface */ 130 int aac_rx_get_fwstatus(struct aac_softc *); 131 void aac_rx_qnotify(struct aac_softc *, int); 132 int aac_rx_get_istatus(struct aac_softc *); 133 void aac_rx_clear_istatus(struct aac_softc *, int); 134 void aac_rx_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t, 135 u_int32_t, u_int32_t, u_int32_t); 136 int aac_rx_get_mailboxstatus(struct aac_softc *); 137 void aac_rx_set_interrupts(struct aac_softc *, int); 138 139 /* StrongARM interface */ 140 int aac_sa_get_fwstatus(struct aac_softc *); 141 void aac_sa_qnotify(struct aac_softc *, int); 142 int aac_sa_get_istatus(struct aac_softc *); 143 void aac_sa_clear_istatus(struct aac_softc *, int); 144 void aac_sa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t, 145 u_int32_t, u_int32_t, u_int32_t); 146 int aac_sa_get_mailboxstatus(struct aac_softc *); 147 void aac_sa_set_interrupts(struct aac_softc *, int); 148 149 struct aac_interface aac_rx_interface = { 150 aac_rx_get_fwstatus, 151 aac_rx_qnotify, 152 aac_rx_get_istatus, 153 aac_rx_clear_istatus, 154 aac_rx_set_mailbox, 155 aac_rx_get_mailboxstatus, 156 aac_rx_set_interrupts 157 }; 158 159 struct aac_interface aac_sa_interface = { 160 aac_sa_get_fwstatus, 161 aac_sa_qnotify, 162 aac_sa_get_istatus, 163 aac_sa_clear_istatus, 164 aac_sa_set_mailbox, 165 aac_sa_get_mailboxstatus, 166 aac_sa_set_interrupts 167 }; 168 169 #ifdef AAC_DEBUG 170 int aac_debug = AAC_DEBUG; 171 #endif 172 173 int 174 aac_attach(sc) 175 struct aac_softc *sc; 176 { 177 int i, error; 178 bus_dma_segment_t seg; 179 int nsegs; 180 struct aac_ccb *ccb; 181 182 TAILQ_INIT(&sc->sc_free_ccb); 183 TAILQ_INIT(&sc->sc_ccbq); 184 TAILQ_INIT(&sc->sc_completed); 185 LIST_INIT(&sc->sc_queue); 186 187 /* disable interrupts before we enable anything */ 188 AAC_MASK_INTERRUPTS(sc); 189 190 /* mark controller as suspended until we get ourselves organised */ 191 sc->sc_state |= AAC_STATE_SUSPEND; 192 193 /* 194 * Initialise the adapter. 195 */ 196 error = aac_init(sc); 197 if (error) 198 return (error); 199 200 /* 201 * Print a little information about the controller. 202 */ 203 aac_describe_controller(sc); 204 205 /* Initialize the ccbs */ 206 for (i = 0; i < AAC_ADAP_NORM_CMD_ENTRIES; i++) { 207 ccb = &sc->sc_ccbs[i]; 208 error = bus_dmamap_create(sc->sc_dmat, 209 (AAC_MAXSGENTRIES - 1) << PGSHIFT, AAC_MAXSGENTRIES, 210 (AAC_MAXSGENTRIES - 1) << PGSHIFT, 0, 211 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->ac_dmamap_xfer); 212 if (error) { 213 printf("%s: cannot create ccb dmamap (%d)", 214 sc->sc_dev.dv_xname, error); 215 /* XXX cleanup */ 216 return (1); 217 } 218 219 /* allocate the FIB cluster in DMAable memory and load it */ 220 if (bus_dmamem_alloc(sc->sc_dmat, sizeof *ccb->ac_fib, 1, 0, 221 &seg, 1, &nsegs, BUS_DMA_NOWAIT)) { 222 printf("%s: can't allocate FIB structure\n", 223 sc->sc_dev.dv_xname); 224 /* XXX cleanup */ 225 return (1); 226 } 227 ccb->ac_fibphys = seg.ds_addr; 228 if (bus_dmamem_map(sc->sc_dmat, &seg, nsegs, 229 sizeof *ccb->ac_fib, (caddr_t *)&ccb->ac_fib, 0)) { 230 printf("%s: can't map FIB structure\n", 231 sc->sc_dev.dv_xname); 232 /* XXX cleanup */ 233 return (1); 234 } 235 236 TAILQ_INSERT_TAIL(&sc->sc_free_ccb, &sc->sc_ccbs[i], 237 ac_chain); 238 } 239 240 /* Fill in the prototype scsi_link. */ 241 sc->sc_link.adapter_softc = sc; 242 sc->sc_link.adapter = &aac_switch; 243 sc->sc_link.device = &aac_dev; 244 sc->sc_link.openings = AAC_ADAP_NORM_CMD_ENTRIES; /* XXX optimal? */ 245 sc->sc_link.adapter_buswidth = AAC_MAX_CONTAINERS; 246 sc->sc_link.adapter_target = AAC_MAX_CONTAINERS; 247 248 config_found(&sc->sc_dev, &sc->sc_link, scsiprint); 249 250 return (0); 251 } 252 253 /* 254 * Look up a text description of a numeric error code and return a pointer to 255 * same. 256 */ 257 char * 258 aac_describe_code(table, code) 259 struct aac_code_lookup *table; 260 u_int32_t code; 261 { 262 int i; 263 264 for (i = 0; table[i].string != NULL; i++) 265 if (table[i].code == code) 266 return (table[i].string); 267 return (table[i + 1].string); 268 } 269 270 void 271 aac_describe_controller(sc) 272 struct aac_softc *sc; 273 { 274 u_int8_t buf[AAC_FIB_DATASIZE]; /* XXX a bit big for the stack */ 275 u_int16_t bufsize; 276 struct aac_adapter_info *info; 277 u_int8_t arg; 278 279 arg = 0; 280 if (aac_sync_fib(sc, RequestAdapterInfo, 0, &arg, sizeof arg, &buf, 281 &bufsize)) { 282 printf("%s: RequestAdapterInfo failed\n", sc->sc_dev.dv_xname); 283 return; 284 } 285 if (bufsize != sizeof *info) { 286 printf("%s: " 287 "RequestAdapterInfo returned wrong data size (%d != %d)\n", 288 sc->sc_dev.dv_xname, bufsize, sizeof *info); 289 return; 290 } 291 info = (struct aac_adapter_info *)&buf[0]; 292 293 printf("%s: %s %dMHz, %dMB, %s (%d) Kernel %d.%d-%d\n", 294 sc->sc_dev.dv_xname, 295 aac_describe_code(aac_cpu_variant, info->CpuVariant), 296 info->ClockSpeed, info->TotalMem / (1024 * 1024), 297 aac_describe_code(aac_battery_platform, info->batteryPlatform), 298 info->batteryPlatform, info->KernelRevision.external.comp.major, 299 info->KernelRevision.external.comp.minor, 300 info->KernelRevision.external.comp.dash); 301 302 /* save the kernel revision structure for later use */ 303 sc->sc_revision = info->KernelRevision; 304 } 305 306 int 307 aac_init(sc) 308 struct aac_softc *sc; 309 { 310 bus_dma_segment_t seg; 311 int nsegs; 312 int i, error; 313 int state = 0; 314 struct aac_adapter_init *ip; 315 u_int32_t code; 316 u_int8_t *qaddr; 317 318 /* 319 * First wait for the adapter to come ready. 320 */ 321 for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) { 322 code = AAC_GET_FWSTATUS(sc); 323 if (code & AAC_SELF_TEST_FAILED) { 324 printf("%s: FATAL: selftest failed\n", 325 sc->sc_dev.dv_xname); 326 return (ENXIO); 327 } 328 if (code & AAC_KERNEL_PANIC) { 329 printf("%s: FATAL: controller kernel panic\n", 330 sc->sc_dev.dv_xname); 331 return (ENXIO); 332 } 333 if (code & AAC_UP_AND_RUNNING) 334 break; 335 DELAY(1000); 336 } 337 if (i == AAC_BOOT_TIMEOUT * 1000) { 338 printf("%s: FATAL: controller not coming ready, status %x\n", 339 sc->sc_dev.dv_xname, code); 340 return (ENXIO); 341 } 342 343 if (bus_dmamem_alloc(sc->sc_dmat, sizeof *sc->sc_common, 1, 0, &seg, 1, 344 &nsegs, BUS_DMA_NOWAIT)) { 345 printf("%s: can't allocate common structure\n", 346 sc->sc_dev.dv_xname); 347 return (ENOMEM); 348 } 349 state++; 350 sc->sc_common_busaddr = seg.ds_addr; 351 if (bus_dmamem_map(sc->sc_dmat, &seg, nsegs, sizeof *sc->sc_common, 352 (caddr_t *)&sc->sc_common, 0)) { 353 printf("%s: can't map common structure\n", 354 sc->sc_dev.dv_xname); 355 error = ENOMEM; 356 goto bail_out; 357 } 358 state++; 359 bzero(sc->sc_common, sizeof *sc->sc_common); 360 361 /* 362 * Fill in the init structure. This tells the adapter about 363 * the physical location * of various important shared data 364 * structures. 365 */ 366 ip = &sc->sc_common->ac_init; 367 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION; 368 369 ip->AdapterFibsPhysicalAddress = 370 sc->sc_common_busaddr + offsetof(struct aac_common, ac_fibs); 371 ip->AdapterFibsVirtualAddress = &sc->sc_common->ac_fibs[0]; 372 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib); 373 ip->AdapterFibAlign = sizeof(struct aac_fib); 374 375 ip->PrintfBufferAddress = 376 sc->sc_common_busaddr + offsetof(struct aac_common, ac_printf); 377 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE; 378 379 ip->HostPhysMemPages = 0; /* not used? */ 380 ip->HostElapsedSeconds = 0; /* reset later if invalid */ 381 382 /* 383 * Initialise FIB queues. Note that it appears that the 384 * layout of the indexes and the segmentation of the entries 385 * is mandated by the adapter, which is only told about the 386 * base of the queue index fields. 387 * 388 * The initial values of the indices are assumed to inform the 389 * adapter of the sizes of the respective queues. 390 * 391 * The Linux driver uses a much more complex scheme whereby 392 * several header * records are kept for each queue. We use a 393 * couple of generic list manipulation functions which 394 * 'know' the size of each list by virtue of a table. 395 */ 396 qaddr = &sc->sc_common->ac_qbuf[0] + AAC_QUEUE_ALIGN; 397 qaddr -= (u_int32_t)qaddr % AAC_QUEUE_ALIGN; /* XXX not portable */ 398 sc->sc_queues = (struct aac_queue_table *)qaddr; 399 ip->CommHeaderAddress = sc->sc_common_busaddr + 400 ((char *)sc->sc_queues - (char *)sc->sc_common); 401 bzero(sc->sc_queues, sizeof(struct aac_queue_table)); 402 403 sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 404 AAC_HOST_NORM_CMD_ENTRIES; 405 sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 406 AAC_HOST_NORM_CMD_ENTRIES; 407 sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 408 AAC_HOST_HIGH_CMD_ENTRIES; 409 sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 410 AAC_HOST_HIGH_CMD_ENTRIES; 411 sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 412 AAC_ADAP_NORM_CMD_ENTRIES; 413 sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 414 AAC_ADAP_NORM_CMD_ENTRIES; 415 sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 416 AAC_ADAP_HIGH_CMD_ENTRIES; 417 sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 418 AAC_ADAP_HIGH_CMD_ENTRIES; 419 sc->sc_queues-> 420 qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = 421 AAC_HOST_NORM_RESP_ENTRIES; 422 sc->sc_queues-> 423 qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = 424 AAC_HOST_NORM_RESP_ENTRIES; 425 sc->sc_queues-> 426 qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = 427 AAC_HOST_HIGH_RESP_ENTRIES; 428 sc->sc_queues-> 429 qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = 430 AAC_HOST_HIGH_RESP_ENTRIES; 431 sc->sc_queues-> 432 qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = 433 AAC_ADAP_NORM_RESP_ENTRIES; 434 sc->sc_queues-> 435 qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = 436 AAC_ADAP_NORM_RESP_ENTRIES; 437 sc->sc_queues-> 438 qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = 439 AAC_ADAP_HIGH_RESP_ENTRIES; 440 sc->sc_queues-> 441 qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = 442 AAC_ADAP_HIGH_RESP_ENTRIES; 443 sc->sc_qentries[AAC_HOST_NORM_CMD_QUEUE] = 444 &sc->sc_queues->qt_HostNormCmdQueue[0]; 445 sc->sc_qentries[AAC_HOST_HIGH_CMD_QUEUE] = 446 &sc->sc_queues->qt_HostHighCmdQueue[0]; 447 sc->sc_qentries[AAC_ADAP_NORM_CMD_QUEUE] = 448 &sc->sc_queues->qt_AdapNormCmdQueue[0]; 449 sc->sc_qentries[AAC_ADAP_HIGH_CMD_QUEUE] = 450 &sc->sc_queues->qt_AdapHighCmdQueue[0]; 451 sc->sc_qentries[AAC_HOST_NORM_RESP_QUEUE] = 452 &sc->sc_queues->qt_HostNormRespQueue[0]; 453 sc->sc_qentries[AAC_HOST_HIGH_RESP_QUEUE] = 454 &sc->sc_queues->qt_HostHighRespQueue[0]; 455 sc->sc_qentries[AAC_ADAP_NORM_RESP_QUEUE] = 456 &sc->sc_queues->qt_AdapNormRespQueue[0]; 457 sc->sc_qentries[AAC_ADAP_HIGH_RESP_QUEUE] = 458 &sc->sc_queues->qt_AdapHighRespQueue[0]; 459 460 /* 461 * Do controller-type-specific initialisation 462 */ 463 switch (sc->sc_hwif) { 464 case AAC_HWIF_I960RX: 465 AAC_SETREG4(sc, AAC_RX_ODBR, ~0); 466 break; 467 } 468 469 /* 470 * Give the init structure to the controller. 471 */ 472 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT, 473 sc->sc_common_busaddr + offsetof(struct aac_common, ac_init), 0, 0, 474 0, NULL)) { 475 printf("%s: error establishing init structure\n", 476 sc->sc_dev.dv_xname); 477 error = EIO; 478 goto bail_out; 479 } 480 481 aac_startup(sc); 482 483 return (0); 484 485 bail_out: 486 if (state > 1) 487 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_common, 488 sizeof *sc->sc_common); 489 if (state > 0) 490 bus_dmamem_free(sc->sc_dmat, &seg, 1); 491 return (error); 492 } 493 494 /* 495 * Probe for containers, create disks. 496 */ 497 void 498 aac_startup (sc) 499 struct aac_softc *sc; 500 { 501 struct aac_mntinfo mi; 502 struct aac_mntinforesponse mir; 503 u_int16_t rsize; 504 int i, drv_cyls, drv_hds, drv_secs; 505 506 /* loop over possible containers */ 507 mi.Command = VM_NameServe; 508 mi.MntType = FT_FILESYS; 509 for (i = 0; i < AAC_MAX_CONTAINERS; i++) { 510 /* request information on this container */ 511 mi.MntCount = i; 512 if (aac_sync_fib(sc, ContainerCommand, 0, &mi, sizeof mi, &mir, 513 &rsize)) { 514 printf("%s: error probing container %d", 515 sc->sc_dev.dv_xname, i); 516 continue; 517 } 518 /* check response size */ 519 if (rsize != sizeof mir) { 520 printf("%s: container info response wrong size " 521 "(%d should be %d)", 522 sc->sc_dev.dv_xname, rsize, sizeof mir); 523 continue; 524 } 525 526 /* 527 * Check container volume type for validity. Note 528 * that many of the possible types * may never show 529 * up. 530 */ 531 if (mir.Status == ST_OK && 532 mir.MntTable[0].VolType != CT_NONE) { 533 AAC_DPRINTF(AAC_D_MISC, 534 ("%d: id %x name '%.16s' size %u type %d", i, 535 mir.MntTable[0].ObjectId, 536 mir.MntTable[0].FileSystemName, 537 mir.MntTable[0].Capacity, 538 mir.MntTable[0].VolType)); 539 540 sc->sc_hdr[i].hd_present = 1; 541 sc->sc_hdr[i].hd_size = mir.MntTable[0].Capacity; 542 543 /* 544 * Evaluate mapping (sectors per head, heads per cyl) 545 */ 546 sc->sc_hdr[i].hd_size &= ~AAC_SECS32; 547 aac_eval_mapping(sc->sc_hdr[i].hd_size, &drv_cyls, 548 &drv_hds, &drv_secs); 549 sc->sc_hdr[i].hd_heads = drv_hds; 550 sc->sc_hdr[i].hd_secs = drv_secs; 551 /* Round the size */ 552 sc->sc_hdr[i].hd_size = drv_cyls * drv_hds * drv_secs; 553 554 sc->sc_hdr[i].hd_devtype = mir.MntTable[0].VolType; 555 556 /* XXX Save the name too for use in IDENTIFY later */ 557 } 558 } 559 560 /* mark the controller up */ 561 sc->sc_state &= ~AAC_STATE_SUSPEND; 562 563 /* enable interrupts now */ 564 AAC_UNMASK_INTERRUPTS(sc); 565 } 566 567 void 568 aac_eval_mapping(size, cyls, heads, secs) 569 u_int32_t size; 570 int *cyls, *heads, *secs; 571 { 572 *cyls = size / AAC_HEADS / AAC_SECS; 573 if (*cyls < AAC_MAXCYLS) { 574 *heads = AAC_HEADS; 575 *secs = AAC_SECS; 576 } else { 577 /* Too high for 64 * 32 */ 578 *cyls = size / AAC_MEDHEADS / AAC_MEDSECS; 579 if (*cyls < AAC_MAXCYLS) { 580 *heads = AAC_MEDHEADS; 581 *secs = AAC_MEDSECS; 582 } else { 583 /* Too high for 127 * 63 */ 584 *cyls = size / AAC_BIGHEADS / AAC_BIGSECS; 585 *heads = AAC_BIGHEADS; 586 *secs = AAC_BIGSECS; 587 } 588 } 589 } 590 591 int 592 aac_raw_scsi_cmd(xs) 593 struct scsi_xfer *xs; 594 { 595 AAC_DPRINTF(AAC_D_CMD, ("aac_raw_scsi_cmd ")); 596 597 /* XXX Not yet implemented */ 598 xs->error = XS_DRIVER_STUFFUP; 599 return (COMPLETE); 600 } 601 602 int 603 aac_scsi_cmd(xs) 604 struct scsi_xfer *xs; 605 { 606 struct scsi_link *link = xs->sc_link; 607 struct aac_softc *sc = link->adapter_softc; 608 u_int8_t target = link->target; 609 struct aac_ccb *ccb; 610 u_int32_t blockno, blockcnt; 611 struct scsi_rw *rw; 612 struct scsi_rw_big *rwb; 613 aac_lock_t lock; 614 int retval = SUCCESSFULLY_QUEUED; 615 616 AAC_DPRINTF(AAC_D_CMD, ("aac_scsi_cmd ")); 617 618 xs->error = XS_NOERROR; 619 620 if (target >= AAC_MAX_CONTAINERS || !sc->sc_hdr[target].hd_present || 621 link->lun != 0) { 622 /* 623 * XXX Should be XS_SENSE but that would require setting up a 624 * faked sense too. 625 */ 626 xs->error = XS_DRIVER_STUFFUP; 627 xs->flags |= ITSDONE; 628 scsi_done(xs); 629 return (COMPLETE); 630 } 631 632 lock = AAC_LOCK(sc); 633 634 /* Don't double enqueue if we came from aac_chain. */ 635 if (xs != LIST_FIRST(&sc->sc_queue)) 636 aac_enqueue(sc, xs, 0); 637 638 while ((xs = aac_dequeue(sc))) { 639 xs->error = XS_NOERROR; 640 ccb = NULL; 641 link = xs->sc_link; 642 target = link->target; 643 644 switch (xs->cmd->opcode) { 645 case TEST_UNIT_READY: 646 case REQUEST_SENSE: 647 case INQUIRY: 648 case MODE_SENSE: 649 case START_STOP: 650 case READ_CAPACITY: 651 #if 0 652 case VERIFY: 653 #endif 654 if (!aac_internal_cache_cmd(xs)) { 655 AAC_UNLOCK(sc, lock); 656 return (TRY_AGAIN_LATER); 657 } 658 xs->flags |= ITSDONE; 659 scsi_done(xs); 660 goto ready; 661 662 case PREVENT_ALLOW: 663 AAC_DPRINTF(AAC_D_CMD, ("PREVENT/ALLOW ")); 664 /* XXX Not yet implemented */ 665 xs->error = XS_NOERROR; 666 xs->flags |= ITSDONE; 667 scsi_done(xs); 668 goto ready; 669 670 case SYNCHRONIZE_CACHE: 671 AAC_DPRINTF(AAC_D_CMD, ("SYNCHRONIZE_CACHE ")); 672 /* XXX Not yet implemented */ 673 xs->error = XS_NOERROR; 674 xs->flags |= ITSDONE; 675 scsi_done(xs); 676 goto ready; 677 678 default: 679 AAC_DPRINTF(AAC_D_CMD, 680 ("unknown opc %d ", xs->cmd->opcode)); 681 /* XXX Not yet implemented */ 682 xs->error = XS_DRIVER_STUFFUP; 683 xs->flags |= ITSDONE; 684 scsi_done(xs); 685 goto ready; 686 687 case READ_COMMAND: 688 case READ_BIG: 689 case WRITE_COMMAND: 690 case WRITE_BIG: 691 AAC_DPRINTF(AAC_D_CMD, 692 ("rw opc %d ", xs->cmd->opcode)); 693 694 if (xs->cmd->opcode != SYNCHRONIZE_CACHE) { 695 /* A read or write operation. */ 696 if (xs->cmdlen == 6) { 697 rw = (struct scsi_rw *)xs->cmd; 698 blockno = _3btol(rw->addr) & 699 (SRW_TOPADDR << 16 | 0xffff); 700 blockcnt = 701 rw->length ? rw->length : 0x100; 702 } else { 703 rwb = (struct scsi_rw_big *)xs->cmd; 704 blockno = _4btol(rwb->addr); 705 blockcnt = _2btol(rwb->length); 706 } 707 if (blockno >= sc->sc_hdr[target].hd_size || 708 blockno + blockcnt > 709 sc->sc_hdr[target].hd_size) { 710 printf( 711 "%s: out of bounds %u-%u >= %u\n", 712 sc->sc_dev.dv_xname, blockno, 713 blockcnt, 714 sc->sc_hdr[target].hd_size); 715 /* 716 * XXX Should be XS_SENSE but that 717 * would require setting up a faked 718 * sense too. 719 */ 720 xs->error = XS_DRIVER_STUFFUP; 721 xs->flags |= ITSDONE; 722 scsi_done(xs); 723 goto ready; 724 } 725 } 726 727 ccb = aac_get_ccb(sc, xs->flags); 728 729 /* 730 * We are out of commands, try again in a little while. 731 */ 732 if (ccb == NULL) { 733 xs->error = XS_DRIVER_STUFFUP; 734 AAC_UNLOCK(sc, lock); 735 return (TRY_AGAIN_LATER); 736 } 737 738 ccb->ac_blockno = blockno; 739 ccb->ac_blockcnt = blockcnt; 740 ccb->ac_xs = xs; 741 ccb->ac_timeout = xs->timeout; 742 743 if (xs->cmd->opcode != SYNCHRONIZE_CACHE && 744 aac_map_command(ccb)) { 745 aac_free_ccb(sc, ccb); 746 xs->error = XS_DRIVER_STUFFUP; 747 xs->flags |= ITSDONE; 748 scsi_done(xs); 749 goto ready; 750 } 751 752 aac_enqueue_ccb(sc, ccb); 753 /* XXX what if enqueue did not start a transfer? */ 754 if (xs->flags & SCSI_POLL) { 755 #if 0 756 if (!aac_wait(sc, ccb, ccb->ac_timeout)) { 757 AAC_UNLOCK(sc, lock); 758 printf("%s: command timed out\n", 759 sc->sc_dev.dv_xname); 760 xs->error = XS_TIMEOUT; 761 return (TRY_AGAIN_LATER); 762 } 763 xs->flags |= ITSDONE; 764 scsi_done(xs); 765 #endif 766 } 767 } 768 769 ready: 770 /* 771 * Don't process the queue if we are polling. 772 */ 773 if (xs->flags & SCSI_POLL) { 774 retval = COMPLETE; 775 break; 776 } 777 } 778 779 AAC_UNLOCK(sc, lock); 780 return (retval); 781 } 782 783 void 784 aac_copy_internal_data(xs, data, size) 785 struct scsi_xfer *xs; 786 u_int8_t *data; 787 size_t size; 788 { 789 size_t copy_cnt; 790 791 AAC_DPRINTF(AAC_D_MISC, ("aac_copy_internal_data ")); 792 793 if (!xs->datalen) 794 printf("uio move not yet supported\n"); 795 else { 796 copy_cnt = MIN(size, xs->datalen); 797 bcopy(data, xs->data, copy_cnt); 798 } 799 } 800 801 /* Emulated SCSI operation on cache device */ 802 int 803 aac_internal_cache_cmd(xs) 804 struct scsi_xfer *xs; 805 { 806 struct scsi_link *link = xs->sc_link; 807 struct aac_softc *sc = link->adapter_softc; 808 struct scsi_inquiry_data inq; 809 struct scsi_sense_data sd; 810 struct { 811 struct scsi_mode_header hd; 812 struct scsi_blk_desc bd; 813 union scsi_disk_pages dp; 814 } mpd; 815 struct scsi_read_cap_data rcd; 816 u_int8_t target = link->target; 817 818 AAC_DPRINTF(AAC_D_CMD, ("aac_internal_cache_cmd ")); 819 820 switch (xs->cmd->opcode) { 821 case TEST_UNIT_READY: 822 case START_STOP: 823 #if 0 824 case VERIFY: 825 #endif 826 AAC_DPRINTF(AAC_D_CMD, ("opc %d tgt %d ", xs->cmd->opcode, 827 target)); 828 break; 829 830 case REQUEST_SENSE: 831 AAC_DPRINTF(AAC_D_CMD, ("REQUEST SENSE tgt %d ", target)); 832 bzero(&sd, sizeof sd); 833 sd.error_code = 0x70; 834 sd.segment = 0; 835 sd.flags = SKEY_NO_SENSE; 836 aac_enc32(sd.info, 0); 837 sd.extra_len = 0; 838 aac_copy_internal_data(xs, (u_int8_t *)&sd, sizeof sd); 839 break; 840 841 case INQUIRY: 842 AAC_DPRINTF(AAC_D_CMD, ("INQUIRY tgt %d devtype %x ", target, 843 sc->sc_hdr[target].hd_devtype)); 844 bzero(&inq, sizeof inq); 845 /* XXX How do we detect removable/CD-ROM devices? */ 846 inq.device = T_DIRECT; 847 inq.dev_qual2 = 0; 848 inq.version = 2; 849 inq.response_format = 2; 850 inq.additional_length = 32; 851 strlcpy(inq.vendor, "Adaptec", sizeof inq.vendor); 852 snprintf(inq.product, sizeof inq.product, "Container #%02d", 853 target); 854 strlcpy(inq.revision, " ", sizeof inq.revision); 855 aac_copy_internal_data(xs, (u_int8_t *)&inq, sizeof inq); 856 break; 857 858 case MODE_SENSE: 859 AAC_DPRINTF(AAC_D_CMD, ("MODE SENSE tgt %d ", target)); 860 861 bzero(&mpd, sizeof mpd); 862 switch (((struct scsi_mode_sense *)xs->cmd)->page) { 863 case 4: 864 /* scsi_disk.h says this should be 0x16 */ 865 mpd.dp.rigid_geometry.pg_length = 0x16; 866 mpd.hd.data_length = sizeof mpd.hd + sizeof mpd.bd + 867 mpd.dp.rigid_geometry.pg_length; 868 mpd.hd.blk_desc_len = sizeof mpd.bd; 869 870 /* XXX */ 871 mpd.hd.dev_spec = 0; 872 _lto3b(AAC_BLOCK_SIZE, mpd.bd.blklen); 873 mpd.dp.rigid_geometry.pg_code = 4; 874 _lto3b(sc->sc_hdr[target].hd_size / 875 sc->sc_hdr[target].hd_heads / 876 sc->sc_hdr[target].hd_secs, 877 mpd.dp.rigid_geometry.ncyl); 878 mpd.dp.rigid_geometry.nheads = 879 sc->sc_hdr[target].hd_heads; 880 aac_copy_internal_data(xs, (u_int8_t *)&mpd, 881 sizeof mpd); 882 break; 883 884 default: 885 printf("%s: mode sense page %d not simulated\n", 886 sc->sc_dev.dv_xname, 887 ((struct scsi_mode_sense *)xs->cmd)->page); 888 xs->error = XS_DRIVER_STUFFUP; 889 return (0); 890 } 891 break; 892 893 case READ_CAPACITY: 894 AAC_DPRINTF(AAC_D_CMD, ("READ CAPACITY tgt %d ", target)); 895 bzero(&rcd, sizeof rcd); 896 _lto4b(sc->sc_hdr[target].hd_size - 1, rcd.addr); 897 _lto4b(AAC_BLOCK_SIZE, rcd.length); 898 aac_copy_internal_data(xs, (u_int8_t *)&rcd, sizeof rcd); 899 break; 900 901 default: 902 printf("aac_internal_cache_cmd got bad opcode: %d\n", 903 xs->cmd->opcode); 904 xs->error = XS_DRIVER_STUFFUP; 905 return (0); 906 } 907 908 xs->error = XS_NOERROR; 909 return (1); 910 } 911 912 /* 913 * Take an interrupt. 914 */ 915 int 916 aac_intr(arg) 917 void *arg; 918 { 919 struct aac_softc *sc = arg; 920 u_int16_t reason; 921 int claimed = 0; 922 923 AAC_DPRINTF(AAC_D_INTR, ("aac_intr(%p) ", sc)); 924 925 reason = AAC_GET_ISTATUS(sc); 926 AAC_DPRINTF(AAC_D_INTR, ("istatus 0x%04x ", reason)); 927 928 /* controller wants to talk to the log? XXX should we defer this? */ 929 if (reason & AAC_DB_PRINTF) { 930 if (sc->sc_common->ac_printf[0]) { 931 printf("%s: ** %.*s", sc->sc_dev.dv_xname, 932 AAC_PRINTF_BUFSIZE, sc->sc_common->ac_printf); 933 sc->sc_common->ac_printf[0] = 0; 934 } 935 AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF); 936 AAC_QNOTIFY(sc, AAC_DB_PRINTF); 937 claimed = 1; 938 } 939 940 /* Controller has a message for us? */ 941 if (reason & AAC_DB_COMMAND_READY) { 942 aac_host_command(sc); 943 AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_READY); 944 claimed = 1; 945 } 946 947 /* Controller has a response for us? */ 948 if (reason & AAC_DB_RESPONSE_READY) { 949 aac_host_response(sc); 950 AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY); 951 claimed = 1; 952 } 953 954 /* 955 * Spurious interrupts that we don't use - reset the mask and clear 956 * the interrupts. 957 */ 958 if (reason & (AAC_DB_SYNC_COMMAND | AAC_DB_COMMAND_NOT_FULL | 959 AAC_DB_RESPONSE_NOT_FULL)) { 960 AAC_UNMASK_INTERRUPTS(sc); 961 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND | 962 AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL); 963 claimed = 1; 964 } 965 966 return (claimed); 967 } 968 969 /* 970 * Handle notification of one or more FIBs coming from the controller. 971 */ 972 void 973 aac_host_command(struct aac_softc *sc) 974 { 975 struct aac_fib *fib; 976 u_int32_t fib_size; 977 978 for (;;) { 979 if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, &fib_size, 980 &fib)) 981 break; /* nothing to do */ 982 983 switch(fib->Header.Command) { 984 case AifRequest: 985 #if 0 986 aac_handle_aif(sc, 987 (struct aac_aif_command *)&fib->data[0]); 988 #endif 989 990 break; 991 default: 992 printf("%s: unknown command from controller\n", 993 sc->sc_dev.dv_xname); 994 AAC_PRINT_FIB(sc, fib); 995 break; 996 } 997 998 /* XXX reply to FIBs requesting responses ?? */ 999 /* XXX how do we return these FIBs to the controller? */ 1000 } 1001 } 1002 1003 /* 1004 * Handle notification of one or more FIBs completed by the controller 1005 */ 1006 void 1007 aac_host_response(struct aac_softc *sc) 1008 { 1009 struct aac_ccb *ccb; 1010 struct aac_fib *fib; 1011 u_int32_t fib_size; 1012 1013 for (;;) { 1014 /* look for completed FIBs on our queue */ 1015 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size, 1016 &fib)) 1017 break; /* nothing to do */ 1018 1019 /* get the command, unmap and queue for later processing */ 1020 ccb = (struct aac_ccb *)fib->Header.SenderData; 1021 if (ccb == NULL) { 1022 AAC_PRINT_FIB(sc, fib); 1023 } else { 1024 timeout_del(&ccb->ac_xs->stimeout); 1025 aac_unmap_command(ccb); /* XXX defer? */ 1026 aac_enqueue_completed(ccb); 1027 } 1028 } 1029 1030 /* handle completion processing */ 1031 aac_complete(sc, 0); 1032 } 1033 1034 /* 1035 * Process completed commands. 1036 */ 1037 void 1038 aac_complete(void *context, int pending) 1039 { 1040 struct aac_softc *sc = (struct aac_softc *)context; 1041 struct aac_ccb *ccb; 1042 1043 /* pull completed commands off the queue */ 1044 for (;;) { 1045 ccb = aac_dequeue_completed(sc); 1046 if (ccb == NULL) 1047 return; 1048 ccb->ac_flags |= AAC_ACF_COMPLETED; 1049 1050 #if 0 1051 /* is there a completion handler? */ 1052 if (ccb->ac_complete != NULL) { 1053 ccb->ac_complete(ccb); 1054 } else { 1055 /* assume that someone is sleeping on this command */ 1056 wakeup(ccb); 1057 } 1058 #else 1059 aac_bio_complete(ccb); 1060 #endif 1061 } 1062 } 1063 1064 /* 1065 * Handle a bio-instigated command that has been completed. 1066 */ 1067 void 1068 aac_bio_complete(struct aac_ccb *ccb) 1069 { 1070 struct scsi_xfer *xs = ccb->ac_xs; 1071 struct aac_softc *sc = xs->sc_link->adapter_softc; 1072 struct buf *bp = xs->bp; 1073 struct aac_blockread_response *brr; 1074 struct aac_blockwrite_response *bwr; 1075 AAC_FSAStatus status; 1076 1077 /* fetch relevant status and then release the command */ 1078 if (bp->b_flags & B_READ) { 1079 brr = (struct aac_blockread_response *)&ccb->ac_fib->data[0]; 1080 status = brr->Status; 1081 } else { 1082 bwr = (struct aac_blockwrite_response *)&ccb->ac_fib->data[0]; 1083 status = bwr->Status; 1084 } 1085 aac_free_ccb(sc, ccb); 1086 1087 /* fix up the bio based on status */ 1088 if (status == ST_OK) { 1089 bp->b_resid = 0; 1090 } else { 1091 bp->b_error = EIO; 1092 bp->b_flags |= B_ERROR; 1093 1094 /* XXX be more verbose? */ 1095 printf("%s: I/O error %d (%s)\n", sc->sc_dev.dv_xname, 1096 status, AAC_COMMAND_STATUS(status)); 1097 } 1098 scsi_done(xs); 1099 } 1100 1101 /* 1102 * Send a synchronous command to the controller and wait for a result. 1103 */ 1104 int 1105 aac_sync_command(sc, command, arg0, arg1, arg2, arg3, sp) 1106 struct aac_softc *sc; 1107 u_int32_t command; 1108 u_int32_t arg0; 1109 u_int32_t arg1; 1110 u_int32_t arg2; 1111 u_int32_t arg3; 1112 u_int32_t *sp; 1113 { 1114 int i; 1115 u_int32_t status; 1116 aac_lock_t lock = AAC_LOCK(sc); 1117 1118 /* populate the mailbox */ 1119 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3); 1120 1121 /* ensure the sync command doorbell flag is cleared */ 1122 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1123 1124 /* then set it to signal the adapter */ 1125 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND); 1126 DELAY(AAC_SYNC_DELAY); 1127 1128 /* spin waiting for the command to complete */ 1129 for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) { 1130 if (AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND); 1131 break; 1132 DELAY(1000); 1133 } 1134 if (i == AAC_IMMEDIATE_TIMEOUT * 1000) { 1135 AAC_UNLOCK(sc, lock); 1136 return (EIO); 1137 } 1138 1139 /* clear the completion flag */ 1140 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 1141 1142 /* get the command status */ 1143 status = AAC_GET_MAILBOXSTATUS(sc); 1144 AAC_UNLOCK(sc, lock); 1145 if (sp != NULL) 1146 *sp = status; 1147 return (0); /* check command return status? */ 1148 } 1149 1150 /* 1151 * Send a synchronous FIB to the controller and wait for a result. 1152 */ 1153 int 1154 aac_sync_fib(sc, command, xferstate, data, datasize, result, resultsize) 1155 struct aac_softc *sc; 1156 u_int32_t command; 1157 u_int32_t xferstate; 1158 void *data; 1159 u_int16_t datasize; 1160 void *result; 1161 u_int16_t *resultsize; 1162 { 1163 struct aac_fib *fib = &sc->sc_common->ac_sync_fib; 1164 1165 if (datasize > AAC_FIB_DATASIZE) 1166 return (EINVAL); 1167 1168 /* 1169 * Set up the sync FIB 1170 */ 1171 fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED | 1172 AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_EMPTY; 1173 fib->Header.XferState |= xferstate; 1174 fib->Header.Command = command; 1175 fib->Header.StructType = AAC_FIBTYPE_TFIB; 1176 fib->Header.Size = sizeof fib + datasize; 1177 fib->Header.SenderSize = sizeof *fib; 1178 fib->Header.SenderFibAddress = (u_int32_t)fib; 1179 fib->Header.ReceiverFibAddress = 1180 sc->sc_common_busaddr + offsetof(struct aac_common, ac_sync_fib); 1181 1182 /* 1183 * Copy in data. 1184 */ 1185 if (data != NULL) { 1186 bcopy(data, fib->data, datasize); 1187 fib->Header.XferState |= 1188 AAC_FIBSTATE_FROMHOST | AAC_FIBSTATE_NORM; 1189 } 1190 1191 /* 1192 * Give the FIB to the controller, wait for a response. 1193 */ 1194 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, 1195 fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) { 1196 return (EIO); 1197 } 1198 1199 /* 1200 * Copy out the result 1201 */ 1202 if (result != NULL) { 1203 *resultsize = fib->Header.Size - sizeof fib->Header; 1204 bcopy(fib->data, result, *resultsize); 1205 } 1206 return (0); 1207 } 1208 1209 void 1210 aacminphys(bp) 1211 struct buf *bp; 1212 { 1213 #if 0 1214 u_int8_t *buf = bp->b_data; 1215 paddr_t pa; 1216 long off; 1217 #endif 1218 1219 AAC_DPRINTF(AAC_D_MISC, ("aacminphys(0x%x) ", bp)); 1220 1221 #if 1 1222 #if 0 /* As this is way more than MAXPHYS it's really not necessary. */ 1223 if (bp->b_bcount > ((AAC_MAXOFFSETS - 1) * PAGE_SIZE)) 1224 bp->b_bcount = ((AAC_MAXOFFSETS - 1) * PAGE_SIZE); 1225 #endif 1226 #else 1227 for (off = PAGE_SIZE, pa = vtophys(buf); off < bp->b_bcount; 1228 off += PAGE_SIZE) 1229 if (pa + off != vtophys(buf + off)) { 1230 bp->b_bcount = off; 1231 break; 1232 } 1233 #endif 1234 minphys(bp); 1235 } 1236 1237 /* 1238 * Read the current firmware status word. 1239 */ 1240 int 1241 aac_sa_get_fwstatus(sc) 1242 struct aac_softc *sc; 1243 { 1244 return (AAC_GETREG4(sc, AAC_SA_FWSTATUS)); 1245 } 1246 1247 int 1248 aac_rx_get_fwstatus(sc) 1249 struct aac_softc *sc; 1250 { 1251 return (AAC_GETREG4(sc, AAC_RX_FWSTATUS)); 1252 } 1253 1254 /* 1255 * Notify the controller of a change in a given queue 1256 */ 1257 1258 void 1259 aac_sa_qnotify(sc, qbit) 1260 struct aac_softc *sc; 1261 int qbit; 1262 { 1263 AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit); 1264 } 1265 1266 void 1267 aac_rx_qnotify(sc, qbit) 1268 struct aac_softc *sc; 1269 int qbit; 1270 { 1271 AAC_SETREG4(sc, AAC_RX_IDBR, qbit); 1272 } 1273 1274 /* 1275 * Get the interrupt reason bits 1276 */ 1277 int 1278 aac_sa_get_istatus(sc) 1279 struct aac_softc *sc; 1280 { 1281 return (AAC_GETREG2(sc, AAC_SA_DOORBELL0)); 1282 } 1283 1284 int 1285 aac_rx_get_istatus(sc) 1286 struct aac_softc *sc; 1287 { 1288 return (AAC_GETREG4(sc, AAC_RX_ODBR)); 1289 } 1290 1291 /* 1292 * Clear some interrupt reason bits 1293 */ 1294 void 1295 aac_sa_clear_istatus(sc, mask) 1296 struct aac_softc *sc; 1297 int mask; 1298 { 1299 AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask); 1300 } 1301 1302 void 1303 aac_rx_clear_istatus(sc, mask) 1304 struct aac_softc *sc; 1305 int mask; 1306 { 1307 AAC_SETREG4(sc, AAC_RX_ODBR, mask); 1308 } 1309 1310 /* 1311 * Populate the mailbox and set the command word 1312 */ 1313 void 1314 aac_sa_set_mailbox(sc, command, arg0, arg1, arg2, arg3) 1315 struct aac_softc *sc; 1316 u_int32_t command; 1317 u_int32_t arg0; 1318 u_int32_t arg1; 1319 u_int32_t arg2; 1320 u_int32_t arg3; 1321 { 1322 AAC_SETREG4(sc, AAC_SA_MAILBOX, command); 1323 AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0); 1324 AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1); 1325 AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2); 1326 AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3); 1327 } 1328 1329 void 1330 aac_rx_set_mailbox(sc, command, arg0, arg1, arg2, arg3) 1331 struct aac_softc *sc; 1332 u_int32_t command; 1333 u_int32_t arg0; 1334 u_int32_t arg1; 1335 u_int32_t arg2; 1336 u_int32_t arg3; 1337 { 1338 AAC_SETREG4(sc, AAC_RX_MAILBOX, command); 1339 AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0); 1340 AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1); 1341 AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2); 1342 AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3); 1343 } 1344 1345 /* 1346 * Fetch the immediate command status word 1347 */ 1348 int 1349 aac_sa_get_mailboxstatus(sc) 1350 struct aac_softc *sc; 1351 { 1352 return (AAC_GETREG4(sc, AAC_SA_MAILBOX)); 1353 } 1354 1355 int 1356 aac_rx_get_mailboxstatus(sc) 1357 struct aac_softc *sc; 1358 { 1359 return (AAC_GETREG4(sc, AAC_RX_MAILBOX)); 1360 } 1361 1362 /* 1363 * Set/clear interrupt masks 1364 */ 1365 void 1366 aac_sa_set_interrupts(sc, enable) 1367 struct aac_softc *sc; 1368 int enable; 1369 { 1370 if (enable) 1371 AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS); 1372 else 1373 AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0); 1374 } 1375 1376 void 1377 aac_rx_set_interrupts(sc, enable) 1378 struct aac_softc *sc; 1379 int enable; 1380 { 1381 if (enable) 1382 AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS); 1383 else 1384 AAC_SETREG4(sc, AAC_RX_OIMR, ~0); 1385 } 1386 1387 struct aac_ccb * 1388 aac_get_ccb(sc, flags) 1389 struct aac_softc *sc; 1390 int flags; 1391 { 1392 struct aac_ccb *ccb; 1393 aac_lock_t lock; 1394 1395 AAC_DPRINTF(AAC_D_QUEUE, ("aac_get_ccb(%p, 0x%x) ", sc, flags)); 1396 1397 lock = AAC_LOCK(sc); 1398 1399 for (;;) { 1400 ccb = TAILQ_FIRST(&sc->sc_free_ccb); 1401 if (ccb != NULL) 1402 break; 1403 if (flags & SCSI_NOSLEEP) 1404 goto bail_out; 1405 tsleep(&sc->sc_free_ccb, PRIBIO, "aac_ccb", 0); 1406 } 1407 1408 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, ac_chain); 1409 1410 /* initialise the command/FIB */ 1411 ccb->ac_sgtable = NULL; 1412 ccb->ac_flags = 0; 1413 ccb->ac_fib->Header.XferState = AAC_FIBSTATE_EMPTY; 1414 ccb->ac_fib->Header.StructType = AAC_FIBTYPE_TFIB; 1415 ccb->ac_fib->Header.Flags = 0; 1416 ccb->ac_fib->Header.SenderSize = sizeof(struct aac_fib); 1417 1418 /* 1419 * These are duplicated in aac_start to cover the case where an 1420 * intermediate stage may have destroyed them. They're left 1421 * initialised here for debugging purposes only. 1422 */ 1423 ccb->ac_fib->Header.SenderFibAddress = (u_int32_t)ccb->ac_fib; 1424 ccb->ac_fib->Header.ReceiverFibAddress = ccb->ac_fibphys; 1425 1426 bail_out: 1427 AAC_UNLOCK(sc, lock); 1428 return (ccb); 1429 } 1430 1431 void 1432 aac_free_ccb(sc, ccb) 1433 struct aac_softc *sc; 1434 struct aac_ccb *ccb; 1435 { 1436 aac_lock_t lock; 1437 1438 AAC_DPRINTF(AAC_D_QUEUE, ("aac_free_ccb(%p, %p) ", sc, ccb)); 1439 1440 lock = AAC_LOCK(sc); 1441 1442 TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, ac_chain); 1443 1444 /* If the free list was empty, wake up potential waiters. */ 1445 if (TAILQ_NEXT(ccb, ac_chain) == NULL) 1446 wakeup(&sc->sc_free_ccb); 1447 1448 AAC_UNLOCK(sc, lock); 1449 } 1450 1451 void 1452 aac_enqueue_ccb(sc, ccb) 1453 struct aac_softc *sc; 1454 struct aac_ccb *ccb; 1455 { 1456 AAC_DPRINTF(AAC_D_QUEUE, ("aac_enqueue_ccb(%p, %p) ", sc, ccb)); 1457 1458 timeout_set(&ccb->ac_xs->stimeout, aac_timeout, ccb); 1459 TAILQ_INSERT_TAIL(&sc->sc_ccbq, ccb, ac_chain); 1460 aac_start_ccbs(sc); 1461 } 1462 1463 void 1464 aac_start_ccbs(sc) 1465 struct aac_softc *sc; 1466 { 1467 struct aac_ccb *ccb; 1468 struct scsi_xfer *xs; 1469 1470 AAC_DPRINTF(AAC_D_QUEUE, ("aac_start_ccbs(%p) ", sc)); 1471 1472 while ((ccb = TAILQ_FIRST(&sc->sc_ccbq)) != NULL) { 1473 1474 xs = ccb->ac_xs; 1475 if (ccb->ac_flags & AAC_ACF_WATCHDOG) 1476 timeout_del(&xs->stimeout); 1477 1478 if (aac_exec_ccb(ccb) == 0) { 1479 ccb->ac_flags |= AAC_ACF_WATCHDOG; 1480 timeout_set(&ccb->ac_xs->stimeout, aac_watchdog, ccb); 1481 timeout_add(&xs->stimeout, 1482 (AAC_WATCH_TIMEOUT * hz) / 1000); 1483 break; 1484 } 1485 TAILQ_REMOVE(&sc->sc_ccbq, ccb, ac_chain); 1486 1487 if ((xs->flags & SCSI_POLL) == 0) { 1488 timeout_set(&ccb->ac_xs->stimeout, aac_timeout, ccb); 1489 timeout_add(&xs->stimeout, 1490 (ccb->ac_timeout * hz) / 1000); 1491 } 1492 } 1493 } 1494 1495 int 1496 aac_exec_ccb(ccb) 1497 struct aac_ccb *ccb; 1498 { 1499 struct scsi_xfer *xs = ccb->ac_xs; 1500 struct scsi_link *link = xs->sc_link; 1501 u_int8_t target = link->target; 1502 int i; 1503 struct aac_fib *fib; 1504 struct aac_blockread *br; 1505 struct aac_blockwrite *bw; 1506 bus_dmamap_t xfer; 1507 1508 AAC_DPRINTF(AAC_D_CMD, ("aac_exec_ccb(%p, %p) ", xs, ccb)); 1509 1510 /* build the FIB */ 1511 fib = ccb->ac_fib; 1512 fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED | 1513 AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_FROMHOST | 1514 AAC_FIBSTATE_REXPECTED | AAC_FIBSTATE_NORM; 1515 fib->Header.Command = ContainerCommand; 1516 fib->Header.Size = sizeof(struct aac_fib_header); 1517 1518 switch (xs->cmd->opcode) { 1519 case PREVENT_ALLOW: 1520 case SYNCHRONIZE_CACHE: 1521 if (xs->cmd->opcode == PREVENT_ALLOW) { 1522 /* XXX PREVENT_ALLOW support goes here */ 1523 } else { 1524 AAC_DPRINTF(AAC_D_CMD, 1525 ("SYNCHRONIZE CACHE tgt %d ", target)); 1526 } 1527 break; 1528 1529 case WRITE_COMMAND: 1530 case WRITE_BIG: 1531 bw = (struct aac_blockwrite *)&fib->data[0]; 1532 bw->Command = VM_CtBlockWrite; 1533 bw->ContainerId = target; 1534 bw->BlockNumber = ccb->ac_blockno; 1535 bw->ByteCount = ccb->ac_blockcnt * DEV_BSIZE; 1536 bw->Stable = CUNSTABLE; /* XXX what's appropriate here? */ 1537 fib->Header.Size += sizeof(struct aac_blockwrite); 1538 ccb->ac_sgtable = &bw->SgMap; 1539 break; 1540 1541 case READ_COMMAND: 1542 case READ_BIG: 1543 br = (struct aac_blockread *)&fib->data[0]; 1544 br->Command = VM_CtBlockRead; 1545 br->ContainerId = target; 1546 br->BlockNumber = ccb->ac_blockno; 1547 br->ByteCount = ccb->ac_blockcnt * DEV_BSIZE; 1548 fib->Header.Size += sizeof(struct aac_blockread); 1549 ccb->ac_sgtable = &br->SgMap; 1550 break; 1551 } 1552 1553 if (xs->cmd->opcode != PREVENT_ALLOW && 1554 xs->cmd->opcode != SYNCHRONIZE_CACHE) { 1555 xfer = ccb->ac_dmamap_xfer; 1556 ccb->ac_sgtable->SgCount = xfer->dm_nsegs; 1557 for (i = 0; i < xfer->dm_nsegs; i++) { 1558 ccb->ac_sgtable->SgEntry[i].SgAddress = 1559 xfer->dm_segs[i].ds_addr; 1560 ccb->ac_sgtable->SgEntry[i].SgByteCount = 1561 xfer->dm_segs[i].ds_len; 1562 AAC_DPRINTF(AAC_D_IO, 1563 ("#%d va %p pa %p len %x\n", i, buf, 1564 xfer->dm_segs[i].ds_addr, 1565 xfer->dm_segs[i].ds_len)); 1566 } 1567 1568 /* update the FIB size for the s/g count */ 1569 fib->Header.Size += xfer->dm_nsegs * 1570 sizeof(struct aac_sg_entry); 1571 } 1572 1573 aac_start(ccb); 1574 1575 xs->error = XS_NOERROR; 1576 xs->resid = 0; 1577 return (1); 1578 } 1579 1580 /******************************************************************************** 1581 * Deliver a command to the controller; allocate controller resources at the 1582 * last moment when possible. 1583 */ 1584 int 1585 aac_start(struct aac_ccb *ccb) 1586 { 1587 struct aac_softc *sc = ccb->ac_xs->sc_link->adapter_softc; 1588 1589 #if 0 1590 /* get the command mapped */ 1591 aac_map_command(ccb); 1592 #endif 1593 1594 /* fix up the address values */ 1595 ccb->ac_fib->Header.SenderFibAddress = (u_int32_t)ccb->ac_fib; 1596 ccb->ac_fib->Header.ReceiverFibAddress = ccb->ac_fibphys; 1597 1598 /* save a pointer to the command for speedy reverse-lookup */ 1599 ccb->ac_fib->Header.SenderData = (u_int32_t)ccb; /* XXX ack, sizing */ 1600 1601 /* put the FIB on the outbound queue */ 1602 if (aac_enqueue_fib(sc, AAC_ADAP_NORM_CMD_QUEUE, ccb)) 1603 return (EBUSY); 1604 1605 return (0); 1606 } 1607 1608 /* 1609 * Map a command into controller-visible space. 1610 */ 1611 int 1612 aac_map_command(struct aac_ccb *ccb) 1613 { 1614 struct scsi_xfer *xs = ccb->ac_xs; 1615 struct aac_softc *sc = xs->sc_link->adapter_softc; 1616 int error; 1617 1618 #if 0 1619 /* don't map more than once */ 1620 if (ccb->ac_flags & AAC_CMD_MAPPED) 1621 return; 1622 #endif 1623 1624 if (xs->datalen != 0) { 1625 error = bus_dmamap_load(sc->sc_dmat, ccb->ac_dmamap_xfer, 1626 xs->data, xs->datalen, NULL, 1627 (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : 1628 BUS_DMA_WAITOK); 1629 if (error) { 1630 printf("%s: aac_scsi_cmd: ", sc->sc_dev.dv_xname); 1631 if (error == EFBIG) 1632 printf("more than %d dma segs\n", 1633 AAC_MAXSGENTRIES); 1634 else 1635 printf("error %d loading dma map\n", error); 1636 return (error); 1637 } 1638 1639 bus_dmamap_sync(sc->sc_dmat, ccb->ac_dmamap_xfer, 0, 1640 ccb->ac_dmamap_xfer->dm_mapsize, 1641 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD : 1642 BUS_DMASYNC_PREWRITE); 1643 } 1644 1645 #if 0 1646 ccb->ac_flags |= AAC_CMD_MAPPED; 1647 #endif 1648 return (0); 1649 } 1650 1651 /* 1652 * Unmap a command from controller-visible space. 1653 */ 1654 void 1655 aac_unmap_command(struct aac_ccb *ccb) 1656 { 1657 struct scsi_xfer *xs = ccb->ac_xs; 1658 struct aac_softc *sc = xs->sc_link->adapter_softc; 1659 1660 #if 0 1661 if (!(ccb->ac_flags & AAC_CMD_MAPPED)) 1662 return; 1663 #endif 1664 1665 if (xs->datalen != 0) { 1666 bus_dmamap_sync(sc->sc_dmat, ccb->ac_dmamap_xfer, 0, 1667 ccb->ac_dmamap_xfer->dm_mapsize, 1668 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD : 1669 BUS_DMASYNC_POSTWRITE); 1670 1671 bus_dmamap_unload(sc->sc_dmat, ccb->ac_dmamap_xfer); 1672 } 1673 #if 0 1674 ccb->ac_flags &= ~AAC_CMD_MAPPED; 1675 #endif 1676 } 1677 1678 void 1679 aac_timeout(arg) 1680 void *arg; 1681 { 1682 struct aac_ccb *ccb = arg; 1683 struct scsi_link *link = ccb->ac_xs->sc_link; 1684 struct aac_softc *sc = link->adapter_softc; 1685 aac_lock_t lock; 1686 1687 sc_print_addr(link); 1688 printf("timed out\n"); 1689 1690 /* XXX Test for multiple timeouts */ 1691 1692 ccb->ac_xs->error = XS_TIMEOUT; 1693 lock = AAC_LOCK(sc); 1694 aac_enqueue_ccb(sc, ccb); 1695 AAC_UNLOCK(sc, lock); 1696 } 1697 1698 void 1699 aac_watchdog(arg) 1700 void *arg; 1701 { 1702 struct aac_ccb *ccb = arg; 1703 struct scsi_link *link = ccb->ac_xs->sc_link; 1704 struct aac_softc *sc = link->adapter_softc; 1705 aac_lock_t lock; 1706 1707 lock = AAC_LOCK(sc); 1708 ccb->ac_flags &= ~AAC_ACF_WATCHDOG; 1709 aac_start_ccbs(sc); 1710 AAC_UNLOCK(sc, lock); 1711 } 1712 /* 1713 * Insert a command into the driver queue, either at the front or at the tail. 1714 * It's ok to overload the freelist link as these structures are never on 1715 * the freelist at this time. 1716 */ 1717 void 1718 aac_enqueue(sc, xs, infront) 1719 struct aac_softc *sc; 1720 struct scsi_xfer *xs; 1721 int infront; 1722 { 1723 if (infront || LIST_FIRST(&sc->sc_queue) == NULL) { 1724 if (LIST_FIRST(&sc->sc_queue) == NULL) 1725 sc->sc_queuelast = xs; 1726 LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list); 1727 return; 1728 } 1729 LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list); 1730 sc->sc_queuelast = xs; 1731 } 1732 1733 /* 1734 * Pull a command off the front of the driver queue. 1735 */ 1736 struct scsi_xfer * 1737 aac_dequeue(sc) 1738 struct aac_softc *sc; 1739 { 1740 struct scsi_xfer *xs; 1741 1742 xs = LIST_FIRST(&sc->sc_queue); 1743 if (xs == NULL) 1744 return (NULL); 1745 LIST_REMOVE(xs, free_list); 1746 1747 if (LIST_FIRST(&sc->sc_queue) == NULL) 1748 sc->sc_queuelast = NULL; 1749 1750 return (xs); 1751 } 1752 1753 /******************************************************************************** 1754 * Adapter-space FIB queue manipulation 1755 * 1756 * Note that the queue implementation here is a little funky; neither the PI or 1757 * CI will ever be zero. This behaviour is a controller feature. 1758 */ 1759 static struct { 1760 int size; 1761 int notify; 1762 } aac_qinfo[] = { 1763 { AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL }, 1764 { AAC_HOST_HIGH_CMD_ENTRIES, 0 }, 1765 { AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY }, 1766 { AAC_ADAP_HIGH_CMD_ENTRIES, 0 }, 1767 { AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL }, 1768 { AAC_HOST_HIGH_RESP_ENTRIES, 0 }, 1769 { AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY }, 1770 { AAC_ADAP_HIGH_RESP_ENTRIES, 0 } 1771 }; 1772 1773 /* 1774 * Atomically insert an entry into the nominated queue, returns 0 on success 1775 * or EBUSY if the queue is full. 1776 * 1777 * XXX Note that it would be more efficient to defer notifying the controller 1778 * in the case where we may be inserting several entries in rapid succession, 1779 * but implementing this usefully is difficult. 1780 */ 1781 int 1782 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_ccb *ccb) 1783 { 1784 u_int32_t pi, ci; 1785 int error; 1786 aac_lock_t lock; 1787 u_int32_t fib_size; 1788 u_int32_t fib_addr; 1789 1790 fib_size = ccb->ac_fib->Header.Size; 1791 fib_addr = ccb->ac_fib->Header.ReceiverFibAddress; 1792 1793 lock = AAC_LOCK(sc); 1794 1795 /* get the producer/consumer indices */ 1796 pi = sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1797 ci = sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1798 1799 /* wrap the queue? */ 1800 if (pi >= aac_qinfo[queue].size) 1801 pi = 0; 1802 1803 /* check for queue full */ 1804 if ((pi + 1) == ci) { 1805 error = EBUSY; 1806 goto out; 1807 } 1808 1809 /* populate queue entry */ 1810 (sc->sc_qentries[queue] + pi)->aq_fib_size = fib_size; 1811 (sc->sc_qentries[queue] + pi)->aq_fib_addr = fib_addr; 1812 1813 /* update producer index */ 1814 sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1; 1815 1816 /* notify the adapter if we know how */ 1817 if (aac_qinfo[queue].notify != 0) 1818 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1819 1820 error = 0; 1821 1822 out: 1823 AAC_UNLOCK(sc, lock); 1824 return (error); 1825 } 1826 1827 /* 1828 * Atomically remove one entry from the nominated queue, returns 0 on success 1829 * or ENOENT if the queue is empty. 1830 */ 1831 int 1832 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size, 1833 struct aac_fib **fib_addr) 1834 { 1835 u_int32_t pi, ci; 1836 int notify; 1837 int error; 1838 aac_lock_t lock; 1839 1840 lock = AAC_LOCK(sc); 1841 1842 /* get the producer/consumer indices */ 1843 pi = sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; 1844 ci = sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; 1845 1846 /* check for queue empty */ 1847 if (ci == pi) { 1848 error = ENOENT; 1849 goto out; 1850 } 1851 1852 notify = 0; 1853 if (ci == pi + 1) 1854 notify++; 1855 1856 /* wrap the queue? */ 1857 if (ci >= aac_qinfo[queue].size) 1858 ci = 0; 1859 1860 /* fetch the entry */ 1861 *fib_size = (sc->sc_qentries[queue] + ci)->aq_fib_size; 1862 *fib_addr = 1863 (struct aac_fib *)(sc->sc_qentries[queue] + ci)->aq_fib_addr; 1864 1865 /* update consumer index */ 1866 sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1; 1867 1868 /* if we have made the queue un-full, notify the adapter */ 1869 if (notify && (aac_qinfo[queue].notify != 0)) 1870 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1871 error = 0; 1872 1873 out: 1874 AAC_UNLOCK(sc, lock); 1875 return (error); 1876 } 1877 1878 #ifdef AAC_DEBUG 1879 /* 1880 * Print a FIB 1881 */ 1882 void 1883 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, char *caller) 1884 { 1885 printf("%s: FIB @ %p\n", caller, fib); 1886 printf(" XferState %b\n", fib->Header.XferState, "\20" 1887 "\1HOSTOWNED" 1888 "\2ADAPTEROWNED" 1889 "\3INITIALISED" 1890 "\4EMPTY" 1891 "\5FROMPOOL" 1892 "\6FROMHOST" 1893 "\7FROMADAP" 1894 "\10REXPECTED" 1895 "\11RNOTEXPECTED" 1896 "\12DONEADAP" 1897 "\13DONEHOST" 1898 "\14HIGH" 1899 "\15NORM" 1900 "\16ASYNC" 1901 "\17PAGEFILEIO" 1902 "\20SHUTDOWN" 1903 "\21LAZYWRITE" 1904 "\22ADAPMICROFIB" 1905 "\23BIOSFIB" 1906 "\24FAST_RESPONSE" 1907 "\25APIFIB\n"); 1908 printf(" Command %d\n", fib->Header.Command); 1909 printf(" StructType %d\n", fib->Header.StructType); 1910 printf(" Flags 0x%x\n", fib->Header.Flags); 1911 printf(" Size %d\n", fib->Header.Size); 1912 printf(" SenderSize %d\n", fib->Header.SenderSize); 1913 printf(" SenderAddress 0x%x\n", fib->Header.SenderFibAddress); 1914 printf(" ReceiverAddress 0x%x\n", fib->Header.ReceiverFibAddress); 1915 printf(" SenderData 0x%x\n", fib->Header.SenderData); 1916 switch(fib->Header.Command) { 1917 case ContainerCommand: { 1918 struct aac_blockread *br = (struct aac_blockread *)fib->data; 1919 struct aac_blockwrite *bw = (struct aac_blockwrite *)fib->data; 1920 struct aac_sg_table *sg = NULL; 1921 int i; 1922 1923 if (br->Command == VM_CtBlockRead) { 1924 printf(" BlockRead: container %d 0x%x/%d\n", 1925 br->ContainerId, br->BlockNumber, br->ByteCount); 1926 sg = &br->SgMap; 1927 } 1928 if (bw->Command == VM_CtBlockWrite) { 1929 printf(" BlockWrite: container %d 0x%x/%d (%s)\n", 1930 bw->ContainerId, bw->BlockNumber, bw->ByteCount, 1931 bw->Stable == CSTABLE ? "stable" : "unstable"); 1932 sg = &bw->SgMap; 1933 } 1934 if (sg != NULL) { 1935 printf(" %d s/g entries\n", sg->SgCount); 1936 for (i = 0; i < sg->SgCount; i++) 1937 printf(" 0x%08x/%d\n", 1938 sg->SgEntry[i].SgAddress, 1939 sg->SgEntry[i].SgByteCount); 1940 } 1941 break; 1942 } 1943 default: 1944 printf(" %16D\n", fib->data, " "); 1945 printf(" %16D\n", fib->data + 16, " "); 1946 break; 1947 } 1948 } 1949 #endif 1950