]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - block/elevator.c
x86: force enable HPET on (some?) ICH9 boards
[linux-2.6-omap-h63xx.git] / block / elevator.c
index c6d153de9fd68ba33fcfb9cc65c00deb35623e8b..8cd5775acd7a2d4c1111acb0f823a57a46819dc0 100644 (file)
@@ -185,9 +185,7 @@ static elevator_t *elevator_alloc(struct request_queue *q,
 
        eq->ops = &e->ops;
        eq->elevator_type = e;
-       kobject_init(&eq->kobj);
-       snprintf(eq->kobj.name, KOBJ_NAME_LEN, "%s", "iosched");
-       eq->kobj.ktype = &elv_ktype;
+       kobject_init(&eq->kobj, &elv_ktype);
        mutex_init(&eq->sysfs_lock);
 
        eq->hash = kmalloc_node(sizeof(struct hlist_head) * ELV_HASH_ENTRIES,
@@ -390,7 +388,7 @@ EXPORT_SYMBOL(elv_rb_find);
 
 /*
  * Insert rq into dispatch queue of q.  Queue lock must be held on
- * entry.  rq is sort insted into the dispatch queue. To be used by
+ * entry.  rq is sort instead into the dispatch queue. To be used by
  * specific elevators.
  */
 void elv_dispatch_sort(struct request_queue *q, struct request *rq)
@@ -712,6 +710,14 @@ struct request *elv_next_request(struct request_queue *q)
        int ret;
 
        while ((rq = __elv_next_request(q)) != NULL) {
+               /*
+                * Kill the empty barrier place holder, the driver must
+                * not ever see it.
+                */
+               if (blk_empty_barrier(rq)) {
+                       end_queued_request(rq, 1);
+                       continue;
+               }
                if (!(rq->cmd_flags & REQ_STARTED)) {
                        /*
                         * This is the first time the device driver
@@ -735,7 +741,21 @@ struct request *elv_next_request(struct request_queue *q)
                        q->boundary_rq = NULL;
                }
 
-               if ((rq->cmd_flags & REQ_DONTPREP) || !q->prep_rq_fn)
+               if (rq->cmd_flags & REQ_DONTPREP)
+                       break;
+
+               if (q->dma_drain_size && rq->data_len) {
+                       /*
+                        * make sure space for the drain appears we
+                        * know we can do this because max_hw_segments
+                        * has been adjusted to be one fewer than the
+                        * device can handle
+                        */
+                       rq->nr_phys_segments++;
+                       rq->nr_hw_segments++;
+               }
+
+               if (!q->prep_rq_fn)
                        break;
 
                ret = q->prep_rq_fn(q, rq);
@@ -748,18 +768,21 @@ struct request *elv_next_request(struct request_queue *q)
                         * avoid resource deadlock.  REQ_STARTED will
                         * prevent other fs requests from passing this one.
                         */
+                       if (q->dma_drain_size && rq->data_len &&
+                           !(rq->cmd_flags & REQ_DONTPREP)) {
+                               /*
+                                * remove the space for the drain we added
+                                * so that we don't add it again
+                                */
+                               --rq->nr_phys_segments;
+                               --rq->nr_hw_segments;
+                       }
+
                        rq = NULL;
                        break;
                } else if (ret == BLKPREP_KILL) {
-                       int nr_bytes = rq->hard_nr_sectors << 9;
-
-                       if (!nr_bytes)
-                               nr_bytes = rq->data_len;
-
-                       blkdev_dequeue_request(rq);
                        rq->cmd_flags |= REQ_QUIET;
-                       end_that_request_chunk(rq, 0, nr_bytes);
-                       end_that_request_last(rq, 0);
+                       end_queued_request(rq, 0);
                } else {
                        printk(KERN_ERR "%s: bad return=%d\n", __FUNCTION__,
                                                                ret);
@@ -930,9 +953,7 @@ int elv_register_queue(struct request_queue *q)
        elevator_t *e = q->elevator;
        int error;
 
-       e->kobj.parent = &q->kobj;
-
-       error = kobject_add(&e->kobj);
+       error = kobject_add(&e->kobj, &q->kobj, "%s", "iosched");
        if (!error) {
                struct elv_fs_entry *attr = e->elevator_type->elevator_attrs;
                if (attr) {
@@ -959,7 +980,7 @@ void elv_unregister_queue(struct request_queue *q)
                __elv_unregister_queue(q->elevator);
 }
 
-int elv_register(struct elevator_type *e)
+void elv_register(struct elevator_type *e)
 {
        char *def = "";
 
@@ -974,7 +995,6 @@ int elv_register(struct elevator_type *e)
                                def = " (default)";
 
        printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name, def);
-       return 0;
 }
 EXPORT_SYMBOL_GPL(elv_register);