]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/ide/ide-atapi.c
ide-atapi: start DMA after issuing a packet command
[mv-sheeva.git] / drivers / ide / ide-atapi.c
index f7fe1decb59d4720e4a3ec86ee5e62d42e94eb86..f591166d2c9335739de34748d688e82880d476e1 100644 (file)
@@ -6,6 +6,8 @@
 #include <linux/cdrom.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
+#include <linux/scatterlist.h>
+
 #include <scsi/scsi.h>
 
 #ifdef DEBUG
@@ -493,6 +495,7 @@ static void ide_init_packet_cmd(struct ide_cmd *cmd, u32 tf_flags,
        cmd->protocol  = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO;
        cmd->tf_flags |= IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM |
                         IDE_TFLAG_OUT_FEATURE | tf_flags;
+       cmd->tf.command = ATA_CMD_PACKET;
        cmd->tf.feature = dma;          /* Use PIO/DMA */
        cmd->tf.lbam    = bcount & 0xff;
        cmd->tf.lbah    = (bcount >> 8) & 0xff;
@@ -610,6 +613,10 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
                                             : ide_pc_intr),
                        timeout);
 
+       /* Send the actual packet */
+       if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
+               hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
+
        /* Begin DMA, if necessary */
        if (dev_is_idecd(drive)) {
                if (drive->dma)
@@ -621,10 +628,6 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
                }
        }
 
-       /* Send the actual packet */
-       if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
-               hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
-
        return ide_started;
 }
 
@@ -638,6 +641,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
        unsigned int timeout;
        u32 tf_flags;
        u16 bcount;
+       u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT);
 
        if (dev_is_idecd(drive)) {
                tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
@@ -687,17 +691,14 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
 
        (void)do_rw_taskfile(drive, cmd);
 
-       /* Issue the packet command */
-       if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
+       if (drq_int) {
                if (drive->dma)
                        drive->waiting_for_dma = 0;
                hwif->expiry = expiry;
-               ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,
-                                   timeout);
-               return ide_started;
-       } else {
-               ide_execute_pkt_cmd(drive);
-               return ide_transfer_pc(drive);
        }
+
+       ide_execute_command(drive, cmd, ide_transfer_pc, timeout);
+
+       return drq_int ? ide_started : ide_transfer_pc(drive);
 }
 EXPORT_SYMBOL_GPL(ide_issue_pc);