mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 02:53:36 +02:00
nvmet: Implement interrupt config feature support
The NVMe base specifications v2.1 mandate supporting the interrupt config feature (NVME_FEAT_IRQ_CONFIG) for PCI controllers. Introduce the data structure struct nvmet_feat_irq_config to define the coalescing disabled (cd) and interrupt vector (iv) fields of this feature and implement the functions nvmet_get_feat_irq_config() and nvmet_set_feat_irq_config() functions to get and set these fields. These functions respectively use the controller get_feature() and set_feature() operations to fill and handle the fields of struct nvmet_feat_irq_config. Support for this feature is prohibited for fabrics controllers. If a get feature command or a set feature command for this feature is received for a fabrics controller, the command is failed with an invalid field error. Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Tested-by: Rick Wertenbroek <rick.wertenbroek@gmail.com> Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Signed-off-by: Keith Busch <kbusch@kernel.org>
This commit is contained in:
parent
89b94a6cbe
commit
f1ecd491b6
|
|
@ -1303,6 +1303,27 @@ static u16 nvmet_set_feat_irq_coalesce(struct nvmet_req *req)
|
|||
return ctrl->ops->set_feature(ctrl, NVME_FEAT_IRQ_COALESCE, &irqc);
|
||||
}
|
||||
|
||||
static u16 nvmet_set_feat_irq_config(struct nvmet_req *req)
|
||||
{
|
||||
struct nvmet_ctrl *ctrl = req->sq->ctrl;
|
||||
u32 cdw11 = le32_to_cpu(req->cmd->common.cdw11);
|
||||
struct nvmet_feat_irq_config irqcfg = {
|
||||
.iv = cdw11 & 0xffff,
|
||||
.cd = (cdw11 >> 16) & 0x1,
|
||||
};
|
||||
|
||||
/*
|
||||
* This feature is not supported for fabrics controllers and mandatory
|
||||
* for PCI controllers.
|
||||
*/
|
||||
if (!nvmet_is_pci_ctrl(ctrl)) {
|
||||
req->error_loc = offsetof(struct nvme_common_command, cdw10);
|
||||
return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
|
||||
}
|
||||
|
||||
return ctrl->ops->set_feature(ctrl, NVME_FEAT_IRQ_CONFIG, &irqcfg);
|
||||
}
|
||||
|
||||
void nvmet_execute_set_features(struct nvmet_req *req)
|
||||
{
|
||||
struct nvmet_subsys *subsys = nvmet_req_subsys(req);
|
||||
|
|
@ -1329,6 +1350,9 @@ void nvmet_execute_set_features(struct nvmet_req *req)
|
|||
case NVME_FEAT_IRQ_COALESCE:
|
||||
status = nvmet_set_feat_irq_coalesce(req);
|
||||
break;
|
||||
case NVME_FEAT_IRQ_CONFIG:
|
||||
status = nvmet_set_feat_irq_config(req);
|
||||
break;
|
||||
case NVME_FEAT_KATO:
|
||||
status = nvmet_set_feat_kato(req);
|
||||
break;
|
||||
|
|
@ -1397,6 +1421,31 @@ static u16 nvmet_get_feat_irq_coalesce(struct nvmet_req *req)
|
|||
return NVME_SC_SUCCESS;
|
||||
}
|
||||
|
||||
static u16 nvmet_get_feat_irq_config(struct nvmet_req *req)
|
||||
{
|
||||
struct nvmet_ctrl *ctrl = req->sq->ctrl;
|
||||
u32 iv = le32_to_cpu(req->cmd->common.cdw11) & 0xffff;
|
||||
struct nvmet_feat_irq_config irqcfg = { .iv = iv };
|
||||
u16 status;
|
||||
|
||||
/*
|
||||
* This feature is not supported for fabrics controllers and mandatory
|
||||
* for PCI controllers.
|
||||
*/
|
||||
if (!nvmet_is_pci_ctrl(ctrl)) {
|
||||
req->error_loc = offsetof(struct nvme_common_command, cdw10);
|
||||
return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
|
||||
}
|
||||
|
||||
status = ctrl->ops->get_feature(ctrl, NVME_FEAT_IRQ_CONFIG, &irqcfg);
|
||||
if (status != NVME_SC_SUCCESS)
|
||||
return status;
|
||||
|
||||
nvmet_set_result(req, ((u32)irqcfg.cd << 16) | iv);
|
||||
|
||||
return NVME_SC_SUCCESS;
|
||||
}
|
||||
|
||||
void nvmet_get_feat_kato(struct nvmet_req *req)
|
||||
{
|
||||
nvmet_set_result(req, req->sq->ctrl->kato * 1000);
|
||||
|
|
@ -1431,14 +1480,15 @@ void nvmet_execute_get_features(struct nvmet_req *req)
|
|||
break;
|
||||
case NVME_FEAT_ERR_RECOVERY:
|
||||
break;
|
||||
case NVME_FEAT_IRQ_CONFIG:
|
||||
break;
|
||||
case NVME_FEAT_WRITE_ATOMIC:
|
||||
break;
|
||||
#endif
|
||||
case NVME_FEAT_IRQ_COALESCE:
|
||||
status = nvmet_get_feat_irq_coalesce(req);
|
||||
break;
|
||||
case NVME_FEAT_IRQ_CONFIG:
|
||||
status = nvmet_get_feat_irq_config(req);
|
||||
break;
|
||||
case NVME_FEAT_ASYNC_EVENT:
|
||||
nvmet_get_feat_async_event(req);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -916,4 +916,9 @@ struct nvmet_feat_irq_coalesce {
|
|||
u8 time;
|
||||
};
|
||||
|
||||
struct nvmet_feat_irq_config {
|
||||
u16 iv;
|
||||
bool cd;
|
||||
};
|
||||
|
||||
#endif /* _NVMET_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user