aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/ide-disk.c15
-rw-r--r--drivers/ide/ide-io.c8
-rw-r--r--drivers/ide/ide-taskfile.c89
-rw-r--r--include/linux/hdreg.h13
-rw-r--r--include/linux/ide.h5
5 files changed, 64 insertions, 66 deletions
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 747dc6023346..d9a4fe27685d 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -516,12 +516,11 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
516 tf->lbam = SMART_LCYL_PASS; 516 tf->lbam = SMART_LCYL_PASS;
517 tf->lbah = SMART_HCYL_PASS; 517 tf->lbah = SMART_HCYL_PASS;
518 tf->command = WIN_SMART; 518 tf->command = WIN_SMART;
519 args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; 519 args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
520 args.command_type = IDE_DRIVE_TASK_IN; 520 args.data_phase = TASKFILE_IN;
521 args.data_phase = TASKFILE_IN; 521 args.handler = task_in_intr;
522 args.handler = &task_in_intr;
523 (void) smart_enable(drive); 522 (void) smart_enable(drive);
524 return ide_raw_taskfile(drive, &args, buf); 523 return ide_raw_taskfile(drive, &args, buf, 1);
525} 524}
526 525
527static int proc_idedisk_read_cache 526static int proc_idedisk_read_cache
@@ -607,9 +606,9 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
607 task.tf.command = WIN_FLUSH_CACHE_EXT; 606 task.tf.command = WIN_FLUSH_CACHE_EXT;
608 else 607 else
609 task.tf.command = WIN_FLUSH_CACHE; 608 task.tf.command = WIN_FLUSH_CACHE;
610 task.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; 609 task.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
611 task.command_type = IDE_DRIVE_TASK_NO_DATA; 610 task.data_phase = TASKFILE_NO_DATA;
612 task.handler = task_no_data_intr; 611 task.handler = task_no_data_intr;
613 612
614 rq->cmd_type = REQ_TYPE_ATA_TASKFILE; 613 rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
615 rq->cmd_flags |= REQ_SOFTBARRIER; 614 rq->cmd_flags |= REQ_SOFTBARRIER;
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 6ee7458d34ed..f4f7e3db10ac 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -232,9 +232,9 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
232 return ide_stopped; 232 return ide_stopped;
233 233
234out_do_tf: 234out_do_tf:
235 args->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; 235 args->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
236 args->command_type = IDE_DRIVE_TASK_NO_DATA; 236 args->data_phase = TASKFILE_NO_DATA;
237 args->handler = task_no_data_intr; 237 args->handler = task_no_data_intr;
238 return do_rw_taskfile(drive, args); 238 return do_rw_taskfile(drive, args);
239} 239}
240 240
@@ -672,7 +672,7 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive)
672 ide_task_t args; 672 ide_task_t args;
673 673
674 memset(&args, 0, sizeof(ide_task_t)); 674 memset(&args, 0, sizeof(ide_task_t));
675 args.command_type = IDE_DRIVE_TASK_NO_DATA; 675 args.data_phase = TASKFILE_NO_DATA;
676 676
677 if (s->b.set_geometry) { 677 if (s->b.set_geometry) {
678 s->b.set_geometry = 0; 678 s->b.set_geometry = 0;
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)
126 args.tf.command = WIN_IDENTIFY; 126 args.tf.command = WIN_IDENTIFY;
127 else 127 else
128 args.tf.command = WIN_PIDENTIFY; 128 args.tf.command = WIN_PIDENTIFY;
129 args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE; 129 args.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE;
130 args.command_type = IDE_DRIVE_TASK_IN; 130 args.data_phase = TASKFILE_IN;
131 args.data_phase = TASKFILE_IN; 131 args.handler = task_in_intr;
132 args.handler = &task_in_intr; 132 return ide_raw_taskfile(drive, &args, buf, 1);
133 return ide_raw_taskfile(drive, &args, buf);
134} 133}
135 134
136static int inline task_dma_ok(ide_task_t *task) 135static 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)
499} 498}
500EXPORT_SYMBOL(pre_task_out_intr); 499EXPORT_SYMBOL(pre_task_out_intr);
501 500
502static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long data_size, u8 *buf) 501int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
503{ 502{
504 struct request rq; 503 struct request rq;
505 504
@@ -514,44 +513,26 @@ static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long
514 * if we would find a solution to transfer any size. 513 * if we would find a solution to transfer any size.
515 * To support special commands like READ LONG. 514 * To support special commands like READ LONG.
516 */ 515 */
517 if (args->command_type != IDE_DRIVE_TASK_NO_DATA) { 516 rq.hard_nr_sectors = rq.nr_sectors = nsect;
518 if (data_size == 0) 517 rq.hard_cur_sectors = rq.current_nr_sectors = nsect;
519 rq.nr_sectors = (args->tf.hob_nsect << 8) | args->tf.nsect;
520 else
521 rq.nr_sectors = data_size / SECTOR_SIZE;
522
523 if (!rq.nr_sectors) {
524 printk(KERN_ERR "%s: in/out command without data\n",
525 drive->name);
526 return -EFAULT;
527 }
528 518
529 rq.hard_nr_sectors = rq.nr_sectors; 519 if (task->tf_flags & IDE_TFLAG_WRITE)
530 rq.hard_cur_sectors = rq.current_nr_sectors = rq.nr_sectors; 520 rq.cmd_flags |= REQ_RW;
531 521
532 if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE) 522 rq.special = task;
533 rq.cmd_flags |= REQ_RW; 523 task->rq = &rq;
534 }
535 524
536 rq.special = args;
537 args->rq = &rq;
538 return ide_do_drive_cmd(drive, &rq, ide_wait); 525 return ide_do_drive_cmd(drive, &rq, ide_wait);
539} 526}
540 527
541int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *args, u8 *buf)
542{
543 return ide_diag_taskfile(drive, args, 0, buf);
544}
545
546EXPORT_SYMBOL(ide_raw_taskfile); 528EXPORT_SYMBOL(ide_raw_taskfile);
547 529
548int ide_no_data_taskfile(ide_drive_t *drive, ide_task_t *task) 530int ide_no_data_taskfile(ide_drive_t *drive, ide_task_t *task)
549{ 531{
550 task->command_type = IDE_DRIVE_TASK_NO_DATA; 532 task->data_phase = TASKFILE_NO_DATA;
551 task->data_phase = TASKFILE_NO_DATA; 533 task->handler = task_no_data_intr;
552 task->handler = task_no_data_intr;
553 534
554 return ide_raw_taskfile(drive, task, NULL); 535 return ide_raw_taskfile(drive, task, NULL, 0);
555} 536}
556EXPORT_SYMBOL_GPL(ide_no_data_taskfile); 537EXPORT_SYMBOL_GPL(ide_no_data_taskfile);
557 538
@@ -562,10 +543,12 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
562 ide_task_t args; 543 ide_task_t args;
563 u8 *outbuf = NULL; 544 u8 *outbuf = NULL;
564 u8 *inbuf = NULL; 545 u8 *inbuf = NULL;
546 u8 *data_buf = NULL;
565 int err = 0; 547 int err = 0;
566 int tasksize = sizeof(struct ide_task_request_s); 548 int tasksize = sizeof(struct ide_task_request_s);
567 unsigned int taskin = 0; 549 unsigned int taskin = 0;
568 unsigned int taskout = 0; 550 unsigned int taskout = 0;
551 u16 nsect = 0;
569 u8 io_32bit = drive->io_32bit; 552 u8 io_32bit = drive->io_32bit;
570 char __user *buf = (char __user *)arg; 553 char __user *buf = (char __user *)arg;
571 554
@@ -618,7 +601,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
618 memcpy(&args.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE); 601 memcpy(&args.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
619 args.tf_in_flags = req_task->in_flags; 602 args.tf_in_flags = req_task->in_flags;
620 args.data_phase = req_task->data_phase; 603 args.data_phase = req_task->data_phase;
621 args.command_type = req_task->req_cmd;
622 604
623 args.tf_flags = IDE_TFLAG_OUT_DEVICE; 605 args.tf_flags = IDE_TFLAG_OUT_DEVICE;
624 if (drive->addressing == 1) 606 if (drive->addressing == 1)
@@ -657,14 +639,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
657 639
658 drive->io_32bit = 0; 640 drive->io_32bit = 0;
659 switch(req_task->data_phase) { 641 switch(req_task->data_phase) {
660 case TASKFILE_OUT_DMAQ:
661 case TASKFILE_OUT_DMA:
662 err = ide_diag_taskfile(drive, &args, taskout, outbuf);
663 break;
664 case TASKFILE_IN_DMAQ:
665 case TASKFILE_IN_DMA:
666 err = ide_diag_taskfile(drive, &args, taskin, inbuf);
667 break;
668 case TASKFILE_MULTI_OUT: 642 case TASKFILE_MULTI_OUT:
669 if (!drive->mult_count) { 643 if (!drive->mult_count) {
670 /* (hs): give up if multcount is not set */ 644 /* (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)
678 case TASKFILE_OUT: 652 case TASKFILE_OUT:
679 args.prehandler = &pre_task_out_intr; 653 args.prehandler = &pre_task_out_intr;
680 args.handler = &task_out_intr; 654 args.handler = &task_out_intr;
681 err = ide_diag_taskfile(drive, &args, taskout, outbuf); 655 /* fall through */
656 case TASKFILE_OUT_DMAQ:
657 case TASKFILE_OUT_DMA:
658 nsect = taskout / SECTOR_SIZE;
659 data_buf = outbuf;
682 break; 660 break;
683 case TASKFILE_MULTI_IN: 661 case TASKFILE_MULTI_IN:
684 if (!drive->mult_count) { 662 if (!drive->mult_count) {
@@ -692,17 +670,38 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
692 /* fall through */ 670 /* fall through */
693 case TASKFILE_IN: 671 case TASKFILE_IN:
694 args.handler = &task_in_intr; 672 args.handler = &task_in_intr;
695 err = ide_diag_taskfile(drive, &args, taskin, inbuf); 673 /* fall through */
674 case TASKFILE_IN_DMAQ:
675 case TASKFILE_IN_DMA:
676 nsect = taskin / SECTOR_SIZE;
677 data_buf = inbuf;
696 break; 678 break;
697 case TASKFILE_NO_DATA: 679 case TASKFILE_NO_DATA:
698 args.handler = &task_no_data_intr; 680 args.handler = &task_no_data_intr;
699 err = ide_diag_taskfile(drive, &args, 0, NULL);
700 break; 681 break;
701 default: 682 default:
702 err = -EFAULT; 683 err = -EFAULT;
703 goto abort; 684 goto abort;
704 } 685 }
705 686
687 if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
688 nsect = 0;
689 else if (!nsect) {
690 nsect = (args.tf.hob_nsect << 8) | args.tf.nsect;
691
692 if (!nsect) {
693 printk(KERN_ERR "%s: in/out command without data\n",
694 drive->name);
695 err = -EFAULT;
696 goto abort;
697 }
698 }
699
700 if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE)
701 args.tf_flags |= IDE_TFLAG_WRITE;
702
703 err = ide_raw_taskfile(drive, &args, data_buf, nsect);
704
706 memcpy(req_task->hob_ports, &args.tf_array[0], HDIO_DRIVE_HOB_HDR_SIZE - 2); 705 memcpy(req_task->hob_ports, &args.tf_array[0], HDIO_DRIVE_HOB_HDR_SIZE - 2);
707 memcpy(req_task->io_ports, &args.tf_array[6], HDIO_DRIVE_TASK_HDR_SIZE); 706 memcpy(req_task->io_ports, &args.tf_array[6], HDIO_DRIVE_TASK_HDR_SIZE);
708 req_task->in_flags = args.tf_in_flags; 707 req_task->in_flags = args.tf_in_flags;
diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h
index 0521f1234f15..ff43f8d6b5b3 100644
--- a/include/linux/hdreg.h
+++ b/include/linux/hdreg.h
@@ -73,13 +73,13 @@
73#define HDIO_DRIVE_HOB_HDR_SIZE (8 * sizeof(__u8)) 73#define HDIO_DRIVE_HOB_HDR_SIZE (8 * sizeof(__u8))
74#define HDIO_DRIVE_TASK_HDR_SIZE (8 * sizeof(__u8)) 74#define HDIO_DRIVE_TASK_HDR_SIZE (8 * sizeof(__u8))
75 75
76#define IDE_DRIVE_TASK_INVALID -1
77#define IDE_DRIVE_TASK_NO_DATA 0 76#define IDE_DRIVE_TASK_NO_DATA 0
77#ifndef __KERNEL__
78#define IDE_DRIVE_TASK_INVALID -1
78#define IDE_DRIVE_TASK_SET_XFER 1 79#define IDE_DRIVE_TASK_SET_XFER 1
79
80#define IDE_DRIVE_TASK_IN 2 80#define IDE_DRIVE_TASK_IN 2
81
82#define IDE_DRIVE_TASK_OUT 3 81#define IDE_DRIVE_TASK_OUT 3
82#endif
83#define IDE_DRIVE_TASK_RAW_WRITE 4 83#define IDE_DRIVE_TASK_RAW_WRITE 4
84 84
85/* 85/*
@@ -166,9 +166,6 @@ typedef struct hd_drive_hob_hdr {
166} hob_struct_t; 166} hob_struct_t;
167#endif 167#endif
168 168
169#define TASKFILE_INVALID 0x7fff
170#define TASKFILE_48 0x8000
171
172#define TASKFILE_NO_DATA 0x0000 169#define TASKFILE_NO_DATA 0x0000
173 170
174#define TASKFILE_IN 0x0001 171#define TASKFILE_IN 0x0001
@@ -183,12 +180,16 @@ typedef struct hd_drive_hob_hdr {
183#define TASKFILE_IN_DMAQ 0x0080 180#define TASKFILE_IN_DMAQ 0x0080
184#define TASKFILE_OUT_DMAQ 0x0100 181#define TASKFILE_OUT_DMAQ 0x0100
185 182
183#ifndef __KERNEL__
186#define TASKFILE_P_IN 0x0200 184#define TASKFILE_P_IN 0x0200
187#define TASKFILE_P_OUT 0x0400 185#define TASKFILE_P_OUT 0x0400
188#define TASKFILE_P_IN_DMA 0x0800 186#define TASKFILE_P_IN_DMA 0x0800
189#define TASKFILE_P_OUT_DMA 0x1000 187#define TASKFILE_P_OUT_DMA 0x1000
190#define TASKFILE_P_IN_DMAQ 0x2000 188#define TASKFILE_P_IN_DMAQ 0x2000
191#define TASKFILE_P_OUT_DMAQ 0x4000 189#define TASKFILE_P_OUT_DMAQ 0x4000
190#define TASKFILE_48 0x8000
191#define TASKFILE_INVALID 0x7fff
192#endif
192 193
193/* ATA/ATAPI Commands pre T13 Spec */ 194/* ATA/ATAPI Commands pre T13 Spec */
194#define WIN_NOP 0x00 195#define WIN_NOP 0x00
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 90f83b65eb8f..7485fc705ca4 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -909,6 +909,7 @@ enum {
909 IDE_TFLAG_OUT_LBAM | 909 IDE_TFLAG_OUT_LBAM |
910 IDE_TFLAG_OUT_LBAH, 910 IDE_TFLAG_OUT_LBAH,
911 IDE_TFLAG_OUT_DEVICE = (1 << 14), 911 IDE_TFLAG_OUT_DEVICE = (1 << 14),
912 IDE_TFLAG_WRITE = (1 << 15),
912}; 913};
913 914
914struct ide_taskfile { 915struct ide_taskfile {
@@ -948,7 +949,6 @@ typedef struct ide_task_s {
948 u16 tf_flags; 949 u16 tf_flags;
949 ide_reg_valid_t tf_in_flags; 950 ide_reg_valid_t tf_in_flags;
950 int data_phase; 951 int data_phase;
951 int command_type;
952 ide_pre_handler_t *prehandler; 952 ide_pre_handler_t *prehandler;
953 ide_handler_t *handler; 953 ide_handler_t *handler;
954 struct request *rq; /* copy of request */ 954 struct request *rq; /* copy of request */
@@ -983,8 +983,7 @@ extern ide_startstop_t task_no_data_intr(ide_drive_t *);
983extern ide_startstop_t task_in_intr(ide_drive_t *); 983extern ide_startstop_t task_in_intr(ide_drive_t *);
984extern ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *); 984extern ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *);
985 985
986extern int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *); 986int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *, u16);
987
988int ide_no_data_taskfile(ide_drive_t *, ide_task_t *); 987int ide_no_data_taskfile(ide_drive_t *, ide_task_t *);
989 988
990int ide_taskfile_ioctl(ide_drive_t *, unsigned int, unsigned long); 989int ide_taskfile_ioctl(ide_drive_t *, unsigned int, unsigned long);