fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / mtd / mtd_blkdevs.c
index 7f3ff50..b879a66 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/hdreg.h>
 #include <linux/init.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 #include <asm/uaccess.h>
 
 static LIST_HEAD(blktrans_majors);
 
-extern struct semaphore mtd_table_mutex;
+extern struct mutex mtd_table_mutex;
 extern struct mtd_info *mtd_table[];
 
 struct mtd_blkcore_priv {
@@ -42,19 +42,20 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
        unsigned long block, nsect;
        char *buf;
 
-       block = req->sector;
-       nsect = req->current_nr_sectors;
+       block = req->sector << 9 >> tr->blkshift;
+       nsect = req->current_nr_sectors << 9 >> tr->blkshift;
+
        buf = req->buffer;
 
-       if (!(req->flags & REQ_CMD))
+       if (!blk_fs_request(req))
                return 0;
 
-       if (block + nsect > get_capacity(req->rq_disk))
+       if (req->sector + req->current_nr_sectors > get_capacity(req->rq_disk))
                return 0;
 
        switch(rq_data_dir(req)) {
        case READ:
-               for (; nsect > 0; nsect--, block++, buf += 512)
+               for (; nsect > 0; nsect--, block++, buf += tr->blksize)
                        if (tr->readsect(dev, block, buf))
                                return 0;
                return 1;
@@ -63,13 +64,13 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
                if (!tr->writesect)
                        return 0;
 
-               for (; nsect > 0; nsect--, block++, buf += 512)
+               for (; nsect > 0; nsect--, block++, buf += tr->blksize)
                        if (tr->writesect(dev, block, buf))
                                return 0;
                return 1;
 
        default:
-               printk(KERN_NOTICE "Unknown request %ld\n", rq_data_dir(req));
+               printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req));
                return 0;
        }
 }
@@ -122,9 +123,9 @@ static int mtd_blktrans_thread(void *arg)
 
                spin_unlock_irq(rq->queue_lock);
 
-               down(&dev->sem);
+               mutex_lock(&dev->lock);
                res = do_blktrans_request(tr, dev, req);
-               up(&dev->sem);
+               mutex_unlock(&dev->lock);
 
                spin_lock_irq(rq->queue_lock);
 
@@ -235,8 +236,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
        int last_devnum = -1;
        struct gendisk *gd;
 
-       if (!down_trylock(&mtd_table_mutex)) {
-               up(&mtd_table_mutex);
+       if (!!mutex_trylock(&mtd_table_mutex)) {
+               mutex_unlock(&mtd_table_mutex);
                BUG();
        }
 
@@ -267,7 +268,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
                return -EBUSY;
        }
 
-       init_MUTEX(&new->sem);
+       mutex_init(&new->lock);
        list_add_tail(&new->list, &tr->devs);
  added:
        if (!tr->writesect)
@@ -297,7 +298,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 
        /* 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 * new->blksize) >> 9);
+       set_capacity(gd, (new->size * tr->blksize) >> 9);
 
        gd->private_data = new;
        new->blkcore_priv = gd;
@@ -313,8 +314,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 
 int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
 {
-       if (!down_trylock(&mtd_table_mutex)) {
-               up(&mtd_table_mutex);
+       if (!!mutex_trylock(&mtd_table_mutex)) {
+               mutex_unlock(&mtd_table_mutex);
                BUG();
        }
 
@@ -372,20 +373,18 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
        if (!blktrans_notifier.list.next)
                register_mtd_user(&blktrans_notifier);
 
-       tr->blkcore_priv = kmalloc(sizeof(*tr->blkcore_priv), GFP_KERNEL);
+       tr->blkcore_priv = kzalloc(sizeof(*tr->blkcore_priv), GFP_KERNEL);
        if (!tr->blkcore_priv)
                return -ENOMEM;
 
-       memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv));
-
-       down(&mtd_table_mutex);
+       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);
-               up(&mtd_table_mutex);
+               mutex_unlock(&mtd_table_mutex);
                return ret;
        }
        spin_lock_init(&tr->blkcore_priv->queue_lock);
@@ -396,18 +395,20 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
        if (!tr->blkcore_priv->rq) {
                unregister_blkdev(tr->major, tr->name);
                kfree(tr->blkcore_priv);
-               up(&mtd_table_mutex);
+               mutex_unlock(&mtd_table_mutex);
                return -ENOMEM;
        }
 
        tr->blkcore_priv->rq->queuedata = tr;
+       blk_queue_hardsect_size(tr->blkcore_priv->rq, tr->blksize);
+       tr->blkshift = ffs(tr->blksize) - 1;
 
        ret = kernel_thread(mtd_blktrans_thread, tr, CLONE_KERNEL);
        if (ret < 0) {
                blk_cleanup_queue(tr->blkcore_priv->rq);
                unregister_blkdev(tr->major, tr->name);
                kfree(tr->blkcore_priv);
-               up(&mtd_table_mutex);
+               mutex_unlock(&mtd_table_mutex);
                return ret;
        }
 
@@ -419,7 +420,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
                        tr->add_mtd(tr, mtd_table[i]);
        }
 
-       up(&mtd_table_mutex);
+       mutex_unlock(&mtd_table_mutex);
 
        return 0;
 }
@@ -428,7 +429,7 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
 {
        struct list_head *this, *next;
 
-       down(&mtd_table_mutex);
+       mutex_lock(&mtd_table_mutex);
 
        /* Clean up the kernel thread */
        tr->blkcore_priv->exiting = 1;
@@ -446,12 +447,11 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
        blk_cleanup_queue(tr->blkcore_priv->rq);
        unregister_blkdev(tr->major, tr->name);
 
-       up(&mtd_table_mutex);
+       mutex_unlock(&mtd_table_mutex);
 
        kfree(tr->blkcore_priv);
 
-       if (!list_empty(&tr->devs))
-               BUG();
+       BUG_ON(!list_empty(&tr->devs));
        return 0;
 }