1 /* $NetBSD: amr.c,v 1.6 2002/10/02 16:51:02 thorpej 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) 1999,2000 Michael Smith 41 * Copyright (c) 2000 BSDi 42 * All rights reserved. 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * SUCH DAMAGE. 64 * 65 * from FreeBSD: amr_pci.c,v 1.5 2000/08/30 07:52:40 msmith Exp 66 * from FreeBSD: amr.c,v 1.16 2000/08/30 07:52:40 msmith Exp 67 */ 68 69 /* 70 * Driver for AMI RAID controllers. 71 */ 72 73 #include <sys/cdefs.h> 74 __KERNEL_RCSID(0, "$NetBSD: amr.c,v 1.6 2002/10/02 16:51:02 thorpej Exp $"); 75 76 #include <sys/param.h> 77 #include <sys/systm.h> 78 #include <sys/kernel.h> 79 #include <sys/device.h> 80 #include <sys/queue.h> 81 #include <sys/proc.h> 82 #include <sys/buf.h> 83 #include <sys/malloc.h> 84 85 #include <uvm/uvm_extern.h> 86 87 #include <machine/endian.h> 88 #include <machine/bus.h> 89 90 #include <dev/pci/pcidevs.h> 91 #include <dev/pci/pcivar.h> 92 #include <dev/pci/amrreg.h> 93 #include <dev/pci/amrvar.h> 94 95 #if AMR_MAX_SEGS > 32 96 #error AMR_MAX_SEGS too high 97 #endif 98 99 #define AMR_ENQUIRY_BUFSIZE 2048 100 #define AMR_SGL_SIZE (sizeof(struct amr_sgentry) * 32) 101 102 void amr_attach(struct device *, struct device *, void *); 103 void *amr_enquire(struct amr_softc *, u_int8_t, u_int8_t, u_int8_t); 104 int amr_init(struct amr_softc *, const char *, 105 struct pci_attach_args *pa); 106 int amr_intr(void *); 107 int amr_match(struct device *, struct cfdata *, void *); 108 int amr_print(void *, const char *); 109 void amr_shutdown(void *); 110 int amr_submatch(struct device *, struct cfdata *, void *); 111 112 int amr_mbox_wait(struct amr_softc *); 113 int amr_quartz_get_work(struct amr_softc *, struct amr_mailbox *); 114 int amr_quartz_submit(struct amr_softc *, struct amr_ccb *); 115 int amr_std_get_work(struct amr_softc *, struct amr_mailbox *); 116 int amr_std_submit(struct amr_softc *, struct amr_ccb *); 117 118 static inline u_int8_t amr_inb(struct amr_softc *, int); 119 static inline u_int32_t amr_inl(struct amr_softc *, int); 120 static inline void amr_outb(struct amr_softc *, int, u_int8_t); 121 static inline void amr_outl(struct amr_softc *, int, u_int32_t); 122 123 CFATTACH_DECL(amr, sizeof(struct amr_softc), 124 amr_match, amr_attach, NULL, NULL); 125 126 #define AT_QUARTZ 0x01 /* `Quartz' chipset */ 127 #define AT_SIG 0x02 /* Check for signature */ 128 129 struct amr_pci_type { 130 u_short apt_vendor; 131 u_short apt_product; 132 u_short apt_flags; 133 } static const amr_pci_type[] = { 134 { PCI_VENDOR_AMI, PCI_PRODUCT_AMI_MEGARAID, 0 }, 135 { PCI_VENDOR_AMI, PCI_PRODUCT_AMI_MEGARAID2, 0 }, 136 { PCI_VENDOR_AMI, PCI_PRODUCT_AMI_MEGARAID3, AT_QUARTZ }, 137 { PCI_VENDOR_INTEL, PCI_PRODUCT_AMI_MEGARAID3, AT_QUARTZ | AT_SIG } 138 }; 139 140 struct amr_typestr { 141 const char *at_str; 142 int at_sig; 143 } static const amr_typestr[] = { 144 { "Series 431", AMR_SIG_431 }, 145 { "Series 438", AMR_SIG_438 }, 146 { "Series 466", AMR_SIG_466 }, 147 { "Series 467", AMR_SIG_467 }, 148 { "Series 490", AMR_SIG_490 }, 149 { "Series 762", AMR_SIG_762 }, 150 { "HP NetRAID (T5)", AMR_SIG_T5 }, 151 { "HP NetRAID (T7)", AMR_SIG_T7 }, 152 }; 153 154 static void *amr_sdh; 155 156 static inline u_int8_t 157 amr_inb(struct amr_softc *amr, int off) 158 { 159 160 bus_space_barrier(amr->amr_iot, amr->amr_ioh, off, 1, 161 BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ); 162 return (bus_space_read_1(amr->amr_iot, amr->amr_ioh, off)); 163 } 164 165 static inline u_int32_t 166 amr_inl(struct amr_softc *amr, int off) 167 { 168 169 bus_space_barrier(amr->amr_iot, amr->amr_ioh, off, 4, 170 BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ); 171 return (bus_space_read_4(amr->amr_iot, amr->amr_ioh, off)); 172 } 173 174 static inline void 175 amr_outb(struct amr_softc *amr, int off, u_int8_t val) 176 { 177 178 bus_space_write_1(amr->amr_iot, amr->amr_ioh, off, val); 179 bus_space_barrier(amr->amr_iot, amr->amr_ioh, off, 1, 180 BUS_SPACE_BARRIER_WRITE); 181 } 182 183 static inline void 184 amr_outl(struct amr_softc *amr, int off, u_int32_t val) 185 { 186 187 bus_space_write_4(amr->amr_iot, amr->amr_ioh, off, val); 188 bus_space_barrier(amr->amr_iot, amr->amr_ioh, off, 4, 189 BUS_SPACE_BARRIER_WRITE); 190 } 191 192 /* 193 * Match a supported device. 194 */ 195 int 196 amr_match(struct device *parent, struct cfdata *match, void *aux) 197 { 198 struct pci_attach_args *pa; 199 pcireg_t s; 200 int i; 201 202 pa = (struct pci_attach_args *)aux; 203 204 /* 205 * Don't match the device if it's operating in I2O mode. In this 206 * case it should be handled by the `iop' driver. 207 */ 208 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_I2O) 209 return (0); 210 211 for (i = 0; i < sizeof(amr_pci_type) / sizeof(amr_pci_type[0]); i++) 212 if (PCI_VENDOR(pa->pa_id) == amr_pci_type[i].apt_vendor && 213 PCI_PRODUCT(pa->pa_id) == amr_pci_type[i].apt_product) 214 break; 215 216 if (i == sizeof(amr_pci_type) / sizeof(amr_pci_type[0])) 217 return (0); 218 219 if ((amr_pci_type[i].apt_flags & AT_SIG) == 0) 220 return (1); 221 222 s = pci_conf_read(pa->pa_pc, pa->pa_tag, AMR_QUARTZ_SIG_REG) & 0xffff; 223 return (s == AMR_QUARTZ_SIG0 || s == AMR_QUARTZ_SIG1); 224 } 225 226 /* 227 * Attach a supported device. XXX This doesn't fail gracefully, and may 228 * over-allocate resources. 229 */ 230 void 231 amr_attach(struct device *parent, struct device *self, void *aux) 232 { 233 bus_space_tag_t memt, iot; 234 bus_space_handle_t memh, ioh; 235 struct pci_attach_args *pa; 236 struct amr_attach_args amra; 237 const struct amr_pci_type *apt; 238 struct amr_softc *amr; 239 pci_chipset_tag_t pc; 240 pci_intr_handle_t ih; 241 const char *intrstr; 242 pcireg_t reg; 243 int rseg, i, size, rv, memreg, ioreg; 244 bus_dma_segment_t seg; 245 struct amr_ccb *ac; 246 247 amr = (struct amr_softc *)self; 248 pa = (struct pci_attach_args *)aux; 249 pc = pa->pa_pc; 250 251 for (i = 0; i < sizeof(amr_pci_type) / sizeof(amr_pci_type[0]); i++) 252 if (PCI_VENDOR(pa->pa_id) == amr_pci_type[i].apt_vendor && 253 PCI_PRODUCT(pa->pa_id) == amr_pci_type[i].apt_product) 254 break; 255 apt = amr_pci_type + i; 256 257 memreg = ioreg = 0; 258 for (i = 0x10; i <= 0x14; i += 4) { 259 reg = pci_conf_read(pc, pa->pa_tag, i); 260 switch (PCI_MAPREG_TYPE(reg)) { 261 case PCI_MAPREG_TYPE_MEM: 262 if (PCI_MAPREG_MEM_SIZE(reg) != 0) 263 memreg = i; 264 break; 265 case PCI_MAPREG_TYPE_IO: 266 if (PCI_MAPREG_IO_SIZE(reg) != 0) 267 ioreg = i; 268 break; 269 } 270 } 271 272 if (memreg != 0) 273 if (pci_mapreg_map(pa, memreg, PCI_MAPREG_TYPE_MEM, 0, 274 &memt, &memh, NULL, NULL)) 275 memreg = 0; 276 if (ioreg != 0) 277 if (pci_mapreg_map(pa, ioreg, PCI_MAPREG_TYPE_IO, 0, 278 &iot, &ioh, NULL, NULL)) 279 ioreg = 0; 280 281 if (memreg) { 282 amr->amr_iot = memt; 283 amr->amr_ioh = memh; 284 } else if (ioreg) { 285 amr->amr_iot = iot; 286 amr->amr_ioh = ioh; 287 } else { 288 printf("can't map control registers\n"); 289 return; 290 } 291 292 amr->amr_dmat = pa->pa_dmat; 293 294 /* Enable the device. */ 295 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 296 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 297 reg | PCI_COMMAND_MASTER_ENABLE); 298 299 /* Map and establish the interrupt. */ 300 if (pci_intr_map(pa, &ih)) { 301 printf("can't map interrupt\n"); 302 return; 303 } 304 intrstr = pci_intr_string(pc, ih); 305 amr->amr_ih = pci_intr_establish(pc, ih, IPL_BIO, amr_intr, amr); 306 if (amr->amr_ih == NULL) { 307 printf("can't establish interrupt"); 308 if (intrstr != NULL) 309 printf(" at %s", intrstr); 310 printf("\n"); 311 return; 312 } 313 314 /* 315 * Allocate space for the mailbox and S/G lists. Some controllers 316 * don't like S/G lists to be located below 0x2000, so we allocate 317 * enough slop to enable us to compensate. 318 * 319 * The standard mailbox structure needs to be aligned on a 16-byte 320 * boundary. The 64-bit mailbox has one extra field, 4 bytes in 321 * size, which preceeds the standard mailbox. 322 */ 323 size = AMR_SGL_SIZE * AMR_MAX_CMDS + 0x2000; 324 325 if ((rv = bus_dmamem_alloc(amr->amr_dmat, size, PAGE_SIZE, NULL, &seg, 326 1, &rseg, BUS_DMA_NOWAIT)) != 0) { 327 printf("%s: unable to allocate buffer, rv = %d\n", 328 amr->amr_dv.dv_xname, rv); 329 return; 330 } 331 332 if ((rv = bus_dmamem_map(amr->amr_dmat, &seg, rseg, size, 333 (caddr_t *)&amr->amr_mbox, 334 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 335 printf("%s: unable to map buffer, rv = %d\n", 336 amr->amr_dv.dv_xname, rv); 337 return; 338 } 339 340 if ((rv = bus_dmamap_create(amr->amr_dmat, size, 1, size, 0, 341 BUS_DMA_NOWAIT, &amr->amr_dmamap)) != 0) { 342 printf("%s: unable to create buffer DMA map, rv = %d\n", 343 amr->amr_dv.dv_xname, rv); 344 return; 345 } 346 347 if ((rv = bus_dmamap_load(amr->amr_dmat, amr->amr_dmamap, 348 amr->amr_mbox, size, NULL, BUS_DMA_NOWAIT)) != 0) { 349 printf("%s: unable to load buffer DMA map, rv = %d\n", 350 amr->amr_dv.dv_xname, rv); 351 return; 352 } 353 354 memset(amr->amr_mbox, 0, size); 355 356 amr->amr_mbox_paddr = amr->amr_dmamap->dm_segs[0].ds_addr + 16; 357 amr->amr_sgls_paddr = (amr->amr_mbox_paddr + 0x1fff) & ~0x1fff; 358 amr->amr_sgls = (struct amr_sgentry *)((caddr_t)amr->amr_mbox + 359 amr->amr_sgls_paddr - amr->amr_dmamap->dm_segs[0].ds_addr); 360 amr->amr_mbox = (struct amr_mailbox *)((caddr_t)amr->amr_mbox + 16); 361 362 /* 363 * Allocate and initalise the command control blocks. 364 */ 365 ac = malloc(sizeof(*ac) * AMR_MAX_CMDS, M_DEVBUF, M_NOWAIT | M_ZERO); 366 amr->amr_ccbs = ac; 367 SLIST_INIT(&amr->amr_ccb_freelist); 368 369 for (i = 0; i < AMR_MAX_CMDS; i++, ac++) { 370 rv = bus_dmamap_create(amr->amr_dmat, AMR_MAX_XFER, 371 AMR_MAX_SEGS, AMR_MAX_XFER, 0, 372 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, 373 &ac->ac_xfer_map); 374 if (rv != 0) 375 break; 376 377 ac->ac_ident = i; 378 SLIST_INSERT_HEAD(&amr->amr_ccb_freelist, ac, ac_chain.slist); 379 } 380 if (i != AMR_MAX_CMDS) 381 printf("%s: %d/%d CCBs created\n", amr->amr_dv.dv_xname, 382 i, AMR_MAX_CMDS); 383 384 /* 385 * Take care of model-specific tasks. 386 */ 387 if ((apt->apt_flags & AT_QUARTZ) != 0) { 388 amr->amr_submit = amr_quartz_submit; 389 amr->amr_get_work = amr_quartz_get_work; 390 } else { 391 amr->amr_submit = amr_std_submit; 392 amr->amr_get_work = amr_std_get_work; 393 394 /* Notify the controller of the mailbox location. */ 395 amr_outl(amr, AMR_SREG_MBOX, amr->amr_mbox_paddr); 396 amr_outb(amr, AMR_SREG_MBOX_ENABLE, AMR_SMBOX_ENABLE_ADDR); 397 398 /* Clear outstanding interrupts and enable interrupts. */ 399 amr_outb(amr, AMR_SREG_CMD, AMR_SCMD_ACKINTR); 400 amr_outb(amr, AMR_SREG_TOGL, 401 amr_inb(amr, AMR_SREG_TOGL) | AMR_STOGL_ENABLE); 402 } 403 404 /* 405 * Retrieve parameters, and tell the world about us. 406 */ 407 amr->amr_maxqueuecnt = i; 408 printf(": AMI RAID "); 409 if (amr_init(amr, intrstr, pa) != 0) 410 return; 411 412 /* 413 * Cap the maximum number of outstanding commands. AMI's Linux 414 * driver doesn't trust the controller's reported value, and lockups 415 * have been seen when we do. 416 */ 417 amr->amr_maxqueuecnt = min(amr->amr_maxqueuecnt, AMR_MAX_CMDS); 418 if (amr->amr_maxqueuecnt > i) 419 amr->amr_maxqueuecnt = i; 420 421 /* Set our `shutdownhook' before we start any device activity. */ 422 if (amr_sdh == NULL) 423 amr_sdh = shutdownhook_establish(amr_shutdown, NULL); 424 425 /* Attach sub-devices. */ 426 for (i = 0; i < amr->amr_numdrives; i++) { 427 if (amr->amr_drive[i].al_size == 0) 428 continue; 429 amra.amra_unit = i; 430 config_found_sm(&amr->amr_dv, &amra, amr_print, amr_submatch); 431 } 432 433 SIMPLEQ_INIT(&amr->amr_ccb_queue); 434 } 435 436 /* 437 * Print autoconfiguration message for a sub-device. 438 */ 439 int 440 amr_print(void *aux, const char *pnp) 441 { 442 struct amr_attach_args *amra; 443 444 amra = (struct amr_attach_args *)aux; 445 446 if (pnp != NULL) 447 printf("block device at %s", pnp); 448 printf(" unit %d", amra->amra_unit); 449 return (UNCONF); 450 } 451 452 /* 453 * Match a sub-device. 454 */ 455 int 456 amr_submatch(struct device *parent, struct cfdata *cf, void *aux) 457 { 458 struct amr_attach_args *amra; 459 460 amra = (struct amr_attach_args *)aux; 461 462 if (cf->amracf_unit != AMRCF_UNIT_DEFAULT && 463 cf->amracf_unit != amra->amra_unit) 464 return (0); 465 466 return (config_match(parent, cf, aux)); 467 } 468 469 /* 470 * Retrieve operational parameters and describe the controller. 471 */ 472 int 473 amr_init(struct amr_softc *amr, const char *intrstr, 474 struct pci_attach_args *pa) 475 { 476 struct amr_prodinfo *ap; 477 struct amr_enquiry *ae; 478 struct amr_enquiry3 *aex; 479 const char *prodstr; 480 u_int i, sig; 481 char buf[64]; 482 483 /* 484 * Try to get 40LD product info, which tells us what the card is 485 * labelled as. 486 */ 487 ap = amr_enquire(amr, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0); 488 if (ap != NULL) { 489 printf("<%.80s>\n", ap->ap_product); 490 if (intrstr != NULL) 491 printf("%s: interrupting at %s\n", 492 amr->amr_dv.dv_xname, intrstr); 493 printf("%s: firmware %.16s, BIOS %.16s, %dMB RAM\n", 494 amr->amr_dv.dv_xname, ap->ap_firmware, ap->ap_bios, 495 le16toh(ap->ap_memsize)); 496 497 amr->amr_maxqueuecnt = ap->ap_maxio; 498 free(ap, M_DEVBUF); 499 500 /* 501 * Fetch and record state of logical drives. 502 */ 503 aex = amr_enquire(amr, AMR_CMD_CONFIG, AMR_CONFIG_ENQ3, 504 AMR_CONFIG_ENQ3_SOLICITED_FULL); 505 if (aex == NULL) { 506 printf("%s ENQUIRY3 failed\n", amr->amr_dv.dv_xname); 507 return (-1); 508 } 509 510 if (aex->ae_numldrives > AMR_MAX_UNITS) { 511 printf("%s: adjust AMR_MAX_UNITS to %d (currently %d)" 512 "\n", amr->amr_dv.dv_xname, 513 ae->ae_ldrv.al_numdrives, AMR_MAX_UNITS); 514 amr->amr_numdrives = AMR_MAX_UNITS; 515 } else 516 amr->amr_numdrives = aex->ae_numldrives; 517 518 for (i = 0; i < amr->amr_numdrives; i++) { 519 amr->amr_drive[i].al_size = 520 le32toh(aex->ae_drivesize[i]); 521 amr->amr_drive[i].al_state = aex->ae_drivestate[i]; 522 amr->amr_drive[i].al_properties = aex->ae_driveprop[i]; 523 } 524 525 free(aex, M_DEVBUF); 526 return (0); 527 } 528 529 /* 530 * Try 8LD extended ENQUIRY to get the controller signature. Once 531 * found, search for a product description. 532 */ 533 if ((ae = amr_enquire(amr, AMR_CMD_EXT_ENQUIRY2, 0, 0)) != NULL) { 534 i = 0; 535 sig = le32toh(ae->ae_signature); 536 537 while (i < sizeof(amr_typestr) / sizeof(amr_typestr[0])) { 538 if (amr_typestr[i].at_sig == sig) 539 break; 540 i++; 541 } 542 if (i == sizeof(amr_typestr) / sizeof(amr_typestr[0])) { 543 sprintf(buf, "unknown ENQUIRY2 sig (0x%08x)", sig); 544 prodstr = buf; 545 } else 546 prodstr = amr_typestr[i].at_str; 547 } else { 548 if ((ae = amr_enquire(amr, AMR_CMD_ENQUIRY, 0, 0)) == NULL) { 549 printf("%s: unsupported controller\n", 550 amr->amr_dv.dv_xname); 551 return (-1); 552 } 553 554 switch (PCI_PRODUCT(pa->pa_id)) { 555 case PCI_PRODUCT_AMI_MEGARAID: 556 prodstr = "Series 428"; 557 break; 558 case PCI_PRODUCT_AMI_MEGARAID2: 559 prodstr = "Series 434"; 560 break; 561 default: 562 sprintf(buf, "unknown PCI dev (0x%04x)", 563 PCI_PRODUCT(pa->pa_id)); 564 prodstr = buf; 565 break; 566 } 567 } 568 569 printf("<%s>\n", prodstr); 570 if (intrstr != NULL) 571 printf("%s: interrupting at %s\n", amr->amr_dv.dv_xname, 572 intrstr); 573 printf("%s: firmware <%.4s>, BIOS <%.4s>, %dMB RAM\n", 574 amr->amr_dv.dv_xname, ae->ae_adapter.aa_firmware, 575 ae->ae_adapter.aa_bios, ae->ae_adapter.aa_memorysize); 576 577 amr->amr_maxqueuecnt = ae->ae_adapter.aa_maxio; 578 579 /* 580 * Record state of logical drives. 581 */ 582 if (ae->ae_ldrv.al_numdrives > AMR_MAX_UNITS) { 583 printf("%s: adjust AMR_MAX_UNITS to %d (currently %d)\n", 584 amr->amr_dv.dv_xname, ae->ae_ldrv.al_numdrives, 585 AMR_MAX_UNITS); 586 amr->amr_numdrives = AMR_MAX_UNITS; 587 } else 588 amr->amr_numdrives = ae->ae_ldrv.al_numdrives; 589 590 for (i = 0; i < AMR_MAX_UNITS; i++) { 591 amr->amr_drive[i].al_size = le32toh(ae->ae_ldrv.al_size[i]); 592 amr->amr_drive[i].al_state = ae->ae_ldrv.al_state[i]; 593 amr->amr_drive[i].al_properties = ae->ae_ldrv.al_properties[i]; 594 } 595 596 free(ae, M_DEVBUF); 597 return (0); 598 } 599 600 /* 601 * Flush the internal cache on each configured controller. Called at 602 * shutdown time. 603 */ 604 void 605 amr_shutdown(void *cookie) 606 { 607 extern struct cfdriver amr_cd; 608 struct amr_softc *amr; 609 struct amr_ccb *ac; 610 int i, rv; 611 612 for (i = 0; i < amr_cd.cd_ndevs; i++) { 613 if ((amr = device_lookup(&amr_cd, i)) == NULL) 614 continue; 615 616 if ((rv = amr_ccb_alloc(amr, &ac)) == 0) { 617 ac->ac_mbox.mb_command = AMR_CMD_FLUSH; 618 rv = amr_ccb_poll(amr, ac, 30000); 619 amr_ccb_free(amr, ac); 620 } 621 if (rv != 0) 622 printf("%s: unable to flush cache (%d)\n", 623 amr->amr_dv.dv_xname, rv); 624 } 625 } 626 627 /* 628 * Interrupt service routine. 629 */ 630 int 631 amr_intr(void *cookie) 632 { 633 struct amr_softc *amr; 634 struct amr_ccb *ac; 635 struct amr_mailbox mbox; 636 u_int i, forus, idx; 637 638 amr = cookie; 639 forus = 0; 640 641 while ((*amr->amr_get_work)(amr, &mbox) == 0) { 642 /* Iterate over completed commands in this result. */ 643 for (i = 0; i < mbox.mb_nstatus; i++) { 644 idx = mbox.mb_completed[i] - 1; 645 ac = amr->amr_ccbs + idx; 646 647 if (idx >= amr->amr_maxqueuecnt) { 648 printf("%s: bad status (bogus ID: %u=%u)\n", 649 amr->amr_dv.dv_xname, i, idx); 650 continue; 651 } 652 653 if ((ac->ac_flags & AC_ACTIVE) == 0) { 654 printf("%s: bad status (not active; 0x04%x)\n", 655 amr->amr_dv.dv_xname, ac->ac_flags); 656 continue; 657 } 658 659 ac->ac_status = mbox.mb_status; 660 ac->ac_flags = (ac->ac_flags & ~AC_ACTIVE) | 661 AC_COMPLETE; 662 663 /* Pass notification to upper layers. */ 664 if (ac->ac_handler != NULL) 665 (*ac->ac_handler)(ac); 666 } 667 forus = 1; 668 } 669 670 if (forus) 671 amr_ccb_enqueue(amr, NULL); 672 return (forus); 673 } 674 675 /* 676 * Run a generic enquiry-style command. 677 */ 678 void * 679 amr_enquire(struct amr_softc *amr, u_int8_t cmd, u_int8_t cmdsub, 680 u_int8_t cmdqual) 681 { 682 struct amr_ccb *ac; 683 u_int8_t *mb; 684 void *buf; 685 int rv; 686 687 if (amr_ccb_alloc(amr, &ac) != 0) 688 return (NULL); 689 buf = malloc(AMR_ENQUIRY_BUFSIZE, M_DEVBUF, M_NOWAIT); 690 691 /* Build the command proper. */ 692 mb = (u_int8_t *)&ac->ac_mbox; 693 mb[0] = cmd; 694 mb[2] = cmdsub; 695 mb[3] = cmdqual; 696 697 if ((rv = amr_ccb_map(amr, ac, buf, AMR_ENQUIRY_BUFSIZE, 0)) == 0) { 698 rv = amr_ccb_poll(amr, ac, 2000); 699 amr_ccb_unmap(amr, ac); 700 } 701 702 amr_ccb_free(amr, ac); 703 704 if (rv != 0) { 705 free(buf, M_DEVBUF); 706 buf = NULL; 707 } 708 709 return (buf); 710 } 711 712 /* 713 * Allocate and initialise a CCB. 714 */ 715 int 716 amr_ccb_alloc(struct amr_softc *amr, struct amr_ccb **acp) 717 { 718 struct amr_ccb *ac; 719 struct amr_mailbox *mb; 720 int s; 721 722 s = splbio(); 723 if ((ac = SLIST_FIRST(&amr->amr_ccb_freelist)) == NULL) { 724 splx(s); 725 return (EAGAIN); 726 } 727 SLIST_REMOVE_HEAD(&amr->amr_ccb_freelist, ac_chain.slist); 728 splx(s); 729 730 ac->ac_handler = NULL; 731 mb = &ac->ac_mbox; 732 *acp = ac; 733 734 memset(mb, 0, sizeof(*mb)); 735 736 mb->mb_ident = ac->ac_ident + 1; 737 mb->mb_busy = 1; 738 mb->mb_poll = 0; 739 mb->mb_ack = 0; 740 741 return (0); 742 } 743 744 /* 745 * Free a CCB. 746 */ 747 void 748 amr_ccb_free(struct amr_softc *amr, struct amr_ccb *ac) 749 { 750 int s; 751 752 ac->ac_flags = 0; 753 754 s = splbio(); 755 SLIST_INSERT_HEAD(&amr->amr_ccb_freelist, ac, ac_chain.slist); 756 splx(s); 757 } 758 759 /* 760 * If a CCB is specified, enqueue it. Pull CCBs off the software queue in 761 * the order that they were enqueued and try to submit their command blocks 762 * to the controller for execution. 763 */ 764 void 765 amr_ccb_enqueue(struct amr_softc *amr, struct amr_ccb *ac) 766 { 767 int s; 768 769 s = splbio(); 770 771 if (ac != NULL) 772 SIMPLEQ_INSERT_TAIL(&amr->amr_ccb_queue, ac, ac_chain.simpleq); 773 774 while ((ac = SIMPLEQ_FIRST(&amr->amr_ccb_queue)) != NULL) { 775 if ((*amr->amr_submit)(amr, ac) != 0) 776 break; 777 SIMPLEQ_REMOVE_HEAD(&amr->amr_ccb_queue, ac_chain.simpleq); 778 } 779 780 splx(s); 781 } 782 783 /* 784 * Map the specified CCB's data buffer onto the bus, and fill the 785 * scatter-gather list. 786 */ 787 int 788 amr_ccb_map(struct amr_softc *amr, struct amr_ccb *ac, void *data, int size, 789 int out) 790 { 791 struct amr_sgentry *sge; 792 struct amr_mailbox *mb; 793 int nsegs, i, rv, sgloff; 794 bus_dmamap_t xfer; 795 796 xfer = ac->ac_xfer_map; 797 798 rv = bus_dmamap_load(amr->amr_dmat, xfer, data, size, NULL, 799 BUS_DMA_NOWAIT); 800 if (rv != 0) 801 return (rv); 802 803 mb = &ac->ac_mbox; 804 ac->ac_xfer_size = size; 805 ac->ac_flags |= (out ? AC_XFER_OUT : AC_XFER_IN); 806 sgloff = AMR_SGL_SIZE * ac->ac_ident; 807 808 /* We don't need to use a scatter/gather list for just 1 segment. */ 809 nsegs = xfer->dm_nsegs; 810 if (nsegs == 1) { 811 mb->mb_nsgelem = 0; 812 mb->mb_physaddr = htole32(xfer->dm_segs[0].ds_addr); 813 ac->ac_flags |= AC_NOSGL; 814 } else { 815 mb->mb_nsgelem = nsegs; 816 mb->mb_physaddr = htole32(amr->amr_sgls_paddr + sgloff); 817 818 sge = (struct amr_sgentry *)((caddr_t)amr->amr_sgls + sgloff); 819 for (i = 0; i < nsegs; i++, sge++) { 820 sge->sge_addr = htole32(xfer->dm_segs[i].ds_addr); 821 sge->sge_count = htole32(xfer->dm_segs[i].ds_len); 822 } 823 } 824 825 bus_dmamap_sync(amr->amr_dmat, xfer, 0, ac->ac_xfer_size, 826 out ? BUS_DMASYNC_PREWRITE : BUS_DMASYNC_PREREAD); 827 828 if ((ac->ac_flags & AC_NOSGL) == 0) 829 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, sgloff, 830 AMR_SGL_SIZE, BUS_DMASYNC_PREWRITE); 831 832 return (0); 833 } 834 835 /* 836 * Unmap the specified CCB's data buffer. 837 */ 838 void 839 amr_ccb_unmap(struct amr_softc *amr, struct amr_ccb *ac) 840 { 841 842 if ((ac->ac_flags & AC_NOSGL) == 0) 843 bus_dmamap_sync(amr->amr_dmat, amr->amr_dmamap, 844 AMR_SGL_SIZE * ac->ac_ident, AMR_SGL_SIZE, 845 BUS_DMASYNC_POSTWRITE); 846 bus_dmamap_sync(amr->amr_dmat, ac->ac_xfer_map, 0, ac->ac_xfer_size, 847 (ac->ac_flags & AC_XFER_IN) != 0 ? 848 BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 849 bus_dmamap_unload(amr->amr_dmat, ac->ac_xfer_map); 850 } 851 852 /* 853 * Submit a command to the controller and poll on completion. Return 854 * non-zero on timeout or error. Must be called with interrupts blocked. 855 */ 856 int 857 amr_ccb_poll(struct amr_softc *amr, struct amr_ccb *ac, int timo) 858 { 859 int rv; 860 861 if ((rv = (*amr->amr_submit)(amr, ac)) != 0) 862 return (rv); 863 864 for (timo *= 10; timo != 0; timo--) { 865 amr_intr(amr); 866 if ((ac->ac_flags & AC_COMPLETE) != 0) 867 break; 868 DELAY(100); 869 } 870 871 return (timo == 0 || ac->ac_status != 0 ? EIO : 0); 872 } 873 874 /* 875 * Wait for the mailbox to become available. 876 */ 877 int 878 amr_mbox_wait(struct amr_softc *amr) 879 { 880 int timo; 881 882 for (timo = 10000; timo != 0; timo--) { 883 if (amr->amr_mbox->mb_busy == 0) 884 break; 885 DELAY(100); 886 } 887 888 #if 0 889 if (timo != 0) 890 printf("%s: controller wedged\n", amr->amr_dv.dv_xname); 891 #endif 892 893 return (timo != 0 ? 0 : EIO); 894 } 895 896 /* 897 * Tell the controller that the mailbox contains a valid command. Must be 898 * called with interrupts blocked. 899 */ 900 int 901 amr_quartz_submit(struct amr_softc *amr, struct amr_ccb *ac) 902 { 903 u_int32_t v; 904 905 v = amr_inl(amr, AMR_QREG_IDB); 906 if ((v & (AMR_QIDB_SUBMIT | AMR_QIDB_ACK)) != 0) 907 return (EBUSY); 908 909 memcpy(amr->amr_mbox, &ac->ac_mbox, sizeof(ac->ac_mbox)); 910 911 ac->ac_flags |= AC_ACTIVE; 912 amr_outl(amr, AMR_QREG_IDB, amr->amr_mbox_paddr | AMR_QIDB_SUBMIT); 913 DELAY(10); 914 return (0); 915 } 916 917 int 918 amr_std_submit(struct amr_softc *amr, struct amr_ccb *ac) 919 { 920 921 if ((amr_inb(amr, AMR_SREG_MBOX_BUSY) & AMR_SMBOX_BUSY_FLAG) != 0) 922 return (EBUSY); 923 924 memcpy(amr->amr_mbox, &ac->ac_mbox, sizeof(ac->ac_mbox)); 925 926 ac->ac_flags |= AC_ACTIVE; 927 amr_outb(amr, AMR_SREG_CMD, AMR_SCMD_POST); 928 return (0); 929 } 930 931 /* 932 * Claim any work that the controller has completed; acknowledge completion, 933 * save details of the completion in (mbsave). Must be called with 934 * interrupts blocked. 935 */ 936 int 937 amr_quartz_get_work(struct amr_softc *amr, struct amr_mailbox *mbsave) 938 { 939 u_int32_t v; 940 941 if (amr_mbox_wait(amr)) 942 return (EBUSY); 943 944 v = amr_inl(amr, AMR_QREG_IDB); 945 if ((v & (AMR_QIDB_SUBMIT | AMR_QIDB_ACK)) != 0) 946 return (EBUSY); 947 948 /* Work waiting for us? */ 949 if (amr_inl(amr, AMR_QREG_ODB) != AMR_QODB_READY) 950 return (-1); 951 952 /* Save the mailbox, which contains a list of completed commands. */ 953 memcpy(mbsave, amr->amr_mbox, sizeof(*mbsave)); 954 955 /* Ack the interrupt and mailbox transfer. */ 956 amr_outl(amr, AMR_QREG_ODB, AMR_QODB_READY); 957 amr_outl(amr, AMR_QREG_IDB, amr->amr_mbox_paddr | AMR_QIDB_ACK); 958 DELAY(10); 959 960 #if 0 961 /* 962 * This waits for the controller to notice that we've taken the 963 * command from it. It's very inefficient, and we shouldn't do it, 964 * but if we remove this code, we stop completing commands under 965 * load. 966 * 967 * Peter J says we shouldn't do this. The documentation says we 968 * should. Who is right? 969 */ 970 while ((amr_inl(amr, AMR_QREG_IDB) & AMR_QIDB_ACK) != 0) 971 ; 972 #endif 973 974 return (0); 975 } 976 977 int 978 amr_std_get_work(struct amr_softc *amr, struct amr_mailbox *mbsave) 979 { 980 u_int8_t istat; 981 982 if (amr_mbox_wait(amr)) 983 return (EBUSY); 984 985 /* Puke if the mailbox is busy. */ 986 if ((amr_inb(amr, AMR_SREG_MBOX_BUSY) & AMR_SMBOX_BUSY_FLAG) != 0) 987 return (-1); 988 989 /* Check for valid interrupt status. */ 990 if (((istat = amr_inb(amr, AMR_SREG_INTR)) & AMR_SINTR_VALID) == 0) 991 return (-1); 992 993 /* Ack the interrupt. */ 994 amr_outb(amr, AMR_SREG_INTR, istat); 995 996 /* Save mailbox, which contains a list of completed commands. */ 997 memcpy(mbsave, amr->amr_mbox, sizeof(*mbsave)); 998 999 /* Ack mailbox transfer. */ 1000 amr_outb(amr, AMR_SREG_CMD, AMR_SCMD_ACKINTR); 1001 1002 return (0); 1003 } 1004