mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-02-03 09:34:42 +00:00
libnvdimm: Fix nvdimm_probe error on NVDIMM-N
'ndctl list --buses --dimms' does not list any NVDIMM-Ns since they are considered as idle. ndctl checks if any driver is attached to nmem device. nvdimm_probe() always fails in nvdimm_init_nsarea() since NVDIMM-Ns do not implement optinal ND_CMD_GET_CONFIG_DATA command. Change nvdimm_probe() to accept the case that the CONFIG_DATA command is not implemented for NVDIMM-Ns. The driver attaches without ndd, which keeps it no-op to the device. Reported-by: Brian Boylston <brian.boylston@hpe.com> Signed-off-by: Toshi Kani <toshi.kani@hpe.com> Cc: Dan Williams <dan.j.williams@intel.com> Tested-by: Johannes Thumshirn <jthumshirn@suse.de> Acked-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
ae551e9ca2
commit
aee6598748
@ -26,6 +26,14 @@ static int nvdimm_probe(struct device *dev)
|
||||
struct nvdimm_drvdata *ndd;
|
||||
int rc;
|
||||
|
||||
rc = nvdimm_check_config_data(dev);
|
||||
if (rc) {
|
||||
/* not required for non-aliased nvdimm, ex. NVDIMM-N */
|
||||
if (rc == -ENOTTY)
|
||||
rc = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
ndd = kzalloc(sizeof(*ndd), GFP_KERNEL);
|
||||
if (!ndd)
|
||||
return -ENOMEM;
|
||||
@ -72,6 +80,9 @@ static int nvdimm_remove(struct device *dev)
|
||||
{
|
||||
struct nvdimm_drvdata *ndd = dev_get_drvdata(dev);
|
||||
|
||||
if (!ndd)
|
||||
return 0;
|
||||
|
||||
nvdimm_bus_lock(dev);
|
||||
dev_set_drvdata(dev, NULL);
|
||||
nvdimm_bus_unlock(dev);
|
||||
|
@ -28,28 +28,30 @@ static DEFINE_IDA(dimm_ida);
|
||||
* Retrieve bus and dimm handle and return if this bus supports
|
||||
* get_config_data commands
|
||||
*/
|
||||
static int __validate_dimm(struct nvdimm_drvdata *ndd)
|
||||
int nvdimm_check_config_data(struct device *dev)
|
||||
{
|
||||
struct nvdimm *nvdimm;
|
||||
struct nvdimm *nvdimm = to_nvdimm(dev);
|
||||
|
||||
if (!ndd)
|
||||
return -EINVAL;
|
||||
|
||||
nvdimm = to_nvdimm(ndd->dev);
|
||||
|
||||
if (!nvdimm->cmd_mask)
|
||||
return -ENXIO;
|
||||
if (!test_bit(ND_CMD_GET_CONFIG_DATA, &nvdimm->cmd_mask))
|
||||
return -ENXIO;
|
||||
if (!nvdimm->cmd_mask ||
|
||||
!test_bit(ND_CMD_GET_CONFIG_DATA, &nvdimm->cmd_mask)) {
|
||||
if (nvdimm->flags & NDD_ALIASING)
|
||||
return -ENXIO;
|
||||
else
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int validate_dimm(struct nvdimm_drvdata *ndd)
|
||||
{
|
||||
int rc = __validate_dimm(ndd);
|
||||
int rc;
|
||||
|
||||
if (rc && ndd)
|
||||
if (!ndd)
|
||||
return -EINVAL;
|
||||
|
||||
rc = nvdimm_check_config_data(ndd->dev);
|
||||
if (rc)
|
||||
dev_dbg(ndd->dev, "%pf: %s error: %d\n",
|
||||
__builtin_return_address(0), __func__, rc);
|
||||
return rc;
|
||||
|
@ -191,6 +191,7 @@ void nvdimm_exit(void);
|
||||
void nd_region_exit(void);
|
||||
struct nvdimm;
|
||||
struct nvdimm_drvdata *to_ndd(struct nd_mapping *nd_mapping);
|
||||
int nvdimm_check_config_data(struct device *dev);
|
||||
int nvdimm_init_nsarea(struct nvdimm_drvdata *ndd);
|
||||
int nvdimm_init_config_data(struct nvdimm_drvdata *ndd);
|
||||
int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
|
||||
|
Loading…
x
Reference in New Issue
Block a user