diff options
-rw-r--r-- | drivers/ide/ide-disk.c | 15 | ||||
-rw-r--r-- | drivers/ide/ide-io.c | 8 | ||||
-rw-r--r-- | drivers/ide/ide-taskfile.c | 89 | ||||
-rw-r--r-- | include/linux/hdreg.h | 13 | ||||
-rw-r--r-- | include/linux/ide.h | 5 |
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 | ||
527 | static int proc_idedisk_read_cache | 526 | static 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 | ||
234 | out_do_tf: | 234 | out_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 | ||
136 | static int inline task_dma_ok(ide_task_t *task) | 135 | static 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 | } |
500 | EXPORT_SYMBOL(pre_task_out_intr); | 499 | EXPORT_SYMBOL(pre_task_out_intr); |
501 | 500 | ||
502 | static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long data_size, u8 *buf) | 501 | int 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 | ||
541 | int 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 | |||
546 | EXPORT_SYMBOL(ide_raw_taskfile); | 528 | EXPORT_SYMBOL(ide_raw_taskfile); |
547 | 529 | ||
548 | int ide_no_data_taskfile(ide_drive_t *drive, ide_task_t *task) | 530 | int 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 | } |
556 | EXPORT_SYMBOL_GPL(ide_no_data_taskfile); | 537 | EXPORT_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 | ||
914 | struct ide_taskfile { | 915 | struct 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 *); | |||
983 | extern ide_startstop_t task_in_intr(ide_drive_t *); | 983 | extern ide_startstop_t task_in_intr(ide_drive_t *); |
984 | extern ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *); | 984 | extern ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *); |
985 | 985 | ||
986 | extern int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *); | 986 | int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *, u16); |
987 | |||
988 | int ide_no_data_taskfile(ide_drive_t *, ide_task_t *); | 987 | int ide_no_data_taskfile(ide_drive_t *, ide_task_t *); |
989 | 988 | ||
990 | int ide_taskfile_ioctl(ide_drive_t *, unsigned int, unsigned long); | 989 | int ide_taskfile_ioctl(ide_drive_t *, unsigned int, unsigned long); |