diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ide/ide-iops.c | 4 | ||||
-rw-r--r-- | drivers/ide/ide-taskfile.c | 63 |
2 files changed, 33 insertions, 34 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index a26c9ca784a6..e2a7e95e1636 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -619,7 +619,7 @@ no_80w: | |||
619 | int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) | 619 | int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) |
620 | { | 620 | { |
621 | if (args->tf.command == WIN_SETFEATURES && | 621 | if (args->tf.command == WIN_SETFEATURES && |
622 | args->tf.lbal > XFER_UDMA_2 && | 622 | args->tf.nsect > XFER_UDMA_2 && |
623 | args->tf.feature == SETFEATURES_XFER) { | 623 | args->tf.feature == SETFEATURES_XFER) { |
624 | if (eighty_ninty_three(drive) == 0) { | 624 | if (eighty_ninty_three(drive) == 0) { |
625 | printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot " | 625 | printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot " |
@@ -639,7 +639,7 @@ int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) | |||
639 | int set_transfer (ide_drive_t *drive, ide_task_t *args) | 639 | int set_transfer (ide_drive_t *drive, ide_task_t *args) |
640 | { | 640 | { |
641 | if (args->tf.command == WIN_SETFEATURES && | 641 | if (args->tf.command == WIN_SETFEATURES && |
642 | args->tf.lbal >= XFER_SW_DMA_0 && | 642 | args->tf.nsect >= XFER_SW_DMA_0 && |
643 | args->tf.feature == SETFEATURES_XFER && | 643 | args->tf.feature == SETFEATURES_XFER && |
644 | (drive->id->dma_ultra || | 644 | (drive->id->dma_ultra || |
645 | drive->id->dma_mword || | 645 | drive->id->dma_mword || |
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 | ||