* [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).