diff options
Diffstat (limited to 'drivers/ide/ide-taskfile.c')
-rw-r--r-- | drivers/ide/ide-taskfile.c | 99 |
1 files changed, 46 insertions, 53 deletions
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 91948a46cc6e..5a1a9f7846b6 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -66,12 +66,13 @@ static void taskfile_output_data(ide_drive_t *drive, void *buffer, u32 wcount) | |||
66 | int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) | 66 | int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) |
67 | { | 67 | { |
68 | ide_task_t args; | 68 | ide_task_t args; |
69 | |||
69 | memset(&args, 0, sizeof(ide_task_t)); | 70 | memset(&args, 0, sizeof(ide_task_t)); |
70 | args.tfRegister[IDE_NSECTOR_OFFSET] = 0x01; | 71 | args.tf.nsect = 0x01; |
71 | if (drive->media == ide_disk) | 72 | if (drive->media == ide_disk) |
72 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_IDENTIFY; | 73 | args.tf.command = WIN_IDENTIFY; |
73 | else | 74 | else |
74 | args.tfRegister[IDE_COMMAND_OFFSET] = WIN_PIDENTIFY; | 75 | args.tf.command = WIN_PIDENTIFY; |
75 | args.command_type = IDE_DRIVE_TASK_IN; | 76 | args.command_type = IDE_DRIVE_TASK_IN; |
76 | args.data_phase = TASKFILE_IN; | 77 | args.data_phase = TASKFILE_IN; |
77 | args.handler = &task_in_intr; | 78 | args.handler = &task_in_intr; |
@@ -81,8 +82,7 @@ int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) | |||
81 | ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) | 82 | ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) |
82 | { | 83 | { |
83 | ide_hwif_t *hwif = HWIF(drive); | 84 | ide_hwif_t *hwif = HWIF(drive); |
84 | task_struct_t *taskfile = (task_struct_t *) task->tfRegister; | 85 | struct ide_taskfile *tf = &task->tf; |
85 | hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister; | ||
86 | u8 HIHI = (drive->addressing == 1) ? 0xE0 : 0xEF; | 86 | u8 HIHI = (drive->addressing == 1) ? 0xE0 : 0xEF; |
87 | 87 | ||
88 | /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */ | 88 | /* ALL Command Block Executions SHALL clear nIEN, unless otherwise */ |
@@ -93,35 +93,35 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) | |||
93 | SELECT_MASK(drive, 0); | 93 | SELECT_MASK(drive, 0); |
94 | 94 | ||
95 | if (drive->addressing == 1) { | 95 | if (drive->addressing == 1) { |
96 | hwif->OUTB(hobfile->feature, IDE_FEATURE_REG); | 96 | hwif->OUTB(tf->hob_feature, IDE_FEATURE_REG); |
97 | hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG); | 97 | hwif->OUTB(tf->hob_nsect, IDE_NSECTOR_REG); |
98 | hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG); | 98 | hwif->OUTB(tf->hob_lbal, IDE_SECTOR_REG); |
99 | hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG); | 99 | hwif->OUTB(tf->hob_lbam, IDE_LCYL_REG); |
100 | hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG); | 100 | hwif->OUTB(tf->hob_lbah, IDE_HCYL_REG); |
101 | } | 101 | } |
102 | 102 | ||
103 | hwif->OUTB(taskfile->feature, IDE_FEATURE_REG); | 103 | hwif->OUTB(tf->feature, IDE_FEATURE_REG); |
104 | hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG); | 104 | hwif->OUTB(tf->nsect, IDE_NSECTOR_REG); |
105 | hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG); | 105 | hwif->OUTB(tf->lbal, IDE_SECTOR_REG); |
106 | hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG); | 106 | hwif->OUTB(tf->lbam, IDE_LCYL_REG); |
107 | hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG); | 107 | hwif->OUTB(tf->lbah, IDE_HCYL_REG); |
108 | 108 | ||
109 | hwif->OUTB((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG); | 109 | hwif->OUTB((tf->device & HIHI) | drive->select.all, IDE_SELECT_REG); |
110 | 110 | ||
111 | if (task->handler != NULL) { | 111 | if (task->handler != NULL) { |
112 | if (task->prehandler != NULL) { | 112 | if (task->prehandler != NULL) { |
113 | hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG); | 113 | hwif->OUTBSYNC(drive, tf->command, IDE_COMMAND_REG); |
114 | ndelay(400); /* FIXME */ | 114 | ndelay(400); /* FIXME */ |
115 | return task->prehandler(drive, task->rq); | 115 | return task->prehandler(drive, task->rq); |
116 | } | 116 | } |
117 | ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL); | 117 | ide_execute_command(drive, tf->command, task->handler, WAIT_WORSTCASE, NULL); |
118 | return ide_started; | 118 | return ide_started; |
119 | } | 119 | } |
120 | 120 | ||
121 | if (!drive->using_dma) | 121 | if (!drive->using_dma) |
122 | return ide_stopped; | 122 | return ide_stopped; |
123 | 123 | ||
124 | switch (taskfile->command) { | 124 | switch (tf->command) { |
125 | case WIN_WRITEDMA_ONCE: | 125 | case WIN_WRITEDMA_ONCE: |
126 | case WIN_WRITEDMA: | 126 | case WIN_WRITEDMA: |
127 | case WIN_WRITEDMA_EXT: | 127 | case WIN_WRITEDMA_EXT: |
@@ -130,7 +130,7 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) | |||
130 | case WIN_READDMA_EXT: | 130 | case WIN_READDMA_EXT: |
131 | case WIN_IDENTIFY_DMA: | 131 | case WIN_IDENTIFY_DMA: |
132 | if (!hwif->dma_setup(drive)) { | 132 | if (!hwif->dma_setup(drive)) { |
133 | hwif->dma_exec_cmd(drive, taskfile->command); | 133 | hwif->dma_exec_cmd(drive, tf->command); |
134 | hwif->dma_start(drive); | 134 | hwif->dma_start(drive); |
135 | return ide_started; | 135 | return ide_started; |
136 | } | 136 | } |
@@ -483,7 +483,7 @@ static int ide_diag_taskfile(ide_drive_t *drive, ide_task_t *args, unsigned long | |||
483 | */ | 483 | */ |
484 | if (args->command_type != IDE_DRIVE_TASK_NO_DATA) { | 484 | if (args->command_type != IDE_DRIVE_TASK_NO_DATA) { |
485 | if (data_size == 0) | 485 | if (data_size == 0) |
486 | rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET]; | 486 | rq.nr_sectors = (args->tf.hob_nsect << 8) | args->tf.nsect; |
487 | else | 487 | else |
488 | rq.nr_sectors = data_size / SECTOR_SIZE; | 488 | rq.nr_sectors = data_size / SECTOR_SIZE; |
489 | 489 | ||
@@ -519,8 +519,6 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
519 | ide_task_t args; | 519 | ide_task_t args; |
520 | u8 *outbuf = NULL; | 520 | u8 *outbuf = NULL; |
521 | u8 *inbuf = NULL; | 521 | u8 *inbuf = NULL; |
522 | u8 *argsptr = args.tfRegister; | ||
523 | u8 *hobsptr = args.hobRegister; | ||
524 | int err = 0; | 522 | int err = 0; |
525 | int tasksize = sizeof(struct ide_task_request_s); | 523 | int tasksize = sizeof(struct ide_task_request_s); |
526 | unsigned int taskin = 0; | 524 | unsigned int taskin = 0; |
@@ -572,9 +570,9 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
572 | } | 570 | } |
573 | 571 | ||
574 | memset(&args, 0, sizeof(ide_task_t)); | 572 | memset(&args, 0, sizeof(ide_task_t)); |
575 | memcpy(argsptr, req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE); | ||
576 | memcpy(hobsptr, req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE); | ||
577 | 573 | ||
574 | memcpy(&args.tf_array[0], req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2); | ||
575 | memcpy(&args.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE); | ||
578 | args.tf_in_flags = req_task->in_flags; | 576 | args.tf_in_flags = req_task->in_flags; |
579 | args.tf_out_flags = req_task->out_flags; | 577 | args.tf_out_flags = req_task->out_flags; |
580 | args.data_phase = req_task->data_phase; | 578 | args.data_phase = req_task->data_phase; |
@@ -628,8 +626,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
628 | goto abort; | 626 | goto abort; |
629 | } | 627 | } |
630 | 628 | ||
631 | memcpy(req_task->io_ports, &(args.tfRegister), HDIO_DRIVE_TASK_HDR_SIZE); | 629 | memcpy(req_task->hob_ports, &args.tf_array[0], HDIO_DRIVE_HOB_HDR_SIZE - 2); |
632 | memcpy(req_task->hob_ports, &(args.hobRegister), HDIO_DRIVE_HOB_HDR_SIZE); | 630 | memcpy(req_task->io_ports, &args.tf_array[6], HDIO_DRIVE_TASK_HDR_SIZE); |
633 | req_task->in_flags = args.tf_in_flags; | 631 | req_task->in_flags = args.tf_in_flags; |
634 | req_task->out_flags = args.tf_out_flags; | 632 | req_task->out_flags = args.tf_out_flags; |
635 | 633 | ||
@@ -688,6 +686,7 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
688 | u8 xfer_rate = 0; | 686 | u8 xfer_rate = 0; |
689 | int argsize = 4; | 687 | int argsize = 4; |
690 | ide_task_t tfargs; | 688 | ide_task_t tfargs; |
689 | struct ide_taskfile *tf = &tfargs.tf; | ||
691 | 690 | ||
692 | if (NULL == (void *) arg) { | 691 | if (NULL == (void *) arg) { |
693 | struct request rq; | 692 | struct request rq; |
@@ -699,13 +698,10 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
699 | return -EFAULT; | 698 | return -EFAULT; |
700 | 699 | ||
701 | memset(&tfargs, 0, sizeof(ide_task_t)); | 700 | memset(&tfargs, 0, sizeof(ide_task_t)); |
702 | tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2]; | 701 | tf->feature = args[2]; |
703 | tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3]; | 702 | tf->nsect = args[3]; |
704 | tfargs.tfRegister[IDE_SECTOR_OFFSET] = args[1]; | 703 | tf->lbal = args[1]; |
705 | tfargs.tfRegister[IDE_LCYL_OFFSET] = 0x00; | 704 | tf->command = args[0]; |
706 | tfargs.tfRegister[IDE_HCYL_OFFSET] = 0x00; | ||
707 | tfargs.tfRegister[IDE_SELECT_OFFSET] = 0x00; | ||
708 | tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0]; | ||
709 | 705 | ||
710 | if (args[3]) { | 706 | if (args[3]) { |
711 | argsize = 4 + (SECTOR_WORDS * 4 * args[3]); | 707 | argsize = 4 + (SECTOR_WORDS * 4 * args[3]); |
@@ -767,8 +763,7 @@ int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg) | |||
767 | ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) | 763 | ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) |
768 | { | 764 | { |
769 | ide_hwif_t *hwif = HWIF(drive); | 765 | ide_hwif_t *hwif = HWIF(drive); |
770 | task_struct_t *taskfile = (task_struct_t *) task->tfRegister; | 766 | struct ide_taskfile *tf = &task->tf; |
771 | hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister; | ||
772 | 767 | ||
773 | if (task->data_phase == TASKFILE_MULTI_IN || | 768 | if (task->data_phase == TASKFILE_MULTI_IN || |
774 | task->data_phase == TASKFILE_MULTI_OUT) { | 769 | task->data_phase == TASKFILE_MULTI_OUT) { |
@@ -798,34 +793,32 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) | |||
798 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); | 793 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); |
799 | SELECT_MASK(drive, 0); | 794 | SELECT_MASK(drive, 0); |
800 | 795 | ||
801 | if (task->tf_out_flags.b.data) { | 796 | if (task->tf_out_flags.b.data) |
802 | u16 data = taskfile->data + (hobfile->data << 8); | 797 | hwif->OUTW((tf->hob_data << 8) | tf->data, IDE_DATA_REG); |
803 | hwif->OUTW(data, IDE_DATA_REG); | ||
804 | } | ||
805 | 798 | ||
806 | /* (ks) send hob registers first */ | 799 | /* (ks) send hob registers first */ |
807 | if (task->tf_out_flags.b.nsector_hob) | 800 | if (task->tf_out_flags.b.nsector_hob) |
808 | hwif->OUTB(hobfile->sector_count, IDE_NSECTOR_REG); | 801 | hwif->OUTB(tf->hob_nsect, IDE_NSECTOR_REG); |
809 | if (task->tf_out_flags.b.sector_hob) | 802 | if (task->tf_out_flags.b.sector_hob) |
810 | hwif->OUTB(hobfile->sector_number, IDE_SECTOR_REG); | 803 | hwif->OUTB(tf->hob_lbal, IDE_SECTOR_REG); |
811 | if (task->tf_out_flags.b.lcyl_hob) | 804 | if (task->tf_out_flags.b.lcyl_hob) |
812 | hwif->OUTB(hobfile->low_cylinder, IDE_LCYL_REG); | 805 | hwif->OUTB(tf->hob_lbam, IDE_LCYL_REG); |
813 | if (task->tf_out_flags.b.hcyl_hob) | 806 | if (task->tf_out_flags.b.hcyl_hob) |
814 | hwif->OUTB(hobfile->high_cylinder, IDE_HCYL_REG); | 807 | hwif->OUTB(tf->hob_lbah, IDE_HCYL_REG); |
815 | 808 | ||
816 | /* (ks) Send now the standard registers */ | 809 | /* (ks) Send now the standard registers */ |
817 | if (task->tf_out_flags.b.error_feature) | 810 | if (task->tf_out_flags.b.error_feature) |
818 | hwif->OUTB(taskfile->feature, IDE_FEATURE_REG); | 811 | hwif->OUTB(tf->feature, IDE_FEATURE_REG); |
819 | /* refers to number of sectors to transfer */ | 812 | /* refers to number of sectors to transfer */ |
820 | if (task->tf_out_flags.b.nsector) | 813 | if (task->tf_out_flags.b.nsector) |
821 | hwif->OUTB(taskfile->sector_count, IDE_NSECTOR_REG); | 814 | hwif->OUTB(tf->nsect, IDE_NSECTOR_REG); |
822 | /* refers to sector offset or start sector */ | 815 | /* refers to sector offset or start sector */ |
823 | if (task->tf_out_flags.b.sector) | 816 | if (task->tf_out_flags.b.sector) |
824 | hwif->OUTB(taskfile->sector_number, IDE_SECTOR_REG); | 817 | hwif->OUTB(tf->lbal, IDE_SECTOR_REG); |
825 | if (task->tf_out_flags.b.lcyl) | 818 | if (task->tf_out_flags.b.lcyl) |
826 | hwif->OUTB(taskfile->low_cylinder, IDE_LCYL_REG); | 819 | hwif->OUTB(tf->lbam, IDE_LCYL_REG); |
827 | if (task->tf_out_flags.b.hcyl) | 820 | if (task->tf_out_flags.b.hcyl) |
828 | hwif->OUTB(taskfile->high_cylinder, IDE_HCYL_REG); | 821 | hwif->OUTB(tf->lbah, IDE_HCYL_REG); |
829 | 822 | ||
830 | /* | 823 | /* |
831 | * (ks) In the flagged taskfile approch, we will use all specified | 824 | * (ks) In the flagged taskfile approch, we will use all specified |
@@ -833,7 +826,7 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) | |||
833 | * select bit (master/slave) in the drive_head register. We must make | 826 | * select bit (master/slave) in the drive_head register. We must make |
834 | * sure that the desired drive is selected. | 827 | * sure that the desired drive is selected. |
835 | */ | 828 | */ |
836 | hwif->OUTB(taskfile->device_head | drive->select.all, IDE_SELECT_REG); | 829 | hwif->OUTB(tf->device | drive->select.all, IDE_SELECT_REG); |
837 | switch(task->data_phase) { | 830 | switch(task->data_phase) { |
838 | 831 | ||
839 | case TASKFILE_OUT_DMAQ: | 832 | case TASKFILE_OUT_DMAQ: |
@@ -844,7 +837,7 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) | |||
844 | break; | 837 | break; |
845 | 838 | ||
846 | if (!hwif->dma_setup(drive)) { | 839 | if (!hwif->dma_setup(drive)) { |
847 | hwif->dma_exec_cmd(drive, taskfile->command); | 840 | hwif->dma_exec_cmd(drive, tf->command); |
848 | hwif->dma_start(drive); | 841 | hwif->dma_start(drive); |
849 | return ide_started; | 842 | return ide_started; |
850 | } | 843 | } |
@@ -856,11 +849,11 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) | |||
856 | 849 | ||
857 | /* Issue the command */ | 850 | /* Issue the command */ |
858 | if (task->prehandler) { | 851 | if (task->prehandler) { |
859 | hwif->OUTBSYNC(drive, taskfile->command, IDE_COMMAND_REG); | 852 | hwif->OUTBSYNC(drive, tf->command, IDE_COMMAND_REG); |
860 | ndelay(400); /* FIXME */ | 853 | ndelay(400); /* FIXME */ |
861 | return task->prehandler(drive, task->rq); | 854 | return task->prehandler(drive, task->rq); |
862 | } | 855 | } |
863 | ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL); | 856 | ide_execute_command(drive, tf->command, task->handler, WAIT_WORSTCASE, NULL); |
864 | return ide_started; | 857 | return ide_started; |
865 | } | 858 | } |
866 | 859 | ||