Merge tag 'stmp-dev' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[deliverable/linux.git] / drivers / block / virtio_blk.c
index 0d39f2f4294a3c2587e5c019e39904b3f8440fc2..693187df76012e1ace1f3c9b58fd4e78d6ec3aab 100644 (file)
@@ -29,9 +29,6 @@ struct virtio_blk
        /* The disk structure for the kernel. */
        struct gendisk *disk;
 
-       /* Request tracking. */
-       struct list_head reqs;
-
        mempool_t *pool;
 
        /* Process context for config space updates */
@@ -55,7 +52,6 @@ struct virtio_blk
 
 struct virtblk_req
 {
-       struct list_head list;
        struct request *req;
        struct virtio_blk_outhdr out_hdr;
        struct virtio_scsi_inhdr in_hdr;
@@ -99,7 +95,6 @@ static void blk_done(struct virtqueue *vq)
                }
 
                __blk_end_request_all(vbr->req, error);
-               list_del(&vbr->list);
                mempool_free(vbr, vblk->pool);
        }
        /* In case queue is stopped waiting for more buffers. */
@@ -184,7 +179,6 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
                return false;
        }
 
-       list_add_tail(&vbr->list, &vblk->reqs);
        return true;
 }
 
@@ -437,7 +431,6 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
                goto out_free_index;
        }
 
-       INIT_LIST_HEAD(&vblk->reqs);
        spin_lock_init(&vblk->lock);
        vblk->vdev = vdev;
        vblk->sg_elems = sg_elems;
@@ -583,21 +576,29 @@ static void __devexit virtblk_remove(struct virtio_device *vdev)
 {
        struct virtio_blk *vblk = vdev->priv;
        int index = vblk->index;
+       struct virtblk_req *vbr;
+       unsigned long flags;
 
        /* Prevent config work handler from accessing the device. */
        mutex_lock(&vblk->config_lock);
        vblk->config_enable = false;
        mutex_unlock(&vblk->config_lock);
 
-       /* Nothing should be pending. */
-       BUG_ON(!list_empty(&vblk->reqs));
-
        /* Stop all the virtqueues. */
        vdev->config->reset(vdev);
 
        flush_work(&vblk->config_work);
 
        del_gendisk(vblk->disk);
+
+       /* Abort requests dispatched to driver. */
+       spin_lock_irqsave(&vblk->lock, flags);
+       while ((vbr = virtqueue_detach_unused_buf(vblk->vq))) {
+               __blk_end_request_all(vbr->req, -EIO);
+               mempool_free(vbr, vblk->pool);
+       }
+       spin_unlock_irqrestore(&vblk->lock, flags);
+
        blk_cleanup_queue(vblk->disk->queue);
        put_disk(vblk->disk);
        mempool_destroy(vblk->pool);
This page took 0.025289 seconds and 5 git commands to generate.