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