1 /* $NetBSD: aac.c,v 1.26 2005/12/27 17:25:41 chs Exp $ */ 2 3 /*- 4 * Copyright (c) 2002 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /*- 40 * Copyright (c) 2001 Scott Long 41 * Copyright (c) 2001 Adaptec, Inc. 42 * Copyright (c) 2000 Michael Smith 43 * Copyright (c) 2000 BSDi 44 * Copyright (c) 2000 Niklas Hallqvist 45 * All rights reserved. 46 * 47 * Redistribution and use in source and binary forms, with or without 48 * modification, are permitted provided that the following conditions 49 * are met: 50 * 1. Redistributions of source code must retain the above copyright 51 * notice, this list of conditions and the following disclaimer. 52 * 2. Redistributions in binary form must reproduce the above copyright 53 * notice, this list of conditions and the following disclaimer in the 54 * documentation and/or other materials provided with the distribution. 55 * 56 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 59 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 66 * SUCH DAMAGE. 67 */ 68 69 /* 70 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters. 71 * 72 * TODO: 73 * 74 * o Management interface. 75 * o Look again at some of the portability issues. 76 * o Handle various AIFs (e.g., notification that a container is going away). 77 */ 78 79 #include <sys/cdefs.h> 80 __KERNEL_RCSID(0, "$NetBSD: aac.c,v 1.26 2005/12/27 17:25:41 chs Exp $"); 81 82 #include <sys/param.h> 83 #include <sys/systm.h> 84 #include <sys/buf.h> 85 #include <sys/device.h> 86 #include <sys/kernel.h> 87 #include <sys/malloc.h> 88 89 #include <machine/bus.h> 90 91 #include <uvm/uvm_extern.h> 92 93 #include <dev/ic/aacreg.h> 94 #include <dev/ic/aacvar.h> 95 #include <dev/ic/aac_tables.h> 96 97 #include "locators.h" 98 99 static int aac_check_firmware(struct aac_softc *); 100 static void aac_describe_controller(struct aac_softc *); 101 static int aac_dequeue_fib(struct aac_softc *, int, u_int32_t *, 102 struct aac_fib **); 103 static int aac_enqueue_fib(struct aac_softc *, int, struct aac_fib *); 104 static void aac_host_command(struct aac_softc *); 105 static void aac_host_response(struct aac_softc *); 106 static int aac_init(struct aac_softc *); 107 static int aac_print(void *, const char *); 108 static void aac_shutdown(void *); 109 static void aac_startup(struct aac_softc *); 110 static int aac_sync_command(struct aac_softc *, u_int32_t, u_int32_t, 111 u_int32_t, u_int32_t, u_int32_t, u_int32_t *); 112 static int aac_sync_fib(struct aac_softc *, u_int32_t, u_int32_t, void *, 113 u_int16_t, void *, u_int16_t *); 114 115 #ifdef AAC_DEBUG 116 static void aac_print_fib(struct aac_softc *, struct aac_fib *, const char *); 117 #endif 118 119 /* 120 * Adapter-space FIB queue manipulation. 121 * 122 * Note that the queue implementation here is a little funky; neither the PI or 123 * CI will ever be zero. This behaviour is a controller feature. 124 */ 125 static struct { 126 int size; 127 int notify; 128 } const aac_qinfo[] = { 129 { AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL }, 130 { AAC_HOST_HIGH_CMD_ENTRIES, 0 }, 131 { AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY }, 132 { AAC_ADAP_HIGH_CMD_ENTRIES, 0 }, 133 { AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL }, 134 { AAC_HOST_HIGH_RESP_ENTRIES, 0 }, 135 { AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY }, 136 { AAC_ADAP_HIGH_RESP_ENTRIES, 0 } 137 }; 138 139 #ifdef AAC_DEBUG 140 int aac_debug = AAC_DEBUG; 141 #endif 142 143 static void *aac_sdh; 144 145 extern struct cfdriver aac_cd; 146 147 int 148 aac_attach(struct aac_softc *sc) 149 { 150 struct aac_attach_args aaca; 151 int nsegs, i, rv, state, size; 152 struct aac_ccb *ac; 153 struct aac_fib *fib; 154 bus_addr_t fibpa; 155 int locs[AACCF_NLOCS]; 156 157 SIMPLEQ_INIT(&sc->sc_ccb_free); 158 SIMPLEQ_INIT(&sc->sc_ccb_queue); 159 SIMPLEQ_INIT(&sc->sc_ccb_complete); 160 161 /* 162 * Disable interrupts before we do anything. 163 */ 164 AAC_MASK_INTERRUPTS(sc); 165 166 /* 167 * Initialise the adapter. 168 */ 169 if (aac_check_firmware(sc)) 170 return (EINVAL); 171 172 if ((rv = aac_init(sc)) != 0) 173 return (rv); 174 aac_startup(sc); 175 176 /* 177 * Print a little information about the controller. 178 */ 179 aac_describe_controller(sc); 180 181 /* 182 * Initialize the ccbs. 183 */ 184 sc->sc_ccbs = malloc(sizeof(*ac) * AAC_NCCBS, M_DEVBUF, 185 M_NOWAIT | M_ZERO); 186 if (sc->sc_ccbs == NULL) { 187 aprint_error("%s: memory allocation failure\n", 188 sc->sc_dv.dv_xname); 189 return (ENOMEM); 190 } 191 state = 0; 192 size = sizeof(*fib) * AAC_NCCBS; 193 194 if ((rv = bus_dmamap_create(sc->sc_dmat, size, 1, size, 195 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_fibs_dmamap)) != 0) { 196 aprint_error("%s: cannot create fibs dmamap\n", 197 sc->sc_dv.dv_xname); 198 goto bail_out; 199 } 200 state++; 201 if ((rv = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, 202 &sc->sc_fibs_seg, 1, &nsegs, BUS_DMA_NOWAIT)) != 0) { 203 aprint_error("%s: can't allocate fibs structure\n", 204 sc->sc_dv.dv_xname); 205 goto bail_out; 206 } 207 state++; 208 if ((rv = bus_dmamem_map(sc->sc_dmat, &sc->sc_fibs_seg, nsegs, size, 209 (caddr_t *)&sc->sc_fibs, 0)) != 0) { 210 aprint_error("%s: can't map fibs structure\n", 211 sc->sc_dv.dv_xname); 212 goto bail_out; 213 } 214 state++; 215 if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_fibs_dmamap, sc->sc_fibs, 216 size, NULL, BUS_DMA_NOWAIT)) != 0) { 217 aprint_error("%s: cannot load fibs dmamap\n", 218 sc->sc_dv.dv_xname); 219 goto bail_out; 220 } 221 state++; 222 223 memset(sc->sc_fibs, 0, size); 224 fibpa = sc->sc_fibs_seg.ds_addr; 225 fib = sc->sc_fibs; 226 227 for (i = 0, ac = sc->sc_ccbs; i < AAC_NCCBS; i++, ac++) { 228 rv = bus_dmamap_create(sc->sc_dmat, AAC_MAX_XFER, 229 AAC_MAX_SGENTRIES, AAC_MAX_XFER, 0, 230 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ac->ac_dmamap_xfer); 231 if (rv) { 232 while (--ac >= sc->sc_ccbs) 233 bus_dmamap_destroy(sc->sc_dmat, 234 ac->ac_dmamap_xfer); 235 aprint_error("%s: cannot create ccb dmamap (%d)", 236 sc->sc_dv.dv_xname, rv); 237 goto bail_out; 238 } 239 240 ac->ac_fib = fib++; 241 ac->ac_fibphys = fibpa; 242 fibpa += sizeof(*fib); 243 aac_ccb_free(sc, ac); 244 } 245 246 /* 247 * Attach devices. 248 */ 249 for (i = 0; i < AAC_MAX_CONTAINERS; i++) { 250 if (!sc->sc_hdr[i].hd_present) 251 continue; 252 aaca.aaca_unit = i; 253 254 locs[AACCF_UNIT] = i; 255 256 config_found_sm_loc(&sc->sc_dv, "aac", locs, &aaca, 257 aac_print, config_stdsubmatch); 258 } 259 260 /* 261 * Enable interrupts, and register our shutdown hook. 262 */ 263 sc->sc_flags |= AAC_ONLINE; 264 AAC_UNMASK_INTERRUPTS(sc); 265 if (aac_sdh != NULL) 266 shutdownhook_establish(aac_shutdown, NULL); 267 return (0); 268 269 bail_out: 270 bus_dmamap_unload(sc->sc_dmat, sc->sc_common_dmamap); 271 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_common, 272 sizeof(*sc->sc_common)); 273 bus_dmamem_free(sc->sc_dmat, &sc->sc_common_seg, 1); 274 bus_dmamap_destroy(sc->sc_dmat, sc->sc_common_dmamap); 275 276 if (state > 3) 277 bus_dmamap_unload(sc->sc_dmat, sc->sc_fibs_dmamap); 278 if (state > 2) 279 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_fibs, size); 280 if (state > 1) 281 bus_dmamem_free(sc->sc_dmat, &sc->sc_fibs_seg, 1); 282 if (state > 0) 283 bus_dmamap_destroy(sc->sc_dmat, sc->sc_fibs_dmamap); 284 285 free(sc->sc_ccbs, M_DEVBUF); 286 return (rv); 287 } 288 289 /* 290 * Print autoconfiguration message for a sub-device. 291 */ 292 static int 293 aac_print(void *aux, const char *pnp) 294 { 295 struct aac_attach_args *aaca; 296 297 aaca = aux; 298 299 if (pnp != NULL) 300 aprint_normal("block device at %s", pnp); 301 aprint_normal(" unit %d", aaca->aaca_unit); 302 return (UNCONF); 303 } 304 305 /* 306 * Look up a text description of a numeric error code and return a pointer to 307 * same. 308 */ 309 const char * 310 aac_describe_code(const struct aac_code_lookup *table, u_int32_t code) 311 { 312 int i; 313 314 for (i = 0; table[i].string != NULL; i++) 315 if (table[i].code == code) 316 return (table[i].string); 317 318 return (table[i + 1].string); 319 } 320 321 /* 322 * bitmask_snprintf(9) format string for the adapter options. 323 */ 324 static const char *optfmt = 325 "\20\1SNAPSHOT\2CLUSTERS\3WCACHE\4DATA64\5HOSTTIME\6RAID50" 326 "\7WINDOW4GB" 327 "\10SCSIUPGD\11SOFTERR\12NORECOND\13SGMAP64\14ALARM\15NONDASD"; 328 329 static void 330 aac_describe_controller(struct aac_softc *sc) 331 { 332 u_int8_t fmtbuf[256]; 333 u_int8_t tbuf[AAC_FIB_DATASIZE]; 334 u_int16_t bufsize; 335 struct aac_adapter_info *info; 336 u_int8_t arg; 337 338 arg = 0; 339 if (aac_sync_fib(sc, RequestAdapterInfo, 0, &arg, sizeof(arg), &tbuf, 340 &bufsize)) { 341 aprint_error("%s: RequestAdapterInfo failed\n", 342 sc->sc_dv.dv_xname); 343 return; 344 } 345 if (bufsize != sizeof(*info)) { 346 aprint_error("%s: " 347 "RequestAdapterInfo returned wrong data size (%d != %zu)\n", 348 sc->sc_dv.dv_xname, bufsize, sizeof(*info)); 349 return; 350 } 351 info = (struct aac_adapter_info *)&tbuf[0]; 352 353 aprint_normal("%s: %s at %dMHz, %dMB mem (%dMB cache), %s\n", 354 sc->sc_dv.dv_xname, 355 aac_describe_code(aac_cpu_variant, le32toh(info->CpuVariant)), 356 le32toh(info->ClockSpeed), 357 le32toh(info->TotalMem) / (1024 * 1024), 358 le32toh(info->BufferMem) / (1024 * 1024), 359 aac_describe_code(aac_battery_platform, 360 le32toh(info->batteryPlatform))); 361 362 aprint_verbose("%s: Kernel %d.%d-%d [Build %d], ", 363 sc->sc_dv.dv_xname, 364 info->KernelRevision.external.comp.major, 365 info->KernelRevision.external.comp.minor, 366 info->KernelRevision.external.comp.dash, 367 info->KernelRevision.buildNumber); 368 369 aprint_verbose("Monitor %d.%d-%d [Build %d], S/N %6X\n", 370 info->MonitorRevision.external.comp.major, 371 info->MonitorRevision.external.comp.minor, 372 info->MonitorRevision.external.comp.dash, 373 info->MonitorRevision.buildNumber, 374 ((u_int32_t)info->SerialNumber & 0xffffff)); 375 376 aprint_verbose("%s: Controller supports: %s\n", 377 sc->sc_dv.dv_xname, 378 bitmask_snprintf(sc->sc_supported_options, optfmt, fmtbuf, 379 sizeof(fmtbuf))); 380 381 /* Save the kernel revision structure for later use. */ 382 sc->sc_revision = info->KernelRevision; 383 } 384 385 /* 386 * Retrieve the firmware version numbers. Dell PERC2/QC cards with firmware 387 * version 1.x are not compatible with this driver. 388 */ 389 static int 390 aac_check_firmware(struct aac_softc *sc) 391 { 392 u_int32_t major, minor, opts; 393 394 if ((sc->sc_quirks & AAC_QUIRK_PERC2QC) != 0) { 395 if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0, 396 NULL)) { 397 aprint_error("%s: error reading firmware version\n", 398 sc->sc_dv.dv_xname); 399 return (1); 400 } 401 402 /* These numbers are stored as ASCII! */ 403 major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30; 404 minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30; 405 if (major == 1) { 406 aprint_error( 407 "%s: firmware version %d.%d not supported.\n", 408 sc->sc_dv.dv_xname, major, minor); 409 return (1); 410 } 411 } 412 413 if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, NULL)) { 414 aprint_error("%s: GETINFO failed\n", sc->sc_dv.dv_xname); 415 return (1); 416 } 417 opts = AAC_GET_MAILBOX(sc, 1); 418 sc->sc_supported_options = opts; 419 420 /* XXX -- Enable 64-bit sglists if we can */ 421 422 return (0); 423 } 424 425 static int 426 aac_init(struct aac_softc *sc) 427 { 428 int nsegs, i, rv, state, norm, high; 429 struct aac_adapter_init *ip; 430 u_int32_t code, qoff; 431 432 state = 0; 433 434 /* 435 * First wait for the adapter to come ready. 436 */ 437 for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) { 438 code = AAC_GET_FWSTATUS(sc); 439 if ((code & AAC_SELF_TEST_FAILED) != 0) { 440 aprint_error("%s: FATAL: selftest failed\n", 441 sc->sc_dv.dv_xname); 442 return (ENXIO); 443 } 444 if ((code & AAC_KERNEL_PANIC) != 0) { 445 aprint_error("%s: FATAL: controller kernel panic\n", 446 sc->sc_dv.dv_xname); 447 return (ENXIO); 448 } 449 if ((code & AAC_UP_AND_RUNNING) != 0) 450 break; 451 DELAY(1000); 452 } 453 if (i == AAC_BOOT_TIMEOUT * 1000) { 454 aprint_error( 455 "%s: FATAL: controller not coming ready, status %x\n", 456 sc->sc_dv.dv_xname, code); 457 return (ENXIO); 458 } 459 460 if ((rv = bus_dmamap_create(sc->sc_dmat, sizeof(*sc->sc_common), 1, 461 sizeof(*sc->sc_common), 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, 462 &sc->sc_common_dmamap)) != 0) { 463 aprint_error("%s: cannot create common dmamap\n", 464 sc->sc_dv.dv_xname); 465 return (rv); 466 } 467 if ((rv = bus_dmamem_alloc(sc->sc_dmat, sizeof(*sc->sc_common), 468 PAGE_SIZE, 0, &sc->sc_common_seg, 1, &nsegs, 469 BUS_DMA_NOWAIT)) != 0) { 470 aprint_error("%s: can't allocate common structure\n", 471 sc->sc_dv.dv_xname); 472 goto bail_out; 473 } 474 state++; 475 if ((rv = bus_dmamem_map(sc->sc_dmat, &sc->sc_common_seg, nsegs, 476 sizeof(*sc->sc_common), (caddr_t *)&sc->sc_common, 0)) != 0) { 477 aprint_error("%s: can't map common structure\n", 478 sc->sc_dv.dv_xname); 479 goto bail_out; 480 } 481 state++; 482 if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_common_dmamap, 483 sc->sc_common, sizeof(*sc->sc_common), NULL, 484 BUS_DMA_NOWAIT)) != 0) { 485 aprint_error("%s: cannot load common dmamap\n", 486 sc->sc_dv.dv_xname); 487 goto bail_out; 488 } 489 state++; 490 491 memset(sc->sc_common, 0, sizeof(*sc->sc_common)); 492 493 /* 494 * Fill in the init structure. This tells the adapter about the 495 * physical location of various important shared data structures. 496 */ 497 ip = &sc->sc_common->ac_init; 498 ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION); 499 500 ip->AdapterFibsPhysicalAddress = htole32(sc->sc_common_seg.ds_addr + 501 offsetof(struct aac_common, ac_fibs)); 502 ip->AdapterFibsVirtualAddress = 503 (void *)(intptr_t) htole32(&sc->sc_common->ac_fibs[0]); 504 ip->AdapterFibsSize = 505 htole32(AAC_ADAPTER_FIBS * sizeof(struct aac_fib)); 506 ip->AdapterFibAlign = htole32(sizeof(struct aac_fib)); 507 508 ip->PrintfBufferAddress = htole32(sc->sc_common_seg.ds_addr + 509 offsetof(struct aac_common, ac_printf)); 510 ip->PrintfBufferSize = htole32(AAC_PRINTF_BUFSIZE); 511 512 ip->HostPhysMemPages = 0; /* not used? */ 513 ip->HostElapsedSeconds = 0; /* reset later if invalid */ 514 515 /* 516 * Initialise FIB queues. Note that it appears that the layout of 517 * the indexes and the segmentation of the entries is mandated by 518 * the adapter, which is only told about the base of the queue index 519 * fields. 520 * 521 * The initial values of the indices are assumed to inform the 522 * adapter of the sizes of the respective queues. 523 * 524 * The Linux driver uses a much more complex scheme whereby several 525 * header records are kept for each queue. We use a couple of 526 * generic list manipulation functions which 'know' the size of each 527 * list by virtue of a table. 528 */ 529 qoff = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN; 530 qoff &= ~(AAC_QUEUE_ALIGN - 1); 531 sc->sc_queues = (struct aac_queue_table *)((uintptr_t)sc->sc_common + qoff); 532 ip->CommHeaderAddress = htole32(sc->sc_common_seg.ds_addr + 533 ((caddr_t)sc->sc_queues - (caddr_t)sc->sc_common)); 534 memset(sc->sc_queues, 0, sizeof(struct aac_queue_table)); 535 536 norm = htole32(AAC_HOST_NORM_CMD_ENTRIES); 537 high = htole32(AAC_HOST_HIGH_CMD_ENTRIES); 538 539 sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 540 norm; 541 sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 542 norm; 543 sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 544 high; 545 sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 546 high; 547 548 norm = htole32(AAC_ADAP_NORM_CMD_ENTRIES); 549 high = htole32(AAC_ADAP_HIGH_CMD_ENTRIES); 550 551 sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = 552 norm; 553 sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = 554 norm; 555 sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = 556 high; 557 sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = 558 high; 559 560 norm = htole32(AAC_HOST_NORM_RESP_ENTRIES); 561 high = htole32(AAC_HOST_HIGH_RESP_ENTRIES); 562 563 sc->sc_queues-> 564 qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm; 565 sc->sc_queues-> 566 qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm; 567 sc->sc_queues-> 568 qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high; 569 sc->sc_queues-> 570 qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high; 571 572 norm = htole32(AAC_ADAP_NORM_RESP_ENTRIES); 573 high = htole32(AAC_ADAP_HIGH_RESP_ENTRIES); 574 575 sc->sc_queues-> 576 qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm; 577 sc->sc_queues-> 578 qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm; 579 sc->sc_queues-> 580 qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high; 581 sc->sc_queues-> 582 qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high; 583 584 sc->sc_qentries[AAC_HOST_NORM_CMD_QUEUE] = 585 &sc->sc_queues->qt_HostNormCmdQueue[0]; 586 sc->sc_qentries[AAC_HOST_HIGH_CMD_QUEUE] = 587 &sc->sc_queues->qt_HostHighCmdQueue[0]; 588 sc->sc_qentries[AAC_ADAP_NORM_CMD_QUEUE] = 589 &sc->sc_queues->qt_AdapNormCmdQueue[0]; 590 sc->sc_qentries[AAC_ADAP_HIGH_CMD_QUEUE] = 591 &sc->sc_queues->qt_AdapHighCmdQueue[0]; 592 sc->sc_qentries[AAC_HOST_NORM_RESP_QUEUE] = 593 &sc->sc_queues->qt_HostNormRespQueue[0]; 594 sc->sc_qentries[AAC_HOST_HIGH_RESP_QUEUE] = 595 &sc->sc_queues->qt_HostHighRespQueue[0]; 596 sc->sc_qentries[AAC_ADAP_NORM_RESP_QUEUE] = 597 &sc->sc_queues->qt_AdapNormRespQueue[0]; 598 sc->sc_qentries[AAC_ADAP_HIGH_RESP_QUEUE] = 599 &sc->sc_queues->qt_AdapHighRespQueue[0]; 600 601 /* 602 * Do controller-type-specific initialisation 603 */ 604 switch (sc->sc_hwif) { 605 case AAC_HWIF_I960RX: 606 AAC_SETREG4(sc, AAC_RX_ODBR, ~0); 607 break; 608 } 609 610 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 0, 611 sizeof(*sc->sc_common), 612 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 613 614 /* 615 * Give the init structure to the controller. 616 */ 617 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT, 618 sc->sc_common_seg.ds_addr + offsetof(struct aac_common, ac_init), 619 0, 0, 0, NULL)) { 620 aprint_error("%s: error establishing init structure\n", 621 sc->sc_dv.dv_xname); 622 rv = EIO; 623 goto bail_out; 624 } 625 626 return (0); 627 628 bail_out: 629 if (state > 2) 630 bus_dmamap_unload(sc->sc_dmat, sc->sc_common_dmamap); 631 if (state > 1) 632 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_common, 633 sizeof(*sc->sc_common)); 634 if (state > 0) 635 bus_dmamem_free(sc->sc_dmat, &sc->sc_common_seg, 1); 636 bus_dmamap_destroy(sc->sc_dmat, sc->sc_common_dmamap); 637 638 return (rv); 639 } 640 641 /* 642 * Probe for containers, create disks. 643 */ 644 static void 645 aac_startup(struct aac_softc *sc) 646 { 647 struct aac_mntinfo mi; 648 struct aac_mntinforesponse mir; 649 struct aac_drive *hd; 650 u_int16_t rsize; 651 int i; 652 653 /* 654 * Loop over possible containers. 655 */ 656 hd = sc->sc_hdr; 657 658 for (i = 0; i < AAC_MAX_CONTAINERS; i++, hd++) { 659 /* 660 * Request information on this container. 661 */ 662 memset(&mi, 0, sizeof(mi)); 663 mi.Command = htole32(VM_NameServe); 664 mi.MntType = htole32(FT_FILESYS); 665 mi.MntCount = htole32(i); 666 if (aac_sync_fib(sc, ContainerCommand, 0, &mi, sizeof(mi), &mir, 667 &rsize)) { 668 aprint_error("%s: error probing container %d\n", 669 sc->sc_dv.dv_xname, i); 670 continue; 671 } 672 if (rsize != sizeof(mir)) { 673 aprint_error("%s: container info response wrong size " 674 "(%d should be %zu)\n", 675 sc->sc_dv.dv_xname, rsize, sizeof(mir)); 676 continue; 677 } 678 679 /* 680 * Check container volume type for validity. Note that many 681 * of the possible types may never show up. 682 */ 683 if (le32toh(mir.Status) != ST_OK || 684 le32toh(mir.MntTable[0].VolType) == CT_NONE) 685 continue; 686 687 hd->hd_present = 1; 688 hd->hd_size = le32toh(mir.MntTable[0].Capacity); 689 hd->hd_devtype = le32toh(mir.MntTable[0].VolType); 690 hd->hd_size &= ~0x1f; 691 sc->sc_nunits++; 692 } 693 } 694 695 static void 696 aac_shutdown(void *cookie) 697 { 698 struct aac_softc *sc; 699 struct aac_close_command cc; 700 u_int32_t i; 701 702 for (i = 0; i < aac_cd.cd_ndevs; i++) { 703 if ((sc = device_lookup(&aac_cd, i)) == NULL) 704 continue; 705 if ((sc->sc_flags & AAC_ONLINE) == 0) 706 continue; 707 708 AAC_MASK_INTERRUPTS(sc); 709 710 /* 711 * Send a Container shutdown followed by a HostShutdown FIB 712 * to the controller to convince it that we don't want to 713 * talk to it anymore. We've been closed and all I/O 714 * completed already 715 */ 716 memset(&cc, 0, sizeof(cc)); 717 cc.Command = htole32(VM_CloseAll); 718 cc.ContainerId = 0xffffffff; 719 if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc), 720 NULL, NULL)) { 721 printf("%s: unable to halt controller\n", 722 sc->sc_dv.dv_xname); 723 continue; 724 } 725 726 /* 727 * Note that issuing this command to the controller makes it 728 * shut down but also keeps it from coming back up without a 729 * reset of the PCI bus. 730 */ 731 if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN, 732 &i, sizeof(i), NULL, NULL)) 733 printf("%s: unable to halt controller\n", 734 sc->sc_dv.dv_xname); 735 736 sc->sc_flags &= ~AAC_ONLINE; 737 } 738 } 739 740 /* 741 * Take an interrupt. 742 */ 743 int 744 aac_intr(void *cookie) 745 { 746 struct aac_softc *sc; 747 u_int16_t reason; 748 int claimed; 749 750 sc = cookie; 751 claimed = 0; 752 753 AAC_DPRINTF(AAC_D_INTR, ("aac_intr(%p) ", sc)); 754 755 reason = AAC_GET_ISTATUS(sc); 756 AAC_DPRINTF(AAC_D_INTR, ("istatus 0x%04x ", reason)); 757 758 /* 759 * Controller wants to talk to the log. XXX Should we defer this? 760 */ 761 if ((reason & AAC_DB_PRINTF) != 0) { 762 if (sc->sc_common->ac_printf[0] != '\0') { 763 printf("%s: WARNING: adapter logged message:\n", 764 sc->sc_dv.dv_xname); 765 printf("%s: %.*s", sc->sc_dv.dv_xname, 766 AAC_PRINTF_BUFSIZE, sc->sc_common->ac_printf); 767 sc->sc_common->ac_printf[0] = '\0'; 768 } 769 AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF); 770 AAC_QNOTIFY(sc, AAC_DB_PRINTF); 771 claimed = 1; 772 } 773 774 /* 775 * Controller has a message for us? 776 */ 777 if ((reason & AAC_DB_COMMAND_READY) != 0) { 778 aac_host_command(sc); 779 AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_READY); 780 claimed = 1; 781 } 782 783 /* 784 * Controller has a response for us? 785 */ 786 if ((reason & AAC_DB_RESPONSE_READY) != 0) { 787 aac_host_response(sc); 788 AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY); 789 claimed = 1; 790 } 791 792 /* 793 * Spurious interrupts that we don't use - reset the mask and clear 794 * the interrupts. 795 */ 796 if ((reason & (AAC_DB_SYNC_COMMAND | AAC_DB_COMMAND_NOT_FULL | 797 AAC_DB_RESPONSE_NOT_FULL)) != 0) { 798 AAC_UNMASK_INTERRUPTS(sc); 799 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND | 800 AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL); 801 claimed = 1; 802 } 803 804 return (claimed); 805 } 806 807 /* 808 * Handle notification of one or more FIBs coming from the controller. 809 */ 810 static void 811 aac_host_command(struct aac_softc *sc) 812 { 813 struct aac_fib *fib; 814 u_int32_t fib_size; 815 816 for (;;) { 817 if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, &fib_size, 818 &fib)) 819 break; /* nothing to do */ 820 821 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 822 (caddr_t)fib - (caddr_t)sc->sc_common, sizeof(*fib), 823 BUS_DMASYNC_POSTREAD); 824 825 switch (le16toh(fib->Header.Command)) { 826 case AifRequest: 827 #ifdef notyet 828 aac_handle_aif(sc, 829 (struct aac_aif_command *)&fib->data[0]); 830 #endif 831 break; 832 default: 833 printf("%s: unknown command from controller\n", 834 sc->sc_dv.dv_xname); 835 AAC_PRINT_FIB(sc, fib); 836 break; 837 } 838 839 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 840 (caddr_t)fib - (caddr_t)sc->sc_common, sizeof(*fib), 841 BUS_DMASYNC_PREREAD); 842 843 /* XXX reply to FIBs requesting responses ?? */ 844 /* XXX how do we return these FIBs to the controller? */ 845 } 846 } 847 848 /* 849 * Handle notification of one or more FIBs completed by the controller 850 */ 851 static void 852 aac_host_response(struct aac_softc *sc) 853 { 854 struct aac_ccb *ac; 855 struct aac_fib *fib; 856 u_int32_t fib_size; 857 858 /* 859 * Look for completed FIBs on our queue. 860 */ 861 for (;;) { 862 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size, 863 &fib)) 864 break; /* nothing to do */ 865 866 bus_dmamap_sync(sc->sc_dmat, sc->sc_fibs_dmamap, 867 (caddr_t)fib - (caddr_t)sc->sc_fibs, sizeof(*fib), 868 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 869 870 if ((fib->Header.SenderData & 0x80000000) == 0) { 871 /* Not valid; not sent by us. */ 872 AAC_PRINT_FIB(sc, fib); 873 } else { 874 ac = (struct aac_ccb *)((caddr_t)sc->sc_ccbs + 875 (fib->Header.SenderData & 0x7fffffff)); 876 fib->Header.SenderData = 0; 877 SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_complete, ac, ac_chain); 878 } 879 } 880 881 /* 882 * Deal with any completed commands. 883 */ 884 while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_complete)) != NULL) { 885 SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_complete, ac_chain); 886 ac->ac_flags |= AAC_CCB_COMPLETED; 887 888 if (ac->ac_intr != NULL) 889 (*ac->ac_intr)(ac); 890 } 891 892 /* 893 * Try to submit more commands. 894 */ 895 if (! SIMPLEQ_EMPTY(&sc->sc_ccb_queue)) 896 aac_ccb_enqueue(sc, NULL); 897 } 898 899 /* 900 * Send a synchronous command to the controller and wait for a result. 901 */ 902 static int 903 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, 904 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp) 905 { 906 int i; 907 u_int32_t status; 908 int s; 909 910 s = splbio(); 911 912 /* Populate the mailbox. */ 913 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3); 914 915 /* Ensure the sync command doorbell flag is cleared. */ 916 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 917 918 /* ... then set it to signal the adapter. */ 919 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND); 920 DELAY(AAC_SYNC_DELAY); 921 922 /* Spin waiting for the command to complete. */ 923 for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) { 924 if (AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND) 925 break; 926 DELAY(1000); 927 } 928 if (i == AAC_IMMEDIATE_TIMEOUT * 1000) { 929 splx(s); 930 return (EIO); 931 } 932 933 /* Clear the completion flag. */ 934 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND); 935 936 /* Get the command status. */ 937 status = AAC_GET_MAILBOXSTATUS(sc); 938 splx(s); 939 if (sp != NULL) 940 *sp = status; 941 942 return (0); /* XXX Check command return status? */ 943 } 944 945 /* 946 * Send a synchronous FIB to the controller and wait for a result. 947 */ 948 static int 949 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate, 950 void *data, u_int16_t datasize, void *result, 951 u_int16_t *resultsize) 952 { 953 struct aac_fib *fib; 954 u_int32_t fibpa, status; 955 956 fib = &sc->sc_common->ac_sync_fib; 957 fibpa = sc->sc_common_seg.ds_addr + 958 offsetof(struct aac_common, ac_sync_fib); 959 960 if (datasize > AAC_FIB_DATASIZE) 961 return (EINVAL); 962 963 /* 964 * Set up the sync FIB. 965 */ 966 fib->Header.XferState = htole32(AAC_FIBSTATE_HOSTOWNED | 967 AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_EMPTY | xferstate); 968 fib->Header.Command = htole16(command); 969 fib->Header.StructType = AAC_FIBTYPE_TFIB; 970 fib->Header.Size = htole16(sizeof(*fib) + datasize); 971 fib->Header.SenderSize = htole16(sizeof(*fib)); 972 fib->Header.SenderFibAddress = 0; /* htole32((u_int32_t)fib); * XXX */ 973 fib->Header.ReceiverFibAddress = htole32(fibpa); 974 975 /* 976 * Copy in data. 977 */ 978 if (data != NULL) { 979 memcpy(fib->data, data, datasize); 980 fib->Header.XferState |= 981 htole32(AAC_FIBSTATE_FROMHOST | AAC_FIBSTATE_NORM); 982 } 983 984 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 985 (caddr_t)fib - (caddr_t)sc->sc_common, sizeof(*fib), 986 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 987 988 /* 989 * Give the FIB to the controller, wait for a response. 990 */ 991 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, fibpa, 0, 0, 0, &status)) 992 return (EIO); 993 if (status != 1) { 994 printf("%s: syncfib command %04x status %08x\n", 995 sc->sc_dv.dv_xname, command, status); 996 } 997 998 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 999 (caddr_t)fib - (caddr_t)sc->sc_common, sizeof(*fib), 1000 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1001 1002 /* 1003 * Copy out the result 1004 */ 1005 if (result != NULL) { 1006 *resultsize = le16toh(fib->Header.Size) - sizeof(fib->Header); 1007 memcpy(result, fib->data, *resultsize); 1008 } 1009 1010 return (0); 1011 } 1012 1013 struct aac_ccb * 1014 aac_ccb_alloc(struct aac_softc *sc, int flags) 1015 { 1016 struct aac_ccb *ac; 1017 int s; 1018 1019 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_alloc(%p, 0x%x) ", sc, flags)); 1020 1021 s = splbio(); 1022 ac = SIMPLEQ_FIRST(&sc->sc_ccb_free); 1023 #ifdef DIAGNOSTIC 1024 if (ac == NULL) 1025 panic("aac_ccb_get: no free CCBS"); 1026 #endif 1027 SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, ac_chain); 1028 splx(s); 1029 1030 ac->ac_flags = flags; 1031 return (ac); 1032 } 1033 1034 void 1035 aac_ccb_free(struct aac_softc *sc, struct aac_ccb *ac) 1036 { 1037 int s; 1038 1039 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_free(%p, %p) ", sc, ac)); 1040 1041 ac->ac_flags = 0; 1042 ac->ac_intr = NULL; 1043 ac->ac_fib->Header.XferState = htole32(AAC_FIBSTATE_EMPTY); 1044 ac->ac_fib->Header.StructType = AAC_FIBTYPE_TFIB; 1045 ac->ac_fib->Header.Flags = 0; 1046 ac->ac_fib->Header.SenderSize = htole16(sizeof(*ac->ac_fib)); 1047 1048 #ifdef AAC_DEBUG 1049 /* 1050 * These are duplicated in aac_ccb_submit() to cover the case where 1051 * an intermediate stage may have destroyed them. They're left 1052 * initialised here for debugging purposes only. 1053 */ 1054 ac->ac_fib->Header.SenderFibAddress = htole32((u_int32_t)(intptr_t/*XXX LP54*/)ac->ac_fib); 1055 ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys); 1056 #endif 1057 1058 s = splbio(); 1059 SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ac, ac_chain); 1060 splx(s); 1061 } 1062 1063 int 1064 aac_ccb_map(struct aac_softc *sc, struct aac_ccb *ac) 1065 { 1066 int error; 1067 1068 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_map(%p, %p) ", sc, ac)); 1069 1070 #ifdef DIAGNOSTIC 1071 if ((ac->ac_flags & AAC_CCB_MAPPED) != 0) 1072 panic("aac_ccb_map: already mapped"); 1073 #endif 1074 1075 error = bus_dmamap_load(sc->sc_dmat, ac->ac_dmamap_xfer, ac->ac_data, 1076 ac->ac_datalen, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING | 1077 ((ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMA_READ : BUS_DMA_WRITE)); 1078 if (error) { 1079 printf("%s: aac_ccb_map: ", sc->sc_dv.dv_xname); 1080 if (error == EFBIG) 1081 printf("more than %d DMA segs\n", AAC_MAX_SGENTRIES); 1082 else 1083 printf("error %d loading DMA map\n", error); 1084 return (error); 1085 } 1086 1087 bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen, 1088 (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_PREREAD : 1089 BUS_DMASYNC_PREWRITE); 1090 1091 #ifdef DIAGNOSTIC 1092 ac->ac_flags |= AAC_CCB_MAPPED; 1093 #endif 1094 return (0); 1095 } 1096 1097 void 1098 aac_ccb_unmap(struct aac_softc *sc, struct aac_ccb *ac) 1099 { 1100 1101 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_unmap(%p, %p) ", sc, ac)); 1102 1103 #ifdef DIAGNOSTIC 1104 if ((ac->ac_flags & AAC_CCB_MAPPED) == 0) 1105 panic("aac_ccb_unmap: not mapped"); 1106 #endif 1107 1108 bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen, 1109 (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_POSTREAD : 1110 BUS_DMASYNC_POSTWRITE); 1111 bus_dmamap_unload(sc->sc_dmat, ac->ac_dmamap_xfer); 1112 1113 #ifdef DIAGNOSTIC 1114 ac->ac_flags &= ~AAC_CCB_MAPPED; 1115 #endif 1116 } 1117 1118 void 1119 aac_ccb_enqueue(struct aac_softc *sc, struct aac_ccb *ac) 1120 { 1121 int s; 1122 1123 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_enqueue(%p, %p) ", sc, ac)); 1124 1125 s = splbio(); 1126 1127 if (ac != NULL) 1128 SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_queue, ac, ac_chain); 1129 1130 while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_queue)) != NULL) { 1131 if (aac_ccb_submit(sc, ac)) 1132 break; 1133 SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_queue, ac_chain); 1134 } 1135 1136 splx(s); 1137 } 1138 1139 int 1140 aac_ccb_submit(struct aac_softc *sc, struct aac_ccb *ac) 1141 { 1142 1143 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_submit(%p, %p) ", sc, ac)); 1144 1145 /* Fix up the address values. */ 1146 ac->ac_fib->Header.SenderFibAddress = htole32((u_int32_t)(intptr_t/*XXX LP64*/)ac->ac_fib); 1147 ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys); 1148 1149 /* Save a pointer to the command for speedy reverse-lookup. */ 1150 ac->ac_fib->Header.SenderData = 1151 (u_int32_t)((caddr_t)ac - (caddr_t)sc->sc_ccbs) | 0x80000000; 1152 1153 bus_dmamap_sync(sc->sc_dmat, sc->sc_fibs_dmamap, 1154 (caddr_t)ac->ac_fib - (caddr_t)sc->sc_fibs, sizeof(*ac->ac_fib), 1155 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1156 1157 /* Put the FIB on the outbound queue. */ 1158 return (aac_enqueue_fib(sc, AAC_ADAP_NORM_CMD_QUEUE, ac->ac_fib)); 1159 } 1160 1161 int 1162 aac_ccb_poll(struct aac_softc *sc, struct aac_ccb *ac, int timo) 1163 { 1164 int rv, s; 1165 1166 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_poll(%p, %p, %d) ", sc, ac, timo)); 1167 1168 s = splbio(); 1169 1170 if ((rv = aac_ccb_submit(sc, ac)) != 0) { 1171 splx(s); 1172 return (rv); 1173 } 1174 1175 for (timo *= 1000; timo != 0; timo--) { 1176 aac_intr(sc); 1177 if ((ac->ac_flags & AAC_CCB_COMPLETED) != 0) 1178 break; 1179 DELAY(100); 1180 } 1181 1182 splx(s); 1183 return (timo == 0); 1184 } 1185 1186 /* 1187 * Atomically insert an entry into the nominated queue, returns 0 on success 1188 * or EBUSY if the queue is full. 1189 * 1190 * XXX Note that it would be more efficient to defer notifying the 1191 * controller in the case where we may be inserting several entries in rapid 1192 * succession, but implementing this usefully is difficult. 1193 */ 1194 static int 1195 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_fib *fib) 1196 { 1197 u_int32_t fib_size, fib_addr, pi, ci; 1198 1199 fib_size = le16toh(fib->Header.Size); 1200 fib_addr = le32toh(fib->Header.ReceiverFibAddress); 1201 1202 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1203 (caddr_t)sc->sc_common->ac_qbuf - (caddr_t)sc->sc_common, 1204 sizeof(sc->sc_common->ac_qbuf), 1205 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1206 1207 /* Get the producer/consumer indices. */ 1208 pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]); 1209 ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]); 1210 1211 /* Wrap the queue? */ 1212 if (pi >= aac_qinfo[queue].size) 1213 pi = 0; 1214 1215 /* Check for queue full. */ 1216 if ((pi + 1) == ci) 1217 return (EAGAIN); 1218 1219 /* Populate queue entry. */ 1220 (sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size); 1221 (sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr); 1222 1223 /* Update producer index. */ 1224 sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1); 1225 1226 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1227 (caddr_t)sc->sc_common->ac_qbuf - (caddr_t)sc->sc_common, 1228 sizeof(sc->sc_common->ac_qbuf), 1229 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1230 1231 /* Notify the adapter if we know how. */ 1232 if (aac_qinfo[queue].notify != 0) 1233 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1234 1235 return (0); 1236 } 1237 1238 /* 1239 * Atomically remove one entry from the nominated queue, returns 0 on success 1240 * or ENOENT if the queue is empty. 1241 */ 1242 static int 1243 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size, 1244 struct aac_fib **fib_addr) 1245 { 1246 u_int32_t pi, ci; 1247 int notify; 1248 1249 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1250 (caddr_t)sc->sc_common->ac_qbuf - (caddr_t)sc->sc_common, 1251 sizeof(sc->sc_common->ac_qbuf), 1252 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1253 1254 /* Get the producer/consumer indices. */ 1255 pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]); 1256 ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]); 1257 1258 /* Check for queue empty. */ 1259 if (ci == pi) 1260 return (ENOENT); 1261 1262 notify = 0; 1263 if (ci == pi + 1) 1264 notify = 1; 1265 1266 /* Wrap the queue? */ 1267 if (ci >= aac_qinfo[queue].size) 1268 ci = 0; 1269 1270 /* Fetch the entry. */ 1271 *fib_size = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_size); 1272 *fib_addr = (void *)(intptr_t) le32toh( 1273 (sc->sc_qentries[queue] + ci)->aq_fib_addr); 1274 1275 /* Update consumer index. */ 1276 sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1; 1277 1278 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 1279 (caddr_t)sc->sc_common->ac_qbuf - (caddr_t)sc->sc_common, 1280 sizeof(sc->sc_common->ac_qbuf), 1281 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1282 1283 /* If we have made the queue un-full, notify the adapter. */ 1284 if (notify && (aac_qinfo[queue].notify != 0)) 1285 AAC_QNOTIFY(sc, aac_qinfo[queue].notify); 1286 1287 return (0); 1288 } 1289 1290 #ifdef AAC_DEBUG 1291 /* 1292 * Print a FIB 1293 */ 1294 static void 1295 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller) 1296 { 1297 struct aac_blockread *br; 1298 struct aac_blockwrite *bw; 1299 struct aac_sg_table *sg; 1300 char tbuf[512]; 1301 int i; 1302 1303 printf("%s: FIB @ %p\n", caller, fib); 1304 bitmask_snprintf(le32toh(fib->Header.XferState), 1305 "\20" 1306 "\1HOSTOWNED" 1307 "\2ADAPTEROWNED" 1308 "\3INITIALISED" 1309 "\4EMPTY" 1310 "\5FROMPOOL" 1311 "\6FROMHOST" 1312 "\7FROMADAP" 1313 "\10REXPECTED" 1314 "\11RNOTEXPECTED" 1315 "\12DONEADAP" 1316 "\13DONEHOST" 1317 "\14HIGH" 1318 "\15NORM" 1319 "\16ASYNC" 1320 "\17PAGEFILEIO" 1321 "\20SHUTDOWN" 1322 "\21LAZYWRITE" 1323 "\22ADAPMICROFIB" 1324 "\23BIOSFIB" 1325 "\24FAST_RESPONSE" 1326 "\25APIFIB\n", 1327 tbuf, 1328 sizeof(tbuf)); 1329 1330 printf(" XferState %s\n", tbuf); 1331 printf(" Command %d\n", le16toh(fib->Header.Command)); 1332 printf(" StructType %d\n", fib->Header.StructType); 1333 printf(" Flags 0x%x\n", fib->Header.Flags); 1334 printf(" Size %d\n", le16toh(fib->Header.Size)); 1335 printf(" SenderSize %d\n", le16toh(fib->Header.SenderSize)); 1336 printf(" SenderAddress 0x%x\n", 1337 le32toh(fib->Header.SenderFibAddress)); 1338 printf(" ReceiverAddress 0x%x\n", 1339 le32toh(fib->Header.ReceiverFibAddress)); 1340 printf(" SenderData 0x%x\n", fib->Header.SenderData); 1341 1342 switch (fib->Header.Command) { 1343 case ContainerCommand: { 1344 br = (struct aac_blockread *)fib->data; 1345 bw = (struct aac_blockwrite *)fib->data; 1346 sg = NULL; 1347 1348 if (le32toh(br->Command) == VM_CtBlockRead) { 1349 printf(" BlockRead: container %d 0x%x/%d\n", 1350 le32toh(br->ContainerId), le32toh(br->BlockNumber), 1351 le32toh(br->ByteCount)); 1352 sg = &br->SgMap; 1353 } 1354 if (le32toh(bw->Command) == VM_CtBlockWrite) { 1355 printf(" BlockWrite: container %d 0x%x/%d (%s)\n", 1356 le32toh(bw->ContainerId), le32toh(bw->BlockNumber), 1357 le32toh(bw->ByteCount), 1358 le32toh(bw->Stable) == CSTABLE ? 1359 "stable" : "unstable"); 1360 sg = &bw->SgMap; 1361 } 1362 if (sg != NULL) { 1363 printf(" %d s/g entries\n", le32toh(sg->SgCount)); 1364 for (i = 0; i < le32toh(sg->SgCount); i++) 1365 printf(" 0x%08x/%d\n", 1366 le32toh(sg->SgEntry[i].SgAddress), 1367 le32toh(sg->SgEntry[i].SgByteCount)); 1368 } 1369 break; 1370 } 1371 default: 1372 // dump first 32 bytes of fib->data 1373 printf(" Raw data:"); 1374 for (i = 0; i < 32; i++) 1375 printf(" %02x", fib->data[i]); 1376 printf("\n"); 1377 break; 1378 } 1379 } 1380 #endif /* AAC_DEBUG */ 1381