Skip to content

Commit

Permalink
nvme: add bug report info for global duplicate id
Browse files Browse the repository at this point in the history
The recent global id check is finding poorly implemented devices in the
wild. Include relavant device information in the output to help quicken
an appropriate quirk patch.

Signed-off-by: Keith Busch <[email protected]>
Signed-off-by: Christoph Hellwig <[email protected]>
  • Loading branch information
keithbusch authored and Christoph Hellwig committed Jun 13, 2022
1 parent 1fc766b commit 2f0dad1
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/nvme/host/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3863,6 +3863,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid,
if (ret) {
dev_err(ctrl->device,
"globally duplicate IDs for nsid %d\n", nsid);
nvme_print_device_info(ctrl);
return ret;
}

Expand Down
28 changes: 28 additions & 0 deletions drivers/nvme/host/nvme.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ struct nvme_ctrl_ops {
void (*submit_async_event)(struct nvme_ctrl *ctrl);
void (*delete_ctrl)(struct nvme_ctrl *ctrl);
int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size);
void (*print_device_info)(struct nvme_ctrl *ctrl);
};

/*
Expand Down Expand Up @@ -548,6 +549,33 @@ static inline struct request *nvme_cid_to_rq(struct blk_mq_tags *tags,
return blk_mq_tag_to_rq(tags, nvme_tag_from_cid(command_id));
}

/*
* Return the length of the string without the space padding
*/
static inline int nvme_strlen(char *s, int len)
{
while (s[len - 1] == ' ')
len--;
return len;
}

static inline void nvme_print_device_info(struct nvme_ctrl *ctrl)
{
struct nvme_subsystem *subsys = ctrl->subsys;

if (ctrl->ops->print_device_info) {
ctrl->ops->print_device_info(ctrl);
return;
}

dev_err(ctrl->device,
"VID:%04x model:%.*s firmware:%.*s\n", subsys->vendor_id,
nvme_strlen(subsys->model, sizeof(subsys->model)),
subsys->model, nvme_strlen(subsys->firmware_rev,
sizeof(subsys->firmware_rev)),
subsys->firmware_rev);
}

#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
void nvme_fault_inject_init(struct nvme_fault_inject *fault_inj,
const char *dev_name);
Expand Down
16 changes: 16 additions & 0 deletions drivers/nvme/host/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -2976,6 +2976,21 @@ static int nvme_pci_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
return snprintf(buf, size, "%s\n", dev_name(&pdev->dev));
}


static void nvme_pci_print_device_info(struct nvme_ctrl *ctrl)
{
struct pci_dev *pdev = to_pci_dev(to_nvme_dev(ctrl)->dev);
struct nvme_subsystem *subsys = ctrl->subsys;

dev_err(ctrl->device,
"VID:DID %04x:%04x model:%.*s firmware:%.*s\n",
pdev->vendor, pdev->device,
nvme_strlen(subsys->model, sizeof(subsys->model)),
subsys->model, nvme_strlen(subsys->firmware_rev,
sizeof(subsys->firmware_rev)),
subsys->firmware_rev);
}

static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
.name = "pcie",
.module = THIS_MODULE,
Expand All @@ -2987,6 +3002,7 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
.free_ctrl = nvme_pci_free_ctrl,
.submit_async_event = nvme_pci_submit_async_event,
.get_address = nvme_pci_get_address,
.print_device_info = nvme_pci_print_device_info,
};

static int nvme_dev_map(struct nvme_dev *dev)
Expand Down

0 comments on commit 2f0dad1

Please sign in to comment.