aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-scsi.c
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-03-21 20:37:47 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-21 20:37:47 -0500
commitb142eb6594003d3f82fd552a9b2ad73d774465d2 (patch)
tree895129c0dae624ea577fd4f71bc0ddec5453d6e4 /drivers/scsi/libata-scsi.c
parente0f4ab8a1741193891f096aa63df9ac8672af54c (diff)
[libata] SCSI VPD page 0x83 fixes
Original patch (and description) by Douglas Gilbert, with minor fixes and API updates from me. Changelog: - make existing libata VPD device identification page (0x83) supply the ATA serial number in the libata "vendor specific" designator (from Chris Paulson-Ellis) - add a "t10 vendor id based" designator as defined in SAT rev 08 (section 10.3.4.2.3) that supplies ATA model and serial numbers - make the libata VPD page 0x83 more extensible (for adding more designators in the future). - rename EVPD to VPD in various places. Enable Vital Product Data (EVPD) is a bit in the INQUIRY cdb. Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r--drivers/scsi/libata-scsi.c59
1 files changed, 41 insertions, 18 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index ccedb4536977..3aaa74cbef1d 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -1542,7 +1542,7 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
1542 * @buflen: Response buffer length. 1542 * @buflen: Response buffer length.
1543 * 1543 *
1544 * Returns standard device identification data associated 1544 * Returns standard device identification data associated
1545 * with non-EVPD INQUIRY command output. 1545 * with non-VPD INQUIRY command output.
1546 * 1546 *
1547 * LOCKING: 1547 * LOCKING:
1548 * spin_lock_irqsave(host_set lock) 1548 * spin_lock_irqsave(host_set lock)
@@ -1593,12 +1593,12 @@ unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,
1593} 1593}
1594 1594
1595/** 1595/**
1596 * ata_scsiop_inq_00 - Simulate INQUIRY EVPD page 0, list of pages 1596 * ata_scsiop_inq_00 - Simulate INQUIRY VPD page 0, list of pages
1597 * @args: device IDENTIFY data / SCSI command of interest. 1597 * @args: device IDENTIFY data / SCSI command of interest.
1598 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 1598 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
1599 * @buflen: Response buffer length. 1599 * @buflen: Response buffer length.
1600 * 1600 *
1601 * Returns list of inquiry EVPD pages available. 1601 * Returns list of inquiry VPD pages available.
1602 * 1602 *
1603 * LOCKING: 1603 * LOCKING:
1604 * spin_lock_irqsave(host_set lock) 1604 * spin_lock_irqsave(host_set lock)
@@ -1612,7 +1612,7 @@ unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf,
1612 0x80, /* page 0x80, unit serial no page */ 1612 0x80, /* page 0x80, unit serial no page */
1613 0x83 /* page 0x83, device ident page */ 1613 0x83 /* page 0x83, device ident page */
1614 }; 1614 };
1615 rbuf[3] = sizeof(pages); /* number of supported EVPD pages */ 1615 rbuf[3] = sizeof(pages); /* number of supported VPD pages */
1616 1616
1617 if (buflen > 6) 1617 if (buflen > 6)
1618 memcpy(rbuf + 4, pages, sizeof(pages)); 1618 memcpy(rbuf + 4, pages, sizeof(pages));
@@ -1621,7 +1621,7 @@ unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf,
1621} 1621}
1622 1622
1623/** 1623/**
1624 * ata_scsiop_inq_80 - Simulate INQUIRY EVPD page 80, device serial number 1624 * ata_scsiop_inq_80 - Simulate INQUIRY VPD page 80, device serial number
1625 * @args: device IDENTIFY data / SCSI command of interest. 1625 * @args: device IDENTIFY data / SCSI command of interest.
1626 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 1626 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
1627 * @buflen: Response buffer length. 1627 * @buflen: Response buffer length.
@@ -1650,16 +1650,16 @@ unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf,
1650 return 0; 1650 return 0;
1651} 1651}
1652 1652
1653static const char * const inq_83_str = "Linux ATA-SCSI simulator";
1654
1655/** 1653/**
1656 * ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity 1654 * ata_scsiop_inq_83 - Simulate INQUIRY VPD page 83, device identity
1657 * @args: device IDENTIFY data / SCSI command of interest. 1655 * @args: device IDENTIFY data / SCSI command of interest.
1658 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 1656 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
1659 * @buflen: Response buffer length. 1657 * @buflen: Response buffer length.
1660 * 1658 *
1661 * Returns device identification. Currently hardcoded to 1659 * Yields two logical unit device identification designators:
1662 * return "Linux ATA-SCSI simulator". 1660 * - vendor specific ASCII containing the ATA serial number
1661 * - SAT defined "t10 vendor id based" containing ASCII vendor
1662 * name ("ATA "), model and serial numbers.
1663 * 1663 *
1664 * LOCKING: 1664 * LOCKING:
1665 * spin_lock_irqsave(host_set lock) 1665 * spin_lock_irqsave(host_set lock)
@@ -1668,16 +1668,39 @@ static const char * const inq_83_str = "Linux ATA-SCSI simulator";
1668unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf, 1668unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf,
1669 unsigned int buflen) 1669 unsigned int buflen)
1670{ 1670{
1671 rbuf[1] = 0x83; /* this page code */ 1671 int num;
1672 rbuf[3] = 4 + strlen(inq_83_str); /* page len */ 1672 const int sat_model_serial_desc_len = 68;
1673 const int ata_model_byte_len = 40;
1673 1674
1674 /* our one and only identification descriptor (vendor-specific) */ 1675 rbuf[1] = 0x83; /* this page code */
1675 if (buflen > (strlen(inq_83_str) + 4 + 4 - 1)) { 1676 num = 4;
1676 rbuf[4 + 0] = 2; /* code set: ASCII */ 1677
1677 rbuf[4 + 3] = strlen(inq_83_str); 1678 if (buflen > (ATA_SERNO_LEN + num + 3)) {
1678 memcpy(rbuf + 4 + 4, inq_83_str, strlen(inq_83_str)); 1679 /* piv=0, assoc=lu, code_set=ACSII, designator=vendor */
1680 rbuf[num + 0] = 2;
1681 rbuf[num + 3] = ATA_SERNO_LEN;
1682 num += 4;
1683 ata_id_string(args->id, (unsigned char *) rbuf + num,
1684 ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
1685 num += ATA_SERNO_LEN;
1679 } 1686 }
1680 1687 if (buflen > (sat_model_serial_desc_len + num + 3)) {
1688 /* SAT defined lu model and serial numbers descriptor */
1689 /* piv=0, assoc=lu, code_set=ACSII, designator=t10 vendor id */
1690 rbuf[num + 0] = 2;
1691 rbuf[num + 1] = 1;
1692 rbuf[num + 3] = sat_model_serial_desc_len;
1693 num += 4;
1694 memcpy(rbuf + num, "ATA ", 8);
1695 num += 8;
1696 ata_id_string(args->id, (unsigned char *) rbuf + num,
1697 ATA_ID_PROD_OFS, ata_model_byte_len);
1698 num += ata_model_byte_len;
1699 ata_id_string(args->id, (unsigned char *) rbuf + num,
1700 ATA_ID_SERNO_OFS, ATA_SERNO_LEN);
1701 num += ATA_SERNO_LEN;
1702 }
1703 rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */
1681 return 0; 1704 return 0;
1682} 1705}
1683 1706