diff options
| author | Pawel Wojcik <Pawel.Wojcik@Sun.COM> | 2008-11-19 21:52:14 -0800 |
|---|---|---|
| committer | Pawel Wojcik <Pawel.Wojcik@Sun.COM> | 2008-11-19 21:52:14 -0800 |
| commit | 275e36bf470b114b8fe92ae8574f8db1a3d7c053 (patch) | |
| tree | 59f72b7f2e84224893d7bd3ce613359ee9c16910 /usr/src | |
| parent | 94fff7907278e4540aa7abee2b1b0ea71d36f7fa (diff) | |
| download | illumos-joyent-275e36bf470b114b8fe92ae8574f8db1a3d7c053.tar.gz | |
6771971 sata:invalid serial number in inquiry page 0x80 if sata disk SN field contains leading spaces
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/uts/common/io/sata/impl/sata.c | 65 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/sata/impl/sata.h | 2 |
2 files changed, 44 insertions, 23 deletions
diff --git a/usr/src/uts/common/io/sata/impl/sata.c b/usr/src/uts/common/io/sata/impl/sata.c index 5b5f06fc08..aa4deee739 100644 --- a/usr/src/uts/common/io/sata/impl/sata.c +++ b/usr/src/uts/common/io/sata/impl/sata.c @@ -129,7 +129,7 @@ static void sata_inject_pkt_fault(sata_pkt_t *, int *, int); #define LEGACY_HWID_LEN 64 /* Model (40) + Serial (20) + pad */ -static char sata_rev_tag[] = {"1.40"}; +static char sata_rev_tag[] = {"1.41"}; /* * SATA cb_ops functions @@ -3149,7 +3149,7 @@ sata_txlt_inquiry(sata_pkt_txlate_t *spx) /* * Request for suported Vital Product Data * pages - assuming only 2 page codes - * supported + * supported. */ page_buf[0] = peripheral_device_type; page_buf[1] = INQUIRY_SUP_VPD_PAGE; @@ -3161,42 +3161,63 @@ sata_txlt_inquiry(sata_pkt_txlate_t *spx) count = MIN(bp->b_bcount, 6); bcopy(page_buf, bp->b_un.b_addr, count); break; + case INQUIRY_USN_PAGE: /* - * Request for Unit Serial Number page + * Request for Unit Serial Number page. + * Set-up the page. */ page_buf[0] = peripheral_device_type; page_buf[1] = INQUIRY_USN_PAGE; page_buf[2] = 0; - page_buf[3] = 20; /* remaining page length */ + /* remaining page length */ + page_buf[3] = SATA_ID_SERIAL_LEN; + + /* + * Copy serial number from Identify Device data + * words into the inquiry page and swap bytes + * when necessary. + */ p = (uint8_t *)(sdinfo->satadrv_id.ai_drvser); #ifdef _LITTLE_ENDIAN - swab(p, &page_buf[4], 20); + swab(p, &page_buf[4], SATA_ID_SERIAL_LEN); #else - bcopy(p, &page_buf[4], 20); + bcopy(p, &page_buf[4], SATA_ID_SERIAL_LEN); #endif - for (i = 0; i < 20; i++) { - if (page_buf[4 + i] == '\0' || - page_buf[4 + i] == '\040') { - break; - } - } /* - * 'i' contains string length. - * * Least significant character of the serial * number shall appear as the last byte, * according to SBC-3 spec. + * Count trailing spaces to determine the + * necessary shift length. */ - p = &page_buf[20 + 4 - 1]; - for (j = i; j > 0; j--, p--) { - *p = *(p - 20 + i); - } - p = &page_buf[4]; - for (j = 20 - i; j > 0; j--) { - *p++ = '\040'; + p = &page_buf[SATA_ID_SERIAL_LEN + 4 - 1]; + for (j = 0; j < SATA_ID_SERIAL_LEN; j++) { + if (*(p - j) != '\0' && + *(p - j) != '\040') + break; } - count = MIN(bp->b_bcount, 24); + + /* + * Shift SN string right, so that the last + * non-blank character would appear in last + * byte of SN field in the page. + * 'j' is the shift length. + */ + for (i = 0; + i < (SATA_ID_SERIAL_LEN - j) && j != 0; + i++, p--) + *p = *(p - j); + + /* + * Add leading spaces - same number as the + * shift size + */ + for (; j > 0; j--) + page_buf[4 + j - 1] = '\040'; + + count = MIN(bp->b_bcount, + SATA_ID_SERIAL_LEN + 4); bcopy(page_buf, bp->b_un.b_addr, count); break; diff --git a/usr/src/uts/common/sys/sata/impl/sata.h b/usr/src/uts/common/sys/sata/impl/sata.h index dc65cc95a1..20ad35e426 100644 --- a/usr/src/uts/common/sys/sata/impl/sata.h +++ b/usr/src/uts/common/sys/sata/impl/sata.h @@ -764,7 +764,7 @@ typedef struct sata_atapi_cmd { #endif -/* sata_rev_tag 1.40 */ +/* sata_rev_tag 1.41 */ #ifdef __cplusplus } |
