]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - block/elevator.c
[ALSA] hda-codec - Make internal speaker work on Acer C20x tablets
[linux-2.6-omap-h63xx.git] / block / elevator.c
index 487dd3da8853971d9bcb77cf6ecf51eb39faedf3..f6dafa8c7c4d03bea2522125895bf43579480cb9 100644 (file)
@@ -50,6 +50,21 @@ static const int elv_hash_shift = 6;
 #define rq_hash_key(rq)                ((rq)->sector + (rq)->nr_sectors)
 #define ELV_ON_HASH(rq)                (!hlist_unhashed(&(rq)->hash))
 
+/*
+ * Query io scheduler to see if the current process issuing bio may be
+ * merged with rq.
+ */
+static int elv_iosched_allow_merge(struct request *rq, struct bio *bio)
+{
+       request_queue_t *q = rq->q;
+       elevator_t *e = q->elevator;
+
+       if (e->ops->elevator_allow_merge_fn)
+               return e->ops->elevator_allow_merge_fn(q, rq, bio);
+
+       return 1;
+}
+
 /*
  * can we safely merge with this request?
  */
@@ -65,12 +80,15 @@ inline int elv_rq_merge_ok(struct request *rq, struct bio *bio)
                return 0;
 
        /*
-        * same device and no special stuff set, merge is ok
+        * must be same device and not a special request
         */
-       if (rq->rq_disk == bio->bi_bdev->bd_disk && !rq->special)
-               return 1;
+       if (rq->rq_disk != bio->bi_bdev->bd_disk || rq->special)
+               return 0;
 
-       return 0;
+       if (!elv_iosched_allow_merge(rq, bio))
+               return 0;
+
+       return 1;
 }
 EXPORT_SYMBOL(elv_rq_merge_ok);
 
@@ -93,21 +111,18 @@ static inline int elv_try_merge(struct request *__rq, struct bio *bio)
 
 static struct elevator_type *elevator_find(const char *name)
 {
-       struct elevator_type *e = NULL;
+       struct elevator_type *e;
        struct list_head *entry;
 
        list_for_each(entry, &elv_list) {
-               struct elevator_type *__e;
 
-               __e = list_entry(entry, struct elevator_type, list);
+               e = list_entry(entry, struct elevator_type, list);
 
-               if (!strcmp(__e->elevator_name, name)) {
-                       e = __e;
-                       break;
-               }
+               if (!strcmp(e->elevator_name, name))
+                       return e;
        }
 
-       return e;
+       return NULL;
 }
 
 static void elevator_put(struct elevator_type *e)
@@ -132,7 +147,7 @@ static struct elevator_type *elevator_get(const char *name)
 
 static void *elevator_init_queue(request_queue_t *q, struct elevator_queue *eq)
 {
-       return eq->ops->elevator_init_fn(q, eq);
+       return eq->ops->elevator_init_fn(q);
 }
 
 static void elevator_attach(request_queue_t *q, struct elevator_queue *eq,
@@ -575,6 +590,12 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
                 */
                rq->cmd_flags |= REQ_SOFTBARRIER;
 
+               /*
+                * Most requeues happen because of a busy condition,
+                * don't force unplug of the queue for that case.
+                */
+               unplug_it = 0;
+
                if (q->ordseq == 0) {
                        list_add(&rq->queuelist, &q->queue_head);
                        break;
@@ -589,11 +610,6 @@ void elv_insert(request_queue_t *q, struct request *rq, int where)
                }
 
                list_add_tail(&rq->queuelist, pos);
-               /*
-                * most requeues happen because of a busy condition, don't
-                * force unplug of the queue for that case.
-                */
-               unplug_it = 0;
                break;
 
        default:
@@ -813,7 +829,7 @@ void elv_put_request(request_queue_t *q, struct request *rq)
        elevator_t *e = q->elevator;
 
        if (e->ops->elevator_put_req_fn)
-               e->ops->elevator_put_req_fn(q, rq);
+               e->ops->elevator_put_req_fn(rq);
 }
 
 int elv_may_queue(request_queue_t *q, int rw)
@@ -1088,7 +1104,7 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name)
        struct list_head *entry;
        int len = 0;
 
-       spin_lock_irq(q->queue_lock);
+       spin_lock_irq(&elv_list_lock);
        list_for_each(entry, &elv_list) {
                struct elevator_type *__e;
 
@@ -1098,7 +1114,7 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name)
                else
                        len += sprintf(name+len, "%s ", __e->elevator_name);
        }
-       spin_unlock_irq(q->queue_lock);
+       spin_unlock_irq(&elv_list_lock);
 
        len += sprintf(len+name, "\n");
        return len;