aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-taskfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-taskfile.c')
-rw-r--r--drivers/ide/ide-taskfile.c99
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)
66int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf) 66int 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)
81ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task) 82ide_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)
767ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task) 763ide_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