1 /* $NetBSD: twe.c,v 1.54 2003/12/04 05:46:47 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2000, 2001, 2002, 2003 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; and by Jason R. Thorpe of Wasabi Systems, Inc. 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) 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: twe.c,v 1.1 2000/05/24 23:35:23 msmith Exp 66 */ 67 68 /* 69 * Driver for the 3ware Escalade family of RAID controllers. 70 */ 71 72 #include <sys/cdefs.h> 73 __KERNEL_RCSID(0, "$NetBSD: twe.c,v 1.54 2003/12/04 05:46:47 thorpej Exp $"); 74 75 #include <sys/param.h> 76 #include <sys/systm.h> 77 #include <sys/kernel.h> 78 #include <sys/device.h> 79 #include <sys/queue.h> 80 #include <sys/proc.h> 81 #include <sys/buf.h> 82 #include <sys/endian.h> 83 #include <sys/malloc.h> 84 #include <sys/conf.h> 85 #include <sys/disk.h> 86 87 #include <uvm/uvm_extern.h> 88 89 #include <machine/bswap.h> 90 #include <machine/bus.h> 91 92 #include <dev/pci/pcireg.h> 93 #include <dev/pci/pcivar.h> 94 #include <dev/pci/pcidevs.h> 95 #include <dev/pci/twereg.h> 96 #include <dev/pci/twevar.h> 97 #include <dev/pci/tweio.h> 98 99 #define PCI_CBIO 0x10 100 101 static int twe_aen_get(struct twe_softc *, uint16_t *); 102 static void twe_aen_handler(struct twe_ccb *, int); 103 static void twe_aen_enqueue(struct twe_softc *sc, uint16_t, int); 104 static uint16_t twe_aen_dequeue(struct twe_softc *); 105 106 static void twe_attach(struct device *, struct device *, void *); 107 static int twe_init_connection(struct twe_softc *); 108 static int twe_intr(void *); 109 static int twe_match(struct device *, struct cfdata *, void *); 110 static int twe_param_set(struct twe_softc *, int, int, size_t, void *); 111 static void twe_poll(struct twe_softc *); 112 static int twe_print(void *, const char *); 113 static int twe_reset(struct twe_softc *); 114 static int twe_submatch(struct device *, struct cfdata *, void *); 115 static int twe_status_check(struct twe_softc *, u_int); 116 static int twe_status_wait(struct twe_softc *, u_int, int); 117 static void twe_describe_controller(struct twe_softc *); 118 119 static int twe_add_unit(struct twe_softc *, int); 120 static int twe_del_unit(struct twe_softc *, int); 121 122 static inline u_int32_t twe_inl(struct twe_softc *, int); 123 static inline void twe_outl(struct twe_softc *, int, u_int32_t); 124 125 dev_type_open(tweopen); 126 dev_type_close(tweclose); 127 dev_type_ioctl(tweioctl); 128 129 const struct cdevsw twe_cdevsw = { 130 tweopen, tweclose, noread, nowrite, tweioctl, 131 nostop, notty, nopoll, nommap, 132 }; 133 134 extern struct cfdriver twe_cd; 135 136 CFATTACH_DECL(twe, sizeof(struct twe_softc), 137 twe_match, twe_attach, NULL, NULL); 138 139 /* 140 * Tables to convert numeric codes to strings. 141 */ 142 const struct twe_code_table twe_table_status[] = { 143 { 0x00, "successful completion" }, 144 145 /* info */ 146 { 0x42, "command in progress" }, 147 { 0x6c, "retrying interface CRC error from UDMA command" }, 148 149 /* warning */ 150 { 0x81, "redundant/inconsequential request ignored" }, 151 { 0x8e, "failed to write zeroes to LBA 0" }, 152 { 0x8f, "failed to profile TwinStor zones" }, 153 154 /* fatal */ 155 { 0xc1, "aborted due to system command or reconfiguration" }, 156 { 0xc4, "aborted" }, 157 { 0xc5, "access error" }, 158 { 0xc6, "access violation" }, 159 { 0xc7, "device failure" }, /* high byte may be port # */ 160 { 0xc8, "controller error" }, 161 { 0xc9, "timed out" }, 162 { 0xcb, "invalid unit number" }, 163 { 0xcf, "unit not available" }, 164 { 0xd2, "undefined opcode" }, 165 { 0xdb, "request incompatible with unit" }, 166 { 0xdc, "invalid request" }, 167 { 0xff, "firmware error, reset requested" }, 168 169 { 0, NULL } 170 }; 171 172 const struct twe_code_table twe_table_unitstate[] = { 173 { TWE_PARAM_UNITSTATUS_Normal, "Normal" }, 174 { TWE_PARAM_UNITSTATUS_Initialising, "Initializing" }, 175 { TWE_PARAM_UNITSTATUS_Degraded, "Degraded" }, 176 { TWE_PARAM_UNITSTATUS_Rebuilding, "Rebuilding" }, 177 { TWE_PARAM_UNITSTATUS_Verifying, "Verifying" }, 178 { TWE_PARAM_UNITSTATUS_Corrupt, "Corrupt" }, 179 { TWE_PARAM_UNITSTATUS_Missing, "Missing" }, 180 181 { 0, NULL } 182 }; 183 184 const struct twe_code_table twe_table_unittype[] = { 185 /* array descriptor configuration */ 186 { TWE_AD_CONFIG_RAID0, "RAID0" }, 187 { TWE_AD_CONFIG_RAID1, "RAID1" }, 188 { TWE_AD_CONFIG_TwinStor, "TwinStor" }, 189 { TWE_AD_CONFIG_RAID5, "RAID5" }, 190 { TWE_AD_CONFIG_RAID10, "RAID10" }, 191 192 { 0, NULL } 193 }; 194 195 const struct twe_code_table twe_table_stripedepth[] = { 196 { TWE_AD_STRIPE_4k, "4K" }, 197 { TWE_AD_STRIPE_8k, "8K" }, 198 { TWE_AD_STRIPE_16k, "16K" }, 199 { TWE_AD_STRIPE_32k, "32K" }, 200 { TWE_AD_STRIPE_64k, "64K" }, 201 202 { 0, NULL } 203 }; 204 205 /* 206 * Asynchronous event notification messages are qualified: 207 * a - not unit/port specific 208 * u - unit specific 209 * p - port specific 210 */ 211 const struct twe_code_table twe_table_aen[] = { 212 { 0x00, "a queue empty" }, 213 { 0x01, "a soft reset" }, 214 { 0x02, "u degraded mode" }, 215 { 0x03, "a controller error" }, 216 { 0x04, "u rebuild fail" }, 217 { 0x05, "u rebuild done" }, 218 { 0x06, "u incomplete unit" }, 219 { 0x07, "u initialization done" }, 220 { 0x08, "u unclean shutdown detected" }, 221 { 0x09, "p drive timeout" }, 222 { 0x0a, "p drive error" }, 223 { 0x0b, "u rebuild started" }, 224 { 0x0c, "u initialization started" }, 225 { 0x0d, "u logical unit deleted" }, 226 { 0x0f, "p SMART threshold exceeded" }, 227 { 0x15, "a table undefined" }, /* XXX: Not in FreeBSD's table */ 228 { 0x21, "p ATA UDMA downgrade" }, 229 { 0x22, "p ATA UDMA upgrade" }, 230 { 0x23, "p sector repair occurred" }, 231 { 0x24, "a SBUF integrity check failure" }, 232 { 0x25, "p lost cached write" }, 233 { 0x26, "p drive ECC error detected" }, 234 { 0x27, "p DCB checksum error" }, 235 { 0x28, "p DCB unsupported version" }, 236 { 0x29, "u verify started" }, 237 { 0x2a, "u verify failed" }, 238 { 0x2b, "u verify complete" }, 239 { 0x2c, "p overwrote bad sector during rebuild" }, 240 { 0x2d, "p encountered bad sector during rebuild" }, 241 { 0x2e, "p replacement drive too small" }, 242 { 0x2f, "u array not previously initialized" }, 243 { 0x30, "p drive not supported" }, 244 { 0xff, "a aen queue full" }, 245 246 { 0, NULL }, 247 }; 248 249 const char * 250 twe_describe_code(const struct twe_code_table *table, uint32_t code) 251 { 252 253 for (; table->string != NULL; table++) { 254 if (table->code == code) 255 return (table->string); 256 } 257 return (NULL); 258 } 259 260 static inline u_int32_t 261 twe_inl(struct twe_softc *sc, int off) 262 { 263 264 bus_space_barrier(sc->sc_iot, sc->sc_ioh, off, 4, 265 BUS_SPACE_BARRIER_WRITE | BUS_SPACE_BARRIER_READ); 266 return (bus_space_read_4(sc->sc_iot, sc->sc_ioh, off)); 267 } 268 269 static inline void 270 twe_outl(struct twe_softc *sc, int off, u_int32_t val) 271 { 272 273 bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, val); 274 bus_space_barrier(sc->sc_iot, sc->sc_ioh, off, 4, 275 BUS_SPACE_BARRIER_WRITE); 276 } 277 278 /* 279 * Match a supported board. 280 */ 281 static int 282 twe_match(struct device *parent, struct cfdata *cfdata, void *aux) 283 { 284 struct pci_attach_args *pa; 285 286 pa = aux; 287 288 return (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_3WARE && 289 (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3WARE_ESCALADE || 290 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3WARE_ESCALADE_ASIC)); 291 } 292 293 /* 294 * Attach a supported board. 295 * 296 * XXX This doesn't fail gracefully. 297 */ 298 static void 299 twe_attach(struct device *parent, struct device *self, void *aux) 300 { 301 struct pci_attach_args *pa; 302 struct twe_softc *sc; 303 pci_chipset_tag_t pc; 304 pci_intr_handle_t ih; 305 pcireg_t csr; 306 const char *intrstr; 307 int s, size, i, rv, rseg; 308 size_t max_segs, max_xfer; 309 bus_dma_segment_t seg; 310 struct twe_cmd *tc; 311 struct twe_ccb *ccb; 312 313 sc = (struct twe_softc *)self; 314 pa = aux; 315 pc = pa->pa_pc; 316 sc->sc_dmat = pa->pa_dmat; 317 SIMPLEQ_INIT(&sc->sc_ccb_queue); 318 SLIST_INIT(&sc->sc_ccb_freelist); 319 320 aprint_naive(": RAID controller\n"); 321 aprint_normal(": 3ware Escalade\n"); 322 323 ccb = malloc(sizeof(*ccb) * TWE_MAX_QUEUECNT, M_DEVBUF, M_NOWAIT); 324 if (ccb == NULL) { 325 aprint_error("%s: unable to allocate memory for ccbs\n", 326 sc->sc_dv.dv_xname); 327 return; 328 } 329 330 if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0, 331 &sc->sc_iot, &sc->sc_ioh, NULL, NULL)) { 332 aprint_error("%s: can't map i/o space\n", sc->sc_dv.dv_xname); 333 return; 334 } 335 336 /* Enable the device. */ 337 csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 338 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 339 csr | PCI_COMMAND_MASTER_ENABLE); 340 341 /* Map and establish the interrupt. */ 342 if (pci_intr_map(pa, &ih)) { 343 aprint_error("%s: can't map interrupt\n", sc->sc_dv.dv_xname); 344 return; 345 } 346 347 intrstr = pci_intr_string(pc, ih); 348 sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, twe_intr, sc); 349 if (sc->sc_ih == NULL) { 350 aprint_error("%s: can't establish interrupt%s%s\n", 351 sc->sc_dv.dv_xname, 352 (intrstr) ? " at " : "", 353 (intrstr) ? intrstr : ""); 354 return; 355 } 356 357 if (intrstr != NULL) 358 aprint_normal("%s: interrupting at %s\n", 359 sc->sc_dv.dv_xname, intrstr); 360 361 /* 362 * Allocate and initialise the command blocks and CCBs. 363 */ 364 size = sizeof(struct twe_cmd) * TWE_MAX_QUEUECNT; 365 366 if ((rv = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &seg, 1, 367 &rseg, BUS_DMA_NOWAIT)) != 0) { 368 aprint_error("%s: unable to allocate commands, rv = %d\n", 369 sc->sc_dv.dv_xname, rv); 370 return; 371 } 372 373 if ((rv = bus_dmamem_map(sc->sc_dmat, &seg, rseg, size, 374 (caddr_t *)&sc->sc_cmds, 375 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 376 aprint_error("%s: unable to map commands, rv = %d\n", 377 sc->sc_dv.dv_xname, rv); 378 return; 379 } 380 381 if ((rv = bus_dmamap_create(sc->sc_dmat, size, size, 1, 0, 382 BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) { 383 aprint_error("%s: unable to create command DMA map, rv = %d\n", 384 sc->sc_dv.dv_xname, rv); 385 return; 386 } 387 388 if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_cmds, 389 size, NULL, BUS_DMA_NOWAIT)) != 0) { 390 aprint_error("%s: unable to load command DMA map, rv = %d\n", 391 sc->sc_dv.dv_xname, rv); 392 return; 393 } 394 395 sc->sc_cmds_paddr = sc->sc_dmamap->dm_segs[0].ds_addr; 396 memset(sc->sc_cmds, 0, size); 397 398 sc->sc_ccbs = ccb; 399 tc = (struct twe_cmd *)sc->sc_cmds; 400 max_segs = twe_get_maxsegs(); 401 max_xfer = twe_get_maxxfer(max_segs); 402 403 for (i = 0; i < TWE_MAX_QUEUECNT; i++, tc++, ccb++) { 404 ccb->ccb_cmd = tc; 405 ccb->ccb_cmdid = i; 406 ccb->ccb_flags = 0; 407 rv = bus_dmamap_create(sc->sc_dmat, max_xfer, 408 max_segs, PAGE_SIZE, 0, 409 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, 410 &ccb->ccb_dmamap_xfer); 411 if (rv != 0) { 412 aprint_error("%s: can't create dmamap, rv = %d\n", 413 sc->sc_dv.dv_xname, rv); 414 return; 415 } 416 417 /* Save the first CCB for AEN retrieval. */ 418 if (i != 0) 419 SLIST_INSERT_HEAD(&sc->sc_ccb_freelist, ccb, 420 ccb_chain.slist); 421 } 422 423 /* Wait for the controller to become ready. */ 424 if (twe_status_wait(sc, TWE_STS_MICROCONTROLLER_READY, 6)) { 425 aprint_error("%s: microcontroller not ready\n", 426 sc->sc_dv.dv_xname); 427 return; 428 } 429 430 twe_outl(sc, TWE_REG_CTL, TWE_CTL_DISABLE_INTRS); 431 432 /* Reset the controller. */ 433 s = splbio(); 434 rv = twe_reset(sc); 435 splx(s); 436 if (rv) { 437 aprint_error("%s: reset failed\n", sc->sc_dv.dv_xname); 438 return; 439 } 440 441 /* Initialise connection with controller. */ 442 twe_init_connection(sc); 443 444 twe_describe_controller(sc); 445 446 /* Find and attach RAID array units. */ 447 sc->sc_nunits = 0; 448 for (i = 0; i < TWE_MAX_UNITS; i++) 449 (void) twe_add_unit(sc, i); 450 451 /* ...and finally, enable interrupts. */ 452 twe_outl(sc, TWE_REG_CTL, TWE_CTL_CLEAR_ATTN_INTR | 453 TWE_CTL_UNMASK_RESP_INTR | 454 TWE_CTL_ENABLE_INTRS); 455 } 456 457 void 458 twe_register_callbacks(struct twe_softc *sc, int unit, 459 const struct twe_callbacks *tcb) 460 { 461 462 sc->sc_units[unit].td_callbacks = tcb; 463 } 464 465 static void 466 twe_recompute_openings(struct twe_softc *sc) 467 { 468 struct twe_drive *td; 469 int unit, openings; 470 471 if (sc->sc_nunits != 0) 472 openings = (TWE_MAX_QUEUECNT - 1) / sc->sc_nunits; 473 else 474 openings = 0; 475 if (openings == sc->sc_openings) 476 return; 477 sc->sc_openings = openings; 478 479 #ifdef TWE_DEBUG 480 printf("%s: %d array%s, %d openings per array\n", 481 sc->sc_dv.dv_xname, sc->sc_nunits, 482 sc->sc_nunits == 1 ? "" : "s", sc->sc_openings); 483 #endif 484 485 for (unit = 0; unit < TWE_MAX_UNITS; unit++) { 486 td = &sc->sc_units[unit]; 487 if (td->td_dev != NULL) 488 (*td->td_callbacks->tcb_openings)(td->td_dev, 489 sc->sc_openings); 490 } 491 } 492 493 static int 494 twe_add_unit(struct twe_softc *sc, int unit) 495 { 496 struct twe_param *dtp, *atp; 497 struct twe_array_descriptor *ad; 498 struct twe_drive *td; 499 struct twe_attach_args twea; 500 uint32_t newsize; 501 int rv; 502 uint16_t dsize; 503 uint8_t newtype, newstripe; 504 505 if (unit < 0 || unit >= TWE_MAX_UNITS) 506 return (EINVAL); 507 508 /* Find attached units. */ 509 rv = twe_param_get(sc, TWE_PARAM_UNITSUMMARY, 510 TWE_PARAM_UNITSUMMARY_Status, TWE_MAX_UNITS, NULL, &dtp); 511 if (rv != 0) { 512 aprint_error("%s: error %d fetching unit summary\n", 513 sc->sc_dv.dv_xname, rv); 514 return (rv); 515 } 516 517 /* For each detected unit, collect size and store in an array. */ 518 td = &sc->sc_units[unit]; 519 520 /* Unit present? */ 521 if ((dtp->tp_data[unit] & TWE_PARAM_UNITSTATUS_Online) == 0) { 522 /* 523 * XXX Should we check to see if a device has been 524 * XXX attached at this index and detach it if it 525 * XXX has? ("rescan" semantics) 526 */ 527 rv = 0; 528 goto out; 529 } 530 531 rv = twe_param_get_2(sc, TWE_PARAM_UNITINFO + unit, 532 TWE_PARAM_UNITINFO_DescriptorSize, &dsize); 533 if (rv != 0) { 534 aprint_error("%s: error %d fetching descriptor size " 535 "for unit %d\n", sc->sc_dv.dv_xname, rv, unit); 536 goto out; 537 } 538 539 rv = twe_param_get(sc, TWE_PARAM_UNITINFO + unit, 540 TWE_PARAM_UNITINFO_Descriptor, dsize - 3, NULL, &atp); 541 if (rv != 0) { 542 aprint_error("%s: error %d fetching array descriptor " 543 "for unit %d\n", sc->sc_dv.dv_xname, rv, unit); 544 goto out; 545 } 546 547 ad = (struct twe_array_descriptor *)atp->tp_data; 548 newtype = ad->configuration; 549 newstripe = ad->stripe_size; 550 free(atp, M_DEVBUF); 551 552 rv = twe_param_get_4(sc, TWE_PARAM_UNITINFO + unit, 553 TWE_PARAM_UNITINFO_Capacity, &newsize); 554 if (rv != 0) { 555 aprint_error( 556 "%s: error %d fetching capacity for unit %d\n", 557 sc->sc_dv.dv_xname, rv, unit); 558 goto out; 559 } 560 561 /* 562 * Have a device, so we need to attach it. If there is currently 563 * something sitting at the slot, and the parameters are different, 564 * then we detach the old device before attaching the new one. 565 */ 566 if (td->td_dev != NULL && 567 td->td_size == newsize && 568 td->td_type == newtype && 569 td->td_stripe == newstripe) { 570 /* Same as the old device; just keep using it. */ 571 rv = 0; 572 goto out; 573 } else if (td->td_dev != NULL) { 574 /* Detach the old device first. */ 575 (void) config_detach(td->td_dev, DETACH_FORCE); 576 td->td_dev = NULL; 577 } else if (td->td_size == 0) 578 sc->sc_nunits++; 579 580 /* 581 * Committed to the new array unit; assign its parameters and 582 * recompute the number of available command openings. 583 */ 584 td->td_size = newsize; 585 td->td_type = newtype; 586 td->td_stripe = newstripe; 587 twe_recompute_openings(sc); 588 589 twea.twea_unit = unit; 590 td->td_dev = config_found_sm(&sc->sc_dv, &twea, twe_print, 591 twe_submatch); 592 593 rv = 0; 594 out: 595 free(dtp, M_DEVBUF); 596 return (rv); 597 } 598 599 static int 600 twe_del_unit(struct twe_softc *sc, int unit) 601 { 602 struct twe_drive *td; 603 604 if (unit < 0 || unit >= TWE_MAX_UNITS) 605 return (EINVAL); 606 607 td = &sc->sc_units[unit]; 608 if (td->td_size != 0) 609 sc->sc_nunits--; 610 td->td_size = 0; 611 td->td_type = 0; 612 td->td_stripe = 0; 613 if (td->td_dev != NULL) { 614 (void) config_detach(td->td_dev, DETACH_FORCE); 615 td->td_dev = NULL; 616 } 617 twe_recompute_openings(sc); 618 return (0); 619 } 620 621 /* 622 * Reset the controller. 623 * MUST BE CALLED AT splbio()! 624 */ 625 static int 626 twe_reset(struct twe_softc *sc) 627 { 628 uint16_t aen; 629 u_int status; 630 volatile u_int32_t junk; 631 int got, rv; 632 633 /* Issue a soft reset. */ 634 twe_outl(sc, TWE_REG_CTL, TWE_CTL_ISSUE_SOFT_RESET | 635 TWE_CTL_CLEAR_HOST_INTR | 636 TWE_CTL_CLEAR_ATTN_INTR | 637 TWE_CTL_MASK_CMD_INTR | 638 TWE_CTL_MASK_RESP_INTR | 639 TWE_CTL_CLEAR_ERROR_STS | 640 TWE_CTL_DISABLE_INTRS); 641 642 /* Wait for attention... */ 643 if (twe_status_wait(sc, TWE_STS_ATTN_INTR, 15)) { 644 printf("%s: no attention interrupt\n", 645 sc->sc_dv.dv_xname); 646 return (-1); 647 } 648 649 /* ...and ACK it. */ 650 twe_outl(sc, TWE_REG_CTL, TWE_CTL_CLEAR_ATTN_INTR); 651 652 /* 653 * Pull AENs out of the controller; look for a soft reset AEN. 654 * Open code this, since we want to detect reset even if the 655 * queue for management tools is full. 656 * 657 * Note that since: 658 * - interrupts are blocked 659 * - we have reset the controller 660 * - acknowledged the pending ATTENTION 661 * that there is no way a pending asynchronous AEN fetch would 662 * finish, so clear the flag. 663 */ 664 sc->sc_flags &= ~TWEF_AEN; 665 for (got = 0;;) { 666 rv = twe_aen_get(sc, &aen); 667 if (rv != 0) 668 printf("%s: error %d while draining event queue\n", 669 sc->sc_dv.dv_xname, rv); 670 if (TWE_AEN_CODE(aen) == TWE_AEN_QUEUE_EMPTY) 671 break; 672 if (TWE_AEN_CODE(aen) == TWE_AEN_SOFT_RESET) 673 got = 1; 674 twe_aen_enqueue(sc, aen, 1); 675 } 676 677 if (!got) { 678 printf("%s: reset not reported\n", sc->sc_dv.dv_xname); 679 return (-1); 680 } 681 682 /* Check controller status. */ 683 status = twe_inl(sc, TWE_REG_STS); 684 if (twe_status_check(sc, status)) { 685 printf("%s: controller errors detected\n", 686 sc->sc_dv.dv_xname); 687 return (-1); 688 } 689 690 /* Drain the response queue. */ 691 for (;;) { 692 status = twe_inl(sc, TWE_REG_STS); 693 if (twe_status_check(sc, status) != 0) { 694 printf("%s: can't drain response queue\n", 695 sc->sc_dv.dv_xname); 696 return (-1); 697 } 698 if ((status & TWE_STS_RESP_QUEUE_EMPTY) != 0) 699 break; 700 junk = twe_inl(sc, TWE_REG_RESP_QUEUE); 701 } 702 703 return (0); 704 } 705 706 /* 707 * Print autoconfiguration message for a sub-device. 708 */ 709 static int 710 twe_print(void *aux, const char *pnp) 711 { 712 struct twe_attach_args *twea; 713 714 twea = aux; 715 716 if (pnp != NULL) 717 aprint_normal("block device at %s", pnp); 718 aprint_normal(" unit %d", twea->twea_unit); 719 return (UNCONF); 720 } 721 722 /* 723 * Match a sub-device. 724 */ 725 static int 726 twe_submatch(struct device *parent, struct cfdata *cf, void *aux) 727 { 728 struct twe_attach_args *twea; 729 730 twea = aux; 731 732 if (cf->tweacf_unit != TWECF_UNIT_DEFAULT && 733 cf->tweacf_unit != twea->twea_unit) 734 return (0); 735 736 return (config_match(parent, cf, aux)); 737 } 738 739 /* 740 * Interrupt service routine. 741 */ 742 static int 743 twe_intr(void *arg) 744 { 745 struct twe_softc *sc; 746 u_int status; 747 int caught, rv; 748 749 sc = arg; 750 caught = 0; 751 status = twe_inl(sc, TWE_REG_STS); 752 twe_status_check(sc, status); 753 754 /* Host interrupts - purpose unknown. */ 755 if ((status & TWE_STS_HOST_INTR) != 0) { 756 #ifdef DEBUG 757 printf("%s: host interrupt\n", sc->sc_dv.dv_xname); 758 #endif 759 twe_outl(sc, TWE_REG_CTL, TWE_CTL_CLEAR_HOST_INTR); 760 caught = 1; 761 } 762 763 /* 764 * Attention interrupts, signalled when a controller or child device 765 * state change has occurred. 766 */ 767 if ((status & TWE_STS_ATTN_INTR) != 0) { 768 rv = twe_aen_get(sc, NULL); 769 if (rv != 0) 770 printf("%s: unable to retrieve AEN (%d)\n", 771 sc->sc_dv.dv_xname, rv); 772 else 773 twe_outl(sc, TWE_REG_CTL, TWE_CTL_CLEAR_ATTN_INTR); 774 caught = 1; 775 } 776 777 /* 778 * Command interrupts, signalled when the controller can accept more 779 * commands. We don't use this; instead, we try to submit commands 780 * when we receive them, and when other commands have completed. 781 * Mask it so we don't get another one. 782 */ 783 if ((status & TWE_STS_CMD_INTR) != 0) { 784 #ifdef DEBUG 785 printf("%s: command interrupt\n", sc->sc_dv.dv_xname); 786 #endif 787 twe_outl(sc, TWE_REG_CTL, TWE_CTL_MASK_CMD_INTR); 788 caught = 1; 789 } 790 791 if ((status & TWE_STS_RESP_INTR) != 0) { 792 twe_poll(sc); 793 caught = 1; 794 } 795 796 return (caught); 797 } 798 799 /* 800 * Fetch an AEN. Even though this is really like parameter 801 * retrieval, we handle this specially, because we issue this 802 * AEN retrieval command from interrupt context, and thus 803 * reserve a CCB for it to avoid resource shortage. 804 * 805 * XXX There are still potential resource shortages we could 806 * XXX encounter. Consider pre-allocating all AEN-related 807 * XXX resources. 808 * 809 * MUST BE CALLED AT splbio()! 810 */ 811 static int 812 twe_aen_get(struct twe_softc *sc, uint16_t *aenp) 813 { 814 struct twe_ccb *ccb; 815 struct twe_cmd *tc; 816 struct twe_param *tp; 817 int rv; 818 819 /* 820 * If we're already retrieving an AEN, just wait; another 821 * retrieval will be chained after the current one completes. 822 */ 823 if (sc->sc_flags & TWEF_AEN) { 824 /* 825 * It is a fatal software programming error to attempt 826 * to fetch an AEN synchronously when an AEN fetch is 827 * already pending. 828 */ 829 KASSERT(aenp == NULL); 830 return (0); 831 } 832 833 tp = malloc(TWE_SECTOR_SIZE, M_DEVBUF, M_NOWAIT); 834 if (tp == NULL) 835 return (ENOMEM); 836 837 ccb = twe_ccb_alloc(sc, 838 TWE_CCB_AEN | TWE_CCB_DATA_IN | TWE_CCB_DATA_OUT); 839 KASSERT(ccb != NULL); 840 841 ccb->ccb_data = tp; 842 ccb->ccb_datasize = TWE_SECTOR_SIZE; 843 ccb->ccb_tx.tx_handler = (aenp == NULL) ? twe_aen_handler : NULL; 844 ccb->ccb_tx.tx_context = tp; 845 ccb->ccb_tx.tx_dv = &sc->sc_dv; 846 847 tc = ccb->ccb_cmd; 848 tc->tc_size = 2; 849 tc->tc_opcode = TWE_OP_GET_PARAM | (tc->tc_size << 5); 850 tc->tc_unit = 0; 851 tc->tc_count = htole16(1); 852 853 /* Fill in the outbound parameter data. */ 854 tp->tp_table_id = htole16(TWE_PARAM_AEN); 855 tp->tp_param_id = TWE_PARAM_AEN_UnitCode; 856 tp->tp_param_size = 2; 857 858 /* Map the transfer. */ 859 if ((rv = twe_ccb_map(sc, ccb)) != 0) { 860 twe_ccb_free(sc, ccb); 861 goto done; 862 } 863 864 /* Enqueue the command and wait. */ 865 if (aenp != NULL) { 866 rv = twe_ccb_poll(sc, ccb, 5); 867 twe_ccb_unmap(sc, ccb); 868 twe_ccb_free(sc, ccb); 869 if (rv == 0) 870 *aenp = le16toh(*(uint16_t *)tp->tp_data); 871 free(tp, M_DEVBUF); 872 } else { 873 sc->sc_flags |= TWEF_AEN; 874 twe_ccb_enqueue(sc, ccb); 875 rv = 0; 876 } 877 878 done: 879 return (rv); 880 } 881 882 /* 883 * Handle an AEN returned by the controller. 884 * MUST BE CALLED AT splbio()! 885 */ 886 static void 887 twe_aen_handler(struct twe_ccb *ccb, int error) 888 { 889 struct twe_softc *sc; 890 struct twe_param *tp; 891 uint16_t aen; 892 int rv; 893 894 sc = (struct twe_softc *)ccb->ccb_tx.tx_dv; 895 tp = ccb->ccb_tx.tx_context; 896 twe_ccb_unmap(sc, ccb); 897 898 sc->sc_flags &= ~TWEF_AEN; 899 900 if (error) { 901 printf("%s: error retrieving AEN\n", sc->sc_dv.dv_xname); 902 aen = TWE_AEN_QUEUE_EMPTY; 903 } else 904 aen = le16toh(*(u_int16_t *)tp->tp_data); 905 free(tp, M_DEVBUF); 906 twe_ccb_free(sc, ccb); 907 908 if (TWE_AEN_CODE(aen) == TWE_AEN_QUEUE_EMPTY) { 909 twe_outl(sc, TWE_REG_CTL, TWE_CTL_CLEAR_ATTN_INTR); 910 return; 911 } 912 913 twe_aen_enqueue(sc, aen, 0); 914 915 /* 916 * Chain another retrieval in case interrupts have been 917 * coalesced. 918 */ 919 rv = twe_aen_get(sc, NULL); 920 if (rv != 0) 921 printf("%s: unable to retrieve AEN (%d)\n", 922 sc->sc_dv.dv_xname, rv); 923 } 924 925 static void 926 twe_aen_enqueue(struct twe_softc *sc, uint16_t aen, int quiet) 927 { 928 const char *str, *msg; 929 int s, next, nextnext; 930 931 /* 932 * First report the AEN on the console. Maybe. 933 */ 934 if (! quiet) { 935 str = twe_describe_code(twe_table_aen, TWE_AEN_CODE(aen)); 936 if (str == NULL) { 937 printf("%s: unknown AEN 0x%04x\n", 938 sc->sc_dv.dv_xname, aen); 939 } else { 940 msg = str + 2; 941 switch (*str) { 942 case 'u': 943 printf("%s: unit %d: %s\n", 944 sc->sc_dv.dv_xname, TWE_AEN_UNIT(aen), msg); 945 break; 946 947 case 'p': 948 printf("%s: port %d: %s\n", 949 sc->sc_dv.dv_xname, TWE_AEN_UNIT(aen), msg); 950 break; 951 952 default: 953 printf("%s: %s\n", sc->sc_dv.dv_xname, msg); 954 } 955 } 956 } 957 958 /* Now enqueue the AEN for mangement tools. */ 959 s = splbio(); 960 961 next = (sc->sc_aen_head + 1) % TWE_AEN_Q_LENGTH; 962 nextnext = (sc->sc_aen_head + 2) % TWE_AEN_Q_LENGTH; 963 964 /* 965 * If this is the last free slot, then queue up a "queue 966 * full" message. 967 */ 968 if (nextnext == sc->sc_aen_tail) 969 aen = TWE_AEN_QUEUE_FULL; 970 971 if (next != sc->sc_aen_tail) { 972 sc->sc_aen_queue[sc->sc_aen_head] = aen; 973 sc->sc_aen_head = next; 974 } 975 976 if (sc->sc_flags & TWEF_AENQ_WAIT) { 977 sc->sc_flags &= ~TWEF_AENQ_WAIT; 978 wakeup(&sc->sc_aen_queue); 979 } 980 981 splx(s); 982 } 983 984 /* NOTE: Must be called at splbio(). */ 985 static uint16_t 986 twe_aen_dequeue(struct twe_softc *sc) 987 { 988 uint16_t aen; 989 990 if (sc->sc_aen_tail == sc->sc_aen_head) 991 aen = TWE_AEN_QUEUE_EMPTY; 992 else { 993 aen = sc->sc_aen_queue[sc->sc_aen_tail]; 994 sc->sc_aen_tail = (sc->sc_aen_tail + 1) & TWE_AEN_Q_LENGTH; 995 } 996 997 return (aen); 998 } 999 1000 /* 1001 * These are short-hand functions that execute TWE_OP_GET_PARAM to 1002 * fetch 1, 2, and 4 byte parameter values, respectively. 1003 */ 1004 int 1005 twe_param_get_1(struct twe_softc *sc, int table_id, int param_id, 1006 uint8_t *valp) 1007 { 1008 struct twe_param *tp; 1009 int rv; 1010 1011 rv = twe_param_get(sc, table_id, param_id, 1, NULL, &tp); 1012 if (rv != 0) 1013 return (rv); 1014 *valp = *(uint8_t *)tp->tp_data; 1015 free(tp, M_DEVBUF); 1016 return (0); 1017 } 1018 1019 int 1020 twe_param_get_2(struct twe_softc *sc, int table_id, int param_id, 1021 uint16_t *valp) 1022 { 1023 struct twe_param *tp; 1024 int rv; 1025 1026 rv = twe_param_get(sc, table_id, param_id, 2, NULL, &tp); 1027 if (rv != 0) 1028 return (rv); 1029 *valp = le16toh(*(uint16_t *)tp->tp_data); 1030 free(tp, M_DEVBUF); 1031 return (0); 1032 } 1033 1034 int 1035 twe_param_get_4(struct twe_softc *sc, int table_id, int param_id, 1036 uint32_t *valp) 1037 { 1038 struct twe_param *tp; 1039 int rv; 1040 1041 rv = twe_param_get(sc, table_id, param_id, 4, NULL, &tp); 1042 if (rv != 0) 1043 return (rv); 1044 *valp = le32toh(*(uint32_t *)tp->tp_data); 1045 free(tp, M_DEVBUF); 1046 return (0); 1047 } 1048 1049 /* 1050 * Execute a TWE_OP_GET_PARAM command. If a callback function is provided, 1051 * it will be called with generated context when the command has completed. 1052 * If no callback is provided, the command will be executed synchronously 1053 * and a pointer to a buffer containing the data returned. 1054 * 1055 * The caller or callback is responsible for freeing the buffer. 1056 * 1057 * NOTE: We assume we can sleep here to wait for a CCB to become available. 1058 */ 1059 int 1060 twe_param_get(struct twe_softc *sc, int table_id, int param_id, size_t size, 1061 void (*func)(struct twe_ccb *, int), struct twe_param **pbuf) 1062 { 1063 struct twe_ccb *ccb; 1064 struct twe_cmd *tc; 1065 struct twe_param *tp; 1066 int rv, s; 1067 1068 tp = malloc(TWE_SECTOR_SIZE, M_DEVBUF, M_NOWAIT); 1069 if (tp == NULL) 1070 return ENOMEM; 1071 1072 ccb = twe_ccb_alloc_wait(sc, TWE_CCB_DATA_IN | TWE_CCB_DATA_OUT); 1073 KASSERT(ccb != NULL); 1074 1075 ccb->ccb_data = tp; 1076 ccb->ccb_datasize = TWE_SECTOR_SIZE; 1077 ccb->ccb_tx.tx_handler = func; 1078 ccb->ccb_tx.tx_context = tp; 1079 ccb->ccb_tx.tx_dv = &sc->sc_dv; 1080 1081 tc = ccb->ccb_cmd; 1082 tc->tc_size = 2; 1083 tc->tc_opcode = TWE_OP_GET_PARAM | (tc->tc_size << 5); 1084 tc->tc_unit = 0; 1085 tc->tc_count = htole16(1); 1086 1087 /* Fill in the outbound parameter data. */ 1088 tp->tp_table_id = htole16(table_id); 1089 tp->tp_param_id = param_id; 1090 tp->tp_param_size = size; 1091 1092 /* Map the transfer. */ 1093 if ((rv = twe_ccb_map(sc, ccb)) != 0) { 1094 twe_ccb_free(sc, ccb); 1095 goto done; 1096 } 1097 1098 /* Submit the command and either wait or let the callback handle it. */ 1099 if (func == NULL) { 1100 s = splbio(); 1101 rv = twe_ccb_poll(sc, ccb, 5); 1102 twe_ccb_unmap(sc, ccb); 1103 twe_ccb_free(sc, ccb); 1104 splx(s); 1105 } else { 1106 #ifdef DEBUG 1107 if (pbuf != NULL) 1108 panic("both func and pbuf defined"); 1109 #endif 1110 twe_ccb_enqueue(sc, ccb); 1111 return 0; 1112 } 1113 1114 done: 1115 if (pbuf == NULL || rv != 0) 1116 free(tp, M_DEVBUF); 1117 else if (pbuf != NULL && rv == 0) 1118 *pbuf = tp; 1119 return rv; 1120 } 1121 1122 /* 1123 * Execute a TWE_OP_SET_PARAM command. 1124 * 1125 * NOTE: We assume we can sleep here to wait for a CCB to become available. 1126 */ 1127 static int 1128 twe_param_set(struct twe_softc *sc, int table_id, int param_id, size_t size, 1129 void *buf) 1130 { 1131 struct twe_ccb *ccb; 1132 struct twe_cmd *tc; 1133 struct twe_param *tp; 1134 int rv, s; 1135 1136 tp = malloc(TWE_SECTOR_SIZE, M_DEVBUF, M_NOWAIT); 1137 if (tp == NULL) 1138 return ENOMEM; 1139 1140 ccb = twe_ccb_alloc_wait(sc, TWE_CCB_DATA_IN | TWE_CCB_DATA_OUT); 1141 KASSERT(ccb != NULL); 1142 1143 ccb->ccb_data = tp; 1144 ccb->ccb_datasize = TWE_SECTOR_SIZE; 1145 ccb->ccb_tx.tx_handler = 0; 1146 ccb->ccb_tx.tx_context = tp; 1147 ccb->ccb_tx.tx_dv = &sc->sc_dv; 1148 1149 tc = ccb->ccb_cmd; 1150 tc->tc_size = 2; 1151 tc->tc_opcode = TWE_OP_SET_PARAM | (tc->tc_size << 5); 1152 tc->tc_unit = 0; 1153 tc->tc_count = htole16(1); 1154 1155 /* Fill in the outbound parameter data. */ 1156 tp->tp_table_id = htole16(table_id); 1157 tp->tp_param_id = param_id; 1158 tp->tp_param_size = size; 1159 memcpy(tp->tp_data, buf, size); 1160 1161 /* Map the transfer. */ 1162 if ((rv = twe_ccb_map(sc, ccb)) != 0) { 1163 twe_ccb_free(sc, ccb); 1164 goto done; 1165 } 1166 1167 /* Submit the command and wait. */ 1168 s = splbio(); 1169 rv = twe_ccb_poll(sc, ccb, 5); 1170 twe_ccb_unmap(sc, ccb); 1171 twe_ccb_free(sc, ccb); 1172 splx(s); 1173 done: 1174 free(tp, M_DEVBUF); 1175 return (rv); 1176 } 1177 1178 /* 1179 * Execute a TWE_OP_INIT_CONNECTION command. Return non-zero on error. 1180 * Must be called with interrupts blocked. 1181 */ 1182 static int 1183 twe_init_connection(struct twe_softc *sc) 1184 /*###762 [cc] warning: `twe_init_connection' was used with no prototype before its definition%%%*/ 1185 /*###762 [cc] warning: `twe_init_connection' was declared implicitly `extern' and later `static'%%%*/ 1186 { 1187 struct twe_ccb *ccb; 1188 struct twe_cmd *tc; 1189 int rv; 1190 1191 if ((ccb = twe_ccb_alloc(sc, 0)) == NULL) 1192 return (EAGAIN); 1193 1194 /* Build the command. */ 1195 tc = ccb->ccb_cmd; 1196 tc->tc_size = 3; 1197 tc->tc_opcode = TWE_OP_INIT_CONNECTION; 1198 tc->tc_unit = 0; 1199 tc->tc_count = htole16(TWE_MAX_CMDS); 1200 tc->tc_args.init_connection.response_queue_pointer = 0; 1201 1202 /* Submit the command for immediate execution. */ 1203 rv = twe_ccb_poll(sc, ccb, 5); 1204 twe_ccb_free(sc, ccb); 1205 return (rv); 1206 } 1207 1208 /* 1209 * Poll the controller for completed commands. Must be called with 1210 * interrupts blocked. 1211 */ 1212 static void 1213 twe_poll(struct twe_softc *sc) 1214 { 1215 struct twe_ccb *ccb; 1216 int found; 1217 u_int status, cmdid; 1218 1219 found = 0; 1220 1221 for (;;) { 1222 status = twe_inl(sc, TWE_REG_STS); 1223 twe_status_check(sc, status); 1224 1225 if ((status & TWE_STS_RESP_QUEUE_EMPTY)) 1226 break; 1227 1228 found = 1; 1229 cmdid = twe_inl(sc, TWE_REG_RESP_QUEUE); 1230 cmdid = (cmdid & TWE_RESP_MASK) >> TWE_RESP_SHIFT; 1231 if (cmdid >= TWE_MAX_QUEUECNT) { 1232 printf("%s: bad cmdid %d\n", sc->sc_dv.dv_xname, cmdid); 1233 continue; 1234 } 1235 1236 ccb = sc->sc_ccbs + cmdid; 1237 if ((ccb->ccb_flags & TWE_CCB_ACTIVE) == 0) { 1238 printf("%s: CCB for cmdid %d not active\n", 1239 sc->sc_dv.dv_xname, cmdid); 1240 continue; 1241 } 1242 ccb->ccb_flags ^= TWE_CCB_COMPLETE | TWE_CCB_ACTIVE; 1243 1244 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 1245 (caddr_t)ccb->ccb_cmd - sc->sc_cmds, 1246 sizeof(struct twe_cmd), 1247 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1248 1249 /* Pass notification to upper layers. */ 1250 if (ccb->ccb_tx.tx_handler != NULL) 1251 (*ccb->ccb_tx.tx_handler)(ccb, 1252 ccb->ccb_cmd->tc_status != 0 ? EIO : 0); 1253 } 1254 1255 /* If any commands have completed, run the software queue. */ 1256 if (found) 1257 twe_ccb_enqueue(sc, NULL); 1258 } 1259 1260 /* 1261 * Wait for `status' to be set in the controller status register. Return 1262 * zero if found, non-zero if the operation timed out. 1263 */ 1264 static int 1265 twe_status_wait(struct twe_softc *sc, u_int32_t status, int timo) 1266 { 1267 1268 for (timo *= 10; timo != 0; timo--) { 1269 if ((twe_inl(sc, TWE_REG_STS) & status) == status) 1270 break; 1271 delay(100000); 1272 } 1273 1274 return (timo == 0); 1275 } 1276 1277 /* 1278 * Complain if the status bits aren't what we expect. 1279 */ 1280 static int 1281 twe_status_check(struct twe_softc *sc, u_int status) 1282 { 1283 int rv; 1284 1285 rv = 0; 1286 1287 if ((status & TWE_STS_EXPECTED_BITS) != TWE_STS_EXPECTED_BITS) { 1288 printf("%s: missing status bits: 0x%08x\n", sc->sc_dv.dv_xname, 1289 status & ~TWE_STS_EXPECTED_BITS); 1290 rv = -1; 1291 } 1292 1293 if ((status & TWE_STS_UNEXPECTED_BITS) != 0) { 1294 printf("%s: unexpected status bits: 0x%08x\n", 1295 sc->sc_dv.dv_xname, status & TWE_STS_UNEXPECTED_BITS); 1296 rv = -1; 1297 } 1298 1299 return (rv); 1300 } 1301 1302 /* 1303 * Allocate and initialise a CCB. 1304 */ 1305 static __inline void 1306 twe_ccb_init(struct twe_softc *sc, struct twe_ccb *ccb, int flags) 1307 { 1308 struct twe_cmd *tc; 1309 1310 ccb->ccb_tx.tx_handler = NULL; 1311 ccb->ccb_flags = flags; 1312 tc = ccb->ccb_cmd; 1313 tc->tc_status = 0; 1314 tc->tc_flags = 0; 1315 tc->tc_cmdid = ccb->ccb_cmdid; 1316 } 1317 1318 struct twe_ccb * 1319 twe_ccb_alloc(struct twe_softc *sc, int flags) 1320 { 1321 struct twe_ccb *ccb; 1322 int s; 1323 1324 s = splbio(); 1325 if (__predict_false((flags & TWE_CCB_AEN) != 0)) { 1326 /* Use the reserved CCB. */ 1327 ccb = sc->sc_ccbs; 1328 } else { 1329 /* Allocate a CCB and command block. */ 1330 if (__predict_false((ccb = 1331 SLIST_FIRST(&sc->sc_ccb_freelist)) == NULL)) { 1332 splx(s); 1333 return (NULL); 1334 } 1335 SLIST_REMOVE_HEAD(&sc->sc_ccb_freelist, ccb_chain.slist); 1336 } 1337 #ifdef DIAGNOSTIC 1338 if ((long)(ccb - sc->sc_ccbs) == 0 && (flags & TWE_CCB_AEN) == 0) 1339 panic("twe_ccb_alloc: got reserved CCB for non-AEN"); 1340 if ((ccb->ccb_flags & TWE_CCB_ALLOCED) != 0) 1341 panic("twe_ccb_alloc: CCB %ld already allocated", 1342 (long)(ccb - sc->sc_ccbs)); 1343 flags |= TWE_CCB_ALLOCED; 1344 #endif 1345 splx(s); 1346 1347 twe_ccb_init(sc, ccb, flags); 1348 return (ccb); 1349 } 1350 1351 struct twe_ccb * 1352 twe_ccb_alloc_wait(struct twe_softc *sc, int flags) 1353 { 1354 struct twe_ccb *ccb; 1355 int s; 1356 1357 KASSERT((flags & TWE_CCB_AEN) == 0); 1358 1359 s = splbio(); 1360 while (__predict_false((ccb = 1361 SLIST_FIRST(&sc->sc_ccb_freelist)) == NULL)) { 1362 sc->sc_flags |= TWEF_WAIT_CCB; 1363 (void) tsleep(&sc->sc_ccb_freelist, PRIBIO, "tweccb", 0); 1364 } 1365 SLIST_REMOVE_HEAD(&sc->sc_ccb_freelist, ccb_chain.slist); 1366 #ifdef DIAGNOSTIC 1367 if ((ccb->ccb_flags & TWE_CCB_ALLOCED) != 0) 1368 panic("twe_ccb_alloc_wait: CCB %ld already allocated", 1369 (long)(ccb - sc->sc_ccbs)); 1370 flags |= TWE_CCB_ALLOCED; 1371 #endif 1372 splx(s); 1373 1374 twe_ccb_init(sc, ccb, flags); 1375 return (ccb); 1376 } 1377 1378 /* 1379 * Free a CCB. 1380 */ 1381 void 1382 twe_ccb_free(struct twe_softc *sc, struct twe_ccb *ccb) 1383 { 1384 int s; 1385 1386 s = splbio(); 1387 if ((ccb->ccb_flags & TWE_CCB_AEN) == 0) { 1388 SLIST_INSERT_HEAD(&sc->sc_ccb_freelist, ccb, ccb_chain.slist); 1389 if (__predict_false((sc->sc_flags & TWEF_WAIT_CCB) != 0)) { 1390 sc->sc_flags &= ~TWEF_WAIT_CCB; 1391 wakeup(&sc->sc_ccb_freelist); 1392 } 1393 } 1394 ccb->ccb_flags = 0; 1395 splx(s); 1396 } 1397 1398 /* 1399 * Map the specified CCB's command block and data buffer (if any) into 1400 * controller visible space. Perform DMA synchronisation. 1401 */ 1402 int 1403 twe_ccb_map(struct twe_softc *sc, struct twe_ccb *ccb) 1404 { 1405 struct twe_cmd *tc; 1406 int flags, nsegs, i, s, rv; 1407 void *data; 1408 1409 /* 1410 * The data as a whole must be 512-byte aligned. 1411 */ 1412 if (((u_long)ccb->ccb_data & (TWE_ALIGNMENT - 1)) != 0) { 1413 s = splvm(); 1414 /* XXX */ 1415 ccb->ccb_abuf = uvm_km_kmemalloc(kmem_map, NULL, 1416 ccb->ccb_datasize, UVM_KMF_NOWAIT); 1417 splx(s); 1418 data = (void *)ccb->ccb_abuf; 1419 if ((ccb->ccb_flags & TWE_CCB_DATA_OUT) != 0) 1420 memcpy(data, ccb->ccb_data, ccb->ccb_datasize); 1421 } else { 1422 ccb->ccb_abuf = (vaddr_t)0; 1423 data = ccb->ccb_data; 1424 } 1425 1426 /* 1427 * Map the data buffer into bus space and build the S/G list. 1428 */ 1429 rv = bus_dmamap_load(sc->sc_dmat, ccb->ccb_dmamap_xfer, data, 1430 ccb->ccb_datasize, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING | 1431 ((ccb->ccb_flags & TWE_CCB_DATA_IN) ? 1432 BUS_DMA_READ : BUS_DMA_WRITE)); 1433 if (rv != 0) { 1434 if (ccb->ccb_abuf != (vaddr_t)0) { 1435 s = splvm(); 1436 /* XXX */ 1437 uvm_km_free(kmem_map, ccb->ccb_abuf, 1438 ccb->ccb_datasize); 1439 splx(s); 1440 } 1441 return (rv); 1442 } 1443 1444 nsegs = ccb->ccb_dmamap_xfer->dm_nsegs; 1445 tc = ccb->ccb_cmd; 1446 tc->tc_size += 2 * nsegs; 1447 1448 /* The location of the S/G list is dependant upon command type. */ 1449 switch (tc->tc_opcode >> 5) { 1450 case 2: 1451 for (i = 0; i < nsegs; i++) { 1452 tc->tc_args.param.sgl[i].tsg_address = 1453 htole32(ccb->ccb_dmamap_xfer->dm_segs[i].ds_addr); 1454 tc->tc_args.param.sgl[i].tsg_length = 1455 htole32(ccb->ccb_dmamap_xfer->dm_segs[i].ds_len); 1456 } 1457 /* XXX Needed? */ 1458 for (; i < TWE_SG_SIZE; i++) { 1459 tc->tc_args.param.sgl[i].tsg_address = 0; 1460 tc->tc_args.param.sgl[i].tsg_length = 0; 1461 } 1462 break; 1463 case 3: 1464 for (i = 0; i < nsegs; i++) { 1465 tc->tc_args.io.sgl[i].tsg_address = 1466 htole32(ccb->ccb_dmamap_xfer->dm_segs[i].ds_addr); 1467 tc->tc_args.io.sgl[i].tsg_length = 1468 htole32(ccb->ccb_dmamap_xfer->dm_segs[i].ds_len); 1469 } 1470 /* XXX Needed? */ 1471 for (; i < TWE_SG_SIZE; i++) { 1472 tc->tc_args.io.sgl[i].tsg_address = 0; 1473 tc->tc_args.io.sgl[i].tsg_length = 0; 1474 } 1475 break; 1476 #ifdef DEBUG 1477 default: 1478 panic("twe_ccb_map: oops"); 1479 #endif 1480 } 1481 1482 if ((ccb->ccb_flags & TWE_CCB_DATA_IN) != 0) 1483 flags = BUS_DMASYNC_PREREAD; 1484 else 1485 flags = 0; 1486 if ((ccb->ccb_flags & TWE_CCB_DATA_OUT) != 0) 1487 flags |= BUS_DMASYNC_PREWRITE; 1488 1489 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap_xfer, 0, 1490 ccb->ccb_datasize, flags); 1491 return (0); 1492 } 1493 1494 /* 1495 * Unmap the specified CCB's command block and data buffer (if any) and 1496 * perform DMA synchronisation. 1497 */ 1498 void 1499 twe_ccb_unmap(struct twe_softc *sc, struct twe_ccb *ccb) 1500 { 1501 int flags, s; 1502 1503 if ((ccb->ccb_flags & TWE_CCB_DATA_IN) != 0) 1504 flags = BUS_DMASYNC_POSTREAD; 1505 else 1506 flags = 0; 1507 if ((ccb->ccb_flags & TWE_CCB_DATA_OUT) != 0) 1508 flags |= BUS_DMASYNC_POSTWRITE; 1509 1510 bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap_xfer, 0, 1511 ccb->ccb_datasize, flags); 1512 bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap_xfer); 1513 1514 if (ccb->ccb_abuf != (vaddr_t)0) { 1515 if ((ccb->ccb_flags & TWE_CCB_DATA_IN) != 0) 1516 memcpy(ccb->ccb_data, (void *)ccb->ccb_abuf, 1517 ccb->ccb_datasize); 1518 s = splvm(); 1519 /* XXX */ 1520 uvm_km_free(kmem_map, ccb->ccb_abuf, ccb->ccb_datasize); 1521 splx(s); 1522 } 1523 } 1524 1525 /* 1526 * Submit a command to the controller and poll on completion. Return 1527 * non-zero on timeout (but don't check status, as some command types don't 1528 * return status). Must be called with interrupts blocked. 1529 */ 1530 int 1531 twe_ccb_poll(struct twe_softc *sc, struct twe_ccb *ccb, int timo) 1532 { 1533 int rv; 1534 1535 if ((rv = twe_ccb_submit(sc, ccb)) != 0) 1536 return (rv); 1537 1538 for (timo *= 1000; timo != 0; timo--) { 1539 twe_poll(sc); 1540 if ((ccb->ccb_flags & TWE_CCB_COMPLETE) != 0) 1541 break; 1542 DELAY(100); 1543 } 1544 1545 return (timo == 0); 1546 } 1547 1548 /* 1549 * If a CCB is specified, enqueue it. Pull CCBs off the software queue in 1550 * the order that they were enqueued and try to submit their command blocks 1551 * to the controller for execution. 1552 */ 1553 void 1554 twe_ccb_enqueue(struct twe_softc *sc, struct twe_ccb *ccb) 1555 { 1556 int s; 1557 1558 s = splbio(); 1559 1560 if (ccb != NULL) 1561 SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_queue, ccb, ccb_chain.simpleq); 1562 1563 while ((ccb = SIMPLEQ_FIRST(&sc->sc_ccb_queue)) != NULL) { 1564 if (twe_ccb_submit(sc, ccb)) 1565 break; 1566 SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_queue, ccb_chain.simpleq); 1567 } 1568 1569 splx(s); 1570 } 1571 1572 /* 1573 * Submit the command block associated with the specified CCB to the 1574 * controller for execution. Must be called with interrupts blocked. 1575 */ 1576 int 1577 twe_ccb_submit(struct twe_softc *sc, struct twe_ccb *ccb) 1578 { 1579 bus_addr_t pa; 1580 int rv; 1581 u_int status; 1582 1583 /* Check to see if we can post a command. */ 1584 status = twe_inl(sc, TWE_REG_STS); 1585 twe_status_check(sc, status); 1586 1587 if ((status & TWE_STS_CMD_QUEUE_FULL) == 0) { 1588 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 1589 (caddr_t)ccb->ccb_cmd - sc->sc_cmds, sizeof(struct twe_cmd), 1590 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1591 #ifdef DIAGNOSTIC 1592 if ((ccb->ccb_flags & TWE_CCB_ALLOCED) == 0) 1593 panic("%s: CCB %ld not ALLOCED\n", 1594 sc->sc_dv.dv_xname, (long)(ccb - sc->sc_ccbs)); 1595 #endif 1596 ccb->ccb_flags |= TWE_CCB_ACTIVE; 1597 pa = sc->sc_cmds_paddr + 1598 ccb->ccb_cmdid * sizeof(struct twe_cmd); 1599 twe_outl(sc, TWE_REG_CMD_QUEUE, (u_int32_t)pa); 1600 rv = 0; 1601 } else 1602 rv = EBUSY; 1603 1604 return (rv); 1605 } 1606 1607 1608 /* 1609 * Accept an open operation on the control device. 1610 */ 1611 int 1612 tweopen(dev_t dev, int flag, int mode, struct proc *p) 1613 { 1614 struct twe_softc *twe; 1615 1616 if ((twe = device_lookup(&twe_cd, minor(dev))) == NULL) 1617 return (ENXIO); 1618 if ((twe->sc_flags & TWEF_OPEN) != 0) 1619 return (EBUSY); 1620 1621 twe->sc_flags |= TWEF_OPEN; 1622 return (0); 1623 } 1624 1625 /* 1626 * Accept the last close on the control device. 1627 */ 1628 int 1629 tweclose(dev_t dev, int flag, int mode, struct proc *p) 1630 { 1631 struct twe_softc *twe; 1632 1633 twe = device_lookup(&twe_cd, minor(dev)); 1634 twe->sc_flags &= ~TWEF_OPEN; 1635 return (0); 1636 } 1637 1638 static void 1639 twe_tweio_command_handler(struct twe_ccb *ccb, int error) 1640 { 1641 1642 /* Just wake up the sleeper. */ 1643 wakeup(ccb); 1644 } 1645 1646 /* 1647 * Handle control operations. 1648 */ 1649 int 1650 tweioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 1651 { 1652 struct twe_softc *twe; 1653 struct twe_ccb *ccb; 1654 struct twe_param *param; 1655 struct twe_usercommand *tu; 1656 struct twe_paramcommand *tp; 1657 struct twe_drivecommand *td; 1658 void *pdata = NULL; 1659 int s, error = 0; 1660 u_int8_t cmdid; 1661 1662 if (securelevel >= 2) 1663 return (EPERM); 1664 1665 twe = device_lookup(&twe_cd, minor(dev)); 1666 tu = (struct twe_usercommand *)data; 1667 tp = (struct twe_paramcommand *)data; 1668 td = (struct twe_drivecommand *)data; 1669 1670 /* This is intended to be compatible with the FreeBSD interface. */ 1671 switch (cmd) { 1672 case TWEIO_COMMAND: 1673 /* XXX mutex */ 1674 if (tu->tu_size > 0) { 1675 /* 1676 * XXX Handle > TWE_SECTOR_SIZE? Let's see if 1677 * it's really necessary, first. 1678 */ 1679 if (tu->tu_size > TWE_SECTOR_SIZE) { 1680 #ifdef TWE_DEBUG 1681 printf("%s: TWEIO_COMMAND: tu_size = %d\n", 1682 twe->sc_dv.dv_xname, tu->tu_size); 1683 #endif 1684 return EINVAL; 1685 } 1686 pdata = malloc(TWE_SECTOR_SIZE, M_DEVBUF, M_WAITOK); 1687 error = copyin(tu->tu_data, pdata, tu->tu_size); 1688 if (error != 0) 1689 goto done; 1690 ccb = twe_ccb_alloc_wait(twe, 1691 TWE_CCB_DATA_IN | TWE_CCB_DATA_OUT); 1692 KASSERT(ccb != NULL); 1693 ccb->ccb_data = pdata; 1694 ccb->ccb_datasize = TWE_SECTOR_SIZE; 1695 } else { 1696 ccb = twe_ccb_alloc_wait(twe, 0); 1697 KASSERT(ccb != NULL); 1698 } 1699 1700 ccb->ccb_tx.tx_handler = twe_tweio_command_handler; 1701 ccb->ccb_tx.tx_context = NULL; 1702 ccb->ccb_tx.tx_dv = &twe->sc_dv; 1703 1704 cmdid = ccb->ccb_cmdid; 1705 memcpy(ccb->ccb_cmd, &tu->tu_cmd, sizeof(struct twe_cmd)); 1706 ccb->ccb_cmd->tc_cmdid = cmdid; 1707 1708 /* Map the transfer. */ 1709 if ((error = twe_ccb_map(twe, ccb)) != 0) { 1710 twe_ccb_free(twe, ccb); 1711 goto done; 1712 } 1713 1714 /* Submit the command and wait up to 1 minute. */ 1715 error = 0; 1716 twe_ccb_enqueue(twe, ccb); 1717 s = splbio(); 1718 while ((ccb->ccb_flags & TWE_CCB_COMPLETE) == 0) 1719 if ((error = tsleep(ccb, PRIBIO, "tweioctl", 1720 60 * hz)) != 0) 1721 break; 1722 splx(s); 1723 1724 /* Copy the command back to the ioctl argument. */ 1725 memcpy(&tu->tu_cmd, ccb->ccb_cmd, sizeof(struct twe_cmd)); 1726 #ifdef TWE_DEBUG 1727 printf("%s: TWEIO_COMMAND: tc_opcode = 0x%02x, " 1728 "tc_status = 0x%02x\n", twe->sc_dv.dv_xname, 1729 tu->tu_cmd.tc_opcode, tu->tu_cmd.tc_status); 1730 #endif 1731 1732 s = splbio(); 1733 twe_ccb_free(twe, ccb); 1734 splx(s); 1735 1736 if (tu->tu_size > 0) 1737 error = copyout(pdata, tu->tu_data, tu->tu_size); 1738 goto done; 1739 1740 case TWEIO_STATS: 1741 return (ENOENT); 1742 1743 case TWEIO_AEN_POLL: 1744 s = splbio(); 1745 *(u_int *)data = twe_aen_dequeue(twe); 1746 splx(s); 1747 return (0); 1748 1749 case TWEIO_AEN_WAIT: 1750 s = splbio(); 1751 while ((*(u_int *)data = 1752 twe_aen_dequeue(twe)) == TWE_AEN_QUEUE_EMPTY) { 1753 twe->sc_flags |= TWEF_AENQ_WAIT; 1754 error = tsleep(&twe->sc_aen_queue, PRIBIO | PCATCH, 1755 "tweaen", 0); 1756 if (error == EINTR) { 1757 splx(s); 1758 return (error); 1759 } 1760 } 1761 splx(s); 1762 return (0); 1763 1764 case TWEIO_GET_PARAM: 1765 error = twe_param_get(twe, tp->tp_table_id, tp->tp_param_id, 1766 tp->tp_size, 0, ¶m); 1767 if (error != 0) 1768 return (error); 1769 if (param->tp_param_size > tp->tp_size) { 1770 error = EFAULT; 1771 goto done; 1772 } 1773 error = copyout(param->tp_data, tp->tp_data, 1774 param->tp_param_size); 1775 goto done; 1776 1777 case TWEIO_SET_PARAM: 1778 pdata = malloc(tp->tp_size, M_DEVBUF, M_WAITOK); 1779 if ((error = copyin(tp->tp_data, pdata, tp->tp_size)) != 0) 1780 goto done; 1781 error = twe_param_set(twe, tp->tp_table_id, tp->tp_param_id, 1782 tp->tp_size, pdata); 1783 goto done; 1784 1785 case TWEIO_RESET: 1786 s = splbio(); 1787 twe_reset(twe); 1788 splx(s); 1789 return (0); 1790 1791 case TWEIO_ADD_UNIT: 1792 /* XXX mutex */ 1793 return (twe_add_unit(twe, td->td_unit)); 1794 1795 case TWEIO_DEL_UNIT: 1796 /* XXX mutex */ 1797 return (twe_del_unit(twe, td->td_unit)); 1798 1799 default: 1800 return EINVAL; 1801 } 1802 done: 1803 if (pdata) 1804 free(pdata, M_DEVBUF); 1805 return error; 1806 } 1807 1808 /* 1809 * Print some information about the controller 1810 */ 1811 static void 1812 twe_describe_controller(struct twe_softc *sc) 1813 { 1814 struct twe_param *p[6]; 1815 int i, rv = 0; 1816 uint32_t dsize; 1817 uint8_t ports; 1818 1819 /* get the port count */ 1820 rv |= twe_param_get_1(sc, TWE_PARAM_CONTROLLER, 1821 TWE_PARAM_CONTROLLER_PortCount, &ports); 1822 1823 /* get version strings */ 1824 rv |= twe_param_get(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_Mon, 1825 16, NULL, &p[0]); 1826 rv |= twe_param_get(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_FW, 1827 16, NULL, &p[1]); 1828 rv |= twe_param_get(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_BIOS, 1829 16, NULL, &p[2]); 1830 rv |= twe_param_get(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_PCB, 1831 8, NULL, &p[3]); 1832 rv |= twe_param_get(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_ATA, 1833 8, NULL, &p[4]); 1834 rv |= twe_param_get(sc, TWE_PARAM_VERSION, TWE_PARAM_VERSION_PCI, 1835 8, NULL, &p[5]); 1836 1837 if (rv) { 1838 /* some error occurred */ 1839 aprint_error("%s: failed to fetch version information\n", 1840 sc->sc_dv.dv_xname); 1841 return; 1842 } 1843 1844 aprint_normal("%s: %d ports, Firmware %.16s, BIOS %.16s\n", 1845 sc->sc_dv.dv_xname, ports, 1846 p[1]->tp_data, p[2]->tp_data); 1847 1848 aprint_verbose("%s: Monitor %.16s, PCB %.8s, Achip %.8s, Pchip %.8s\n", 1849 sc->sc_dv.dv_xname, 1850 p[0]->tp_data, p[3]->tp_data, 1851 p[4]->tp_data, p[5]->tp_data); 1852 1853 free(p[0], M_DEVBUF); 1854 free(p[1], M_DEVBUF); 1855 free(p[2], M_DEVBUF); 1856 free(p[3], M_DEVBUF); 1857 free(p[4], M_DEVBUF); 1858 free(p[5], M_DEVBUF); 1859 1860 rv = twe_param_get(sc, TWE_PARAM_DRIVESUMMARY, 1861 TWE_PARAM_DRIVESUMMARY_Status, 16, NULL, &p[0]); 1862 if (rv) { 1863 aprint_error("%s: failed to get drive status summary\n", 1864 sc->sc_dv.dv_xname); 1865 return; 1866 } 1867 for (i = 0; i < ports; i++) { 1868 if (p[0]->tp_data[i] != TWE_PARAM_DRIVESTATUS_Present) 1869 continue; 1870 rv = twe_param_get_4(sc, TWE_PARAM_DRIVEINFO + i, 1871 TWE_PARAM_DRIVEINFO_Size, &dsize); 1872 if (rv) { 1873 aprint_error( 1874 "%s: unable to get drive size for port %d\n", 1875 sc->sc_dv.dv_xname, i); 1876 continue; 1877 } 1878 rv = twe_param_get(sc, TWE_PARAM_DRIVEINFO + i, 1879 TWE_PARAM_DRIVEINFO_Model, 40, NULL, &p[1]); 1880 if (rv) { 1881 aprint_error( 1882 "%s: unable to get drive model for port %d\n", 1883 sc->sc_dv.dv_xname, i); 1884 continue; 1885 } 1886 aprint_verbose("%s: port %d: %.40s %d MB\n", sc->sc_dv.dv_xname, 1887 i, p[1]->tp_data, dsize / 2048); 1888 free(p[1], M_DEVBUF); 1889 } 1890 free(p[0], M_DEVBUF); 1891 } 1892