1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * These functions are used to encode SCSI INQUIRY data into 29 * Solaris devid / guid values. 30 */ 31 32 #ifndef _KERNEL 33 #include <stdio.h> 34 #endif /* _KERNEL */ 35 36 #include <sys/inttypes.h> 37 #include <sys/types.h> 38 #include <sys/stropts.h> 39 #include <sys/debug.h> 40 #include <sys/isa_defs.h> 41 #include <sys/dditypes.h> 42 #include <sys/ddi_impldefs.h> 43 #include <sys/scsi/scsi.h> 44 #ifndef _KERNEL 45 #include <sys/libdevid.h> 46 #endif /* !_KERNEL */ 47 #include "devid_impl.h" 48 49 #define SCSI_INQUIRY_VID_POS 9 50 #define SCSI_INQUIRY_VID_SUN "SUN" 51 #define SCSI_INQUIRY_VID_SUN_LEN 3 52 #define SCSI_INQUIRY_VID_HITACHI "HITACHI" 53 #define SCSI_INQUIRY_VID_HITACHI_LEN 7 54 #define SCSI_INQUIRY_PID_HITACHI_OPEN "OPEN-" 55 #define SCSI_INQUIRY_PID_HITACHI_OPEN_LEN 5 56 #define SCSI_INQUIRY_VID_EMC "EMC " 57 #define SCSI_INQUIRY_VID_EMC_LEN 8 58 #define SCSI_INQUIRY_PID_EMC_SYMMETRIX "SYMMETRIX " 59 #define SCSI_INQUIRY_PID_EMC_SYMMETRIX_LEN 16 60 61 #define MSG_NOT_STANDARDS_COMPLIANT "!Page83 data not standards compliant " 62 #define MSG_NOT_STANDARDS_COMPLIANT_SIZE ( \ 63 sizeof (MSG_NOT_STANDARDS_COMPLIANT) + \ 64 sizeof (((struct scsi_inquiry *)NULL)->inq_vid) + \ 65 sizeof (((struct scsi_inquiry *)NULL)->inq_pid) + \ 66 sizeof (((struct scsi_inquiry *)NULL)->inq_revision) + 4) 67 68 #define IS_DEVID_GUID_TYPE(type) ((type == DEVID_SCSI3_WWN) || \ 69 (IS_DEVID_SCSI3_VPD_TYPE(type))) 70 71 #define IS_DEVID_SCSI_TYPE(type) ((IS_DEVID_GUID_TYPE(type)) || \ 72 (type == DEVID_SCSI_SERIAL)) 73 74 /* 75 * The max inquiry page 83 size as expected in the code today 76 * is 0xf0 bytes. Defining a constant to make it easy incase 77 * this needs to be changed at a later time. 78 */ 79 80 #define SCMD_MAX_INQUIRY_PAGE83_SIZE 0xFF 81 #define SCMD_MIN_INQUIRY_PAGE83_SIZE 0x08 82 #define SCMD_INQUIRY_PAGE83_HDR_SIZE 4 83 #define SCSI_INQUIRY_PAGE83_EMC_SYMMETRIX_ID_LEN 16 84 85 #define SCMD_MAX_INQUIRY_PAGE80_SIZE 0xFF 86 #define SCMD_MIN_INQUIRY_PAGE80_SIZE 0x04 87 88 #define SCMD_MIN_STANDARD_INQUIRY_SIZE 0x04 89 90 #define SCMD_INQUIRY_PAGE83_IDENT_DESC_HDR_SIZE 4 91 92 #define SCMD_INQUIRY_VPD_TYPE_T10 0x01 93 #define SCMD_INQUIRY_VPD_TYPE_EUI 0x02 94 #define SCMD_INQUIRY_VPD_TYPE_NAA 0x03 95 #define SCMD_INQUIRY_VPD_TYPE_RTP 0x04 96 #define SCMD_INQUIRY_VPD_TYPE_TPG 0x05 97 #define SCMD_INQUIRY_VPD_TYPE_LUG 0x06 98 #define SCMD_INQUIRY_VPD_TYPE_MD5 0x07 99 #define SCMD_INQUIRY_VPD_TYPE_SSN 0x08 100 101 static int is_page83_data_valid(uchar_t *inq83, size_t inq83_len); 102 static int is_page80_data_valid(uchar_t *inq80, size_t inq80_len); 103 static int is_initialized_id(uchar_t *id, size_t id_len); 104 105 static void encode_scsi3_page83(int version, uchar_t *inq83, 106 size_t inq83_len, uchar_t **id, size_t *id_len, ushort_t *id_type); 107 static void encode_scsi3_page83_emc(int version, uchar_t *inq83, 108 size_t inq83_len, uchar_t **id, size_t *id_len, ushort_t *id_type); 109 static void encode_serialnum(int version, uchar_t *inq, uchar_t *inq80, 110 size_t inq80_len, uchar_t **id, size_t *id_len, ushort_t *id_type); 111 static void encode_sun_serialnum(int version, uchar_t *inq, 112 size_t inq_len, uchar_t **id, size_t *id_len, ushort_t *id_type); 113 114 static int devid_scsi_init(char *driver_name, 115 uchar_t *raw_id, size_t raw_id_len, ushort_t raw_id_type, 116 ddi_devid_t *ret_devid); 117 118 static char ctoi(char c); 119 120 /* 121 * Function: ddi_/devid_scsi_encode 122 * 123 * Description: This routine finds and encodes a unique devid 124 * 125 * Arguments: version - id encode algorithm version 126 * driver_name - binding driver name (if ! known use NULL) 127 * inq - standard inquiry buffer 128 * inq_len - standard inquiry buffer length 129 * inq80 - serial number inquiry buffer 130 * inq80_len - serial number inquiry buffer length 131 * inq83 - vpd inquiry buffer 132 * inq83_len - vpd inquiry buffer length 133 * devid - id returned 134 * 135 * Return Code: DEVID_SUCCESS - success 136 * DEVID_FAILURE - failure 137 * DEVID_RETRY - LUN is in a transitional state. A delay should 138 * occur and then this inquiry data should be re-acquired and 139 * this function should be called again. 140 */ 141 int 142 #ifdef _KERNEL 143 ddi_devid_scsi_encode( 144 #else /* ! _KERNEL */ 145 devid_scsi_encode( 146 #endif /* _KERNEL */ 147 int version, /* IN */ 148 char *driver_name, /* IN */ 149 uchar_t *inq, /* IN */ 150 size_t inq_len, /* IN */ 151 uchar_t *inq80, /* IN */ 152 size_t inq80_len, /* IN */ 153 uchar_t *inq83, /* IN */ 154 size_t inq83_len, /* IN */ 155 ddi_devid_t *devid) /* OUT */ 156 { 157 int rval = DEVID_FAILURE; 158 uchar_t *id = NULL; 159 size_t id_len = 0; 160 ushort_t id_type = DEVID_NONE; 161 struct scsi_inquiry *inq_std = (struct scsi_inquiry *)inq; 162 #ifdef _KERNEL 163 char *msg = NULL; 164 #endif /* _KERNEL */ 165 166 DEVID_ASSERT(devid != NULL); 167 168 /* verify valid version */ 169 if (version > DEVID_SCSI_ENCODE_VERSION_LATEST) { 170 return (rval); 171 } 172 173 /* make sure minimum inquiry bytes are available */ 174 if (inq_len < SCMD_MIN_STANDARD_INQUIRY_SIZE) { 175 return (rval); 176 } 177 178 /* 179 * If 0x83 is availible, that is the best choice. Our next choice is 180 * 0x80. If neither are availible, we leave it to the caller to 181 * determine possible alternate ID, although discouraged. In the 182 * case of the target drivers they create a fabricated id which is 183 * stored in the acyl. The HBA drivers should avoid using an 184 * alternate id. Although has already created a hack of using the 185 * node wwn in some cases. Which needs to be carried forward for 186 * legacy reasons. 187 */ 188 if (inq83 != NULL) { 189 /* 190 * Perform page 83 validation tests and report offenders. 191 * We cannot enforce the page 83 specification because 192 * many Sun partners (ex. HDS) do not conform to the 193 * standards yet. 194 */ 195 if (is_page83_data_valid(inq83, inq83_len) == 196 DEVID_RET_INVALID) { 197 /* 198 * invalid page 83 data. bug 4939576 introduced 199 * handling for EMC non-standard data. 200 */ 201 if ((bcmp(inq_std->inq_vid, SCSI_INQUIRY_VID_EMC, 202 SCSI_INQUIRY_VID_EMC_LEN) == 0) && 203 (bcmp(inq_std->inq_pid, 204 SCSI_INQUIRY_PID_EMC_SYMMETRIX, 205 SCSI_INQUIRY_PID_EMC_SYMMETRIX_LEN) == 0)) { 206 encode_scsi3_page83_emc(version, inq83, 207 inq83_len, &id, &id_len, &id_type); 208 } 209 #ifdef _KERNEL 210 /* 211 * invalid page 83 data. Special hack for HDS 212 * specific device, to suppress the warning msg. 213 */ 214 if ((bcmp(inq_std->inq_vid, SCSI_INQUIRY_VID_HITACHI, 215 SCSI_INQUIRY_VID_HITACHI_LEN) != 0) || 216 (bcmp(inq_std->inq_pid, 217 SCSI_INQUIRY_PID_HITACHI_OPEN, 218 SCSI_INQUIRY_PID_HITACHI_OPEN_LEN) != 0)) { 219 /* 220 * report the page 0x83 standards violation. 221 */ 222 msg = kmem_alloc( 223 MSG_NOT_STANDARDS_COMPLIANT_SIZE, 224 KM_SLEEP); 225 (void) strcpy(msg, MSG_NOT_STANDARDS_COMPLIANT); 226 (void) strncat(msg, inq_std->inq_vid, 227 sizeof (inq_std->inq_vid)); 228 (void) strcat(msg, " "); 229 (void) strncat(msg, inq_std->inq_pid, 230 sizeof (inq_std->inq_pid)); 231 (void) strcat(msg, " "); 232 (void) strncat(msg, inq_std->inq_revision, 233 sizeof (inq_std->inq_revision)); 234 (void) strcat(msg, "\n"); 235 cmn_err(CE_WARN, msg); 236 kmem_free(msg, 237 MSG_NOT_STANDARDS_COMPLIANT_SIZE); 238 } 239 #endif /* _KERNEL */ 240 } 241 242 if (id_type == DEVID_NONE) { 243 encode_scsi3_page83(version, inq83, 244 inq83_len, &id, &id_len, &id_type); 245 } 246 } 247 248 /* 249 * If no vpd page is available at this point then we 250 * attempt to use a SCSI serial number from page 0x80. 251 */ 252 if ((id_type == DEVID_NONE) && 253 (inq != NULL) && 254 (inq80 != NULL)) { 255 if (is_page80_data_valid(inq80, inq80_len) == DEVID_RET_VALID) { 256 encode_serialnum(version, inq, inq80, 257 inq80_len, &id, &id_len, &id_type); 258 } 259 } 260 261 /* 262 * If no vpd page or serial is available at this point and 263 * it's a SUN disk it conforms to the disk qual. 850 specifications 264 * and we can fabricate a serial number id based on the standard 265 * inquiry page. 266 */ 267 if ((id_type == DEVID_NONE) && 268 (inq != NULL)) { 269 encode_sun_serialnum(version, inq, inq_len, 270 &id, &id_len, &id_type); 271 } 272 273 if (id_type != DEVID_NONE) { 274 if (is_initialized_id(id, id_len) == DEVID_RET_VALID) { 275 rval = devid_scsi_init(driver_name, 276 id, id_len, id_type, devid); 277 } else { 278 rval = DEVID_RETRY; 279 } 280 DEVID_FREE(id, id_len); 281 } 282 283 return (rval); 284 } 285 286 287 /* 288 * Function: is_page83_data_valid 289 * 290 * Description: This routine is used to validate the page 0x83 data 291 * passed in valid based on the standards specification. 292 * 293 * Arguments: inq83 - 294 * inq83_len - 295 * 296 * Return Code: DEVID_RET_VALID 297 * DEVID_RET_INVALID 298 * 299 */ 300 static int 301 is_page83_data_valid(uchar_t *inq83, size_t inq83_len) 302 { 303 304 int covered_desc_len = 0; 305 int dlen = 0; 306 uchar_t *dblk = NULL; 307 308 DEVID_ASSERT(inq83 != NULL); 309 310 /* if not large enough fail */ 311 if (inq83_len < SCMD_MIN_INQUIRY_PAGE83_SIZE) 312 return (DEVID_RET_INVALID); 313 314 /* 315 * Ensuring that the Peripheral device type(bits 0 - 4) has 316 * the valid settings - the value 0x1f indicates no device type. 317 * Only this value can be validated since all other fields are 318 * either used or reserved. 319 */ 320 if ((inq83[0] & DTYPE_MASK) == DTYPE_UNKNOWN) { 321 /* failed-peripheral devtype */ 322 return (DEVID_RET_INVALID); 323 } 324 325 /* 326 * Ensure that the page length field - third and 4th bytes 327 * contain a non zero length value. Our implementation 328 * does not seem to expect more that 255 bytes of data... 329 * what is to be done if the reported size is > 255 bytes? 330 * Yes the device will return only 255 bytes as we provide 331 * buffer to house only that much data but the standards 332 * prevent the targets from reporting the truncated size 333 * in this field. 334 * 335 * Currently reporting sizes more than 255 as failure. 336 * 337 */ 338 339 if ((inq83[2] == 0) && (inq83[3] == 0)) { 340 /* length field is 0! */ 341 return (DEVID_RET_INVALID); 342 } 343 if (inq83[3] > (SCMD_MAX_INQUIRY_PAGE83_SIZE - 3)) { 344 /* length field exceeds expected size of 255 bytes */ 345 return (DEVID_RET_INVALID); 346 } 347 348 /* 349 * Validation of individual descriptor blocks are done in the 350 * following while loop. It is possible to have multiple 351 * descriptor blocks. 352 * the 'dblk' pointer will be pointing to the start of 353 * each entry of the descriptor block. 354 */ 355 covered_desc_len = 0; 356 dblk = &inq83[4]; /* start of first decriptor blk */ 357 while (covered_desc_len < inq83[3]) { 358 359 /* 360 * Ensure that the length field is non zero 361 * Further length validations will be done 362 * along with the 'identifier type' as some of 363 * the lengths are dependent on it. 364 */ 365 dlen = dblk[3]; 366 if (dlen == 0) { 367 /* descr length is 0 */ 368 return (DEVID_RET_INVALID); 369 } 370 371 /* 372 * ensure that the size of the descriptor block does 373 * not claim to be larger than the entire page83 374 * data that has been received. 375 */ 376 if ((covered_desc_len + dlen) > inq83[3]) { 377 /* failed-descr length */ 378 return (DEVID_RET_INVALID); 379 } 380 381 /* 382 * The spec says that if the PIV field is 0 OR the 383 * association field contains value other than 1 and 2, 384 * then the protocol identifier field should be ignored. 385 * If association field contains a value of 1 or 2 386 * and the PIV field is set, then the protocol identifier 387 * field has to be validated. 388 * The protocol identifier values 0 - f are either assigned 389 * or reserved. Nothing to validate here, hence skipping 390 * over to the next check. 391 */ 392 393 /* 394 * Check for valid code set values. 395 * All possible values are reserved or assigned. Nothing 396 * to validate - skipping over. 397 */ 398 399 /* 400 * Identifier Type validation 401 * All SPC3rev22 identified types and the expected lengths 402 * are validated. 403 */ 404 switch (dblk[1] & 0x0f) { 405 case SCMD_INQUIRY_VPD_TYPE_T10: /* T10 vendor Id */ 406 /* No specific length validation required */ 407 break; 408 409 case SCMD_INQUIRY_VPD_TYPE_EUI: /* EUI 64 ID */ 410 /* EUI-64: size is expected to be 8, 12, or 16 bytes */ 411 if ((dlen != 8) && (dlen != 12) && (dlen != 16)) { 412 /* page83 validation failed-EIU64 */ 413 return (DEVID_RET_INVALID); 414 } 415 break; 416 417 case SCMD_INQUIRY_VPD_TYPE_NAA: /* NAA Id type */ 418 419 /* 420 * the size for this varies - 421 * IEEE extended/registered is 8 bytes 422 * IEEE Registered extended is 16 bytes 423 */ 424 switch (dblk[4] & 0xf0) { 425 426 case 0x20: /* IEEE Ext */ 427 case 0x50: /* IEEE Reg */ 428 if (dlen != 8) { 429 /* failed-IEE E/R len */ 430 return (DEVID_RET_INVALID); 431 } 432 /* 433 * the codeSet for this MUST 434 * be set to 1 435 */ 436 if ((dblk[0] & 0x0f) != 1) { 437 /* 438 * failed-IEEE E/R 439 * codeSet != 1. 440 */ 441 return (DEVID_RET_INVALID); 442 } 443 break; 444 445 case 0x60: /* IEEE EXT REG */ 446 if (dlen != 16) { 447 /* failed-IEEE ER len */ 448 return (DEVID_RET_INVALID); 449 } 450 /* 451 * the codeSet for this MUST 452 * be set to 1 453 */ 454 if ((dblk[0] & 0x0f) != 1) { 455 /* 456 * failed-IEEE ER 457 * codeSet != 1. 458 */ 459 return (DEVID_RET_INVALID); 460 } 461 break; 462 463 default: 464 /* reserved values */ 465 break; 466 } 467 break; 468 469 case SCMD_INQUIRY_VPD_TYPE_RTP: /* Relative Target port */ 470 if (dlen != 4) { 471 /* failed-Rel target Port length */ 472 return (DEVID_RET_INVALID); 473 } 474 break; 475 476 case SCMD_INQUIRY_VPD_TYPE_TPG: /* Target port group */ 477 if (dlen != 4) { 478 /* failed-target Port group length */ 479 return (DEVID_RET_INVALID); 480 } 481 break; 482 483 case SCMD_INQUIRY_VPD_TYPE_LUG: /* Logical unit group */ 484 if (dlen != 4) { 485 /* failed-Logical Unit group length */ 486 return (DEVID_RET_INVALID); 487 } 488 break; 489 490 case SCMD_INQUIRY_VPD_TYPE_MD5: /* MD5 unit group */ 491 if (dlen != 16) { 492 /* failed-MD5 Unit grp */ 493 return (DEVID_RET_INVALID); 494 } 495 break; 496 497 default: 498 break; 499 } 500 501 /* 502 * Now lets advance to the next descriptor block 503 * and validate it. 504 * the descriptor block size is <descr Header> + <descr Data> 505 * <descr Header> is equal to 4 bytes 506 * <descr Data> is available in dlen or dblk[3]. 507 */ 508 dblk = &dblk[4 + dlen]; 509 510 /* 511 * update the covered_desc_len so that we can ensure that 512 * the 'while' loop terminates. 513 */ 514 covered_desc_len += (dlen + 4); 515 } 516 return (DEVID_RET_VALID); 517 } 518 519 520 /* 521 * Function: is_initialized_id 522 * 523 * Description: Routine to ensure that the ID calculated is not a 524 * space or zero filled ID. Returning a space / zero 525 * filled ID when the luns on the target are not fully 526 * initialized is a valid response from the target as 527 * per the T10 spec. When a space/zero filled ID is 528 * found its information needs to be polled again 529 * after sometime time to see if the luns are fully 530 * initialized to return a valid guid information. 531 * 532 * Arguments: id - raw id 533 * id_len - raw id len 534 * 535 * Return Code: DEVID_VALID - indicates a non space/zero filled id 536 * DEVID_INVALID - indicates id contains uninitialized data 537 * and suggests retry of the collection commands. 538 */ 539 static int 540 is_initialized_id(uchar_t *id, size_t id_len) 541 { 542 int idx; 543 544 if ((id == NULL) || 545 (id_len == 0)) { 546 /* got id length as 0 fetch info again */ 547 return (DEVID_RET_INVALID); 548 } 549 550 /* First lets check if the guid is filled with spaces */ 551 for (idx = 0; idx < id_len; idx++) { 552 if (id[idx] != ' ') { 553 break; 554 } 555 } 556 557 /* 558 * Lets exit if we find that it contains ALL spaces 559 * saying that it has an uninitialized guid 560 */ 561 if (idx >= id_len) { 562 /* guid filled with spaces found */ 563 return (DEVID_RET_INVALID); 564 } 565 566 /* 567 * Since we have found that it is not filled with spaces 568 * now lets ensure that the guid is not filled with only 569 * zeros. 570 */ 571 for (idx = 0; idx < id_len; idx ++) { 572 if (id[idx] != 0) { 573 return (DEVID_RET_VALID); 574 } 575 } 576 577 /* guid filled with zeros found */ 578 return (DEVID_RET_INVALID); 579 } 580 581 582 /* 583 * Function: is_page80_data_valid 584 * 585 * Description: This routine is used to validate the page 0x80 data 586 * passed in valid based on the standards specification. 587 * 588 * Arguments: inq80 - 589 * inq80_len - 590 * 591 * Return Code: DEVID_RET_VALID 592 * DEVID_RET_INVALID 593 * 594 */ 595 /* ARGSUSED */ 596 static int 597 is_page80_data_valid(uchar_t *inq80, size_t inq80_len) 598 { 599 DEVID_ASSERT(inq80); 600 601 /* if not large enough fail */ 602 if (inq80_len < SCMD_MIN_INQUIRY_PAGE80_SIZE) { 603 return (DEVID_RET_INVALID); 604 } 605 606 /* 607 * (inq80_len - 4) is the size of the buffer space available 608 * for the product serial number. So inq80[3] (ie. product 609 * serial number) should be <= (inq80_len -4). 610 */ 611 if (inq80[3] > (inq80_len - 4)) { 612 return (DEVID_RET_INVALID); 613 } 614 615 return (DEVID_RET_VALID); 616 } 617 618 619 /* 620 * Function: encode_devid_page 621 * 622 * Description: This routine finds the unique devid if available and 623 * fills the devid and length parameters. 624 * 625 * Arguments: version - encode version 626 * inq83 - driver soft state (unit) structure 627 * inq83_len - length of raw inq83 data 628 * id - raw id 629 * id_len - len of raw id 630 * id_type - type of id 631 * 632 * Note: DEVID_NONE is returned in the id_type field 633 * if no supported page 83 id is found. 634 */ 635 static void 636 encode_scsi3_page83(int version, uchar_t *inq83, size_t inq83_len, 637 uchar_t **id, size_t *id_len, ushort_t *id_type) 638 { 639 size_t descriptor_bytes_left = 0; 640 size_t offset = 0; 641 int idx = 0; 642 size_t offset_id_type[4]; 643 644 DEVID_ASSERT(inq83 != NULL); 645 /* inq83 length was already validate in is_page83_valid */ 646 DEVID_ASSERT(id != NULL); 647 DEVID_ASSERT(id_len != NULL); 648 DEVID_ASSERT(id_type != NULL); 649 650 /* preset defaults */ 651 *id = NULL; 652 *id_len = 0; 653 *id_type = DEVID_NONE; 654 655 /* verify we have enough memory for a ident header */ 656 if (inq83_len < SCMD_INQUIRY_PAGE83_HDR_SIZE) { 657 return; 658 } 659 660 /* 661 * Attempt to validate the page data. Once validated, we'll walk 662 * the descriptors, looking for certain identifier types that will 663 * mark this device with a unique id/wwn. Note the comment below 664 * for what we really want to receive. 665 */ 666 667 /* 668 * The format of the inq83 data (Device Identification VPD page) is 669 * a header (containing the total length of the page, from which 670 * descriptor_bytes_left is calculated), followed by a list of 671 * identification descriptors. Each identifcation descriptor has a 672 * header which includes the length of the individual identification 673 * descriptor). 674 * 675 * Set the offset to the beginning byte of the first identification 676 * descriptor. We'll index everything from there. 677 */ 678 offset = SCMD_INQUIRY_PAGE83_HDR_SIZE; 679 descriptor_bytes_left = (size_t)((inq83[2] << 8) | inq83[3]); 680 681 /* 682 * If the raw data states that the data is larger 683 * than what is actually received abort encode. 684 * Otherwise we will run off into unknown memory 685 * on the decode. 686 */ 687 if ((descriptor_bytes_left + offset) > inq83_len) { 688 return; 689 } 690 691 692 /* Zero out our offset array */ 693 bzero(offset_id_type, sizeof (offset_id_type)); 694 695 /* 696 * According to the scsi spec 8.4.3 SPC-2, there could be several 697 * descriptors associated with each lun. Some we care about and some 698 * we don't. This loop is set up to iterate through the descriptors. 699 * We want the 0x03 case which represents an FC-PH, FC-PH3 or FC-FS 700 * Name_Identifier. The spec mentions nothing about ordering, so we 701 * don't assume any. 702 * 703 * We need to check if we've finished walking the list of descriptors, 704 * we also perform additional checks to be sure the newly calculated 705 * offset is within the bounds of the buffer, and the identifier length 706 * (as calculated by the length field in the header) is valid. This is 707 * done to protect against devices which return bad page83 data. 708 */ 709 while ((descriptor_bytes_left > 0) && (offset_id_type[3] == 0) && 710 (offset + SCMD_INQUIRY_PAGE83_IDENT_DESC_HDR_SIZE <= inq83_len) && 711 (offset + SCMD_INQUIRY_PAGE83_IDENT_DESC_HDR_SIZE + 712 (size_t)inq83[offset + 3] <= inq83_len)) { 713 /* 714 * Inspect the Identification descriptor list. Store the 715 * offsets in the devid page separately for 0x03, 0x01 and 716 * 0x02. Identifiers 0x00 and 0x04 are not useful as they 717 * don't represent unique identifiers for a lun. We also 718 * check the association by masking with 0x3f because we want 719 * an association of 0x0 - indicating the identifier field is 720 * associated with the addressed physical or logical device 721 * and not the port. 722 */ 723 switch ((inq83[offset + 1] & 0x3f)) { 724 case SCMD_INQUIRY_VPD_TYPE_T10: 725 offset_id_type[SCMD_INQUIRY_VPD_TYPE_T10] = offset; 726 break; 727 case SCMD_INQUIRY_VPD_TYPE_EUI: 728 offset_id_type[SCMD_INQUIRY_VPD_TYPE_EUI] = offset; 729 break; 730 case SCMD_INQUIRY_VPD_TYPE_NAA: 731 offset_id_type[SCMD_INQUIRY_VPD_TYPE_NAA] = offset; 732 break; 733 default: 734 /* Devid page undesired id type */ 735 break; 736 } 737 /* 738 * Calculate the descriptor bytes left and move to 739 * the beginning byte of the next id descriptor. 740 */ 741 descriptor_bytes_left -= (size_t)(inq83[offset + 3] + 742 SCMD_INQUIRY_PAGE83_IDENT_DESC_HDR_SIZE); 743 offset += (SCMD_INQUIRY_PAGE83_IDENT_DESC_HDR_SIZE + 744 (size_t)inq83[offset + 3]); 745 } 746 747 offset = 0; 748 749 /* 750 * We can't depend on an order from a device by identifier type, but 751 * once we have them, we'll walk them in the same order to prevent a 752 * firmware upgrade from breaking our algorithm. Start with the one 753 * we want the most: id_offset_type[3]. 754 */ 755 for (idx = 3; idx > 0; idx--) { 756 if (offset_id_type[idx] > 0) { 757 offset = offset_id_type[idx]; 758 break; 759 } 760 } 761 762 /* 763 * We have a valid Device ID page, set the length of the 764 * identifier and copy the value into the wwn. 765 */ 766 if (offset > 0) { 767 *id_len = (size_t)inq83[offset + 3]; 768 if ((*id = DEVID_MALLOC(*id_len)) == NULL) { 769 *id_len = 0; 770 return; 771 } 772 bcopy(&inq83[offset + SCMD_INQUIRY_PAGE83_IDENT_DESC_HDR_SIZE], 773 *id, *id_len); 774 775 /* set devid type */ 776 switch (version) { 777 /* In version 1 all page 83 types were grouped */ 778 case DEVID_SCSI_ENCODE_VERSION1: 779 *id_type = DEVID_SCSI3_WWN; 780 break; 781 /* In version 2 we break page 83 apart to be unique */ 782 case DEVID_SCSI_ENCODE_VERSION2: 783 switch (idx) { 784 case 3: 785 *id_type = DEVID_SCSI3_VPD_NAA; 786 break; 787 case 2: 788 *id_type = DEVID_SCSI3_VPD_EUI; 789 break; 790 case 1: 791 *id_type = DEVID_SCSI3_VPD_T10; 792 break; 793 default: 794 DEVID_FREE(*id, *id_len); 795 *id_len = 0; 796 break; 797 } 798 break; 799 default: 800 DEVID_FREE(*id, *id_len); 801 *id_len = 0; 802 break; 803 } 804 } 805 } 806 807 808 /* 809 * Function: encode_scsi3_page83_emc 810 * 811 * Description: Routine to handle proprietary page 83 of EMC Symmetrix 812 * device. Called by ssfcp_handle_page83() 813 * 814 * Arguments: version - encode version 815 * inq83 - scsi page 83 buffer 816 * inq83_len - scsi page 83 buffer size 817 * id - raw emc id 818 * id_len - len of raw emc id 819 * id_type - type of emc id 820 */ 821 static void 822 encode_scsi3_page83_emc(int version, uchar_t *inq83, 823 size_t inq83_len, uchar_t **id, size_t *id_len, ushort_t *id_type) 824 { 825 uchar_t *guidp = NULL; 826 827 DEVID_ASSERT(inq83 != NULL); 828 DEVID_ASSERT(id != NULL); 829 DEVID_ASSERT(id_len != NULL); 830 DEVID_ASSERT(id_type != NULL); 831 832 /* preset defaults */ 833 *id = NULL; 834 *id_len = 0; 835 *id_type = DEVID_NONE; 836 837 /* The initial devid algorithm didn't use EMC page 83 data */ 838 if (version == DEVID_SCSI_ENCODE_VERSION1) { 839 return; 840 } 841 842 /* EMC page 83 requires atleast 20 bytes */ 843 if (inq83_len < (SCMD_INQUIRY_PAGE83_HDR_SIZE + 844 SCSI_INQUIRY_PAGE83_EMC_SYMMETRIX_ID_LEN)) { 845 return; 846 } 847 848 /* 849 * The 4th byte in the page 83 info returned is most likely 850 * indicating the length of the id - which 0x10(16 bytes) 851 * and the 5th byte is indicating that the id is of 852 * IEEE Registered Extended Name format(6). Validate 853 * these code prints before proceeding further as the 854 * following proprietary approach is tied to the specific 855 * device type and incase the EMC firmware changes, we will 856 * have to validate for the changed device before we start 857 * supporting such a device. 858 */ 859 if ((inq83[3] != 0x10) || (inq83[4] != 0x60)) { 860 /* unsupported emc symtx device type */ 861 return; 862 } else { 863 guidp = &inq83[SCMD_INQUIRY_PAGE83_HDR_SIZE]; 864 /* 865 * The GUID returned by the EMC device is 866 * in the IEEE Registered Extended Name format(6) 867 * as a result it is of 16 bytes in length. 868 * An IEEE Registered Name format(5) will be of 869 * 8 bytes which is NOT what is being returned 870 * by the device type for which we are providing 871 * the support. 872 */ 873 *id_len = SCSI_INQUIRY_PAGE83_EMC_SYMMETRIX_ID_LEN; 874 if ((*id = DEVID_MALLOC(*id_len)) == NULL) { 875 *id_len = 0; 876 return; 877 } 878 bcopy(guidp, *id, *id_len); 879 880 /* emc id matches type 3 */ 881 *id_type = DEVID_SCSI3_VPD_NAA; 882 } 883 } 884 885 886 /* 887 * Function: encode_serialnum 888 * 889 * Description: This routine finds the unique devid from the inquiry page 890 * 0x80, serial number page. If available and fills the wwn 891 * and length parameters. 892 * 893 * Arguments: version - encode version 894 * inq - standard inquiry data 895 * inq80 - serial inquiry data 896 * inq80_len - serial inquiry data len 897 * id - raw id 898 * id_len - raw id len 899 * id_type - raw id type 900 */ 901 /* ARGSUSED */ 902 static void 903 encode_serialnum(int version, uchar_t *inq, uchar_t *inq80, 904 size_t inq80_len, uchar_t **id, size_t *id_len, ushort_t *id_type) 905 { 906 struct scsi_inquiry *inq_std = (struct scsi_inquiry *)inq; 907 int idx = 0; 908 909 DEVID_ASSERT(inq != NULL); 910 DEVID_ASSERT(inq80 != NULL); 911 DEVID_ASSERT(id != NULL); 912 DEVID_ASSERT(id_len != NULL); 913 DEVID_ASSERT(id_type != NULL); 914 915 /* preset defaults */ 916 *id = NULL; 917 *id_len = 0; 918 *id_type = DEVID_NONE; 919 920 /* verify inq80 buffer is large enough for a header */ 921 if (inq80_len < SCMD_MIN_INQUIRY_PAGE80_SIZE) { 922 return; 923 } 924 925 /* 926 * Attempt to validate the page data. Once validated, we'll check 927 * the serial number. 928 */ 929 *id_len = (size_t)inq80[3]; /* Store Product Serial Number length */ 930 931 /* verify buffer is large enough for serial number */ 932 if (inq80_len < (*id_len + SCMD_MIN_INQUIRY_PAGE80_SIZE)) { 933 return; 934 } 935 936 /* 937 * Device returns ASCII space (20h) in all the bytes of successful data 938 * transfer, if the product serial number is not available. So we end 939 * up having to check all the bytes for a space until we reach 940 * something else. 941 */ 942 for (idx = 0; idx < *id_len; idx++) { 943 if (inq80[4 + idx] == ' ') { 944 continue; 945 } 946 /* 947 * The serial number is valid, but since this is only vendor 948 * unique, we'll combine the inquiry vid and pid with the 949 * serial number. 950 */ 951 *id_len += sizeof (inq_std->inq_vid); 952 *id_len += sizeof (inq_std->inq_pid); 953 954 if ((*id = DEVID_MALLOC(*id_len)) == NULL) { 955 *id_len = 0; 956 return; 957 } 958 959 bcopy(&inq_std->inq_vid, *id, sizeof (inq_std->inq_vid)); 960 bcopy(&inq_std->inq_pid, &(*id)[sizeof (inq_std->inq_vid)], 961 sizeof (inq_std->inq_pid)); 962 bcopy(&inq80[4], &(*id)[sizeof (inq_std->inq_vid) + 963 sizeof (inq_std->inq_pid)], inq80[3]); 964 965 *id_type = DEVID_SCSI_SERIAL; 966 break; 967 } 968 969 /* 970 * The spec suggests that the command could succeed but return all 971 * spaces if the product serial number is not available. In this case 972 * we need to fail this routine. To accomplish this, we compare our 973 * length to the serial number length. If they are the same, then we 974 * never copied in the vid and updated the length. That being the case, 975 * we must not have found a valid serial number. 976 */ 977 if (*id_len == (size_t)inq80[3]) { 978 /* empty unit serial number */ 979 if (*id != NULL) { 980 DEVID_FREE(*id, *id_len); 981 } 982 *id = NULL; 983 *id_len = 0; 984 } 985 } 986 987 988 /* 989 * Function: encode_sun_serialnum 990 * 991 * Description: This routine finds the unique devid from the inquiry page 992 * 0x80, serial number page. If available and fills the wwn 993 * and length parameters. 994 * 995 * Arguments: version - encode version 996 * inq - standard inquiry data 997 * inq_len - standard inquiry data len 998 * id - raw id 999 * id_len - raw id len 1000 * id_type - raw id type 1001 * 1002 * Return Code: DEVID_SUCCESS 1003 * DEVID_FAILURE 1004 */ 1005 /* ARGSUSED */ 1006 static void 1007 encode_sun_serialnum(int version, uchar_t *inq, 1008 size_t inq_len, uchar_t **id, size_t *id_len, ushort_t *id_type) 1009 { 1010 struct scsi_inquiry *inq_std = (struct scsi_inquiry *)inq; 1011 1012 DEVID_ASSERT(inq != NULL); 1013 DEVID_ASSERT(id != NULL); 1014 DEVID_ASSERT(id_len != NULL); 1015 DEVID_ASSERT(id_type != NULL); 1016 1017 /* verify enough buffer is available */ 1018 if (inq_len < SCMD_MIN_STANDARD_INQUIRY_SIZE) { 1019 return; 1020 } 1021 1022 /* sun qual drive */ 1023 if ((inq_std != NULL) && 1024 (bcmp(&inq_std->inq_pid[SCSI_INQUIRY_VID_POS], 1025 SCSI_INQUIRY_VID_SUN, SCSI_INQUIRY_VID_SUN_LEN) == 0)) { 1026 /* 1027 * VPD pages 0x83 and 0x80 are unavailable. This 1028 * is a Sun qualified disks as indicated by 1029 * "SUN" in bytes 25-27 of the inquiry data 1030 * (bytes 9-11 of the pid). Devid's are created 1031 * for Sun qualified disks by combining the 1032 * vendor id with the product id with the serial 1033 * number located in bytes 36-47 of the inquiry data. 1034 */ 1035 1036 /* get data size */ 1037 *id_len = sizeof (inq_std->inq_vid) + 1038 sizeof (inq_std->inq_pid) + 1039 sizeof (inq_std->inq_serial); 1040 1041 if ((*id = DEVID_MALLOC(*id_len)) == NULL) { 1042 *id_len = 0; 1043 return; 1044 } 1045 1046 /* copy the vid at the beginning */ 1047 bcopy(&inq_std->inq_vid, *id, 1048 sizeof (inq_std->inq_vid)); 1049 /* copy the pid after the vid */ 1050 bcopy(&inq_std->inq_pid, 1051 &(*id)[sizeof (inq_std->inq_vid)], 1052 sizeof (inq_std->inq_pid)); 1053 /* copy the serial number after the vid and pid */ 1054 bcopy(&inq_std->inq_serial, 1055 &(*id)[sizeof (inq_std->inq_vid) + 1056 sizeof (inq_std->inq_pid)], 1057 sizeof (inq_std->inq_serial)); 1058 /* devid formed from inquiry data */ 1059 *id_type = DEVID_SCSI_SERIAL; 1060 } 1061 } 1062 1063 1064 /* 1065 * Function: devid_scsi_init 1066 * 1067 * Description: This routine is used to create a devid for a scsi 1068 * devid type. 1069 * 1070 * Arguments: hint - driver soft state (unit) structure 1071 * raw_id - pass by reference variable to hold wwn 1072 * raw_id_len - wwn length 1073 * raw_id_type - 1074 * ret_devid - 1075 * 1076 * Return Code: DEVID_SUCCESS 1077 * DEVID_FAILURE 1078 * 1079 */ 1080 static int 1081 devid_scsi_init( 1082 char *driver_name, 1083 uchar_t *raw_id, 1084 size_t raw_id_len, 1085 ushort_t raw_id_type, 1086 ddi_devid_t *ret_devid) 1087 { 1088 impl_devid_t *i_devid = NULL; 1089 int i_devid_len = 0; 1090 int driver_name_len = 0; 1091 ushort_t u_raw_id_len = 0; 1092 1093 DEVID_ASSERT(raw_id != NULL); 1094 DEVID_ASSERT(ret_devid != NULL); 1095 1096 if (!IS_DEVID_SCSI_TYPE(raw_id_type)) { 1097 *ret_devid = NULL; 1098 return (DEVID_FAILURE); 1099 } 1100 1101 i_devid_len = sizeof (*i_devid) + raw_id_len - sizeof (i_devid->did_id); 1102 if ((i_devid = DEVID_MALLOC(i_devid_len)) == NULL) { 1103 *ret_devid = NULL; 1104 return (DEVID_FAILURE); 1105 } 1106 1107 i_devid->did_magic_hi = DEVID_MAGIC_MSB; 1108 i_devid->did_magic_lo = DEVID_MAGIC_LSB; 1109 i_devid->did_rev_hi = DEVID_REV_MSB; 1110 i_devid->did_rev_lo = DEVID_REV_LSB; 1111 DEVID_FORMTYPE(i_devid, raw_id_type); 1112 u_raw_id_len = raw_id_len; 1113 DEVID_FORMLEN(i_devid, u_raw_id_len); 1114 1115 /* Fill in driver name hint */ 1116 bzero(i_devid->did_driver, DEVID_HINT_SIZE); 1117 if (driver_name != NULL) { 1118 driver_name_len = strlen(driver_name); 1119 if (driver_name_len > DEVID_HINT_SIZE) { 1120 /* Pick up last four characters of driver name */ 1121 driver_name += driver_name_len - DEVID_HINT_SIZE; 1122 driver_name_len = DEVID_HINT_SIZE; 1123 } 1124 bcopy(driver_name, i_devid->did_driver, driver_name_len); 1125 } 1126 1127 bcopy(raw_id, i_devid->did_id, raw_id_len); 1128 1129 /* return device id */ 1130 *ret_devid = (ddi_devid_t)i_devid; 1131 return (DEVID_SUCCESS); 1132 } 1133 1134 1135 /* 1136 * Function: devid_to_guid 1137 * 1138 * Description: This routine extracts a guid string form a devid. 1139 * The common use of this guid is for a HBA driver 1140 * to pass into mdi_pi_alloc(). 1141 * 1142 * Arguments: devid - devid to extract guid from 1143 * 1144 * Return Code: guid string - success 1145 * NULL - failure 1146 */ 1147 char * 1148 #ifdef _KERNEL 1149 ddi_devid_to_guid(ddi_devid_t devid) 1150 #else /* !_KERNEL */ 1151 devid_to_guid(ddi_devid_t devid) 1152 #endif /* _KERNEL */ 1153 { 1154 impl_devid_t *id = (impl_devid_t *)devid; 1155 int len = 0; 1156 int idx = 0; 1157 int num = 0; 1158 char *guid = NULL; 1159 char *ptr = NULL; 1160 char *dp = NULL; 1161 1162 DEVID_ASSERT(devid != NULL); 1163 1164 /* NULL devid -> NULL guid */ 1165 if (devid == NULL) 1166 return (NULL); 1167 1168 if (!IS_DEVID_GUID_TYPE(DEVID_GETTYPE(id))) 1169 return (NULL); 1170 1171 /* guid is always converted to ascii, append NULL */ 1172 len = DEVID_GETLEN(id); 1173 1174 /* allocate guid string */ 1175 if ((guid = DEVID_MALLOC((len * 2) + 1)) == NULL) 1176 return (NULL); 1177 1178 /* perform encode of id to hex string */ 1179 ptr = guid; 1180 for (idx = 0, dp = &id->did_id[0]; idx < len; idx++, dp++) { 1181 num = ((*dp) >> 4) & 0xF; 1182 *ptr++ = (num < 10) ? (num + '0') : (num + ('a' - 10)); 1183 num = (*dp) & 0xF; 1184 *ptr++ = (num < 10) ? (num + '0') : (num + ('a' - 10)); 1185 } 1186 *ptr = 0; 1187 1188 return (guid); 1189 } 1190 1191 /* 1192 * Function: devid_free_guid 1193 * 1194 * Description: This routine frees a guid allocated by 1195 * devid_to_guid(). 1196 * 1197 * Arguments: guid - guid to free 1198 */ 1199 void 1200 #ifdef _KERNEL 1201 ddi_devid_free_guid(char *guid) 1202 #else /* !_KERNEL */ 1203 devid_free_guid(char *guid) 1204 #endif /* _KERNEL */ 1205 { 1206 if (guid != NULL) { 1207 DEVID_FREE(guid, strlen(guid) + 1); 1208 } 1209 } 1210 1211 static char 1212 ctoi(char c) 1213 { 1214 if ((c >= '0') && (c <= '9')) 1215 c -= '0'; 1216 else if ((c >= 'A') && (c <= 'F')) 1217 c = c - 'A' + 10; 1218 else if ((c >= 'a') && (c <= 'f')) 1219 c = c - 'a' + 10; 1220 else 1221 c = -1; 1222 return (c); 1223 } 1224 1225 /* ====NOTE: The scsi_* interfaces are not related to devids :NOTE==== */ 1226 1227 /* 1228 * Function: scsi_wwnstr_to_wwn 1229 * 1230 * Description: This routine translates wwn from wwnstr string to uint64 wwn. 1231 * 1232 * Arguments: wwnstr - the string wwn to be transformed 1233 * wwnp - the pointer to 64 bit wwn 1234 */ 1235 int 1236 scsi_wwnstr_to_wwn(const char *wwnstr, uint64_t *wwnp) 1237 { 1238 int i; 1239 char cl, ch; 1240 uint64_t tmp; 1241 1242 if (wwnp == NULL) 1243 return (DDI_FAILURE); 1244 *wwnp = 0; 1245 1246 if (wwnstr == NULL) 1247 return (DDI_FAILURE); 1248 1249 /* Skip leading 'w' if wwnstr is in unit-address form */ 1250 wwnstr = scsi_wwnstr_skip_ua_prefix(wwnstr); 1251 1252 if (strlen(wwnstr) != 16) 1253 return (DDI_FAILURE); 1254 1255 for (i = 0; i < 8; i++) { 1256 ch = ctoi(*wwnstr++); 1257 cl = ctoi(*wwnstr++); 1258 if (cl == -1 || ch == -1) { 1259 return (DDI_FAILURE); 1260 } 1261 tmp = (ch << 4) + cl; 1262 *wwnp = (*wwnp << 8) | tmp; 1263 } 1264 return (DDI_SUCCESS); 1265 } 1266 1267 /* 1268 * Function: scsi_wwn_to_wwnstr 1269 * 1270 * Description: This routine translates from a uint64 wwn to a wwnstr 1271 * 1272 * Arguments: 1273 * wwn - the 64 bit wwn 1274 * unit_address_form - do we want a leading 'w'? 1275 * wwnstr - allow caller to perform wwnstr allocation. 1276 * If non-NULL, don't use scsi_free_wwnstr(), 1277 * and make sure you provide 18/17 bytes of space. 1278 */ 1279 char * 1280 scsi_wwn_to_wwnstr(uint64_t wwn, int unit_address_form, char *wwnstr) 1281 { 1282 int len; 1283 1284 /* make space for leading 'w' */ 1285 if (unit_address_form) 1286 len = 1 + 16 + 1; /* "w0123456789abcdef\0" */ 1287 else 1288 len = 16 + 1; /* "0123456789abcdef\0" */ 1289 1290 if (wwnstr == NULL) { 1291 /* We allocate, caller uses scsi_free_wwnstr(). */ 1292 if ((wwnstr = DEVID_MALLOC(len)) == NULL) 1293 return (NULL); 1294 } 1295 1296 if (unit_address_form) 1297 (void) snprintf(wwnstr, len, "w%016" PRIx64, wwn); 1298 else 1299 (void) snprintf(wwnstr, len, "%016" PRIx64, wwn); 1300 return (wwnstr); 1301 } 1302 1303 /* 1304 * Function: scsi_wwnstr_hexcase 1305 * 1306 * Description: This routine switches a wwnstr to upper/lower case hex 1307 * (a wwnstr uses lower-case hex by default). 1308 * 1309 * Arguments: 1310 * wwnstr - the pointer to the wwnstr string. 1311 * upper_case_hex - non-zero will convert to upper_case hex 1312 * zero will convert to lower case hex. 1313 */ 1314 void 1315 scsi_wwnstr_hexcase(char *wwnstr, int upper_case_hex) 1316 { 1317 char *s; 1318 char c; 1319 1320 for (s = wwnstr; *s; s++) { 1321 c = *s; 1322 if ((upper_case_hex != 0) && 1323 ((c >= 'a') && (c <= 'f'))) 1324 c -= ('a' - 'A'); /* lower to upper */ 1325 else if ((upper_case_hex == 0) && 1326 ((c >= 'A') && (c <= 'F'))) 1327 c += ('a' - 'A'); /* upper to lower */ 1328 *s = c; 1329 } 1330 } 1331 1332 /* 1333 * Function: scsi_wwnstr_skip_ua_prefix 1334 * 1335 * Description: This routine removes the leading 'w' in wwnstr, 1336 * if its in unit-address form. 1337 * 1338 * Arguments: wwnstr - the string wwn to be transformed 1339 * 1340 */ 1341 const char * 1342 scsi_wwnstr_skip_ua_prefix(const char *wwnstr) 1343 { 1344 if (*wwnstr == 'w') 1345 wwnstr++; 1346 return (wwnstr); 1347 } 1348 1349 /* 1350 * Function: scsi_wwnstr_free 1351 * 1352 * Description: This routine frees a wwnstr returned by a call 1353 * to scsi_wwn_to_strwwn with a NULL wwnstr argument. 1354 * 1355 * Arguments: 1356 * wwnstr - the pointer to the wwnstr string to free. 1357 */ 1358 void 1359 scsi_free_wwnstr(char *wwnstr) 1360 { 1361 #ifdef _KERNEL 1362 kmem_free(wwnstr, strlen(wwnstr) + 1); 1363 #else /* _KERNEL */ 1364 free(wwnstr); 1365 #endif /* _KERNEL */ 1366 } 1367 1368 /* 1369 * Function: scsi_lun_to_lun64/scsi_lun64_to_lun 1370 * 1371 * Description: Convert between normalized (SCSI-3) LUN format, as 1372 * described by scsi_lun_t, and a normalized lun64_t 1373 * representation (used by Solaris SCSI_ADDR_PROP_LUN64 1374 * "lun64" property). The normalized representation maps 1375 * in a compatible way to SCSI-2 LUNs. See scsi_address.h 1376 * 1377 * SCSI-3 LUNs are 64 bits. SCSI-2 LUNs are 3 bits (up to 1378 * 5 bits in non-compliant implementations). SCSI-3 will 1379 * pass a (64-bit) scsi_lun_t, but we need a 1380 * representation from which we can for example, make 1381 * device names. For unit-address compatibility, we represent 1382 * 64-bit LUN numbers in such a way that they appear like they 1383 * would have under SCSI-2. This means that the single level 1384 * LUN number is in the lowest byte with the second, 1385 * third, and fourth level LUNs represented in 1386 * successively higher bytes. In particular, if (and only 1387 * if) the first byte of a 64 bit LUN is zero, denoting 1388 * "Peripheral Device Addressing Method" and "Bus 1389 * Identifier" zero, then the target implements LUNs 1390 * compatible in spirit with SCSI-2 LUNs (although under 1391 * SCSI-3 there may be up to 256 of them). Under SCSI-3 1392 * rules, a target is *required* to use this format if it 1393 * contains 256 or fewer Logical Units, none of which are 1394 * dependent logical units. These routines have knowledge 1395 * of the structure and size of a scsi_lun_t. 1396 * 1397 * NOTE: We tolerate vendors that use "Single level LUN structure using 1398 * peripheral device addressing method" with a non-zero bus identifier 1399 * (spec says bus identifier must be zero). Described another way, we let 1400 * the non-'addressing method' bits of sl_lun1_msb contribute to our lun64 1401 * value). 1402 */ 1403 scsi_lun64_t 1404 scsi_lun_to_lun64(scsi_lun_t lun) 1405 { 1406 scsi_lun64_t lun64; 1407 1408 /* 1409 * Check to see if we have a single level lun that uses the 1410 * "Peripheral Device" addressing method. If so, the lun64 value is 1411 * kept in Solaris 'unit-address compatibility' form. 1412 */ 1413 if (((lun.sl_lun2_msb == 0) && (lun.sl_lun2_lsb == 0) && 1414 (lun.sl_lun3_msb == 0) && (lun.sl_lun3_lsb == 0) && 1415 (lun.sl_lun4_msb == 0) && (lun.sl_lun4_lsb == 0)) && 1416 ((lun.sl_lun1_msb & SCSI_LUN_AM_MASK) == SCSI_LUN_AM_PDEV)) { 1417 /* 1418 * LUN has Solaris 'unit-address compatibility' form, construct 1419 * lun64 value from non-'addressing method' bits of msb and lsb. 1420 */ 1421 lun64 = ((lun.sl_lun1_msb & ~SCSI_LUN_AM_MASK) << 8) | 1422 lun.sl_lun1_lsb; 1423 } else { 1424 /* 1425 * LUN does not have a Solaris 'unit-address compatibility' 1426 * form, construct lun64 value in full 64 bit LUN format. 1427 */ 1428 lun64 = 1429 ((scsi_lun64_t)lun.sl_lun1_msb << 56) | 1430 ((scsi_lun64_t)lun.sl_lun1_lsb << 48) | 1431 ((scsi_lun64_t)lun.sl_lun2_msb << 40) | 1432 ((scsi_lun64_t)lun.sl_lun2_lsb << 32) | 1433 ((scsi_lun64_t)lun.sl_lun3_msb << 24) | 1434 ((scsi_lun64_t)lun.sl_lun3_lsb << 16) | 1435 ((scsi_lun64_t)lun.sl_lun4_msb << 8) | 1436 (scsi_lun64_t)lun.sl_lun4_lsb; 1437 } 1438 return (lun64); 1439 } 1440 1441 scsi_lun_t 1442 scsi_lun64_to_lun(scsi_lun64_t lun64) 1443 { 1444 scsi_lun_t lun; 1445 1446 if (lun64 <= (((0xFF & ~SCSI_LUN_AM_MASK) << 8) | 0xFF)) { 1447 /* 1448 * lun64 is in Solaris 'unit-address compatibility' form. 1449 */ 1450 lun.sl_lun1_msb = SCSI_LUN_AM_PDEV | (lun64 >> 8); 1451 lun.sl_lun1_lsb = (uchar_t)lun64; 1452 lun.sl_lun2_msb = 0; 1453 lun.sl_lun2_lsb = 0; 1454 lun.sl_lun3_msb = 0; 1455 lun.sl_lun3_lsb = 0; 1456 lun.sl_lun4_msb = 0; 1457 lun.sl_lun4_lsb = 0; 1458 } else { 1459 /* lun64 is in full 64 bit LUN format. */ 1460 lun.sl_lun1_msb = (uchar_t)(lun64 >> 56); 1461 lun.sl_lun1_lsb = (uchar_t)(lun64 >> 48); 1462 lun.sl_lun2_msb = (uchar_t)(lun64 >> 40); 1463 lun.sl_lun2_lsb = (uchar_t)(lun64 >> 32); 1464 lun.sl_lun3_msb = (uchar_t)(lun64 >> 24); 1465 lun.sl_lun3_lsb = (uchar_t)(lun64 >> 16); 1466 lun.sl_lun4_msb = (uchar_t)(lun64 >> 8); 1467 lun.sl_lun4_lsb = (uchar_t)(lun64); 1468 } 1469 return (lun); 1470 } 1471