diff options
Diffstat (limited to 'drivers/ide/ide-iops.c')
-rw-r--r-- | drivers/ide/ide-iops.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index dfe47d5eb157..ac9e063bcf93 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -127,6 +127,94 @@ void SELECT_MASK (ide_drive_t *drive, int mask) | |||
127 | port_ops->maskproc(drive, mask); | 127 | port_ops->maskproc(drive, mask); |
128 | } | 128 | } |
129 | 129 | ||
130 | void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | ||
131 | { | ||
132 | ide_hwif_t *hwif = drive->hwif; | ||
133 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
134 | struct ide_taskfile *tf = &task->tf; | ||
135 | u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; | ||
136 | |||
137 | if (task->tf_flags & IDE_TFLAG_FLAGGED) | ||
138 | HIHI = 0xFF; | ||
139 | |||
140 | ide_set_irq(drive, 1); | ||
141 | |||
142 | if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0) | ||
143 | SELECT_MASK(drive, 0); | ||
144 | |||
145 | if (task->tf_flags & IDE_TFLAG_OUT_DATA) | ||
146 | hwif->OUTW((tf->hob_data << 8) | tf->data, io_ports->data_addr); | ||
147 | |||
148 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) | ||
149 | hwif->OUTB(tf->hob_feature, io_ports->feature_addr); | ||
150 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) | ||
151 | hwif->OUTB(tf->hob_nsect, io_ports->nsect_addr); | ||
152 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) | ||
153 | hwif->OUTB(tf->hob_lbal, io_ports->lbal_addr); | ||
154 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) | ||
155 | hwif->OUTB(tf->hob_lbam, io_ports->lbam_addr); | ||
156 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) | ||
157 | hwif->OUTB(tf->hob_lbah, io_ports->lbah_addr); | ||
158 | |||
159 | if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) | ||
160 | hwif->OUTB(tf->feature, io_ports->feature_addr); | ||
161 | if (task->tf_flags & IDE_TFLAG_OUT_NSECT) | ||
162 | hwif->OUTB(tf->nsect, io_ports->nsect_addr); | ||
163 | if (task->tf_flags & IDE_TFLAG_OUT_LBAL) | ||
164 | hwif->OUTB(tf->lbal, io_ports->lbal_addr); | ||
165 | if (task->tf_flags & IDE_TFLAG_OUT_LBAM) | ||
166 | hwif->OUTB(tf->lbam, io_ports->lbam_addr); | ||
167 | if (task->tf_flags & IDE_TFLAG_OUT_LBAH) | ||
168 | hwif->OUTB(tf->lbah, io_ports->lbah_addr); | ||
169 | |||
170 | if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) | ||
171 | hwif->OUTB((tf->device & HIHI) | drive->select.all, | ||
172 | io_ports->device_addr); | ||
173 | } | ||
174 | |||
175 | void ide_tf_read(ide_drive_t *drive, ide_task_t *task) | ||
176 | { | ||
177 | ide_hwif_t *hwif = drive->hwif; | ||
178 | struct ide_io_ports *io_ports = &hwif->io_ports; | ||
179 | struct ide_taskfile *tf = &task->tf; | ||
180 | |||
181 | if (task->tf_flags & IDE_TFLAG_IN_DATA) { | ||
182 | u16 data = hwif->INW(io_ports->data_addr); | ||
183 | |||
184 | tf->data = data & 0xff; | ||
185 | tf->hob_data = (data >> 8) & 0xff; | ||
186 | } | ||
187 | |||
188 | /* be sure we're looking at the low order bits */ | ||
189 | hwif->OUTB(drive->ctl & ~0x80, io_ports->ctl_addr); | ||
190 | |||
191 | if (task->tf_flags & IDE_TFLAG_IN_NSECT) | ||
192 | tf->nsect = hwif->INB(io_ports->nsect_addr); | ||
193 | if (task->tf_flags & IDE_TFLAG_IN_LBAL) | ||
194 | tf->lbal = hwif->INB(io_ports->lbal_addr); | ||
195 | if (task->tf_flags & IDE_TFLAG_IN_LBAM) | ||
196 | tf->lbam = hwif->INB(io_ports->lbam_addr); | ||
197 | if (task->tf_flags & IDE_TFLAG_IN_LBAH) | ||
198 | tf->lbah = hwif->INB(io_ports->lbah_addr); | ||
199 | if (task->tf_flags & IDE_TFLAG_IN_DEVICE) | ||
200 | tf->device = hwif->INB(io_ports->device_addr); | ||
201 | |||
202 | if (task->tf_flags & IDE_TFLAG_LBA48) { | ||
203 | hwif->OUTB(drive->ctl | 0x80, io_ports->ctl_addr); | ||
204 | |||
205 | if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) | ||
206 | tf->hob_feature = hwif->INB(io_ports->feature_addr); | ||
207 | if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) | ||
208 | tf->hob_nsect = hwif->INB(io_ports->nsect_addr); | ||
209 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) | ||
210 | tf->hob_lbal = hwif->INB(io_ports->lbal_addr); | ||
211 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) | ||
212 | tf->hob_lbam = hwif->INB(io_ports->lbam_addr); | ||
213 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) | ||
214 | tf->hob_lbah = hwif->INB(io_ports->lbah_addr); | ||
215 | } | ||
216 | } | ||
217 | |||
130 | /* | 218 | /* |
131 | * Some localbus EIDE interfaces require a special access sequence | 219 | * Some localbus EIDE interfaces require a special access sequence |
132 | * when using 32-bit I/O instructions to transfer data. We call this | 220 | * when using 32-bit I/O instructions to transfer data. We call this |