diff options
Diffstat (limited to 'drivers/block/nvme-scsi.c')
-rw-r--r-- | drivers/block/nvme-scsi.c | 96 |
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; |