ide: switch ide_cmd_ioctl() to use REQ_TYPE_ATA_TASKFILE requests
Based on the earlier work by Tejun Heo. There should be no functionality changes caused by this patch. Cc: Tejun Heo <htejun@gmail.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
This commit is contained in:
parent
34f5d5ae35
commit
5a9e77af97
2 changed files with 33 additions and 34 deletions
|
@ -619,7 +619,7 @@ u8 eighty_ninty_three (ide_drive_t *drive)
|
||||||
int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
|
int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
|
||||||
{
|
{
|
||||||
if (args->tf.command == WIN_SETFEATURES &&
|
if (args->tf.command == WIN_SETFEATURES &&
|
||||||
args->tf.lbal > XFER_UDMA_2 &&
|
args->tf.nsect > XFER_UDMA_2 &&
|
||||||
args->tf.feature == SETFEATURES_XFER) {
|
args->tf.feature == SETFEATURES_XFER) {
|
||||||
if (eighty_ninty_three(drive) == 0) {
|
if (eighty_ninty_three(drive) == 0) {
|
||||||
printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot "
|
printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot "
|
||||||
|
@ -639,7 +639,7 @@ int ide_ata66_check (ide_drive_t *drive, ide_task_t *args)
|
||||||
int set_transfer (ide_drive_t *drive, ide_task_t *args)
|
int set_transfer (ide_drive_t *drive, ide_task_t *args)
|
||||||
{
|
{
|
||||||
if (args->tf.command == WIN_SETFEATURES &&
|
if (args->tf.command == WIN_SETFEATURES &&
|
||||||
args->tf.lbal >= XFER_SW_DMA_0 &&
|
args->tf.nsect >= XFER_SW_DMA_0 &&
|
||||||
args->tf.feature == SETFEATURES_XFER &&
|
args->tf.feature == SETFEATURES_XFER &&
|
||||||
(drive->id->dma_ultra ||
|
(drive->id->dma_ultra ||
|
||||||
drive->id->dma_mword ||
|
drive->id->dma_mword ||
|
||||||
|
|
|
@ -750,31 +750,11 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int ide_wait_cmd(ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature,
|
|
||||||
u8 sectors, u8 *buf)
|
|
||||||
{
|
|
||||||
struct request rq;
|
|
||||||
u8 buffer[4];
|
|
||||||
|
|
||||||
if (!buf)
|
|
||||||
buf = buffer;
|
|
||||||
memset(buf, 0, 4 + SECTOR_WORDS * 4 * sectors);
|
|
||||||
ide_init_drive_cmd(&rq);
|
|
||||||
rq.cmd_type = REQ_TYPE_ATA_CMD;
|
|
||||||
rq.buffer = buf;
|
|
||||||
*buf++ = cmd;
|
|
||||||
*buf++ = nsect;
|
|
||||||
*buf++ = feature;
|
|
||||||
*buf++ = sectors;
|
|
||||||
return ide_do_drive_cmd(drive, &rq, ide_wait);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
|
int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
int err = 0;
|
u8 *buf = NULL;
|
||||||
u8 args[4], *argbuf = args;
|
int bufsize = 0, err = 0;
|
||||||
u8 xfer_rate = 0;
|
u8 args[4], xfer_rate = 0;
|
||||||
int argsize = 4;
|
|
||||||
ide_task_t tfargs;
|
ide_task_t tfargs;
|
||||||
struct ide_taskfile *tf = &tfargs.tf;
|
struct ide_taskfile *tf = &tfargs.tf;
|
||||||
|
|
||||||
|
@ -792,23 +772,39 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
|
||||||
|
|
||||||
memset(&tfargs, 0, sizeof(ide_task_t));
|
memset(&tfargs, 0, sizeof(ide_task_t));
|
||||||
tf->feature = args[2];
|
tf->feature = args[2];
|
||||||
tf->nsect = args[3];
|
if (args[0] == WIN_SMART) {
|
||||||
tf->lbal = args[1];
|
tf->nsect = args[3];
|
||||||
|
tf->lbal = args[1];
|
||||||
|
tf->lbam = 0x4f;
|
||||||
|
tf->lbah = 0xc2;
|
||||||
|
tfargs.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT;
|
||||||
|
} else {
|
||||||
|
tf->nsect = args[1];
|
||||||
|
tfargs.tf_flags = IDE_TFLAG_OUT_FEATURE |
|
||||||
|
IDE_TFLAG_OUT_NSECT | IDE_TFLAG_IN_NSECT;
|
||||||
|
}
|
||||||
tf->command = args[0];
|
tf->command = args[0];
|
||||||
|
tfargs.data_phase = args[3] ? TASKFILE_IN : TASKFILE_NO_DATA;
|
||||||
|
|
||||||
if (args[3]) {
|
if (args[3]) {
|
||||||
argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
|
tfargs.tf_flags |= IDE_TFLAG_IO_16BIT;
|
||||||
argbuf = kzalloc(argsize, GFP_KERNEL);
|
bufsize = SECTOR_WORDS * 4 * args[3];
|
||||||
if (argbuf == NULL)
|
buf = kzalloc(bufsize, GFP_KERNEL);
|
||||||
|
if (buf == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (set_transfer(drive, &tfargs)) {
|
if (set_transfer(drive, &tfargs)) {
|
||||||
xfer_rate = args[1];
|
xfer_rate = args[1];
|
||||||
if (ide_ata66_check(drive, &tfargs))
|
if (ide_ata66_check(drive, &tfargs))
|
||||||
goto abort;
|
goto abort;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf);
|
err = ide_raw_taskfile(drive, &tfargs, buf, args[3]);
|
||||||
|
|
||||||
|
args[0] = tf->status;
|
||||||
|
args[1] = tf->error;
|
||||||
|
args[2] = tf->nsect;
|
||||||
|
|
||||||
if (!err && xfer_rate) {
|
if (!err && xfer_rate) {
|
||||||
/* active-retuning-calls future */
|
/* active-retuning-calls future */
|
||||||
|
@ -816,10 +812,13 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
|
||||||
ide_driveid_update(drive);
|
ide_driveid_update(drive);
|
||||||
}
|
}
|
||||||
abort:
|
abort:
|
||||||
if (copy_to_user((void __user *)arg, argbuf, argsize))
|
if (copy_to_user((void __user *)arg, &args, 4))
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
if (argsize > 4)
|
if (buf) {
|
||||||
kfree(argbuf);
|
if (copy_to_user((void __user *)(arg + 4), buf, bufsize))
|
||||||
|
err = -EFAULT;
|
||||||
|
kfree(buf);
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue