1 /* $OpenBSD: scsiconf.c,v 1.182 2011/09/22 21:36:00 jsing Exp $ */ 2 /* $NetBSD: scsiconf.c,v 1.57 1996/05/02 01:09:01 neil Exp $ */ 3 4 /* 5 * Copyright (c) 1994 Charles Hannum. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Charles Hannum. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Originally written by Julian Elischer (julian@tfs.com) 35 * for TRW Financial Systems for use under the MACH(2.5) operating system. 36 * 37 * TRW Financial Systems, in accordance with their agreement with Carnegie 38 * Mellon University, makes this software available to CMU to distribute 39 * or use in any manner that they see fit as long as this message is kept with 40 * the software. For this reason TFS also grants any other persons or 41 * organisations permission to use or modify this software. 42 * 43 * TFS supplies this software to be publicly redistributed 44 * on the understanding that TFS is not responsible for the correct 45 * functioning of this software in any circumstances. 46 * 47 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 48 */ 49 50 #include "bio.h" 51 #include "mpath.h" 52 53 #include <sys/types.h> 54 #include <sys/param.h> 55 #include <sys/systm.h> 56 #include <sys/malloc.h> 57 #include <sys/pool.h> 58 #include <sys/device.h> 59 #include <sys/buf.h> 60 #include <sys/lock.h> 61 62 #include <scsi/scsi_all.h> 63 #include <scsi/scsiconf.h> 64 #include <scsi/mpathvar.h> 65 66 #if NBIO > 0 67 #include <sys/ioctl.h> 68 #include <sys/scsiio.h> 69 #include <dev/biovar.h> 70 #endif 71 72 /* 73 * Declarations 74 */ 75 int scsi_probedev(struct scsibus_softc *, int, int); 76 77 void scsi_devid(struct scsi_link *); 78 int scsi_devid_pg80(struct scsi_link *); 79 int scsi_devid_pg83(struct scsi_link *); 80 81 int scsibusmatch(struct device *, void *, void *); 82 void scsibusattach(struct device *, struct device *, void *); 83 int scsibusactivate(struct device *, int); 84 int scsibusdetach(struct device *, int); 85 86 int scsibussubmatch(struct device *, void *, void *); 87 88 #if NBIO > 0 89 int scsibus_bioctl(struct device *, u_long, caddr_t); 90 #endif 91 92 struct cfattach scsibus_ca = { 93 sizeof(struct scsibus_softc), scsibusmatch, scsibusattach, 94 scsibusdetach, scsibusactivate 95 }; 96 97 struct cfdriver scsibus_cd = { 98 NULL, "scsibus", DV_DULL 99 }; 100 101 #ifdef SCSIDEBUG 102 u_int32_t scsidebug_buses = SCSIDEBUG_BUSES; 103 u_int32_t scsidebug_targets = SCSIDEBUG_TARGETS; 104 u_int32_t scsidebug_luns = SCSIDEBUG_LUNS; 105 int scsidebug_level = SCSIDEBUG_LEVEL; 106 #endif 107 108 int scsi_autoconf = SCSI_AUTOCONF; 109 110 int scsibusprint(void *, const char *); 111 void scsibus_printlink(struct scsi_link *); 112 113 int scsi_activate_bus(struct scsibus_softc *, int); 114 int scsi_activate_target(struct scsibus_softc *, int, int); 115 int scsi_activate_lun(struct scsibus_softc *, int, int, int); 116 117 const u_int8_t version_to_spc [] = { 118 0, /* 0x00: The device does not claim conformance to any standard. */ 119 1, /* 0x01: (Obsolete) SCSI-1 in olden times. */ 120 2, /* 0x02: (Obsolete) SCSI-2 in olden times. */ 121 3, /* 0x03: The device complies to ANSI INCITS 301-1997 (SPC-3). */ 122 2, /* 0x04: The device complies to ANSI INCITS 351-2001 (SPC-2). */ 123 3, /* 0x05: The device complies to ANSI INCITS 408-2005 (SPC-3). */ 124 4, /* 0x06: The device complies to SPC-4. */ 125 0, /* 0x07: RESERVED. */ 126 }; 127 128 int 129 scsiprint(void *aux, const char *pnp) 130 { 131 /* only "scsibus"es can attach to "scsi"s; easy. */ 132 if (pnp) 133 printf("scsibus at %s", pnp); 134 135 return (UNCONF); 136 } 137 138 int 139 scsibusmatch(struct device *parent, void *match, void *aux) 140 { 141 return (1); 142 } 143 144 /* 145 * The routine called by the adapter boards to get all their 146 * devices configured in. 147 */ 148 void 149 scsibusattach(struct device *parent, struct device *self, void *aux) 150 { 151 struct scsibus_softc *sb = (struct scsibus_softc *)self; 152 struct scsibus_attach_args *saa = aux; 153 struct scsi_link *sc_link_proto = saa->saa_sc_link; 154 155 if (!cold) 156 scsi_autoconf = 0; 157 158 sc_link_proto->bus = sb; 159 sc_link_proto->scsibus = sb->sc_dev.dv_unit; 160 sb->adapter_link = sc_link_proto; 161 if (sb->adapter_link->adapter_buswidth == 0) 162 sb->adapter_link->adapter_buswidth = 8; 163 sb->sc_buswidth = sb->adapter_link->adapter_buswidth; 164 if (sb->adapter_link->luns == 0) 165 sb->adapter_link->luns = 8; 166 167 printf(": %d targets", sb->sc_buswidth); 168 if (sb->adapter_link->adapter_target < sb->sc_buswidth) 169 printf(", initiator %d", sb->adapter_link->adapter_target); 170 if (sb->adapter_link->port_wwn != 0x0 && 171 sb->adapter_link->node_wwn != 0x0) { 172 printf(", WWPN %016llx, WWNN %016llx", 173 sb->adapter_link->port_wwn, sb->adapter_link->node_wwn); 174 } 175 printf("\n"); 176 177 /* Initialize shared data. */ 178 scsi_init(); 179 180 SLIST_INIT(&sb->sc_link); 181 182 #if NBIO > 0 183 if (bio_register(&sb->sc_dev, scsibus_bioctl) != 0) 184 printf("%s: unable to register bio\n", sb->sc_dev.dv_xname); 185 #endif 186 187 scsi_probe_bus(sb); 188 } 189 190 int 191 scsibusactivate(struct device *dev, int act) 192 { 193 struct scsibus_softc *sc = (struct scsibus_softc *)dev; 194 195 return scsi_activate(sc, -1, -1, act); 196 } 197 198 int 199 scsi_activate(struct scsibus_softc *sc, int target, int lun, int act) 200 { 201 if (target == -1 && lun == -1) 202 return scsi_activate_bus(sc, act); 203 204 if (target == -1) 205 return 0; 206 207 if (lun == -1) 208 return scsi_activate_target(sc, target, act); 209 210 return scsi_activate_lun(sc, target, lun, act); 211 } 212 213 int 214 scsi_activate_bus(struct scsibus_softc *sc, int act) 215 { 216 int target, rv = 0, r; 217 218 for (target = 0; target < sc->sc_buswidth; target++) { 219 r = scsi_activate_target(sc, target, act); 220 if (r) 221 rv = r; 222 } 223 return (rv); 224 } 225 226 int 227 scsi_activate_target(struct scsibus_softc *sc, int target, int act) 228 { 229 int lun, rv = 0, r; 230 231 for (lun = 0; lun < sc->adapter_link->luns; lun++) { 232 r = scsi_activate_lun(sc, target, lun, act); 233 if (r) 234 rv = r; 235 } 236 return (rv); 237 } 238 239 int 240 scsi_activate_lun(struct scsibus_softc *sc, int target, int lun, int act) 241 { 242 struct scsi_link *link; 243 struct device *dev; 244 245 link = scsi_get_link(sc, target, lun); 246 if (link == NULL) 247 return (0); 248 249 dev = link->device_softc; 250 switch (act) { 251 case DVACT_QUIESCE: 252 case DVACT_SUSPEND: 253 case DVACT_RESUME: 254 config_suspend(dev, act); 255 break; 256 case DVACT_DEACTIVATE: 257 atomic_setbits_int(&link->state, SDEV_S_DYING); 258 config_deactivate(dev); 259 break; 260 default: 261 break; 262 } 263 264 return (0); 265 } 266 267 int 268 scsibusdetach(struct device *dev, int type) 269 { 270 struct scsibus_softc *sb = (struct scsibus_softc *)dev; 271 int error; 272 273 #if NBIO > 0 274 bio_unregister(&sb->sc_dev); 275 #endif 276 277 error = scsi_detach_bus(sb, type); 278 if (error != 0) 279 return (error); 280 281 KASSERT(SLIST_EMPTY(&sb->sc_link)); 282 283 return (0); 284 } 285 286 int 287 scsibussubmatch(struct device *parent, void *match, void *aux) 288 { 289 struct cfdata *cf = match; 290 struct scsi_attach_args *sa = aux; 291 struct scsi_link *sc_link = sa->sa_sc_link; 292 293 if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != sc_link->target) 294 return (0); 295 if (cf->cf_loc[1] != -1 && cf->cf_loc[1] != sc_link->lun) 296 return (0); 297 298 return ((*cf->cf_attach->ca_match)(parent, match, aux)); 299 } 300 301 #if NBIO > 0 302 int 303 scsibus_bioctl(struct device *dev, u_long cmd, caddr_t addr) 304 { 305 struct scsibus_softc *sc = (struct scsibus_softc *)dev; 306 struct sbioc_device *sdev; 307 308 switch (cmd) { 309 case SBIOCPROBE: 310 sdev = (struct sbioc_device *)addr; 311 312 if (sdev->sd_target == -1 && sdev->sd_lun == -1) 313 return (scsi_probe_bus(sc)); 314 315 /* specific lun and wildcard target is bad */ 316 if (sdev->sd_target == -1) 317 return (EINVAL); 318 319 if (sdev->sd_lun == -1) 320 return (scsi_probe_target(sc, sdev->sd_target)); 321 322 return (scsi_probe_lun(sc, sdev->sd_target, sdev->sd_lun)); 323 324 case SBIOCDETACH: 325 sdev = (struct sbioc_device *)addr; 326 327 if (sdev->sd_target == -1 && sdev->sd_lun == -1) 328 return (scsi_detach_bus(sc, 0)); 329 330 if (sdev->sd_target == -1) 331 return (EINVAL); 332 333 if (sdev->sd_lun == -1) 334 return (scsi_detach_target(sc, sdev->sd_target, 0)); 335 336 return (scsi_detach_lun(sc, sdev->sd_target, sdev->sd_lun, 0)); 337 338 default: 339 return (ENOTTY); 340 } 341 } 342 #endif 343 344 int 345 scsi_probe_bus(struct scsibus_softc *sc) 346 { 347 struct scsi_link *alink = sc->adapter_link; 348 int i; 349 350 for (i = 0; i < alink->adapter_buswidth; i++) 351 scsi_probe_target(sc, i); 352 353 return (0); 354 } 355 356 int 357 scsi_probe_target(struct scsibus_softc *sc, int target) 358 { 359 struct scsi_link *alink = sc->adapter_link; 360 struct scsi_link *link; 361 struct scsi_report_luns_data *report; 362 int i, nluns, lun; 363 364 if (scsi_probe_lun(sc, target, 0) == EINVAL) 365 return (EINVAL); 366 367 link = scsi_get_link(sc, target, 0); 368 if (link == NULL) 369 return (ENXIO); 370 371 if ((link->flags & (SDEV_UMASS | SDEV_ATAPI)) == 0 && 372 SCSISPC(link->inqdata.version) > 2) { 373 report = dma_alloc(sizeof(*report), PR_WAITOK); 374 if (report == NULL) 375 goto dumbscan; 376 377 if (scsi_report_luns(link, REPORT_NORMAL, report, 378 sizeof(*report), scsi_autoconf | SCSI_SILENT | 379 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY | 380 SCSI_IGNORE_MEDIA_CHANGE, 10000) != 0) { 381 dma_free(report, sizeof(*report)); 382 goto dumbscan; 383 } 384 385 /* 386 * XXX In theory we should check if data is full, which 387 * would indicate it needs to be enlarged and REPORT 388 * LUNS tried again. Solaris tries up to 3 times with 389 * larger sizes for data. 390 */ 391 nluns = _4btol(report->length) / RPL_LUNDATA_SIZE; 392 for (i = 0; i < nluns; i++) { 393 if (report->luns[i].lundata[0] != 0) 394 continue; 395 lun = report->luns[i].lundata[RPL_LUNDATA_T0LUN]; 396 if (lun == 0) 397 continue; 398 399 /* Probe the provided LUN. Don't check LUN 0. */ 400 scsi_remove_link(sc, link); 401 scsi_probe_lun(sc, target, lun); 402 scsi_add_link(sc, link); 403 } 404 405 dma_free(report, sizeof(*report)); 406 return (0); 407 } 408 409 dumbscan: 410 for (i = 1; i < alink->luns; i++) { 411 if (scsi_probe_lun(sc, target, i) == EINVAL) 412 break; 413 } 414 415 return (0); 416 } 417 418 int 419 scsi_probe_lun(struct scsibus_softc *sc, int target, int lun) 420 { 421 struct scsi_link *alink = sc->adapter_link; 422 423 if (target < 0 || target >= alink->adapter_buswidth || 424 target == alink->adapter_target || 425 lun < 0 || lun >= alink->luns) 426 return (ENXIO); 427 428 return (scsi_probedev(sc, target, lun)); 429 } 430 431 int 432 scsi_detach_bus(struct scsibus_softc *sc, int flags) 433 { 434 struct scsi_link *alink = sc->adapter_link; 435 int i, err, rv = 0; 436 437 for (i = 0; i < alink->adapter_buswidth; i++) { 438 err = scsi_detach_target(sc, i, flags); 439 if (err != 0 && err != ENXIO) 440 rv = err; 441 } 442 443 return (rv); 444 } 445 446 int 447 scsi_detach_target(struct scsibus_softc *sc, int target, int flags) 448 { 449 struct scsi_link *alink = sc->adapter_link; 450 int i, err, rv = 0; 451 452 if (target < 0 || target >= alink->adapter_buswidth || 453 target == alink->adapter_target) 454 return (ENXIO); 455 456 for (i = 0; i < alink->luns; i++) { /* nicer backwards? */ 457 if (scsi_get_link(sc, target, i) == NULL) 458 continue; 459 460 err = scsi_detach_lun(sc, target, i, flags); 461 if (err != 0 && err != ENXIO) 462 rv = err; 463 } 464 465 return (rv); 466 } 467 468 int 469 scsi_detach_lun(struct scsibus_softc *sc, int target, int lun, int flags) 470 { 471 struct scsi_link *alink = sc->adapter_link; 472 struct scsi_link *link; 473 int rv; 474 475 if (target < 0 || target >= alink->adapter_buswidth || 476 target == alink->adapter_target || 477 lun < 0 || lun >= alink->luns) 478 return (ENXIO); 479 480 link = scsi_get_link(sc, target, lun); 481 if (link == NULL) 482 return (ENXIO); 483 484 if (((flags & DETACH_FORCE) == 0) && (link->flags & SDEV_OPEN)) 485 return (EBUSY); 486 487 /* detaching a device from scsibus is a five step process... */ 488 489 /* 1. wake up processes sleeping for an xs */ 490 scsi_link_shutdown(link); 491 492 /* 2. detach the device */ 493 rv = config_detach(link->device_softc, flags); 494 495 if (rv != 0) 496 return (rv); 497 498 /* 3. if its using the openings io allocator, clean it up */ 499 if (ISSET(link->flags, SDEV_OWN_IOPL)) { 500 scsi_iopool_destroy(link->pool); 501 free(link->pool, M_DEVBUF); 502 } 503 504 /* 4. free up its state in the adapter */ 505 if (alink->adapter->dev_free != NULL) 506 alink->adapter->dev_free(link); 507 508 /* 5. free up its state in the midlayer */ 509 if (link->id != NULL) 510 devid_free(link->id); 511 scsi_remove_link(sc, link); 512 free(link, M_DEVBUF); 513 514 return (0); 515 } 516 517 struct scsi_link * 518 scsi_get_link(struct scsibus_softc *sc, int target, int lun) 519 { 520 struct scsi_link *link; 521 522 SLIST_FOREACH(link, &sc->sc_link, bus_list) 523 if (link->target == target && link->lun == lun) 524 return (link); 525 526 return (NULL); 527 } 528 529 void 530 scsi_add_link(struct scsibus_softc *sc, struct scsi_link *link) 531 { 532 SLIST_INSERT_HEAD(&sc->sc_link, link, bus_list); 533 } 534 535 void 536 scsi_remove_link(struct scsibus_softc *sc, struct scsi_link *link) 537 { 538 SLIST_REMOVE(&sc->sc_link, link, scsi_link, bus_list); 539 } 540 541 void 542 scsi_strvis(u_char *dst, u_char *src, int len) 543 { 544 u_char last; 545 546 /* Trim leading and trailing whitespace and NULs. */ 547 while (len > 0 && (src[0] == ' ' || src[0] == '\t' || src[0] == '\n' || 548 src[0] == '\0' || src[0] == 0xff)) 549 ++src, --len; 550 while (len > 0 && (src[len-1] == ' ' || src[len-1] == '\t' || 551 src[len-1] == '\n' || src[len-1] == '\0' || src[len-1] == 0xff)) 552 --len; 553 554 last = 0xff; 555 while (len > 0) { 556 switch (*src) { 557 case ' ': 558 case '\t': 559 case '\n': 560 case '\0': 561 case 0xff: 562 /* collapse whitespace and NULs to a single space */ 563 if (last != ' ') 564 *dst++ = ' '; 565 last = ' '; 566 break; 567 case '\\': 568 /* quote characters */ 569 *dst++ = '\\'; 570 *dst++ = '\\'; 571 last = '\\'; 572 break; 573 default: 574 if (*src < 0x20 || *src >= 0x80) { 575 /* non-printable characters */ 576 *dst++ = '\\'; 577 *dst++ = ((*src & 0300) >> 6) + '0'; 578 *dst++ = ((*src & 0070) >> 3) + '0'; 579 *dst++ = ((*src & 0007) >> 0) + '0'; 580 } else { 581 /* normal characters */ 582 *dst++ = *src; 583 } 584 last = *src; 585 break; 586 } 587 ++src, --len; 588 } 589 590 *dst++ = 0; 591 } 592 593 struct scsi_quirk_inquiry_pattern { 594 struct scsi_inquiry_pattern pattern; 595 u_int16_t quirks; 596 }; 597 598 const struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = { 599 {{T_CDROM, T_REMOV, 600 "PLEXTOR", "CD-ROM PX-40TS", "1.01"}, SDEV_NOSYNC}, 601 602 {{T_DIRECT, T_FIXED, 603 "MICROP ", "1588-15MBSUN0669", ""}, SDEV_AUTOSAVE}, 604 {{T_DIRECT, T_FIXED, 605 "DEC ", "RZ55 (C) DEC", ""}, SDEV_AUTOSAVE}, 606 {{T_DIRECT, T_FIXED, 607 "EMULEX ", "MD21/S2 ESDI", "A00"}, SDEV_AUTOSAVE}, 608 {{T_DIRECT, T_FIXED, 609 "IBMRAID ", "0662S", ""}, SDEV_AUTOSAVE}, 610 {{T_DIRECT, T_FIXED, 611 "IBM ", "0663H", ""}, SDEV_AUTOSAVE}, 612 {{T_DIRECT, T_FIXED, 613 "IBM", "0664", ""}, SDEV_AUTOSAVE}, 614 {{T_DIRECT, T_FIXED, 615 "IBM ", "H3171-S2", ""}, SDEV_AUTOSAVE}, 616 {{T_DIRECT, T_FIXED, 617 "IBM ", "KZ-C", ""}, SDEV_AUTOSAVE}, 618 /* Broken IBM disk */ 619 {{T_DIRECT, T_FIXED, 620 "" , "DFRSS2F", ""}, SDEV_AUTOSAVE}, 621 {{T_DIRECT, T_FIXED, 622 "QUANTUM ", "ELS85S ", ""}, SDEV_AUTOSAVE}, 623 {{T_DIRECT, T_REMOV, 624 "iomega", "jaz 1GB", ""}, SDEV_NOTAGS}, 625 {{T_DIRECT, T_FIXED, 626 "MICROP", "4421-07", ""}, SDEV_NOTAGS}, 627 {{T_DIRECT, T_FIXED, 628 "SEAGATE", "ST150176LW", "0002"}, SDEV_NOTAGS}, 629 {{T_DIRECT, T_FIXED, 630 "HP", "C3725S", ""}, SDEV_NOTAGS}, 631 {{T_DIRECT, T_FIXED, 632 "IBM", "DCAS", ""}, SDEV_NOTAGS}, 633 634 {{T_SEQUENTIAL, T_REMOV, 635 "SONY ", "SDT-5000 ", "3."}, SDEV_NOSYNC|SDEV_NOWIDE}, 636 {{T_SEQUENTIAL, T_REMOV, 637 "WangDAT ", "Model 1300 ", "02.4"}, SDEV_NOSYNC|SDEV_NOWIDE}, 638 {{T_SEQUENTIAL, T_REMOV, 639 "WangDAT ", "Model 2600 ", "01.7"}, SDEV_NOSYNC|SDEV_NOWIDE}, 640 {{T_SEQUENTIAL, T_REMOV, 641 "WangDAT ", "Model 3200 ", "02.2"}, SDEV_NOSYNC|SDEV_NOWIDE}, 642 643 /* ATAPI device quirks */ 644 {{T_CDROM, T_REMOV, 645 "CR-2801TE", "", "1.07"}, ADEV_NOSENSE}, 646 {{T_CDROM, T_REMOV, 647 "CREATIVECD3630E", "", "AC101"}, ADEV_NOSENSE}, 648 {{T_CDROM, T_REMOV, 649 "FX320S", "", "q01"}, ADEV_NOSENSE}, 650 {{T_CDROM, T_REMOV, 651 "GCD-R580B", "", "1.00"}, ADEV_LITTLETOC}, 652 {{T_CDROM, T_REMOV, 653 "MATSHITA CR-574", "", "1.02"}, ADEV_NOCAPACITY}, 654 {{T_CDROM, T_REMOV, 655 "MATSHITA CR-574", "", "1.06"}, ADEV_NOCAPACITY}, 656 {{T_CDROM, T_REMOV, 657 "Memorex CRW-2642", "", "1.0g"}, ADEV_NOSENSE}, 658 {{T_CDROM, T_REMOV, 659 "SANYO CRD-256P", "", "1.02"}, ADEV_NOCAPACITY}, 660 {{T_CDROM, T_REMOV, 661 "SANYO CRD-254P", "", "1.02"}, ADEV_NOCAPACITY}, 662 {{T_CDROM, T_REMOV, 663 "SANYO CRD-S54P", "", "1.08"}, ADEV_NOCAPACITY}, 664 {{T_CDROM, T_REMOV, 665 "CD-ROM CDR-S1", "", "1.70"}, ADEV_NOCAPACITY}, /* Sanyo */ 666 {{T_CDROM, T_REMOV, 667 "CD-ROM CDR-N16", "", "1.25"}, ADEV_NOCAPACITY}, /* Sanyo */ 668 {{T_CDROM, T_REMOV, 669 "UJDCD8730", "", "1.14"}, ADEV_NODOORLOCK}, /* Acer */ 670 }; 671 672 673 void 674 scsibus_printlink(struct scsi_link *link) 675 { 676 char vendor[33], product[65], revision[17]; 677 struct scsi_inquiry_data *inqbuf; 678 u_int8_t type; 679 int removable; 680 char *dtype = NULL, *qtype = NULL; 681 682 inqbuf = &link->inqdata; 683 684 type = inqbuf->device & SID_TYPE; 685 removable = inqbuf->dev_qual2 & SID_REMOVABLE ? 1 : 0; 686 687 /* 688 * Figure out basic device type and qualifier. 689 */ 690 switch (inqbuf->device & SID_QUAL) { 691 case SID_QUAL_LU_OK: 692 qtype = ""; 693 break; 694 695 case SID_QUAL_LU_OFFLINE: 696 qtype = " offline"; 697 break; 698 699 case SID_QUAL_RSVD: 700 panic("scsibusprint: qualifier == SID_QUAL_RSVD"); 701 case SID_QUAL_BAD_LU: 702 panic("scsibusprint: qualifier == SID_QUAL_BAD_LU"); 703 704 default: 705 qtype = ""; 706 dtype = "vendor-unique"; 707 break; 708 } 709 if (dtype == NULL) { 710 switch (type) { 711 case T_DIRECT: 712 dtype = "direct"; 713 break; 714 case T_SEQUENTIAL: 715 dtype = "sequential"; 716 break; 717 case T_PRINTER: 718 dtype = "printer"; 719 break; 720 case T_PROCESSOR: 721 dtype = "processor"; 722 break; 723 case T_CDROM: 724 dtype = "cdrom"; 725 break; 726 case T_WORM: 727 dtype = "worm"; 728 break; 729 case T_SCANNER: 730 dtype = "scanner"; 731 break; 732 case T_OPTICAL: 733 dtype = "optical"; 734 break; 735 case T_CHANGER: 736 dtype = "changer"; 737 break; 738 case T_COMM: 739 dtype = "communication"; 740 break; 741 case T_ENCLOSURE: 742 dtype = "enclosure services"; 743 break; 744 case T_RDIRECT: 745 dtype = "simplified direct"; 746 break; 747 case T_NODEVICE: 748 panic("scsibusprint: device type T_NODEVICE"); 749 default: 750 dtype = "unknown"; 751 break; 752 } 753 } 754 755 scsi_strvis(vendor, inqbuf->vendor, 8); 756 scsi_strvis(product, inqbuf->product, 16); 757 scsi_strvis(revision, inqbuf->revision, 4); 758 759 printf(" targ %d lun %d: <%s, %s, %s> ", link->target, link->lun, 760 vendor, product, revision); 761 if (link->flags & SDEV_ATAPI) 762 printf("ATAPI"); 763 else 764 printf("SCSI%d", SCSISPC(inqbuf->version)); 765 printf(" %d/%s %s%s", type, dtype, removable ? "removable" : "fixed", 766 qtype); 767 768 if (link->id != NULL && link->id->d_type != DEVID_NONE) { 769 u_int8_t *id = (u_int8_t *)(link->id + 1); 770 int i; 771 772 switch (link->id->d_type) { 773 case DEVID_NAA: 774 printf(" naa."); 775 break; 776 case DEVID_EUI: 777 printf(" eui."); 778 break; 779 case DEVID_T10: 780 printf(" t10."); 781 break; 782 case DEVID_SERIAL: 783 printf(" serial."); 784 break; 785 } 786 787 if (ISSET(link->id->d_flags, DEVID_F_PRINT)) { 788 for (i = 0; i < link->id->d_len; i++) { 789 if (id[i] == '\0' || id[i] == ' ') { 790 /* skip leading blanks */ 791 /* collapse multiple blanks into one */ 792 if (i > 0 && id[i-1] != id[i]) 793 printf("_"); 794 } else if (id[i] < 0x20 || id[i] >= 0x80) { 795 /* non-printable characters */ 796 printf("~"); 797 } else { 798 /* normal characters */ 799 printf("%c", id[i]); 800 } 801 } 802 } else { 803 for (i = 0; i < link->id->d_len; i++) 804 printf("%02x", id[i]); 805 } 806 } 807 } 808 809 /* 810 * Print out autoconfiguration information for a subdevice. 811 * 812 * This is a slight abuse of 'standard' autoconfiguration semantics, 813 * because 'print' functions don't normally print the colon and 814 * device information. However, in this case that's better than 815 * either printing redundant information before the attach message, 816 * or having the device driver call a special function to print out 817 * the standard device information. 818 */ 819 int 820 scsibusprint(void *aux, const char *pnp) 821 { 822 struct scsi_attach_args *sa = aux; 823 824 if (pnp != NULL) 825 printf("%s", pnp); 826 827 scsibus_printlink(sa->sa_sc_link); 828 829 return (UNCONF); 830 } 831 832 /* 833 * Given a target and lun, ask the device what it is, and find the correct 834 * driver table entry. 835 * 836 * Return 0 if further LUNs are possible, EINVAL if not. 837 */ 838 int 839 scsi_probedev(struct scsibus_softc *scsi, int target, int lun) 840 { 841 const struct scsi_quirk_inquiry_pattern *finger; 842 struct scsi_inquiry_data *inqbuf, *usbinqbuf; 843 struct scsi_attach_args sa; 844 struct scsi_link *sc_link, *link0; 845 struct cfdata *cf; 846 int priority, rslt = 0; 847 848 /* Skip this slot if it is already attached and try the next LUN. */ 849 if (scsi_get_link(scsi, target, lun) != NULL) 850 return (0); 851 852 sc_link = malloc(sizeof(*sc_link), M_DEVBUF, M_NOWAIT); 853 if (sc_link == NULL) 854 return (EINVAL); 855 856 *sc_link = *scsi->adapter_link; 857 sc_link->target = target; 858 sc_link->lun = lun; 859 sc_link->interpret_sense = scsi_interpret_sense; 860 sc_link->node_wwn = sc_link->port_wwn = 0; 861 TAILQ_INIT(&sc_link->queue); 862 863 SC_DEBUG(sc_link, SDEV_DB2, ("scsi_link created.\n")); 864 865 /* ask the adapter if this will be a valid device */ 866 if (scsi->adapter_link->adapter->dev_probe != NULL && 867 scsi->adapter_link->adapter->dev_probe(sc_link) != 0) { 868 if (lun == 0) 869 rslt = EINVAL; 870 goto free; 871 } 872 873 /* 874 * If we havent been given an io pool by now then fall back to 875 * using sc_link->openings. 876 */ 877 if (sc_link->pool == NULL) { 878 sc_link->pool = malloc(sizeof(*sc_link->pool), 879 M_DEVBUF, M_NOWAIT); 880 if (sc_link->pool == NULL) { 881 rslt = ENOMEM; 882 goto bad; 883 } 884 scsi_iopool_init(sc_link->pool, sc_link, 885 scsi_default_get, scsi_default_put); 886 887 SET(sc_link->flags, SDEV_OWN_IOPL); 888 } 889 890 /* 891 * Tell drivers that are paying attention to avoid sync/wide/tags until 892 * INQUIRY data has been processed and the quirks information is 893 * complete. Some drivers set bits in quirks before we get here, so 894 * just add NOTAGS, NOWIDE and NOSYNC. 895 */ 896 sc_link->quirks |= SDEV_NOSYNC | SDEV_NOWIDE | SDEV_NOTAGS; 897 898 /* 899 * Ask the device what it is 900 */ 901 #ifdef SCSIDEBUG 902 if (((scsi->sc_dev.dv_unit < 32) && 903 ((1U << scsi->sc_dev.dv_unit) & scsidebug_buses)) && 904 ((target < 32) && ((1U << target) & scsidebug_targets)) && 905 ((lun < 32) && ((1U << lun) & scsidebug_luns))) 906 sc_link->flags |= scsidebug_level; 907 #endif /* SCSIDEBUG */ 908 909 if (lun == 0) { 910 /* Clear any outstanding errors. */ 911 scsi_test_unit_ready(sc_link, TEST_READY_RETRIES, 912 scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST | 913 SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE); 914 } 915 916 /* Now go ask the device all about itself. */ 917 inqbuf = dma_alloc(sizeof(*inqbuf), PR_NOWAIT | PR_ZERO); 918 if (inqbuf == NULL) { 919 rslt = ENOMEM; 920 goto bad; 921 } 922 923 rslt = scsi_inquire(sc_link, inqbuf, scsi_autoconf | SCSI_SILENT); 924 bcopy(inqbuf, &sc_link->inqdata, sizeof(sc_link->inqdata)); 925 dma_free(inqbuf, sizeof(*inqbuf)); 926 927 if (rslt != 0) { 928 SC_DEBUG(sc_link, SDEV_DB2, ("Bad LUN. rslt = %i\n", rslt)); 929 if (lun == 0) 930 rslt = EINVAL; 931 goto bad; 932 } 933 inqbuf = &sc_link->inqdata; 934 935 switch (inqbuf->device & SID_QUAL) { 936 case SID_QUAL_RSVD: 937 case SID_QUAL_BAD_LU: 938 case SID_QUAL_LU_OFFLINE: 939 SC_DEBUG(sc_link, SDEV_DB1, ("Bad LUN. SID_QUAL = 0x%02x\n", 940 inqbuf->device & SID_QUAL)); 941 goto bad; 942 943 case SID_QUAL_LU_OK: 944 if ((inqbuf->device & SID_TYPE) == T_NODEVICE) { 945 SC_DEBUG(sc_link, SDEV_DB1, 946 ("Bad LUN. SID_TYPE = T_NODEVICE\n")); 947 goto bad; 948 } 949 break; 950 951 default: 952 break; 953 } 954 955 scsi_devid(sc_link); 956 957 link0 = scsi_get_link(scsi, target, 0); 958 if (lun == 0 || link0 == NULL) 959 ; 960 else if (sc_link->flags & SDEV_UMASS) 961 ; 962 else if (sc_link->id != NULL && !DEVID_CMP(link0->id, sc_link->id)) 963 ; 964 else if (memcmp(inqbuf, &link0->inqdata, sizeof(*inqbuf)) == 0) { 965 /* The device doesn't distinguish between LUNs. */ 966 SC_DEBUG(sc_link, SDEV_DB1, ("IDENTIFY not supported.\n")); 967 rslt = EINVAL; 968 goto free_devid; 969 } 970 971 finger = (const struct scsi_quirk_inquiry_pattern *)scsi_inqmatch( 972 inqbuf, scsi_quirk_patterns, 973 nitems(scsi_quirk_patterns), 974 sizeof(scsi_quirk_patterns[0]), &priority); 975 976 /* 977 * Based upon the inquiry flags we got back, and if we're 978 * at SCSI-2 or better, remove some limiting quirks. 979 */ 980 if (SCSISPC(inqbuf->version) >= 2) { 981 if ((inqbuf->flags & SID_CmdQue) != 0) 982 sc_link->quirks &= ~SDEV_NOTAGS; 983 if ((inqbuf->flags & SID_Sync) != 0) 984 sc_link->quirks &= ~SDEV_NOSYNC; 985 if ((inqbuf->flags & SID_WBus16) != 0) 986 sc_link->quirks &= ~SDEV_NOWIDE; 987 } else 988 /* Older devices do not have SYNCHRONIZE CACHE capability. */ 989 sc_link->quirks |= SDEV_NOSYNCCACHE; 990 991 /* 992 * Now apply any quirks from the table. 993 */ 994 if (priority != 0) 995 sc_link->quirks |= finger->quirks; 996 997 /* 998 * If the device can't use tags, >1 opening may confuse it. 999 */ 1000 if (ISSET(sc_link->quirks, SDEV_NOTAGS)) 1001 sc_link->openings = 1; 1002 1003 /* 1004 * note what BASIC type of device it is 1005 */ 1006 if ((inqbuf->dev_qual2 & SID_REMOVABLE) != 0) 1007 sc_link->flags |= SDEV_REMOVABLE; 1008 1009 sa.sa_sc_link = sc_link; 1010 sa.sa_inqbuf = &sc_link->inqdata; 1011 1012 if ((cf = config_search(scsibussubmatch, (struct device *)scsi, 1013 &sa)) == 0) { 1014 scsibusprint(&sa, scsi->sc_dev.dv_xname); 1015 printf(" not configured\n"); 1016 goto free_devid; 1017 } 1018 1019 /* 1020 * Braindead USB devices, especially some x-in-1 media readers, try to 1021 * 'help' by pretending any LUN is actually LUN 0 until they see a 1022 * different LUN used in a command. So do an INQUIRY on LUN 1 at this 1023 * point to prevent such helpfulness before it causes confusion. 1024 */ 1025 if (lun == 0 && (sc_link->flags & SDEV_UMASS) && 1026 scsi_get_link(scsi, target, 1) == NULL && sc_link->luns > 1 && 1027 (usbinqbuf = dma_alloc(sizeof(*usbinqbuf), M_NOWAIT)) != NULL) { 1028 1029 sc_link->lun = 1; 1030 scsi_inquire(sc_link, usbinqbuf, scsi_autoconf | SCSI_SILENT); 1031 sc_link->lun = 0; 1032 1033 dma_free(usbinqbuf, sizeof(*usbinqbuf)); 1034 } 1035 1036 scsi_add_link(scsi, sc_link); 1037 1038 /* 1039 * Generate a TEST_UNIT_READY command. This gives drivers waiting for 1040 * valid quirks data a chance to set wide/sync/tag options 1041 * appropriately. It also clears any outstanding ACA conditions that 1042 * INQUIRY may leave behind. 1043 * 1044 * Do this now so that any messages generated by config_attach() do not 1045 * have negotiation messages inserted into their midst. 1046 */ 1047 scsi_test_unit_ready(sc_link, TEST_READY_RETRIES, 1048 scsi_autoconf | SCSI_IGNORE_ILLEGAL_REQUEST | 1049 SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE); 1050 1051 config_attach((struct device *)scsi, cf, &sa, scsibusprint); 1052 1053 return (0); 1054 1055 free_devid: 1056 if (sc_link->id) 1057 devid_free(sc_link->id); 1058 bad: 1059 if (ISSET(sc_link->flags, SDEV_OWN_IOPL)) 1060 free(sc_link->pool, M_DEVBUF); 1061 1062 if (scsi->adapter_link->adapter->dev_free != NULL) 1063 scsi->adapter_link->adapter->dev_free(sc_link); 1064 free: 1065 free(sc_link, M_DEVBUF); 1066 return (rslt); 1067 } 1068 1069 /* 1070 * Return a priority based on how much of the inquiry data matches 1071 * the patterns for the particular driver. 1072 */ 1073 const void * 1074 scsi_inqmatch(struct scsi_inquiry_data *inqbuf, const void *_base, 1075 int nmatches, int matchsize, int *bestpriority) 1076 { 1077 u_int8_t type; 1078 int removable; 1079 const void *bestmatch; 1080 const unsigned char *base = (const unsigned char *)_base; 1081 1082 /* Include the qualifier to catch vendor-unique types. */ 1083 type = inqbuf->device; 1084 removable = inqbuf->dev_qual2 & SID_REMOVABLE ? T_REMOV : T_FIXED; 1085 1086 for (*bestpriority = 0, bestmatch = 0; nmatches--; base += matchsize) { 1087 struct scsi_inquiry_pattern *match = (void *)base; 1088 int priority, len; 1089 1090 if (type != match->type) 1091 continue; 1092 if (removable != match->removable) 1093 continue; 1094 priority = 2; 1095 len = strlen(match->vendor); 1096 if (bcmp(inqbuf->vendor, match->vendor, len)) 1097 continue; 1098 priority += len; 1099 len = strlen(match->product); 1100 if (bcmp(inqbuf->product, match->product, len)) 1101 continue; 1102 priority += len; 1103 len = strlen(match->revision); 1104 if (bcmp(inqbuf->revision, match->revision, len)) 1105 continue; 1106 priority += len; 1107 1108 #if SCSIDEBUG 1109 printf("scsi_inqmatch: %d/%d/%d <%s, %s, %s>\n", 1110 priority, match->type, match->removable, 1111 match->vendor, match->product, match->revision); 1112 #endif 1113 if (priority > *bestpriority) { 1114 *bestpriority = priority; 1115 bestmatch = base; 1116 } 1117 } 1118 1119 return (bestmatch); 1120 } 1121 1122 void 1123 scsi_devid(struct scsi_link *link) 1124 { 1125 struct { 1126 struct scsi_vpd_hdr hdr; 1127 u_int8_t list[32]; 1128 } __packed *pg; 1129 int pg80 = 0, pg83 = 0, i; 1130 size_t len; 1131 1132 if (link->id != NULL) 1133 return; 1134 1135 pg = dma_alloc(sizeof(*pg), PR_WAITOK | PR_ZERO); 1136 1137 if (SCSISPC(link->inqdata.version) >= 2) { 1138 if (scsi_inquire_vpd(link, pg, sizeof(*pg), SI_PG_SUPPORTED, 1139 scsi_autoconf) != 0) 1140 goto done; 1141 1142 len = MIN(sizeof(pg->list), _2btol(pg->hdr.page_length)); 1143 for (i = 0; i < len; i++) { 1144 switch (pg->list[i]) { 1145 case SI_PG_SERIAL: 1146 pg80 = 1; 1147 break; 1148 case SI_PG_DEVID: 1149 pg83 = 1; 1150 break; 1151 } 1152 } 1153 1154 if (pg83 && scsi_devid_pg83(link) == 0) 1155 goto done; 1156 if (pg80 && scsi_devid_pg80(link) == 0) 1157 goto done; 1158 } 1159 done: 1160 dma_free(pg, sizeof(*pg)); 1161 } 1162 1163 int 1164 scsi_devid_pg83(struct scsi_link *link) 1165 { 1166 struct scsi_vpd_hdr *hdr = NULL; 1167 struct scsi_vpd_devid_hdr dhdr, chdr; 1168 u_int8_t *pg = NULL, *id; 1169 int type, idtype = 0; 1170 u_char idflags; 1171 int len, pos; 1172 int rv; 1173 1174 hdr = dma_alloc(sizeof(*hdr), PR_WAITOK | PR_ZERO); 1175 1176 rv = scsi_inquire_vpd(link, hdr, sizeof(*hdr), SI_PG_DEVID, 1177 scsi_autoconf); 1178 if (rv != 0) 1179 goto done; 1180 1181 len = sizeof(*hdr) + _2btol(hdr->page_length); 1182 pg = dma_alloc(len, PR_WAITOK | PR_ZERO); 1183 1184 rv = scsi_inquire_vpd(link, pg, len, SI_PG_DEVID, scsi_autoconf); 1185 if (rv != 0) 1186 goto done; 1187 1188 pos = sizeof(*hdr); 1189 1190 do { 1191 if (len - pos < sizeof(dhdr)) { 1192 rv = EIO; 1193 goto done; 1194 } 1195 memcpy(&dhdr, &pg[pos], sizeof(dhdr)); 1196 pos += sizeof(dhdr); 1197 if (len - pos < dhdr.len) { 1198 rv = EIO; 1199 goto done; 1200 } 1201 1202 if (VPD_DEVID_ASSOC(dhdr.flags) == VPD_DEVID_ASSOC_LU) { 1203 type = VPD_DEVID_TYPE(dhdr.flags); 1204 switch (type) { 1205 case VPD_DEVID_TYPE_NAA: 1206 case VPD_DEVID_TYPE_EUI64: 1207 case VPD_DEVID_TYPE_T10: 1208 if (type >= idtype) { 1209 idtype = type; 1210 1211 chdr = dhdr; 1212 id = &pg[pos]; 1213 } 1214 break; 1215 1216 default: 1217 /* skip */ 1218 break; 1219 } 1220 } 1221 1222 pos += dhdr.len; 1223 } while (idtype != VPD_DEVID_TYPE_NAA && len != pos); 1224 1225 if (idtype > 0) { 1226 switch (VPD_DEVID_TYPE(chdr.flags)) { 1227 case VPD_DEVID_TYPE_NAA: 1228 idtype = DEVID_NAA; 1229 break; 1230 case VPD_DEVID_TYPE_EUI64: 1231 idtype = DEVID_EUI; 1232 break; 1233 case VPD_DEVID_TYPE_T10: 1234 idtype = DEVID_T10; 1235 break; 1236 } 1237 switch (VPD_DEVID_CODE(chdr.pi_code)) { 1238 case VPD_DEVID_CODE_ASCII: 1239 case VPD_DEVID_CODE_UTF8: 1240 idflags = DEVID_F_PRINT; 1241 break; 1242 default: 1243 idflags = 0; 1244 break; 1245 } 1246 link->id = devid_alloc(idtype, idflags, chdr.len, id); 1247 } else 1248 rv = ENODEV; 1249 1250 done: 1251 if (pg) 1252 dma_free(pg, len); 1253 if (hdr) 1254 dma_free(hdr, sizeof(*hdr)); 1255 return (rv); 1256 } 1257 1258 int 1259 scsi_devid_pg80(struct scsi_link *link) 1260 { 1261 struct scsi_vpd_hdr *hdr = NULL; 1262 u_int8_t *pg = NULL; 1263 char *id; 1264 int pglen, len; 1265 int rv; 1266 1267 hdr = dma_alloc(sizeof(*hdr), PR_WAITOK | PR_ZERO); 1268 1269 rv = scsi_inquire_vpd(link, hdr, sizeof(*hdr), SI_PG_SERIAL, 1270 scsi_autoconf); 1271 if (rv != 0) 1272 goto freehdr; 1273 1274 len = _2btol(hdr->page_length); 1275 if (len == 0) { 1276 rv = EINVAL; 1277 goto freehdr; 1278 } 1279 1280 pglen = sizeof(*hdr) + len; 1281 pg = dma_alloc(pglen, PR_WAITOK | PR_ZERO); 1282 1283 rv = scsi_inquire_vpd(link, pg, pglen, SI_PG_SERIAL, scsi_autoconf); 1284 if (rv != 0) 1285 goto free; 1286 1287 id = malloc(sizeof(link->inqdata.vendor) + 1288 sizeof(link->inqdata.product) + len, M_TEMP, M_WAITOK); 1289 memcpy(id, link->inqdata.vendor, sizeof(link->inqdata.vendor)); 1290 memcpy(id + sizeof(link->inqdata.vendor), link->inqdata.product, 1291 sizeof(link->inqdata.product)); 1292 memcpy(id + sizeof(link->inqdata.vendor) + 1293 sizeof(link->inqdata.product), pg + sizeof(*hdr), len); 1294 1295 link->id = devid_alloc(DEVID_SERIAL, DEVID_F_PRINT, 1296 sizeof(link->inqdata.vendor) + sizeof(link->inqdata.product) + len, 1297 id); 1298 1299 free(id, M_TEMP); 1300 1301 free: 1302 dma_free(pg, pglen); 1303 freehdr: 1304 dma_free(hdr, sizeof(*hdr)); 1305 return (rv); 1306 } 1307 1308 /* 1309 * scsi_minphys member of struct scsi_adapter for drivers which don't 1310 * need any specific routine. 1311 */ 1312 void 1313 scsi_minphys(struct buf *bp, struct scsi_link *sl) 1314 { 1315 minphys(bp); 1316 } 1317 1318 struct devid * 1319 devid_alloc(u_int8_t type, u_int8_t flags, u_int8_t len, u_int8_t *id) 1320 { 1321 struct devid *d; 1322 1323 d = malloc(sizeof(*d) + len, M_DEVBUF, M_WAITOK|M_CANFAIL); 1324 if (d == NULL) 1325 return (NULL); 1326 1327 d->d_type = type; 1328 d->d_flags = flags; 1329 d->d_len = len; 1330 d->d_refcount = 1; 1331 memcpy(d + 1, id, len); 1332 1333 return (d); 1334 } 1335 1336 struct devid * 1337 devid_copy(struct devid *d) 1338 { 1339 d->d_refcount++; 1340 return (d); 1341 } 1342 1343 void 1344 devid_free(struct devid *d) 1345 { 1346 if (--d->d_refcount == 0) 1347 free(d, M_DEVBUF); 1348 } 1349