virtio: let header files include virtio_ids.h
[safe/jmp/linux-2.6] / drivers / block / virtio_blk.c
index 07d8e59..55635d1 100644 (file)
@@ -91,15 +91,26 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
                return false;
 
        vbr->req = req;
-       if (blk_fs_request(vbr->req)) {
+       switch (req->cmd_type) {
+       case REQ_TYPE_FS:
                vbr->out_hdr.type = 0;
                vbr->out_hdr.sector = blk_rq_pos(vbr->req);
                vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
-       } else if (blk_pc_request(vbr->req)) {
+               break;
+       case REQ_TYPE_BLOCK_PC:
                vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD;
                vbr->out_hdr.sector = 0;
                vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
-       } else {
+               break;
+       case REQ_TYPE_LINUX_BLOCK:
+               if (req->cmd[0] == REQ_LB_OP_FLUSH) {
+                       vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH;
+                       vbr->out_hdr.sector = 0;
+                       vbr->out_hdr.ioprio = req_get_ioprio(vbr->req);
+                       break;
+               }
+               /*FALLTHRU*/
+       default:
                /* We don't put anything else in the queue. */
                BUG();
        }
@@ -139,7 +150,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
                }
        }
 
-       if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr)) {
+       if (vblk->vq->vq_ops->add_buf(vblk->vq, vblk->sg, out, in, vbr) < 0) {
                mempool_free(vbr, vblk->pool);
                return false;
        }
@@ -199,6 +210,12 @@ out:
        return err;
 }
 
+static void virtblk_prepare_flush(struct request_queue *q, struct request *req)
+{
+       req->cmd_type = REQ_TYPE_LINUX_BLOCK;
+       req->cmd[0] = REQ_LB_OP_FLUSH;
+}
+
 static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
                         unsigned cmd, unsigned long data)
 {
@@ -213,7 +230,7 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
         * Only allow the generic SCSI ioctls if the host can support it.
         */
        if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI))
-               return -ENOIOCTLCMD;
+               return -ENOTTY;
 
        return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp);
 }
@@ -243,7 +260,7 @@ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)
        return 0;
 }
 
-static struct block_device_operations virtblk_fops = {
+static const struct block_device_operations virtblk_fops = {
        .locked_ioctl = virtblk_ioctl,
        .owner  = THIS_MODULE,
        .getgeo = virtblk_getgeo,
@@ -254,7 +271,7 @@ static int index_to_minor(int index)
        return index << PART_BITS;
 }
 
-static int virtblk_probe(struct virtio_device *vdev)
+static int __devinit virtblk_probe(struct virtio_device *vdev)
 {
        struct virtio_blk *vblk;
        int err;
@@ -314,7 +331,6 @@ static int virtblk_probe(struct virtio_device *vdev)
        }
 
        vblk->disk->queue->queuedata = vblk;
-       queue_flag_set_unlocked(QUEUE_FLAG_VIRT, vblk->disk->queue);
 
        if (index < 26) {
                sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26);
@@ -337,7 +353,10 @@ static int virtblk_probe(struct virtio_device *vdev)
        index++;
 
        /* If barriers are supported, tell block layer that queue is ordered */
-       if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER))
+       if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH))
+               blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_DRAIN_FLUSH,
+                                 virtblk_prepare_flush);
+       else if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER))
                blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL);
 
        /* If disk is read-only in the host, the guest should obey */
@@ -360,6 +379,9 @@ static int virtblk_probe(struct virtio_device *vdev)
        blk_queue_max_phys_segments(vblk->disk->queue, vblk->sg_elems-2);
        blk_queue_max_hw_segments(vblk->disk->queue, vblk->sg_elems-2);
 
+       /* No need to bounce any requests */
+       blk_queue_bounce_limit(vblk->disk->queue, BLK_BOUNCE_ANY);
+
        /* No real sector limit. */
        blk_queue_max_sectors(vblk->disk->queue, -1U);
 
@@ -395,7 +417,7 @@ out:
        return err;
 }
 
-static void virtblk_remove(struct virtio_device *vdev)
+static void __devexit virtblk_remove(struct virtio_device *vdev)
 {
        struct virtio_blk *vblk = vdev->priv;
 
@@ -421,10 +443,15 @@ static struct virtio_device_id id_table[] = {
 static unsigned int features[] = {
        VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX,
        VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
-       VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY
+       VIRTIO_BLK_F_SCSI, VIRTIO_BLK_F_IDENTIFY, VIRTIO_BLK_F_FLUSH
 };
 
-static struct virtio_driver virtio_blk = {
+/*
+ * virtio_blk causes spurious section mismatch warning by
+ * simultaneously referring to a __devinit and a __devexit function.
+ * Use __refdata to avoid this warning.
+ */
+static struct virtio_driver __refdata virtio_blk = {
        .feature_table = features,
        .feature_table_size = ARRAY_SIZE(features),
        .driver.name =  KBUILD_MODNAME,