diff options
-rw-r--r-- | drivers/ide/ide-disk.c | 34 | ||||
-rw-r--r-- | drivers/ide/ide-disk_proc.c | 5 | ||||
-rw-r--r-- | drivers/ide/ide-io.c | 11 | ||||
-rw-r--r-- | drivers/ide/ide-ioctls.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-park.c | 4 | ||||
-rw-r--r-- | drivers/ide/ide-pm.c | 5 | ||||
-rw-r--r-- | drivers/ide/ide-taskfile.c | 83 | ||||
-rw-r--r-- | include/linux/ide.h | 3 |
8 files changed, 58 insertions, 89 deletions
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index d00d807c0f5..dae9d988de1 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -28,7 +28,6 @@ #include <linux/mutex.h> #include <linux/leds.h> #include <linux/ide.h> -#include <linux/hdreg.h> #include <asm/byteorder.h> #include <asm/irq.h> @@ -53,15 +52,6 @@ static const u8 ide_rw_cmds[] = { ATA_CMD_WRITE_EXT, }; -static const u8 ide_data_phases[] = { - TASKFILE_MULTI_IN, - TASKFILE_MULTI_OUT, - TASKFILE_IN, - TASKFILE_OUT, - TASKFILE_IN_DMA, - TASKFILE_OUT_DMA, -}; - static void ide_tf_set_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 dma) { u8 index, lba48, write; @@ -69,17 +59,19 @@ static void ide_tf_set_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 dma) lba48 = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0; write = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0; - if (dma) + if (dma) { + cmd->protocol = ATA_PROT_DMA; index = 8; - else - index = drive->mult_count ? 0 : 4; + } else { + cmd->protocol = ATA_PROT_PIO; + if (drive->mult_count) { + cmd->tf_flags |= IDE_TFLAG_MULTI_PIO; + index = 0; + } else + index = 4; + } cmd->tf.command = ide_rw_cmds[index + lba48 + write]; - - if (dma) - index = 8; /* fixup index */ - - cmd->data_phase = ide_data_phases[index / 2 + write]; } /* @@ -401,9 +393,9 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq) cmd->tf.command = ATA_CMD_FLUSH_EXT; else cmd->tf.command = ATA_CMD_FLUSH; - cmd->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | - IDE_TFLAG_DYN; - cmd->data_phase = TASKFILE_NO_DATA; + cmd->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE | + IDE_TFLAG_DYN; + cmd->protocol = ATA_PROT_NODATA; rq->cmd_type = REQ_TYPE_ATA_TASKFILE; rq->cmd_flags |= REQ_SOFTBARRIER; diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c index afe4f47e9e1..eaea3bef207 100644 --- a/drivers/ide/ide-disk_proc.c +++ b/drivers/ide/ide-disk_proc.c @@ -1,6 +1,5 @@ #include <linux/kernel.h> #include <linux/ide.h> -#include <linux/hdreg.h> #include "ide-disk.h" @@ -30,8 +29,8 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd) tf->lbam = ATA_SMART_LBAM_PASS; tf->lbah = ATA_SMART_LBAH_PASS; tf->command = ATA_CMD_SMART; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - cmd.data_phase = TASKFILE_IN; + cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + cmd.protocol = ATA_PROT_PIO; return ide_raw_taskfile(drive, &cmd, buf, 1); } diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 7917fa09bf1..c27eaab1ffc 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -40,7 +40,6 @@ #include <linux/pci.h> #include <linux/delay.h> #include <linux/ide.h> -#include <linux/hdreg.h> #include <linux/completion.h> #include <linux/reboot.h> #include <linux/cdrom.h> @@ -220,7 +219,7 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive) struct ide_cmd cmd; memset(&cmd, 0, sizeof(cmd)); - cmd.data_phase = TASKFILE_NO_DATA; + cmd.protocol = ATA_PROT_NODATA; if (s->b.set_geometry) { s->b.set_geometry = 0; @@ -314,15 +313,9 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct ide_cmd *cmd = rq->special; if (cmd) { - switch (cmd->data_phase) { - case TASKFILE_MULTI_OUT: - case TASKFILE_OUT: - case TASKFILE_MULTI_IN: - case TASKFILE_IN: + if (cmd->protocol == ATA_PROT_PIO) { ide_init_sg_cmd(cmd, rq->nr_sectors); ide_map_sg(drive, rq); - default: - break; } return do_rw_taskfile(drive, cmd); diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index 4953028a13d..77014276743 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c @@ -148,7 +148,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) IDE_TFLAG_IN_NSECT; } tf->command = args[0]; - cmd.data_phase = args[3] ? TASKFILE_IN : TASKFILE_NO_DATA; + cmd.protocol = args[3] ? ATA_PROT_PIO : ATA_PROT_NODATA; if (args[3]) { cmd.tf_flags |= IDE_TFLAG_IO_16BIT; diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c index 63c77f99a72..c575900d559 100644 --- a/drivers/ide/ide-park.c +++ b/drivers/ide/ide-park.c @@ -1,6 +1,5 @@ #include <linux/kernel.h> #include <linux/ide.h> -#include <linux/hdreg.h> #include <linux/jiffies.h> #include <linux/blkdev.h> @@ -80,8 +79,9 @@ ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq) tf->command = ATA_CMD_CHK_POWER; cmd.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + cmd.protocol = ATA_PROT_NODATA; + cmd.rq = rq; - cmd.data_phase = TASKFILE_NO_DATA; return do_rw_taskfile(drive, &cmd); } diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c index 5c9fc20f95b..ebf2d21ebdc 100644 --- a/drivers/ide/ide-pm.c +++ b/drivers/ide/ide-pm.c @@ -1,6 +1,5 @@ #include <linux/kernel.h> #include <linux/ide.h> -#include <linux/hdreg.h> int generic_ide_suspend(struct device *dev, pm_message_t mesg) { @@ -164,8 +163,8 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) return ide_stopped; out_do_tf: - cmd->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - cmd->data_phase = TASKFILE_NO_DATA; + cmd->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + cmd->protocol = ATA_PROT_NODATA; return do_rw_taskfile(drive, cmd); } diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 647216c772d..0c9d7148572 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -47,8 +47,8 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) cmd.tf.command = ATA_CMD_ID_ATA; else cmd.tf.command = ATA_CMD_ID_ATAPI; - cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - cmd.data_phase = TASKFILE_IN; + cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; + cmd.protocol = ATA_PROT_PIO; return ide_raw_taskfile(drive, &cmd, buf, 1); } @@ -66,13 +66,11 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd) const struct ide_tp_ops *tp_ops = hwif->tp_ops; const struct ide_dma_ops *dma_ops = hwif->dma_ops; - if (orig_cmd->data_phase == TASKFILE_MULTI_IN || - orig_cmd->data_phase == TASKFILE_MULTI_OUT) { - if (!drive->mult_count) { - printk(KERN_ERR "%s: multimode not set!\n", - drive->name); - return ide_stopped; - } + if (orig_cmd->protocol == ATA_PROT_PIO && + (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) && + drive->mult_count == 0) { + printk(KERN_ERR "%s: multimode not set!\n", drive->name); + return ide_stopped; } if (orig_cmd->ftf_flags & IDE_FTFLAG_FLAGGED) @@ -87,17 +85,16 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd) tp_ops->tf_load(drive, cmd); } - switch (cmd->data_phase) { - case TASKFILE_MULTI_OUT: - case TASKFILE_OUT: - tp_ops->exec_command(hwif, tf->command); - ndelay(400); /* FIXME */ - return pre_task_out_intr(drive, cmd); - case TASKFILE_MULTI_IN: - case TASKFILE_IN: + switch (cmd->protocol) { + case ATA_PROT_PIO: + if (cmd->tf_flags & IDE_TFLAG_WRITE) { + tp_ops->exec_command(hwif, tf->command); + ndelay(400); /* FIXME */ + return pre_task_out_intr(drive, cmd); + } handler = task_in_intr; /* fall-through */ - case TASKFILE_NO_DATA: + case ATA_PROT_NODATA: if (handler == NULL) handler = task_no_data_intr; ide_execute_command(drive, tf->command, handler, @@ -115,9 +112,6 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd) } EXPORT_SYMBOL_GPL(do_rw_taskfile); -/* - * Handler for commands without a data phase - */ static ide_startstop_t task_no_data_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; @@ -278,15 +272,10 @@ static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd, touch_softlockup_watchdog(); - switch (cmd->data_phase) { - case TASKFILE_MULTI_IN: - case TASKFILE_MULTI_OUT: + if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ide_pio_multi(drive, cmd, write); - break; - default: + else ide_pio_sector(drive, cmd, write); - break; - } drive->io_32bit = saved_io_32bit; } @@ -297,22 +286,12 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct ide_cmd *cmd, if (cmd->tf_flags & IDE_TFLAG_FS) { int sectors = cmd->nsect - cmd->nleft; - switch (cmd->data_phase) { - case TASKFILE_IN: - if (cmd->nleft) - break; - /* fall through */ - case TASKFILE_OUT: - sectors--; - break; - case TASKFILE_MULTI_IN: - if (cmd->nleft) - break; - /* fall through */ - case TASKFILE_MULTI_OUT: - sectors -= drive->mult_count; - default: - break; + if (cmd->protocol == ATA_PROT_PIO && + ((cmd->tf_flags & IDE_TFLAG_WRITE) || cmd->nleft == 0)) { + if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) + sectors -= drive->mult_count; + else + sectors--; } if (sectors > 0) @@ -425,7 +404,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, drive->bad_wstat, WAIT_DRQ)) { printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n", drive->name, - cmd->data_phase == TASKFILE_MULTI_OUT ? "MULT" : "", + (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "", (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : ""); return startstop; } @@ -474,7 +453,7 @@ EXPORT_SYMBOL(ide_raw_taskfile); int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd) { - cmd->data_phase = TASKFILE_NO_DATA; + cmd->protocol = ATA_PROT_NODATA; return ide_raw_taskfile(drive, cmd, NULL, 0); } @@ -545,7 +524,6 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) memcpy(&cmd.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE); - cmd.data_phase = req_task->data_phase; cmd.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE | IDE_TFLAG_IN_TF; @@ -590,10 +568,12 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) /* fixup data phase if needed */ if (req_task->data_phase == TASKFILE_IN_DMAQ || req_task->data_phase == TASKFILE_IN_DMA) - cmd.data_phase = TASKFILE_OUT_DMA; + cmd.tf_flags |= IDE_TFLAG_WRITE; } - switch (cmd.data_phase) { + cmd.protocol = ATA_PROT_DMA; + + switch (req_task->data_phase) { case TASKFILE_MULTI_OUT: if (!drive->mult_count) { /* (hs): give up if multcount is not set */ @@ -603,8 +583,10 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) err = -EPERM; goto abort; } + cmd.tf_flags |= IDE_TFLAG_MULTI_PIO; /* fall through */ case TASKFILE_OUT: + cmd.protocol = ATA_PROT_PIO; /* fall through */ case TASKFILE_OUT_DMAQ: case TASKFILE_OUT_DMA: @@ -621,8 +603,10 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) err = -EPERM; goto abort; } + cmd.tf_flags |= IDE_TFLAG_MULTI_PIO; /* fall through */ case TASKFILE_IN: + cmd.protocol = ATA_PROT_PIO; /* fall through */ case TASKFILE_IN_DMAQ: case TASKFILE_IN_DMA: @@ -630,6 +614,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg) data_buf = inbuf; break; case TASKFILE_NO_DATA: + cmd.protocol = ATA_PROT_NODATA; break; default: err = -EFAULT; diff --git a/include/linux/ide.h b/include/linux/ide.h index 02128e9241d..f9decc9852e 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -298,6 +298,7 @@ enum { /* struct ide_cmd was allocated using kmalloc() */ IDE_TFLAG_DYN = (1 << 27), IDE_TFLAG_FS = (1 << 28), + IDE_TFLAG_MULTI_PIO = (1 << 29), }; enum { @@ -343,7 +344,7 @@ struct ide_cmd { }; u8 ftf_flags; /* for TASKFILE ioctl */ u32 tf_flags; - int data_phase; + int protocol; int sg_nents; /* number of sg entries */ int orig_sg_nents; |