Skip to content

Commit 2f0dad1

Browse files
keithbuschChristoph Hellwig
authored andcommitted
nvme: add bug report info for global duplicate id
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]>
1 parent 1fc766b commit 2f0dad1

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

drivers/nvme/host/core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3863,6 +3863,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid,
38633863
if (ret) {
38643864
dev_err(ctrl->device,
38653865
"globally duplicate IDs for nsid %d\n", nsid);
3866+
nvme_print_device_info(ctrl);
38663867
return ret;
38673868
}
38683869

drivers/nvme/host/nvme.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,7 @@ struct nvme_ctrl_ops {
503503
void (*submit_async_event)(struct nvme_ctrl *ctrl);
504504
void (*delete_ctrl)(struct nvme_ctrl *ctrl);
505505
int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size);
506+
void (*print_device_info)(struct nvme_ctrl *ctrl);
506507
};
507508

508509
/*
@@ -548,6 +549,33 @@ static inline struct request *nvme_cid_to_rq(struct blk_mq_tags *tags,
548549
return blk_mq_tag_to_rq(tags, nvme_tag_from_cid(command_id));
549550
}
550551

552+
/*
553+
* Return the length of the string without the space padding
554+
*/
555+
static inline int nvme_strlen(char *s, int len)
556+
{
557+
while (s[len - 1] == ' ')
558+
len--;
559+
return len;
560+
}
561+
562+
static inline void nvme_print_device_info(struct nvme_ctrl *ctrl)
563+
{
564+
struct nvme_subsystem *subsys = ctrl->subsys;
565+
566+
if (ctrl->ops->print_device_info) {
567+
ctrl->ops->print_device_info(ctrl);
568+
return;
569+
}
570+
571+
dev_err(ctrl->device,
572+
"VID:%04x model:%.*s firmware:%.*s\n", subsys->vendor_id,
573+
nvme_strlen(subsys->model, sizeof(subsys->model)),
574+
subsys->model, nvme_strlen(subsys->firmware_rev,
575+
sizeof(subsys->firmware_rev)),
576+
subsys->firmware_rev);
577+
}
578+
551579
#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
552580
void nvme_fault_inject_init(struct nvme_fault_inject *fault_inj,
553581
const char *dev_name);

drivers/nvme/host/pci.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2976,6 +2976,21 @@ static int nvme_pci_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
29762976
return snprintf(buf, size, "%s\n", dev_name(&pdev->dev));
29772977
}
29782978

2979+
2980+
static void nvme_pci_print_device_info(struct nvme_ctrl *ctrl)
2981+
{
2982+
struct pci_dev *pdev = to_pci_dev(to_nvme_dev(ctrl)->dev);
2983+
struct nvme_subsystem *subsys = ctrl->subsys;
2984+
2985+
dev_err(ctrl->device,
2986+
"VID:DID %04x:%04x model:%.*s firmware:%.*s\n",
2987+
pdev->vendor, pdev->device,
2988+
nvme_strlen(subsys->model, sizeof(subsys->model)),
2989+
subsys->model, nvme_strlen(subsys->firmware_rev,
2990+
sizeof(subsys->firmware_rev)),
2991+
subsys->firmware_rev);
2992+
}
2993+
29792994
static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
29802995
.name = "pcie",
29812996
.module = THIS_MODULE,
@@ -2987,6 +3002,7 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
29873002
.free_ctrl = nvme_pci_free_ctrl,
29883003
.submit_async_event = nvme_pci_submit_async_event,
29893004
.get_address = nvme_pci_get_address,
3005+
.print_device_info = nvme_pci_print_device_info,
29903006
};
29913007

29923008
static int nvme_dev_map(struct nvme_dev *dev)

0 commit comments

Comments
 (0)