nvme updates for Linux 5.19
- set non-mdts limits in nvme_scan_work (Chaitanya Kulkarni) - add support for TP4084 - Time-to-Ready Enhancements (me) -----BEGIN PGP SIGNATURE----- iQI/BAABCgApFiEEgdbnc3r/njty3Iq9D55TZVIEUYMFAmKGnjgLHGhjaEBsc3Qu ZGUACgkQD55TZVIEUYPxSA//XaYH0kncX2znto5S6772TJ64L2Rtfbh7LPQzE40V /Au3OvEESyP/oGh7RQxTMdKnU19Gzc+lYzTZ8VP3h/cORVEtHb5RSzb2UEUWyRbm 3+WEurG6d91PlH0HyfUsRe1y441pwr6WVDb3Zh/O1/PhsM0RihjnLEjdjobQMQJL BKFPpEfOxBPFDaaHEAVM8SB0wkhAD17C8C+YPow8IF4F1iBqmjpgtjixtHBmAovu 0Uq99ySyypyjPsEYPrUHesNFmOP4FJbosBvLVJuHDrOVdl900PmWhbCjsOcfzVRn g7xpYxreStHFUsneA8GkfUM6gEVMhOpTjdeborv9P64O9oziH35ZENHorHf+QCAu Es0HGJ3QziWqchkWxFxzLJWB4Ab5j0hhBNocQB4aM6lb8sV82+Fcyxf7NOMIkJIo aFlHXRdm6d3Ox/hBJiERFmb52Op3KAvrTYyhpPFGhQRdptAf3p1IQCfUykl5mIXz KW5BhonVtY/jS/lqbe5bw08becIqlcaX9+4QbxHGHaQO7tBRewBPMmbWfIs4Nh9i OytRRqiF/jigL66C6+wZR8bvnyk1kKvJvfUJDBv2s0THPqfqG55uYkDfZsX+B3nV n8KF4xRoLwbqIhkDRdnrhYbFaRwsK7S6hEa8nHLsUR+Ue1lc9rzOJmnbSHgXALWg VeA= =6fdL -----END PGP SIGNATURE----- Merge tag 'nvme-5.19-2022-05-19' of git://git.infradead.org/nvme into for-5.19/drivers Pull NVMe updates from Christoph: "nvme updates for Linux 5.19 - set non-mdts limits in nvme_scan_work (Chaitanya Kulkarni) - add support for TP4084 - Time-to-Ready Enhancements (me)" * tag 'nvme-5.19-2022-05-19' of git://git.infradead.org/nvme: nvme: set non-mdts limits in nvme_scan_work nvme: add support for TP4084 - Time-to-Ready Enhancements
This commit is contained in:
commit
8ad9f57755
@ -91,6 +91,7 @@ static const char * const nvme_statuses[] = {
|
||||
[NVME_SC_NS_WRITE_PROTECTED] = "Namespace is Write Protected",
|
||||
[NVME_SC_CMD_INTERRUPTED] = "Command Interrupted",
|
||||
[NVME_SC_TRANSIENT_TR_ERR] = "Transient Transport Error",
|
||||
[NVME_SC_ADMIN_COMMAND_MEDIA_NOT_READY] = "Admin Command Media Not Ready",
|
||||
[NVME_SC_INVALID_IO_CMD_SET] = "Invalid IO Command Set",
|
||||
[NVME_SC_LBA_RANGE] = "LBA Out of Range",
|
||||
[NVME_SC_CAP_EXCEEDED] = "Capacity Exceeded",
|
||||
|
@ -1427,6 +1427,32 @@ out_free_id:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int nvme_identify_ns_cs_indep(struct nvme_ctrl *ctrl, unsigned nsid,
|
||||
struct nvme_id_ns_cs_indep **id)
|
||||
{
|
||||
struct nvme_command c = {
|
||||
.identify.opcode = nvme_admin_identify,
|
||||
.identify.nsid = cpu_to_le32(nsid),
|
||||
.identify.cns = NVME_ID_CNS_NS_CS_INDEP,
|
||||
};
|
||||
int ret;
|
||||
|
||||
*id = kmalloc(sizeof(**id), GFP_KERNEL);
|
||||
if (!*id)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = nvme_submit_sync_cmd(ctrl->admin_q, &c, *id, sizeof(**id));
|
||||
if (ret) {
|
||||
dev_warn(ctrl->device,
|
||||
"Identify namespace (CS independent) failed (%d)\n",
|
||||
ret);
|
||||
kfree(*id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nvme_features(struct nvme_ctrl *dev, u8 op, unsigned int fid,
|
||||
unsigned int dword11, void *buffer, size_t buflen, u32 *result)
|
||||
{
|
||||
@ -2103,10 +2129,9 @@ static const struct block_device_operations nvme_bdev_ops = {
|
||||
.pr_ops = &nvme_pr_ops,
|
||||
};
|
||||
|
||||
static int nvme_wait_ready(struct nvme_ctrl *ctrl, u64 cap, bool enabled)
|
||||
static int nvme_wait_ready(struct nvme_ctrl *ctrl, u32 timeout, bool enabled)
|
||||
{
|
||||
unsigned long timeout =
|
||||
((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies;
|
||||
unsigned long timeout_jiffies = ((timeout + 1) * HZ / 2) + jiffies;
|
||||
u32 csts, bit = enabled ? NVME_CSTS_RDY : 0;
|
||||
int ret;
|
||||
|
||||
@ -2119,7 +2144,7 @@ static int nvme_wait_ready(struct nvme_ctrl *ctrl, u64 cap, bool enabled)
|
||||
usleep_range(1000, 2000);
|
||||
if (fatal_signal_pending(current))
|
||||
return -EINTR;
|
||||
if (time_after(jiffies, timeout)) {
|
||||
if (time_after(jiffies, timeout_jiffies)) {
|
||||
dev_err(ctrl->device,
|
||||
"Device not ready; aborting %s, CSTS=0x%x\n",
|
||||
enabled ? "initialisation" : "reset", csts);
|
||||
@ -2150,13 +2175,14 @@ int nvme_disable_ctrl(struct nvme_ctrl *ctrl)
|
||||
if (ctrl->quirks & NVME_QUIRK_DELAY_BEFORE_CHK_RDY)
|
||||
msleep(NVME_QUIRK_DELAY_AMOUNT);
|
||||
|
||||
return nvme_wait_ready(ctrl, ctrl->cap, false);
|
||||
return nvme_wait_ready(ctrl, NVME_CAP_TIMEOUT(ctrl->cap), false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvme_disable_ctrl);
|
||||
|
||||
int nvme_enable_ctrl(struct nvme_ctrl *ctrl)
|
||||
{
|
||||
unsigned dev_page_min;
|
||||
u32 timeout;
|
||||
int ret;
|
||||
|
||||
ret = ctrl->ops->reg_read64(ctrl, NVME_REG_CAP, &ctrl->cap);
|
||||
@ -2177,6 +2203,27 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl)
|
||||
ctrl->ctrl_config = NVME_CC_CSS_CSI;
|
||||
else
|
||||
ctrl->ctrl_config = NVME_CC_CSS_NVM;
|
||||
|
||||
if (ctrl->cap & NVME_CAP_CRMS_CRWMS) {
|
||||
u32 crto;
|
||||
|
||||
ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CRTO, &crto);
|
||||
if (ret) {
|
||||
dev_err(ctrl->device, "Reading CRTO failed (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ctrl->cap & NVME_CAP_CRMS_CRIMS) {
|
||||
ctrl->ctrl_config |= NVME_CC_CRIME;
|
||||
timeout = NVME_CRTO_CRIMT(crto);
|
||||
} else {
|
||||
timeout = NVME_CRTO_CRWMT(crto);
|
||||
}
|
||||
} else {
|
||||
timeout = NVME_CAP_TIMEOUT(ctrl->cap);
|
||||
}
|
||||
|
||||
ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT;
|
||||
ctrl->ctrl_config |= NVME_CC_AMS_RR | NVME_CC_SHN_NONE;
|
||||
ctrl->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES;
|
||||
@ -2185,7 +2232,7 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl)
|
||||
ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config);
|
||||
if (ret)
|
||||
return ret;
|
||||
return nvme_wait_ready(ctrl, ctrl->cap, true);
|
||||
return nvme_wait_ready(ctrl, timeout, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvme_enable_ctrl);
|
||||
|
||||
@ -3082,10 +3129,6 @@ int nvme_init_ctrl_finish(struct nvme_ctrl *ctrl)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nvme_init_non_mdts_limits(ctrl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = nvme_configure_apst(ctrl);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -4092,11 +4135,26 @@ out:
|
||||
static void nvme_validate_or_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
|
||||
{
|
||||
struct nvme_ns_ids ids = { };
|
||||
struct nvme_id_ns_cs_indep *id;
|
||||
struct nvme_ns *ns;
|
||||
bool ready = true;
|
||||
|
||||
if (nvme_identify_ns_descs(ctrl, nsid, &ids))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Check if the namespace is ready. If not ignore it, we will get an
|
||||
* AEN once it becomes ready and restart the scan.
|
||||
*/
|
||||
if ((ctrl->cap & NVME_CAP_CRMS_CRIMS) &&
|
||||
!nvme_identify_ns_cs_indep(ctrl, nsid, &id)) {
|
||||
ready = id->nstat & NVME_NSTAT_NRDY;
|
||||
kfree(id);
|
||||
}
|
||||
|
||||
if (!ready)
|
||||
return;
|
||||
|
||||
ns = nvme_find_get_ns(ctrl, nsid);
|
||||
if (ns) {
|
||||
nvme_validate_ns(ns, &ids);
|
||||
@ -4239,11 +4297,26 @@ static void nvme_scan_work(struct work_struct *work)
|
||||
{
|
||||
struct nvme_ctrl *ctrl =
|
||||
container_of(work, struct nvme_ctrl, scan_work);
|
||||
int ret;
|
||||
|
||||
/* No tagset on a live ctrl means IO queues could not created */
|
||||
if (ctrl->state != NVME_CTRL_LIVE || !ctrl->tagset)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Identify controller limits can change at controller reset due to
|
||||
* new firmware download, even though it is not common we cannot ignore
|
||||
* such scenario. Controller's non-mdts limits are reported in the unit
|
||||
* of logical blocks that is dependent on the format of attached
|
||||
* namespace. Hence re-read the limits at the time of ns allocation.
|
||||
*/
|
||||
ret = nvme_init_non_mdts_limits(ctrl);
|
||||
if (ret < 0) {
|
||||
dev_warn(ctrl->device,
|
||||
"reading non-mdts-limits failed: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
if (test_and_clear_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events)) {
|
||||
dev_info(ctrl->device, "rescanning namespaces.\n");
|
||||
nvme_clear_changed_ns_log(ctrl);
|
||||
@ -4841,6 +4914,8 @@ static inline void _nvme_check_size(void)
|
||||
BUILD_BUG_ON(sizeof(struct nvme_command) != 64);
|
||||
BUILD_BUG_ON(sizeof(struct nvme_id_ctrl) != NVME_IDENTIFY_DATA_SIZE);
|
||||
BUILD_BUG_ON(sizeof(struct nvme_id_ns) != NVME_IDENTIFY_DATA_SIZE);
|
||||
BUILD_BUG_ON(sizeof(struct nvme_id_ns_cs_indep) !=
|
||||
NVME_IDENTIFY_DATA_SIZE);
|
||||
BUILD_BUG_ON(sizeof(struct nvme_id_ns_zns) != NVME_IDENTIFY_DATA_SIZE);
|
||||
BUILD_BUG_ON(sizeof(struct nvme_id_ns_nvm) != NVME_IDENTIFY_DATA_SIZE);
|
||||
BUILD_BUG_ON(sizeof(struct nvme_id_ctrl_zns) != NVME_IDENTIFY_DATA_SIZE);
|
||||
|
@ -137,6 +137,7 @@ enum {
|
||||
NVME_REG_CMBMSC = 0x0050, /* Controller Memory Buffer Memory
|
||||
* Space Control
|
||||
*/
|
||||
NVME_REG_CRTO = 0x0068, /* Controller Ready Timeouts */
|
||||
NVME_REG_PMRCAP = 0x0e00, /* Persistent Memory Capabilities */
|
||||
NVME_REG_PMRCTL = 0x0e04, /* Persistent Memory Region Control */
|
||||
NVME_REG_PMRSTS = 0x0e08, /* Persistent Memory Region Status */
|
||||
@ -161,6 +162,9 @@ enum {
|
||||
#define NVME_CMB_BIR(cmbloc) ((cmbloc) & 0x7)
|
||||
#define NVME_CMB_OFST(cmbloc) (((cmbloc) >> 12) & 0xfffff)
|
||||
|
||||
#define NVME_CRTO_CRIMT(crto) ((crto) >> 16)
|
||||
#define NVME_CRTO_CRWMT(crto) ((crto) & 0xffff)
|
||||
|
||||
enum {
|
||||
NVME_CMBSZ_SQS = 1 << 0,
|
||||
NVME_CMBSZ_CQS = 1 << 1,
|
||||
@ -204,6 +208,7 @@ enum {
|
||||
NVME_CC_SHN_MASK = 3 << NVME_CC_SHN_SHIFT,
|
||||
NVME_CC_IOSQES = NVME_NVM_IOSQES << NVME_CC_IOSQES_SHIFT,
|
||||
NVME_CC_IOCQES = NVME_NVM_IOCQES << NVME_CC_IOCQES_SHIFT,
|
||||
NVME_CC_CRIME = 1 << 24,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -227,6 +232,11 @@ enum {
|
||||
NVME_CAP_CSS_CSI = 1 << 6,
|
||||
};
|
||||
|
||||
enum {
|
||||
NVME_CAP_CRMS_CRIMS = 1ULL << 59,
|
||||
NVME_CAP_CRMS_CRWMS = 1ULL << 60,
|
||||
};
|
||||
|
||||
struct nvme_id_power_state {
|
||||
__le16 max_power; /* centiwatts */
|
||||
__u8 rsvd2;
|
||||
@ -414,6 +424,21 @@ struct nvme_id_ns {
|
||||
__u8 vs[3712];
|
||||
};
|
||||
|
||||
/* I/O Command Set Independent Identify Namespace Data Structure */
|
||||
struct nvme_id_ns_cs_indep {
|
||||
__u8 nsfeat;
|
||||
__u8 nmic;
|
||||
__u8 rescap;
|
||||
__u8 fpi;
|
||||
__le32 anagrpid;
|
||||
__u8 nsattr;
|
||||
__u8 rsvd9;
|
||||
__le16 nvmsetid;
|
||||
__le16 endgid;
|
||||
__u8 nstat;
|
||||
__u8 rsvd15[4081];
|
||||
};
|
||||
|
||||
struct nvme_zns_lbafe {
|
||||
__le64 zsze;
|
||||
__u8 zdes;
|
||||
@ -478,6 +503,7 @@ enum {
|
||||
NVME_ID_CNS_NS_DESC_LIST = 0x03,
|
||||
NVME_ID_CNS_CS_NS = 0x05,
|
||||
NVME_ID_CNS_CS_CTRL = 0x06,
|
||||
NVME_ID_CNS_NS_CS_INDEP = 0x08,
|
||||
NVME_ID_CNS_NS_PRESENT_LIST = 0x10,
|
||||
NVME_ID_CNS_NS_PRESENT = 0x11,
|
||||
NVME_ID_CNS_CTRL_NS_LIST = 0x12,
|
||||
@ -531,6 +557,10 @@ enum {
|
||||
NVME_NS_DPS_PI_TYPE3 = 3,
|
||||
};
|
||||
|
||||
enum {
|
||||
NVME_NSTAT_NRDY = 1 << 0,
|
||||
};
|
||||
|
||||
enum {
|
||||
NVME_NVM_NS_16B_GUARD = 0,
|
||||
NVME_NVM_NS_32B_GUARD = 1,
|
||||
@ -1592,6 +1622,7 @@ enum {
|
||||
NVME_SC_NS_WRITE_PROTECTED = 0x20,
|
||||
NVME_SC_CMD_INTERRUPTED = 0x21,
|
||||
NVME_SC_TRANSIENT_TR_ERR = 0x22,
|
||||
NVME_SC_ADMIN_COMMAND_MEDIA_NOT_READY = 0x24,
|
||||
NVME_SC_INVALID_IO_CMD_SET = 0x2C,
|
||||
|
||||
NVME_SC_LBA_RANGE = 0x80,
|
||||
|
Loading…
Reference in New Issue
Block a user