summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorPawel Wojcik <Pawel.Wojcik@Sun.COM>2008-11-19 21:52:14 -0800
committerPawel Wojcik <Pawel.Wojcik@Sun.COM>2008-11-19 21:52:14 -0800
commit275e36bf470b114b8fe92ae8574f8db1a3d7c053 (patch)
tree59f72b7f2e84224893d7bd3ce613359ee9c16910 /usr/src
parent94fff7907278e4540aa7abee2b1b0ea71d36f7fa (diff)
downloadillumos-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.c65
-rw-r--r--usr/src/uts/common/sys/sata/impl/sata.h2
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
}