浏览代码

ide: use ata_tf_protocols enums

* Add IDE_TFLAG_MULTI_PIO taskfile flag and set it for commands
  using multi-PIO protocol.

* Use ata_tf_protocols enums instead of TASKFILE_* defines to
  denote command's protocol and then rename ->data_phase field
  to ->protocol.

* Remove no longer needed <linux/hdreg.h> includes.

There should be no functional changes caused by this patch.

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Bartlomiej Zolnierkiewicz 16 年之前
父节点
当前提交
0dfb991c69

+ 13 - 21
drivers/ide/ide-disk.c

@@ -28,7 +28,6 @@
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 #include <linux/leds.h>
 #include <linux/leds.h>
 #include <linux/ide.h>
 #include <linux/ide.h>
-#include <linux/hdreg.h>
 
 
 #include <asm/byteorder.h>
 #include <asm/byteorder.h>
 #include <asm/irq.h>
 #include <asm/irq.h>
@@ -53,15 +52,6 @@ static const u8 ide_rw_cmds[] = {
 	ATA_CMD_WRITE_EXT,
 	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)
 static void ide_tf_set_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 dma)
 {
 {
 	u8 index, lba48, write;
 	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;
 	lba48 = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0;
 	write = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;
 	write = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;
 
 
-	if (dma)
+	if (dma) {
+		cmd->protocol = ATA_PROT_DMA;
 		index = 8;
 		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];
 	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;
 		cmd->tf.command = ATA_CMD_FLUSH_EXT;
 	else
 	else
 		cmd->tf.command = ATA_CMD_FLUSH;
 		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_type = REQ_TYPE_ATA_TASKFILE;
 	rq->cmd_flags |= REQ_SOFTBARRIER;
 	rq->cmd_flags |= REQ_SOFTBARRIER;

+ 2 - 3
drivers/ide/ide-disk_proc.c

@@ -1,6 +1,5 @@
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/ide.h>
 #include <linux/ide.h>
-#include <linux/hdreg.h>
 
 
 #include "ide-disk.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->lbam    = ATA_SMART_LBAM_PASS;
 	tf->lbah    = ATA_SMART_LBAH_PASS;
 	tf->lbah    = ATA_SMART_LBAH_PASS;
 	tf->command = ATA_CMD_SMART;
 	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);
 	return ide_raw_taskfile(drive, &cmd, buf, 1);
 }
 }

+ 2 - 9
drivers/ide/ide-io.c

@@ -40,7 +40,6 @@
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
 #include <linux/ide.h>
-#include <linux/hdreg.h>
 #include <linux/completion.h>
 #include <linux/completion.h>
 #include <linux/reboot.h>
 #include <linux/reboot.h>
 #include <linux/cdrom.h>
 #include <linux/cdrom.h>
@@ -220,7 +219,7 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive)
 	struct ide_cmd cmd;
 	struct ide_cmd cmd;
 
 
 	memset(&cmd, 0, sizeof(cmd));
 	memset(&cmd, 0, sizeof(cmd));
-	cmd.data_phase = TASKFILE_NO_DATA;
+	cmd.protocol = ATA_PROT_NODATA;
 
 
 	if (s->b.set_geometry) {
 	if (s->b.set_geometry) {
 		s->b.set_geometry = 0;
 		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;
 	struct ide_cmd *cmd = rq->special;
 
 
 	if (cmd) {
 	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_init_sg_cmd(cmd, rq->nr_sectors);
 			ide_map_sg(drive, rq);
 			ide_map_sg(drive, rq);
-		default:
-			break;
 		}
 		}
 
 
 		return do_rw_taskfile(drive, cmd);
 		return do_rw_taskfile(drive, cmd);

+ 1 - 1
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;
 			       IDE_TFLAG_IN_NSECT;
 	}
 	}
 	tf->command = args[0];
 	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]) {
 	if (args[3]) {
 		cmd.tf_flags |= IDE_TFLAG_IO_16BIT;
 		cmd.tf_flags |= IDE_TFLAG_IO_16BIT;

+ 2 - 2
drivers/ide/ide-park.c

@@ -1,6 +1,5 @@
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/ide.h>
 #include <linux/ide.h>
-#include <linux/hdreg.h>
 #include <linux/jiffies.h>
 #include <linux/jiffies.h>
 #include <linux/blkdev.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;
 		tf->command = ATA_CMD_CHK_POWER;
 
 
 	cmd.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
 	cmd.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+	cmd.protocol = ATA_PROT_NODATA;
+
 	cmd.rq = rq;
 	cmd.rq = rq;
-	cmd.data_phase = TASKFILE_NO_DATA;
 
 
 	return do_rw_taskfile(drive, &cmd);
 	return do_rw_taskfile(drive, &cmd);
 }
 }

+ 2 - 3
drivers/ide/ide-pm.c

@@ -1,6 +1,5 @@
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/ide.h>
 #include <linux/ide.h>
-#include <linux/hdreg.h>
 
 
 int generic_ide_suspend(struct device *dev, pm_message_t mesg)
 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;
 	return ide_stopped;
 
 
 out_do_tf:
 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);
 	return do_rw_taskfile(drive, cmd);
 }
 }

+ 34 - 49
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;
 		cmd.tf.command = ATA_CMD_ID_ATA;
 	else
 	else
 		cmd.tf.command = ATA_CMD_ID_ATAPI;
 		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);
 	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_tp_ops *tp_ops = hwif->tp_ops;
 	const struct ide_dma_ops *dma_ops = hwif->dma_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)
 	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);
 		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;
 		handler = task_in_intr;
 		/* fall-through */
 		/* fall-through */
-	case TASKFILE_NO_DATA:
+	case ATA_PROT_NODATA:
 		if (handler == NULL)
 		if (handler == NULL)
 			handler = task_no_data_intr;
 			handler = task_no_data_intr;
 		ide_execute_command(drive, tf->command, handler,
 		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);
 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)
 static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
 {
 {
 	ide_hwif_t *hwif = drive->hwif;
 	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();
 	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);
 		ide_pio_multi(drive, cmd, write);
-		break;
-	default:
+	else
 		ide_pio_sector(drive, cmd, write);
 		ide_pio_sector(drive, cmd, write);
-		break;
-	}
 
 
 	drive->io_32bit = saved_io_32bit;
 	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) {
 	if (cmd->tf_flags & IDE_TFLAG_FS) {
 		int sectors = cmd->nsect - cmd->nleft;
 		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)
 		if (sectors > 0)
@@ -425,7 +404,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive,
 			  drive->bad_wstat, WAIT_DRQ)) {
 			  drive->bad_wstat, WAIT_DRQ)) {
 		printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
 		printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
 			drive->name,
 			drive->name,
-			cmd->data_phase == TASKFILE_MULTI_OUT ? "MULT" : "",
+			(cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "",
 			(drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
 			(drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
 		return startstop;
 		return startstop;
 	}
 	}
@@ -474,7 +453,7 @@ EXPORT_SYMBOL(ide_raw_taskfile);
 
 
 int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd)
 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);
 	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,
 	memcpy(&cmd.tf_array[6], req_task->io_ports,
 	       HDIO_DRIVE_TASK_HDR_SIZE);
 	       HDIO_DRIVE_TASK_HDR_SIZE);
 
 
-	cmd.data_phase = req_task->data_phase;
 	cmd.tf_flags   = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
 	cmd.tf_flags   = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
 			 IDE_TFLAG_IN_TF;
 			 IDE_TFLAG_IN_TF;
 
 
@@ -590,10 +568,12 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
 		/* fixup data phase if needed */
 		/* fixup data phase if needed */
 		if (req_task->data_phase == TASKFILE_IN_DMAQ ||
 		if (req_task->data_phase == TASKFILE_IN_DMAQ ||
 		    req_task->data_phase == TASKFILE_IN_DMA)
 		    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:
 		case TASKFILE_MULTI_OUT:
 			if (!drive->mult_count) {
 			if (!drive->mult_count) {
 				/* (hs): give up if multcount is not set */
 				/* (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;
 				err = -EPERM;
 				goto abort;
 				goto abort;
 			}
 			}
+			cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
 			/* fall through */
 			/* fall through */
 		case TASKFILE_OUT:
 		case TASKFILE_OUT:
+			cmd.protocol = ATA_PROT_PIO;
 			/* fall through */
 			/* fall through */
 		case TASKFILE_OUT_DMAQ:
 		case TASKFILE_OUT_DMAQ:
 		case TASKFILE_OUT_DMA:
 		case TASKFILE_OUT_DMA:
@@ -621,8 +603,10 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
 				err = -EPERM;
 				err = -EPERM;
 				goto abort;
 				goto abort;
 			}
 			}
+			cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
 			/* fall through */
 			/* fall through */
 		case TASKFILE_IN:
 		case TASKFILE_IN:
+			cmd.protocol = ATA_PROT_PIO;
 			/* fall through */
 			/* fall through */
 		case TASKFILE_IN_DMAQ:
 		case TASKFILE_IN_DMAQ:
 		case TASKFILE_IN_DMA:
 		case TASKFILE_IN_DMA:
@@ -630,6 +614,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
 			data_buf = inbuf;
 			data_buf = inbuf;
 			break;
 			break;
 		case TASKFILE_NO_DATA:
 		case TASKFILE_NO_DATA:
+			cmd.protocol = ATA_PROT_NODATA;
 			break;
 			break;
 		default:
 		default:
 			err = -EFAULT;
 			err = -EFAULT;

+ 2 - 1
include/linux/ide.h

@@ -298,6 +298,7 @@ enum {
 	/* struct ide_cmd was allocated using kmalloc() */
 	/* struct ide_cmd was allocated using kmalloc() */
 	IDE_TFLAG_DYN			= (1 << 27),
 	IDE_TFLAG_DYN			= (1 << 27),
 	IDE_TFLAG_FS			= (1 << 28),
 	IDE_TFLAG_FS			= (1 << 28),
+	IDE_TFLAG_MULTI_PIO		= (1 << 29),
 };
 };
 
 
 enum {
 enum {
@@ -343,7 +344,7 @@ struct ide_cmd {
 	};
 	};
 	u8			ftf_flags;	/* for TASKFILE ioctl */
 	u8			ftf_flags;	/* for TASKFILE ioctl */
 	u32			tf_flags;
 	u32			tf_flags;
-	int			data_phase;
+	int			protocol;
 
 
 	int			sg_nents;	  /* number of sg entries */
 	int			sg_nents;	  /* number of sg entries */
 	int			orig_sg_nents;
 	int			orig_sg_nents;