USB: CP2101 Support AN205 baud rates
[safe/jmp/linux-2.6] / drivers / ide / ide-cd.c
index 52e4bbd..ddfbea4 100644 (file)
 
 #include "ide-cd.h"
 
-#define IDECD_DEBUG_LOG                1
-
-#if IDECD_DEBUG_LOG
-#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
-#else
-#define ide_debug_log(lvl, fmt, args...) do {} while (0)
-#endif
-
 static DEFINE_MUTEX(idecd_ref_mutex);
 
-static void ide_cd_release(struct kref *);
+static void ide_cd_release(struct device *);
 
 static struct cdrom_info *ide_cd_get(struct gendisk *disk)
 {
@@ -75,7 +67,7 @@ static struct cdrom_info *ide_cd_get(struct gendisk *disk)
                if (ide_device_get(cd->drive))
                        cd = NULL;
                else
-                       kref_get(&cd->kref);
+                       get_device(&cd->dev);
 
        }
        mutex_unlock(&idecd_ref_mutex);
@@ -87,7 +79,7 @@ static void ide_cd_put(struct cdrom_info *cd)
        ide_drive_t *drive = cd->drive;
 
        mutex_lock(&idecd_ref_mutex);
-       kref_put(&cd->kref, ide_cd_release);
+       put_device(&cd->dev);
        ide_device_put(drive);
        mutex_unlock(&idecd_ref_mutex);
 }
@@ -99,7 +91,7 @@ static void ide_cd_put(struct cdrom_info *cd)
 /* Mark that we've seen a media change and invalidate our internal buffers. */
 static void cdrom_saw_media_change(ide_drive_t *drive)
 {
-       drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED;
+       drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
        drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID;
 }
 
@@ -202,6 +194,14 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
                        bio_sectors = max(bio_sectors(failed_command->bio), 4U);
                        sector &= ~(bio_sectors - 1);
 
+                       /*
+                        * The SCSI specification allows for the value
+                        * returned by READ CAPACITY to be up to 75 2K
+                        * sectors past the last readable block.
+                        * Therefore, if we hit a medium error within the
+                        * last 75 2K sectors, we decrease the saved size
+                        * value.
+                        */
                        if (sector < get_capacity(info->disk) &&
                            drive->probed_capacity - sector < 4 * 75)
                                set_capacity(info->disk, sector);
@@ -247,7 +247,7 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
 
 static void cdrom_end_request(ide_drive_t *drive, int uptodate)
 {
-       struct request *rq = HWGROUP(drive)->rq;
+       struct request *rq = drive->hwif->rq;
        int nsectors = rq->hard_cur_sectors;
 
        ide_debug_log(IDE_DBG_FUNC, "Call %s, cmd: 0x%x, uptodate: 0x%x, "
@@ -262,7 +262,6 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate)
                struct request *failed = (struct request *) rq->buffer;
                struct cdrom_info *info = drive->driver_data;
                void *sense = &info->sense_data;
-               unsigned long flags;
 
                if (failed) {
                        if (failed->sense) {
@@ -278,11 +277,9 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate)
                                                failed->hard_nr_sectors))
                                        BUG();
                        } else {
-                               spin_lock_irqsave(&ide_lock, flags);
-                               if (__blk_end_request(failed, -EIO,
-                                                     failed->data_len))
+                               if (blk_end_request(failed, -EIO,
+                                                   failed->data_len))
                                        BUG();
-                               spin_unlock_irqrestore(&ide_lock, flags);
                        }
                } else
                        cdrom_analyze_sense_data(drive, NULL, sense);
@@ -317,7 +314,7 @@ static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st)
 static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
 {
        ide_hwif_t *hwif = drive->hwif;
-       struct request *rq = hwif->hwgroup->rq;
+       struct request *rq = hwif->rq;
        int stat, err, sense_key;
 
        /* check for errors */
@@ -340,8 +337,8 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
        }
 
        ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, "
-                     "rq->cmd_type: 0x%x, err: 0x%x\n", __func__, stat,
-                     good_stat, rq->cmd_type, err);
+                     "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x\n",
+                     __func__, stat, good_stat, rq->cmd[0], rq->cmd_type, err);
 
        if (blk_sense_request(rq)) {
                /*
@@ -426,16 +423,17 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
                                if (time_after(jiffies, info->write_timeout))
                                        do_end_request = 1;
                                else {
+                                       struct request_queue *q = drive->queue;
                                        unsigned long flags;
 
                                        /*
                                         * take a breather relying on the unplug
                                         * timer to kick us again
                                         */
-                                       spin_lock_irqsave(&ide_lock, flags);
-                                       blk_plug_device(drive->queue);
-                                       spin_unlock_irqrestore(&ide_lock,
-                                                               flags);
+                                       spin_lock_irqsave(q->queue_lock, flags);
+                                       blk_plug_device(q);
+                                       spin_unlock_irqrestore(q->queue_lock, flags);
+
                                        return 1;
                                }
                        }
@@ -504,12 +502,14 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
 
 end_request:
        if (stat & ATA_ERR) {
+               struct request_queue *q = drive->queue;
                unsigned long flags;
 
-               spin_lock_irqsave(&ide_lock, flags);
+               spin_lock_irqsave(q->queue_lock, flags);
                blkdev_dequeue_request(rq);
-               HWGROUP(drive)->rq = NULL;
-               spin_unlock_irqrestore(&ide_lock, flags);
+               spin_unlock_irqrestore(q->queue_lock, flags);
+
+               hwif->rq = NULL;
 
                cdrom_queue_request_sense(drive, rq->sense, rq);
        } else
@@ -518,135 +518,6 @@ end_request:
        return 1;
 }
 
-static int cdrom_timer_expiry(ide_drive_t *drive)
-{
-       struct request *rq = HWGROUP(drive)->rq;
-       unsigned long wait = 0;
-
-       ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd[0]: 0x%x\n", __func__,
-                     rq->cmd[0]);
-
-       /*
-        * Some commands are *slow* and normally take a long time to complete.
-        * Usually we can use the ATAPI "disconnect" to bypass this, but not all
-        * commands/drives support that. Let ide_timer_expiry keep polling us
-        * for these.
-        */
-       switch (rq->cmd[0]) {
-       case GPCMD_BLANK:
-       case GPCMD_FORMAT_UNIT:
-       case GPCMD_RESERVE_RZONE_TRACK:
-       case GPCMD_CLOSE_TRACK:
-       case GPCMD_FLUSH_CACHE:
-               wait = ATAPI_WAIT_PC;
-               break;
-       default:
-               if (!(rq->cmd_flags & REQ_QUIET))
-                       printk(KERN_INFO PFX "cmd 0x%x timed out\n",
-                                        rq->cmd[0]);
-               wait = 0;
-               break;
-       }
-       return wait;
-}
-
-/*
- * Set up the device registers for transferring a packet command on DEV,
- * expecting to later transfer XFERLEN bytes.  HANDLER is the routine
- * which actually transfers the command to the drive.  If this is a
- * drq_interrupt device, this routine will arrange for HANDLER to be
- * called when the interrupt from the drive arrives.  Otherwise, HANDLER
- * will be called immediately after the drive is prepared for the transfer.
- */
-static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
-                                                 int xferlen,
-                                                 ide_handler_t *handler)
-{
-       struct cdrom_info *info = drive->driver_data;
-       ide_hwif_t *hwif = drive->hwif;
-
-       ide_debug_log(IDE_DBG_PC, "Call %s, xferlen: %d\n", __func__, xferlen);
-
-       /* FIXME: for Virtual DMA we must check harder */
-       if (info->dma)
-               info->dma = !hwif->dma_ops->dma_setup(drive);
-
-       /* set up the controller registers */
-       ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL,
-                          xferlen, info->dma);
-
-       if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
-               /* waiting for CDB interrupt, not DMA yet. */
-               if (info->dma)
-                       drive->waiting_for_dma = 0;
-
-               /* packet command */
-               ide_execute_command(drive, ATA_CMD_PACKET, handler,
-                                   ATAPI_WAIT_PC, cdrom_timer_expiry);
-               return ide_started;
-       } else {
-               ide_execute_pkt_cmd(drive);
-
-               return (*handler) (drive);
-       }
-}
-
-/*
- * Send a packet command to DRIVE described by CMD_BUF and CMD_LEN. The device
- * registers must have already been prepared by cdrom_start_packet_command.
- * HANDLER is the interrupt handler to call when the command completes or
- * there's data ready.
- */
-#define ATAPI_MIN_CDB_BYTES 12
-static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive,
-                                         struct request *rq,
-                                         ide_handler_t *handler)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       int cmd_len;
-       struct cdrom_info *info = drive->driver_data;
-       ide_startstop_t startstop;
-
-       ide_debug_log(IDE_DBG_PC, "Call %s\n", __func__);
-
-       if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
-               /*
-                * Here we should have been called after receiving an interrupt
-                * from the device.  DRQ should how be set.
-                */
-
-               /* check for errors */
-               if (cdrom_decode_status(drive, ATA_DRQ, NULL))
-                       return ide_stopped;
-
-               /* ok, next interrupt will be DMA interrupt */
-               if (info->dma)
-                       drive->waiting_for_dma = 1;
-       } else {
-               /* otherwise, we must wait for DRQ to get set */
-               if (ide_wait_stat(&startstop, drive, ATA_DRQ,
-                                 ATA_BUSY, WAIT_READY))
-                       return startstop;
-       }
-
-       /* arm the interrupt handler */
-       ide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry);
-
-       /* ATAPI commands get padded out to 12 bytes minimum */
-       cmd_len = COMMAND_SIZE(rq->cmd[0]);
-       if (cmd_len < ATAPI_MIN_CDB_BYTES)
-               cmd_len = ATAPI_MIN_CDB_BYTES;
-
-       /* send the command to the device */
-       hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
-
-       /* start the DMA if need be */
-       if (info->dma)
-               hwif->dma_ops->dma_start(drive);
-
-       return ide_started;
-}
-
 /*
  * Check the contents of the interrupt reason register from the cdrom
  * and attempt to recover if there are problems.  Returns  0 if everything's
@@ -718,8 +589,6 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
        return 1;
 }
 
-static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);
-
 static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,
                                                 struct request *rq)
 {
@@ -762,66 +631,6 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,
 }
 
 /*
- * Routine to send a read/write packet command to the drive. This is usually
- * called directly from cdrom_start_{read,write}(). However, for drq_interrupt
- * devices, it is called from an interrupt when the drive is ready to accept
- * the command.
- */
-static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive)
-{
-       struct request *rq = drive->hwif->hwgroup->rq;
-
-       /* send the command to the drive and return */
-       return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
-}
-
-#define IDECD_SEEK_THRESHOLD   (1000)                  /* 1000 blocks */
-#define IDECD_SEEK_TIMER       (5 * WAIT_MIN_SLEEP)    /* 100 ms */
-#define IDECD_SEEK_TIMEOUT     (2 * WAIT_CMD)          /* 20 sec */
-
-static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive)
-{
-       struct cdrom_info *info = drive->driver_data;
-       int stat;
-       static int retry = 10;
-
-       ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
-       if (cdrom_decode_status(drive, 0, &stat))
-               return ide_stopped;
-
-       drive->atapi_flags |= IDE_AFLAG_SEEKING;
-
-       if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) {
-               if (--retry == 0)
-                       drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP;
-       }
-       return ide_stopped;
-}
-
-static void ide_cd_prepare_seek_request(ide_drive_t *drive, struct request *rq)
-{
-       sector_t frame = rq->sector;
-
-       ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
-       sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS);
-
-       memset(rq->cmd, 0, BLK_MAX_CDB);
-       rq->cmd[0] = GPCMD_SEEK;
-       put_unaligned(cpu_to_be32(frame), (unsigned int *) &rq->cmd[2]);
-
-       rq->timeout = ATAPI_WAIT_PC;
-}
-
-static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive)
-{
-       struct request *rq = drive->hwif->hwgroup->rq;
-
-       return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr);
-}
-
-/*
  * Fix up a possibly partially-processed request so that we can start it over
  * entirely, or even put it back on the request queue.
  */
@@ -845,13 +654,10 @@ static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq)
        rq->q->prep_rq_fn(rq->q, rq);
 }
 
-/*
- * All other packet commands.
- */
 static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq)
 {
-
-       ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+       ide_debug_log(IDE_DBG_FUNC, "Call %s, rq->cmd[0]: 0x%x\n",
+                     __func__, rq->cmd[0]);
 
        /*
         * Some of the trailing request sense fields are optional,
@@ -878,7 +684,7 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
        if (!sense)
                sense = &local_sense;
 
-       ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, "
+       ide_debug_log(IDE_DBG_PC, "Call %s, cmd[0]: 0x%x, write: 0x%x, "
                      "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write,
                      timeout, cmd_flags);
 
@@ -955,8 +761,7 @@ static int cdrom_newpc_intr_dummy_cb(struct request *rq)
 static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
-       struct cdrom_info *info = drive->driver_data;
-       struct request *rq = HWGROUP(drive)->rq;
+       struct request *rq = hwif->rq;
        xfer_func_t *xferfunc;
        ide_expiry_t *expiry = NULL;
        int dma_error = 0, dma, stat, thislen, uptodate = 0;
@@ -969,9 +774,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
                      __func__, rq->cmd[0], write);
 
        /* check for errors */
-       dma = info->dma;
+       dma = drive->dma;
        if (dma) {
-               info->dma = 0;
+               drive->dma = 0;
                dma_error = hwif->dma_ops->dma_end(drive);
                if (dma_error) {
                        printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name,
@@ -990,6 +795,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
                if (blk_fs_request(rq)) {
                        ide_end_request(drive, 1, rq->nr_sectors);
                        return ide_stopped;
+               } else if (rq->cmd_type == REQ_TYPE_ATA_PC && !rq->bio) {
+                       ide_end_request(drive, 1, 1);
+                       return ide_stopped;
                }
                goto end_request;
        }
@@ -1146,7 +954,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
        } else {
                timeout = ATAPI_WAIT_PC;
                if (!blk_fs_request(rq))
-                       expiry = cdrom_timer_expiry;
+                       expiry = ide_cd_expiry;
        }
 
        ide_set_handler(drive, cdrom_newpc_intr, timeout, expiry);
@@ -1154,17 +962,15 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 
 end_request:
        if (blk_pc_request(rq)) {
-               unsigned long flags;
                unsigned int dlen = rq->data_len;
 
                if (dma)
                        rq->data_len = 0;
 
-               spin_lock_irqsave(&ide_lock, flags);
-               if (__blk_end_request(rq, 0, dlen))
+               if (blk_end_request(rq, 0, dlen))
                        BUG();
-               HWGROUP(drive)->rq = NULL;
-               spin_unlock_irqrestore(&ide_lock, flags);
+
+               hwif->rq = NULL;
        } else {
                if (!uptodate)
                        rq->cmd_flags |= REQ_FAILED;
@@ -1180,8 +986,9 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
        unsigned short sectors_per_frame =
                queue_hardsect_size(drive->queue) >> SECTOR_BITS;
 
-       ide_debug_log(IDE_DBG_RQ, "Call %s, write: 0x%x, secs_per_frame: %u\n",
-                     __func__, write, sectors_per_frame);
+       ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, "
+                     "secs_per_frame: %u\n",
+                     __func__, rq->cmd[0], write, sectors_per_frame);
 
        if (write) {
                /* disk has become write protected */
@@ -1204,9 +1011,9 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
                        cdrom_end_request(drive, 0);
                        return ide_stopped;
                }
-               cd->dma = 0;
+               drive->dma = 0;
        } else
-               cd->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
+               drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
 
        if (write)
                cd->devinfo.media_written = 1;
@@ -1214,18 +1021,11 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
        return ide_started;
 }
 
-static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)
-{
-       struct request *rq = HWGROUP(drive)->rq;
-
-       return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
-}
-
 static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
 {
-       struct cdrom_info *info = drive->driver_data;
 
-       ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd_type: 0x%x\n", __func__,
+       ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, "
+                     "rq->cmd_type: 0x%x\n", __func__, rq->cmd[0],
                      rq->cmd_type);
 
        if (blk_pc_request(rq))
@@ -1233,7 +1033,7 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
        else
                rq->cmd_flags &= ~REQ_FAILED;
 
-       info->dma = 0;
+       drive->dma = 0;
 
        /* sg request */
        if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) {
@@ -1246,7 +1046,7 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
                else
                        buf = rq->data;
 
-               info->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
+               drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
 
                /*
                 * check if dma is safe
@@ -1255,69 +1055,29 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
                 * separate masks.
                 */
                alignment = queue_dma_alignment(q) | q->dma_pad_mask;
-               if ((unsigned long)buf & alignment || rq->data_len & alignment
+               if ((unsigned long)buf & alignment
+                   || rq->data_len & q->dma_pad_mask
                    || object_is_on_stack(buf))
-                       info->dma = 0;
+                       drive->dma = 0;
        }
 }
 
-/*
- * cdrom driver request routine.
- */
 static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
                                        sector_t block)
 {
-       struct cdrom_info *info = drive->driver_data;
-       ide_handler_t *fn;
-       int xferlen;
-
-       ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd_type: 0x%x, block: %llu\n",
-                     __func__, rq->cmd_type, (u64)block);
+       ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, "
+                     "rq->cmd_type: 0x%x, block: %llu\n",
+                     __func__, rq->cmd[0], rq->cmd_type,
+                     (unsigned long long)block);
 
        if (blk_fs_request(rq)) {
-               if (drive->atapi_flags & IDE_AFLAG_SEEKING) {
-                       ide_hwif_t *hwif = drive->hwif;
-                       unsigned long elapsed = jiffies - info->start_seek;
-                       int stat = hwif->tp_ops->read_status(hwif);
-
-                       if ((stat & ATA_DSC) != ATA_DSC) {
-                               if (elapsed < IDECD_SEEK_TIMEOUT) {
-                                       ide_stall_queue(drive,
-                                                       IDECD_SEEK_TIMER);
-                                       return ide_stopped;
-                               }
-                               printk(KERN_ERR PFX "%s: DSC timeout\n",
-                                               drive->name);
-                       }
-                       drive->atapi_flags &= ~IDE_AFLAG_SEEKING;
-               }
-               if (rq_data_dir(rq) == READ &&
-                   IDE_LARGE_SEEK(info->last_block, block,
-                           IDECD_SEEK_THRESHOLD) &&
-                   (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP)) {
-                       xferlen = 0;
-                       fn = cdrom_start_seek_continuation;
-
-                       info->dma = 0;
-                       info->start_seek = jiffies;
-
-                       ide_cd_prepare_seek_request(drive, rq);
-               } else {
-                       xferlen = 32768;
-                       fn = cdrom_start_rw_cont;
-
-                       if (cdrom_start_rw(drive, rq) == ide_stopped)
-                               return ide_stopped;
+               if (cdrom_start_rw(drive, rq) == ide_stopped)
+                       return ide_stopped;
 
-                       if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped)
-                               return ide_stopped;
-               }
-               info->last_block = block;
+               if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped)
+                       return ide_stopped;
        } else if (blk_sense_request(rq) || blk_pc_request(rq) ||
                   rq->cmd_type == REQ_TYPE_ATA_PC) {
-               xferlen = rq->data_len;
-               fn = cdrom_do_newpc_cont;
-
                if (!rq->timeout)
                        rq->timeout = ATAPI_WAIT_PC;
 
@@ -1332,7 +1092,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
                return ide_stopped;
        }
 
-       return cdrom_start_packet_command(drive, xferlen, fn);
+       return ide_issue_pc(drive);
 }
 
 /*
@@ -1416,6 +1176,10 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
 
        *capacity = 1 + be32_to_cpu(capbuf.lba);
        *sectors_per_frame = blocklen >> SECTOR_BITS;
+
+       ide_debug_log(IDE_DBG_PROBE, "%s: cap: %lu, sectors_per_frame: %lu\n",
+                     __func__, *capacity, *sectors_per_frame);
+
        return 0;
 }
 
@@ -1647,6 +1411,9 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
                maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]);
        }
 
+       ide_debug_log(IDE_DBG_PROBE, "%s: curspeed: %u, maxspeed: %u\n",
+                     __func__, curspeed, maxspeed);
+
        cd->current_speed = (curspeed + (176/2)) / 176;
        cd->max_speed = (maxspeed + (176/2)) / 176;
 }
@@ -1736,7 +1503,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
                return 0;
 
        if ((buf[8 + 6] & 0x01) == 0)
-               drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
+               drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
        if (buf[8 + 6] & 0x08)
                drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT;
        if (buf[8 + 3] & 0x01)
@@ -1781,7 +1548,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
        if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0)
                printk(KERN_CONT " DVD%s%s",
                                 (cdi->mask & CDC_DVD_R) ? "" : "-R",
-                                (cdi->mask & CDC_DVD_RAM) ? "" : "-RAM");
+                                (cdi->mask & CDC_DVD_RAM) ? "" : "/RAM");
 
        if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0)
                printk(KERN_CONT " CD%s%s",
@@ -1906,12 +1673,15 @@ static ide_proc_entry_t idecd_proc[] = {
        { NULL, 0, NULL, NULL }
 };
 
-ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP);
+static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive)
+{
+       return idecd_proc;
+}
 
-static const struct ide_proc_devset idecd_settings[] = {
-       IDE_PROC_DEVSET(dsc_overlap, 0, 1),
-       { 0 },
-};
+static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive)
+{
+       return NULL;
+}
 #endif
 
 static const struct cd_list_entry ide_cd_quirks_list[] = {
@@ -1955,6 +1725,7 @@ static const struct cd_list_entry ide_cd_quirks_list[] = {
        { "Optiarc DVD RW AD-5200A", NULL,   IDE_AFLAG_PLAY_AUDIO_OK         },
        { "Optiarc DVD RW AD-7200A", NULL,   IDE_AFLAG_PLAY_AUDIO_OK         },
        { "Optiarc DVD RW AD-7543A", NULL,   IDE_AFLAG_NO_AUTOCLOSE          },
+       { "TEAC CD-ROM CD-224E",     NULL,   IDE_AFLAG_NO_AUTOCLOSE          },
        { NULL, NULL, 0 }
 };
 
@@ -1990,8 +1761,8 @@ static int ide_cdrom_setup(ide_drive_t *drive)
        if (!drive->queue->unplug_delay)
                drive->queue->unplug_delay = 1;
 
-       drive->atapi_flags = IDE_AFLAG_MEDIA_CHANGED | IDE_AFLAG_NO_EJECT |
-                      ide_cd_flags(id);
+       drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
+       drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id);
 
        if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) &&
            fw_rev[4] == '1' && fw_rev[6] <= '2')
@@ -2009,11 +1780,6 @@ static int ide_cdrom_setup(ide_drive_t *drive)
        /* set correct block size */
        blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
 
-       if (drive->next != drive)
-               drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP;
-       else
-               drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP;
-
        if (ide_cdrom_register(drive, nslots)) {
                printk(KERN_ERR PFX "%s: %s failed to register device with the"
                                " cdrom driver.\n", drive->name, __func__);
@@ -2032,15 +1798,17 @@ static void ide_cd_remove(ide_drive_t *drive)
        ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
 
        ide_proc_unregister_driver(drive, info->driver);
-
+       device_del(&info->dev);
        del_gendisk(info->disk);
 
-       ide_cd_put(info);
+       mutex_lock(&idecd_ref_mutex);
+       put_device(&info->dev);
+       mutex_unlock(&idecd_ref_mutex);
 }
 
-static void ide_cd_release(struct kref *kref)
+static void ide_cd_release(struct device *dev)
 {
-       struct cdrom_info *info = to_ide_drv(kref, cdrom_info);
+       struct cdrom_info *info = to_ide_drv(dev, cdrom_info);
        struct cdrom_device_info *devinfo = &info->devinfo;
        ide_drive_t *drive = info->drive;
        struct gendisk *g = info->disk;
@@ -2050,7 +1818,6 @@ static void ide_cd_release(struct kref *kref)
        kfree(info->toc);
        if (devinfo->handle == drive)
                unregister_cdrom(devinfo);
-       drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP;
        drive->driver_data = NULL;
        blk_queue_prep_rq(drive->queue, NULL);
        g->private_data = NULL;
@@ -2060,7 +1827,7 @@ static void ide_cd_release(struct kref *kref)
 
 static int ide_cd_probe(ide_drive_t *);
 
-static ide_driver_t ide_cdrom_driver = {
+static struct ide_driver ide_cdrom_driver = {
        .gen_driver = {
                .owner          = THIS_MODULE,
                .name           = "ide-cdrom",
@@ -2071,24 +1838,21 @@ static ide_driver_t ide_cdrom_driver = {
        .version                = IDECD_VERSION,
        .do_request             = ide_cd_do_request,
        .end_request            = ide_end_request,
-       .error                  = __ide_error,
 #ifdef CONFIG_IDE_PROC_FS
-       .proc                   = idecd_proc,
-       .settings               = idecd_settings,
+       .proc_entries           = ide_cd_proc_entries,
+       .proc_devsets           = ide_cd_proc_devsets,
 #endif
 };
 
-static int idecd_open(struct inode *inode, struct file *file)
+static int idecd_open(struct block_device *bdev, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
-       struct cdrom_info *info;
+       struct cdrom_info *info = ide_cd_get(bdev->bd_disk);
        int rc = -ENOMEM;
 
-       info = ide_cd_get(disk);
        if (!info)
                return -ENXIO;
 
-       rc = cdrom_open(&info->devinfo, inode, file);
+       rc = cdrom_open(&info->devinfo, bdev, mode);
 
        if (rc < 0)
                ide_cd_put(info);
@@ -2096,12 +1860,11 @@ static int idecd_open(struct inode *inode, struct file *file)
        return rc;
 }
 
-static int idecd_release(struct inode *inode, struct file *file)
+static int idecd_release(struct gendisk *disk, fmode_t mode)
 {
-       struct gendisk *disk = inode->i_bdev->bd_disk;
        struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
 
-       cdrom_release(&info->devinfo, file);
+       cdrom_release(&info->devinfo, mode);
 
        ide_cd_put(info);
 
@@ -2147,10 +1910,9 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
        return 0;
 }
 
-static int idecd_ioctl(struct inode *inode, struct file *file,
+static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
                        unsigned int cmd, unsigned long arg)
 {
-       struct block_device *bdev = inode->i_bdev;
        struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info);
        int err;
 
@@ -2163,9 +1925,9 @@ static int idecd_ioctl(struct inode *inode, struct file *file,
                break;
        }
 
-       err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
+       err = generic_ide_ioctl(info->drive, bdev, cmd, arg);
        if (err == -EINVAL)
-               err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg);
+               err = cdrom_ioctl(&info->devinfo, bdev, mode, cmd, arg);
 
        return err;
 }
@@ -2190,15 +1952,18 @@ static struct block_device_operations idecd_ops = {
        .owner                  = THIS_MODULE,
        .open                   = idecd_open,
        .release                = idecd_release,
-       .ioctl                  = idecd_ioctl,
+       .locked_ioctl           = idecd_ioctl,
        .media_changed          = idecd_media_changed,
        .revalidate_disk        = idecd_revalidate_disk
 };
 
 /* module options */
 static char *ignore;
-
 module_param(ignore, charp, 0400);
+
+static unsigned long debug_mask;
+module_param(debug_mask, ulong, 0644);
+
 MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
 
 static int ide_cd_probe(ide_drive_t *drive)
@@ -2225,6 +1990,10 @@ static int ide_cd_probe(ide_drive_t *drive)
                        goto failed;
                }
        }
+
+       drive->debug_mask = debug_mask;
+       drive->irq_handler = cdrom_newpc_intr;
+
        info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
        if (info == NULL) {
                printk(KERN_ERR PFX "%s: Can't allocate a cdrom structure\n",
@@ -2238,7 +2007,12 @@ static int ide_cd_probe(ide_drive_t *drive)
 
        ide_init_disk(g, drive);
 
-       kref_init(&info->kref);
+       info->dev.parent = &drive->gendev;
+       info->dev.release = ide_cd_release;
+       dev_set_name(&info->dev, dev_name(&drive->gendev));
+
+       if (device_register(&info->dev))
+               goto out_free_disk;
 
        info->drive = drive;
        info->driver = &ide_cdrom_driver;
@@ -2252,7 +2026,7 @@ static int ide_cd_probe(ide_drive_t *drive)
        g->driverfs_dev = &drive->gendev;
        g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
        if (ide_cdrom_setup(drive)) {
-               ide_cd_release(&info->kref);
+               put_device(&info->dev);
                goto failed;
        }
 
@@ -2262,6 +2036,8 @@ static int ide_cd_probe(ide_drive_t *drive)
        add_disk(g);
        return 0;
 
+out_free_disk:
+       put_disk(g);
 out_free_cd:
        kfree(info);
 failed: