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 disk 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 1050 /* copy the pid after the vid */ 1051 bcopy(&inq_std->inq_pid, 1052 &(*id)[sizeof (inq_std->inq_vid)], 1053 sizeof (inq_std->inq_pid)); 1054 1055 /* copy the serial number after the vid and pid */ 1056 bcopy(&inq_std->inq_serial, 1057 &(*id)[sizeof (inq_std->inq_vid) + 1058 sizeof (inq_std->inq_pid)], 1059 sizeof (inq_std->inq_serial)); 1060 1061 /* devid formed from inquiry data */ 1062 *id_type = DEVID_SCSI_SERIAL; 1063 } 1064 } 1065 1066 1067 /* 1068 * Function: devid_scsi_init 1069 * 1070 * Description: This routine is used to create a devid for a scsi 1071 * devid type. 1072 * 1073 * Arguments: hint - driver soft state (unit) structure 1074 * raw_id - pass by reference variable to hold wwn 1075 * raw_id_len - wwn length 1076 * raw_id_type - 1077 * ret_devid - 1078 * 1079 * Return Code: DEVID_SUCCESS 1080 * DEVID_FAILURE 1081 * 1082 */ 1083 static int 1084 devid_scsi_init( 1085 char *driver_name, 1086 uchar_t *raw_id, 1087 size_t raw_id_len, 1088 ushort_t raw_id_type, 1089 ddi_devid_t *ret_devid) 1090 { 1091 impl_devid_t *i_devid = NULL; 1092 int i_devid_len = 0; 1093 int driver_name_len = 0; 1094 ushort_t u_raw_id_len = 0; 1095 1096 DEVID_ASSERT(raw_id != NULL); 1097 DEVID_ASSERT(ret_devid != NULL); 1098 1099 if (!IS_DEVID_SCSI_TYPE(raw_id_type)) { 1100 *ret_devid = NULL; 1101 return (DEVID_FAILURE); 1102 } 1103 1104 i_devid_len = sizeof (*i_devid) + raw_id_len - sizeof (i_devid->did_id); 1105 if ((i_devid = DEVID_MALLOC(i_devid_len)) == NULL) { 1106 *ret_devid = NULL; 1107 return (DEVID_FAILURE); 1108 } 1109 1110 i_devid->did_magic_hi = DEVID_MAGIC_MSB; 1111 i_devid->did_magic_lo = DEVID_MAGIC_LSB; 1112 i_devid->did_rev_hi = DEVID_REV_MSB; 1113 i_devid->did_rev_lo = DEVID_REV_LSB; 1114 DEVID_FORMTYPE(i_devid, raw_id_type); 1115 u_raw_id_len = raw_id_len; 1116 DEVID_FORMLEN(i_devid, u_raw_id_len); 1117 1118 /* Fill in driver name hint */ 1119 bzero(i_devid->did_driver, DEVID_HINT_SIZE); 1120 if (driver_name != NULL) { 1121 driver_name_len = strlen(driver_name); 1122 if (driver_name_len > DEVID_HINT_SIZE) { 1123 /* Pick up last four characters of driver name */ 1124 driver_name += driver_name_len - DEVID_HINT_SIZE; 1125 driver_name_len = DEVID_HINT_SIZE; 1126 } 1127 bcopy(driver_name, i_devid->did_driver, driver_name_len); 1128 } 1129 1130 bcopy(raw_id, i_devid->did_id, raw_id_len); 1131 1132 /* return device id */ 1133 *ret_devid = (ddi_devid_t)i_devid; 1134 return (DEVID_SUCCESS); 1135 } 1136 1137 1138 /* 1139 * Function: devid_to_guid 1140 * 1141 * Description: This routine extracts a guid string form a devid. 1142 * The common use of this guid is for a HBA driver 1143 * to pass into mdi_pi_alloc(). 1144 * 1145 * Arguments: devid - devid to extract guid from 1146 * 1147 * Return Code: guid string - success 1148 * NULL - failure 1149 */ 1150 char * 1151 #ifdef _KERNEL 1152 ddi_devid_to_guid(ddi_devid_t devid) 1153 #else /* !_KERNEL */ 1154 devid_to_guid(ddi_devid_t devid) 1155 #endif /* _KERNEL */ 1156 { 1157 impl_devid_t *id = (impl_devid_t *)devid; 1158 int len = 0; 1159 int idx = 0; 1160 int num = 0; 1161 char *guid = NULL; 1162 char *ptr = NULL; 1163 char *dp = NULL; 1164 1165 DEVID_ASSERT(devid != NULL); 1166 1167 /* NULL devid -> NULL guid */ 1168 if (devid == NULL) 1169 return (NULL); 1170 1171 if (!IS_DEVID_GUID_TYPE(DEVID_GETTYPE(id))) 1172 return (NULL); 1173 1174 /* guid is always converted to ascii, append NULL */ 1175 len = DEVID_GETLEN(id); 1176 1177 /* allocate guid string */ 1178 if ((guid = DEVID_MALLOC((len * 2) + 1)) == NULL) 1179 return (NULL); 1180 1181 /* perform encode of id to hex string */ 1182 ptr = guid; 1183 for (idx = 0, dp = &id->did_id[0]; idx < len; idx++, dp++) { 1184 num = ((*dp) >> 4) & 0xF; 1185 *ptr++ = (num < 10) ? (num + '0') : (num + ('a' - 10)); 1186 num = (*dp) & 0xF; 1187 *ptr++ = (num < 10) ? (num + '0') : (num + ('a' - 10)); 1188 } 1189 *ptr = 0; 1190 1191 return (guid); 1192 } 1193 1194 /* 1195 * Function: devid_free_guid 1196 * 1197 * Description: This routine frees a guid allocated by 1198 * devid_to_guid(). 1199 * 1200 * Arguments: guid - guid to free 1201 */ 1202 void 1203 #ifdef _KERNEL 1204 ddi_devid_free_guid(char *guid) 1205 #else /* !_KERNEL */ 1206 devid_free_guid(char *guid) 1207 #endif /* _KERNEL */ 1208 { 1209 if (guid != NULL) { 1210 DEVID_FREE(guid, strlen(guid) + 1); 1211 } 1212 } 1213 1214 static char 1215 ctoi(char c) 1216 { 1217 if ((c >= '0') && (c <= '9')) 1218 c -= '0'; 1219 else if ((c >= 'A') && (c <= 'F')) 1220 c = c - 'A' + 10; 1221 else if ((c >= 'a') && (c <= 'f')) 1222 c = c - 'a' + 10; 1223 else 1224 c = -1; 1225 return (c); 1226 } 1227 1228 /* ====NOTE: The scsi_* interfaces are not related to devids :NOTE==== */ 1229 1230 /* 1231 * Function: scsi_wwnstr_to_wwn 1232 * 1233 * Description: This routine translates wwn from wwnstr string to uint64 wwn. 1234 * 1235 * Arguments: wwnstr - the string wwn to be transformed 1236 * wwnp - the pointer to 64 bit wwn 1237 */ 1238 int 1239 scsi_wwnstr_to_wwn(const char *wwnstr, uint64_t *wwnp) 1240 { 1241 int i; 1242 char cl, ch; 1243 uint64_t tmp; 1244 1245 if (wwnp == NULL) 1246 return (DDI_FAILURE); 1247 *wwnp = 0; 1248 1249 if (wwnstr == NULL) 1250 return (DDI_FAILURE); 1251 1252 /* Skip leading 'w' if wwnstr is in unit-address form */ 1253 wwnstr = scsi_wwnstr_skip_ua_prefix(wwnstr); 1254 1255 if (strlen(wwnstr) != 16) 1256 return (DDI_FAILURE); 1257 1258 for (i = 0; i < 8; i++) { 1259 ch = ctoi(*wwnstr++); 1260 cl = ctoi(*wwnstr++); 1261 if (cl == -1 || ch == -1) { 1262 return (DDI_FAILURE); 1263 } 1264 tmp = (ch << 4) + cl; 1265 *wwnp = (*wwnp << 8) | tmp; 1266 } 1267 return (DDI_SUCCESS); 1268 } 1269 1270 /* 1271 * Function: scsi_wwn_to_wwnstr 1272 * 1273 * Description: This routine translates from a uint64 wwn to a wwnstr 1274 * 1275 * Arguments: 1276 * wwn - the 64 bit wwn 1277 * unit_address_form - do we want a leading 'w'? 1278 * wwnstr - allow caller to perform wwnstr allocation. 1279 * If non-NULL, don't use scsi_free_wwnstr(), 1280 * and make sure you provide 18/17 bytes of space. 1281 */ 1282 char * 1283 scsi_wwn_to_wwnstr(uint64_t wwn, int unit_address_form, char *wwnstr) 1284 { 1285 int len; 1286 1287 /* make space for leading 'w' */ 1288 if (unit_address_form) 1289 len = 1 + 16 + 1; /* "w0123456789abcdef\0" */ 1290 else 1291 len = 16 + 1; /* "0123456789abcdef\0" */ 1292 1293 if (wwnstr == NULL) { 1294 /* We allocate, caller uses scsi_free_wwnstr(). */ 1295 if ((wwnstr = DEVID_MALLOC(len)) == NULL) 1296 return (NULL); 1297 } 1298 1299 if (unit_address_form) 1300 (void) snprintf(wwnstr, len, "w%016" PRIx64, wwn); 1301 else 1302 (void) snprintf(wwnstr, len, "%016" PRIx64, wwn); 1303 return (wwnstr); 1304 } 1305 1306 /* 1307 * Function: scsi_wwnstr_hexcase 1308 * 1309 * Description: This routine switches a wwnstr to upper/lower case hex 1310 * (a wwnstr uses lower-case hex by default). 1311 * 1312 * Arguments: 1313 * wwnstr - the pointer to the wwnstr string. 1314 * upper_case_hex - non-zero will convert to upper_case hex 1315 * zero will convert to lower case hex. 1316 */ 1317 void 1318 scsi_wwnstr_hexcase(char *wwnstr, int upper_case_hex) 1319 { 1320 char *s; 1321 char c; 1322 1323 for (s = wwnstr; *s; s++) { 1324 c = *s; 1325 if ((upper_case_hex != 0) && 1326 ((c >= 'a') && (c <= 'f'))) 1327 c -= ('a' - 'A'); /* lower to upper */ 1328 else if ((upper_case_hex == 0) && 1329 ((c >= 'A') && (c <= 'F'))) 1330 c += ('a' - 'A'); /* upper to lower */ 1331 *s = c; 1332 } 1333 } 1334 1335 /* 1336 * Function: scsi_wwnstr_skip_ua_prefix 1337 * 1338 * Description: This routine removes the leading 'w' in wwnstr, 1339 * if its in unit-address form. 1340 * 1341 * Arguments: wwnstr - the string wwn to be transformed 1342 * 1343 */ 1344 const char * 1345 scsi_wwnstr_skip_ua_prefix(const char *wwnstr) 1346 { 1347 if (*wwnstr == 'w') 1348 wwnstr++; 1349 return (wwnstr); 1350 } 1351 1352 /* 1353 * Function: scsi_wwnstr_free 1354 * 1355 * Description: This routine frees a wwnstr returned by a call 1356 * to scsi_wwn_to_strwwn with a NULL wwnstr argument. 1357 * 1358 * Arguments: 1359 * wwnstr - the pointer to the wwnstr string to free. 1360 */ 1361 void 1362 scsi_free_wwnstr(char *wwnstr) 1363 { 1364 #ifdef _KERNEL 1365 kmem_free(wwnstr, strlen(wwnstr) + 1); 1366 #else /* _KERNEL */ 1367 free(wwnstr); 1368 #endif /* _KERNEL */ 1369 } 1370 1371 /* 1372 * Function: scsi_lun_to_lun64/scsi_lun64_to_lun 1373 * 1374 * Description: Convert between normalized (SCSI-3) LUN format, as 1375 * described by scsi_lun_t, and a normalized lun64_t 1376 * representation (used by Solaris SCSI_ADDR_PROP_LUN64 1377 * "lun64" property). The normalized representation maps 1378 * in a compatible way to SCSI-2 LUNs. See scsi_address.h 1379 * 1380 * SCSI-3 LUNs are 64 bits. SCSI-2 LUNs are 3 bits (up to 1381 * 5 bits in non-compliant implementations). SCSI-3 will 1382 * pass a (64-bit) scsi_lun_t, but we need a 1383 * representation from which we can for example, make 1384 * device names. For unit-address compatibility, we represent 1385 * 64-bit LUN numbers in such a way that they appear like they 1386 * would have under SCSI-2. This means that the single level 1387 * LUN number is in the lowest byte with the second, 1388 * third, and fourth level LUNs represented in 1389 * successively higher bytes. In particular, if (and only 1390 * if) the first byte of a 64 bit LUN is zero, denoting 1391 * "Peripheral Device Addressing Method" and "Bus 1392 * Identifier" zero, then the target implements LUNs 1393 * compatible in spirit with SCSI-2 LUNs (although under 1394 * SCSI-3 there may be up to 256 of them). Under SCSI-3 1395 * rules, a target is *required* to use this format if it 1396 * contains 256 or fewer Logical Units, none of which are 1397 * dependent logical units. These routines have knowledge 1398 * of the structure and size of a scsi_lun_t. 1399 * 1400 * NOTE: We tolerate vendors that use "Single level LUN structure using 1401 * peripheral device addressing method" with a non-zero bus identifier 1402 * (spec says bus identifier must be zero). Described another way, we let 1403 * the non-'addressing method' bits of sl_lun1_msb contribute to our lun64 1404 * value). 1405 */ 1406 scsi_lun64_t 1407 scsi_lun_to_lun64(scsi_lun_t lun) 1408 { 1409 scsi_lun64_t lun64; 1410 1411 /* 1412 * Check to see if we have a single level lun that uses the 1413 * "Peripheral Device" addressing method. If so, the lun64 value is 1414 * kept in Solaris 'unit-address compatibility' form. 1415 */ 1416 if (((lun.sl_lun2_msb == 0) && (lun.sl_lun2_lsb == 0) && 1417 (lun.sl_lun3_msb == 0) && (lun.sl_lun3_lsb == 0) && 1418 (lun.sl_lun4_msb == 0) && (lun.sl_lun4_lsb == 0)) && 1419 ((lun.sl_lun1_msb & SCSI_LUN_AM_MASK) == SCSI_LUN_AM_PDEV)) { 1420 /* 1421 * LUN has Solaris 'unit-address compatibility' form, construct 1422 * lun64 value from non-'addressing method' bits of msb and lsb. 1423 */ 1424 lun64 = ((lun.sl_lun1_msb & ~SCSI_LUN_AM_MASK) << 8) | 1425 lun.sl_lun1_lsb; 1426 } else { 1427 /* 1428 * LUN does not have a Solaris 'unit-address compatibility' 1429 * form, construct lun64 value in full 64 bit LUN format. 1430 */ 1431 lun64 = 1432 ((scsi_lun64_t)lun.sl_lun1_msb << 56) | 1433 ((scsi_lun64_t)lun.sl_lun1_lsb << 48) | 1434 ((scsi_lun64_t)lun.sl_lun2_msb << 40) | 1435 ((scsi_lun64_t)lun.sl_lun2_lsb << 32) | 1436 ((scsi_lun64_t)lun.sl_lun3_msb << 24) | 1437 ((scsi_lun64_t)lun.sl_lun3_lsb << 16) | 1438 ((scsi_lun64_t)lun.sl_lun4_msb << 8) | 1439 (scsi_lun64_t)lun.sl_lun4_lsb; 1440 } 1441 return (lun64); 1442 } 1443 1444 scsi_lun_t 1445 scsi_lun64_to_lun(scsi_lun64_t lun64) 1446 { 1447 scsi_lun_t lun; 1448 1449 if (lun64 <= (((0xFF & ~SCSI_LUN_AM_MASK) << 8) | 0xFF)) { 1450 /* 1451 * lun64 is in Solaris 'unit-address compatibility' form. 1452 */ 1453 lun.sl_lun1_msb = SCSI_LUN_AM_PDEV | (lun64 >> 8); 1454 lun.sl_lun1_lsb = (uchar_t)lun64; 1455 lun.sl_lun2_msb = 0; 1456 lun.sl_lun2_lsb = 0; 1457 lun.sl_lun3_msb = 0; 1458 lun.sl_lun3_lsb = 0; 1459 lun.sl_lun4_msb = 0; 1460 lun.sl_lun4_lsb = 0; 1461 } else { 1462 /* lun64 is in full 64 bit LUN format. */ 1463 lun.sl_lun1_msb = (uchar_t)(lun64 >> 56); 1464 lun.sl_lun1_lsb = (uchar_t)(lun64 >> 48); 1465 lun.sl_lun2_msb = (uchar_t)(lun64 >> 40); 1466 lun.sl_lun2_lsb = (uchar_t)(lun64 >> 32); 1467 lun.sl_lun3_msb = (uchar_t)(lun64 >> 24); 1468 lun.sl_lun3_lsb = (uchar_t)(lun64 >> 16); 1469 lun.sl_lun4_msb = (uchar_t)(lun64 >> 8); 1470 lun.sl_lun4_lsb = (uchar_t)(lun64); 1471 } 1472 return (lun); 1473 } 1474 1475 /* 1476 * This routine returns the true length of the ascii inquiry fields that are to 1477 * be created by removing the padded spaces at the end of the inquiry data. 1478 * This routine was designed for trimming spaces from the vid, pid and revision 1479 * which are defined as being left aligned. In addition, we return 0 length 1480 * if the field is full of all 0's or spaces, indicating to the caller that 1481 * the device was not ready to return the inquiry data as per note 65 in 1482 * the scsi-2 spec. 1483 */ 1484 int 1485 scsi_ascii_inquiry_len(char *field, size_t length) 1486 { 1487 int retval; 1488 int trailer; 1489 char *p; 1490 1491 retval = length; 1492 1493 /* 1494 * The vid, pid and revision are left-aligned ascii fields within the 1495 * inquiry data. Here we trim the end of these fields by discounting 1496 * length associated with trailing spaces or NULL bytes. The remaining 1497 * bytes shall be only graphics codes - 0x20 through 0x7e as per the 1498 * scsi spec definition. If we have all 0's or spaces, we return 0 1499 * length. For devices that store inquiry data on the device, they 1500 * can return 0's or spaces in these fields until the data is avail- 1501 * able from the device (See NOTE 65 in the scsi-2 specification 1502 * around the inquiry command.) We don't want to create a field in 1503 * the case of a device not able to return valid data. 1504 */ 1505 trailer = 1; 1506 for (p = field + length - 1; p >= field; p--) { 1507 if (trailer) { 1508 if ((*p == ' ') || (*p == '\0')) { 1509 retval--; 1510 continue; 1511 } 1512 trailer = 0; 1513 } 1514 1515 /* each char must be within 0x20 - 0x7e */ 1516 if (*p < 0x20 || *p > 0x7e) { 1517 retval = -1; 1518 break; 1519 } 1520 1521 } 1522 1523 return (retval); 1524 } 1525