aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-io-std.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-io-std.c')
-rw-r--r--drivers/ide/ide-io-std.c60
1 files changed, 28 insertions, 32 deletions
diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c
index 31f5c5f4c093..96a537da8925 100644
--- a/drivers/ide/ide-io-std.c
+++ b/drivers/ide/ide-io-std.c
@@ -216,11 +216,10 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
216 ide_hwif_t *hwif = drive->hwif; 216 ide_hwif_t *hwif = drive->hwif;
217 struct ide_io_ports *io_ports = &hwif->io_ports; 217 struct ide_io_ports *io_ports = &hwif->io_ports;
218 unsigned long data_addr = io_ports->data_addr; 218 unsigned long data_addr = io_ports->data_addr;
219 unsigned int words = (len + 1) >> 1;
219 u8 io_32bit = drive->io_32bit; 220 u8 io_32bit = drive->io_32bit;
220 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; 221 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
221 222
222 len++;
223
224 if (io_32bit) { 223 if (io_32bit) {
225 unsigned long uninitialized_var(flags); 224 unsigned long uninitialized_var(flags);
226 225
@@ -229,27 +228,26 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
229 ata_vlb_sync(io_ports->nsect_addr); 228 ata_vlb_sync(io_ports->nsect_addr);
230 } 229 }
231 230
231 words >>= 1;
232 if (mmio) 232 if (mmio)
233 __ide_mm_insl((void __iomem *)data_addr, buf, len / 4); 233 __ide_mm_insl((void __iomem *)data_addr, buf, words);
234 else 234 else
235 insl(data_addr, buf, len / 4); 235 insl(data_addr, buf, words);
236 236
237 if ((io_32bit & 2) && !mmio) 237 if ((io_32bit & 2) && !mmio)
238 local_irq_restore(flags); 238 local_irq_restore(flags);
239 239
240 if ((len & 3) >= 2) { 240 if (((len + 1) & 3) < 2)
241 if (mmio) 241 return;
242 __ide_mm_insw((void __iomem *)data_addr, 242
243 (u8 *)buf + (len & ~3), 1); 243 buf += len & ~3;
244 else 244 words = 1;
245 insw(data_addr, (u8 *)buf + (len & ~3), 1);
246 }
247 } else {
248 if (mmio)
249 __ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
250 else
251 insw(data_addr, buf, len / 2);
252 } 245 }
246
247 if (mmio)
248 __ide_mm_insw((void __iomem *)data_addr, buf, words);
249 else
250 insw(data_addr, buf, words);
253} 251}
254EXPORT_SYMBOL_GPL(ide_input_data); 252EXPORT_SYMBOL_GPL(ide_input_data);
255 253
@@ -262,11 +260,10 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
262 ide_hwif_t *hwif = drive->hwif; 260 ide_hwif_t *hwif = drive->hwif;
263 struct ide_io_ports *io_ports = &hwif->io_ports; 261 struct ide_io_ports *io_ports = &hwif->io_ports;
264 unsigned long data_addr = io_ports->data_addr; 262 unsigned long data_addr = io_ports->data_addr;
263 unsigned int words = (len + 1) >> 1;
265 u8 io_32bit = drive->io_32bit; 264 u8 io_32bit = drive->io_32bit;
266 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; 265 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
267 266
268 len++;
269
270 if (io_32bit) { 267 if (io_32bit) {
271 unsigned long uninitialized_var(flags); 268 unsigned long uninitialized_var(flags);
272 269
@@ -275,27 +272,26 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
275 ata_vlb_sync(io_ports->nsect_addr); 272 ata_vlb_sync(io_ports->nsect_addr);
276 } 273 }
277 274
275 words >>= 1;
278 if (mmio) 276 if (mmio)
279 __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4); 277 __ide_mm_outsl((void __iomem *)data_addr, buf, words);
280 else 278 else
281 outsl(data_addr, buf, len / 4); 279 outsl(data_addr, buf, words);
282 280
283 if ((io_32bit & 2) && !mmio) 281 if ((io_32bit & 2) && !mmio)
284 local_irq_restore(flags); 282 local_irq_restore(flags);
285 283
286 if ((len & 3) >= 2) { 284 if (((len + 1) & 3) < 2)
287 if (mmio) 285 return;
288 __ide_mm_outsw((void __iomem *)data_addr, 286
289 (u8 *)buf + (len & ~3), 1); 287 buf += len & ~3;
290 else 288 words = 1;
291 outsw(data_addr, (u8 *)buf + (len & ~3), 1);
292 }
293 } else {
294 if (mmio)
295 __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
296 else
297 outsw(data_addr, buf, len / 2);
298 } 289 }
290
291 if (mmio)
292 __ide_mm_outsw((void __iomem *)data_addr, buf, words);
293 else
294 outsw(data_addr, buf, words);
299} 295}
300EXPORT_SYMBOL_GPL(ide_output_data); 296EXPORT_SYMBOL_GPL(ide_output_data);
301 297