* [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 1:56 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.