summaryrefslogtreecommitdiff
path: root/drivers/ide/ide-taskfile.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-01-25 22:17:14 +0100
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-01-25 22:17:14 +0100
commitac026ff254b32915bb14ba97a23b4019d137f181 (patch)
treeab5687be210c4016d16fae7a8e51bfc1c41c4c42 /drivers/ide/ide-taskfile.c
parent7299a3918442dc9a5abb71b9f65b1dd17637c8c0 (diff)
ide: remove 'command_type' field from ide_task_t
* Add 'data_buf' and 'nsect' variables in ide_taskfile_ioctl() to cache data buffer pointer and number of sectors to transfer (this allows us to have only one ide_diag_taskfile() call). * Add IDE_TFLAG_WRITE taskfile flag and use it to check whether the REQ_RW request flag should be set. * Move ->command_type handling from ide_diag_taskfile() to ide_taskfile_ioctl() and use ->req_cmd instead of ->command_type. * Add 'nsect' parameter to ide_raw_taskfile(). * Merge ide_diag_taskfile() into ide_raw_taskfile(). * Initialize ->data_phase explicitly in idedisk_prepare_flush(), ide_start_power_step() and ide_disk_special(). * Remove no longer needed 'command_type' field from ide_task_t. * Add #ifndef/#endif __KERNEL__ to <linux/hdreg.h> around no longer used by kernel IDE_DRIVE_TASK_* and TASKFILE_* defines. There should be no functionality changes caused by this patch. Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-taskfile.c')
-rw-r--r--drivers/ide/ide-taskfile.c89
1 files changed, 44 insertions, 45 deletions
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 7c8e9802898a..ff28449bbcaf 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -126,11 +126,10 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
args.tf.command = WIN_IDENTIFY;
else
args.tf.command = WIN_PIDENTIFY;
- args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
- args.command_type = IDE_DRIVE_TASK_IN;
- args.data_phase = TASKFILE_IN;
- args.handler = &task_in_intr;
- return ide_raw_taskfile(drive, &args, buf);
+ args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
+ args.data_phase = TASKFILE_IN;
+ args.handler = task_in_intr;
+ return ide_raw_taskfile(drive, &args, buf, 1);
}
static int inline task_dma_ok(ide_task_t *task)
@@ -499,7 +498,7 @@ ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq)
}
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)
+int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
{
struct request rq;
@@ -514,44 +513,26 @@ static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long
* 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 (data_size == 0)
- rq.nr_sectors = (args->tf.hob_nsect << 8) | args->tf.nsect;
- else
- rq.nr_sectors = data_size / SECTOR_SIZE;
-
- if (!rq.nr_sectors) {
- printk(KERN_ERR "%s: in/out command without data\n",
- drive->name);
- return -EFAULT;
- }
+ rq.hard_nr_sectors = rq.nr_sectors = nsect;
+ rq.hard_cur_sectors = rq.current_nr_sectors = nsect;
- rq.hard_nr_sectors = rq.nr_sectors;
- rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors;
+ if (task->tf_flags & IDE_TFLAG_WRITE)
+ rq.cmd_flags |= REQ_RW;
- if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
- rq.cmd_flags |= REQ_RW;
- }
+ rq.special = task;
+ task->rq = &rq;
- rq.special = args;
- args->rq = &rq;
return ide_do_drive_cmd(drive, &rq, ide_wait);
}
-int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, u8 *buf)
-{
- return ide_diag_taskfile(drive, args, 0, buf);
-}
-
EXPORT_SYMBOL(ide_raw_taskfile);
int ide_no_data_taskfile(ide_drive_t *drive, ide_task_t *task)
{
- task->command_type = IDE_DRIVE_TASK_NO_DATA;
- task->data_phase = TASKFILE_NO_DATA;
- task->handler = task_no_data_intr;
+ task->data_phase = TASKFILE_NO_DATA;
+ task->handler = task_no_data_intr;
- return ide_raw_taskfile(drive, task, NULL);
+ return ide_raw_taskfile(drive, task, NULL, 0);
}
EXPORT_SYMBOL_GPL(ide_no_data_taskfile);
@@ -562,10 +543,12 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
ide_task_t args;
u8 *outbuf = NULL;
u8 *inbuf = NULL;
+ u8 *data_buf = NULL;
int err = 0;
int tasksize = sizeof(struct ide_task_request_s);
unsigned int taskin = 0;
unsigned int taskout = 0;
+ u16 nsect = 0;
u8 io_32bit = drive->io_32bit;
char __user *buf = (char __user *)arg;
@@ -618,7 +601,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
memcpy(&args.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
args.tf_in_flags = req_task->in_flags;
args.data_phase = req_task->data_phase;
- args.command_type = req_task->req_cmd;
args.tf_flags = IDE_TFLAG_OUT_DEVICE;
if (drive->addressing == 1)
@@ -657,14 +639,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
drive->io_32bit = 0;
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 */
@@ -678,7 +652,11 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
case TASKFILE_OUT:
args.prehandler = &pre_task_out_intr;
args.handler = &task_out_intr;
- err = ide_diag_taskfile(drive, &args, taskout, outbuf);
+ /* fall through */
+ case TASKFILE_OUT_DMAQ:
+ case TASKFILE_OUT_DMA:
+ nsect = taskout / SECTOR_SIZE;
+ data_buf = outbuf;
break;
case TASKFILE_MULTI_IN:
if (!drive->mult_count) {
@@ -692,17 +670,38 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
/* fall through */
case TASKFILE_IN:
args.handler = &task_in_intr;
- err = ide_diag_taskfile(drive, &args, taskin, inbuf);
+ /* fall through */
+ case TASKFILE_IN_DMAQ:
+ case TASKFILE_IN_DMA:
+ nsect = taskin / SECTOR_SIZE;
+ data_buf = 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;
}
+ if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
+ nsect = 0;
+ else if (!nsect) {
+ nsect = (args.tf.hob_nsect << 8) | args.tf.nsect;
+
+ if (!nsect) {
+ printk(KERN_ERR "%s: in/out command without data\n",
+ drive->name);
+ err = -EFAULT;
+ goto abort;
+ }
+ }
+
+ if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE)
+ args.tf_flags |= IDE_TFLAG_WRITE;
+
+ err = ide_raw_taskfile(drive, &args, data_buf, nsect);
+
memcpy(req_task->hob_ports, &args.tf_array[0], HDIO_DRIVE_HOB_HDR_SIZE - 2);
memcpy(req_task->io_ports, &args.tf_array[6], HDIO_DRIVE_TASK_HDR_SIZE);
req_task->in_flags = args.tf_in_flags;