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