JFS: pageno needs to be long
[safe/jmp/linux-2.6] / drivers / block / pktcdvd.c
index 58d01c8..f2904f6 100644 (file)
@@ -5,36 +5,45 @@
  * May be copied or modified under the terms of the GNU General Public
  * License.  See linux/COPYING for more information.
  *
- * Packet writing layer for ATAPI and SCSI CD-R, CD-RW, DVD-R, and
- * DVD-RW devices (aka an exercise in block layer masturbation)
+ * Packet writing layer for ATAPI and SCSI CD-RW, DVD+RW, DVD-RW and
+ * DVD-RAM devices.
  *
+ * Theory of operation:
  *
- * TODO: (circa order of when I will fix it)
- * - Only able to write on CD-RW media right now.
- * - check host application code on media and set it in write page
- * - interface for UDF <-> packet to negotiate a new location when a write
- *   fails.
- * - handle OPC, especially for -RW media
+ * At the lowest level, there is the standard driver for the CD/DVD device,
+ * typically ide-cd.c or sr.c. This driver can handle read and write requests,
+ * but it doesn't know anything about the special restrictions that apply to
+ * packet writing. One restriction is that write requests must be aligned to
+ * packet boundaries on the physical media, and the size of a write request
+ * must be equal to the packet size. Another restriction is that a
+ * GPCMD_FLUSH_CACHE command has to be issued to the drive before a read
+ * command, if the previous command was a write.
  *
- * Theory of operation:
+ * The purpose of the packet writing driver is to hide these restrictions from
+ * higher layers, such as file systems, and present a block device that can be
+ * randomly read and written using 2kB-sized blocks.
  *
- * We use a custom make_request_fn function that forwards reads directly to
- * the underlying CD device. Write requests are either attached directly to
- * a live packet_data object, or simply stored sequentially in a list for
- * later processing by the kcdrwd kernel thread. This driver doesn't use
- * any elevator functionally as defined by the elevator_s struct, but the
- * underlying CD device uses a standard elevator.
+ * The lowest layer in the packet writing driver is the packet I/O scheduler.
+ * Its data is defined by the struct packet_iosched and includes two bio
+ * queues with pending read and write requests. These queues are processed
+ * by the pkt_iosched_process_queue() function. The write requests in this
+ * queue are already properly aligned and sized. This layer is responsible for
+ * issuing the flush cache commands and scheduling the I/O in a good order.
  *
- * This strategy makes it possible to do very late merging of IO requests.
- * A new bio sent to pkt_make_request can be merged with a live packet_data
- * object even if the object is in the data gathering state.
+ * The next layer transforms unaligned write requests to aligned writes. This
+ * transformation requires reading missing pieces of data from the underlying
+ * block device, assembling the pieces to full packets and queuing them to the
+ * packet I/O scheduler.
+ *
+ * At the top layer there is a custom make_request_fn function that forwards
+ * read requests directly to the iosched queue and puts write requests in the
+ * unaligned write queue. A kernel thread performs the necessary read
+ * gathering to convert the unaligned writes to aligned writes and then feeds
+ * them to the packet I/O scheduler.
  *
  *************************************************************************/
 
-#define VERSION_CODE   "v0.2.0a 2004-07-14 Jens Axboe (axboe@suse.de) and petero2@telia.com"
-
 #include <linux/pktcdvd.h>
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/seq_file.h>
 #include <linux/miscdevice.h>
 #include <linux/suspend.h>
+#include <linux/mutex.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_ioctl.h>
+#include <scsi/scsi.h>
 
 #include <asm/uaccess.h>
 
+#define DRIVER_NAME    "pktcdvd"
+
 #if PACKET_DEBUG
 #define DPRINTK(fmt, args...) printk(KERN_NOTICE fmt, ##args)
 #else
@@ -69,8 +82,8 @@
 
 static struct pktcdvd_device *pkt_devs[MAX_WRITERS];
 static struct proc_dir_entry *pkt_proc;
-static int pkt_major;
-static struct semaphore ctl_mutex;     /* Serialize open/close/setup/teardown */
+static int pktdev_major;
+static struct mutex ctl_mutex; /* Serialize open/close/setup/teardown */
 static mempool_t *psd_pool;
 
 
@@ -78,7 +91,7 @@ static void pkt_bio_finished(struct pktcdvd_device *pd)
 {
        BUG_ON(atomic_read(&pd->cdrw.pending_bios) <= 0);
        if (atomic_dec_and_test(&pd->cdrw.pending_bios)) {
-               VPRINTK("pktcdvd: queue empty\n");
+               VPRINTK(DRIVER_NAME": queue empty\n");
                atomic_set(&pd->iosched.attention, 1);
                wake_up(&pd->wqueue);
        }
@@ -100,10 +113,9 @@ static struct bio *pkt_bio_alloc(int nr_iovecs)
                goto no_bio;
        bio_init(bio);
 
-       bvl = kmalloc(nr_iovecs * sizeof(struct bio_vec), GFP_KERNEL);
+       bvl = kcalloc(nr_iovecs, sizeof(struct bio_vec), GFP_KERNEL);
        if (!bvl)
                goto no_bvl;
-       memset(bvl, 0, nr_iovecs * sizeof(struct bio_vec));
 
        bio->bi_max_vecs = nr_iovecs;
        bio->bi_io_vec = bvl;
@@ -120,21 +132,21 @@ static struct bio *pkt_bio_alloc(int nr_iovecs)
 /*
  * Allocate a packet_data struct
  */
-static struct packet_data *pkt_alloc_packet_data(void)
+static struct packet_data *pkt_alloc_packet_data(int frames)
 {
        int i;
        struct packet_data *pkt;
 
-       pkt = kmalloc(sizeof(struct packet_data), GFP_KERNEL);
+       pkt = kzalloc(sizeof(struct packet_data), GFP_KERNEL);
        if (!pkt)
                goto no_pkt;
-       memset(pkt, 0, sizeof(struct packet_data));
 
-       pkt->w_bio = pkt_bio_alloc(PACKET_MAX_SIZE);
+       pkt->frames = frames;
+       pkt->w_bio = pkt_bio_alloc(frames);
        if (!pkt->w_bio)
                goto no_bio;
 
-       for (i = 0; i < PAGES_PER_PACKET; i++) {
+       for (i = 0; i < frames / FRAMES_PER_PAGE; i++) {
                pkt->pages[i] = alloc_page(GFP_KERNEL|__GFP_ZERO);
                if (!pkt->pages[i])
                        goto no_page;
@@ -142,7 +154,7 @@ static struct packet_data *pkt_alloc_packet_data(void)
 
        spin_lock_init(&pkt->lock);
 
-       for (i = 0; i < PACKET_MAX_SIZE; i++) {
+       for (i = 0; i < frames; i++) {
                struct bio *bio = pkt_bio_alloc(1);
                if (!bio)
                        goto no_rd_bio;
@@ -152,14 +164,14 @@ static struct packet_data *pkt_alloc_packet_data(void)
        return pkt;
 
 no_rd_bio:
-       for (i = 0; i < PACKET_MAX_SIZE; i++) {
+       for (i = 0; i < frames; i++) {
                struct bio *bio = pkt->r_bios[i];
                if (bio)
                        bio_put(bio);
        }
 
 no_page:
-       for (i = 0; i < PAGES_PER_PACKET; i++)
+       for (i = 0; i < frames / FRAMES_PER_PAGE; i++)
                if (pkt->pages[i])
                        __free_page(pkt->pages[i]);
        bio_put(pkt->w_bio);
@@ -176,12 +188,12 @@ static void pkt_free_packet_data(struct packet_data *pkt)
 {
        int i;
 
-       for (i = 0; i < PACKET_MAX_SIZE; i++) {
+       for (i = 0; i < pkt->frames; i++) {
                struct bio *bio = pkt->r_bios[i];
                if (bio)
                        bio_put(bio);
        }
-       for (i = 0; i < PAGES_PER_PACKET; i++)
+       for (i = 0; i < pkt->frames / FRAMES_PER_PAGE; i++)
                __free_page(pkt->pages[i]);
        bio_put(pkt->w_bio);
        kfree(pkt);
@@ -196,17 +208,17 @@ static void pkt_shrink_pktlist(struct pktcdvd_device *pd)
        list_for_each_entry_safe(pkt, next, &pd->cdrw.pkt_free_list, list) {
                pkt_free_packet_data(pkt);
        }
+       INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
 }
 
 static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets)
 {
        struct packet_data *pkt;
 
-       INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
-       INIT_LIST_HEAD(&pd->cdrw.pkt_active_list);
-       spin_lock_init(&pd->cdrw.active_list_lock);
+       BUG_ON(!list_empty(&pd->cdrw.pkt_free_list));
+
        while (nr_packets > 0) {
-               pkt = pkt_alloc_packet_data();
+               pkt = pkt_alloc_packet_data(pd->settings.size >> 2);
                if (!pkt) {
                        pkt_shrink_pktlist(pd);
                        return 0;
@@ -219,16 +231,6 @@ static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets)
        return 1;
 }
 
-static void *pkt_rb_alloc(unsigned int __nocast gfp_mask, void *data)
-{
-       return kmalloc(sizeof(struct pkt_rb_node), gfp_mask);
-}
-
-static void pkt_rb_free(void *ptr, void *data)
-{
-       kfree(ptr);
-}
-
 static inline struct pkt_rb_node *pkt_rbtree_next(struct pkt_rb_node *node)
 {
        struct rb_node *n = rb_next(&node->rb_node);
@@ -237,7 +239,7 @@ static inline struct pkt_rb_node *pkt_rbtree_next(struct pkt_rb_node *node)
        return rb_entry(n, struct pkt_rb_node, rb_node);
 }
 
-static inline void pkt_rbtree_erase(struct pktcdvd_device *pd, struct pkt_rb_node *node)
+static void pkt_rbtree_erase(struct pktcdvd_device *pd, struct pkt_rb_node *node)
 {
        rb_erase(&node->rb_node, &pd->bio_queue);
        mempool_free(node, pd->rb_pool);
@@ -305,7 +307,7 @@ static void pkt_rbtree_insert(struct pktcdvd_device *pd, struct pkt_rb_node *nod
 /*
  * Add a bio to a single linked list defined by its head and tail pointers.
  */
-static inline void pkt_add_list_last(struct bio *bio, struct bio **list_head, struct bio **list_tail)
+static void pkt_add_list_last(struct bio *bio, struct bio **list_head, struct bio **list_tail)
 {
        bio->bi_next = NULL;
        if (*list_tail) {
@@ -348,7 +350,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
        char sense[SCSI_SENSE_BUFFERSIZE];
        request_queue_t *q;
        struct request *rq;
-       DECLARE_COMPLETION(wait);
+       DECLARE_COMPLETION_ONSTACK(wait);
        int err = 0;
 
        q = bdev_get_queue(pd->bdev);
@@ -365,16 +367,17 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
        rq->sense = sense;
        memset(sense, 0, sizeof(sense));
        rq->sense_len = 0;
-       rq->flags |= REQ_BLOCK_PC | REQ_HARDBARRIER;
+       rq->cmd_type = REQ_TYPE_BLOCK_PC;
+       rq->cmd_flags |= REQ_HARDBARRIER;
        if (cgc->quiet)
-               rq->flags |= REQ_QUIET;
+               rq->cmd_flags |= REQ_QUIET;
        memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE);
        if (sizeof(rq->cmd) > CDROM_PACKET_SIZE)
                memset(rq->cmd + CDROM_PACKET_SIZE, 0, sizeof(rq->cmd) - CDROM_PACKET_SIZE);
+       rq->cmd_len = COMMAND_SIZE(rq->cmd[0]);
 
        rq->ref_count++;
-       rq->flags |= REQ_NOMERGE;
-       rq->waiting = &wait;
+       rq->end_io_data = &wait;
        rq->end_io = blk_end_sync_rq;
        elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1);
        generic_unplug_device(q);
@@ -399,7 +402,7 @@ static void pkt_dump_sense(struct packet_command *cgc)
        int i;
        struct request_sense *sense = cgc->sense;
 
-       printk("pktcdvd:");
+       printk(DRIVER_NAME":");
        for (i = 0; i < CDROM_PACKET_SIZE; i++)
                printk(" %02x", cgc->cmd[i]);
        printk(" - ");
@@ -501,14 +504,11 @@ static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio)
  */
 static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
 {
-       request_queue_t *q;
 
        if (atomic_read(&pd->iosched.attention) == 0)
                return;
        atomic_set(&pd->iosched.attention, 0);
 
-       q = bdev_get_queue(pd->bdev);
-
        for (;;) {
                struct bio *bio;
                int reads_queued, writes_queued;
@@ -530,7 +530,7 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
                                need_write_seek = 0;
                        if (need_write_seek && reads_queued) {
                                if (atomic_read(&pd->cdrw.pending_bios) > 0) {
-                                       VPRINTK("pktcdvd: write, waiting\n");
+                                       VPRINTK(DRIVER_NAME": write, waiting\n");
                                        break;
                                }
                                pkt_flush_cache(pd);
@@ -539,7 +539,7 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
                } else {
                        if (!reads_queued && writes_queued) {
                                if (atomic_read(&pd->cdrw.pending_bios) > 0) {
-                                       VPRINTK("pktcdvd: read, waiting\n");
+                                       VPRINTK(DRIVER_NAME": read, waiting\n");
                                        break;
                                }
                                pd->iosched.writing = 1;
@@ -602,7 +602,7 @@ static int pkt_set_segment_merging(struct pktcdvd_device *pd, request_queue_t *q
                set_bit(PACKET_MERGE_SEGS, &pd->flags);
                return 0;
        } else {
-               printk("pktcdvd: cdrom max_phys_segments too small\n");
+               printk(DRIVER_NAME": cdrom max_phys_segments too small\n");
                return -EIO;
        }
 }
@@ -639,7 +639,7 @@ static void pkt_copy_bio_data(struct bio *src_bio, int seg, int offs, struct pag
  * b) The data can be used as cache to avoid read requests if we receive a
  *    new write request for the same zone.
  */
-static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, int *offsets)
+static void pkt_make_local_copy(struct packet_data *pkt, struct bio_vec *bvec)
 {
        int f, p, offs;
 
@@ -647,19 +647,18 @@ static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, in
        p = 0;
        offs = 0;
        for (f = 0; f < pkt->frames; f++) {
-               if (pages[f] != pkt->pages[p]) {
-                       void *vfrom = kmap_atomic(pages[f], KM_USER0) + offsets[f];
+               if (bvec[f].bv_page != pkt->pages[p]) {
+                       void *vfrom = kmap_atomic(bvec[f].bv_page, KM_USER0) + bvec[f].bv_offset;
                        void *vto = page_address(pkt->pages[p]) + offs;
                        memcpy(vto, vfrom, CD_FRAMESIZE);
                        kunmap_atomic(vfrom, KM_USER0);
-                       pages[f] = pkt->pages[p];
-                       offsets[f] = offs;
+                       bvec[f].bv_page = pkt->pages[p];
+                       bvec[f].bv_offset = offs;
                } else {
-                       BUG_ON(offsets[f] != offs);
+                       BUG_ON(bvec[f].bv_offset != offs);
                }
                offs += CD_FRAMESIZE;
                if (offs >= PAGE_SIZE) {
-                       BUG_ON(offs > PAGE_SIZE);
                        offs = 0;
                        p++;
                }
@@ -724,12 +723,6 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
        atomic_set(&pkt->io_wait, 0);
        atomic_set(&pkt->io_errors, 0);
 
-       if (pkt->cache_valid) {
-               VPRINTK("pkt_gather_data: zone %llx cached\n",
-                       (unsigned long long)pkt->sector);
-               goto out_account;
-       }
-
        /*
         * Figure out which frames we need to read before we can write.
         */
@@ -738,6 +731,7 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
        for (bio = pkt->orig_bios; bio; bio = bio->bi_next) {
                int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9);
                int num_frames = bio->bi_size / CD_FRAMESIZE;
+               pd->stats.secs_w += num_frames * (CD_FRAMESIZE >> 9);
                BUG_ON(first_frame < 0);
                BUG_ON(first_frame + num_frames > pkt->frames);
                for (f = first_frame; f < first_frame + num_frames; f++)
@@ -745,6 +739,12 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
        }
        spin_unlock(&pkt->lock);
 
+       if (pkt->cache_valid) {
+               VPRINTK("pkt_gather_data: zone %llx cached\n",
+                       (unsigned long long)pkt->sector);
+               goto out_account;
+       }
+
        /*
         * Schedule reads for missing parts of the packet.
         */
@@ -778,7 +778,6 @@ out_account:
                frames_read, (unsigned long long)pkt->sector);
        pd->stats.pkt_started++;
        pd->stats.secs_rg += frames_read * (CD_FRAMESIZE >> 9);
-       pd->stats.secs_w += pd->settings.size;
 }
 
 /*
@@ -794,10 +793,11 @@ static struct packet_data *pkt_get_packet_data(struct pktcdvd_device *pd, int zo
                        list_del_init(&pkt->list);
                        if (pkt->sector != zone)
                                pkt->cache_valid = 0;
-                       break;
+                       return pkt;
                }
        }
-       return pkt;
+       BUG();
+       return NULL;
 }
 
 static void pkt_put_packet_data(struct pktcdvd_device *pd, struct packet_data *pkt)
@@ -941,11 +941,10 @@ try_next_bio:
        }
 
        pkt = pkt_get_packet_data(pd, zone);
-       BUG_ON(!pkt);
 
        pd->current_sector = zone + pd->settings.size;
        pkt->sector = zone;
-       pkt->frames = pd->settings.size >> 2;
+       BUG_ON(pkt->frames != pd->settings.size >> 2);
        pkt->write_size = 0;
 
        /*
@@ -986,18 +985,17 @@ try_next_bio:
 static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
 {
        struct bio *bio;
-       struct page *pages[PACKET_MAX_SIZE];
-       int offsets[PACKET_MAX_SIZE];
        int f;
        int frames_write;
+       struct bio_vec *bvec = pkt->w_bio->bi_io_vec;
 
        for (f = 0; f < pkt->frames; f++) {
-               pages[f] = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE];
-               offsets[f] = (f * CD_FRAMESIZE) % PAGE_SIZE;
+               bvec[f].bv_page = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE];
+               bvec[f].bv_offset = (f * CD_FRAMESIZE) % PAGE_SIZE;
        }
 
        /*
-        * Fill-in pages[] and offsets[] with data from orig_bios.
+        * Fill-in bvec with data from orig_bios.
         */
        frames_write = 0;
        spin_lock(&pkt->lock);
@@ -1019,11 +1017,11 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
                        }
 
                        if (src_bvl->bv_len - src_offs >= CD_FRAMESIZE) {
-                               pages[f] = src_bvl->bv_page;
-                               offsets[f] = src_bvl->bv_offset + src_offs;
+                               bvec[f].bv_page = src_bvl->bv_page;
+                               bvec[f].bv_offset = src_bvl->bv_offset + src_offs;
                        } else {
                                pkt_copy_bio_data(bio, segment, src_offs,
-                                                 pages[f], offsets[f]);
+                                                 bvec[f].bv_page, bvec[f].bv_offset);
                        }
                        src_offs += CD_FRAMESIZE;
                        frames_write++;
@@ -1037,7 +1035,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
        BUG_ON(frames_write != pkt->write_size);
 
        if (test_bit(PACKET_MERGE_SEGS, &pd->flags) || (pkt->write_size < pkt->frames)) {
-               pkt_make_local_copy(pkt, pages, offsets);
+               pkt_make_local_copy(pkt, bvec);
                pkt->cache_valid = 1;
        } else {
                pkt->cache_valid = 0;
@@ -1050,18 +1048,10 @@ 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;
-       for (f = 0; f < pkt->frames; f++) {
-               if ((f + 1 < pkt->frames) && (pages[f + 1] == pages[f]) &&
-                   (offsets[f + 1] = offsets[f] + CD_FRAMESIZE)) {
-                       if (!bio_add_page(pkt->w_bio, pages[f], CD_FRAMESIZE * 2, offsets[f]))
-                               BUG();
-                       f++;
-               } else {
-                       if (!bio_add_page(pkt->w_bio, pages[f], CD_FRAMESIZE, offsets[f]))
-                               BUG();
-               }
-       }
-       VPRINTK("pktcdvd: vcnt=%d\n", pkt->w_bio->bi_vcnt);
+       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();
+       VPRINTK(DRIVER_NAME": vcnt=%d\n", pkt->w_bio->bi_vcnt);
 
        atomic_set(&pkt->io_wait, 1);
        pkt->w_bio->bi_rw = WRITE;
@@ -1182,7 +1172,7 @@ static void pkt_count_states(struct pktcdvd_device *pd, int *states)
        struct packet_data *pkt;
        int i;
 
-       for (i = 0; i <= PACKET_NUM_STATES; i++)
+       for (i = 0; i < PACKET_NUM_STATES; i++)
                states[i] = 0;
 
        spin_lock(&pd->cdrw.active_list_lock);
@@ -1298,7 +1288,7 @@ work_to_do:
 
 static void pkt_print_settings(struct pktcdvd_device *pd)
 {
-       printk("pktcdvd: %s packets, ", pd->settings.fp ? "Fixed" : "Variable");
+       printk(DRIVER_NAME": %s packets, ", pd->settings.fp ? "Fixed" : "Variable");
        printk("%u blocks, ", pd->settings.size >> 2);
        printk("Mode-%c disc\n", pd->settings.block_mode == 8 ? '1' : '2');
 }
@@ -1483,7 +1473,7 @@ static int pkt_set_write_settings(struct pktcdvd_device *pd)
                /*
                 * paranoia
                 */
-               printk("pktcdvd: write mode wrong %d\n", wp->data_block_type);
+               printk(DRIVER_NAME": write mode wrong %d\n", wp->data_block_type);
                return 1;
        }
        wp->packet_size = cpu_to_be32(pd->settings.size >> 2);
@@ -1499,40 +1489,42 @@ static int pkt_set_write_settings(struct pktcdvd_device *pd)
 }
 
 /*
- * 0 -- we can write to this track, 1 -- we can't
+ * 1 -- we can write to this track, 0 -- we can't
  */
-static int pkt_good_track(track_information *ti)
+static int pkt_writable_track(struct pktcdvd_device *pd, track_information *ti)
 {
-       /*
-        * only good for CD-RW at the moment, not DVD-RW
-        */
+       switch (pd->mmc3_profile) {
+               case 0x1a: /* DVD+RW */
+               case 0x12: /* DVD-RAM */
+                       /* The track is always writable on DVD+RW/DVD-RAM */
+                       return 1;
+               default:
+                       break;
+       }
 
-       /*
-        * FIXME: only for FP
-        */
-       if (ti->fp == 0)
+       if (!ti->packet || !ti->fp)
                return 0;
 
        /*
         * "good" settings as per Mt Fuji.
         */
-       if (ti->rt == 0 && ti->blank == 0 && ti->packet == 1)
-               return 0;
+       if (ti->rt == 0 && ti->blank == 0)
+               return 1;
 
-       if (ti->rt == 0 && ti->blank == 1 && ti->packet == 1)
-               return 0;
+       if (ti->rt == 0 && ti->blank == 1)
+               return 1;
 
-       if (ti->rt == 1 && ti->blank == 0 && ti->packet == 1)
-               return 0;
+       if (ti->rt == 1 && ti->blank == 0)
+               return 1;
 
-       printk("pktcdvd: bad state %d-%d-%d\n", ti->rt, ti->blank, ti->packet);
-       return 1;
+       printk(DRIVER_NAME": bad state %d-%d-%d\n", ti->rt, ti->blank, ti->packet);
+       return 0;
 }
 
 /*
- * 0 -- we can write to this disc, 1 -- we can't
+ * 1 -- we can write to this disc, 0 -- we can't
  */
-static int pkt_good_disc(struct pktcdvd_device *pd, disc_information *di)
+static int pkt_writable_disc(struct pktcdvd_device *pd, disc_information *di)
 {
        switch (pd->mmc3_profile) {
                case 0x0a: /* CD-RW */
@@ -1541,10 +1533,10 @@ static int pkt_good_disc(struct pktcdvd_device *pd, disc_information *di)
                case 0x1a: /* DVD+RW */
                case 0x13: /* DVD-RW */
                case 0x12: /* DVD-RAM */
-                       return 0;
-               default:
-                       printk("pktcdvd: Wrong disc profile (%x)\n", pd->mmc3_profile);
                        return 1;
+               default:
+                       VPRINTK(DRIVER_NAME": Wrong disc profile (%x)\n", pd->mmc3_profile);
+                       return 0;
        }
 
        /*
@@ -1552,26 +1544,26 @@ static int pkt_good_disc(struct pktcdvd_device *pd, disc_information *di)
         * but i'm not sure, should we leave this to user apps? probably.
         */
        if (di->disc_type == 0xff) {
-               printk("pktcdvd: Unknown disc. No track?\n");
-               return 1;
+               printk(DRIVER_NAME": Unknown disc. No track?\n");
+               return 0;
        }
 
        if (di->disc_type != 0x20 && di->disc_type != 0) {
-               printk("pktcdvd: Wrong disc type (%x)\n", di->disc_type);
-               return 1;
+               printk(DRIVER_NAME": Wrong disc type (%x)\n", di->disc_type);
+               return 0;
        }
 
        if (di->erasable == 0) {
-               printk("pktcdvd: Disc not erasable\n");
-               return 1;
+               printk(DRIVER_NAME": Disc not erasable\n");
+               return 0;
        }
 
        if (di->border_status == PACKET_SESSION_RESERVED) {
-               printk("pktcdvd: Can't write to last track (reserved)\n");
-               return 1;
+               printk(DRIVER_NAME": Can't write to last track (reserved)\n");
+               return 0;
        }
 
-       return 0;
+       return 1;
 }
 
 static int pkt_probe_settings(struct pktcdvd_device *pd)
@@ -1596,34 +1588,20 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
                return ret;
        }
 
-       if (pkt_good_disc(pd, &di))
-               return -ENXIO;
+       if (!pkt_writable_disc(pd, &di))
+               return -EROFS;
 
-       switch (pd->mmc3_profile) {
-               case 0x1a: /* DVD+RW */
-                       printk("pktcdvd: inserted media is DVD+RW\n");
-                       break;
-               case 0x13: /* DVD-RW */
-                       printk("pktcdvd: inserted media is DVD-RW\n");
-                       break;
-               case 0x12: /* DVD-RAM */
-                       printk("pktcdvd: inserted media is DVD-RAM\n");
-                       break;
-               default:
-                       printk("pktcdvd: inserted media is CD-R%s\n", di.erasable ? "W" : "");
-                       break;
-       }
        pd->type = di.erasable ? PACKET_CDRW : PACKET_CDR;
 
        track = 1; /* (di.last_track_msb << 8) | di.last_track_lsb; */
        if ((ret = pkt_get_track_info(pd, track, 1, &ti))) {
-               printk("pktcdvd: failed get_track\n");
+               printk(DRIVER_NAME": failed get_track\n");
                return ret;
        }
 
-       if (pkt_good_track(&ti)) {
-               printk("pktcdvd: can't write to this track\n");
-               return -ENXIO;
+       if (!pkt_writable_track(pd, &ti)) {
+               printk(DRIVER_NAME": can't write to this track\n");
+               return -EROFS;
        }
 
        /*
@@ -1632,12 +1610,12 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
         */
        pd->settings.size = be32_to_cpu(ti.fixed_packet_size) << 2;
        if (pd->settings.size == 0) {
-               printk("pktcdvd: detected zero packet size!\n");
-               pd->settings.size = 128;
+               printk(DRIVER_NAME": detected zero packet size!\n");
+               return -ENXIO;
        }
        if (pd->settings.size > PACKET_MAX_SECTORS) {
-               printk("pktcdvd: packet size is too big\n");
-               return -ENXIO;
+               printk(DRIVER_NAME": packet size is too big\n");
+               return -EROFS;
        }
        pd->settings.fp = ti.fp;
        pd->offset = (be32_to_cpu(ti.track_start) << 2) & (pd->settings.size - 1);
@@ -1678,8 +1656,8 @@ static int pkt_probe_settings(struct pktcdvd_device *pd)
                        pd->settings.block_mode = PACKET_BLOCK_MODE2;
                        break;
                default:
-                       printk("pktcdvd: unknown data mode\n");
-                       return 1;
+                       printk(DRIVER_NAME": unknown data mode\n");
+                       return -EROFS;
        }
        return 0;
 }
@@ -1712,10 +1690,10 @@ static int pkt_write_caching(struct pktcdvd_device *pd, int set)
        cgc.buflen = cgc.cmd[8] = 2 + ((buf[0] << 8) | (buf[1] & 0xff));
        ret = pkt_mode_select(pd, &cgc);
        if (ret) {
-               printk("pktcdvd: write caching control failed\n");
+               printk(DRIVER_NAME": write caching control failed\n");
                pkt_dump_sense(&cgc);
        } else if (!ret && set)
-               printk("pktcdvd: enabled write caching on %s\n", pd->name);
+               printk(DRIVER_NAME": enabled write caching on %s\n", pd->name);
        return ret;
 }
 
@@ -1829,11 +1807,11 @@ static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed)
        }
 
        if (!buf[6] & 0x40) {
-               printk("pktcdvd: Disc type is not CD-RW\n");
+               printk(DRIVER_NAME": Disc type is not CD-RW\n");
                return 1;
        }
        if (!buf[6] & 0x4) {
-               printk("pktcdvd: A1 values on media are not valid, maybe not CDRW?\n");
+               printk(DRIVER_NAME": A1 values on media are not valid, maybe not CDRW?\n");
                return 1;
        }
 
@@ -1853,14 +1831,14 @@ static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed)
                        *speed = us_clv_to_speed[sp];
                        break;
                default:
-                       printk("pktcdvd: Unknown disc sub-type %d\n",st);
+                       printk(DRIVER_NAME": Unknown disc sub-type %d\n",st);
                        return 1;
        }
        if (*speed) {
-               printk("pktcdvd: Max. media speed: %d\n",*speed);
+               printk(DRIVER_NAME": Max. media speed: %d\n",*speed);
                return 0;
        } else {
-               printk("pktcdvd: Unknown speed %d for sub-type %d\n",sp,st);
+               printk(DRIVER_NAME": Unknown speed %d for sub-type %d\n",sp,st);
                return 1;
        }
 }
@@ -1871,7 +1849,7 @@ static int pkt_perform_opc(struct pktcdvd_device *pd)
        struct request_sense sense;
        int ret;
 
-       VPRINTK("pktcdvd: Performing OPC\n");
+       VPRINTK(DRIVER_NAME": Performing OPC\n");
 
        init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
        cgc.sense = &sense;
@@ -1889,12 +1867,12 @@ static int pkt_open_write(struct pktcdvd_device *pd)
        unsigned int write_speed, media_write_speed, read_speed;
 
        if ((ret = pkt_probe_settings(pd))) {
-               DPRINTK("pktcdvd: %s failed probe\n", pd->name);
-               return -EIO;
+               VPRINTK(DRIVER_NAME": %s failed probe\n", pd->name);
+               return ret;
        }
 
        if ((ret = pkt_set_write_settings(pd))) {
-               DPRINTK("pktcdvd: %s failed saving write settings\n", pd->name);
+               DPRINTK(DRIVER_NAME": %s failed saving write settings\n", pd->name);
                return -EIO;
        }
 
@@ -1906,26 +1884,26 @@ static int pkt_open_write(struct pktcdvd_device *pd)
                case 0x13: /* DVD-RW */
                case 0x1a: /* DVD+RW */
                case 0x12: /* DVD-RAM */
-                       DPRINTK("pktcdvd: write speed %ukB/s\n", write_speed);
+                       DPRINTK(DRIVER_NAME": write speed %ukB/s\n", write_speed);
                        break;
                default:
                        if ((ret = pkt_media_speed(pd, &media_write_speed)))
                                media_write_speed = 16;
                        write_speed = min(write_speed, media_write_speed * 177);
-                       DPRINTK("pktcdvd: write speed %ux\n", write_speed / 176);
+                       DPRINTK(DRIVER_NAME": write speed %ux\n", write_speed / 176);
                        break;
        }
        read_speed = write_speed;
 
        if ((ret = pkt_set_speed(pd, write_speed, read_speed))) {
-               DPRINTK("pktcdvd: %s couldn't set write speed\n", pd->name);
+               DPRINTK(DRIVER_NAME": %s couldn't set write speed\n", pd->name);
                return -EIO;
        }
        pd->write_speed = write_speed;
        pd->read_speed = read_speed;
 
        if ((ret = pkt_perform_opc(pd))) {
-               DPRINTK("pktcdvd: %s Optimum Power Calibration failed\n", pd->name);
+               DPRINTK(DRIVER_NAME": %s Optimum Power Calibration failed\n", pd->name);
        }
 
        return 0;
@@ -1949,9 +1927,12 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write)
        if ((ret = blkdev_get(pd->bdev, FMODE_READ, O_RDONLY)))
                goto out;
 
-       if ((ret = pkt_get_last_written(pd, &lba))) {
-               printk("pktcdvd: pkt_get_last_written failed\n");
+       if ((ret = bd_claim(pd->bdev, pd)))
                goto out_putdev;
+
+       if ((ret = pkt_get_last_written(pd, &lba))) {
+               printk(DRIVER_NAME": pkt_get_last_written failed\n");
+               goto out_unclaim;
        }
 
        set_capacity(pd->disk, lba << 2);
@@ -1961,7 +1942,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write)
        q = bdev_get_queue(pd->bdev);
        if (write) {
                if ((ret = pkt_open_write(pd)))
-                       goto out_putdev;
+                       goto out_unclaim;
                /*
                 * Some CDRW drives can not handle writes larger than one packet,
                 * even if the size is a multiple of the packet size.
@@ -1976,13 +1957,21 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write)
        }
 
        if ((ret = pkt_set_segment_merging(pd, q)))
-               goto out_putdev;
+               goto out_unclaim;
 
-       if (write)
-               printk("pktcdvd: %lukB available on disc\n", lba << 1);
+       if (write) {
+               if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
+                       printk(DRIVER_NAME": not enough memory for buffers\n");
+                       ret = -ENOMEM;
+                       goto out_unclaim;
+               }
+               printk(DRIVER_NAME": %lukB available on disc\n", lba << 1);
+       }
 
        return 0;
 
+out_unclaim:
+       bd_release(pd->bdev);
 out_putdev:
        blkdev_put(pd->bdev);
 out:
@@ -1996,12 +1985,15 @@ out:
 static void pkt_release_dev(struct pktcdvd_device *pd, int flush)
 {
        if (flush && pkt_flush_cache(pd))
-               DPRINTK("pktcdvd: %s not flushing cache\n", pd->name);
+               DPRINTK(DRIVER_NAME": %s not flushing cache\n", pd->name);
 
        pkt_lock_door(pd, 0);
 
        pkt_set_speed(pd, MAX_SPEED, MAX_SPEED);
+       bd_release(pd->bdev);
        blkdev_put(pd->bdev);
+
+       pkt_shrink_pktlist(pd);
 }
 
 static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor)
@@ -2016,9 +2008,9 @@ static int pkt_open(struct inode *inode, struct file *file)
        struct pktcdvd_device *pd = NULL;
        int ret;
 
-       VPRINTK("pktcdvd: entering open\n");
+       VPRINTK(DRIVER_NAME": entering open\n");
 
-       down(&ctl_mutex);
+       mutex_lock(&ctl_mutex);
        pd = pkt_find_dev_from_minor(iminor(inode));
        if (!pd) {
                ret = -ENODEV;
@@ -2034,10 +2026,9 @@ static int pkt_open(struct inode *inode, struct file *file)
                        goto out_dec;
                }
        } else {
-               if (pkt_open_dev(pd, file->f_mode & FMODE_WRITE)) {
-                       ret = -EIO;
+               ret = pkt_open_dev(pd, file->f_mode & FMODE_WRITE);
+               if (ret)
                        goto out_dec;
-               }
                /*
                 * needed here as well, since ext2 (among others) may change
                 * the blocksize at mount time
@@ -2045,14 +2036,14 @@ static int pkt_open(struct inode *inode, struct file *file)
                set_blocksize(inode->i_bdev, CD_FRAMESIZE);
        }
 
-       up(&ctl_mutex);
+       mutex_unlock(&ctl_mutex);
        return 0;
 
 out_dec:
        pd->refcnt--;
 out:
-       VPRINTK("pktcdvd: failed open (%d)\n", ret);
-       up(&ctl_mutex);
+       VPRINTK(DRIVER_NAME": failed open (%d)\n", ret);
+       mutex_unlock(&ctl_mutex);
        return ret;
 }
 
@@ -2061,28 +2052,18 @@ static int pkt_close(struct inode *inode, struct file *file)
        struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data;
        int ret = 0;
 
-       down(&ctl_mutex);
+       mutex_lock(&ctl_mutex);
        pd->refcnt--;
        BUG_ON(pd->refcnt < 0);
        if (pd->refcnt == 0) {
                int flush = test_bit(PACKET_WRITABLE, &pd->flags);
                pkt_release_dev(pd, flush);
        }
-       up(&ctl_mutex);
+       mutex_unlock(&ctl_mutex);
        return ret;
 }
 
 
-static void *psd_pool_alloc(unsigned int __nocast gfp_mask, void *data)
-{
-       return kmalloc(sizeof(struct packet_stacked_data), gfp_mask);
-}
-
-static void psd_pool_free(void *ptr, void *data)
-{
-       kfree(ptr);
-}
-
 static int pkt_end_io_read_cloned(struct bio *bio, unsigned int bytes_done, int err)
 {
        struct packet_stacked_data *psd = bio->bi_private;
@@ -2109,7 +2090,7 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio)
 
        pd = q->queuedata;
        if (!pd) {
-               printk("pktcdvd: %s incorrect request queue\n", bdevname(bio->bi_bdev, b));
+               printk(DRIVER_NAME": %s incorrect request queue\n", bdevname(bio->bi_bdev, b));
                goto end_io;
        }
 
@@ -2131,13 +2112,13 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio)
        }
 
        if (!test_bit(PACKET_WRITABLE, &pd->flags)) {
-               printk("pktcdvd: WRITE for ro device %s (%llu)\n",
+               printk(DRIVER_NAME": WRITE for ro device %s (%llu)\n",
                        pd->name, (unsigned long long)bio->bi_sector);
                goto end_io;
        }
 
        if (!bio->bi_size || (bio->bi_size % CD_FRAMESIZE)) {
-               printk("pktcdvd: wrong bio size\n");
+               printk(DRIVER_NAME": wrong bio size\n");
                goto end_io;
        }
 
@@ -2201,7 +2182,6 @@ static int pkt_make_request(request_queue_t *q, struct bio *bio)
         * No matching packet found. Store the bio in the work queue.
         */
        node = mempool_alloc(pd->rb_pool, GFP_NOIO);
-       BUG_ON(!node);
        node->bio = bio;
        spin_lock(&pd->lock);
        BUG_ON(pd->bio_queue_size < 0);
@@ -2341,7 +2321,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
        struct block_device *bdev;
 
        if (pd->pkt_dev == dev) {
-               printk("pktcdvd: Recursive setup not allowed\n");
+               printk(DRIVER_NAME": Recursive setup not allowed\n");
                return -EBUSY;
        }
        for (i = 0; i < MAX_WRITERS; i++) {
@@ -2349,11 +2329,11 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
                if (!pd2)
                        continue;
                if (pd2->bdev->bd_dev == dev) {
-                       printk("pktcdvd: %s already setup\n", bdevname(pd2->bdev, b));
+                       printk(DRIVER_NAME": %s already setup\n", bdevname(pd2->bdev, b));
                        return -EBUSY;
                }
                if (pd2->pkt_dev == dev) {
-                       printk("pktcdvd: Can't chain pktcdvd devices\n");
+                       printk(DRIVER_NAME": Can't chain pktcdvd devices\n");
                        return -EBUSY;
                }
        }
@@ -2368,12 +2348,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
        /* This is safe, since we have a reference from open(). */
        __module_get(THIS_MODULE);
 
-       if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) {
-               printk("pktcdvd: not enough memory for buffers\n");
-               ret = -ENOMEM;
-               goto out_mem;
-       }
-
        pd->bdev = bdev;
        set_blocksize(bdev, CD_FRAMESIZE);
 
@@ -2382,9 +2356,9 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
        atomic_set(&pd->cdrw.pending_bios, 0);
        pd->cdrw.thread = kthread_run(kcdrwd, pd, "%s", pd->name);
        if (IS_ERR(pd->cdrw.thread)) {
-               printk("pktcdvd: can't start kernel thread\n");
+               printk(DRIVER_NAME": can't start kernel thread\n");
                ret = -ENOMEM;
-               goto out_thread;
+               goto out_mem;
        }
 
        proc = create_proc_entry(pd->name, 0, pkt_proc);
@@ -2392,11 +2366,9 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
                proc->data = pd;
                proc->proc_fops = &pkt_proc_fops;
        }
-       DPRINTK("pktcdvd: writer %s mapped to %s\n", pd->name, bdevname(bdev, b));
+       DPRINTK(DRIVER_NAME": writer %s mapped to %s\n", pd->name, bdevname(bdev, b));
        return 0;
 
-out_thread:
-       pkt_shrink_pktlist(pd);
 out_mem:
        blkdev_put(bdev);
        /* This is safe: open() is still holding a reference. */
@@ -2409,7 +2381,6 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
        struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data;
 
        VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode));
-       BUG_ON(!pd);
 
        switch (cmd) {
        /*
@@ -2427,11 +2398,12 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
                 * The door gets locked when the device is opened, so we
                 * have to unlock it or else the eject command fails.
                 */
-               pkt_lock_door(pd, 0);
+               if (pd->refcnt == 1)
+                       pkt_lock_door(pd, 0);
                return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
 
        default:
-               printk("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd);
+               VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd);
                return -ENOTTY;
        }
 
@@ -2476,16 +2448,16 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
                if (!pkt_devs[idx])
                        break;
        if (idx == MAX_WRITERS) {
-               printk("pktcdvd: max %d writers supported\n", MAX_WRITERS);
+               printk(DRIVER_NAME": max %d writers supported\n", MAX_WRITERS);
                return -EBUSY;
        }
 
-       pd = kmalloc(sizeof(struct pktcdvd_device), GFP_KERNEL);
+       pd = kzalloc(sizeof(struct pktcdvd_device), GFP_KERNEL);
        if (!pd)
                return ret;
-       memset(pd, 0, sizeof(struct pktcdvd_device));
 
-       pd->rb_pool = mempool_create(PKT_RB_POOL_SIZE, pkt_rb_alloc, pkt_rb_free, NULL);
+       pd->rb_pool = mempool_create_kmalloc_pool(PKT_RB_POOL_SIZE,
+                                                 sizeof(struct pkt_rb_node));
        if (!pd->rb_pool)
                goto out_mem;
 
@@ -2494,17 +2466,21 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
                goto out_mem;
        pd->disk = disk;
 
+       INIT_LIST_HEAD(&pd->cdrw.pkt_free_list);
+       INIT_LIST_HEAD(&pd->cdrw.pkt_active_list);
+       spin_lock_init(&pd->cdrw.active_list_lock);
+
        spin_lock_init(&pd->lock);
        spin_lock_init(&pd->iosched.lock);
-       sprintf(pd->name, "pktcdvd%d", idx);
+       sprintf(pd->name, DRIVER_NAME"%d", idx);
        init_waitqueue_head(&pd->wqueue);
        pd->bio_queue = RB_ROOT;
 
-       disk->major = pkt_major;
+       disk->major = pktdev_major;
        disk->first_minor = idx;
        disk->fops = &pktcdvd_ops;
        disk->flags = GENHD_FL_REMOVABLE;
-       sprintf(disk->disk_name, "pktcdvd%d", idx);
+       sprintf(disk->disk_name, DRIVER_NAME"%d", idx);
        disk->private_data = pd;
        disk->queue = blk_alloc_queue(GFP_KERNEL);
        if (!disk->queue)
@@ -2521,7 +2497,7 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd)
        return 0;
 
 out_new_dev:
-       blk_put_queue(disk->queue);
+       blk_cleanup_queue(disk->queue);
 out_mem2:
        put_disk(disk);
 out_mem:
@@ -2546,7 +2522,7 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
                        break;
        }
        if (idx == MAX_WRITERS) {
-               DPRINTK("pktcdvd: dev not setup\n");
+               DPRINTK(DRIVER_NAME": dev not setup\n");
                return -ENXIO;
        }
 
@@ -2558,13 +2534,11 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd)
 
        blkdev_put(pd->bdev);
 
-       pkt_shrink_pktlist(pd);
-
        remove_proc_entry(pd->name, pkt_proc);
-       DPRINTK("pktcdvd: writer %s unmapped\n", pd->name);
+       DPRINTK(DRIVER_NAME": writer %s unmapped\n", pd->name);
 
        del_gendisk(pd->disk);
-       blk_put_queue(pd->disk->queue);
+       blk_cleanup_queue(pd->disk->queue);
        put_disk(pd->disk);
 
        pkt_devs[idx] = NULL;
@@ -2605,21 +2579,21 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm
        case PKT_CTRL_CMD_SETUP:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               down(&ctl_mutex);
+               mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
                ret = pkt_setup_dev(&ctrl_cmd);
-               up(&ctl_mutex);
+               mutex_unlock(&ctl_mutex);
                break;
        case PKT_CTRL_CMD_TEARDOWN:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               down(&ctl_mutex);
+               mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
                ret = pkt_remove_dev(&ctrl_cmd);
-               up(&ctl_mutex);
+               mutex_unlock(&ctl_mutex);
                break;
        case PKT_CTRL_CMD_STATUS:
-               down(&ctl_mutex);
+               mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
                pkt_get_status(&ctrl_cmd);
-               up(&ctl_mutex);
+               mutex_unlock(&ctl_mutex);
                break;
        default:
                return -ENOTTY;
@@ -2638,8 +2612,7 @@ static struct file_operations pkt_ctl_fops = {
 
 static struct miscdevice pkt_misc = {
        .minor          = MISC_DYNAMIC_MINOR,
-       .name           = "pktcdvd",
-       .devfs_name     = "pktcdvd/control",
+       .name           = DRIVER_NAME,
        .fops           = &pkt_ctl_fops
 };
 
@@ -2647,33 +2620,33 @@ static int __init pkt_init(void)
 {
        int ret;
 
-       psd_pool = mempool_create(PSD_POOL_SIZE, psd_pool_alloc, psd_pool_free, NULL);
+       psd_pool = mempool_create_kmalloc_pool(PSD_POOL_SIZE,
+                                       sizeof(struct packet_stacked_data));
        if (!psd_pool)
                return -ENOMEM;
 
-       ret = register_blkdev(pkt_major, "pktcdvd");
+       ret = register_blkdev(pktdev_major, DRIVER_NAME);
        if (ret < 0) {
-               printk("pktcdvd: Unable to register block device\n");
+               printk(DRIVER_NAME": Unable to register block device\n");
                goto out2;
        }
-       if (!pkt_major)
-               pkt_major = ret;
+       if (!pktdev_major)
+               pktdev_major = ret;
 
        ret = misc_register(&pkt_misc);
        if (ret) {
-               printk("pktcdvd: Unable to register misc device\n");
+               printk(DRIVER_NAME": Unable to register misc device\n");
                goto out;
        }
 
-       init_MUTEX(&ctl_mutex);
+       mutex_init(&ctl_mutex);
 
-       pkt_proc = proc_mkdir("pktcdvd", proc_root_driver);
+       pkt_proc = proc_mkdir(DRIVER_NAME, proc_root_driver);
 
-       DPRINTK("pktcdvd: %s\n", VERSION_CODE);
        return 0;
 
 out:
-       unregister_blkdev(pkt_major, "pktcdvd");
+       unregister_blkdev(pktdev_major, DRIVER_NAME);
 out2:
        mempool_destroy(psd_pool);
        return ret;
@@ -2681,9 +2654,9 @@ out2:
 
 static void __exit pkt_exit(void)
 {
-       remove_proc_entry("pktcdvd", proc_root_driver);
+       remove_proc_entry(DRIVER_NAME, proc_root_driver);
        misc_deregister(&pkt_misc);
-       unregister_blkdev(pkt_major, "pktcdvd");
+       unregister_blkdev(pktdev_major, DRIVER_NAME);
        mempool_destroy(psd_pool);
 }