aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/nvme-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/nvme-scsi.c')
-rw-r--r--drivers/block/nvme-scsi.c96
1 files changed, 54 insertions, 42 deletions
diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c
index 5e78568026c3..e10196e0182d 100644
--- a/drivers/block/nvme-scsi.c
+++ b/drivers/block/nvme-scsi.c
@@ -779,10 +779,8 @@ static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
779 struct nvme_dev *dev = ns->dev; 779 struct nvme_dev *dev = ns->dev;
780 dma_addr_t dma_addr; 780 dma_addr_t dma_addr;
781 void *mem; 781 void *mem;
782 struct nvme_id_ctrl *id_ctrl;
783 int res = SNTI_TRANSLATION_SUCCESS; 782 int res = SNTI_TRANSLATION_SUCCESS;
784 int nvme_sc; 783 int nvme_sc;
785 u8 ieee[4];
786 int xfer_len; 784 int xfer_len;
787 __be32 tmp_id = cpu_to_be32(ns->ns_id); 785 __be32 tmp_id = cpu_to_be32(ns->ns_id);
788 786
@@ -793,46 +791,60 @@ static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
793 goto out_dma; 791 goto out_dma;
794 } 792 }
795 793
796 /* nvme controller identify */ 794 memset(inq_response, 0, alloc_len);
797 nvme_sc = nvme_identify(dev, 0, 1, dma_addr);
798 res = nvme_trans_status_code(hdr, nvme_sc);
799 if (res)
800 goto out_free;
801 if (nvme_sc) {
802 res = nvme_sc;
803 goto out_free;
804 }
805 id_ctrl = mem;
806
807 /* Since SCSI tried to save 4 bits... [SPC-4(r34) Table 591] */
808 ieee[0] = id_ctrl->ieee[0] << 4;
809 ieee[1] = id_ctrl->ieee[0] >> 4 | id_ctrl->ieee[1] << 4;
810 ieee[2] = id_ctrl->ieee[1] >> 4 | id_ctrl->ieee[2] << 4;
811 ieee[3] = id_ctrl->ieee[2] >> 4;
812
813 memset(inq_response, 0, STANDARD_INQUIRY_LENGTH);
814 inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE; /* Page Code */ 795 inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE; /* Page Code */
815 inq_response[3] = 20; /* Page Length */ 796 if (readl(&dev->bar->vs) >= NVME_VS(1, 1)) {
816 /* Designation Descriptor start */ 797 struct nvme_id_ns *id_ns = mem;
817 inq_response[4] = 0x01; /* Proto ID=0h | Code set=1h */ 798 void *eui = id_ns->eui64;
818 inq_response[5] = 0x03; /* PIV=0b | Asso=00b | Designator Type=3h */ 799 int len = sizeof(id_ns->eui64);
819 inq_response[6] = 0x00; /* Rsvd */
820 inq_response[7] = 16; /* Designator Length */
821 /* Designator start */
822 inq_response[8] = 0x60 | ieee[3]; /* NAA=6h | IEEE ID MSB, High nibble*/
823 inq_response[9] = ieee[2]; /* IEEE ID */
824 inq_response[10] = ieee[1]; /* IEEE ID */
825 inq_response[11] = ieee[0]; /* IEEE ID| Vendor Specific ID... */
826 inq_response[12] = (dev->pci_dev->vendor & 0xFF00) >> 8;
827 inq_response[13] = (dev->pci_dev->vendor & 0x00FF);
828 inq_response[14] = dev->serial[0];
829 inq_response[15] = dev->serial[1];
830 inq_response[16] = dev->model[0];
831 inq_response[17] = dev->model[1];
832 memcpy(&inq_response[18], &tmp_id, sizeof(u32));
833 /* Last 2 bytes are zero */
834 800
835 xfer_len = min(alloc_len, STANDARD_INQUIRY_LENGTH); 801 nvme_sc = nvme_identify(dev, ns->ns_id, 0, dma_addr);
802 res = nvme_trans_status_code(hdr, nvme_sc);
803 if (res)
804 goto out_free;
805 if (nvme_sc) {
806 res = nvme_sc;
807 goto out_free;
808 }
809
810 if (readl(&dev->bar->vs) >= NVME_VS(1, 2)) {
811 if (bitmap_empty(eui, len * 8)) {
812 eui = id_ns->nguid;
813 len = sizeof(id_ns->nguid);
814 }
815 }
816 if (bitmap_empty(eui, len * 8))
817 goto scsi_string;
818
819 inq_response[3] = 4 + len; /* Page Length */
820 /* Designation Descriptor start */
821 inq_response[4] = 0x01; /* Proto ID=0h | Code set=1h */
822 inq_response[5] = 0x02; /* PIV=0b | Asso=00b | Designator Type=2h */
823 inq_response[6] = 0x00; /* Rsvd */
824 inq_response[7] = len; /* Designator Length */
825 memcpy(&inq_response[8], eui, len);
826 } else {
827 scsi_string:
828 if (alloc_len < 72) {
829 res = nvme_trans_completion(hdr,
830 SAM_STAT_CHECK_CONDITION,
831 ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB,
832 SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
833 goto out_free;
834 }
835 inq_response[3] = 0x48; /* Page Length */
836 /* Designation Descriptor start */
837 inq_response[4] = 0x03; /* Proto ID=0h | Code set=3h */
838 inq_response[5] = 0x08; /* PIV=0b | Asso=00b | Designator Type=8h */
839 inq_response[6] = 0x00; /* Rsvd */
840 inq_response[7] = 0x44; /* Designator Length */
841
842 sprintf(&inq_response[8], "%04x", dev->pci_dev->vendor);
843 memcpy(&inq_response[12], dev->model, sizeof(dev->model));
844 sprintf(&inq_response[52], "%04x", tmp_id);
845 memcpy(&inq_response[56], dev->serial, sizeof(dev->serial));
846 }
847 xfer_len = alloc_len;
836 res = nvme_trans_copy_to_user(hdr, inq_response, xfer_len); 848 res = nvme_trans_copy_to_user(hdr, inq_response, xfer_len);
837 849
838 out_free: 850 out_free:
@@ -1600,7 +1612,7 @@ static inline void nvme_trans_modesel_get_bd_len(u8 *parm_list, u8 cdb10,
1600 /* 10 Byte CDB */ 1612 /* 10 Byte CDB */
1601 *bd_len = (parm_list[MODE_SELECT_10_BD_OFFSET] << 8) + 1613 *bd_len = (parm_list[MODE_SELECT_10_BD_OFFSET] << 8) +
1602 parm_list[MODE_SELECT_10_BD_OFFSET + 1]; 1614 parm_list[MODE_SELECT_10_BD_OFFSET + 1];
1603 *llbaa = parm_list[MODE_SELECT_10_LLBAA_OFFSET] && 1615 *llbaa = parm_list[MODE_SELECT_10_LLBAA_OFFSET] &
1604 MODE_SELECT_10_LLBAA_MASK; 1616 MODE_SELECT_10_LLBAA_MASK;
1605 } else { 1617 } else {
1606 /* 6 Byte CDB */ 1618 /* 6 Byte CDB */
@@ -2222,7 +2234,7 @@ static int nvme_trans_inquiry(struct nvme_ns *ns, struct sg_io_hdr *hdr,
2222 page_code = GET_INQ_PAGE_CODE(cmd); 2234 page_code = GET_INQ_PAGE_CODE(cmd);
2223 alloc_len = GET_INQ_ALLOC_LENGTH(cmd); 2235 alloc_len = GET_INQ_ALLOC_LENGTH(cmd);
2224 2236
2225 inq_response = kmalloc(STANDARD_INQUIRY_LENGTH, GFP_KERNEL); 2237 inq_response = kmalloc(alloc_len, GFP_KERNEL);
2226 if (inq_response == NULL) { 2238 if (inq_response == NULL) {
2227 res = -ENOMEM; 2239 res = -ENOMEM;
2228 goto out_mem; 2240 goto out_mem;