powerpc: Make the irq reverse mapping radix tree lockless
[safe/jmp/linux-2.6] / drivers / block / sunvdc.c
index 2288b55..a8de037 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/scatterlist.h>
 
 #include <asm/vio.h>
 #include <asm/ldc.h>
@@ -64,7 +65,6 @@ struct vdc_port {
        u64                     operations;
        u32                     vdisk_size;
        u8                      vdisk_type;
-       u8                      dev_no;
 
        char                    disk_name[32];
 
@@ -212,12 +212,9 @@ static void vdc_end_special(struct vdc_port *port, struct vio_disk_desc *desc)
        vdc_finish(&port->vio, -err, WAITING_FOR_GEN_CMD);
 }
 
-static void vdc_end_request(struct request *req, int uptodate, int num_sectors)
+static void vdc_end_request(struct request *req, int error, int num_sectors)
 {
-       if (end_that_request_first(req, uptodate, num_sectors))
-               return;
-       add_disk_randomness(req->rq_disk);
-       end_that_request_last(req, uptodate);
+       __blk_end_request(req, error, num_sectors << 9);
 }
 
 static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr,
@@ -242,7 +239,7 @@ static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr,
 
        rqe->req = NULL;
 
-       vdc_end_request(req, !desc->status, desc->size >> 9);
+       vdc_end_request(req, (desc->status ? -EIO : 0), desc->size >> 9);
 
        if (blk_queue_stopped(port->disk->queue))
                blk_start_queue(port->disk->queue);
@@ -389,6 +386,7 @@ static int __send_request(struct request *req)
                op = VD_OP_BWRITE;
        }
 
+       sg_init_table(sg, port->ring_cookies);
        nsg = blk_rq_map_sg(req->q, req, sg);
 
        len = 0;
@@ -418,7 +416,7 @@ static int __send_request(struct request *req)
        desc->req_id = port->req_id;
        desc->operation = op;
        if (port->vdisk_type == VD_DISK_TYPE_DISK) {
-               desc->slice = 2;
+               desc->slice = 0xff;
        } else {
                desc->slice = 0;
        }
@@ -445,7 +443,7 @@ out:
        return err;
 }
 
-static void do_vdc_request(request_queue_t *q)
+static void do_vdc_request(struct request_queue *q)
 {
        while (1) {
                struct request *req = elv_next_request(q);
@@ -455,7 +453,7 @@ static void do_vdc_request(request_queue_t *q)
 
                blkdev_dequeue_request(req);
                if (__send_request(req) < 0)
-                       vdc_end_request(req, 0, req->hard_nr_sectors);
+                       vdc_end_request(req, -EIO, req->hard_nr_sectors);
        }
 }
 
@@ -703,7 +701,7 @@ static int probe_disk(struct vdc_port *port)
        blk_queue_max_phys_segments(q, port->ring_cookies);
        blk_queue_max_sectors(q, port->max_xfer_size);
        g->major = vdc_major;
-       g->first_minor = port->dev_no << PARTITION_SHIFT;
+       g->first_minor = port->vio.vdev->dev_no << PARTITION_SHIFT;
        strcpy(g->disk_name, port->disk_name);
 
        g->fops = &vdc_fops;
@@ -734,7 +732,7 @@ static struct vio_driver_ops vdc_vio_ops = {
        .handshake_complete     = vdc_handshake_complete,
 };
 
-static void print_version(void)
+static void __devinit print_version(void)
 {
        static int version_printed;
 
@@ -747,21 +745,16 @@ static int __devinit vdc_port_probe(struct vio_dev *vdev,
 {
        struct mdesc_handle *hp;
        struct vdc_port *port;
-       const u64 *port_id;
        int err;
 
        print_version();
 
        hp = mdesc_grab();
 
-       port_id = mdesc_get_property(hp, vdev->mp, "id", NULL);
        err = -ENODEV;
-       if (!port_id) {
-               printk(KERN_ERR PFX "Port lacks id property.\n");
-               goto err_out_release_mdesc;
-       }
-       if ((*port_id << PARTITION_SHIFT) & ~(u64)MINORMASK) {
-               printk(KERN_ERR PFX "Port id [%lu] too large.\n", *port_id);
+       if ((vdev->dev_no << PARTITION_SHIFT) & ~(u64)MINORMASK) {
+               printk(KERN_ERR PFX "Port id [%lu] too large.\n",
+                      vdev->dev_no);
                goto err_out_release_mdesc;
        }
 
@@ -772,16 +765,14 @@ static int __devinit vdc_port_probe(struct vio_dev *vdev,
                goto err_out_release_mdesc;
        }
 
-       port->dev_no = *port_id;
-
-       if (port->dev_no >= 26)
+       if (vdev->dev_no >= 26)
                snprintf(port->disk_name, sizeof(port->disk_name),
                         VDCBLK_NAME "%c%c",
-                        'a' + (port->dev_no / 26) - 1,
-                        'a' + (port->dev_no % 26));
+                        'a' + ((int)vdev->dev_no / 26) - 1,
+                        'a' + ((int)vdev->dev_no % 26));
        else
                snprintf(port->disk_name, sizeof(port->disk_name),
-                        VDCBLK_NAME "%c", 'a' + (port->dev_no % 26));
+                        VDCBLK_NAME "%c", 'a' + ((int)vdev->dev_no % 26));
 
        err = vio_driver_init(&port->vio, vdev, VDEV_DISK,
                              vdc_versions, ARRAY_SIZE(vdc_versions),
@@ -849,7 +840,7 @@ static struct vio_device_id vdc_port_match[] = {
        },
        {},
 };
-MODULE_DEVICE_TABLE(vio, vdc_match);
+MODULE_DEVICE_TABLE(vio, vdc_port_match);
 
 static struct vio_driver vdc_port_driver = {
        .id_table       = vdc_port_match,