Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 195887
b: refs/heads/master
c: a863862
h: refs/heads/master
i:
  195885: 4029f2a
  195883: 5f99587
  195879: 5c1219a
  195871: d1b65b3
v: v3
  • Loading branch information
Maxim Levitsky authored and David Woodhouse committed Feb 26, 2010
1 parent a470387 commit 9a4427e
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 72 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3bd456576f22acd55fb6c3d3d4261131821f5a3b
refs/heads/master: a863862257b7dd08d855bafcb0aedd9ad848ed91
124 changes: 58 additions & 66 deletions trunk/drivers/mtd/mtd_blkdevs.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include <linux/mtd/mtd.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
#include <linux/freezer.h>
#include <linux/spinlock.h>
#include <linux/hdreg.h>
#include <linux/init.h>
Expand All @@ -26,11 +25,6 @@

static LIST_HEAD(blktrans_majors);

struct mtd_blkcore_priv {
struct task_struct *thread;
struct request_queue *rq;
spinlock_t queue_lock;
};

static int do_blktrans_request(struct mtd_blktrans_ops *tr,
struct mtd_blktrans_dev *dev,
Expand Down Expand Up @@ -61,7 +55,6 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
return -EIO;
rq_flush_dcache_pages(req);
return 0;

case WRITE:
if (!tr->writesect)
return -EIO;
Expand All @@ -71,7 +64,6 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
if (tr->writesect(dev, block, buf))
return -EIO;
return 0;

default:
printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req));
return -EIO;
Expand All @@ -80,14 +72,13 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,

static int mtd_blktrans_thread(void *arg)
{
struct mtd_blktrans_ops *tr = arg;
struct request_queue *rq = tr->blkcore_priv->rq;
struct mtd_blktrans_dev *dev = arg;
struct request_queue *rq = dev->rq;
struct request *req = NULL;

spin_lock_irq(rq->queue_lock);

while (!kthread_should_stop()) {
struct mtd_blktrans_dev *dev;
int res;

if (!req && !(req = blk_fetch_request(rq))) {
Expand All @@ -98,13 +89,10 @@ static int mtd_blktrans_thread(void *arg)
continue;
}

dev = req->rq_disk->private_data;
tr = dev->tr;

spin_unlock_irq(rq->queue_lock);

mutex_lock(&dev->lock);
res = do_blktrans_request(tr, dev, req);
res = do_blktrans_request(dev->tr, dev, req);
mutex_unlock(&dev->lock);

spin_lock_irq(rq->queue_lock);
Expand All @@ -123,8 +111,8 @@ static int mtd_blktrans_thread(void *arg)

static void mtd_blktrans_request(struct request_queue *rq)
{
struct mtd_blktrans_ops *tr = rq->queuedata;
wake_up_process(tr->blkcore_priv->thread);
struct mtd_blktrans_dev *dev = rq->queuedata;
wake_up_process(dev->thread);
}


Expand Down Expand Up @@ -214,6 +202,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
struct mtd_blktrans_dev *d;
int last_devnum = -1;
struct gendisk *gd;
int ret;

if (mutex_trylock(&mtd_table_mutex)) {
mutex_unlock(&mtd_table_mutex);
Expand All @@ -239,6 +228,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
}
last_devnum = d->devnum;
}

ret = -EBUSY;
if (new->devnum == -1)
new->devnum = last_devnum+1;

Expand All @@ -247,19 +238,24 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
* with this number. */
if (new->devnum > (MINORMASK >> tr->part_bits) ||
(tr->part_bits && new->devnum >= 27 * 26))
return -EBUSY;
goto error1;

list_add_tail(&new->list, &tr->devs);
added:
mutex_init(&new->lock);
if (!tr->writesect)
new->readonly = 1;


/* Create gendisk */
ret = -ENOMEM;
gd = alloc_disk(1 << tr->part_bits);
if (!gd) {
list_del(&new->list);
return -ENOMEM;
}

if (!gd)
goto error2;

new->disk = gd;
gd->private_data = new;
gd->major = tr->major;
gd->first_minor = (new->devnum) << tr->part_bits;
gd->fops = &mtd_blktrans_ops;
Expand All @@ -277,21 +273,49 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
snprintf(gd->disk_name, sizeof(gd->disk_name),
"%s%d", tr->name, new->devnum);

/* 2.5 has capacity in units of 512 bytes while still
having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */
set_capacity(gd, (new->size * tr->blksize) >> 9);

gd->private_data = new;
new->blkcore_priv = gd;
gd->queue = tr->blkcore_priv->rq;

/* Create the request queue */
spin_lock_init(&new->queue_lock);
new->rq = blk_init_queue(mtd_blktrans_request, &new->queue_lock);

if (!new->rq)
goto error3;

new->rq->queuedata = new;
blk_queue_logical_block_size(new->rq, tr->blksize);

if (tr->discard)
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
new->rq);

gd->queue = new->rq;

/* Create processing thread */
/* TODO: workqueue ? */
new->thread = kthread_run(mtd_blktrans_thread, new,
"%s%d", tr->name, new->mtd->index);
if (IS_ERR(new->thread)) {
ret = PTR_ERR(new->thread);
goto error4;
}
gd->driverfs_dev = &new->mtd->dev;

if (new->readonly)
set_disk_ro(gd, 1);

add_disk(gd);

return 0;
error4:
blk_cleanup_queue(new->rq);
error3:
put_disk(new->disk);
error2:
list_del(&new->list);
error1:
kfree(new);
return ret;
}

int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
Expand All @@ -303,9 +327,13 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)

list_del(&old->list);

del_gendisk(old->blkcore_priv);
put_disk(old->blkcore_priv);
/* stop new requests to arrive */
del_gendisk(old->disk);

/* Stop the thread */
kthread_stop(old->thread);

blk_cleanup_queue(old->rq);
return 0;
}

Expand Down Expand Up @@ -347,49 +375,19 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
if (!blktrans_notifier.list.next)
register_mtd_user(&blktrans_notifier);

tr->blkcore_priv = kzalloc(sizeof(*tr->blkcore_priv), GFP_KERNEL);
if (!tr->blkcore_priv)
return -ENOMEM;

mutex_lock(&mtd_table_mutex);

ret = register_blkdev(tr->major, tr->name);
if (ret) {
printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
tr->name, tr->major, ret);
kfree(tr->blkcore_priv);
mutex_unlock(&mtd_table_mutex);
return ret;
}
spin_lock_init(&tr->blkcore_priv->queue_lock);

tr->blkcore_priv->rq = blk_init_queue(mtd_blktrans_request, &tr->blkcore_priv->queue_lock);
if (!tr->blkcore_priv->rq) {
unregister_blkdev(tr->major, tr->name);
kfree(tr->blkcore_priv);
mutex_unlock(&mtd_table_mutex);
return -ENOMEM;
}

tr->blkcore_priv->rq->queuedata = tr;
blk_queue_logical_block_size(tr->blkcore_priv->rq, tr->blksize);
if (tr->discard)
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
tr->blkcore_priv->rq);

tr->blkshift = ffs(tr->blksize) - 1;

tr->blkcore_priv->thread = kthread_run(mtd_blktrans_thread, tr,
"%sd", tr->name);
if (IS_ERR(tr->blkcore_priv->thread)) {
ret = PTR_ERR(tr->blkcore_priv->thread);
blk_cleanup_queue(tr->blkcore_priv->rq);
unregister_blkdev(tr->major, tr->name);
kfree(tr->blkcore_priv);
mutex_unlock(&mtd_table_mutex);
return ret;
}

INIT_LIST_HEAD(&tr->devs);
list_add(&tr->list, &blktrans_majors);

Expand All @@ -408,22 +406,16 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)

mutex_lock(&mtd_table_mutex);

/* Clean up the kernel thread */
kthread_stop(tr->blkcore_priv->thread);

/* Remove it from the list of active majors */
list_del(&tr->list);

list_for_each_entry_safe(dev, next, &tr->devs, list)
tr->remove_dev(dev);

blk_cleanup_queue(tr->blkcore_priv->rq);
unregister_blkdev(tr->major, tr->name);

mutex_unlock(&mtd_table_mutex);

kfree(tr->blkcore_priv);

BUG_ON(!list_empty(&tr->devs));
return 0;
}
Expand Down
10 changes: 5 additions & 5 deletions trunk/include/linux/mtd/blktrans.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ struct mtd_blktrans_dev {
int devnum;
unsigned long size;
int readonly;
void *blkcore_priv; /* gendisk in 2.5, devfs_handle in 2.4 */
struct gendisk *disk;
struct task_struct *thread;
struct request_queue *rq;
spinlock_t queue_lock;
void *priv;
};

struct blkcore_priv; /* Differs for 2.4 and 2.5 kernels; private */

struct mtd_blktrans_ops {
char *name;
int major;
Expand Down Expand Up @@ -60,8 +62,6 @@ struct mtd_blktrans_ops {
struct list_head devs;
struct list_head list;
struct module *owner;

struct mtd_blkcore_priv *blkcore_priv;
};

extern int register_mtd_blktrans(struct mtd_blktrans_ops *tr);
Expand Down

0 comments on commit 9a4427e

Please sign in to comment.