aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lightnvm
diff options
context:
space:
mode:
authorMatias Bjørling <m@bjorling.me>2015-12-06 05:25:49 -0500
committerJens Axboe <axboe@fb.com>2015-12-07 11:14:19 -0500
commit762796bc9e5758df6c72253e4ec19657055cea1f (patch)
tree2d7eda1eb035ebbe5c1e6cd92b5f30f961c1864f /drivers/lightnvm
parent16f26c3aa9b9c36a9d1092ae3258461d1008481e (diff)
lightnvm: fix media mgr registration
This patch fixes two issues during media manager registration. 1. The ppa pool can be used at media manager registration. Allocate the ppa pool before that. 2. If a media manager can't be found, this should not lead to the device being unallocated. A media manager can be registered later, that can manage the device. Only warn if a media manager fails initialization. Signed-off-by: Matias Bjørling <m@bjorling.me> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/lightnvm')
-rw-r--r--drivers/lightnvm/core.c78
1 files changed, 39 insertions, 39 deletions
diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index 4a8d1fe34c4e..8f41b245cd55 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -97,15 +97,47 @@ static struct nvmm_type *nvm_find_mgr_type(const char *name)
97 return NULL; 97 return NULL;
98} 98}
99 99
100struct nvmm_type *nvm_init_mgr(struct nvm_dev *dev)
101{
102 struct nvmm_type *mt;
103 int ret;
104
105 lockdep_assert_held(&nvm_lock);
106
107 list_for_each_entry(mt, &nvm_mgrs, list) {
108 ret = mt->register_mgr(dev);
109 if (ret < 0) {
110 pr_err("nvm: media mgr failed to init (%d) on dev %s\n",
111 ret, dev->name);
112 return NULL; /* initialization failed */
113 } else if (ret > 0)
114 return mt;
115 }
116
117 return NULL;
118}
119
100int nvm_register_mgr(struct nvmm_type *mt) 120int nvm_register_mgr(struct nvmm_type *mt)
101{ 121{
122 struct nvm_dev *dev;
102 int ret = 0; 123 int ret = 0;
103 124
104 down_write(&nvm_lock); 125 down_write(&nvm_lock);
105 if (nvm_find_mgr_type(mt->name)) 126 if (nvm_find_mgr_type(mt->name)) {
106 ret = -EEXIST; 127 ret = -EEXIST;
107 else 128 goto finish;
129 } else {
108 list_add(&mt->list, &nvm_mgrs); 130 list_add(&mt->list, &nvm_mgrs);
131 }
132
133 /* try to register media mgr if any device have none configured */
134 list_for_each_entry(dev, &nvm_devices, devices) {
135 if (dev->mt)
136 continue;
137
138 dev->mt = nvm_init_mgr(dev);
139 }
140finish:
109 up_write(&nvm_lock); 141 up_write(&nvm_lock);
110 142
111 return ret; 143 return ret;
@@ -123,26 +155,6 @@ void nvm_unregister_mgr(struct nvmm_type *mt)
123} 155}
124EXPORT_SYMBOL(nvm_unregister_mgr); 156EXPORT_SYMBOL(nvm_unregister_mgr);
125 157
126/* register with device with a supported manager */
127static int register_mgr(struct nvm_dev *dev)
128{
129 struct nvmm_type *mt;
130 int ret = 0;
131
132 list_for_each_entry(mt, &nvm_mgrs, list) {
133 ret = mt->register_mgr(dev);
134 if (ret > 0) {
135 dev->mt = mt;
136 break; /* successfully initialized */
137 }
138 }
139
140 if (!ret)
141 pr_info("nvm: no compatible nvm manager found.\n");
142
143 return ret;
144}
145
146static struct nvm_dev *nvm_find_nvm_dev(const char *name) 158static struct nvm_dev *nvm_find_nvm_dev(const char *name)
147{ 159{
148 struct nvm_dev *dev; 160 struct nvm_dev *dev;
@@ -271,14 +283,6 @@ static int nvm_init(struct nvm_dev *dev)
271 goto err; 283 goto err;
272 } 284 }
273 285
274 down_write(&nvm_lock);
275 ret = register_mgr(dev);
276 up_write(&nvm_lock);
277 if (ret < 0)
278 goto err;
279 if (!ret)
280 return 0;
281
282 pr_info("nvm: registered %s [%u/%u/%u/%u/%u/%u]\n", 286 pr_info("nvm: registered %s [%u/%u/%u/%u/%u/%u]\n",
283 dev->name, dev->sec_per_pg, dev->nr_planes, 287 dev->name, dev->sec_per_pg, dev->nr_planes,
284 dev->pgs_per_blk, dev->blks_per_lun, dev->nr_luns, 288 dev->pgs_per_blk, dev->blks_per_lun, dev->nr_luns,
@@ -334,7 +338,9 @@ int nvm_register(struct request_queue *q, char *disk_name,
334 } 338 }
335 } 339 }
336 340
341 /* register device with a supported media manager */
337 down_write(&nvm_lock); 342 down_write(&nvm_lock);
343 dev->mt = nvm_init_mgr(dev);
338 list_add(&dev->devices, &nvm_devices); 344 list_add(&dev->devices, &nvm_devices);
339 up_write(&nvm_lock); 345 up_write(&nvm_lock);
340 346
@@ -379,19 +385,13 @@ static int nvm_create_target(struct nvm_dev *dev,
379 struct nvm_tgt_type *tt; 385 struct nvm_tgt_type *tt;
380 struct nvm_target *t; 386 struct nvm_target *t;
381 void *targetdata; 387 void *targetdata;
382 int ret = 0;
383 388
384 down_write(&nvm_lock);
385 if (!dev->mt) { 389 if (!dev->mt) {
386 ret = register_mgr(dev); 390 pr_info("nvm: device has no media manager registered.\n");
387 if (!ret) 391 return -ENODEV;
388 ret = -ENODEV;
389 if (ret < 0) {
390 up_write(&nvm_lock);
391 return ret;
392 }
393 } 392 }
394 393
394 down_write(&nvm_lock);
395 tt = nvm_find_target_type(create->tgttype); 395 tt = nvm_find_target_type(create->tgttype);
396 if (!tt) { 396 if (!tt) {
397 pr_err("nvm: target type %s not found\n", create->tgttype); 397 pr_err("nvm: target type %s not found\n", create->tgttype);