mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04: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 <[email protected]> Signed-off-by: Toshi Kani <[email protected]> Cc: Dan Williams <[email protected]> Tested-by: Johannes Thumshirn <[email protected]> Acked-by: Johannes Thumshirn <[email protected]> Signed-off-by: Dan Williams <[email protected]>
This commit is contained in:
parent
ae551e9ca2
commit
aee6598748
3 changed files with 27 additions and 13 deletions
|
|
@ -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…
Reference in a new issue