diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-01-26 14:13:13 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-01-26 14:13:13 -0500 |
commit | 5a9e77af970f14a94482a6d4dca5c48efb70deb2 (patch) | |
tree | de3ad64511e39ec9fb8ac8411f7a5469d9e70cd0 /drivers/ide/ide-taskfile.c | |
parent | 34f5d5ae35240a11846875d76eb935875ab0c366 (diff) |
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>
Diffstat (limited to 'drivers/ide/ide-taskfile.c')
-rw-r--r-- | drivers/ide/ide-taskfile.c | 63 |
1 files changed, 31 insertions, 32 deletions
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index a1796cf5835c..5eb6fa15dc4d 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -750,31 +750,11 @@ abort: | |||
750 | } | 750 | } |
751 | #endif | 751 | #endif |
752 | 752 | ||
753 | static int ide_wait_cmd(ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, | ||
754 | u8 sectors, u8 *buf) | ||
755 | { | ||
756 | struct request rq; | ||
757 | u8 buffer[4]; | ||
758 | |||
759 | if (!buf) | ||
760 | buf = buffer; | ||
761 | memset(buf, 0, 4 + SECTOR_WORDS * 4 * sectors); | ||
762 | ide_init_drive_cmd(&rq); | ||
763 | rq.cmd_type = REQ_TYPE_ATA_CMD; | ||
764 | rq.buffer = buf; | ||
765 | *buf++ = cmd; | ||
766 | *buf++ = nsect; | ||
767 | *buf++ = feature; | ||
768 | *buf++ = sectors; | ||
769 | return ide_do_drive_cmd(drive, &rq, ide_wait); | ||
770 | } | ||
771 | |||
772 | int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | 753 | int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) |
773 | { | 754 | { |
774 | int err = 0; | 755 | u8 *buf = NULL; |
775 | u8 args[4], *argbuf = args; | 756 | int bufsize = 0, err = 0; |
776 | u8 xfer_rate = 0; | 757 | u8 args[4], xfer_rate = 0; |
777 | int argsize = 4; | ||
778 | ide_task_t tfargs; | 758 | ide_task_t tfargs; |
779 | struct ide_taskfile *tf = &tfargs.tf; | 759 | struct ide_taskfile *tf = &tfargs.tf; |
780 | 760 | ||
@@ -792,23 +772,39 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
792 | 772 | ||
793 | memset(&tfargs, 0, sizeof(ide_task_t)); | 773 | memset(&tfargs, 0, sizeof(ide_task_t)); |
794 | tf->feature = args[2]; | 774 | tf->feature = args[2]; |
795 | tf->nsect = args[3]; | 775 | if (args[0] == WIN_SMART) { |
796 | tf->lbal = args[1]; | 776 | tf->nsect = args[3]; |
777 | tf->lbal = args[1]; | ||
778 | tf->lbam = 0x4f; | ||
779 | tf->lbah = 0xc2; | ||
780 | tfargs.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT; | ||
781 | } else { | ||
782 | tf->nsect = args[1]; | ||
783 | tfargs.tf_flags = IDE_TFLAG_OUT_FEATURE | | ||
784 | IDE_TFLAG_OUT_NSECT | IDE_TFLAG_IN_NSECT; | ||
785 | } | ||
797 | tf->command = args[0]; | 786 | tf->command = args[0]; |
787 | tfargs.data_phase = args[3] ? TASKFILE_IN : TASKFILE_NO_DATA; | ||
798 | 788 | ||
799 | if (args[3]) { | 789 | if (args[3]) { |
800 | argsize = 4 + (SECTOR_WORDS * 4 * args[3]); | 790 | tfargs.tf_flags |= IDE_TFLAG_IO_16BIT; |
801 | argbuf = kzalloc(argsize, GFP_KERNEL); | 791 | bufsize = SECTOR_WORDS * 4 * args[3]; |
802 | if (argbuf == NULL) | 792 | buf = kzalloc(bufsize, GFP_KERNEL); |
793 | if (buf == NULL) | ||
803 | return -ENOMEM; | 794 | return -ENOMEM; |
804 | } | 795 | } |
796 | |||
805 | if (set_transfer(drive, &tfargs)) { | 797 | if (set_transfer(drive, &tfargs)) { |
806 | xfer_rate = args[1]; | 798 | xfer_rate = args[1]; |
807 | if (ide_ata66_check(drive, &tfargs)) | 799 | if (ide_ata66_check(drive, &tfargs)) |
808 | goto abort; | 800 | goto abort; |
809 | } | 801 | } |
810 | 802 | ||
811 | err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf); | 803 | err = ide_raw_taskfile(drive, &tfargs, buf, args[3]); |
804 | |||
805 | args[0] = tf->status; | ||
806 | args[1] = tf->error; | ||
807 | args[2] = tf->nsect; | ||
812 | 808 | ||
813 | if (!err && xfer_rate) { | 809 | if (!err && xfer_rate) { |
814 | /* active-retuning-calls future */ | 810 | /* active-retuning-calls future */ |
@@ -816,10 +812,13 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
816 | ide_driveid_update(drive); | 812 | ide_driveid_update(drive); |
817 | } | 813 | } |
818 | abort: | 814 | abort: |
819 | if (copy_to_user((void __user *)arg, argbuf, argsize)) | 815 | if (copy_to_user((void __user *)arg, &args, 4)) |
820 | err = -EFAULT; | 816 | err = -EFAULT; |
821 | if (argsize > 4) | 817 | if (buf) { |
822 | kfree(argbuf); | 818 | if (copy_to_user((void __user *)(arg + 4), buf, bufsize)) |
819 | err = -EFAULT; | ||
820 | kfree(buf); | ||
821 | } | ||
823 | return err; | 822 | return err; |
824 | } | 823 | } |
825 | 824 | ||