projects
/
firefly-linux-kernel-4.4.55.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'drm-intel-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ickle...
[firefly-linux-kernel-4.4.55.git]
/
drivers
/
mtd
/
mtd_blkdevs.c
diff --git
a/drivers/mtd/mtd_blkdevs.c
b/drivers/mtd/mtd_blkdevs.c
index 50ab431b24ebafd456269061ac7a6873c152a57d..cb20c67995d8ba52652d8765b80dbceb82eba2b8 100644
(file)
--- a/
drivers/mtd/mtd_blkdevs.c
+++ b/
drivers/mtd/mtd_blkdevs.c
@@
-37,7
+37,6
@@
#include "mtdcore.h"
#include "mtdcore.h"
-static DEFINE_MUTEX(mtd_blkdevs_mutex);
static LIST_HEAD(blktrans_majors);
static DEFINE_MUTEX(blktrans_ref_mutex);
static LIST_HEAD(blktrans_majors);
static DEFINE_MUTEX(blktrans_ref_mutex);
@@
-133,6
+132,10
@@
static int mtd_blktrans_thread(void *arg)
if (!req && !(req = blk_fetch_request(rq))) {
set_current_state(TASK_INTERRUPTIBLE);
if (!req && !(req = blk_fetch_request(rq))) {
set_current_state(TASK_INTERRUPTIBLE);
+
+ if (kthread_should_stop())
+ set_current_state(TASK_RUNNING);
+
spin_unlock_irq(rq->queue_lock);
schedule();
spin_lock_irq(rq->queue_lock);
spin_unlock_irq(rq->queue_lock);
schedule();
spin_lock_irq(rq->queue_lock);
@@
-176,54
+179,53
@@
static void mtd_blktrans_request(struct request_queue *rq)
static int blktrans_open(struct block_device *bdev, fmode_t mode)
{
struct mtd_blktrans_dev *dev = blktrans_dev_get(bdev->bd_disk);
static int blktrans_open(struct block_device *bdev, fmode_t mode)
{
struct mtd_blktrans_dev *dev = blktrans_dev_get(bdev->bd_disk);
- int ret;
+ int ret
= 0
;
if (!dev)
return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/
if (!dev)
return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/
- mutex_lock(&mtd_blkdevs_mutex);
mutex_lock(&dev->lock);
mutex_lock(&dev->lock);
- if (!dev->mtd) {
- ret = -ENXIO;
+ if (dev->open++)
goto unlock;
goto unlock;
- }
- ret = !dev->open++ && dev->tr->open ? dev->tr->open(dev) : 0;
+ kref_get(&dev->ref);
+ __module_get(dev->tr->owner);
+
+ if (dev->mtd) {
+ ret = dev->tr->open ? dev->tr->open(dev) : 0;
+ __get_mtd_device(dev->mtd);
+ }
- /* Take another reference on the device so it won't go away till
- last release */
- if (!ret)
- kref_get(&dev->ref);
unlock:
mutex_unlock(&dev->lock);
blktrans_dev_put(dev);
unlock:
mutex_unlock(&dev->lock);
blktrans_dev_put(dev);
- mutex_unlock(&mtd_blkdevs_mutex);
return ret;
}
static int blktrans_release(struct gendisk *disk, fmode_t mode)
{
struct mtd_blktrans_dev *dev = blktrans_dev_get(disk);
return ret;
}
static int blktrans_release(struct gendisk *disk, fmode_t mode)
{
struct mtd_blktrans_dev *dev = blktrans_dev_get(disk);
- int ret =
-ENXIO
;
+ int ret =
0
;
if (!dev)
return ret;
if (!dev)
return ret;
- mutex_lock(&mtd_blkdevs_mutex);
mutex_lock(&dev->lock);
mutex_lock(&dev->lock);
- /* Release one reference, we sure its not the last one here*/
- kref_put(&dev->ref, blktrans_dev_release);
-
- if (!dev->mtd)
+ if (--dev->open)
goto unlock;
goto unlock;
- ret = !--dev->open && dev->tr->release ? dev->tr->release(dev) : 0;
+ kref_put(&dev->ref, blktrans_dev_release);
+ module_put(dev->tr->owner);
+
+ if (dev->mtd) {
+ ret = dev->tr->release ? dev->tr->release(dev) : 0;
+ __put_mtd_device(dev->mtd);
+ }
unlock:
mutex_unlock(&dev->lock);
blktrans_dev_put(dev);
unlock:
mutex_unlock(&dev->lock);
blktrans_dev_put(dev);
- mutex_unlock(&mtd_blkdevs_mutex);
return ret;
}
return ret;
}
@@
-256,7
+258,6
@@
static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
if (!dev)
return ret;
if (!dev)
return ret;
- mutex_lock(&mtd_blkdevs_mutex);
mutex_lock(&dev->lock);
if (!dev->mtd)
mutex_lock(&dev->lock);
if (!dev->mtd)
@@
-271,7
+272,6
@@
static int blktrans_ioctl(struct block_device *bdev, fmode_t mode,
}
unlock:
mutex_unlock(&dev->lock);
}
unlock:
mutex_unlock(&dev->lock);
- mutex_unlock(&mtd_blkdevs_mutex);
blktrans_dev_put(dev);
return ret;
}
blktrans_dev_put(dev);
return ret;
}
@@
-385,9
+385,6
@@
int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
gd->queue = new->rq;
gd->queue = new->rq;
- __get_mtd_device(new->mtd);
- __module_get(tr->owner);
-
/* Create processing thread */
/* TODO: workqueue ? */
new->thread = kthread_run(mtd_blktrans_thread, new,
/* Create processing thread */
/* TODO: workqueue ? */
new->thread = kthread_run(mtd_blktrans_thread, new,
@@
-410,8
+407,6
@@
int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
}
return 0;
error4:
}
return 0;
error4:
- module_put(tr->owner);
- __put_mtd_device(new->mtd);
blk_cleanup_queue(new->rq);
error3:
put_disk(new->disk);
blk_cleanup_queue(new->rq);
error3:
put_disk(new->disk);
@@
-448,17
+443,15
@@
int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
blk_start_queue(old->rq);
spin_unlock_irqrestore(&old->queue_lock, flags);
blk_start_queue(old->rq);
spin_unlock_irqrestore(&old->queue_lock, flags);
- /* Ask trans driver for release to the mtd device */
+ /* If the device is currently open, tell trans driver to close it,
+ then put mtd device, and don't touch it again */
mutex_lock(&old->lock);
mutex_lock(&old->lock);
- if (old->open && old->tr->release) {
- old->tr->release(old);
- old->open = 0;
+ if (old->open) {
+ if (old->tr->release)
+ old->tr->release(old);
+ __put_mtd_device(old->mtd);
}
}
- __put_mtd_device(old->mtd);
- module_put(old->tr->owner);
-
- /* At that point, we don't touch the mtd anymore */
old->mtd = NULL;
mutex_unlock(&old->lock);
old->mtd = NULL;
mutex_unlock(&old->lock);
@@
-508,13
+501,16
@@
int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
mutex_lock(&mtd_table_mutex);
ret = register_blkdev(tr->major, tr->name);
mutex_lock(&mtd_table_mutex);
ret = register_blkdev(tr->major, tr->name);
- if (ret) {
+ if (ret
< 0
) {
printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
tr->name, tr->major, ret);
mutex_unlock(&mtd_table_mutex);
return ret;
}
printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
tr->name, tr->major, ret);
mutex_unlock(&mtd_table_mutex);
return ret;
}
+ if (ret)
+ tr->major = ret;
+
tr->blkshift = ffs(tr->blksize) - 1;
INIT_LIST_HEAD(&tr->devs);
tr->blkshift = ffs(tr->blksize) - 1;
INIT_LIST_HEAD(&tr->devs);