ide-cd: remove wait-for-idle-controller bit in cdrom_start_packet_command
[pandora-kernel.git] / drivers / ide / ide-cd.c
index 68e7f19..eb4b275 100644 (file)
@@ -188,16 +188,6 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
        ide_cd_log_error(drive->name, failed_command, sense);
 }
 
-/* Initialize a ide-cd packet command request */
-void ide_cd_init_rq(ide_drive_t *drive, struct request *rq)
-{
-       struct cdrom_info *cd = drive->driver_data;
-
-       ide_init_drive_cmd(rq);
-       rq->cmd_type = REQ_TYPE_ATA_PC;
-       rq->rq_disk = cd->disk;
-}
-
 static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
                                      struct request *failed_command)
 {
@@ -208,7 +198,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
                sense = &info->sense_data;
 
        /* stuff the sense request in front of our current request */
-       ide_cd_init_rq(drive, rq);
+       blk_rq_init(NULL, rq);
+       rq->cmd_type = REQ_TYPE_ATA_PC;
+       rq->rq_disk = info->disk;
 
        rq->data = sense;
        rq->cmd[0] = GPCMD_REQUEST_SENSE;
@@ -216,11 +208,12 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
        rq->data_len = 18;
 
        rq->cmd_type = REQ_TYPE_SENSE;
+       rq->cmd_flags |= REQ_PREEMPT;
 
        /* NOTE! Save the failed command in "rq->buffer" */
        rq->buffer = (void *) failed_command;
 
-       (void) ide_do_drive_cmd(drive, rq, ide_preempt);
+       ide_do_drive_cmd(drive, rq);
 }
 
 static void cdrom_end_request(ide_drive_t *drive, int uptodate)
@@ -524,21 +517,16 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
                                                  int xferlen,
                                                  ide_handler_t *handler)
 {
-       ide_startstop_t startstop;
        struct cdrom_info *info = drive->driver_data;
        ide_hwif_t *hwif = drive->hwif;
 
-       /* wait for the controller to be idle */
-       if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY))
-               return startstop;
-
        /* 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 |
-                          IDE_TFLAG_NO_SELECT_MASK, xferlen, info->dma);
+       ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL,
+                          xferlen, info->dma);
 
        if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) {
                /* waiting for CDB interrupt, not DMA yet. */
@@ -838,34 +826,54 @@ static void ide_cd_request_sense_fixup(struct request *rq)
                }
 }
 
-int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq)
+int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
+                   int write, void *buffer, unsigned *bufflen,
+                   struct request_sense *sense, int timeout,
+                   unsigned int cmd_flags)
 {
-       struct request_sense sense;
+       struct cdrom_info *info = drive->driver_data;
+       struct request_sense local_sense;
        int retries = 10;
-       unsigned int flags = rq->cmd_flags;
+       unsigned int flags = 0;
 
-       if (rq->sense == NULL)
-               rq->sense = &sense;
+       if (!sense)
+               sense = &local_sense;
 
        /* start of retry loop */
        do {
+               struct request *rq;
                int error;
-               unsigned long time = jiffies;
-               rq->cmd_flags = flags;
 
-               error = ide_do_drive_cmd(drive, rq, ide_wait);
-               time = jiffies - time;
+               rq = blk_get_request(drive->queue, write, __GFP_WAIT);
+
+               memcpy(rq->cmd, cmd, BLK_MAX_CDB);
+               rq->cmd_type = REQ_TYPE_ATA_PC;
+               rq->sense = sense;
+               rq->cmd_flags |= cmd_flags;
+               rq->timeout = timeout;
+               if (buffer) {
+                       rq->data = buffer;
+                       rq->data_len = *bufflen;
+               }
+
+               error = blk_execute_rq(drive->queue, info->disk, rq, 0);
+
+               if (buffer)
+                       *bufflen = rq->data_len;
+
+               flags = rq->cmd_flags;
+               blk_put_request(rq);
 
                /*
                 * FIXME: we should probably abort/retry or something in case of
                 * failure.
                 */
-               if (rq->cmd_flags & REQ_FAILED) {
+               if (flags & REQ_FAILED) {
                        /*
                         * The request failed.  Retry if it was due to a unit
                         * attention status (usually means media was changed).
                         */
-                       struct request_sense *reqbuf = rq->sense;
+                       struct request_sense *reqbuf = sense;
 
                        if (reqbuf->sense_key == UNIT_ATTENTION)
                                cdrom_saw_media_change(drive);
@@ -885,10 +893,10 @@ int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq)
                }
 
                /* end of retry loop */
-       } while ((rq->cmd_flags & REQ_FAILED) && retries >= 0);
+       } while ((flags & REQ_FAILED) && retries >= 0);
 
        /* return an error if the command failed */
-       return (rq->cmd_flags & REQ_FAILED) ? -EIO : 0;
+       return (flags & REQ_FAILED) ? -EIO : 0;
 }
 
 /*
@@ -1178,10 +1186,16 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
        info->dma = 0;
 
        /* sg request */
-       if (rq->bio) {
-               int mask = drive->queue->dma_alignment;
-               unsigned long addr =
-                       (unsigned long)page_address(bio_page(rq->bio));
+       if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) {
+               struct request_queue *q = drive->queue;
+               unsigned int alignment;
+               unsigned long addr;
+               unsigned long stack_mask = ~(THREAD_SIZE - 1);
+
+               if (rq->bio)
+                       addr = (unsigned long)bio_data(rq->bio);
+               else
+                       addr = (unsigned long)rq->data;
 
                info->dma = drive->using_dma;
 
@@ -1191,7 +1205,12 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
                 * NOTE! The "len" and "addr" checks should possibly have
                 * separate masks.
                 */
-               if ((rq->data_len & 15) || (addr & mask))
+               alignment = queue_dma_alignment(q) | q->dma_pad_mask;
+               if (addr & alignment || rq->data_len & alignment)
+                       info->dma = 0;
+
+               if (!((addr & stack_mask) ^
+                     ((unsigned long)current->stack & stack_mask)))
                        info->dma = 0;
        }
 
@@ -1268,23 +1287,20 @@ static void msf_from_bcd(struct atapi_msf *msf)
 
 int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
 {
-       struct request req;
        struct cdrom_info *info = drive->driver_data;
        struct cdrom_device_info *cdi = &info->devinfo;
+       unsigned char cmd[BLK_MAX_CDB];
 
-       ide_cd_init_rq(drive, &req);
-
-       req.sense = sense;
-       req.cmd[0] = GPCMD_TEST_UNIT_READY;
-       req.cmd_flags |= REQ_QUIET;
+       memset(cmd, 0, BLK_MAX_CDB);
+       cmd[0] = GPCMD_TEST_UNIT_READY;
 
        /*
         * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to switch CDs
         * instead of supporting the LOAD_UNLOAD opcode.
         */
-       req.cmd[7] = cdi->sanyo_slot % 3;
+       cmd[7] = cdi->sanyo_slot % 3;
 
-       return ide_cd_queue_pc(drive, &req);
+       return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, sense, 0, REQ_QUIET);
 }
 
 static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
@@ -1297,17 +1313,14 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
        } capbuf;
 
        int stat;
-       struct request req;
-
-       ide_cd_init_rq(drive, &req);
+       unsigned char cmd[BLK_MAX_CDB];
+       unsigned len = sizeof(capbuf);
 
-       req.sense = sense;
-       req.cmd[0] = GPCMD_READ_CDVD_CAPACITY;
-       req.data = (char *)&capbuf;
-       req.data_len = sizeof(capbuf);
-       req.cmd_flags |= REQ_QUIET;
+       memset(cmd, 0, BLK_MAX_CDB);
+       cmd[0] = GPCMD_READ_CDVD_CAPACITY;
 
-       stat = ide_cd_queue_pc(drive, &req);
+       stat = ide_cd_queue_pc(drive, cmd, 0, &capbuf, &len, sense, 0,
+                              REQ_QUIET);
        if (stat == 0) {
                *capacity = 1 + be32_to_cpu(capbuf.lba);
                *sectors_per_frame =
@@ -1321,24 +1334,20 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
                                int format, char *buf, int buflen,
                                struct request_sense *sense)
 {
-       struct request req;
+       unsigned char cmd[BLK_MAX_CDB];
 
-       ide_cd_init_rq(drive, &req);
+       memset(cmd, 0, BLK_MAX_CDB);
 
-       req.sense = sense;
-       req.data =  buf;
-       req.data_len = buflen;
-       req.cmd_flags |= REQ_QUIET;
-       req.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
-       req.cmd[6] = trackno;
-       req.cmd[7] = (buflen >> 8);
-       req.cmd[8] = (buflen & 0xff);
-       req.cmd[9] = (format << 6);
+       cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
+       cmd[6] = trackno;
+       cmd[7] = (buflen >> 8);
+       cmd[8] = (buflen & 0xff);
+       cmd[9] = (format << 6);
 
        if (msf_flag)
-               req.cmd[1] = 2;
+               cmd[1] = 2;
 
-       return ide_cd_queue_pc(drive, &req);
+       return ide_cd_queue_pc(drive, cmd, 0, buf, &buflen, sense, 0, REQ_QUIET);
 }
 
 /* Try to read the entire TOC for the disk into our internal buffer. */
@@ -1869,6 +1878,7 @@ static int ide_cdrom_setup(ide_drive_t *drive)
 
        blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
        blk_queue_dma_alignment(drive->queue, 31);
+       blk_queue_update_dma_pad(drive->queue, 15);
        drive->queue->unplug_delay = (1 * HZ) / 1000;
        if (!drive->queue->unplug_delay)
                drive->queue->unplug_delay = 1;
@@ -2103,11 +2113,6 @@ static int ide_cd_probe(ide_drive_t *drive)
                        goto failed;
                }
        }
-       if (drive->scsi) {
-               printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi "
-                                "emulation.\n", drive->name);
-               goto failed;
-       }
        info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
        if (info == NULL) {
                printk(KERN_ERR "%s: Can't allocate a cdrom structure\n",