USB: CP2101 Support AN205 baud rates
[safe/jmp/linux-2.6] / drivers / ide / ide-cd.c
index 2cb301d..ddfbea4 100644 (file)
@@ -55,7 +55,7 @@
 
 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)
 {
@@ -67,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);
@@ -79,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);
 }
@@ -194,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);
@@ -510,99 +518,6 @@ end_request:
        return 1;
 }
 
-static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *);
-static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);
-
-/*
- * 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)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       struct request *rq = hwif->rq;
-       int xferlen;
-
-       xferlen = ide_cd_get_xferlen(rq);
-
-       ide_debug_log(IDE_DBG_PC, "Call %s, xferlen: %d\n", __func__, xferlen);
-
-       /* FIXME: for Virtual DMA we must check harder */
-       if (drive->dma)
-               drive->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, drive->dma);
-
-       if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
-               /* waiting for CDB interrupt, not DMA yet. */
-               if (drive->dma)
-                       drive->waiting_for_dma = 0;
-
-               /* packet command */
-               ide_execute_command(drive, ATA_CMD_PACKET,
-                                   cdrom_transfer_packet_command,
-                                   ATAPI_WAIT_PC, ide_cd_expiry);
-               return ide_started;
-       } else {
-               ide_execute_pkt_cmd(drive);
-
-               return cdrom_transfer_packet_command(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)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       struct request *rq = hwif->rq;
-       int cmd_len;
-       ide_startstop_t startstop;
-
-       ide_debug_log(IDE_DBG_PC, "Call %s\n", __func__);
-
-       /* we must wait for DRQ to get set */
-       if (ide_wait_stat(&startstop, drive, ATA_DRQ, ATA_BUSY, WAIT_READY)) {
-               printk(KERN_ERR "%s: timeout while waiting for DRQ to assert\n",
-                               drive->name);
-               return startstop;
-       }
-
-       if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
-               /* ok, next interrupt will be DMA interrupt */
-               if (drive->dma)
-                       drive->waiting_for_dma = 1;
-       }
-
-       /* arm the interrupt handler */
-       ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, ide_cd_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;
-
-       /* start the DMA if need be */
-       if (drive->dma)
-               hwif->dma_ops->dma_start(drive);
-
-       /* send the command to the device */
-       hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
-
-       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
@@ -880,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;
        }
@@ -1174,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);
+       return ide_issue_pc(drive);
 }
 
 /*
@@ -1880,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;
@@ -2072,6 +1992,7 @@ static int ide_cd_probe(ide_drive_t *drive)
        }
 
        drive->debug_mask = debug_mask;
+       drive->irq_handler = cdrom_newpc_intr;
 
        info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
        if (info == NULL) {
@@ -2086,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;
@@ -2100,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;
        }
 
@@ -2110,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: