diff options
Diffstat (limited to 'drivers/ide/ide-iops.c')
-rw-r--r-- | drivers/ide/ide-iops.c | 83 |
1 files changed, 56 insertions, 27 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 65275454a209..e981e2943073 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -132,8 +132,15 @@ static void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | |||
132 | ide_hwif_t *hwif = drive->hwif; | 132 | ide_hwif_t *hwif = drive->hwif; |
133 | struct ide_io_ports *io_ports = &hwif->io_ports; | 133 | struct ide_io_ports *io_ports = &hwif->io_ports; |
134 | struct ide_taskfile *tf = &task->tf; | 134 | struct ide_taskfile *tf = &task->tf; |
135 | void (*tf_outb)(u8 addr, unsigned long port); | ||
136 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | ||
135 | u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; | 137 | u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; |
136 | 138 | ||
139 | if (mmio) | ||
140 | tf_outb = ide_mm_outb; | ||
141 | else | ||
142 | tf_outb = ide_outb; | ||
143 | |||
137 | if (task->tf_flags & IDE_TFLAG_FLAGGED) | 144 | if (task->tf_flags & IDE_TFLAG_FLAGGED) |
138 | HIHI = 0xFF; | 145 | HIHI = 0xFF; |
139 | 146 | ||
@@ -142,34 +149,40 @@ static void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | |||
142 | if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0) | 149 | if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0) |
143 | SELECT_MASK(drive, 0); | 150 | SELECT_MASK(drive, 0); |
144 | 151 | ||
145 | if (task->tf_flags & IDE_TFLAG_OUT_DATA) | 152 | if (task->tf_flags & IDE_TFLAG_OUT_DATA) { |
146 | hwif->OUTW((tf->hob_data << 8) | tf->data, io_ports->data_addr); | 153 | u16 data = (tf->hob_data << 8) | tf->data; |
154 | |||
155 | if (mmio) | ||
156 | writew(data, (void __iomem *)io_ports->data_addr); | ||
157 | else | ||
158 | outw(data, io_ports->data_addr); | ||
159 | } | ||
147 | 160 | ||
148 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) | 161 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) |
149 | hwif->OUTB(tf->hob_feature, io_ports->feature_addr); | 162 | tf_outb(tf->hob_feature, io_ports->feature_addr); |
150 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) | 163 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) |
151 | hwif->OUTB(tf->hob_nsect, io_ports->nsect_addr); | 164 | tf_outb(tf->hob_nsect, io_ports->nsect_addr); |
152 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) | 165 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) |
153 | hwif->OUTB(tf->hob_lbal, io_ports->lbal_addr); | 166 | tf_outb(tf->hob_lbal, io_ports->lbal_addr); |
154 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) | 167 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) |
155 | hwif->OUTB(tf->hob_lbam, io_ports->lbam_addr); | 168 | tf_outb(tf->hob_lbam, io_ports->lbam_addr); |
156 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) | 169 | if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) |
157 | hwif->OUTB(tf->hob_lbah, io_ports->lbah_addr); | 170 | tf_outb(tf->hob_lbah, io_ports->lbah_addr); |
158 | 171 | ||
159 | if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) | 172 | if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) |
160 | hwif->OUTB(tf->feature, io_ports->feature_addr); | 173 | tf_outb(tf->feature, io_ports->feature_addr); |
161 | if (task->tf_flags & IDE_TFLAG_OUT_NSECT) | 174 | if (task->tf_flags & IDE_TFLAG_OUT_NSECT) |
162 | hwif->OUTB(tf->nsect, io_ports->nsect_addr); | 175 | tf_outb(tf->nsect, io_ports->nsect_addr); |
163 | if (task->tf_flags & IDE_TFLAG_OUT_LBAL) | 176 | if (task->tf_flags & IDE_TFLAG_OUT_LBAL) |
164 | hwif->OUTB(tf->lbal, io_ports->lbal_addr); | 177 | tf_outb(tf->lbal, io_ports->lbal_addr); |
165 | if (task->tf_flags & IDE_TFLAG_OUT_LBAM) | 178 | if (task->tf_flags & IDE_TFLAG_OUT_LBAM) |
166 | hwif->OUTB(tf->lbam, io_ports->lbam_addr); | 179 | tf_outb(tf->lbam, io_ports->lbam_addr); |
167 | if (task->tf_flags & IDE_TFLAG_OUT_LBAH) | 180 | if (task->tf_flags & IDE_TFLAG_OUT_LBAH) |
168 | hwif->OUTB(tf->lbah, io_ports->lbah_addr); | 181 | tf_outb(tf->lbah, io_ports->lbah_addr); |
169 | 182 | ||
170 | if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) | 183 | if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) |
171 | hwif->OUTB((tf->device & HIHI) | drive->select.all, | 184 | tf_outb((tf->device & HIHI) | drive->select.all, |
172 | io_ports->device_addr); | 185 | io_ports->device_addr); |
173 | } | 186 | } |
174 | 187 | ||
175 | static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) | 188 | static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) |
@@ -177,41 +190,57 @@ static void ide_tf_read(ide_drive_t *drive, ide_task_t *task) | |||
177 | ide_hwif_t *hwif = drive->hwif; | 190 | ide_hwif_t *hwif = drive->hwif; |
178 | struct ide_io_ports *io_ports = &hwif->io_ports; | 191 | struct ide_io_ports *io_ports = &hwif->io_ports; |
179 | struct ide_taskfile *tf = &task->tf; | 192 | struct ide_taskfile *tf = &task->tf; |
193 | void (*tf_outb)(u8 addr, unsigned long port); | ||
194 | u8 (*tf_inb)(unsigned long port); | ||
195 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | ||
196 | |||
197 | if (mmio) { | ||
198 | tf_outb = ide_mm_outb; | ||
199 | tf_inb = ide_mm_inb; | ||
200 | } else { | ||
201 | tf_outb = ide_outb; | ||
202 | tf_inb = ide_inb; | ||
203 | } | ||
180 | 204 | ||
181 | if (task->tf_flags & IDE_TFLAG_IN_DATA) { | 205 | if (task->tf_flags & IDE_TFLAG_IN_DATA) { |
182 | u16 data = hwif->INW(io_ports->data_addr); | 206 | u16 data; |
207 | |||
208 | if (mmio) | ||
209 | data = readw((void __iomem *)io_ports->data_addr); | ||
210 | else | ||
211 | data = inw(io_ports->data_addr); | ||
183 | 212 | ||
184 | tf->data = data & 0xff; | 213 | tf->data = data & 0xff; |
185 | tf->hob_data = (data >> 8) & 0xff; | 214 | tf->hob_data = (data >> 8) & 0xff; |
186 | } | 215 | } |
187 | 216 | ||
188 | /* be sure we're looking at the low order bits */ | 217 | /* be sure we're looking at the low order bits */ |
189 | hwif->OUTB(drive->ctl & ~0x80, io_ports->ctl_addr); | 218 | tf_outb(drive->ctl & ~0x80, io_ports->ctl_addr); |
190 | 219 | ||
191 | if (task->tf_flags & IDE_TFLAG_IN_NSECT) | 220 | if (task->tf_flags & IDE_TFLAG_IN_NSECT) |
192 | tf->nsect = hwif->INB(io_ports->nsect_addr); | 221 | tf->nsect = tf_inb(io_ports->nsect_addr); |
193 | if (task->tf_flags & IDE_TFLAG_IN_LBAL) | 222 | if (task->tf_flags & IDE_TFLAG_IN_LBAL) |
194 | tf->lbal = hwif->INB(io_ports->lbal_addr); | 223 | tf->lbal = tf_inb(io_ports->lbal_addr); |
195 | if (task->tf_flags & IDE_TFLAG_IN_LBAM) | 224 | if (task->tf_flags & IDE_TFLAG_IN_LBAM) |
196 | tf->lbam = hwif->INB(io_ports->lbam_addr); | 225 | tf->lbam = tf_inb(io_ports->lbam_addr); |
197 | if (task->tf_flags & IDE_TFLAG_IN_LBAH) | 226 | if (task->tf_flags & IDE_TFLAG_IN_LBAH) |
198 | tf->lbah = hwif->INB(io_ports->lbah_addr); | 227 | tf->lbah = tf_inb(io_ports->lbah_addr); |
199 | if (task->tf_flags & IDE_TFLAG_IN_DEVICE) | 228 | if (task->tf_flags & IDE_TFLAG_IN_DEVICE) |
200 | tf->device = hwif->INB(io_ports->device_addr); | 229 | tf->device = tf_inb(io_ports->device_addr); |
201 | 230 | ||
202 | if (task->tf_flags & IDE_TFLAG_LBA48) { | 231 | if (task->tf_flags & IDE_TFLAG_LBA48) { |
203 | hwif->OUTB(drive->ctl | 0x80, io_ports->ctl_addr); | 232 | tf_outb(drive->ctl | 0x80, io_ports->ctl_addr); |
204 | 233 | ||
205 | if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) | 234 | if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) |
206 | tf->hob_feature = hwif->INB(io_ports->feature_addr); | 235 | tf->hob_feature = tf_inb(io_ports->feature_addr); |
207 | if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) | 236 | if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT) |
208 | tf->hob_nsect = hwif->INB(io_ports->nsect_addr); | 237 | tf->hob_nsect = tf_inb(io_ports->nsect_addr); |
209 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) | 238 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL) |
210 | tf->hob_lbal = hwif->INB(io_ports->lbal_addr); | 239 | tf->hob_lbal = tf_inb(io_ports->lbal_addr); |
211 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) | 240 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM) |
212 | tf->hob_lbam = hwif->INB(io_ports->lbam_addr); | 241 | tf->hob_lbam = tf_inb(io_ports->lbam_addr); |
213 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) | 242 | if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH) |
214 | tf->hob_lbah = hwif->INB(io_ports->lbah_addr); | 243 | tf->hob_lbah = tf_inb(io_ports->lbah_addr); |
215 | } | 244 | } |
216 | } | 245 | } |
217 | 246 | ||