Merge branch 'for-2.6.36' of git://git.kernel.dk/linux-2.6-block
[pandora-kernel.git] / drivers / ide / ide-cd.c
index 2de76cc..31fc769 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/delay.h>
 #include <linux/timer.h>
 #include <linux/seq_file.h>
+#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
@@ -176,7 +177,7 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
                        if (!sense->valid)
                                break;
                        if (failed_command == NULL ||
-                                       !blk_fs_request(failed_command))
+                           failed_command->cmd_type != REQ_TYPE_FS)
                                break;
                        sector = (sense->information[0] << 24) |
                                 (sense->information[1] << 16) |
@@ -292,7 +293,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
                                  "stat 0x%x",
                                  rq->cmd[0], rq->cmd_type, err, stat);
 
-       if (blk_sense_request(rq)) {
+       if (rq->cmd_type == REQ_TYPE_SENSE) {
                /*
                 * We got an error trying to get sense info from the drive
                 * (probably while trying to recover from a former error).
@@ -303,7 +304,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
        }
 
        /* if we have an error, pass CHECK_CONDITION as the SCSI status byte */
-       if (blk_pc_request(rq) && !rq->errors)
+       if (rq->cmd_type == REQ_TYPE_BLOCK_PC && !rq->errors)
                rq->errors = SAM_STAT_CHECK_CONDITION;
 
        if (blk_noretry_request(rq))
@@ -311,13 +312,14 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
 
        switch (sense_key) {
        case NOT_READY:
-               if (blk_fs_request(rq) && rq_data_dir(rq) == WRITE) {
+               if (rq->cmd_type == REQ_TYPE_FS && rq_data_dir(rq) == WRITE) {
                        if (ide_cd_breathe(drive, rq))
                                return 1;
                } else {
                        cdrom_saw_media_change(drive);
 
-                       if (blk_fs_request(rq) && !blk_rq_quiet(rq))
+                       if (rq->cmd_type == REQ_TYPE_FS &&
+                           !(rq->cmd_flags & REQ_QUIET))
                                printk(KERN_ERR PFX "%s: tray open\n",
                                        drive->name);
                }
@@ -326,7 +328,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
        case UNIT_ATTENTION:
                cdrom_saw_media_change(drive);
 
-               if (blk_fs_request(rq) == 0)
+               if (rq->cmd_type != REQ_TYPE_FS)
                        return 0;
 
                /*
@@ -352,7 +354,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 (!blk_rq_quiet(rq))
+               if (!(rq->cmd_flags & REQ_QUIET))
                        ide_dump_status(drive, "command error", stat);
                do_end_request = 1;
                break;
@@ -361,20 +363,20 @@ 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 (!blk_rq_quiet(rq))
+               if (!(rq->cmd_flags & REQ_QUIET))
                        ide_dump_status(drive, "media error "
                                        "(bad sector)", stat);
                do_end_request = 1;
                break;
        case BLANK_CHECK:
                /* disk appears blank? */
-               if (!blk_rq_quiet(rq))
+               if (!(rq->cmd_flags & REQ_QUIET))
                        ide_dump_status(drive, "media error (blank)",
                                        stat);
                do_end_request = 1;
                break;
        default:
-               if (blk_fs_request(rq) == 0)
+               if (rq->cmd_type != REQ_TYPE_FS)
                        break;
                if (err & ~ATA_ABORTED) {
                        /* go to the default handler for other errors */
@@ -385,7 +387,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
                        do_end_request = 1;
        }
 
-       if (blk_fs_request(rq) == 0) {
+       if (rq->cmd_type != REQ_TYPE_FS) {
                rq->cmd_flags |= REQ_FAILED;
                do_end_request = 1;
        }
@@ -532,7 +534,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
        ide_expiry_t *expiry = NULL;
        int dma_error = 0, dma, thislen, uptodate = 0;
        int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0;
-       int sense = blk_sense_request(rq);
+       int sense = (rq->cmd_type == REQ_TYPE_SENSE);
        unsigned int timeout;
        u16 len;
        u8 ireason, stat;
@@ -575,7 +577,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 
        ide_read_bcount_and_ireason(drive, &len, &ireason);
 
-       thislen = blk_fs_request(rq) ? len : cmd->nleft;
+       thislen = (rq->cmd_type == REQ_TYPE_FS) ? len : cmd->nleft;
        if (thislen > len)
                thislen = len;
 
@@ -584,7 +586,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 
        /* If DRQ is clear, the command has completed. */
        if ((stat & ATA_DRQ) == 0) {
-               if (blk_fs_request(rq)) {
+               if (rq->cmd_type == REQ_TYPE_FS) {
                        /*
                         * If we're not done reading/writing, complain.
                         * Otherwise, complete the command normally.
@@ -598,7 +600,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
                                        rq->cmd_flags |= REQ_FAILED;
                                uptodate = 0;
                        }
-               } else if (!blk_pc_request(rq)) {
+               } else if (rq->cmd_type != REQ_TYPE_BLOCK_PC) {
                        ide_cd_request_sense_fixup(drive, cmd);
 
                        uptodate = cmd->nleft ? 0 : 1;
@@ -647,7 +649,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
 
        /* pad, if necessary */
        if (len > 0) {
-               if (blk_fs_request(rq) == 0 || write == 0)
+               if (rq->cmd_type != REQ_TYPE_FS || write == 0)
                        ide_pad_transfer(drive, write, len);
                else {
                        printk(KERN_ERR PFX "%s: confused, missing data\n",
@@ -656,11 +658,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
                }
        }
 
-       if (blk_pc_request(rq)) {
+       if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
                timeout = rq->timeout;
        } else {
                timeout = ATAPI_WAIT_PC;
-               if (!blk_fs_request(rq))
+               if (rq->cmd_type != REQ_TYPE_FS)
                        expiry = ide_cd_expiry;
        }
 
@@ -669,7 +671,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
        return ide_started;
 
 out_end:
-       if (blk_pc_request(rq) && rc == 0) {
+       if (rq->cmd_type == REQ_TYPE_BLOCK_PC && rc == 0) {
                rq->resid_len = 0;
                blk_end_request_all(rq, 0);
                hwif->rq = NULL;
@@ -677,7 +679,7 @@ out_end:
                if (sense && uptodate)
                        ide_cd_complete_failed_rq(drive, rq);
 
-               if (blk_fs_request(rq)) {
+               if (rq->cmd_type == REQ_TYPE_FS) {
                        if (cmd->nleft == 0)
                                uptodate = 1;
                } else {
@@ -690,7 +692,7 @@ out_end:
                                return ide_stopped;
 
                /* make sure it's fully ended */
-               if (blk_fs_request(rq) == 0) {
+               if (rq->cmd_type != REQ_TYPE_FS) {
                        rq->resid_len -= cmd->nbytes - cmd->nleft;
                        if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE))
                                rq->resid_len += cmd->last_xfer_len;
@@ -750,7 +752,7 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
        ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x",
                                  rq->cmd[0], rq->cmd_type);
 
-       if (blk_pc_request(rq))
+       if (rq->cmd_type == REQ_TYPE_BLOCK_PC)
                rq->cmd_flags |= REQ_QUIET;
        else
                rq->cmd_flags &= ~REQ_FAILED;
@@ -791,21 +793,26 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
        if (drive->debug_mask & IDE_DBG_RQ)
                blk_dump_rq_flags(rq, "ide_cd_do_request");
 
-       if (blk_fs_request(rq)) {
+       switch (rq->cmd_type) {
+       case REQ_TYPE_FS:
                if (cdrom_start_rw(drive, rq) == ide_stopped)
                        goto out_end;
-       } else if (blk_sense_request(rq) || blk_pc_request(rq) ||
-                  rq->cmd_type == REQ_TYPE_ATA_PC) {
+               break;
+       case REQ_TYPE_SENSE:
+       case REQ_TYPE_BLOCK_PC:
+       case REQ_TYPE_ATA_PC:
                if (!rq->timeout)
                        rq->timeout = ATAPI_WAIT_PC;
 
                cdrom_do_block_pc(drive, rq);
-       } else if (blk_special_request(rq)) {
+               break;
+       case REQ_TYPE_SPECIAL:
                /* right now this can only be a reset... */
                uptodate = 1;
                goto out_end;
-       } else
+       default:
                BUG();
+       }
 
        /* prepare sense request for this command */
        ide_prep_sense(drive, rq);
@@ -817,7 +824,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
 
        cmd.rq = rq;
 
-       if (blk_fs_request(rq) || blk_rq_bytes(rq)) {
+       if (rq->cmd_type == REQ_TYPE_FS || blk_rq_bytes(rq)) {
                ide_init_sg_cmd(&cmd, blk_rq_bytes(rq));
                ide_map_sg(drive, &cmd);
        }
@@ -1373,9 +1380,9 @@ static int ide_cdrom_prep_pc(struct request *rq)
 
 static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq)
 {
-       if (blk_fs_request(rq))
+       if (rq->cmd_type == REQ_TYPE_FS)
                return ide_cdrom_prep_fs(q, rq);
-       else if (blk_pc_request(rq))
+       else if (rq->cmd_type == REQ_TYPE_BLOCK_PC)
                return ide_cdrom_prep_pc(rq);
 
        return 0;
@@ -1592,17 +1599,19 @@ static struct ide_driver ide_cdrom_driver = {
 
 static int idecd_open(struct block_device *bdev, fmode_t mode)
 {
-       struct cdrom_info *info = ide_cd_get(bdev->bd_disk);
-       int rc = -ENOMEM;
+       struct cdrom_info *info;
+       int rc = -ENXIO;
 
+       lock_kernel();
+       info = ide_cd_get(bdev->bd_disk);
        if (!info)
-               return -ENXIO;
+               goto out;
 
        rc = cdrom_open(&info->devinfo, bdev, mode);
-
        if (rc < 0)
                ide_cd_put(info);
-
+out:
+       unlock_kernel();
        return rc;
 }
 
@@ -1610,9 +1619,11 @@ static int idecd_release(struct gendisk *disk, fmode_t mode)
 {
        struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
 
+       lock_kernel();
        cdrom_release(&info->devinfo, mode);
 
        ide_cd_put(info);
+       unlock_kernel();
 
        return 0;
 }
@@ -1656,7 +1667,7 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
        return 0;
 }
 
-static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
+static int idecd_locked_ioctl(struct block_device *bdev, fmode_t mode,
                        unsigned int cmd, unsigned long arg)
 {
        struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info);
@@ -1678,6 +1689,19 @@ static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
        return err;
 }
 
+static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
+                            unsigned int cmd, unsigned long arg)
+{
+       int ret;
+
+       lock_kernel();
+       ret = idecd_locked_ioctl(bdev, mode, cmd, arg);
+       unlock_kernel();
+
+       return ret;
+}
+
+
 static int idecd_media_changed(struct gendisk *disk)
 {
        struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
@@ -1698,7 +1722,7 @@ static const struct block_device_operations idecd_ops = {
        .owner                  = THIS_MODULE,
        .open                   = idecd_open,
        .release                = idecd_release,
-       .locked_ioctl           = idecd_ioctl,
+       .ioctl                  = idecd_ioctl,
        .media_changed          = idecd_media_changed,
        .revalidate_disk        = idecd_revalidate_disk
 };