V4L/DVB (9011): S2API: A number of cleanusp from the last 24 months.
[safe/jmp/linux-2.6] / drivers / mtd / mtd_blkdevs.c
index a8a1587..681d5ac 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id: mtd_blkdevs.c,v 1.27 2005/11/07 11:14:20 gleixner Exp $
- *
  * (C) 2003 David Woodhouse <dwmw2@infradead.org>
  *
  * Interface to Linux 2.5 block layer for MTD 'translation layers'.
@@ -16,6 +14,7 @@
 #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>
@@ -33,6 +32,14 @@ struct mtd_blkcore_priv {
        spinlock_t queue_lock;
 };
 
+static int blktrans_discard_request(struct request_queue *q,
+                                   struct request *req)
+{
+       req->cmd_type = REQ_TYPE_LINUX_BLOCK;
+       req->cmd[0] = REQ_LB_OP_DISCARD;
+       return 0;
+}
+
 static int do_blktrans_request(struct mtd_blktrans_ops *tr,
                               struct mtd_blktrans_dev *dev,
                               struct request *req)
@@ -45,6 +52,10 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
 
        buf = req->buffer;
 
+       if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
+           req->cmd[0] == REQ_LB_OP_DISCARD)
+               return !tr->discard(dev, block, nsect);
+
        if (!blk_fs_request(req))
                return 0;
 
@@ -79,7 +90,7 @@ static int mtd_blktrans_thread(void *arg)
        struct request_queue *rq = tr->blkcore_priv->rq;
 
        /* we might get involved when memory gets low, so use PF_MEMALLOC */
-       current->flags |= PF_MEMALLOC | PF_NOFREEZE;
+       current->flags |= PF_MEMALLOC;
 
        spin_lock_irq(rq->queue_lock);
        while (!kthread_should_stop()) {
@@ -211,7 +222,7 @@ static struct block_device_operations mtd_blktrans_ops = {
 int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 {
        struct mtd_blktrans_ops *tr = new->tr;
-       struct list_head *this;
+       struct mtd_blktrans_dev *d;
        int last_devnum = -1;
        struct gendisk *gd;
 
@@ -220,8 +231,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
                BUG();
        }
 
-       list_for_each(this, &tr->devs) {
-               struct mtd_blktrans_dev *d = list_entry(this, struct mtd_blktrans_dev, list);
+       list_for_each_entry(d, &tr->devs, list) {
                if (new->devnum == -1) {
                        /* Use first free number */
                        if (d->devnum != last_devnum+1) {
@@ -247,9 +257,9 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
                return -EBUSY;
        }
 
-       mutex_init(&new->lock);
        list_add_tail(&new->list, &tr->devs);
  added:
+       mutex_init(&new->lock);
        if (!tr->writesect)
                new->readonly = 1;
 
@@ -308,33 +318,24 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
 
 static void blktrans_notify_remove(struct mtd_info *mtd)
 {
-       struct list_head *this, *this2, *next;
-
-       list_for_each(this, &blktrans_majors) {
-               struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
-
-               list_for_each_safe(this2, next, &tr->devs) {
-                       struct mtd_blktrans_dev *dev = list_entry(this2, struct mtd_blktrans_dev, list);
+       struct mtd_blktrans_ops *tr;
+       struct mtd_blktrans_dev *dev, *next;
 
+       list_for_each_entry(tr, &blktrans_majors, list)
+               list_for_each_entry_safe(dev, next, &tr->devs, list)
                        if (dev->mtd == mtd)
                                tr->remove_dev(dev);
-               }
-       }
 }
 
 static void blktrans_notify_add(struct mtd_info *mtd)
 {
-       struct list_head *this;
+       struct mtd_blktrans_ops *tr;
 
        if (mtd->type == MTD_ABSENT)
                return;
 
-       list_for_each(this, &blktrans_majors) {
-               struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
-
+       list_for_each_entry(tr, &blktrans_majors, list)
                tr->add_mtd(tr, mtd);
-       }
-
 }
 
 static struct mtd_notifier blktrans_notifier = {
@@ -378,6 +379,10 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
 
        tr->blkcore_priv->rq->queuedata = tr;
        blk_queue_hardsect_size(tr->blkcore_priv->rq, tr->blksize);
+       if (tr->discard)
+               blk_queue_set_discard(tr->blkcore_priv->rq,
+                                     blktrans_discard_request);
+
        tr->blkshift = ffs(tr->blksize) - 1;
 
        tr->blkcore_priv->thread = kthread_run(mtd_blktrans_thread, tr,
@@ -405,7 +410,7 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
 
 int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
 {
-       struct list_head *this, *next;
+       struct mtd_blktrans_dev *dev, *next;
 
        mutex_lock(&mtd_table_mutex);
 
@@ -415,10 +420,8 @@ int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
        /* Remove it from the list of active majors */
        list_del(&tr->list);
 
-       list_for_each_safe(this, next, &tr->devs) {
-               struct mtd_blktrans_dev *dev = list_entry(this, struct mtd_blktrans_dev, 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);