ALSA: hda - Add new GPU codec ID 0x10de0083 to snd-hda
[linux-2.6-block.git] / block / blk-core.c
index a0af4043dda2bbe953b3550c07ac40f88148958b..ab51685988c253616f751615ba06206732149de4 100644 (file)
@@ -51,7 +51,7 @@ DEFINE_IDA(blk_queue_ida);
 /*
  * For the allocated request tables
  */
-struct kmem_cache *request_cachep = NULL;
+struct kmem_cache *request_cachep;
 
 /*
  * For queue allocation
@@ -206,6 +206,22 @@ void blk_delay_queue(struct request_queue *q, unsigned long msecs)
 }
 EXPORT_SYMBOL(blk_delay_queue);
 
+/**
+ * blk_start_queue_async - asynchronously restart a previously stopped queue
+ * @q:    The &struct request_queue in question
+ *
+ * Description:
+ *   blk_start_queue_async() will clear the stop flag on the queue, and
+ *   ensure that the request_fn for the queue is run from an async
+ *   context.
+ **/
+void blk_start_queue_async(struct request_queue *q)
+{
+       queue_flag_clear(QUEUE_FLAG_STOPPED, q);
+       blk_run_queue_async(q);
+}
+EXPORT_SYMBOL(blk_start_queue_async);
+
 /**
  * blk_start_queue - restart a previously stopped queue
  * @q:    The &struct request_queue in question
@@ -630,7 +646,7 @@ struct request_queue *blk_alloc_queue(gfp_t gfp_mask)
 }
 EXPORT_SYMBOL(blk_alloc_queue);
 
-int blk_queue_enter(struct request_queue *q, gfp_t gfp)
+int blk_queue_enter(struct request_queue *q, bool nowait)
 {
        while (true) {
                int ret;
@@ -638,7 +654,7 @@ int blk_queue_enter(struct request_queue *q, gfp_t gfp)
                if (percpu_ref_tryget_live(&q->q_usage_counter))
                        return 0;
 
-               if (!gfpflags_allow_blocking(gfp))
+               if (nowait)
                        return -EBUSY;
 
                ret = wait_event_interruptible(q->mq_freeze_wq,
@@ -664,6 +680,13 @@ static void blk_queue_usage_counter_release(struct percpu_ref *ref)
        wake_up_all(&q->mq_freeze_wq);
 }
 
+static void blk_rq_timed_out_timer(unsigned long data)
+{
+       struct request_queue *q = (struct request_queue *)data;
+
+       kblockd_schedule_work(&q->timeout_work);
+}
+
 struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
 {
        struct request_queue *q;
@@ -825,6 +848,7 @@ blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn,
        if (blk_init_rl(&q->root_rl, q, GFP_KERNEL))
                goto fail;
 
+       INIT_WORK(&q->timeout_work, blk_timeout_work);
        q->request_fn           = rfn;
        q->prep_rq_fn           = NULL;
        q->unprep_rq_fn         = NULL;
@@ -1276,7 +1300,9 @@ static struct request *blk_old_get_request(struct request_queue *q, int rw,
 struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask)
 {
        if (q->mq_ops)
-               return blk_mq_alloc_request(q, rw, gfp_mask, false);
+               return blk_mq_alloc_request(q, rw,
+                       (gfp_mask & __GFP_DIRECT_RECLAIM) ?
+                               0 : BLK_MQ_REQ_NOWAIT);
        else
                return blk_old_get_request(q, rw, gfp_mask);
 }
@@ -1689,8 +1715,6 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
        struct request *req;
        unsigned int request_count = 0;
 
-       blk_queue_split(q, &bio, q->bio_split);
-
        /*
         * low level driver can indicate that it wants pages above a
         * certain limit bounced to low memory (ie for highmem, or even
@@ -1698,6 +1722,8 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
         */
        blk_queue_bounce(q, &bio);
 
+       blk_queue_split(q, &bio, q->bio_split);
+
        if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
                bio->bi_error = -EIO;
                bio_endio(bio);
@@ -2044,8 +2070,7 @@ blk_qc_t generic_make_request(struct bio *bio)
        do {
                struct request_queue *q = bdev_get_queue(bio->bi_bdev);
 
-               if (likely(blk_queue_enter(q, __GFP_DIRECT_RECLAIM) == 0)) {
-
+               if (likely(blk_queue_enter(q, false) == 0)) {
                        ret = q->make_request_fn(q, bio);
 
                        blk_queue_exit(q);
@@ -3405,6 +3430,9 @@ int blk_pre_runtime_suspend(struct request_queue *q)
 {
        int ret = 0;
 
+       if (!q->dev)
+               return ret;
+
        spin_lock_irq(q->queue_lock);
        if (q->nr_pending) {
                ret = -EBUSY;
@@ -3432,6 +3460,9 @@ EXPORT_SYMBOL(blk_pre_runtime_suspend);
  */
 void blk_post_runtime_suspend(struct request_queue *q, int err)
 {
+       if (!q->dev)
+               return;
+
        spin_lock_irq(q->queue_lock);
        if (!err) {
                q->rpm_status = RPM_SUSPENDED;
@@ -3456,6 +3487,9 @@ EXPORT_SYMBOL(blk_post_runtime_suspend);
  */
 void blk_pre_runtime_resume(struct request_queue *q)
 {
+       if (!q->dev)
+               return;
+
        spin_lock_irq(q->queue_lock);
        q->rpm_status = RPM_RESUMING;
        spin_unlock_irq(q->queue_lock);
@@ -3478,6 +3512,9 @@ EXPORT_SYMBOL(blk_pre_runtime_resume);
  */
 void blk_post_runtime_resume(struct request_queue *q, int err)
 {
+       if (!q->dev)
+               return;
+
        spin_lock_irq(q->queue_lock);
        if (!err) {
                q->rpm_status = RPM_ACTIVE;
@@ -3506,7 +3543,7 @@ int __init blk_dev_init(void)
        request_cachep = kmem_cache_create("blkdev_requests",
                        sizeof(struct request), 0, SLAB_PANIC, NULL);
 
-       blk_requestq_cachep = kmem_cache_create("blkdev_queue",
+       blk_requestq_cachep = kmem_cache_create("request_queue",
                        sizeof(struct request_queue), 0, SLAB_PANIC, NULL);
 
        return 0;