Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shaggy...
[pandora-kernel.git] / drivers / block / pktcdvd.c
index 540bf36..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;
 }
 
@@ -1133,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;
@@ -1439,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();