Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shaggy...
[pandora-kernel.git] / drivers / block / pktcdvd.c
index fadbfd8..e9de171 100644 (file)
@@ -110,15 +110,18 @@ static struct pktcdvd_kobj* pkt_kobj_create(struct pktcdvd_device *pd,
                                        struct kobj_type* ktype)
 {
        struct pktcdvd_kobj *p;
+       int error;
+
        p = kzalloc(sizeof(*p), GFP_KERNEL);
        if (!p)
                return NULL;
-       kobject_set_name(&p->kobj, "%s", name);
-       p->kobj.parent = parent;
-       p->kobj.ktype = ktype;
        p->pd = pd;
-       if (kobject_register(&p->kobj) != 0)
+       error = kobject_init_and_add(&p->kobj, ktype, parent, "%s", name);
+       if (error) {
+               kobject_put(&p->kobj);
                return NULL;
+       }
+       kobject_uevent(&p->kobj, KOBJ_ADD);
        return p;
 }
 /*
@@ -127,7 +130,7 @@ static struct pktcdvd_kobj* pkt_kobj_create(struct pktcdvd_device *pd,
 static void pkt_kobj_remove(struct pktcdvd_kobj *p)
 {
        if (p)
-               kobject_unregister(&p->kobj);
+               kobject_put(&p->kobj);
 }
 /*
  * default release function for pktcdvd kernel objects.
@@ -299,18 +302,16 @@ static struct kobj_type kobj_pkt_type_wqueue = {
 static void pkt_sysfs_dev_new(struct pktcdvd_device *pd)
 {
        if (class_pktcdvd) {
-               pd->clsdev = class_device_create(class_pktcdvd,
-                                       NULL, pd->pkt_dev,
-                                       NULL, "%s", pd->name);
-               if (IS_ERR(pd->clsdev))
-                       pd->clsdev = NULL;
+               pd->dev = device_create(class_pktcdvd, NULL, pd->pkt_dev, "%s", pd->name);
+               if (IS_ERR(pd->dev))
+                       pd->dev = NULL;
        }
-       if (pd->clsdev) {
+       if (pd->dev) {
                pd->kobj_stat = pkt_kobj_create(pd, "stat",
-                                       &pd->clsdev->kobj,
+                                       &pd->dev->kobj,
                                        &kobj_pkt_type_stat);
                pd->kobj_wqueue = pkt_kobj_create(pd, "write_queue",
-                                       &pd->clsdev->kobj,
+                                       &pd->dev->kobj,
                                        &kobj_pkt_type_wqueue);
        }
 }
@@ -320,7 +321,7 @@ static void pkt_sysfs_dev_remove(struct pktcdvd_device *pd)
        pkt_kobj_remove(pd->kobj_stat);
        pkt_kobj_remove(pd->kobj_wqueue);
        if (class_pktcdvd)
-               class_device_destroy(class_pktcdvd, pd->pkt_dev);
+               device_destroy(class_pktcdvd, pd->pkt_dev);
 }
 
 
@@ -358,10 +359,19 @@ static ssize_t class_pktcdvd_store_add(struct class *c, const char *buf,
                                        size_t count)
 {
        unsigned int major, minor;
+
        if (sscanf(buf, "%u:%u", &major, &minor) == 2) {
+               /* pkt_setup_dev() expects caller to hold reference to self */
+               if (!try_module_get(THIS_MODULE))
+                       return -ENODEV;
+
                pkt_setup_dev(MKDEV(major, minor), NULL);
+
+               module_put(THIS_MODULE);
+
                return count;
        }
+
        return -EINVAL;
 }
 
@@ -1058,15 +1068,12 @@ static void pkt_make_local_copy(struct packet_data *pkt, struct bio_vec *bvec)
        }
 }
 
-static int pkt_end_io_read(struct bio *bio, unsigned int bytes_done, int err)
+static void pkt_end_io_read(struct bio *bio, int err)
 {
        struct packet_data *pkt = bio->bi_private;
        struct pktcdvd_device *pd = pkt->pd;
        BUG_ON(!pd);
 
-       if (bio->bi_size)
-               return 1;
-
        VPRINTK("pkt_end_io_read: bio=%p sec0=%llx sec=%llx err=%d\n", bio,
                (unsigned long long)pkt->sector, (unsigned long long)bio->bi_sector, err);
 
@@ -1077,19 +1084,14 @@ static int pkt_end_io_read(struct bio *bio, unsigned int bytes_done, int err)
                wake_up(&pd->wqueue);
        }
        pkt_bio_finished(pd);
-
-       return 0;
 }
 
-static int pkt_end_io_packet_write(struct bio *bio, unsigned int bytes_done, int err)
+static void pkt_end_io_packet_write(struct bio *bio, int err)
 {
        struct packet_data *pkt = bio->bi_private;
        struct pktcdvd_device *pd = pkt->pd;
        BUG_ON(!pd);
 
-       if (bio->bi_size)
-               return 1;
-
        VPRINTK("pkt_end_io_packet_write: id=%d, err=%d\n", pkt->id, err);
 
        pd->stats.pkt_ended++;
@@ -1098,7 +1100,6 @@ static int pkt_end_io_packet_write(struct bio *bio, unsigned int bytes_done, int
        atomic_dec(&pkt->io_wait);
        atomic_inc(&pkt->run_sm);
        wake_up(&pd->wqueue);
-       return 0;
 }
 
 /*
@@ -1142,16 +1143,21 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
         * Schedule reads for missing parts of the packet.
         */
        for (f = 0; f < pkt->frames; f++) {
+               struct bio_vec *vec;
+
                int p, offset;
                if (written[f])
                        continue;
                bio = pkt->r_bios[f];
+               vec = bio->bi_io_vec;
                bio_init(bio);
                bio->bi_max_vecs = 1;
                bio->bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9);
                bio->bi_bdev = pd->bdev;
                bio->bi_end_io = pkt_end_io_read;
                bio->bi_private = pkt;
+               bio->bi_io_vec = vec;
+               bio->bi_destructor = pkt_bio_destructor;
 
                p = (f * CD_FRAMESIZE) / PAGE_SIZE;
                offset = (f * CD_FRAMESIZE) % PAGE_SIZE;
@@ -1448,6 +1454,8 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
        pkt->w_bio->bi_bdev = pd->bdev;
        pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
        pkt->w_bio->bi_private = pkt;
+       pkt->w_bio->bi_io_vec = bvec;
+       pkt->w_bio->bi_destructor = pkt_bio_destructor;
        for (f = 0; f < pkt->frames; f++)
                if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset))
                        BUG();
@@ -1470,7 +1478,7 @@ static void pkt_finish_packet(struct packet_data *pkt, int uptodate)
        while (bio) {
                next = bio->bi_next;
                bio->bi_next = NULL;
-               bio_endio(bio, bio->bi_size, uptodate ? 0 : -EIO);
+               bio_endio(bio, uptodate ? 0 : -EIO);
                bio = next;
        }
        pkt->orig_bios = pkt->orig_bios_tail = NULL;
@@ -2462,19 +2470,15 @@ static int pkt_close(struct inode *inode, struct file *file)
 }
 
 
-static int pkt_end_io_read_cloned(struct bio *bio, unsigned int bytes_done, int err)
+static void pkt_end_io_read_cloned(struct bio *bio, int err)
 {
        struct packet_stacked_data *psd = bio->bi_private;
        struct pktcdvd_device *pd = psd->pd;
 
-       if (bio->bi_size)
-               return 1;
-
        bio_put(bio);
-       bio_endio(psd->bio, psd->bio->bi_size, err);
+       bio_endio(psd->bio, err);
        mempool_free(psd, psd_pool);
        pkt_bio_finished(pd);
-       return 0;
 }
 
 static int pkt_make_request(struct request_queue *q, struct bio *bio)
@@ -2620,7 +2624,7 @@ static int pkt_make_request(struct request_queue *q, struct bio *bio)
        }
        return 0;
 end_io:
-       bio_io_error(bio, bio->bi_size);
+       bio_io_error(bio);
        return 0;
 }