linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup
@ 2005-03-05  1:47 Tejun Heo
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 01/08] ide: add individual ATA_TFLAG_{OUT|IN}_* flags Tejun Heo
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: Tejun Heo @ 2005-03-05  1:47 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, lkml, linux-ide, Jeff Garzik


 Hello, Bartlomiej.
 Hello, Jeff.

 These eight patches

 * define ATA_TFLAG_{OUT|IN}_* flags
 * unify/generalize taskfile transport
 * cleanup ide driver accordingly

 For behavior changes by #03.  I don't think defining a special flag
to handle the TASKFILE case is necessary.  The change isn't
user-visible.  And for the TASK ioctl, I think we should modify all
ioctls to disallow changing the upper nibble of the DEVICE register
except for the LBA bit.  What do you think?

 I tried hard not to break things and tested changes but I'm pretty
sure that I've missed something.  So, please comment.  :-)

[ Start of patch descriptions ]

01_ide_TFLAG_OUT_IN.patch
	: add individual ATA_TFLAG_{OUT|IN}_* flags

	This patch replaces ide_task_t->tf_{out|in}_flags handling
	with newly defined individual ATA_TFLAG_{OUT|IN}_* flags and
	helper functions ide_{load|read}_taskfile().  To ease
	transition of the IDE code, temporary flags
	ATA_TFLAG_IDE_FLAGGED and ATA_TFLAG_IDE_LBA48 are defined.
	This patch is tit-for-tat and shouldn't change any behavior.

02_ide_use_load_taskfile_in_do_rw_disk.patch
	: convert __ide_do_rw_disk() to use ide_load_taskfile()

	Reimplements __ide_do_rw_disk() using ide_load_taskfile().
	While at it, clean up the function a little bit.

03_ide_remove_flagged_taskfile.patch
	: remove flagged_taskfile() and unify taskfile paths

	This patch removes flagged_taskfile().  All taskfile command
	issuing goes through do_rw_taskfile().  do_rw_taskfile()
	doesn't modify mangle with load flags anymore.  It's now
	caller's responsibility to set appropriate flags.  Likewise,
	ide_end_drive_cmd() is modified not to mangle with read flags,
	and ide_dma_intr() now also finishes commands with
	task_end_request().  Above changes make taskfile path unified
	& generic.

	As all ioctl subtleties are now responsibility of respective
	ioctl functions.  TASKFILE and TASK ioctl functions are
	updated to set flags according to old behaviors.  The
	following two behavior changes occur.

	* TASKFILE ioctl: taskfile registers are read back whether or
	  not the command fails.  As copying back to user doesn't
	  happen in cases where reading back didn't occur before, this
	  change isn't user-visible.  Defining & using a flag like
	  ATA_TFLAG_READ_ON_ERROR will remove this issue.
	* TASK ioctl: drive->select.all & ~ATA_LBA is OR'd to device
	  value.  Previously, only ATA_DEV bit was OR'd.

	Also, all ide_{raw|diag}_taskfile(), do_rw_taskfile() users
	are converted to use the new individual OUT/IN flags.  As
	results, the following behavior changes occur.

	* idedisk_read_native_max_address(): ADDR/LBA48 regs are not
	  loaded.  LBA48/DEVICE registers are not read back unless
	  necessary.
	* idedisk_set_max_address(): DEVICE register is not read
	  unless necessary.
	* smart_enable(): DEVICE register is not loaded.  Registers
	  are not read back.
	* smart_disable(): ditto
	* get_smart_threshold(): DEVICE register is not loaded.
	* ide_task_init_flush(): ADDR/LBA48/DEVICE registers are not
	  loaded.
	* ide_init_specify_cmd(): Register aren't read back.
	* ide_init_restore_cmd(): DEVICE register not loaded.  No read back.
	* ide_init_setmult_cmd(): ditto

04_ide_remove_unused_fields.patch
	: remove unused fields ide_drive_t->rq and ide_task_t->special

	Remove unused fields ide_drive_t->rq and ide_task_t->special

05_ide_use_protocol.patch
	: use ide_task_t->tf.protocol instead of ide_task_t->data_phase

	Remove ide_task_t->{data_phase,command_type,prehandler,rq} and
	use tf->protocol instead.  Now the protocol value wholey
	defines how to drive a taskfile except for NODATA cases where
	a caller can optionally specify handler (for special
	commands).  The following behavior changes occur.

	* ide_taskfile_ioctl(): req_task->command_type is ignored.
	  This doesn't make any difference except for error/crash
	  cases in the original code.

06_ide_taskfile_set_xfer_rate.patch
	: convert set_xfer_rate() to use taskfile ioctl

	Convert set_xfer_rate() to use taskfile ioctl.

07_ide_taskfile_cmd_ioctl.patch
	: reimplement ide_cmd_ioctl() using taskfile

	Reimplement ide_cmd_ioctl() using taskfile.

08_ide_remove_REQ_DRIVE_CMD.patch
	: remove REQ_DRIVE_CMD handling

	Remove REQ_DRIVE_CMD handling.  ide_init_drive_cmd() now
	defaults to REQ_DRIVE_TASKFILE (now the only drive command :-).

[ End of patch descriptions ]

 Thanks.

--
tejun

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2.6.11-rc3 01/08] ide: add individual ATA_TFLAG_{OUT|IN}_* flags
  2005-03-05  1:47 [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup Tejun Heo
@ 2005-03-05  1:48 ` Tejun Heo
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 02/08] ide: convert __ide_do_rw_disk() to use ide_load_taskfile() Tejun Heo
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Tejun Heo @ 2005-03-05  1:48 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, lkml, linux-ide, Jeff Garzik


01_ide_TFLAG_OUT_IN.patch

	This patch replaces ide_task_t->tf_{out|in}_flags handling
	with newly defined individual ATA_TFLAG_{OUT|IN}_* flags and
	helper functions ide_{load|read}_taskfile().  To ease
	transition of the IDE code, temporary flags
	ATA_TFLAG_IDE_FLAGGED and ATA_TFLAG_IDE_LBA48 are defined.
	This patch is tit-for-tat and shouldn't change any behavior.

Signed-off-by: Tejun Heo <htejun@gmail.com>

 drivers/ide/ide-disk.c     |    4 
 drivers/ide/ide-io.c       |   35 +------
 drivers/ide/ide-taskfile.c |  220 +++++++++++++++++++++++++++------------------
 include/linux/ata.h        |   66 ++++++++++++-
 include/linux/ide.h        |   10 +-
 5 files changed, 213 insertions(+), 122 deletions(-)

Index: linux-taskfile-ng/drivers/ide/ide-disk.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-disk.c	2005-03-05 10:37:51.738348597 +0900
+++ linux-taskfile-ng/drivers/ide/ide-disk.c	2005-03-05 10:46:58.305078940 +0900
@@ -337,7 +337,7 @@ static u64 idedisk_read_native_max_addre
 	tf->device	= 0x40;
 	if (lba48) {
 		tf->command = WIN_READ_NATIVE_MAX_EXT;
-		tf->flags |= ATA_TFLAG_LBA48;
+		tf->flags |= ATA_TFLAG_IDE_LBA48;
 	} else
 		tf->command = WIN_READ_NATIVE_MAX;
 
@@ -379,7 +379,7 @@ static u64 idedisk_set_max_address(ide_d
 		tf->device	= 0x40;
 		tf->command	= WIN_SET_MAX_EXT;
 
-		tf->flags |= ATA_TFLAG_LBA48;
+		tf->flags |= ATA_TFLAG_IDE_LBA48;
 	} else {
 		tf->device	= ((addr_req >> 24) & 0xf) | 0x40;
 		tf->command	= WIN_SET_MAX;
Index: linux-taskfile-ng/drivers/ide/ide-io.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-io.c	2005-03-05 10:37:51.738348597 +0900
+++ linux-taskfile-ng/drivers/ide/ide-io.c	2005-03-05 10:46:58.307078627 +0900
@@ -64,7 +64,7 @@ void ide_task_init_flush(ide_drive_t *dr
 	if (ide_id_has_flush_cache_ext(drive->id) &&
 	    (drive->capacity64 >= (1UL << 28))) {
 		tf->command = WIN_FLUSH_CACHE_EXT;
-		tf->flags |= ATA_TFLAG_LBA48;
+		tf->flags |= ATA_TFLAG_IDE_LBA48;
 	} else
 		tf->command = WIN_FLUSH_CACHE;
 
@@ -322,7 +322,7 @@ u64 ide_tf_get_address(ide_drive_t *driv
 {
 	u32 high, low;
 
-	if (tf->flags & ATA_TFLAG_LBA48) {
+	if (tf->flags & ATA_TFLAG_IDE_LBA48) {
 		high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) | tf->hob_lbal;
 		low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal;
 	} else {
@@ -458,31 +458,10 @@ void ide_end_drive_cmd (ide_drive_t *dri
 			
 		if (args) {
 			struct ata_taskfile *tf = &args->tf;
-
-			if (args->tf_in_flags.b.data)
-				args->data = hwif->INW(IDE_DATA_REG);
-
-			tf->feature	= err;
-
-			/* be sure we're looking at the low order bits */
-			hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG);
-
-			tf->nsect	= hwif->INB(IDE_NSECTOR_REG);
-			tf->lbal	= hwif->INB(IDE_SECTOR_REG);
-			tf->lbam	= hwif->INB(IDE_LCYL_REG);
-			tf->lbah	= hwif->INB(IDE_HCYL_REG);
-			tf->device	= hwif->INB(IDE_SELECT_REG);
-			tf->command	= stat;
-
-			if (tf->flags & ATA_TFLAG_LBA48) {
-				hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
-
-				tf->hob_feature	= hwif->INB(IDE_FEATURE_REG);
-				tf->hob_nsect	= hwif->INB(IDE_NSECTOR_REG);
-				tf->hob_lbal	= hwif->INB(IDE_SECTOR_REG);
-				tf->hob_lbam	= hwif->INB(IDE_LCYL_REG);
-				tf->hob_lbah	= hwif->INB(IDE_HCYL_REG);
-			}
+			tf->flags |= ATA_TFLAG_IN_ADDR | ATA_TFLAG_IN_DEVICE;
+			if (tf->flags & ATA_TFLAG_IDE_LBA48)
+				tf->flags |= ATA_TFLAG_IN_LBA48;
+			ide_read_taskfile(drive, args, stat, err);
 		}
 	} else if (blk_pm_request(rq)) {
 #ifdef DEBUG_PM
@@ -935,7 +914,7 @@ static ide_startstop_t execute_drive_cmd
 			break;
 		}
 
-		if (args->tf_out_flags.all != 0) 
+		if (args->tf.flags & ATA_TFLAG_IDE_FLAGGED)
 			return flagged_taskfile(drive, args);
 		return do_rw_taskfile(drive, args);
 	} else if (rq->flags & REQ_DRIVE_CMD) {
Index: linux-taskfile-ng/drivers/ide/ide-taskfile.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-taskfile.c	2005-03-05 10:37:51.739348441 +0900
+++ linux-taskfile-ng/drivers/ide/ide-taskfile.c	2005-03-05 10:46:58.315077377 +0900
@@ -53,6 +53,92 @@
 
 #define DEBUG_TASKFILE	0	/* unset when fixed */
 
+void ide_load_taskfile(ide_drive_t *drive, ide_task_t *task)
+{
+	struct ata_taskfile *tf = &task->tf;
+	ide_hwif_t *hwif = drive->hwif;
+
+	/* The caller is responsible for supplying a valid device value. */
+	if (tf->flags & ATA_TFLAG_OUT_DEVICE)
+		hwif->OUTB(tf->device,	IDE_SELECT_REG);
+
+	/* Load HOB registers. */
+	if (tf->flags & ATA_TFLAG_OUT_HOB_FEATURE)
+		hwif->OUTB(tf->hob_feature,	IDE_FEATURE_REG);
+	if (tf->flags & ATA_TFLAG_OUT_HOB_NSECT)
+		hwif->OUTB(tf->hob_nsect,	IDE_NSECTOR_REG);
+	if (tf->flags & ATA_TFLAG_OUT_HOB_LBAL)
+		hwif->OUTB(tf->hob_lbal,	IDE_SECTOR_REG);
+	if (tf->flags & ATA_TFLAG_OUT_HOB_LBAM)
+		hwif->OUTB(tf->hob_lbam,	IDE_LCYL_REG);
+	if (tf->flags & ATA_TFLAG_OUT_HOB_LBAH)
+		hwif->OUTB(tf->hob_lbah,	IDE_HCYL_REG);
+
+	/* Now push HOBs upward by loading LOBs.  The caller is
+	   responsible for supplying matching LOB for each matching
+	   HOB; otherwise, HOB won't be pushed upward. */
+	if (tf->flags & ATA_TFLAG_OUT_FEATURE)
+		hwif->OUTB(tf->feature,		IDE_FEATURE_REG);
+	if (tf->flags & ATA_TFLAG_OUT_NSECT)
+		hwif->OUTB(tf->nsect,		IDE_NSECTOR_REG);
+	if (tf->flags & ATA_TFLAG_OUT_LBAL)
+		hwif->OUTB(tf->lbal,		IDE_SECTOR_REG);
+	if (tf->flags & ATA_TFLAG_OUT_LBAM)
+		hwif->OUTB(tf->lbam,		IDE_LCYL_REG);
+	if (tf->flags & ATA_TFLAG_OUT_LBAH)
+		hwif->OUTB(tf->lbah,		IDE_HCYL_REG);
+
+	/* Load data.  This is for the brain-damaged TASKFILE ioctl. */
+	if (task->load_data)
+		hwif->OUTW(task->data,		IDE_DATA_REG);
+}
+EXPORT_SYMBOL(ide_load_taskfile);
+
+void ide_read_taskfile(ide_drive_t *drive, ide_task_t *task, u8 stat, u8 err)
+{
+	struct ata_taskfile *tf = &task->tf;
+	ide_hwif_t *hwif = drive->hwif;
+
+	/* Read HOB registers first such that the HOB bit in the control
+	   register stays cleared when we leave this function. */
+	if (tf->flags & ATA_TFLAG_IN_LBA48) {
+		hwif->OUTB(drive->ctl | ATA_HOB, IDE_CONTROL_REG);
+
+		if (tf->flags & ATA_TFLAG_IN_HOB_FEATURE)
+			tf->hob_feature	= hwif->INB(IDE_FEATURE_REG);
+		if (tf->flags & ATA_TFLAG_IN_HOB_NSECT)
+			tf->hob_nsect	= hwif->INB(IDE_NSECTOR_REG);
+		if (tf->flags & ATA_TFLAG_IN_HOB_LBAL)
+			tf->hob_lbal	= hwif->INB(IDE_SECTOR_REG);
+		if (tf->flags & ATA_TFLAG_IN_HOB_LBAM)
+			tf->hob_lbam	= hwif->INB(IDE_LCYL_REG);
+		if (tf->flags & ATA_TFLAG_IN_HOB_LBAH)
+			tf->hob_lbah	= hwif->INB(IDE_HCYL_REG);
+
+		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
+	}
+
+	if (tf->flags & ATA_TFLAG_IN_FEATURE)
+		tf->feature	= err;
+	if (tf->flags & ATA_TFLAG_IN_NSECT)
+		tf->nsect	= hwif->INB(IDE_NSECTOR_REG);
+	if (tf->flags & ATA_TFLAG_IN_LBAL)
+		tf->lbal	= hwif->INB(IDE_SECTOR_REG);
+	if (tf->flags & ATA_TFLAG_IN_LBAM)
+		tf->lbam	= hwif->INB(IDE_LCYL_REG);
+	if (tf->flags & ATA_TFLAG_IN_LBAH)
+		tf->lbah	= hwif->INB(IDE_HCYL_REG);
+
+	if (tf->flags & ATA_TFLAG_IN_DEVICE)
+		tf->device	= hwif->INB(IDE_SELECT_REG);
+
+	tf->command = stat;
+
+	/* And, for the braindamaged TASKFILE ioctl. */
+	if (task->read_data)
+		task->data	= hwif->INW(IDE_DATA_REG);
+}
+
 static void ata_bswap_data (void *buffer, int wcount)
 {
 	u16 *p = buffer;
@@ -104,7 +190,7 @@ ide_startstop_t do_rw_taskfile (ide_driv
 {
 	ide_hwif_t *hwif	= HWIF(drive);
 	struct ata_taskfile *tf = &task->tf;
-	u8 HIHI			= (tf->flags & ATA_TFLAG_LBA48) ? 0xE0 : 0xEF;
+	u8 HIHI			= (tf->flags & ATA_TFLAG_IDE_LBA48) ? 0xE0 : 0xEF;
 
 	/* ALL Command Block Executions SHALL clear nIEN, unless otherwise */
 	if (IDE_CONTROL_REG) {
@@ -113,21 +199,13 @@ ide_startstop_t do_rw_taskfile (ide_driv
 	}
 	SELECT_MASK(drive, 0);
 
-	if (tf->flags & ATA_TFLAG_LBA48) {
-		hwif->OUTB(tf->hob_feature, IDE_FEATURE_REG);
-		hwif->OUTB(tf->hob_nsect, IDE_NSECTOR_REG);
-		hwif->OUTB(tf->hob_lbal, IDE_SECTOR_REG);
-		hwif->OUTB(tf->hob_lbam, IDE_LCYL_REG);
-		hwif->OUTB(tf->hob_lbah, IDE_HCYL_REG);
-	}
-
-	hwif->OUTB(tf->feature, IDE_FEATURE_REG);
-	hwif->OUTB(tf->nsect, IDE_NSECTOR_REG);
-	hwif->OUTB(tf->lbal, IDE_SECTOR_REG);
-	hwif->OUTB(tf->lbam, IDE_LCYL_REG);
-	hwif->OUTB(tf->lbah, IDE_HCYL_REG);
+	if (tf->flags & ATA_TFLAG_IDE_LBA48)
+		tf->flags |= ATA_TFLAG_OUT_LBA48;
+	tf->flags |= ATA_TFLAG_OUT_ADDR;
+	tf->flags |= ATA_TFLAG_OUT_DEVICE;
+	tf->device = (tf->device & HIHI) | (drive->select.all & 0xBF);
 
-	hwif->OUTB((tf->device & HIHI) | (drive->select.all & 0xBF), IDE_SELECT_REG);
+	ide_load_taskfile(drive, task);
 
 	if (task->handler != NULL) {
 		if (task->prehandler != NULL) {
@@ -383,7 +461,7 @@ static void task_end_request(ide_drive_t
 	if (rq->flags & REQ_DRIVE_TASKFILE) {
 		ide_task_t *task = rq->special;
 
-		if (task->tf_out_flags.all) {
+		if (task->tf.flags & ATA_TFLAG_IDE_FLAGGED) {
 			u8 err = drive->hwif->INB(IDE_ERROR_REG);
 			ide_end_drive_cmd(drive, stat, err);
 			return;
@@ -596,14 +674,46 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 	tf->device	= req_task->io_ports[6];
 	tf->command	= req_task->io_ports[7];
 
-	args.tf_in_flags  = req_task->in_flags;
-	args.tf_out_flags = req_task->out_flags;
+	/* Translate out/in flags. */
+	if (req_task->out_flags.all)
+		tf->flags |= ATA_TFLAG_IDE_FLAGGED;
+
+	if (req_task->out_flags.b.error_feature_hob)
+		tf->flags |= ATA_TFLAG_OUT_HOB_FEATURE;
+	if (req_task->out_flags.b.nsector_hob)
+		tf->flags |= ATA_TFLAG_OUT_HOB_NSECT;
+	if (req_task->out_flags.b.sector_hob)
+		tf->flags |= ATA_TFLAG_OUT_HOB_LBAL;
+	if (req_task->out_flags.b.lcyl_hob)
+		tf->flags |= ATA_TFLAG_OUT_HOB_LBAM;
+	if (req_task->out_flags.b.hcyl_hob)
+		tf->flags |= ATA_TFLAG_OUT_HOB_LBAH;
+
+	if (req_task->out_flags.b.error_feature)
+		tf->flags |= ATA_TFLAG_OUT_FEATURE;
+	if (req_task->out_flags.b.nsector)
+		tf->flags |= ATA_TFLAG_OUT_NSECT;
+	if (req_task->out_flags.b.sector)
+		tf->flags |= ATA_TFLAG_OUT_LBAL;
+	if (req_task->out_flags.b.lcyl)
+		tf->flags |= ATA_TFLAG_OUT_LBAM;
+	if (req_task->out_flags.b.hcyl)
+		tf->flags |= ATA_TFLAG_OUT_LBAH;
+
+	if (req_task->out_flags.b.select)
+		tf->flags |= ATA_TFLAG_OUT_DEVICE;
+	if (req_task->out_flags.b.data)
+		args.load_data = 1;
+
+	if (req_task->in_flags.b.data)
+		args.read_data = 1;
+
 	args.data_phase   = req_task->data_phase;
 	args.command_type = req_task->req_cmd;
 
-	tf->flags = ATA_TFLAG_IO_16BIT;
+	tf->flags |= ATA_TFLAG_IO_16BIT;
 	if (drive->addressing == 1)
-		tf->flags |= ATA_TFLAG_LBA48;
+		tf->flags |= ATA_TFLAG_IDE_LBA48;
 
 	if (drive->select.b.lba)
 		tf->device |= ATA_LBA;
@@ -672,9 +782,6 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 	req_task->io_ports[6] = tf->device;
 	req_task->io_ports[7] = tf->command;
 
-	req_task->in_flags  = args.tf_in_flags;
-	req_task->out_flags = args.tf_out_flags;
-
 	if (copy_to_user(buf, req_task, tasksize)) {
 		err = -EFAULT;
 		goto abort;
@@ -838,76 +945,19 @@ ide_startstop_t flagged_taskfile (ide_dr
 		}
 	}
 
-	/*
-	 * (ks) Check taskfile in/out flags.
-	 * If set, then execute as it is defined.
-	 * If not set, then define default settings.
-	 * The default values are:
-	 *	write and read all taskfile registers (except data) 
-	 *	write and read the hob registers (sector,nsector,lcyl,hcyl)
-	 */
-	if (task->tf_out_flags.all == 0) {
-		task->tf_out_flags.all = IDE_TASKFILE_STD_OUT_FLAGS;
-		if (drive->addressing == 1)
-			task->tf_out_flags.all |= (IDE_HOB_STD_OUT_FLAGS << 8);
-        }
-
-	if (task->tf_in_flags.all == 0) {
-		task->tf_in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
-		if (drive->addressing == 1)
-			task->tf_in_flags.all |= (IDE_HOB_STD_IN_FLAGS  << 8);
-        }
-
 	/* ALL Command Block Executions SHALL clear nIEN, unless otherwise */
 	if (IDE_CONTROL_REG)
 		/* clear nIEN */
 		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
 	SELECT_MASK(drive, 0);
 
-#if DEBUG_TASKFILE
-	status = hwif->INB(IDE_STATUS_REG);
-	if (status & 0x80) {
-		printk("flagged_taskfile -> Bad status. Status = %02x. wait 100 usec ...\n", status);
-		udelay(100);
-		status = hwif->INB(IDE_STATUS_REG);
-		printk("flagged_taskfile -> Status = %02x\n", status);
-	}
-#endif
+	/* Adjust task. */
+	tf->flags &= ~ATA_TFLAG_OUT_HOB_FEATURE;
+	tf->flags |= ATA_TFLAG_OUT_DEVICE;
+	tf->device |= drive->select.all & 0xBF;
 
-	if (task->tf_out_flags.b.data)
-		hwif->OUTW(task->data, IDE_DATA_REG);
+	ide_load_taskfile(drive, task);
 
-	/* (ks) send hob registers first */
-	if (task->tf_out_flags.b.nsector_hob)
-		hwif->OUTB(tf->hob_nsect, IDE_NSECTOR_REG);
-	if (task->tf_out_flags.b.sector_hob)
-		hwif->OUTB(tf->hob_lbal, IDE_SECTOR_REG);
-	if (task->tf_out_flags.b.lcyl_hob)
-		hwif->OUTB(tf->hob_lbam, IDE_LCYL_REG);
-	if (task->tf_out_flags.b.hcyl_hob)
-		hwif->OUTB(tf->hob_lbah, IDE_HCYL_REG);
-
-	/* (ks) Send now the standard registers */
-	if (task->tf_out_flags.b.error_feature)
-		hwif->OUTB(tf->feature, IDE_FEATURE_REG);
-	/* refers to number of sectors to transfer */
-	if (task->tf_out_flags.b.nsector)
-		hwif->OUTB(tf->nsect, IDE_NSECTOR_REG);
-	/* refers to sector offset or start sector */
-	if (task->tf_out_flags.b.sector)
-		hwif->OUTB(tf->lbal, IDE_SECTOR_REG);
-	if (task->tf_out_flags.b.lcyl)
-		hwif->OUTB(tf->lbam, IDE_LCYL_REG);
-	if (task->tf_out_flags.b.hcyl)
-		hwif->OUTB(tf->lbah, IDE_HCYL_REG);
-
-        /*
-	 * (ks) In the flagged taskfile approch, we will use all specified
-	 * registers and the register value will not be changed, except the
-	 * select bit (master/slave) in the drive_head register. We must make
-	 * sure that the desired drive is selected.
-	 */
-	hwif->OUTB(tf->device | (drive->select.all & 0xBF), IDE_SELECT_REG);
 	switch(task->data_phase) {
 
    	        case TASKFILE_OUT_DMAQ:
Index: linux-taskfile-ng/include/linux/ata.h
===================================================================
--- linux-taskfile-ng.orig/include/linux/ata.h	2005-03-05 10:37:51.739348441 +0900
+++ linux-taskfile-ng/include/linux/ata.h	2005-03-05 10:46:58.316077220 +0900
@@ -168,11 +168,67 @@ enum {
 	SCR_NOTIFICATION	= 4,
 
 	/* struct ata_taskfile flags */
-	ATA_TFLAG_LBA48		= (1 << 0), /* enable 48-bit LBA and "HOB" */
-	ATA_TFLAG_ISADDR	= (1 << 1), /* enable r/w to nsect/lba regs */
-	ATA_TFLAG_DEVICE	= (1 << 2), /* enable r/w to device reg */
-	ATA_TFLAG_WRITE		= (1 << 3), /* data dir: host->dev==1 (write) */
-	ATA_TFLAG_IO_16BIT	= (1 << 4), /* force 16bit pio */
+	ATA_TFLAG_OUT_FEATURE	= (1 <<  0),
+	ATA_TFLAG_OUT_NSECT	= (1 <<  1),
+	ATA_TFLAG_OUT_LBAL	= (1 <<  2),
+	ATA_TFLAG_OUT_LBAM	= (1 <<  3),
+	ATA_TFLAG_OUT_LBAH	= (1 <<  4),
+	ATA_TFLAG_OUT_HOB_FEATURE = (1 <<  5),
+	ATA_TFLAG_OUT_HOB_NSECT	= (1 <<  6),
+	ATA_TFLAG_OUT_HOB_LBAL	= (1 <<  7),
+	ATA_TFLAG_OUT_HOB_LBAM	= (1 <<  8),
+	ATA_TFLAG_OUT_HOB_LBAH	= (1 <<  9),
+	ATA_TFLAG_OUT_DEVICE	= (1 << 10),
+
+	ATA_TFLAG_IN_FEATURE	= (1 << 11),
+	ATA_TFLAG_IN_NSECT	= (1 << 12),
+	ATA_TFLAG_IN_LBAL	= (1 << 13),
+	ATA_TFLAG_IN_LBAM	= (1 << 14),
+	ATA_TFLAG_IN_LBAH	= (1 << 15),
+	ATA_TFLAG_IN_HOB_FEATURE = (1 << 16),
+	ATA_TFLAG_IN_HOB_NSECT	= (1 << 17),
+	ATA_TFLAG_IN_HOB_LBAL	= (1 << 18),
+	ATA_TFLAG_IN_HOB_LBAM	= (1 << 19),
+	ATA_TFLAG_IN_HOB_LBAH	= (1 << 20),
+	ATA_TFLAG_IN_DEVICE	= (1 << 21),
+
+	/* The following four aggreate flags are used by IDE to control
+	   register IO. */
+	ATA_TFLAG_OUT_LBA48	= (ATA_TFLAG_OUT_HOB_FEATURE	|
+				   ATA_TFLAG_OUT_HOB_NSECT	|
+				   ATA_TFLAG_OUT_HOB_LBAL	|
+				   ATA_TFLAG_OUT_HOB_LBAM	|
+				   ATA_TFLAG_OUT_HOB_LBAH	),
+	ATA_TFLAG_OUT_ADDR	= (ATA_TFLAG_OUT_FEATURE	|
+				   ATA_TFLAG_OUT_NSECT		|
+				   ATA_TFLAG_OUT_LBAL		|
+				   ATA_TFLAG_OUT_LBAM		|
+				   ATA_TFLAG_OUT_LBAH		),
+	ATA_TFLAG_IN_LBA48	= (ATA_TFLAG_IN_HOB_FEATURE	|
+				   ATA_TFLAG_IN_HOB_NSECT	|
+				   ATA_TFLAG_IN_HOB_LBAL	|
+				   ATA_TFLAG_IN_HOB_LBAM	|
+				   ATA_TFLAG_IN_HOB_LBAH	),
+	ATA_TFLAG_IN_ADDR	= (ATA_TFLAG_IN_FEATURE		|
+				   ATA_TFLAG_IN_NSECT		|
+				   ATA_TFLAG_IN_LBAL		|
+				   ATA_TFLAG_IN_LBAM		|
+				   ATA_TFLAG_IN_LBAH		),
+
+	/* These three aggregate flags are used by libata, as it doesn't
+	   really need to optimize register INs */
+	ATA_TFLAG_LBA48		= (ATA_TFLAG_OUT_LBA48  | ATA_TFLAG_IN_LBA48 ),
+	ATA_TFLAG_ISADDR	= (ATA_TFLAG_OUT_ADDR   | ATA_TFLAG_IN_ADDR  ),
+	ATA_TFLAG_DEVICE	= (ATA_TFLAG_OUT_DEVICE | ATA_TFLAG_IN_DEVICE),
+
+	ATA_TFLAG_WRITE		= (1 << 22), /* data dir */
+	ATA_TFLAG_IO_16BIT	= (1 << 23), /* force 16bit PIO (IDE) */
+
+	/* Following two flags are just to ease migration to the new
+	   taskfile implementation.  They will go away as soon as the
+	   transition is complete. */
+	ATA_TFLAG_IDE_FLAGGED	= (1 << 24),
+	ATA_TFLAG_IDE_LBA48	= (1 << 25),
 };
 
 enum ata_tf_protocols {
Index: linux-taskfile-ng/include/linux/ide.h
===================================================================
--- linux-taskfile-ng.orig/include/linux/ide.h	2005-03-05 10:37:51.739348441 +0900
+++ linux-taskfile-ng/include/linux/ide.h	2005-03-05 10:46:58.318076908 +0900
@@ -927,8 +927,8 @@ typedef int (ide_expiry_t)(ide_drive_t *
 typedef struct ide_task_s {
 	struct ata_taskfile	tf;
 	u16			data;
-	ide_reg_valid_t		tf_out_flags;
-	ide_reg_valid_t		tf_in_flags;
+	unsigned		load_data:1;
+	unsigned		read_data:1;
 	int			data_phase;
 	int			command_type;
 	ide_pre_handler_t	*prehandler;
@@ -1276,6 +1276,12 @@ extern int drive_is_ready(ide_drive_t *)
 extern int wait_for_ready(ide_drive_t *, int /* timeout */);
 
 /*
+ * Taskfile load/read functions
+ */
+void ide_load_taskfile(ide_drive_t *drive, ide_task_t *task);
+void ide_read_taskfile(ide_drive_t *drive, ide_task_t *task, u8 stat, u8 err);
+
+/*
  * taskfile io for disks for now...and builds request from ide_ioctl
  */
 extern ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *);

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2.6.11-rc3 02/08] ide: convert __ide_do_rw_disk() to use ide_load_taskfile()
  2005-03-05  1:47 [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup Tejun Heo
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 01/08] ide: add individual ATA_TFLAG_{OUT|IN}_* flags Tejun Heo
@ 2005-03-05  1:48 ` Tejun Heo
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 03/08] ide: remove flagged_taskfile() and unify taskfile paths Tejun Heo
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Tejun Heo @ 2005-03-05  1:48 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, lkml, linux-ide, Jeff Garzik


02_ide_use_load_taskfile_in_do_rw_disk.patch

	Reimplements __ide_do_rw_disk() using ide_load_taskfile().
	While at it, clean up the function a little bit.

Signed-off-by: Tejun Heo <htejun@gmail.com>

 ide-disk.c |  163 ++++++++++++++++++++++++-------------------------------------
 1 files changed, 65 insertions(+), 98 deletions(-)

Index: linux-taskfile-ng/drivers/ide/ide-disk.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-disk.c	2005-03-05 10:46:58.305078940 +0900
+++ linux-taskfile-ng/drivers/ide/ide-disk.c	2005-03-05 10:46:58.762007508 +0900
@@ -158,114 +158,80 @@ static int lba_capacity_is_ok (struct hd
  */
 ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
-	unsigned int dma	= drive->using_dma;
-	u8 lba48		= (drive->addressing == 1) ? 1 : 0;
-	task_ioreg_t command	= WIN_NOP;
-	ata_nsector_t		nsectors;
-
-	nsectors.all		= (u16) rq->nr_sectors;
-
-	if (hwif->no_lba48_dma && lba48 && dma) {
-		if (block + rq->nr_sectors > 1ULL << 28)
-			dma = 0;
-	}
-
-	if (!dma) {
-		ide_init_sg_cmd(drive, rq);
-		ide_map_sg(drive, rq);
-	}
+	ide_hwif_t *hwif = drive->hwif;
+	int lba48 = (drive->addressing == 1) ? 1 : 0;
+	ide_task_t task;
+	struct ata_taskfile *tf = &task.tf;
+	u8 command;
 
+	/* ALL Command Block Executions SHALL clear nIEN. */
 	if (IDE_CONTROL_REG)
 		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
-
 	/* FIXME: SELECT_MASK(drive, 0) ? */
 
-	if (drive->select.b.lba) {
-		if (drive->addressing == 1) {
-			task_ioreg_t tasklets[10];
-
-			pr_debug("%s: LBA=0x%012llx\n", drive->name, block);
+	memset(&task, 0, sizeof(task));
 
-			tasklets[0] = 0;
-			tasklets[1] = 0;
-			tasklets[2] = nsectors.b.low;
-			tasklets[3] = nsectors.b.high;
-			tasklets[4] = (task_ioreg_t) block;
-			tasklets[5] = (task_ioreg_t) (block>>8);
-			tasklets[6] = (task_ioreg_t) (block>>16);
-			tasklets[7] = (task_ioreg_t) (block>>24);
-			if (sizeof(block) == 4) {
-				tasklets[8] = (task_ioreg_t) 0;
-				tasklets[9] = (task_ioreg_t) 0;
-			} else {
-				tasklets[8] = (task_ioreg_t)((u64)block >> 32);
-				tasklets[9] = (task_ioreg_t)((u64)block >> 40);
-			}
-#ifdef DEBUG
-			printk("%s: 0x%02x%02x 0x%02x%02x%02x%02x%02x%02x\n",
-				drive->name, tasklets[3], tasklets[2],
-				tasklets[9], tasklets[8], tasklets[7],
-				tasklets[6], tasklets[5], tasklets[4]);
-#endif
-			hwif->OUTB(tasklets[1], IDE_FEATURE_REG);
-			hwif->OUTB(tasklets[3], IDE_NSECTOR_REG);
-			hwif->OUTB(tasklets[7], IDE_SECTOR_REG);
-			hwif->OUTB(tasklets[8], IDE_LCYL_REG);
-			hwif->OUTB(tasklets[9], IDE_HCYL_REG);
-
-			hwif->OUTB(tasklets[0], IDE_FEATURE_REG);
-			hwif->OUTB(tasklets[2], IDE_NSECTOR_REG);
-			hwif->OUTB(tasklets[4], IDE_SECTOR_REG);
-			hwif->OUTB(tasklets[5], IDE_LCYL_REG);
-			hwif->OUTB(tasklets[6], IDE_HCYL_REG);
-			hwif->OUTB(0x00|drive->select.all,IDE_SELECT_REG);
-		} else {
-			hwif->OUTB(0x00, IDE_FEATURE_REG);
-			hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG);
-			hwif->OUTB(block, IDE_SECTOR_REG);
-			hwif->OUTB(block>>=8, IDE_LCYL_REG);
-			hwif->OUTB(block>>=8, IDE_HCYL_REG);
-			hwif->OUTB(((block>>8)&0x0f)|drive->select.all,IDE_SELECT_REG);
-		}
+	if (drive->select.b.lba) {
+		/* LBA28/LBA48 */
+		tf->flags	|= ATA_TFLAG_OUT_ADDR | ATA_TFLAG_OUT_DEVICE;
+		tf->nsect	= rq->nr_sectors;
+		tf->lbal	= block;
+		tf->lbam	= block >> 8;
+		tf->lbah	= block >> 16;
+
+		if (lba48) {
+			tf->flags	|= ATA_TFLAG_OUT_LBA48;
+			tf->hob_nsect	= rq->nr_sectors >> 8;
+			tf->hob_lbal	= block >> 24;
+			tf->hob_lbam	= block >> 32;
+			tf->hob_lbah	= block >> 40;
+		} else
+			tf->device	= (block >> 24) & 0xf;
 	} else {
-		unsigned int sect,head,cyl,track;
-		track = (int)block / drive->sect;
-		sect  = (int)block % drive->sect + 1;
-		hwif->OUTB(sect, IDE_SECTOR_REG);
-		head  = track % drive->head;
-		cyl   = track / drive->head;
-
-		pr_debug("%s: CHS=%u/%u/%u\n", drive->name, cyl, head, sect);
-
-		hwif->OUTB(0x00, IDE_FEATURE_REG);
-		hwif->OUTB(nsectors.b.low, IDE_NSECTOR_REG);
-		hwif->OUTB(cyl, IDE_LCYL_REG);
-		hwif->OUTB(cyl>>8, IDE_HCYL_REG);
-		hwif->OUTB(head|drive->select.all,IDE_SELECT_REG);
-	}
-
-	if (dma) {
-		if (!hwif->dma_setup(drive)) {
-			if (rq_data_dir(rq)) {
-				command = lba48 ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
-				if (drive->vdma)
-					command = lba48 ? WIN_WRITE_EXT: WIN_WRITE;
-			} else {
-				command = lba48 ? WIN_READDMA_EXT : WIN_READDMA;
-				if (drive->vdma)
-					command = lba48 ? WIN_READ_EXT: WIN_READ;
-			}
-			hwif->dma_exec_cmd(drive, command);
-			hwif->dma_start(drive);
-			return ide_started;
+		/* CHS */
+		int track	= (int)block / drive->sect;
+		int cyl		= track / drive->head;
+		int head	= track % drive->head;
+		int sect	= (int)block % drive->sect + 1;
+
+		tf->flags	|= ATA_TFLAG_OUT_ADDR | ATA_TFLAG_OUT_DEVICE;
+		tf->nsect	= rq->nr_sectors;
+		tf->lbal	= sect;
+		tf->lbam	= cyl;
+		tf->lbah	= cyl >> 8;
+		tf->device	= head;
+	}
+
+	tf->device |= drive->select.all;
+
+	ide_load_taskfile(drive, &task);
+
+	if (drive->using_dma &&
+	    !(hwif->no_lba48_dma && block + rq->nr_sectors > 1ULL << 28)) {
+		/* DMA */
+		if (hwif->dma_setup(drive))
+			goto fallback_to_pio;
+		if (rq_data_dir(rq) == READ) {
+			command = lba48 ? WIN_READDMA_EXT : WIN_READDMA;
+			if (drive->vdma)
+				command = lba48 ? WIN_READ_EXT : WIN_READ;
+		} else {
+			command = lba48 ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
+			if (drive->vdma)
+				command = lba48 ? WIN_WRITE_EXT : WIN_WRITE;
 		}
-		/* fallback to PIO */
-		ide_init_sg_cmd(drive, rq);
+		hwif->dma_exec_cmd(drive, command);
+		hwif->dma_start(drive);
+		return ide_started;
 	}
 
-	if (rq_data_dir(rq) == READ) {
+	/* PIO */
+	ide_map_sg(drive, rq);
+	/* dma_setup() has already done ide_map_sg(). */
+ fallback_to_pio:
+	ide_init_sg_cmd(drive, rq);
 
+	if (rq_data_dir(rq) == READ) {
 		if (drive->mult_count) {
 			hwif->data_phase = TASKFILE_MULTI_IN;
 			command = lba48 ? WIN_MULTREAD_EXT : WIN_MULTREAD;
@@ -274,7 +240,8 @@ ide_startstop_t __ide_do_rw_disk (ide_dr
 			command = lba48 ? WIN_READ_EXT : WIN_READ;
 		}
 
-		ide_execute_command(drive, command, &task_in_intr, WAIT_CMD, NULL);
+		ide_execute_command(drive, command, &task_in_intr,
+				    WAIT_CMD, NULL);
 		return ide_started;
 	} else {
 		if (drive->mult_count) {

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2.6.11-rc3 03/08] ide: remove flagged_taskfile() and unify taskfile paths
  2005-03-05  1:47 [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup Tejun Heo
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 01/08] ide: add individual ATA_TFLAG_{OUT|IN}_* flags Tejun Heo
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 02/08] ide: convert __ide_do_rw_disk() to use ide_load_taskfile() Tejun Heo
@ 2005-03-05  1:48 ` Tejun Heo
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 04/08] ide: remove unused fields ide_drive_t->rq and ide_task_t->special Tejun Heo
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Tejun Heo @ 2005-03-05  1:48 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, lkml, linux-ide, Jeff Garzik


03_ide_remove_flagged_taskfile.patch

	This patch removes flagged_taskfile().  All taskfile command
	issuing goes through do_rw_taskfile().  do_rw_taskfile()
	doesn't modify mangle with load flags anymore.  It's now
	caller's responsibility to set appropriate flags.  Likewise,
	ide_end_drive_cmd() is modified not to mangle with read flags,
	and ide_dma_intr() now also finishes commands with
	task_end_request().  Above changes make taskfile path unified
	& generic.

	As all ioctl subtleties are now responsibility of respective
	ioctl functions.  TASKFILE and TASK ioctl functions are
	updated to set flags according to old behaviors.  The
	following two behavior changes occur.

	* TASKFILE ioctl: taskfile registers are read back whether or
	  not the command fails.  As copying back to user doesn't
	  happen in cases where reading back didn't occur before, this
	  change isn't user-visible.  Defining & using a flag like
	  ATA_TFLAG_READ_ON_ERROR will remove this issue.
	* TASK ioctl: drive->select.all & ~ATA_LBA is OR'd to device
	  value.  Previously, only ATA_DEV bit was OR'd.

	Also, all ide_{raw|diag}_taskfile(), do_rw_taskfile() users
	are converted to use the new individual OUT/IN flags.  As
	results, the following behavior changes occur.

	* idedisk_read_native_max_address(): ADDR/LBA48 regs are not
	  loaded.  LBA48/DEVICE registers are not read back unless
	  necessary.
	* idedisk_set_max_address(): DEVICE register is not read
	  unless necessary.
	* smart_enable(): DEVICE register is not loaded.  Registers
	  are not read back.
	* smart_disable(): ditto
	* get_smart_threshold(): DEVICE register is not loaded.
	* ide_task_init_flush(): ADDR/LBA48/DEVICE registers are not
	  loaded.
	* ide_init_specify_cmd(): Register aren't read back.
	* ide_init_restore_cmd(): DEVICE register not loaded.  No read back.
	* ide_init_setmult_cmd(): ditto

Signed-off-by: Tejun Heo <htejun@gmail.com>

 drivers/ide/ide-disk.c     |   31 ++---
 drivers/ide/ide-dma.c      |   16 --
 drivers/ide/ide-io.c       |   21 +--
 drivers/ide/ide-taskfile.c |  263 +++++++++++++++++----------------------------
 include/linux/ata.h        |    6 -
 include/linux/ide.h        |    6 -
 6 files changed, 136 insertions(+), 207 deletions(-)

Index: linux-taskfile-ng/drivers/ide/ide-disk.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-disk.c	2005-03-05 10:46:58.762007508 +0900
+++ linux-taskfile-ng/drivers/ide/ide-disk.c	2005-03-05 10:46:59.081957489 +0900
@@ -301,21 +301,22 @@ static u64 idedisk_read_native_max_addre
 	/* Create IDE/ATA command request structure */
 	memset(&args, 0, sizeof(ide_task_t));
 
-	tf->device	= 0x40;
+	tf->flags	= ATA_TFLAG_OUT_DEVICE | ATA_TFLAG_IN_ADDR;
+	tf->device	= ATA_LBA;
 	if (lba48) {
+		tf->flags |= ATA_TFLAG_IN_LBA48;
 		tf->command = WIN_READ_NATIVE_MAX_EXT;
-		tf->flags |= ATA_TFLAG_IDE_LBA48;
-	} else
+	} else {
+		tf->flags |= ATA_TFLAG_IN_DEVICE;
 		tf->command = WIN_READ_NATIVE_MAX;
+	}
 
 	args.command_type			= IDE_DRIVE_TASK_NO_DATA;
 	args.handler				= &task_no_data_intr;
 
         /* submit command request */
-        ide_raw_taskfile(drive, &args, NULL);
-
-	/* if OK, compute maximum address value */
-	if ((tf->command & 1) == 0) {
+	if (ide_raw_taskfile(drive, &args, NULL) == 0) {
+		/* if OK, compute maximum address value */
 		addr = ide_tf_get_address(drive, tf);
 		addr++;	/* since the return value is (maxlba - 1), we add 1 */
 	}
@@ -336,19 +337,20 @@ static u64 idedisk_set_max_address(ide_d
 	/* Create IDE/ATA command request structure */
 	memset(&args, 0, sizeof(ide_task_t));
 
+	tf->flags	= ATA_TFLAG_OUT_DEVICE | ATA_TFLAG_ISADDR;
+	tf->device	= ATA_LBA;
 	tf->lbal	= addr_req;
 	tf->lbam	= addr_req >> 8;
 	tf->lbah	= addr_req >> 16;
 	if (lba48) {
+		tf->flags	|= ATA_TFLAG_LBA48;
 		tf->hob_lbal	= addr_req >> 24;
 		tf->hob_lbam	= addr_req >> 32;
 		tf->hob_lbah	= addr_req >> 40;
-		tf->device	= 0x40;
 		tf->command	= WIN_SET_MAX_EXT;
-
-		tf->flags |= ATA_TFLAG_IDE_LBA48;
 	} else {
-		tf->device	= ((addr_req >> 24) & 0xf) | 0x40;
+		tf->flags	|= ATA_TFLAG_IN_DEVICE;
+		tf->device	|= (addr_req >> 24) & 0xf;
 		tf->command	= WIN_SET_MAX;
 	}
 
@@ -356,9 +358,7 @@ static u64 idedisk_set_max_address(ide_d
 	args.handler				= &task_no_data_intr;
 
 	/* submit command request */
-	ide_raw_taskfile(drive, &args, NULL);
-	/* if OK, compute maximum address value */
-	if ((tf->command & 1) == 0) {
+	if (ide_raw_taskfile(drive, &args, NULL) == 0) {
 		addr_set = ide_tf_get_address(drive, tf);
 		addr_set++;
 	}
@@ -474,6 +474,7 @@ static int smart_enable(ide_drive_t *dri
 
 	memset(&args, 0, sizeof(ide_task_t));
 
+	tf->flags	= ATA_TFLAG_OUT_ADDR;
 	tf->feature	= SMART_ENABLE;
 	tf->lbam	= SMART_LCYL_PASS;
 	tf->lbah	= SMART_HCYL_PASS;
@@ -491,6 +492,7 @@ static int get_smart_values(ide_drive_t 
 
 	memset(&args, 0, sizeof(ide_task_t));
 
+	tf->flags	= ATA_TFLAG_OUT_ADDR;
 	tf->feature	= SMART_READ_VALUES;
 	tf->nsect	= 1;
 	tf->lbam	= SMART_LCYL_PASS;
@@ -511,6 +513,7 @@ static int get_smart_thresholds(ide_driv
 
 	memset(&args, 0, sizeof(ide_task_t));
 
+	tf->flags	= ATA_TFLAG_OUT_ADDR;
 	tf->feature	= SMART_READ_THRESHOLDS;
 	tf->nsect	= 1;
 	tf->lbam	= SMART_LCYL_PASS;
Index: linux-taskfile-ng/drivers/ide/ide-dma.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-dma.c	2005-03-05 10:46:58.188097228 +0900
+++ linux-taskfile-ng/drivers/ide/ide-dma.c	2005-03-05 10:46:59.082957333 +0900
@@ -168,21 +168,15 @@ static int in_drive_list(struct hd_drive
  
 ide_startstop_t ide_dma_intr (ide_drive_t *drive)
 {
-	u8 stat = 0, dma_stat = 0;
+	u8 stat, dma_stat;
 
+	stat = HWIF(drive)->INB(IDE_STATUS_REG);
 	dma_stat = HWIF(drive)->ide_dma_end(drive);
-	stat = HWIF(drive)->INB(IDE_STATUS_REG);	/* get drive status */
-	if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
+
+	if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat|DRQ_STAT)) {
 		if (!dma_stat) {
 			struct request *rq = HWGROUP(drive)->rq;
-
-			if (rq->rq_disk) {
-				ide_driver_t *drv;
-
-				drv = *(ide_driver_t **)rq->rq_disk->private_data;;
-				drv->end_request(drive, 1, rq->nr_sectors);
-			} else
-				ide_end_request(drive, 1, rq->nr_sectors);
+			task_end_request(drive, rq, stat);
 			return ide_stopped;
 		}
 		printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", 
Index: linux-taskfile-ng/drivers/ide/ide-io.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-io.c	2005-03-05 10:46:58.307078627 +0900
+++ linux-taskfile-ng/drivers/ide/ide-io.c	2005-03-05 10:46:59.084957020 +0900
@@ -61,10 +61,12 @@ void ide_task_init_flush(ide_drive_t *dr
 
 	memset(task, 0, sizeof(*task));
 
+	tf->flags = ATA_TFLAG_IN_ADDR | ATA_TFLAG_IN_DEVICE;
+
 	if (ide_id_has_flush_cache_ext(drive->id) &&
 	    (drive->capacity64 >= (1UL << 28))) {
 		tf->command = WIN_FLUSH_CACHE_EXT;
-		tf->flags |= ATA_TFLAG_IDE_LBA48;
+		tf->flags |= ATA_TFLAG_IN_LBA48;
 	} else
 		tf->command = WIN_FLUSH_CACHE;
 
@@ -322,7 +324,7 @@ u64 ide_tf_get_address(ide_drive_t *driv
 {
 	u32 high, low;
 
-	if (tf->flags & ATA_TFLAG_IDE_LBA48) {
+	if (tf->flags & ATA_TFLAG_IN_LBA48) {
 		high = (tf->hob_lbah << 16) | (tf->hob_lbam << 8) | tf->hob_lbal;
 		low = (tf->lbah << 16) | (tf->lbam << 8) | tf->lbal;
 	} else {
@@ -455,14 +457,8 @@ void ide_end_drive_cmd (ide_drive_t *dri
 		ide_task_t *args = (ide_task_t *) rq->special;
 		if (rq->errors == 0)
 			rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
-			
-		if (args) {
-			struct ata_taskfile *tf = &args->tf;
-			tf->flags |= ATA_TFLAG_IN_ADDR | ATA_TFLAG_IN_DEVICE;
-			if (tf->flags & ATA_TFLAG_IDE_LBA48)
-				tf->flags |= ATA_TFLAG_IN_LBA48;
+		if (args)
 			ide_read_taskfile(drive, args, stat, err);
-		}
 	} else if (blk_pm_request(rq)) {
 #ifdef DEBUG_PM
 		printk("%s: complete_power_step(step: %d, stat: %x, err: %x)\n",
@@ -759,11 +755,12 @@ static void ide_init_specify_cmd(ide_dri
 {
 	struct ata_taskfile *tf = &task->tf;
 
+	tf->flags	= ATA_TFLAG_OUT_ADDR | ATA_TFLAG_OUT_DEVICE;
 	tf->nsect	= drive->sect;
 	tf->lbal	= drive->sect;
 	tf->lbam	= drive->cyl;
 	tf->lbah	= drive->cyl >> 8;
-	tf->device	= ((drive->head - 1) | drive->select.all) & 0xBF;
+	tf->device	= drive->head - 1;
 	tf->command	= WIN_SPECIFY;
 
 	task->handler = &set_geometry_intr;
@@ -773,6 +770,7 @@ static void ide_init_restore_cmd(ide_dri
 {
 	struct ata_taskfile *tf = &task->tf;
 
+	tf->flags	= ATA_TFLAG_OUT_ADDR;
 	tf->nsect	= drive->sect;
 	tf->command	= WIN_RESTORE;
 
@@ -783,6 +781,7 @@ static void ide_init_setmult_cmd(ide_dri
 {
 	struct ata_taskfile *tf = &task->tf;
 
+	tf->flags	= ATA_TFLAG_OUT_ADDR;
 	tf->nsect	= drive->mult_req;
 	tf->command	= WIN_SETMULT;
 
@@ -914,8 +913,6 @@ static ide_startstop_t execute_drive_cmd
 			break;
 		}
 
-		if (args->tf.flags & ATA_TFLAG_IDE_FLAGGED)
-			return flagged_taskfile(drive, args);
 		return do_rw_taskfile(drive, args);
 	} else if (rq->flags & REQ_DRIVE_CMD) {
 		u8 *args = rq->buffer;
Index: linux-taskfile-ng/drivers/ide/ide-taskfile.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-taskfile.c	2005-03-05 10:46:58.315077377 +0900
+++ linux-taskfile-ng/drivers/ide/ide-taskfile.c	2005-03-05 10:46:59.092955770 +0900
@@ -186,25 +186,28 @@ int taskfile_lib_get_identify (ide_drive
 	return ide_raw_taskfile(drive, &args, buf);
 }
 
-ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
+ide_startstop_t do_rw_taskfile(ide_drive_t *drive, ide_task_t *task)
 {
-	ide_hwif_t *hwif	= HWIF(drive);
+	ide_hwif_t *hwif = drive->hwif;
 	struct ata_taskfile *tf = &task->tf;
-	u8 HIHI			= (tf->flags & ATA_TFLAG_IDE_LBA48) ? 0xE0 : 0xEF;
 
-	/* ALL Command Block Executions SHALL clear nIEN, unless otherwise */
-	if (IDE_CONTROL_REG) {
-		/* clear nIEN */
-		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
+	/* We check this in ide_taskfile_ioctl(), but the setting could
+	   have been changed inbetween. */
+	if ((task->data_phase == TASKFILE_MULTI_IN ||
+	     task->data_phase == TASKFILE_MULTI_OUT) && !drive->mult_count) {
+		printk(KERN_ERR "%s: multimode not set!\n",
+		       drive->name);
+		/* FIXME: this path is an infinite loop. */
+		return ide_stopped;
 	}
-	SELECT_MASK(drive, 0);
 
-	if (tf->flags & ATA_TFLAG_IDE_LBA48)
-		tf->flags |= ATA_TFLAG_OUT_LBA48;
-	tf->flags |= ATA_TFLAG_OUT_ADDR;
-	tf->flags |= ATA_TFLAG_OUT_DEVICE;
-	tf->device = (tf->device & HIHI) | (drive->select.all & 0xBF);
+	/* ALL Command Block Executions SHALL clear nIEN. */
+	if (IDE_CONTROL_REG)
+		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
+	SELECT_MASK(drive, 0);
 
+	if (tf->flags & ATA_TFLAG_OUT_DEVICE)
+		tf->device |= drive->select.all & ~ATA_LBA;
 	ide_load_taskfile(drive, task);
 
 	if (task->handler != NULL) {
@@ -213,33 +216,25 @@ ide_startstop_t do_rw_taskfile (ide_driv
 			ndelay(400);	/* FIXME */
 			return task->prehandler(drive, task->rq);
 		}
-		ide_execute_command(drive, tf->command, task->handler, WAIT_WORSTCASE, NULL);
+		ide_execute_command(drive, tf->command, task->handler,
+				    WAIT_WORSTCASE, NULL);
 		return ide_started;
 	}
 
-	if (!drive->using_dma)
+	switch (task->data_phase) {
+	case TASKFILE_OUT_DMAQ:
+	case TASKFILE_OUT_DMA:
+	case TASKFILE_IN_DMAQ:
+	case TASKFILE_IN_DMA:
+		if (!hwif->dma_setup(drive)) {
+			hwif->dma_exec_cmd(drive, tf->command);
+			hwif->dma_start(drive);
+			return ide_started;
+		}
+		return ide_stopped;
+	default:
 		return ide_stopped;
-
-	switch (tf->command) {
-		case WIN_WRITEDMA_ONCE:
-		case WIN_WRITEDMA:
-		case WIN_WRITEDMA_EXT:
-		case WIN_READDMA_ONCE:
-		case WIN_READDMA:
-		case WIN_READDMA_EXT:
-		case WIN_IDENTIFY_DMA:
-			if (!hwif->dma_setup(drive)) {
-				hwif->dma_exec_cmd(drive, tf->command);
-				hwif->dma_start(drive);
-				return ide_started;
-			}
-			break;
-		default:
-			if (task->handler == NULL)
-				return ide_stopped;
 	}
-
-	return ide_stopped;
 }
 
 EXPORT_SYMBOL(do_rw_taskfile);
@@ -302,7 +297,7 @@ ide_startstop_t recal_intr (ide_drive_t 
 /*
  * Handler for commands without a data phase
  */
-ide_startstop_t task_no_data_intr (ide_drive_t *drive)
+ide_startstop_t task_no_data_intr(ide_drive_t *drive)
 {
 	ide_task_t *args	= HWGROUP(drive)->rq->special;
 	ide_hwif_t *hwif	= HWIF(drive);
@@ -456,19 +451,16 @@ static ide_startstop_t task_error(ide_dr
 	return ide_error(drive, s, stat);
 }
 
-static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
+void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
 {
 	if (rq->flags & REQ_DRIVE_TASKFILE) {
-		ide_task_t *task = rq->special;
-
-		if (task->tf.flags & ATA_TFLAG_IDE_FLAGGED) {
-			u8 err = drive->hwif->INB(IDE_ERROR_REG);
-			ide_end_drive_cmd(drive, stat, err);
-			return;
-		}
+		u8 err = drive->hwif->INB(IDE_ERROR_REG);
+		ide_end_drive_cmd(drive, stat, err);
+		return;
+	} else {
+		ide_driver_t *drv = *(ide_driver_t **)rq->rq_disk->private_data;;
+		drv->end_request(drive, 1, rq->hard_nr_sectors);
 	}
-
-	ide_end_request(drive, 1, rq->hard_nr_sectors);
 }
 
 /*
@@ -674,49 +666,58 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 	tf->device	= req_task->io_ports[6];
 	tf->command	= req_task->io_ports[7];
 
-	/* Translate out/in flags. */
-	if (req_task->out_flags.all)
-		tf->flags |= ATA_TFLAG_IDE_FLAGGED;
-
-	if (req_task->out_flags.b.error_feature_hob)
-		tf->flags |= ATA_TFLAG_OUT_HOB_FEATURE;
-	if (req_task->out_flags.b.nsector_hob)
-		tf->flags |= ATA_TFLAG_OUT_HOB_NSECT;
-	if (req_task->out_flags.b.sector_hob)
-		tf->flags |= ATA_TFLAG_OUT_HOB_LBAL;
-	if (req_task->out_flags.b.lcyl_hob)
-		tf->flags |= ATA_TFLAG_OUT_HOB_LBAM;
-	if (req_task->out_flags.b.hcyl_hob)
-		tf->flags |= ATA_TFLAG_OUT_HOB_LBAH;
-
-	if (req_task->out_flags.b.error_feature)
-		tf->flags |= ATA_TFLAG_OUT_FEATURE;
-	if (req_task->out_flags.b.nsector)
-		tf->flags |= ATA_TFLAG_OUT_NSECT;
-	if (req_task->out_flags.b.sector)
-		tf->flags |= ATA_TFLAG_OUT_LBAL;
-	if (req_task->out_flags.b.lcyl)
-		tf->flags |= ATA_TFLAG_OUT_LBAM;
-	if (req_task->out_flags.b.hcyl)
-		tf->flags |= ATA_TFLAG_OUT_LBAH;
+	/* Translate & adjust flags */
+	tf->flags |= ATA_TFLAG_OUT_DEVICE;
+	tf->flags |= ATA_TFLAG_IN_ADDR | ATA_TFLAG_IN_DEVICE;
+
+	if (drive->addressing == 1)
+		tf->flags |= ATA_TFLAG_IN_LBA48;
+
+	if (req_task->out_flags.all) {
+		/* out_flags.b.error_feature_hob is ignored */
+		if (req_task->out_flags.b.nsector_hob)
+			tf->flags |= ATA_TFLAG_OUT_HOB_NSECT;
+		if (req_task->out_flags.b.sector_hob)
+			tf->flags |= ATA_TFLAG_OUT_HOB_LBAL;
+		if (req_task->out_flags.b.lcyl_hob)
+			tf->flags |= ATA_TFLAG_OUT_HOB_LBAM;
+		if (req_task->out_flags.b.hcyl_hob)
+			tf->flags |= ATA_TFLAG_OUT_HOB_LBAH;
+
+		if (req_task->out_flags.b.error_feature)
+			tf->flags |= ATA_TFLAG_OUT_FEATURE;
+		if (req_task->out_flags.b.nsector)
+			tf->flags |= ATA_TFLAG_OUT_NSECT;
+		if (req_task->out_flags.b.sector)
+			tf->flags |= ATA_TFLAG_OUT_LBAL;
+		if (req_task->out_flags.b.lcyl)
+			tf->flags |= ATA_TFLAG_OUT_LBAM;
+		if (req_task->out_flags.b.hcyl)
+			tf->flags |= ATA_TFLAG_OUT_LBAH;
+
+		/* FIXME: tf->device isn't filtered to keep the old
+		   behavior, so TASKFILE ioctl can issue commands to
+		   slave with permissions to master. */
+	} else {
+		tf->flags |= ATA_TFLAG_OUT_ADDR;
+		if (drive->addressing == 1)
+			tf->flags |= ATA_TFLAG_OUT_LBA48;
+
+		/* FIXME: The DEV bit is filtered when no out_flags is
+		   set, but other drives still can be selected on
+		   four-drive-per-port chipsets. */
+		tf->device &= drive->addressing == 1 ? 0xE0 : 0xEF;
+	}
 
-	if (req_task->out_flags.b.select)
-		tf->flags |= ATA_TFLAG_OUT_DEVICE;
 	if (req_task->out_flags.b.data)
 		args.load_data = 1;
-
 	if (req_task->in_flags.b.data)
 		args.read_data = 1;
 
-	args.data_phase   = req_task->data_phase;
-	args.command_type = req_task->req_cmd;
-
 	tf->flags |= ATA_TFLAG_IO_16BIT;
-	if (drive->addressing == 1)
-		tf->flags |= ATA_TFLAG_IDE_LBA48;
 
-	if (drive->select.b.lba)
-		tf->device |= ATA_LBA;
+	args.data_phase   = req_task->data_phase;
+	args.command_type = req_task->req_cmd;
 
 	switch(req_task->data_phase) {
 		case TASKFILE_OUT_DMAQ:
@@ -765,22 +766,25 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 			goto abort;
 	}
 
-	req_task->io_ports[0]	= args.data;
-	req_task->hob_ports[0]	= args.data << 8;
-
-	req_task->hob_ports[1] = tf->hob_feature;
-	req_task->hob_ports[2] = tf->hob_nsect;
-	req_task->hob_ports[3] = tf->hob_lbal;
-	req_task->hob_ports[4] = tf->hob_lbam;
-	req_task->hob_ports[5] = tf->hob_lbah;
-
-	req_task->io_ports[1] = tf->feature;
-	req_task->io_ports[2] = tf->nsect;
-	req_task->io_ports[3] = tf->lbal;
-	req_task->io_ports[4] = tf->lbam;
-	req_task->io_ports[5] = tf->lbah;
-	req_task->io_ports[6] = tf->device;
-	req_task->io_ports[7] = tf->command;
+	if (req_task->data_phase == TASKFILE_NO_DATA ||
+	    req_task->out_flags.all || err) {
+		req_task->io_ports[0]	= args.data;
+		req_task->hob_ports[0]	= args.data << 8;
+
+		req_task->hob_ports[1]	= tf->hob_feature;
+		req_task->hob_ports[2]	= tf->hob_nsect;
+		req_task->hob_ports[3]	= tf->hob_lbal;
+		req_task->hob_ports[4]	= tf->hob_lbam;
+		req_task->hob_ports[5]	= tf->hob_lbah;
+
+		req_task->io_ports[1]	= tf->feature;
+		req_task->io_ports[2]	= tf->nsect;
+		req_task->io_ports[3]	= tf->lbal;
+		req_task->io_ports[4]	= tf->lbam;
+		req_task->io_ports[5]	= tf->lbah;
+		req_task->io_ports[6]	= tf->device;
+		req_task->io_ports[7]	= tf->command;
+	}
 
 	if (copy_to_user(buf, req_task, tasksize)) {
 		err = -EFAULT;
@@ -897,13 +901,15 @@ int ide_task_ioctl(ide_drive_t *drive, u
 
 	memset(&task, 0, sizeof(task));
 
+	tf->flags	= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+
 	tf->command	= args[0];
 	tf->feature	= args[1];
 	tf->nsect	= args[2];
 	tf->lbal	= args[3];
 	tf->lbam	= args[4];
 	tf->lbah	= args[5];
-	tf->device	= args[6];
+	tf->device	= args[6] & ~ATA_DEV1;
 
 	task.command_type = IDE_DRIVE_TASK_NO_DATA;
 	task.data_phase = TASKFILE_NO_DATA;
@@ -923,64 +929,3 @@ int ide_task_ioctl(ide_drive_t *drive, u
 		err = -EFAULT;
 	return err;
 }
-
-/*
- * NOTICE: This is additions from IBM to provide a discrete interface,
- * for selective taskregister access operations.  Nice JOB Klaus!!!
- * Glad to be able to work and co-develop this with you and IBM.
- */
-ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
-{
-	ide_hwif_t *hwif	= HWIF(drive);
-	struct ata_taskfile *tf = &task->tf;
-#if DEBUG_TASKFILE
-	u8 status;
-#endif
-
-	if (task->data_phase == TASKFILE_MULTI_IN ||
-	    task->data_phase == TASKFILE_MULTI_OUT) {
-		if (!drive->mult_count) {
-			printk(KERN_ERR "%s: multimode not set!\n", drive->name);
-			return ide_stopped;
-		}
-	}
-
-	/* ALL Command Block Executions SHALL clear nIEN, unless otherwise */
-	if (IDE_CONTROL_REG)
-		/* clear nIEN */
-		hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
-	SELECT_MASK(drive, 0);
-
-	/* Adjust task. */
-	tf->flags &= ~ATA_TFLAG_OUT_HOB_FEATURE;
-	tf->flags |= ATA_TFLAG_OUT_DEVICE;
-	tf->device |= drive->select.all & 0xBF;
-
-	ide_load_taskfile(drive, task);
-
-	switch(task->data_phase) {
-
-   	        case TASKFILE_OUT_DMAQ:
-		case TASKFILE_OUT_DMA:
-		case TASKFILE_IN_DMAQ:
-		case TASKFILE_IN_DMA:
-			hwif->dma_setup(drive);
-			hwif->dma_exec_cmd(drive, tf->command);
-			hwif->dma_start(drive);
-			break;
-
-	        default:
- 			if (task->handler == NULL)
-				return ide_stopped;
-
-			/* Issue the command */
-			if (task->prehandler) {
-				hwif->OUTBSYNC(drive, tf->command, IDE_COMMAND_REG);
-				ndelay(400);	/* FIXME */
-				return task->prehandler(drive, task->rq);
-			}
-			ide_execute_command(drive, tf->command, task->handler, WAIT_WORSTCASE, NULL);
-	}
-
-	return ide_started;
-}
Index: linux-taskfile-ng/include/linux/ata.h
===================================================================
--- linux-taskfile-ng.orig/include/linux/ata.h	2005-03-05 10:46:58.316077220 +0900
+++ linux-taskfile-ng/include/linux/ata.h	2005-03-05 10:46:59.093955614 +0900
@@ -223,12 +223,6 @@ enum {
 
 	ATA_TFLAG_WRITE		= (1 << 22), /* data dir */
 	ATA_TFLAG_IO_16BIT	= (1 << 23), /* force 16bit PIO (IDE) */
-
-	/* Following two flags are just to ease migration to the new
-	   taskfile implementation.  They will go away as soon as the
-	   transition is complete. */
-	ATA_TFLAG_IDE_FLAGGED	= (1 << 24),
-	ATA_TFLAG_IDE_LBA48	= (1 << 25),
 };
 
 enum ata_tf_protocols {
Index: linux-taskfile-ng/include/linux/ide.h
===================================================================
--- linux-taskfile-ng.orig/include/linux/ide.h	2005-03-05 10:46:58.318076908 +0900
+++ linux-taskfile-ng/include/linux/ide.h	2005-03-05 10:46:59.095955301 +0900
@@ -1285,11 +1285,7 @@ void ide_read_taskfile(ide_drive_t *driv
  * taskfile io for disks for now...and builds request from ide_ioctl
  */
 extern ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *);
-
-/*
- * Special Flagged Register Validation Caller
- */
-extern ide_startstop_t flagged_taskfile(ide_drive_t *, ide_task_t *);
+void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat);
 
 extern ide_startstop_t set_multmode_intr(ide_drive_t *);
 extern ide_startstop_t set_geometry_intr(ide_drive_t *);

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2.6.11-rc3 04/08] ide: remove unused fields ide_drive_t->rq and ide_task_t->special
  2005-03-05  1:47 [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup Tejun Heo
                   ` (2 preceding siblings ...)
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 03/08] ide: remove flagged_taskfile() and unify taskfile paths Tejun Heo
@ 2005-03-05  1:48 ` Tejun Heo
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 05/08] ide: use ide_task_t->tf.protocol instead of ide_task_t->data_phase Tejun Heo
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Tejun Heo @ 2005-03-05  1:48 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, lkml, linux-ide, Jeff Garzik


04_ide_remove_unused_fields.patch

	Remove unused fields ide_drive_t->rq and ide_task_t->special

Signed-off-by: Tejun Heo <htejun@gmail.com>

 drivers/ide/ide-tape.c |    1 -
 include/linux/ide.h    |    2 --
 2 files changed, 3 deletions(-)

Index: linux-taskfile-ng/drivers/ide/ide-tape.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-tape.c	2005-03-05 10:37:51.567375213 +0900
+++ linux-taskfile-ng/drivers/ide/ide-tape.c	2005-03-05 10:46:59.482894810 +0900
@@ -1733,7 +1733,6 @@ static int idetape_end_request(ide_drive
 	}
 	ide_end_drive_cmd(drive, 0, 0);
 //	blkdev_dequeue_request(rq);
-//	drive->rq = NULL;
 //	end_that_request_last(rq);
 
 	if (remove_stage)
Index: linux-taskfile-ng/include/linux/ide.h
===================================================================
--- linux-taskfile-ng.orig/include/linux/ide.h	2005-03-05 10:46:59.095955301 +0900
+++ linux-taskfile-ng/include/linux/ide.h	2005-03-05 10:46:59.483894654 +0900
@@ -660,7 +660,6 @@ typedef struct ide_drive_s {
 
 	request_queue_t		*queue;	/* request queue */
 
-	struct request		*rq;	/* current request */
 	struct ide_drive_s 	*next;	/* circular list of hwgroup drives */
 	struct ide_driver_s	*driver;/* (ide_driver_t *) */
 	void		*driver_data;	/* extra driver data */
@@ -934,7 +933,6 @@ typedef struct ide_task_s {
 	ide_pre_handler_t	*prehandler;
 	ide_handler_t		*handler;
 	struct request		*rq;		/* copy of request */
-	void			*special;	/* valid_t generally */
 } ide_task_t;
 
 typedef struct hwgroup_s {

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2.6.11-rc3 05/08] ide: use ide_task_t->tf.protocol instead of ide_task_t->data_phase
  2005-03-05  1:47 [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup Tejun Heo
                   ` (3 preceding siblings ...)
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 04/08] ide: remove unused fields ide_drive_t->rq and ide_task_t->special Tejun Heo
@ 2005-03-05  1:48 ` Tejun Heo
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 06/08] ide: convert set_xfer_rate() to use taskfile ioctl Tejun Heo
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Tejun Heo @ 2005-03-05  1:48 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, lkml, linux-ide, Jeff Garzik


05_ide_use_protocol.patch

	Remove ide_task_t->{data_phase,command_type,prehandler,rq} and
	use tf->protocol instead.  Now the protocol value wholey
	defines how to drive a taskfile except for NODATA cases where
	a caller can optionally specify handler (for special
	commands).  The following behavior changes occur.

	* ide_taskfile_ioctl(): req_task->command_type is ignored.
	  This doesn't make any difference except for error/crash
	  cases in the original code.

Signed-off-by: Tejun Heo <htejun@gmail.com>

 drivers/ide/ide-disk.c     |   70 +++++-------
 drivers/ide/ide-io.c       |   29 +----
 drivers/ide/ide-taskfile.c |  257 ++++++++++++++++++---------------------------
 include/linux/ide.h        |   11 -
 4 files changed, 142 insertions(+), 225 deletions(-)

Index: linux-taskfile-ng/drivers/ide/ide-disk.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-disk.c	2005-03-05 10:46:59.081957489 +0900
+++ linux-taskfile-ng/drivers/ide/ide-disk.c	2005-03-05 10:46:59.684863236 +0900
@@ -233,10 +233,10 @@ ide_startstop_t __ide_do_rw_disk (ide_dr
 
 	if (rq_data_dir(rq) == READ) {
 		if (drive->mult_count) {
-			hwif->data_phase = TASKFILE_MULTI_IN;
+			hwif->protocol = ATA_PROT_PIO_MULT;
 			command = lba48 ? WIN_MULTREAD_EXT : WIN_MULTREAD;
 		} else {
-			hwif->data_phase = TASKFILE_IN;
+			hwif->protocol = ATA_PROT_PIO;
 			command = lba48 ? WIN_READ_EXT : WIN_READ;
 		}
 
@@ -245,10 +245,10 @@ ide_startstop_t __ide_do_rw_disk (ide_dr
 		return ide_started;
 	} else {
 		if (drive->mult_count) {
-			hwif->data_phase = TASKFILE_MULTI_OUT;
+			hwif->protocol = ATA_PROT_PIO_MULT;
 			command = lba48 ? WIN_MULTWRITE_EXT : WIN_MULTWRITE;
 		} else {
-			hwif->data_phase = TASKFILE_OUT;
+			hwif->protocol = ATA_PROT_PIO;
 			command = lba48 ? WIN_WRITE_EXT : WIN_WRITE;
 		}
 
@@ -301,6 +301,7 @@ static u64 idedisk_read_native_max_addre
 	/* Create IDE/ATA command request structure */
 	memset(&args, 0, sizeof(ide_task_t));
 
+	tf->protocol	= ATA_PROT_NODATA;
 	tf->flags	= ATA_TFLAG_OUT_DEVICE | ATA_TFLAG_IN_ADDR;
 	tf->device	= ATA_LBA;
 	if (lba48) {
@@ -311,11 +312,8 @@ static u64 idedisk_read_native_max_addre
 		tf->command = WIN_READ_NATIVE_MAX;
 	}
 
-	args.command_type			= IDE_DRIVE_TASK_NO_DATA;
-	args.handler				= &task_no_data_intr;
-
         /* submit command request */
-	if (ide_raw_taskfile(drive, &args, NULL) == 0) {
+	if (ide_raw_taskfile(drive, &args, 0, NULL) == 0) {
 		/* if OK, compute maximum address value */
 		addr = ide_tf_get_address(drive, tf);
 		addr++;	/* since the return value is (maxlba - 1), we add 1 */
@@ -337,6 +335,7 @@ static u64 idedisk_set_max_address(ide_d
 	/* Create IDE/ATA command request structure */
 	memset(&args, 0, sizeof(ide_task_t));
 
+	tf->protocol	= ATA_PROT_NODATA;
 	tf->flags	= ATA_TFLAG_OUT_DEVICE | ATA_TFLAG_ISADDR;
 	tf->device	= ATA_LBA;
 	tf->lbal	= addr_req;
@@ -354,11 +353,8 @@ static u64 idedisk_set_max_address(ide_d
 		tf->command	= WIN_SET_MAX;
 	}
 
-	args.command_type			= IDE_DRIVE_TASK_NO_DATA;
-	args.handler				= &task_no_data_intr;
-
 	/* submit command request */
-	if (ide_raw_taskfile(drive, &args, NULL) == 0) {
+	if (ide_raw_taskfile(drive, &args, 0, NULL) == 0) {
 		addr_set = ide_tf_get_address(drive, tf);
 		addr_set++;
 	}
@@ -474,15 +470,14 @@ static int smart_enable(ide_drive_t *dri
 
 	memset(&args, 0, sizeof(ide_task_t));
 
+	tf->protocol	= ATA_PROT_NODATA;
 	tf->flags	= ATA_TFLAG_OUT_ADDR;
 	tf->feature	= SMART_ENABLE;
 	tf->lbam	= SMART_LCYL_PASS;
 	tf->lbah	= SMART_HCYL_PASS;
 	tf->command	= WIN_SMART;
 
-	args.command_type			= IDE_DRIVE_TASK_NO_DATA;
-	args.handler				= &task_no_data_intr;
-	return ide_raw_taskfile(drive, &args, NULL);
+	return ide_raw_taskfile(drive, &args, 0, NULL);
 }
 
 static int get_smart_values(ide_drive_t *drive, u8 *buf)
@@ -490,8 +485,11 @@ static int get_smart_values(ide_drive_t 
 	ide_task_t args;
 	struct ata_taskfile *tf = &args.tf;
 
+	smart_enable(drive);
+
 	memset(&args, 0, sizeof(ide_task_t));
 
+	tf->protocol	= ATA_PROT_PIO;
 	tf->flags	= ATA_TFLAG_OUT_ADDR;
 	tf->feature	= SMART_READ_VALUES;
 	tf->nsect	= 1;
@@ -499,11 +497,7 @@ static int get_smart_values(ide_drive_t 
 	tf->lbah	= SMART_HCYL_PASS;
 	tf->command	= WIN_SMART;
 
-	args.command_type			= IDE_DRIVE_TASK_IN;
-	args.data_phase				= TASKFILE_IN;
-	args.handler				= &task_in_intr;
-	(void) smart_enable(drive);
-	return ide_raw_taskfile(drive, &args, buf);
+	return ide_raw_taskfile(drive, &args, READ, buf);
 }
 
 static int get_smart_thresholds(ide_drive_t *drive, u8 *buf)
@@ -511,8 +505,11 @@ static int get_smart_thresholds(ide_driv
 	ide_task_t args;
 	struct ata_taskfile *tf = &args.tf;
 
+	smart_enable(drive);
+
 	memset(&args, 0, sizeof(ide_task_t));
 
+	tf->protocol	= ATA_PROT_PIO;
 	tf->flags	= ATA_TFLAG_OUT_ADDR;
 	tf->feature	= SMART_READ_THRESHOLDS;
 	tf->nsect	= 1;
@@ -520,11 +517,7 @@ static int get_smart_thresholds(ide_driv
 	tf->lbah	= SMART_HCYL_PASS;
 	tf->command	= WIN_SMART;
 
-	args.command_type			= IDE_DRIVE_TASK_IN;
-	args.data_phase				= TASKFILE_IN;
-	args.handler				= &task_in_intr;
-	(void) smart_enable(drive);
-	return ide_raw_taskfile(drive, &args, buf);
+	return ide_raw_taskfile(drive, &args, READ, buf);
 }
 
 static int proc_idedisk_read_cache
@@ -673,13 +666,11 @@ static int write_cache(ide_drive_t *driv
 
 	memset(&args, 0, sizeof(ide_task_t));
 
-	tf->feature = arg ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
-	tf->command = WIN_SETFEATURES;
-
-	args.command_type			= IDE_DRIVE_TASK_NO_DATA;
-	args.handler				= &task_no_data_intr;
+	tf->protocol	= ATA_PROT_NODATA;
+	tf->feature	= arg ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
+	tf->command	= WIN_SETFEATURES;
 
-	err = ide_raw_taskfile(drive, &args, NULL);
+	err = ide_raw_taskfile(drive, &args, 0, NULL);
 	if (err)
 		return err;
 
@@ -694,14 +685,13 @@ static int set_acoustic (ide_drive_t *dr
 
 	memset(&args, 0, sizeof(ide_task_t));
 
+	tf->protocol	= ATA_PROT_NODATA;
 	tf->feature	= arg ? SETFEATURES_EN_AAM : SETFEATURES_DIS_AAM;
 	tf->nsect	= arg;
 	tf->command	= WIN_SETFEATURES;
 
-	args.command_type = IDE_DRIVE_TASK_NO_DATA;
-	args.handler	  = &task_no_data_intr;
-	ide_raw_taskfile(drive, &args, NULL);
 	drive->acoustic = arg;
+
 	return 0;
 }
 
@@ -884,7 +874,7 @@ static void ide_cacheflush_p(ide_drive_t
 
 	ide_task_init_flush(drive, &task);
 
-	if (ide_raw_taskfile(drive, &task, NULL))
+	if (ide_raw_taskfile(drive, &task, 0, NULL))
 		printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
 }
 
@@ -984,16 +974,15 @@ static int idedisk_open(struct inode *in
 	if (drive->removable && drive->usage == 1) {
 		ide_task_t args;
 		memset(&args, 0, sizeof(ide_task_t));
+		args.tf.protocol = ATA_PROT_NODATA;
 		args.tf.command = WIN_DOORLOCK;
-		args.command_type = IDE_DRIVE_TASK_NO_DATA;
-		args.handler	  = &task_no_data_intr;
 		check_disk_change(inode->i_bdev);
 		/*
 		 * Ignore the return code from door_lock,
 		 * since the open() has already succeeded,
 		 * and the door_lock is irrelevant at this point.
 		 */
-		if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL))
+		if (drive->doorlocking && ide_raw_taskfile(drive, &args, 0, NULL))
 			drive->doorlocking = 0;
 	}
 	return 0;
@@ -1010,10 +999,9 @@ static int idedisk_release(struct inode 
 	if (drive->removable && drive->usage == 1) {
 		ide_task_t args;
 		memset(&args, 0, sizeof(ide_task_t));
+		args.tf.protocol = ATA_PROT_NODATA;
 		args.tf.command = WIN_DOORUNLOCK;
-		args.command_type = IDE_DRIVE_TASK_NO_DATA;
-		args.handler	  = &task_no_data_intr;
-		if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL))
+		if (drive->doorlocking && ide_raw_taskfile(drive, &args, 0, NULL))
 			drive->doorlocking = 0;
 	}
 	drive->usage--;
Index: linux-taskfile-ng/drivers/ide/ide-io.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-io.c	2005-03-05 10:46:59.084957020 +0900
+++ linux-taskfile-ng/drivers/ide/ide-io.c	2005-03-05 10:46:59.685863080 +0900
@@ -61,6 +61,7 @@ void ide_task_init_flush(ide_drive_t *dr
 
 	memset(task, 0, sizeof(*task));
 
+	tf->protocol = ATA_PROT_NODATA;
 	tf->flags = ATA_TFLAG_IN_ADDR | ATA_TFLAG_IN_DEVICE;
 
 	if (ide_id_has_flush_cache_ext(drive->id) &&
@@ -69,9 +70,6 @@ void ide_task_init_flush(ide_drive_t *dr
 		tf->flags |= ATA_TFLAG_IN_LBA48;
 	} else
 		tf->command = WIN_FLUSH_CACHE;
-
-	task->command_type = IDE_DRIVE_TASK_NO_DATA;
-	task->handler	   = &task_no_data_intr;
 }
 
 EXPORT_SYMBOL_GPL(ide_task_init_flush);
@@ -261,17 +259,13 @@ static ide_startstop_t ide_start_power_s
 		return do_rw_taskfile(drive, args);
 
 	case idedisk_pm_standby:	/* Suspend step 2 (standby) */
+		tf->protocol = ATA_PROT_NODATA;
 		tf->command = WIN_STANDBYNOW1;
-
-		args->command_type = IDE_DRIVE_TASK_NO_DATA;
-		args->handler	   = &task_no_data_intr;
 		return do_rw_taskfile(drive, args);
 
 	case idedisk_pm_idle:		/* Resume step 1 (idle) */
+		tf->protocol = ATA_PROT_NODATA;
 		tf->command = WIN_IDLEIMMEDIATE;
-
-		args->command_type = IDE_DRIVE_TASK_NO_DATA;
-		args->handler = task_no_data_intr;
 		return do_rw_taskfile(drive, args);
 
 	case ide_pm_restore_dma:	/* Resume step 2 (restore DMA) */
@@ -755,6 +749,7 @@ static void ide_init_specify_cmd(ide_dri
 {
 	struct ata_taskfile *tf = &task->tf;
 
+	tf->protocol	= ATA_PROT_NODATA;
 	tf->flags	= ATA_TFLAG_OUT_ADDR | ATA_TFLAG_OUT_DEVICE;
 	tf->nsect	= drive->sect;
 	tf->lbal	= drive->sect;
@@ -770,6 +765,7 @@ static void ide_init_restore_cmd(ide_dri
 {
 	struct ata_taskfile *tf = &task->tf;
 
+	tf->protocol	= ATA_PROT_NODATA;
 	tf->flags	= ATA_TFLAG_OUT_ADDR;
 	tf->nsect	= drive->sect;
 	tf->command	= WIN_RESTORE;
@@ -781,6 +777,7 @@ static void ide_init_setmult_cmd(ide_dri
 {
 	struct ata_taskfile *tf = &task->tf;
 
+	tf->protocol	= ATA_PROT_NODATA;
 	tf->flags	= ATA_TFLAG_OUT_ADDR;
 	tf->nsect	= drive->mult_req;
 	tf->command	= WIN_SETMULT;
@@ -794,7 +791,6 @@ static ide_startstop_t ide_disk_special(
 	ide_task_t args;
 
 	memset(&args, 0, sizeof(ide_task_t));
-	args.command_type = IDE_DRIVE_TASK_NO_DATA;
 
 	if (s->b.set_geometry) {
 		s->b.set_geometry = 0;
@@ -900,19 +896,6 @@ static ide_startstop_t execute_drive_cmd
 		if (!args)
 			goto done;
 
-		hwif->data_phase = args->data_phase;
-
-		switch (hwif->data_phase) {
-		case TASKFILE_MULTI_OUT:
-		case TASKFILE_OUT:
-		case TASKFILE_MULTI_IN:
-		case TASKFILE_IN:
-			ide_init_sg_cmd(drive, rq);
-			ide_map_sg(drive, rq);
-		default:
-			break;
-		}
-
 		return do_rw_taskfile(drive, args);
 	} else if (rq->flags & REQ_DRIVE_CMD) {
 		u8 *args = rq->buffer;
Index: linux-taskfile-ng/drivers/ide/ide-taskfile.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-taskfile.c	2005-03-05 10:46:59.092955770 +0900
+++ linux-taskfile-ng/drivers/ide/ide-taskfile.c	2005-03-05 10:46:59.686862923 +0900
@@ -6,25 +6,6 @@
  *  Copyright (C) 2001-2002	Klaus Smolin
  *					IBM Storage Technology Division
  *  Copyright (C) 2003-2004	Bartlomiej Zolnierkiewicz
- *
- *  The big the bad and the ugly.
- *
- *  Problems to be fixed because of BH interface or the lack therefore.
- *
- *  Fill me in stupid !!!
- *
- *  HOST:
- *	General refers to the Controller and Driver "pair".
- *  DATA HANDLER:
- *	Under the context of Linux it generally refers to an interrupt handler.
- *	However, it correctly describes the 'HOST'
- *  DATA BLOCK:
- *	The amount of data needed to be transfered as predefined in the
- *	setup of the device.
- *  STORAGE ATOMIC:
- *	The 'DATA BLOCK' associated to the 'DATA HANDLER', and can be as
- *	small as a single sector or as large as the entire command block
- *	request.
  */
 
 #include <linux/config.h>
@@ -174,29 +155,44 @@ int taskfile_lib_get_identify (ide_drive
 
 	memset(&args, 0, sizeof(ide_task_t));
 
+	tf->protocol = ATA_PROT_PIO;
 	tf->nsect = 1;
 	if (drive->media == ide_disk)
 		tf->command = WIN_IDENTIFY;
 	else
 		tf->command = WIN_PIDENTIFY;
 
-	args.command_type = IDE_DRIVE_TASK_IN;
-	args.data_phase   = TASKFILE_IN;
-	args.handler	  = &task_in_intr;
-	return ide_raw_taskfile(drive, &args, buf);
+	return ide_raw_taskfile(drive, &args, READ, buf);
+}
+
+static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
+{
+	ide_task_t *args	= HWGROUP(drive)->rq->special;
+	ide_hwif_t *hwif	= HWIF(drive);
+	u8 stat;
+
+	local_irq_enable();
+	if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) {
+		return ide_error(drive, "task_no_data_intr", stat);
+		/* calls ide_end_drive_cmd */
+	}
+	if (args)
+		ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
+
+	return ide_stopped;
 }
 
 ide_startstop_t do_rw_taskfile(ide_drive_t *drive, ide_task_t *task)
 {
 	ide_hwif_t *hwif = drive->hwif;
+	struct request *rq = hwif->hwgroup->rq;
 	struct ata_taskfile *tf = &task->tf;
+	ide_handler_t *handler = NULL; /* shut up, gcc */
 
 	/* We check this in ide_taskfile_ioctl(), but the setting could
 	   have been changed inbetween. */
-	if ((task->data_phase == TASKFILE_MULTI_IN ||
-	     task->data_phase == TASKFILE_MULTI_OUT) && !drive->mult_count) {
-		printk(KERN_ERR "%s: multimode not set!\n",
-		       drive->name);
+	if (tf->protocol == ATA_PROT_PIO_MULT && !drive->mult_count) {
+		printk(KERN_ERR "%s: multimode not set!\n", drive->name);
 		/* FIXME: this path is an infinite loop. */
 		return ide_stopped;
 	}
@@ -210,22 +206,24 @@ ide_startstop_t do_rw_taskfile(ide_drive
 		tf->device |= drive->select.all & ~ATA_LBA;
 	ide_load_taskfile(drive, task);
 
-	if (task->handler != NULL) {
-		if (task->prehandler != NULL) {
+	hwif->protocol = tf->protocol;
+
+	switch (tf->protocol) {
+	case ATA_PROT_NODATA:
+		handler = task->handler ?: task_no_data_intr;
+		break;
+	case ATA_PROT_PIO:
+	case ATA_PROT_PIO_MULT:
+		ide_init_sg_cmd(drive, rq);
+		ide_map_sg(drive, rq);
+		if (rq_data_dir(rq) == WRITE) {
 			hwif->OUTBSYNC(drive, tf->command, IDE_COMMAND_REG);
 			ndelay(400);	/* FIXME */
-			return task->prehandler(drive, task->rq);
-		}
-		ide_execute_command(drive, tf->command, task->handler,
-				    WAIT_WORSTCASE, NULL);
-		return ide_started;
-	}
-
-	switch (task->data_phase) {
-	case TASKFILE_OUT_DMAQ:
-	case TASKFILE_OUT_DMA:
-	case TASKFILE_IN_DMAQ:
-	case TASKFILE_IN_DMA:
+			return pre_task_out_intr(drive, rq);
+		} else
+			handler = task_in_intr;
+		break;
+	case ATA_PROT_DMA:
 		if (!hwif->dma_setup(drive)) {
 			hwif->dma_exec_cmd(drive, tf->command);
 			hwif->dma_start(drive);
@@ -233,8 +231,12 @@ ide_startstop_t do_rw_taskfile(ide_drive
 		}
 		return ide_stopped;
 	default:
-		return ide_stopped;
+		BUG();
 	}
+
+	ide_execute_command(drive, tf->command, handler, WAIT_WORSTCASE, NULL);
+
+	return ide_started;
 }
 
 EXPORT_SYMBOL(do_rw_taskfile);
@@ -294,28 +296,6 @@ ide_startstop_t recal_intr (ide_drive_t 
 	return ide_stopped;
 }
 
-/*
- * Handler for commands without a data phase
- */
-ide_startstop_t task_no_data_intr(ide_drive_t *drive)
-{
-	ide_task_t *args	= HWGROUP(drive)->rq->special;
-	ide_hwif_t *hwif	= HWIF(drive);
-	u8 stat;
-
-	local_irq_enable();
-	if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) {
-		return ide_error(drive, "task_no_data_intr", stat);
-		/* calls ide_end_drive_cmd */
-	}
-	if (args)
-		ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
-
-	return ide_stopped;
-}
-
-EXPORT_SYMBOL(task_no_data_intr);
-
 static u8 wait_drive_not_busy(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
@@ -403,15 +383,10 @@ static inline void ide_pio_datablock(ide
 			drive->io_32bit = 0;
 	}
 
-	switch (drive->hwif->data_phase) {
-	case TASKFILE_MULTI_IN:
-	case TASKFILE_MULTI_OUT:
+	if (drive->hwif->protocol == ATA_PROT_PIO_MULT)
 		ide_pio_multi(drive, write);
-		break;
-	default:
+	else
 		ide_pio_sector(drive, write);
-		break;
-	}
 
 	drive->io_32bit = saved_io_32bit;
 }
@@ -423,22 +398,12 @@ static ide_startstop_t task_error(ide_dr
 		ide_hwif_t *hwif = drive->hwif;
 		int sectors = hwif->nsect - hwif->nleft;
 
-		switch (hwif->data_phase) {
-		case TASKFILE_IN:
-			if (hwif->nleft)
-				break;
-			/* fall through */
-		case TASKFILE_OUT:
-			sectors--;
-			break;
-		case TASKFILE_MULTI_IN:
-			if (hwif->nleft)
-				break;
-			/* fall through */
-		case TASKFILE_MULTI_OUT:
-			sectors -= drive->mult_count;
-		default:
-			break;
+		if (hwif->protocol == ATA_PROT_PIO) {
+			if (rq_data_dir(rq) == WRITE || hwif->nleft == 0)
+				sectors--;
+		} else {
+			if (rq_data_dir(rq) == WRITE || hwif->nleft == 0)
+				sectors -= drive->mult_count;
 		}
 
 		if (sectors > 0) {
@@ -534,9 +499,9 @@ ide_startstop_t pre_task_out_intr (ide_d
 	if (ide_wait_stat(&startstop, drive, DATA_READY,
 			  drive->bad_wstat, WAIT_DRQ)) {
 		printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
-				drive->name,
-				drive->hwif->data_phase ? "MULT" : "",
-				drive->addressing ? "_EXT" : "");
+		       drive->name,
+		       drive->hwif->protocol == ATA_PROT_PIO_MULT ? "MULT" : "",
+		       drive->addressing ? "_EXT" : "");
 		return startstop;
 	}
 
@@ -550,7 +515,8 @@ ide_startstop_t pre_task_out_intr (ide_d
 }
 EXPORT_SYMBOL(pre_task_out_intr);
 
-static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long data_size, u8 *buf)
+static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args,
+			     int rw, unsigned long data_size, u8 *buf)
 {
 	struct request rq;
 
@@ -564,7 +530,7 @@ static int ide_diag_taskfile(ide_drive_t
 	 * if we would find a solution to transfer any size.
 	 * To support special commands like READ LONG.
 	 */
-	if (args->command_type != IDE_DRIVE_TASK_NO_DATA) {
+	if (args->tf.protocol != ATA_PROT_NODATA) {
 		if (data_size == 0)
 			rq.nr_sectors = (args->tf.hob_nsect << 8) | args->tf.nsect;
 		else
@@ -579,7 +545,7 @@ static int ide_diag_taskfile(ide_drive_t
 		rq.hard_nr_sectors = rq.nr_sectors;
 		rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors;
 
-		if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
+		if (rw == WRITE)
 			rq.flags |= REQ_RW;
 	}
 
@@ -587,14 +553,14 @@ static int ide_diag_taskfile(ide_drive_t
 	return ide_do_drive_cmd(drive, &rq, ide_wait);
 }
 
-int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, u8 *buf)
+int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, int rw, u8 *buf)
 {
-	return ide_diag_taskfile(drive, args, 0, buf);
+	return ide_diag_taskfile(drive, args, rw, 0, buf);
 }
 
 EXPORT_SYMBOL(ide_raw_taskfile);
 
-int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
+int ide_taskfile_ioctl(ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 {
 	ide_task_request_t	*req_task;
 	ide_task_t		args;
@@ -607,8 +573,6 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 	int taskout		= 0;
 	char __user *buf = (char __user *)arg;
 
-//	printk("IDE Taskfile ...\n");
-
 	req_task = kmalloc(tasksize, GFP_KERNEL);
 	if (req_task == NULL) return -ENOMEM;
 	memset(req_task, 0, tasksize);
@@ -716,54 +680,47 @@ int ide_taskfile_ioctl (ide_drive_t *dri
 
 	tf->flags |= ATA_TFLAG_IO_16BIT;
 
-	args.data_phase   = req_task->data_phase;
-	args.command_type = req_task->req_cmd;
+	if ((req_task->data_phase == TASKFILE_MULTI_IN ||
+	     req_task->data_phase == TASKFILE_MULTI_OUT) && !drive->mult_count) {
+		printk(KERN_ERR "%s: multimode not set!\n", drive->name);
+		err = -EPERM;
+		goto abort;
+	}
 
-	switch(req_task->data_phase) {
-		case TASKFILE_OUT_DMAQ:
-		case TASKFILE_OUT_DMA:
-			err = ide_diag_taskfile(drive, &args, taskout, outbuf);
-			break;
-		case TASKFILE_IN_DMAQ:
-		case TASKFILE_IN_DMA:
-			err = ide_diag_taskfile(drive, &args, taskin, inbuf);
-			break;
-		case TASKFILE_MULTI_OUT:
-			if (!drive->mult_count) {
-				/* (hs): give up if multcount is not set */
-				printk(KERN_ERR "%s: %s Multimode Write " \
-					"multcount is not set\n",
-					drive->name, __FUNCTION__);
-				err = -EPERM;
-				goto abort;
-			}
-			/* fall through */
-		case TASKFILE_OUT:
-			args.prehandler = &pre_task_out_intr;
-			args.handler = &task_out_intr;
-			err = ide_diag_taskfile(drive, &args, taskout, outbuf);
-			break;
-		case TASKFILE_MULTI_IN:
-			if (!drive->mult_count) {
-				/* (hs): give up if multcount is not set */
-				printk(KERN_ERR "%s: %s Multimode Read failure " \
-					"multcount is not set\n",
-					drive->name, __FUNCTION__);
-				err = -EPERM;
-				goto abort;
-			}
-			/* fall through */
-		case TASKFILE_IN:
-			args.handler = &task_in_intr;
-			err = ide_diag_taskfile(drive, &args, taskin, inbuf);
-			break;
-		case TASKFILE_NO_DATA:
-			args.handler = &task_no_data_intr;
-			err = ide_diag_taskfile(drive, &args, 0, NULL);
-			break;
-		default:
-			err = -EFAULT;
-			goto abort;
+	switch (req_task->data_phase) {
+	case TASKFILE_NO_DATA:
+		tf->protocol = ATA_PROT_NODATA;
+		err = ide_diag_taskfile(drive, &args, 0, 0, NULL);
+		break;
+	case TASKFILE_IN:
+		tf->protocol = ATA_PROT_PIO;
+		err = ide_diag_taskfile(drive, &args, READ, taskin, inbuf);
+		break;
+	case TASKFILE_OUT:
+		tf->protocol = ATA_PROT_PIO;
+		err = ide_diag_taskfile(drive, &args, WRITE, taskout, outbuf);
+		break;
+	case TASKFILE_MULTI_IN:
+		tf->protocol = ATA_PROT_PIO_MULT;
+		err = ide_diag_taskfile(drive, &args, READ, taskin, inbuf);
+		break;
+	case TASKFILE_MULTI_OUT:
+		tf->protocol = ATA_PROT_PIO_MULT;
+		err = ide_diag_taskfile(drive, &args, WRITE, taskout, outbuf);
+		break;
+	case TASKFILE_IN_DMAQ:
+	case TASKFILE_IN_DMA:
+		tf->protocol = ATA_PROT_DMA;
+		err = ide_diag_taskfile(drive, &args, READ, taskin, inbuf);
+		break;
+	case TASKFILE_OUT_DMAQ:
+	case TASKFILE_OUT_DMA:
+		tf->protocol = ATA_PROT_DMA;
+		err = ide_diag_taskfile(drive, &args, WRITE, taskout, outbuf);
+		break;
+	default:
+		err = -EFAULT;	/* FIXME: -EFAULT? really? */
+		goto abort;
 	}
 
 	if (req_task->data_phase == TASKFILE_NO_DATA ||
@@ -810,9 +767,6 @@ abort:
 		kfree(outbuf);
 	if (inbuf != NULL)
 		kfree(inbuf);
-
-//	printk("IDE Taskfile ioctl ended. rc = %i\n", err);
-
 	return err;
 }
 
@@ -901,6 +855,7 @@ int ide_task_ioctl(ide_drive_t *drive, u
 
 	memset(&task, 0, sizeof(task));
 
+	tf->protocol	= ATA_PROT_NODATA;
 	tf->flags	= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
 
 	tf->command	= args[0];
@@ -911,11 +866,7 @@ int ide_task_ioctl(ide_drive_t *drive, u
 	tf->lbah	= args[5];
 	tf->device	= args[6] & ~ATA_DEV1;
 
-	task.command_type = IDE_DRIVE_TASK_NO_DATA;
-	task.data_phase = TASKFILE_NO_DATA;
-	task.handler = &task_no_data_intr;
-
-	err = ide_diag_taskfile(drive, &task, 0, NULL);
+	err = ide_diag_taskfile(drive, &task, 0, 0, NULL);
 
 	args[0] = tf->command;
 	args[1] = tf->feature;
Index: linux-taskfile-ng/include/linux/ide.h
===================================================================
--- linux-taskfile-ng.orig/include/linux/ide.h	2005-03-05 10:46:59.483894654 +0900
+++ linux-taskfile-ng/include/linux/ide.h	2005-03-05 10:46:59.687862767 +0900
@@ -867,8 +867,8 @@ typedef struct hwif_s {
 	int sg_nents;			/* Current number of entries in it */
 	int sg_dma_direction;		/* dma transfer direction */
 
-	/* data phase of the active command (currently only valid for PIO/DMA) */
-	int		data_phase;
+	/* protocol of the active command */
+	int		protocol;
 
 	unsigned int nsect;
 	unsigned int nleft;
@@ -928,11 +928,7 @@ typedef struct ide_task_s {
 	u16			data;
 	unsigned		load_data:1;
 	unsigned		read_data:1;
-	int			data_phase;
-	int			command_type;
-	ide_pre_handler_t	*prehandler;
 	ide_handler_t		*handler;
-	struct request		*rq;		/* copy of request */
 } ide_task_t;
 
 typedef struct hwgroup_s {
@@ -1288,11 +1284,10 @@ void task_end_request(ide_drive_t *drive
 extern ide_startstop_t set_multmode_intr(ide_drive_t *);
 extern ide_startstop_t set_geometry_intr(ide_drive_t *);
 extern ide_startstop_t recal_intr(ide_drive_t *);
-extern ide_startstop_t task_no_data_intr(ide_drive_t *);
 extern ide_startstop_t task_in_intr(ide_drive_t *);
 extern ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *);
 
-extern int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *);
+extern int ide_raw_taskfile(ide_drive_t *, ide_task_t *, int, u8 *);
 
 int ide_taskfile_ioctl(ide_drive_t *, unsigned int, unsigned long);
 int ide_cmd_ioctl(ide_drive_t *, unsigned int, unsigned long);

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2.6.11-rc3 06/08] ide: convert set_xfer_rate() to use taskfile ioctl
  2005-03-05  1:47 [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup Tejun Heo
                   ` (4 preceding siblings ...)
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 05/08] ide: use ide_task_t->tf.protocol instead of ide_task_t->data_phase Tejun Heo
@ 2005-03-05  1:48 ` Tejun Heo
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 07/08] ide: reimplement ide_cmd_ioctl() using taskfile Tejun Heo
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: Tejun Heo @ 2005-03-05  1:48 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, lkml, linux-ide, Jeff Garzik


06_ide_taskfile_set_xfer_rate.patch

	Convert set_xfer_rate() to use taskfile ioctl.

Signed-off-by: Tejun Heo <htejun@gmail.com>

 ide.c |   15 ++++++++++++---
 1 files changed, 12 insertions(+), 3 deletions(-)

Index: linux-taskfile-ng/drivers/ide/ide.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide.c	2005-03-05 10:37:51.451393268 +0900
+++ linux-taskfile-ng/drivers/ide/ide.c	2005-03-05 10:46:59.933824315 +0900
@@ -1250,10 +1250,19 @@ static int set_pio_mode (ide_drive_t *dr
 
 static int set_xfer_rate (ide_drive_t *drive, int arg)
 {
-	int err = ide_wait_cmd(drive,
-			WIN_SETFEATURES, (u8) arg,
-			SETFEATURES_XFER, 0, NULL);
+	ide_task_t task;
+	struct ata_taskfile *tf = &task.tf;
+	int err;
+
+	memset(&task, 0, sizeof(task));
+
+	tf->protocol	= ATA_PROT_NODATA;
+	tf->flags	= ATA_TFLAG_OUT_ADDR;
+	tf->feature	= SETFEATURES_XFER;
+	tf->nsect	= arg;
+	tf->command	= WIN_SETFEATURES;
 
+	err = ide_raw_taskfile(drive, &task, 0, NULL);
 	if (!err && arg) {
 		ide_set_xfer_rate(drive, (u8) arg);
 		ide_driveid_update(drive);

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2.6.11-rc3 07/08] ide: reimplement ide_cmd_ioctl() using taskfile
  2005-03-05  1:47 [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup Tejun Heo
                   ` (5 preceding siblings ...)
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 06/08] ide: convert set_xfer_rate() to use taskfile ioctl Tejun Heo
@ 2005-03-05  1:48 ` Tejun Heo
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 08/08] ide: remove REQ_DRIVE_CMD handling Tejun Heo
  2005-03-05  1:56 ` [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup Tejun Heo
  8 siblings, 0 replies; 10+ messages in thread
From: Tejun Heo @ 2005-03-05  1:48 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, lkml, linux-ide, Jeff Garzik


07_ide_taskfile_cmd_ioctl.patch

	Reimplement ide_cmd_ioctl() using taskfile.

Signed-off-by: Tejun Heo <htejun@gmail.com>

 drivers/ide/ide-taskfile.c |  105 +++++++++++++++++++++++++--------------------
 include/linux/ide.h        |    8 ---
 2 files changed, 60 insertions(+), 53 deletions(-)

Index: linux-taskfile-ng/drivers/ide/ide-taskfile.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-taskfile.c	2005-03-05 10:46:59.686862923 +0900
+++ linux-taskfile-ng/drivers/ide/ide-taskfile.c	2005-03-05 10:47:00.116795711 +0900
@@ -770,75 +770,90 @@ abort:
 	return err;
 }
 
-int ide_wait_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
+int ide_cmd_ioctl(ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 {
-	struct request rq;
-	u8 buffer[4];
-
-	if (!buf)
-		buf = buffer;
-	memset(buf, 0, 4 + SECTOR_WORDS * 4 * sectors);
-	ide_init_drive_cmd(&rq);
-	rq.buffer = buf;
-	*buf++ = cmd;
-	*buf++ = nsect;
-	*buf++ = feature;
-	*buf++ = sectors;
-	return ide_do_drive_cmd(drive, &rq, ide_wait);
-}
-
-/*
- * FIXME : this needs to map into at taskfile. <andre@linux-ide.org>
- */
-int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
-{
-	int err = 0;
-	u8 args[4], *argbuf = args;
-	u8 xfer_rate = 0;
-	int argsize = 4;
-	ide_task_t tfargs;
-	struct ata_taskfile *tf = &tfargs.tf;
+	void __user *p = (void __user *)arg;
+	u8 args[4];
+	ide_task_t task;
+	struct ata_taskfile *tf = &task.tf;
+	void *buf = NULL;
+	int xfer_rate = 0, in_size, err;
 
-	if (NULL == (void *) arg) {
+	if (p == NULL) {
 		struct request rq;
 		ide_init_drive_cmd(&rq);
 		return ide_do_drive_cmd(drive, &rq, ide_wait);
 	}
 
-	if (copy_from_user(args, (void __user *)arg, 4))
+	if (copy_from_user(args, p, 4))
 		return -EFAULT;
 
-	memset(&tfargs, 0, sizeof(ide_task_t));
+	memset(&task, 0, sizeof(task));
+
+	/*
+	 * Due to a bug in the original code, args[1] was not loaded
+	 * into lbal but instead loaded into nsect except for
+	 * WIN_SMART.  IOW, args[3] was used for sector count to setup
+	 * the command but it was args[1] which actually got into the
+	 * nsect register.
+	 *
+	 * Another problem is that lbal is used in the
+	 * WIN_SETFEATURES/SETFEATURES_XFER command.  The original
+	 * code worked because ide_set_xfer_rate() issued the command
+	 * again with correct registers loaded.
+	 *
+	 * So, here, we load args[1] for WIN_SMART and
+	 * SETFEATURES_XFER; otherwise, we ignore args[1].
+	 */
+	tf->flags	= ATA_TFLAG_OUT_FEATURE	| ATA_TFLAG_IN_FEATURE	|
+			  ATA_TFLAG_OUT_NSECT	| ATA_TFLAG_IN_NSECT	|
+			  ATA_TFLAG_IO_16BIT;
 	tf->feature	= args[2];
 	tf->nsect	= args[3];
 	tf->lbal	= args[1];
 	tf->command	= args[0];
 
-	if (args[3]) {
-		argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
-		argbuf = kmalloc(argsize, GFP_KERNEL);
-		if (argbuf == NULL)
-			return -ENOMEM;
-		memcpy(argbuf, args, 4);
+	if (set_transfer(drive, &task)) {
+		tf->flags	|= ATA_TFLAG_OUT_LBAL;
+		xfer_rate	= args[1];
+		if (ide_ata66_check(drive, &task))
+			return -EIO;
 	}
-	if (set_transfer(drive, &tfargs)) {
-		xfer_rate = args[1];
-		if (ide_ata66_check(drive, &tfargs))
-			goto abort;
+
+	/* SMART needs its secret keys in lcyl and hcyl registers. */
+	if (tf->command == WIN_SMART) {
+		tf->flags	|= ATA_TFLAG_OUT_LBAL | ATA_TFLAG_OUT_LBAM |
+				   ATA_TFLAG_OUT_LBAH;
+		tf->lbam	= SMART_LCYL_PASS;
+		tf->lbah	= SMART_HCYL_PASS;
 	}
 
-	err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf);
+	in_size = 4 * SECTOR_WORDS * args[3];
+
+	if (in_size) {
+		tf->protocol	= ATA_PROT_PIO;
+		if ((buf = kmalloc(in_size, GFP_KERNEL)) == NULL)
+			return -ENOMEM;
+		memset(buf, 0, in_size);	/* paranoia */
+	} else
+		tf->protocol	= ATA_PROT_NODATA;
+
+	err = ide_diag_taskfile(drive, &task, READ, in_size, buf);
 
 	if (!err && xfer_rate) {
 		/* active-retuning-calls future */
 		ide_set_xfer_rate(drive, xfer_rate);
 		ide_driveid_update(drive);
 	}
-abort:
-	if (copy_to_user((void __user *)arg, argbuf, argsize))
+
+	args[0] = tf->command;
+	args[1] = tf->feature;
+	args[2] = tf->nsect;
+	args[3] = 0;
+
+	if (copy_to_user(p, args, 4) || copy_to_user(p + 4, buf, in_size))
 		err = -EFAULT;
-	if (argsize > 4)
-		kfree(argbuf);
+	kfree(buf);
 	return err;
 }
 
Index: linux-taskfile-ng/include/linux/ide.h
===================================================================
--- linux-taskfile-ng.orig/include/linux/ide.h	2005-03-05 10:46:59.687862767 +0900
+++ linux-taskfile-ng/include/linux/ide.h	2005-03-05 10:47:00.117795555 +0900
@@ -1251,14 +1251,6 @@ extern int ide_do_drive_cmd(ide_drive_t 
  */
 extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
 
-/*
- * Issue ATA command and wait for completion.
- * Use for implementing commands in kernel
- *
- *  (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *buf)
- */
-extern int ide_wait_cmd(ide_drive_t *, u8, u8, u8, u8, u8 *);
-
 extern u32 ide_read_24(ide_drive_t *);
 
 extern void SELECT_DRIVE(ide_drive_t *);

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2.6.11-rc3 08/08] ide: remove REQ_DRIVE_CMD handling
  2005-03-05  1:47 [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup Tejun Heo
                   ` (6 preceding siblings ...)
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 07/08] ide: reimplement ide_cmd_ioctl() using taskfile Tejun Heo
@ 2005-03-05  1:48 ` Tejun Heo
  2005-03-05  1:56 ` [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup Tejun Heo
  8 siblings, 0 replies; 10+ messages in thread
From: Tejun Heo @ 2005-03-05  1:48 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, lkml, linux-ide, Jeff Garzik


08_ide_remove_REQ_DRIVE_CMD.patch

	Remove REQ_DRIVE_CMD handling.  ide_init_drive_cmd() now
	defaults to REQ_DRIVE_TASKFILE (now the only drive command :-).

Signed-off-by: Tejun Heo <htejun@gmail.com>

 drivers/block/ll_rw_blk.c |    1 
 drivers/ide/ide-disk.c    |    1 
 drivers/ide/ide-io.c      |  132 +++++-----------------------------------------
 drivers/ide/ide-lib.c     |    8 --
 include/linux/blkdev.h    |    2 
 5 files changed, 17 insertions(+), 127 deletions(-)

Index: linux-taskfile-ng/drivers/block/ll_rw_blk.c
===================================================================
--- linux-taskfile-ng.orig/drivers/block/ll_rw_blk.c	2005-03-05 10:37:51.398401518 +0900
+++ linux-taskfile-ng/drivers/block/ll_rw_blk.c	2005-03-05 10:47:00.319763980 +0900
@@ -850,7 +850,6 @@ static char *rq_flags[] = {
 	"REQ_FAILED",
 	"REQ_QUIET",
 	"REQ_SPECIAL",
-	"REQ_DRIVE_CMD",
 	"REQ_DRIVE_TASKFILE",
 	"REQ_PREEMPT",
 	"REQ_PM_SUSPEND",
Index: linux-taskfile-ng/drivers/ide/ide-disk.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-disk.c	2005-03-05 10:46:59.684863236 +0900
+++ linux-taskfile-ng/drivers/ide/ide-disk.c	2005-03-05 10:47:00.319763980 +0900
@@ -638,7 +638,6 @@ static int set_multcount(ide_drive_t *dr
 	if (drive->special.b.set_multmode)
 		return -EBUSY;
 	ide_init_drive_cmd (&rq);
-	rq.flags = REQ_DRIVE_CMD;
 	drive->mult_req = arg;
 	drive->special.b.set_multmode = 1;
 	(void) ide_do_drive_cmd (drive, &rq, ide_wait);
Index: linux-taskfile-ng/drivers/ide/ide-io.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-io.c	2005-03-05 10:46:59.685863080 +0900
+++ linux-taskfile-ng/drivers/ide/ide-io.c	2005-03-05 10:47:00.320763824 +0900
@@ -97,7 +97,7 @@ static struct request *ide_queue_flush_c
 	ide_task_init_flush(drive, task);
 
 	ide_init_drive_cmd(flush_rq);
-	flush_rq->flags = REQ_DRIVE_TASKFILE | REQ_STARTED;
+	flush_rq->flags = REQ_STARTED;
 	flush_rq->nr_sectors = rq->nr_sectors;
 	flush_rq->special = task;
 
@@ -429,7 +429,6 @@ static void ide_complete_barrier(ide_dri
  
 void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
 {
-	ide_hwif_t *hwif = HWIF(drive);
 	unsigned long flags;
 	struct request *rq;
 
@@ -437,17 +436,7 @@ void ide_end_drive_cmd (ide_drive_t *dri
 	rq = HWGROUP(drive)->rq;
 	spin_unlock_irqrestore(&ide_lock, flags);
 
-	if (rq->flags & REQ_DRIVE_CMD) {
-		u8 *args = (u8 *) rq->buffer;
-		if (rq->errors == 0)
-			rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
-
-		if (args) {
-			args[0] = stat;
-			args[1] = err;
-			args[2] = hwif->INB(IDE_NSECTOR_REG);
-		}
-	} else if (rq->flags & REQ_DRIVE_TASKFILE) {
+	if (rq->flags & REQ_DRIVE_TASKFILE) {
 		ide_task_t *args = (ide_task_t *) rq->special;
 		if (rq->errors == 0)
 			rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
@@ -622,7 +611,7 @@ ide_startstop_t ide_error (ide_drive_t *
 		return ide_stopped;
 
 	/* retry only "normal" I/O: */
-	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASKFILE)) {
+	if (rq->flags & REQ_DRIVE_TASKFILE) {
 		rq->errors = 1;
 		ide_end_drive_cmd(drive, stat, err);
 		return ide_stopped;
@@ -673,7 +662,7 @@ ide_startstop_t ide_abort(ide_drive_t *d
 		return ide_stopped;
 
 	/* retry only "normal" I/O: */
-	if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASKFILE)) {
+	if (rq->flags & REQ_DRIVE_TASKFILE) {
 		rq->errors = 1;
 		ide_end_drive_cmd(drive, BUSY_STAT, 0);
 		return ide_stopped;
@@ -688,63 +677,6 @@ ide_startstop_t ide_abort(ide_drive_t *d
 		return __ide_abort(drive, rq);
 }
 
-/**
- *	ide_cmd		-	issue a simple drive command
- *	@drive: drive the command is for
- *	@cmd: command byte
- *	@nsect: sector byte
- *	@handler: handler for the command completion
- *
- *	Issue a simple drive command with interrupts.
- *	The drive must be selected beforehand.
- */
-
-static void ide_cmd (ide_drive_t *drive, u8 cmd, u8 nsect,
-		ide_handler_t *handler)
-{
-	ide_hwif_t *hwif = HWIF(drive);
-	if (IDE_CONTROL_REG)
-		hwif->OUTB(drive->ctl,IDE_CONTROL_REG);	/* clear nIEN */
-	SELECT_MASK(drive,0);
-	hwif->OUTB(nsect,IDE_NSECTOR_REG);
-	ide_execute_command(drive, cmd, handler, WAIT_CMD, NULL);
-}
-
-/**
- *	drive_cmd_intr		- 	drive command completion interrupt
- *	@drive: drive the completion interrupt occurred on
- *
- *	drive_cmd_intr() is invoked on completion of a special DRIVE_CMD.
- *	We do any necessary daya reading and then wait for the drive to
- *	go non busy. At that point we may read the error data and complete
- *	the request
- */
- 
-static ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
-{
-	struct request *rq = HWGROUP(drive)->rq;
-	ide_hwif_t *hwif = HWIF(drive);
-	u8 *args = (u8 *) rq->buffer;
-	u8 stat = hwif->INB(IDE_STATUS_REG);
-	int retries = 10;
-
-	local_irq_enable();
-	if ((stat & DRQ_STAT) && args && args[3]) {
-		u8 io_32bit = drive->io_32bit;
-		drive->io_32bit = 0;
-		hwif->ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS);
-		drive->io_32bit = io_32bit;
-		while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--)
-			udelay(100);
-	}
-
-	if (!OK_STAT(stat, READY_STAT, BAD_STAT))
-		return ide_error(drive, "drive_cmd", stat);
-		/* calls ide_end_drive_cmd */
-	ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG));
-	return ide_stopped;
-}
-
 static void ide_init_specify_cmd(ide_drive_t *drive, ide_task_t *task)
 {
 	struct ata_taskfile *tf = &task->tf;
@@ -886,53 +818,23 @@ EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
  *	all commands to finish. Don't do this as that is due to change
  */
 
-static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
-		struct request *rq)
+static ide_startstop_t execute_drive_cmd(ide_drive_t *drive, struct request *rq)
 {
-	ide_hwif_t *hwif = HWIF(drive);
-	if (rq->flags & REQ_DRIVE_TASKFILE) {
- 		ide_task_t *args = rq->special;
- 
-		if (!args)
-			goto done;
-
-		return do_rw_taskfile(drive, args);
-	} else if (rq->flags & REQ_DRIVE_CMD) {
-		u8 *args = rq->buffer;
+	ide_hwif_t *hwif = drive->hwif;
+	ide_task_t *task = rq->special;
 
-		if (!args)
-			goto done;
-#ifdef DEBUG
- 		printk("%s: DRIVE_CMD ", drive->name);
- 		printk("cmd=0x%02x ", args[0]);
- 		printk("sc=0x%02x ", args[1]);
- 		printk("fr=0x%02x ", args[2]);
- 		printk("xx=0x%02x\n", args[3]);
-#endif
- 		if (args[0] == WIN_SMART) {
- 			hwif->OUTB(0x4f, IDE_LCYL_REG);
- 			hwif->OUTB(0xc2, IDE_HCYL_REG);
- 			hwif->OUTB(args[2],IDE_FEATURE_REG);
- 			hwif->OUTB(args[1],IDE_SECTOR_REG);
- 			ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
- 			return ide_started;
- 		}
- 		hwif->OUTB(args[2],IDE_FEATURE_REG);
- 		ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
- 		return ide_started;
- 	}
+	if (task)
+		return do_rw_taskfile(drive, task);
 
-done:
  	/*
  	 * NULL is actually a valid way of waiting for
  	 * all current requests to be flushed from the queue.
  	 */
-#ifdef DEBUG
- 	printk("%s: DRIVE_CMD (null)\n", drive->name);
-#endif
+
  	ide_end_drive_cmd(drive,
-			hwif->INB(IDE_STATUS_REG),
-			hwif->INB(IDE_ERROR_REG));
+			  hwif->INB(IDE_STATUS_REG),
+			  hwif->INB(IDE_ERROR_REG));
+
  	return ide_stopped;
 }
 
@@ -1010,9 +912,7 @@ static ide_startstop_t start_request (id
 	if (!drive->special.all) {
 		ide_driver_t *drv;
 
-		if (rq->flags & REQ_DRIVE_CMD)
-			return execute_drive_cmd(drive, rq);
-		else if (rq->flags & REQ_DRIVE_TASKFILE)
+		if (rq->flags & REQ_DRIVE_TASKFILE)
 			return execute_drive_cmd(drive, rq);
 		else if (blk_pm_request(rq)) {
 #ifdef DEBUG_PM
@@ -1662,10 +1562,10 @@ irqreturn_t ide_intr (int irq, void *dev
  *	nasty suprise.
  */
 
-void ide_init_drive_cmd (struct request *rq)
+void ide_init_drive_cmd(struct request *rq)
 {
 	memset(rq, 0, sizeof(*rq));
-	rq->flags = REQ_DRIVE_CMD;
+	rq->flags = REQ_DRIVE_TASKFILE;
 	rq->ref_count = 1;
 }
 
Index: linux-taskfile-ng/drivers/ide/ide-lib.c
===================================================================
--- linux-taskfile-ng.orig/drivers/ide/ide-lib.c	2005-03-05 10:37:51.398401518 +0900
+++ linux-taskfile-ng/drivers/ide/ide-lib.c	2005-03-05 10:47:00.321763668 +0900
@@ -458,13 +458,7 @@ static void ide_dump_opcode(ide_drive_t 
 	spin_unlock(&ide_lock);
 	if (!rq)
 		return;
-	if (rq->flags & REQ_DRIVE_CMD) {
-		char *args = rq->buffer;
-		if (args) {
-			opcode = args[0];
-			found = 1;
-		}
-	} else if (rq->flags & REQ_DRIVE_TASKFILE) {
+	if (rq->flags & REQ_DRIVE_TASKFILE) {
 		ide_task_t *args = rq->special;
 		if (args) {
 			opcode = args->tf.command;
Index: linux-taskfile-ng/include/linux/blkdev.h
===================================================================
--- linux-taskfile-ng.orig/include/linux/blkdev.h	2005-03-05 10:37:51.398401518 +0900
+++ linux-taskfile-ng/include/linux/blkdev.h	2005-03-05 10:47:00.321763668 +0900
@@ -201,7 +201,6 @@ enum rq_flag_bits {
 	__REQ_FAILED,		/* set if the request failed */
 	__REQ_QUIET,		/* don't worry about errors */
 	__REQ_SPECIAL,		/* driver suplied command */
-	__REQ_DRIVE_CMD,
 	__REQ_DRIVE_TASKFILE,
 	__REQ_PREEMPT,		/* set for "ide_preempt" requests */
 	__REQ_PM_SUSPEND,	/* suspend request */
@@ -227,7 +226,6 @@ enum rq_flag_bits {
 #define REQ_FAILED	(1 << __REQ_FAILED)
 #define REQ_QUIET	(1 << __REQ_QUIET)
 #define REQ_SPECIAL	(1 << __REQ_SPECIAL)
-#define REQ_DRIVE_CMD	(1 << __REQ_DRIVE_CMD)
 #define REQ_DRIVE_TASKFILE	(1 << __REQ_DRIVE_TASKFILE)
 #define REQ_PREEMPT	(1 << __REQ_PREEMPT)
 #define REQ_PM_SUSPEND	(1 << __REQ_PM_SUSPEND)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup
  2005-03-05  1:47 [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup Tejun Heo
                   ` (7 preceding siblings ...)
  2005-03-05  1:48 ` [PATCH 2.6.11-rc3 08/08] ide: remove REQ_DRIVE_CMD handling Tejun Heo
@ 2005-03-05  1:56 ` Tejun Heo
  8 siblings, 0 replies; 10+ messages in thread
From: Tejun Heo @ 2005-03-05  1:56 UTC (permalink / raw)
  To: Bartlomiej Zolnierkiewicz, lkml, linux-ide, Jeff Garzik

 Oh, all the patches are against ide-dev-t + 9 recent patches +
ide_dma_intr fix.

--
tejun

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2005-03-05  2:23 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-03-05  1:47 [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup Tejun Heo
2005-03-05  1:48 ` [PATCH 2.6.11-rc3 01/08] ide: add individual ATA_TFLAG_{OUT|IN}_* flags Tejun Heo
2005-03-05  1:48 ` [PATCH 2.6.11-rc3 02/08] ide: convert __ide_do_rw_disk() to use ide_load_taskfile() Tejun Heo
2005-03-05  1:48 ` [PATCH 2.6.11-rc3 03/08] ide: remove flagged_taskfile() and unify taskfile paths Tejun Heo
2005-03-05  1:48 ` [PATCH 2.6.11-rc3 04/08] ide: remove unused fields ide_drive_t->rq and ide_task_t->special Tejun Heo
2005-03-05  1:48 ` [PATCH 2.6.11-rc3 05/08] ide: use ide_task_t->tf.protocol instead of ide_task_t->data_phase Tejun Heo
2005-03-05  1:48 ` [PATCH 2.6.11-rc3 06/08] ide: convert set_xfer_rate() to use taskfile ioctl Tejun Heo
2005-03-05  1:48 ` [PATCH 2.6.11-rc3 07/08] ide: reimplement ide_cmd_ioctl() using taskfile Tejun Heo
2005-03-05  1:48 ` [PATCH 2.6.11-rc3 08/08] ide: remove REQ_DRIVE_CMD handling Tejun Heo
2005-03-05  1:56 ` [PATCH 2.6.11-rc3 00/08] ide: taskfile cleanup Tejun Heo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).