alim15x3: fix handling of command timings
[safe/jmp/linux-2.6] / drivers / ide / ide-cd.c
index 081aed6..64207df 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/timer.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
@@ -92,16 +93,16 @@ static void cdrom_saw_media_change(ide_drive_t *drive)
        drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID;
 }
 
-static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
-                          struct request_sense *sense)
+static int cdrom_log_sense(ide_drive_t *drive, struct request *rq)
 {
+       struct request_sense *sense = &drive->sense_data;
        int log = 0;
 
-       ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key);
-
        if (!sense || !rq || (rq->cmd_flags & REQ_QUIET))
                return 0;
 
+       ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key);
+
        switch (sense->sense_key) {
        case NO_SENSE:
        case RECOVERED_ERROR:
@@ -140,12 +141,12 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
 }
 
 static void cdrom_analyze_sense_data(ide_drive_t *drive,
-                             struct request *failed_command,
-                             struct request_sense *sense)
+                                    struct request *failed_command)
 {
+       struct request_sense *sense = &drive->sense_data;
+       struct cdrom_info *info = drive->driver_data;
        unsigned long sector;
        unsigned long bio_sectors;
-       struct cdrom_info *info = drive->driver_data;
 
        ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x",
                                     sense->error_code, sense->sense_key);
@@ -154,7 +155,7 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
                ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x",
                                             failed_command->cmd[0]);
 
-       if (!cdrom_log_sense(drive, failed_command, sense))
+       if (!cdrom_log_sense(drive, failed_command))
                return;
 
        /*
@@ -182,7 +183,7 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
                                 (sense->information[2] <<  8) |
                                 (sense->information[3]);
 
-                       if (drive->queue->hardsect_size == 2048)
+                       if (queue_logical_block_size(drive->queue) == 2048)
                                /* device sector size is 2K */
                                sector <<= 2;
 
@@ -225,15 +226,14 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
                         * sense pointer set.
                         */
                        memcpy(failed->sense, sense, 18);
-                       sense = failed->sense;
                        failed->sense_len = rq->sense_len;
                }
-               cdrom_analyze_sense_data(drive, failed, sense);
+               cdrom_analyze_sense_data(drive, failed);
 
                if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed)))
                        BUG();
        } else
-               cdrom_analyze_sense_data(drive, NULL, sense);
+               cdrom_analyze_sense_data(drive, NULL);
 }
 
 
@@ -283,7 +283,6 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
        ide_hwif_t *hwif = drive->hwif;
        struct request *rq = hwif->rq;
        int err, sense_key, do_end_request = 0;
-       u8 quiet = rq->cmd_flags & REQ_QUIET;
 
        /* get the IDE error register */
        err = ide_read_error(drive);
@@ -318,7 +317,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
                } else {
                        cdrom_saw_media_change(drive);
 
-                       if (blk_fs_request(rq) && !quiet)
+                       if (blk_fs_request(rq) && !blk_rq_quiet(rq))
                                printk(KERN_ERR PFX "%s: tray open\n",
                                        drive->name);
                }
@@ -353,7 +352,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
                 * No point in retrying after an illegal request or data
                 * protect error.
                 */
-               if (!quiet)
+               if (!blk_rq_quiet(rq))
                        ide_dump_status(drive, "command error", stat);
                do_end_request = 1;
                break;
@@ -362,14 +361,14 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
                 * No point in re-trying a zillion times on a bad sector.
                 * If we got here the error is not correctable.
                 */
-               if (!quiet)
+               if (!blk_rq_quiet(rq))
                        ide_dump_status(drive, "media error "
                                        "(bad sector)", stat);
                do_end_request = 1;
                break;
        case BLANK_CHECK:
                /* disk appears blank? */
-               if (!quiet)
+               if (!blk_rq_quiet(rq))
                        ide_dump_status(drive, "media error (blank)",
                                        stat);
                do_end_request = 1;
@@ -411,50 +410,6 @@ end_request:
                return 2;
 }
 
-/*
- * Check the contents of the interrupt reason register from the cdrom
- * and attempt to recover if there are problems.  Returns  0 if everything's
- * ok; nonzero if the request has been terminated.
- */
-static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
-                               int len, int ireason, int rw)
-{
-       ide_hwif_t *hwif = drive->hwif;
-
-       ide_debug_log(IDE_DBG_FUNC, "ireason: 0x%x, rw: 0x%x", ireason, rw);
-
-       /*
-        * ireason == 0: the drive wants to receive data from us
-        * ireason == 2: the drive is expecting to transfer data to us
-        */
-       if (ireason == (!rw << 1))
-               return 0;
-       else if (ireason == (rw << 1)) {
-
-               /* whoops... */
-               printk(KERN_ERR PFX "%s: %s: wrong transfer direction!\n",
-                               drive->name, __func__);
-
-               ide_pad_transfer(drive, rw, len);
-       } else  if (rw == 0 && ireason == 1) {
-               /*
-                * Some drives (ASUS) seem to tell us that status info is
-                * available.  Just get it and ignore.
-                */
-               (void)hwif->tp_ops->read_status(hwif);
-               return 0;
-       } else {
-               /* drive wants a command packet, or invalid ireason... */
-               printk(KERN_ERR PFX "%s: %s: bad interrupt reason 0x%02x\n",
-                               drive->name, __func__, ireason);
-       }
-
-       if (rq->cmd_type == REQ_TYPE_ATA_PC)
-               rq->cmd_flags |= REQ_FAILED;
-
-       return -1;
-}
-
 static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd)
 {
        struct request *rq = cmd->rq;
@@ -638,16 +593,25 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
                        }
                } else if (!blk_pc_request(rq)) {
                        ide_cd_request_sense_fixup(drive, cmd);
-                       /* complain if we still have data left to transfer */
+
                        uptodate = cmd->nleft ? 0 : 1;
-                       if (uptodate == 0)
+
+                       /*
+                        * suck out the remaining bytes from the drive in an
+                        * attempt to complete the data xfer. (see BZ#13399)
+                        */
+                       if (!(stat & ATA_ERR) && !uptodate && thislen) {
+                               ide_pio_bytes(drive, cmd, write, thislen);
+                               uptodate = cmd->nleft ? 0 : 1;
+                       }
+
+                       if (!uptodate)
                                rq->cmd_flags |= REQ_FAILED;
                }
                goto out_end;
        }
 
-       /* check which way to transfer data */
-       rc = ide_cd_check_ireason(drive, rq, len, ireason, write);
+       rc = ide_check_ireason(drive, rq, len, ireason, write);
        if (rc)
                goto out_end;
 
@@ -714,7 +678,7 @@ out_end:
                                rq->errors = -EIO;
                }
 
-               if (uptodate == 0)
+               if (uptodate == 0 && rq->bio)
                        ide_cd_error_cmd(drive, cmd);
 
                /* make sure it's fully ended */
@@ -738,7 +702,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
        struct request_queue *q = drive->queue;
        int write = rq_data_dir(rq) == WRITE;
        unsigned short sectors_per_frame =
-               queue_hardsect_size(q) >> SECTOR_BITS;
+               queue_logical_block_size(q) >> SECTOR_BITS;
 
        ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, "
                                  "secs_per_frame: %u",
@@ -832,12 +796,8 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
                /* right now this can only be a reset... */
                uptodate = 1;
                goto out_end;
-       } else {
-               blk_dump_rq_flags(rq, DRV_NAME " bad flags");
-               if (rq->errors == 0)
-                       rq->errors = -EIO;
-               goto out_end;
-       }
+       } else
+               BUG();
 
        /* prepare sense request for this command */
        ide_prep_sense(drive, rq);
@@ -927,9 +887,12 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
                return stat;
 
        /*
-        * Sanity check the given block size
+        * Sanity check the given block size, in so far as making
+        * sure the sectors_per_frame we give to the caller won't
+        * end up being bogus.
         */
        blocklen = be32_to_cpu(capbuf.blocklen);
+       blocklen = (blocklen >> SECTOR_BITS) << SECTOR_BITS;
        switch (blocklen) {
        case 512:
        case 1024:
@@ -937,10 +900,9 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
        case 4096:
                break;
        default:
-               printk(KERN_ERR PFX "%s: weird block size %u\n",
+               printk_once(KERN_ERR PFX "%s: weird block size %u; "
+                               "setting default block size to 2048\n",
                                drive->name, blocklen);
-               printk(KERN_ERR PFX "%s: default to 2kb block size\n",
-                               drive->name);
                blocklen = 2048;
                break;
        }
@@ -1022,8 +984,8 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
        /* save a private copy of the TOC capacity for error handling */
        drive->probed_capacity = toc->capacity * sectors_per_frame;
 
-       blk_queue_hardsect_size(drive->queue,
-                               sectors_per_frame << SECTOR_BITS);
+       blk_queue_logical_block_size(drive->queue,
+                                    sectors_per_frame << SECTOR_BITS);
 
        /* first read just the header, so we know how long the TOC is */
        stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
@@ -1185,8 +1147,8 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
        ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u",
                                     curspeed, maxspeed);
 
-       cd->current_speed = (curspeed + (176/2)) / 176;
-       cd->max_speed = (maxspeed + (176/2)) / 176;
+       cd->current_speed = DIV_ROUND_CLOSEST(curspeed, 176);
+       cd->max_speed = DIV_ROUND_CLOSEST(maxspeed, 176);
 }
 
 #define IDE_CD_CAPABILITIES \
@@ -1339,7 +1301,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
 /* standard prep_rq_fn that builds 10 byte cmds */
 static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
 {
-       int hard_sect = queue_hardsect_size(q);
+       int hard_sect = queue_logical_block_size(q);
        long block = (long)blk_rq_pos(rq) / (hard_sect >> 9);
        unsigned long blocks = blk_rq_sectors(rq) / (hard_sect >> 9);
 
@@ -1428,19 +1390,30 @@ static sector_t ide_cdrom_capacity(ide_drive_t *drive)
        return capacity * sectors_per_frame;
 }
 
-static int proc_idecd_read_capacity(char *page, char **start, off_t off,
-                                       int count, int *eof, void *data)
+static int idecd_capacity_proc_show(struct seq_file *m, void *v)
 {
-       ide_drive_t *drive = data;
-       int len;
+       ide_drive_t *drive = m->private;
 
-       len = sprintf(page, "%llu\n", (long long)ide_cdrom_capacity(drive));
-       PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+       seq_printf(m, "%llu\n", (long long)ide_cdrom_capacity(drive));
+       return 0;
 }
 
+static int idecd_capacity_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, idecd_capacity_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations idecd_capacity_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = idecd_capacity_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
 static ide_proc_entry_t idecd_proc[] = {
-       { "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL },
-       { NULL, 0, NULL, NULL }
+       { "capacity", S_IFREG|S_IRUGO, &idecd_capacity_proc_fops },
+       {}
 };
 
 static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive)
@@ -1544,7 +1517,7 @@ static int ide_cdrom_setup(ide_drive_t *drive)
 
        nslots = ide_cdrom_probe_capabilities(drive);
 
-       blk_queue_hardsect_size(q, CD_FRAMESIZE);
+       blk_queue_logical_block_size(q, CD_FRAMESIZE);
 
        if (ide_cdrom_register(drive, nslots)) {
                printk(KERN_ERR PFX "%s: %s failed to register device with the"
@@ -1713,7 +1686,7 @@ static int idecd_revalidate_disk(struct gendisk *disk)
        return  0;
 }
 
-static struct block_device_operations idecd_ops = {
+static const struct block_device_operations idecd_ops = {
        .owner                  = THIS_MODULE,
        .open                   = idecd_open,
        .release                = idecd_release,