Loading drivers/nvme/host/scsi.c +79 −56 Original line number Original line Diff line number Diff line Loading @@ -600,57 +600,67 @@ static int nvme_trans_unit_serial_page(struct nvme_ns *ns, return nvme_trans_copy_to_user(hdr, inq_response, xfer_len); return nvme_trans_copy_to_user(hdr, inq_response, xfer_len); } } static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, static int nvme_fill_device_id_eui64(struct nvme_ns *ns, struct sg_io_hdr *hdr, u8 *inq_response, int alloc_len) u8 *inq_response, int alloc_len) { { struct nvme_dev *dev = ns->dev; int res; int nvme_sc; int xfer_len; __be32 tmp_id = cpu_to_be32(ns->ns_id); memset(inq_response, 0, alloc_len); inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE; /* Page Code */ if (readl(dev->bar + NVME_REG_VS) >= NVME_VS(1, 1)) { struct nvme_id_ns *id_ns; struct nvme_id_ns *id_ns; int nvme_sc, res; size_t len; void *eui; void *eui; int len; nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns); nvme_sc = nvme_identify_ns(ns->dev, ns->ns_id, &id_ns); res = nvme_trans_status_code(hdr, nvme_sc); res = nvme_trans_status_code(hdr, nvme_sc); if (res) if (res) return res; return res; eui = id_ns->eui64; eui = id_ns->eui64; len = sizeof(id_ns->eui64); len = sizeof(id_ns->eui64); if (readl(dev->bar + NVME_REG_VS) >= NVME_VS(1, 2)) { if (readl(ns->dev->bar + NVME_REG_VS) >= NVME_VS(1, 2)) { if (bitmap_empty(eui, len * 8)) { if (bitmap_empty(eui, len * 8)) { eui = id_ns->nguid; eui = id_ns->nguid; len = sizeof(id_ns->nguid); len = sizeof(id_ns->nguid); } } } } if (bitmap_empty(eui, len * 8)) { if (bitmap_empty(eui, len * 8)) { kfree(id_ns); res = -EOPNOTSUPP; goto scsi_string; goto out_free_id; } } memset(inq_response, 0, alloc_len); inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE; inq_response[3] = 4 + len; /* Page Length */ inq_response[3] = 4 + len; /* Page Length */ /* Designation Descriptor start */ /* Designation Descriptor start */ inq_response[4] = 0x01; /* Proto ID=0h | Code set=1h */ inq_response[4] = 0x01; /* Proto ID=0h | Code set=1h */ inq_response[5] = 0x02; /* PIV=0b | Asso=00b | Designator Type=2h */ inq_response[5] = 0x02; /* PIV=0b | Asso=00b | Designator Type=2h */ inq_response[6] = 0x00; /* Rsvd */ inq_response[6] = 0x00; /* Rsvd */ inq_response[7] = len; /* Designator Length */ inq_response[7] = len; /* Designator Length */ memcpy(&inq_response[8], eui, len); memcpy(&inq_response[8], eui, len); res = nvme_trans_copy_to_user(hdr, inq_response, alloc_len); out_free_id: kfree(id_ns); kfree(id_ns); } else { return res; scsi_string: } static int nvme_fill_device_id_scsi_string(struct nvme_ns *ns, struct sg_io_hdr *hdr, u8 *inq_response, int alloc_len) { struct nvme_dev *dev = ns->dev; if (alloc_len < 72) { if (alloc_len < 72) { return nvme_trans_completion(hdr, return nvme_trans_completion(hdr, SAM_STAT_CHECK_CONDITION, SAM_STAT_CHECK_CONDITION, ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB, ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB, SCSI_ASCQ_CAUSE_NOT_REPORTABLE); SCSI_ASCQ_CAUSE_NOT_REPORTABLE); } } memset(inq_response, 0, alloc_len); inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE; inq_response[3] = 0x48; /* Page Length */ inq_response[3] = 0x48; /* Page Length */ /* Designation Descriptor start */ /* Designation Descriptor start */ inq_response[4] = 0x03; /* Proto ID=0h | Code set=3h */ inq_response[4] = 0x03; /* Proto ID=0h | Code set=3h */ inq_response[5] = 0x08; /* PIV=0b | Asso=00b | Designator Type=8h */ inq_response[5] = 0x08; /* PIV=0b | Asso=00b | Designator Type=8h */ Loading @@ -659,11 +669,24 @@ static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, sprintf(&inq_response[8], "%04x", to_pci_dev(dev->dev)->vendor); sprintf(&inq_response[8], "%04x", to_pci_dev(dev->dev)->vendor); memcpy(&inq_response[12], dev->model, sizeof(dev->model)); memcpy(&inq_response[12], dev->model, sizeof(dev->model)); sprintf(&inq_response[52], "%04x", tmp_id); sprintf(&inq_response[52], "%04x", cpu_to_be32(ns->ns_id)); memcpy(&inq_response[56], dev->serial, sizeof(dev->serial)); memcpy(&inq_response[56], dev->serial, sizeof(dev->serial)); return nvme_trans_copy_to_user(hdr, inq_response, alloc_len); } } xfer_len = alloc_len; return nvme_trans_copy_to_user(hdr, inq_response, xfer_len); static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, u8 *resp, int alloc_len) { int res; if (readl(ns->dev->bar + NVME_REG_VS) >= NVME_VS(1, 1)) { res = nvme_fill_device_id_eui64(ns, hdr, resp, alloc_len); if (res != -EOPNOTSUPP) return res; } return nvme_fill_device_id_scsi_string(ns, hdr, resp, alloc_len); } } static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, Loading Loading
drivers/nvme/host/scsi.c +79 −56 Original line number Original line Diff line number Diff line Loading @@ -600,57 +600,67 @@ static int nvme_trans_unit_serial_page(struct nvme_ns *ns, return nvme_trans_copy_to_user(hdr, inq_response, xfer_len); return nvme_trans_copy_to_user(hdr, inq_response, xfer_len); } } static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, static int nvme_fill_device_id_eui64(struct nvme_ns *ns, struct sg_io_hdr *hdr, u8 *inq_response, int alloc_len) u8 *inq_response, int alloc_len) { { struct nvme_dev *dev = ns->dev; int res; int nvme_sc; int xfer_len; __be32 tmp_id = cpu_to_be32(ns->ns_id); memset(inq_response, 0, alloc_len); inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE; /* Page Code */ if (readl(dev->bar + NVME_REG_VS) >= NVME_VS(1, 1)) { struct nvme_id_ns *id_ns; struct nvme_id_ns *id_ns; int nvme_sc, res; size_t len; void *eui; void *eui; int len; nvme_sc = nvme_identify_ns(dev, ns->ns_id, &id_ns); nvme_sc = nvme_identify_ns(ns->dev, ns->ns_id, &id_ns); res = nvme_trans_status_code(hdr, nvme_sc); res = nvme_trans_status_code(hdr, nvme_sc); if (res) if (res) return res; return res; eui = id_ns->eui64; eui = id_ns->eui64; len = sizeof(id_ns->eui64); len = sizeof(id_ns->eui64); if (readl(dev->bar + NVME_REG_VS) >= NVME_VS(1, 2)) { if (readl(ns->dev->bar + NVME_REG_VS) >= NVME_VS(1, 2)) { if (bitmap_empty(eui, len * 8)) { if (bitmap_empty(eui, len * 8)) { eui = id_ns->nguid; eui = id_ns->nguid; len = sizeof(id_ns->nguid); len = sizeof(id_ns->nguid); } } } } if (bitmap_empty(eui, len * 8)) { if (bitmap_empty(eui, len * 8)) { kfree(id_ns); res = -EOPNOTSUPP; goto scsi_string; goto out_free_id; } } memset(inq_response, 0, alloc_len); inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE; inq_response[3] = 4 + len; /* Page Length */ inq_response[3] = 4 + len; /* Page Length */ /* Designation Descriptor start */ /* Designation Descriptor start */ inq_response[4] = 0x01; /* Proto ID=0h | Code set=1h */ inq_response[4] = 0x01; /* Proto ID=0h | Code set=1h */ inq_response[5] = 0x02; /* PIV=0b | Asso=00b | Designator Type=2h */ inq_response[5] = 0x02; /* PIV=0b | Asso=00b | Designator Type=2h */ inq_response[6] = 0x00; /* Rsvd */ inq_response[6] = 0x00; /* Rsvd */ inq_response[7] = len; /* Designator Length */ inq_response[7] = len; /* Designator Length */ memcpy(&inq_response[8], eui, len); memcpy(&inq_response[8], eui, len); res = nvme_trans_copy_to_user(hdr, inq_response, alloc_len); out_free_id: kfree(id_ns); kfree(id_ns); } else { return res; scsi_string: } static int nvme_fill_device_id_scsi_string(struct nvme_ns *ns, struct sg_io_hdr *hdr, u8 *inq_response, int alloc_len) { struct nvme_dev *dev = ns->dev; if (alloc_len < 72) { if (alloc_len < 72) { return nvme_trans_completion(hdr, return nvme_trans_completion(hdr, SAM_STAT_CHECK_CONDITION, SAM_STAT_CHECK_CONDITION, ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB, ILLEGAL_REQUEST, SCSI_ASC_INVALID_CDB, SCSI_ASCQ_CAUSE_NOT_REPORTABLE); SCSI_ASCQ_CAUSE_NOT_REPORTABLE); } } memset(inq_response, 0, alloc_len); inq_response[1] = INQ_DEVICE_IDENTIFICATION_PAGE; inq_response[3] = 0x48; /* Page Length */ inq_response[3] = 0x48; /* Page Length */ /* Designation Descriptor start */ /* Designation Descriptor start */ inq_response[4] = 0x03; /* Proto ID=0h | Code set=3h */ inq_response[4] = 0x03; /* Proto ID=0h | Code set=3h */ inq_response[5] = 0x08; /* PIV=0b | Asso=00b | Designator Type=8h */ inq_response[5] = 0x08; /* PIV=0b | Asso=00b | Designator Type=8h */ Loading @@ -659,11 +669,24 @@ static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, sprintf(&inq_response[8], "%04x", to_pci_dev(dev->dev)->vendor); sprintf(&inq_response[8], "%04x", to_pci_dev(dev->dev)->vendor); memcpy(&inq_response[12], dev->model, sizeof(dev->model)); memcpy(&inq_response[12], dev->model, sizeof(dev->model)); sprintf(&inq_response[52], "%04x", tmp_id); sprintf(&inq_response[52], "%04x", cpu_to_be32(ns->ns_id)); memcpy(&inq_response[56], dev->serial, sizeof(dev->serial)); memcpy(&inq_response[56], dev->serial, sizeof(dev->serial)); return nvme_trans_copy_to_user(hdr, inq_response, alloc_len); } } xfer_len = alloc_len; return nvme_trans_copy_to_user(hdr, inq_response, xfer_len); static int nvme_trans_device_id_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, u8 *resp, int alloc_len) { int res; if (readl(ns->dev->bar + NVME_REG_VS) >= NVME_VS(1, 1)) { res = nvme_fill_device_id_eui64(ns, hdr, resp, alloc_len); if (res != -EOPNOTSUPP) return res; } return nvme_fill_device_id_scsi_string(ns, hdr, resp, alloc_len); } } static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr, Loading