aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/ide-iops.c4
-rw-r--r--drivers/ide/ide-taskfile.c63
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:
619int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) 619int 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)
639int set_transfer (ide_drive_t *drive, ide_task_t *args) 639int 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
753static 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
772int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) 753int 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 }
818abort: 814abort:
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