]> 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 75df05add1b961cef95d4b7e960e44296821926a..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
@@ -483,7 +485,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
                  rq->cmd[0], bcount);
 next_irq:
        /* And set the interrupt handler again */
-       ide_set_handler(drive, ide_pc_intr, timeout, NULL);
+       ide_set_handler(drive, ide_pc_intr, timeout);
        return ide_started;
 }
 
@@ -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;
@@ -602,11 +605,17 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
                }
        }
 
+       hwif->expiry = expiry;
+
        /* Set the interrupt routine */
        ide_set_handler(drive,
                        (dev_is_idecd(drive) ? drive->irq_handler
                                             : ide_pc_intr),
-                       timeout, expiry);
+                       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)) {
@@ -619,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;
 }
 
@@ -636,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;
@@ -685,16 +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;
-               ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,
-                                   timeout, expiry);
-               return ide_started;
-       } else {
-               ide_execute_pkt_cmd(drive);
-               return ide_transfer_pc(drive);
+               hwif->expiry = expiry;
        }
+
+       ide_execute_command(drive, cmd, ide_transfer_pc, timeout);
+
+       return drq_int ? ide_started : ide_transfer_pc(drive);
 }
 EXPORT_SYMBOL_GPL(ide_issue_pc);