diff options
author | Keith Busch <keith.busch@intel.com> | 2015-04-07 17:34:18 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2015-04-07 21:11:04 -0400 |
commit | 7f749d9c109223e4d1724e674e7d603082e85839 (patch) | |
tree | 5df24f1d7dc7c59cae7ad1dedc6c342aa7deec0f /drivers/block | |
parent | 447228023eaa8c96a48a8a459be7a992008df830 (diff) |
NVMe: Add translation for block limits
Adds SCSI-to-NVMe translation for VPD B0h, block limits inquiry data.
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/nvme-scsi.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c index e10196e0182d..6b736b00f63e 100644 --- a/drivers/block/nvme-scsi.c +++ b/drivers/block/nvme-scsi.c | |||
@@ -55,6 +55,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */ | |||
55 | #define VPD_SERIAL_NUMBER 0x80 | 55 | #define VPD_SERIAL_NUMBER 0x80 |
56 | #define VPD_DEVICE_IDENTIFIERS 0x83 | 56 | #define VPD_DEVICE_IDENTIFIERS 0x83 |
57 | #define VPD_EXTENDED_INQUIRY 0x86 | 57 | #define VPD_EXTENDED_INQUIRY 0x86 |
58 | #define VPD_BLOCK_LIMITS 0xB0 | ||
58 | #define VPD_BLOCK_DEV_CHARACTERISTICS 0xB1 | 59 | #define VPD_BLOCK_DEV_CHARACTERISTICS 0xB1 |
59 | 60 | ||
60 | /* CDB offsets */ | 61 | /* CDB offsets */ |
@@ -132,9 +133,10 @@ static int sg_version_num = 30534; /* 2 digits for each component */ | |||
132 | #define INQ_UNIT_SERIAL_NUMBER_PAGE 0x80 | 133 | #define INQ_UNIT_SERIAL_NUMBER_PAGE 0x80 |
133 | #define INQ_DEVICE_IDENTIFICATION_PAGE 0x83 | 134 | #define INQ_DEVICE_IDENTIFICATION_PAGE 0x83 |
134 | #define INQ_EXTENDED_INQUIRY_DATA_PAGE 0x86 | 135 | #define INQ_EXTENDED_INQUIRY_DATA_PAGE 0x86 |
136 | #define INQ_BDEV_LIMITS_PAGE 0xB0 | ||
135 | #define INQ_BDEV_CHARACTERISTICS_PAGE 0xB1 | 137 | #define INQ_BDEV_CHARACTERISTICS_PAGE 0xB1 |
136 | #define INQ_SERIAL_NUMBER_LENGTH 0x14 | 138 | #define INQ_SERIAL_NUMBER_LENGTH 0x14 |
137 | #define INQ_NUM_SUPPORTED_VPD_PAGES 5 | 139 | #define INQ_NUM_SUPPORTED_VPD_PAGES 6 |
138 | #define VERSION_SPC_4 0x06 | 140 | #define VERSION_SPC_4 0x06 |
139 | #define ACA_UNSUPPORTED 0 | 141 | #define ACA_UNSUPPORTED 0 |
140 | #define STANDARD_INQUIRY_LENGTH 36 | 142 | #define STANDARD_INQUIRY_LENGTH 36 |
@@ -747,6 +749,7 @@ static int nvme_trans_supported_vpd_pages(struct nvme_ns *ns, | |||
747 | inq_response[6] = INQ_DEVICE_IDENTIFICATION_PAGE; | 749 | inq_response[6] = INQ_DEVICE_IDENTIFICATION_PAGE; |
748 | inq_response[7] = INQ_EXTENDED_INQUIRY_DATA_PAGE; | 750 | inq_response[7] = INQ_EXTENDED_INQUIRY_DATA_PAGE; |
749 | inq_response[8] = INQ_BDEV_CHARACTERISTICS_PAGE; | 751 | inq_response[8] = INQ_BDEV_CHARACTERISTICS_PAGE; |
752 | inq_response[9] = INQ_BDEV_LIMITS_PAGE; | ||
750 | 753 | ||
751 | xfer_len = min(alloc_len, STANDARD_INQUIRY_LENGTH); | 754 | xfer_len = min(alloc_len, STANDARD_INQUIRY_LENGTH); |
752 | res = nvme_trans_copy_to_user(hdr, inq_response, xfer_len); | 755 | res = nvme_trans_copy_to_user(hdr, inq_response, xfer_len); |
@@ -938,6 +941,25 @@ static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, | |||
938 | return res; | 941 | return res; |
939 | } | 942 | } |
940 | 943 | ||
944 | static int nvme_trans_bdev_limits_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, | ||
945 | u8 *inq_response, int alloc_len) | ||
946 | { | ||
947 | __be32 max_sectors = cpu_to_be32(queue_max_hw_sectors(ns->queue)); | ||
948 | __be32 max_discard = cpu_to_be32(ns->queue->limits.max_discard_sectors); | ||
949 | __be32 discard_desc_count = cpu_to_be32(0x100); | ||
950 | |||
951 | memset(inq_response, 0, STANDARD_INQUIRY_LENGTH); | ||
952 | inq_response[1] = VPD_BLOCK_LIMITS; | ||
953 | inq_response[3] = 0x3c; /* Page Length */ | ||
954 | memcpy(&inq_response[8], &max_sectors, sizeof(u32)); | ||
955 | memcpy(&inq_response[20], &max_discard, sizeof(u32)); | ||
956 | |||
957 | if (max_discard) | ||
958 | memcpy(&inq_response[24], &discard_desc_count, sizeof(u32)); | ||
959 | |||
960 | return nvme_trans_copy_to_user(hdr, inq_response, 0x3c); | ||
961 | } | ||
962 | |||
941 | static int nvme_trans_bdev_char_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, | 963 | static int nvme_trans_bdev_char_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, |
942 | int alloc_len) | 964 | int alloc_len) |
943 | { | 965 | { |
@@ -2268,6 +2290,10 @@ static int nvme_trans_inquiry(struct nvme_ns *ns, struct sg_io_hdr *hdr, | |||
2268 | case VPD_EXTENDED_INQUIRY: | 2290 | case VPD_EXTENDED_INQUIRY: |
2269 | res = nvme_trans_ext_inq_page(ns, hdr, alloc_len); | 2291 | res = nvme_trans_ext_inq_page(ns, hdr, alloc_len); |
2270 | break; | 2292 | break; |
2293 | case VPD_BLOCK_LIMITS: | ||
2294 | res = nvme_trans_bdev_limits_page(ns, hdr, inq_response, | ||
2295 | alloc_len); | ||
2296 | break; | ||
2271 | case VPD_BLOCK_DEV_CHARACTERISTICS: | 2297 | case VPD_BLOCK_DEV_CHARACTERISTICS: |
2272 | res = nvme_trans_bdev_char_page(ns, hdr, alloc_len); | 2298 | res = nvme_trans_bdev_char_page(ns, hdr, alloc_len); |
2273 | break; | 2299 | break; |