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 <kbusch@kernel.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
Keith Busch 2022-06-07 08:30:29 -07:00 committed by Christoph Hellwig
parent 1fc766b5c0
commit 2f0dad1719
3 changed files with 45 additions and 0 deletions

View File

@ -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;
}

View File

@ -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);
};
/*
@ -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);

View File

@ -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,
@ -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)