diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-04-28 17:44:36 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-04-28 17:44:36 -0400 |
commit | 92d3ab27e8fd23d1a9dc3b69d17b2afb83e5c6f5 (patch) | |
tree | e58076cb0102443dfe76401931a41931f97053cf | |
parent | 284aa76b5339ce79d5ad2ac1c7cbf717082816a7 (diff) |
falconide/q40ide: add ->atapi_*put_bytes and ->ata_*put_data methods (take 2)
* Add ->atapi_{in,out}put_bytes and ->ata_{in,out}put_data methods to
falconide and q40ide host drivers (->ata_* methods are implemented on
top of ->atapi_* methods so they also do byte-swapping now).
* Cleanup atapi_{in,out}put_bytes().
v2:
* Add 'struct request *rq' argument to ->ata_{in,out}put_data methods
and don't byte-swap disk fs requests (we shouldn't un-swap fs requests
because fs itself is stored byte-swapped on the disk) - this is how
things were done before the patch (ideally device mapper should be
used instead but it would break existing setups and would have some
performance impact).
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Michael Schmitz <schmitz@debian.org>
Cc: Roman Zippel <zippel@linux-m68k.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Richard Zidlicky <rz@linux-m68k.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r-- | drivers/ide/cris/ide-cris.c | 14 | ||||
-rw-r--r-- | drivers/ide/ide-io.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-iops.c | 26 | ||||
-rw-r--r-- | drivers/ide/ide-probe.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-taskfile.c | 16 | ||||
-rw-r--r-- | drivers/ide/legacy/falconide.c | 36 | ||||
-rw-r--r-- | drivers/ide/legacy/q40ide.c | 34 | ||||
-rw-r--r-- | include/linux/ide.h | 4 |
8 files changed, 98 insertions, 36 deletions
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index 9df26855bc05..aa263df76569 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c | |||
@@ -673,8 +673,10 @@ cris_ide_inb(unsigned long reg) | |||
673 | return (unsigned char)cris_ide_inw(reg); | 673 | return (unsigned char)cris_ide_inw(reg); |
674 | } | 674 | } |
675 | 675 | ||
676 | static void cris_ide_input_data (ide_drive_t *drive, void *, unsigned int); | 676 | static void cris_ide_input_data(ide_drive_t *, struct request *, |
677 | static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int); | 677 | void *, unsigned int); |
678 | static void cris_ide_output_data(ide_drive_t *, struct request *, | ||
679 | void *, unsigned int); | ||
678 | static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int); | 680 | static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int); |
679 | static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int); | 681 | static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int); |
680 | 682 | ||
@@ -900,8 +902,8 @@ cris_atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecoun | |||
900 | /* | 902 | /* |
901 | * This is used for most PIO data transfers *from* the IDE interface | 903 | * This is used for most PIO data transfers *from* the IDE interface |
902 | */ | 904 | */ |
903 | static void | 905 | static void cris_ide_input_data(ide_drive_t *drive, struct request *rq, |
904 | cris_ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) | 906 | void *buffer, unsigned int wcount) |
905 | { | 907 | { |
906 | cris_atapi_input_bytes(drive, buffer, wcount << 2); | 908 | cris_atapi_input_bytes(drive, buffer, wcount << 2); |
907 | } | 909 | } |
@@ -909,8 +911,8 @@ cris_ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount) | |||
909 | /* | 911 | /* |
910 | * This is used for most PIO data transfers *to* the IDE interface | 912 | * This is used for most PIO data transfers *to* the IDE interface |
911 | */ | 913 | */ |
912 | static void | 914 | static void cris_ide_output_data(ide_drive_t *drive, struct request *, |
913 | cris_ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount) | 915 | void *buffer, unsigned int wcount) |
914 | { | 916 | { |
915 | cris_atapi_output_bytes(drive, buffer, wcount << 2); | 917 | cris_atapi_output_bytes(drive, buffer, wcount << 2); |
916 | } | 918 | } |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 3a2d8930d17f..60078cf307fb 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -422,7 +422,7 @@ static void try_to_flush_leftover_data (ide_drive_t *drive) | |||
422 | u32 wcount = (i > 16) ? 16 : i; | 422 | u32 wcount = (i > 16) ? 16 : i; |
423 | 423 | ||
424 | i -= wcount; | 424 | i -= wcount; |
425 | HWIF(drive)->ata_input_data(drive, buffer, wcount); | 425 | drive->hwif->ata_input_data(drive, NULL, buffer, wcount); |
426 | } | 426 | } |
427 | } | 427 | } |
428 | 428 | ||
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 5425d3038ec2..7ec7fa2aef96 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -192,7 +192,8 @@ static void ata_vlb_sync(ide_drive_t *drive, unsigned long port) | |||
192 | /* | 192 | /* |
193 | * This is used for most PIO data transfers *from* the IDE interface | 193 | * This is used for most PIO data transfers *from* the IDE interface |
194 | */ | 194 | */ |
195 | static void ata_input_data(ide_drive_t *drive, void *buffer, u32 wcount) | 195 | static void ata_input_data(ide_drive_t *drive, struct request *rq, |
196 | void *buffer, u32 wcount) | ||
196 | { | 197 | { |
197 | ide_hwif_t *hwif = drive->hwif; | 198 | ide_hwif_t *hwif = drive->hwif; |
198 | struct ide_io_ports *io_ports = &hwif->io_ports; | 199 | struct ide_io_ports *io_ports = &hwif->io_ports; |
@@ -215,7 +216,8 @@ static void ata_input_data(ide_drive_t *drive, void *buffer, u32 wcount) | |||
215 | /* | 216 | /* |
216 | * This is used for most PIO data transfers *to* the IDE interface | 217 | * This is used for most PIO data transfers *to* the IDE interface |
217 | */ | 218 | */ |
218 | static void ata_output_data(ide_drive_t *drive, void *buffer, u32 wcount) | 219 | static void ata_output_data(ide_drive_t *drive, struct request *rq, |
220 | void *buffer, u32 wcount) | ||
219 | { | 221 | { |
220 | ide_hwif_t *hwif = drive->hwif; | 222 | ide_hwif_t *hwif = drive->hwif; |
221 | struct ide_io_ports *io_ports = &hwif->io_ports; | 223 | struct ide_io_ports *io_ports = &hwif->io_ports; |
@@ -248,14 +250,7 @@ static void atapi_input_bytes(ide_drive_t *drive, void *buffer, u32 bytecount) | |||
248 | ide_hwif_t *hwif = HWIF(drive); | 250 | ide_hwif_t *hwif = HWIF(drive); |
249 | 251 | ||
250 | ++bytecount; | 252 | ++bytecount; |
251 | #if defined(CONFIG_ATARI) || defined(CONFIG_Q40) | 253 | hwif->ata_input_data(drive, NULL, buffer, bytecount / 4); |
252 | if (MACH_IS_ATARI || MACH_IS_Q40) { | ||
253 | /* Atari has a byte-swapped IDE interface */ | ||
254 | insw_swapw(hwif->io_ports.data_addr, buffer, bytecount / 2); | ||
255 | return; | ||
256 | } | ||
257 | #endif /* CONFIG_ATARI || CONFIG_Q40 */ | ||
258 | hwif->ata_input_data(drive, buffer, bytecount / 4); | ||
259 | if ((bytecount & 0x03) >= 2) | 254 | if ((bytecount & 0x03) >= 2) |
260 | hwif->INSW(hwif->io_ports.data_addr, | 255 | hwif->INSW(hwif->io_ports.data_addr, |
261 | (u8 *)buffer + (bytecount & ~0x03), 1); | 256 | (u8 *)buffer + (bytecount & ~0x03), 1); |
@@ -266,14 +261,7 @@ static void atapi_output_bytes(ide_drive_t *drive, void *buffer, u32 bytecount) | |||
266 | ide_hwif_t *hwif = HWIF(drive); | 261 | ide_hwif_t *hwif = HWIF(drive); |
267 | 262 | ||
268 | ++bytecount; | 263 | ++bytecount; |
269 | #if defined(CONFIG_ATARI) || defined(CONFIG_Q40) | 264 | hwif->ata_output_data(drive, NULL, buffer, bytecount / 4); |
270 | if (MACH_IS_ATARI || MACH_IS_Q40) { | ||
271 | /* Atari has a byte-swapped IDE interface */ | ||
272 | outsw_swapw(hwif->io_ports.data_addr, buffer, bytecount / 2); | ||
273 | return; | ||
274 | } | ||
275 | #endif /* CONFIG_ATARI || CONFIG_Q40 */ | ||
276 | hwif->ata_output_data(drive, buffer, bytecount / 4); | ||
277 | if ((bytecount & 0x03) >= 2) | 265 | if ((bytecount & 0x03) >= 2) |
278 | hwif->OUTSW(hwif->io_ports.data_addr, | 266 | hwif->OUTSW(hwif->io_ports.data_addr, |
279 | (u8 *)buffer + (bytecount & ~0x03), 1); | 267 | (u8 *)buffer + (bytecount & ~0x03), 1); |
@@ -668,7 +656,7 @@ int ide_driveid_update(ide_drive_t *drive) | |||
668 | local_irq_restore(flags); | 656 | local_irq_restore(flags); |
669 | return 0; | 657 | return 0; |
670 | } | 658 | } |
671 | hwif->ata_input_data(drive, id, SECTOR_WORDS); | 659 | hwif->ata_input_data(drive, NULL, id, SECTOR_WORDS); |
672 | (void)ide_read_status(drive); /* clear drive IRQ */ | 660 | (void)ide_read_status(drive); /* clear drive IRQ */ |
673 | local_irq_enable(); | 661 | local_irq_enable(); |
674 | local_irq_restore(flags); | 662 | local_irq_restore(flags); |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 862f02603f9b..e06a64605215 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -124,7 +124,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) | |||
124 | 124 | ||
125 | id = drive->id; | 125 | id = drive->id; |
126 | /* read 512 bytes of id info */ | 126 | /* read 512 bytes of id info */ |
127 | hwif->ata_input_data(drive, id, SECTOR_WORDS); | 127 | hwif->ata_input_data(drive, NULL, id, SECTOR_WORDS); |
128 | 128 | ||
129 | drive->id_read = 1; | 129 | drive->id_read = 1; |
130 | local_irq_enable(); | 130 | local_irq_enable(); |
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 9f9ad9fb6b89..7f6bfd314411 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -283,7 +283,8 @@ static u8 wait_drive_not_busy(ide_drive_t *drive) | |||
283 | return stat; | 283 | return stat; |
284 | } | 284 | } |
285 | 285 | ||
286 | static void ide_pio_sector(ide_drive_t *drive, unsigned int write) | 286 | static void ide_pio_sector(ide_drive_t *drive, struct request *rq, |
287 | unsigned int write) | ||
287 | { | 288 | { |
288 | ide_hwif_t *hwif = drive->hwif; | 289 | ide_hwif_t *hwif = drive->hwif; |
289 | struct scatterlist *sg = hwif->sg_table; | 290 | struct scatterlist *sg = hwif->sg_table; |
@@ -323,9 +324,9 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write) | |||
323 | 324 | ||
324 | /* do the actual data transfer */ | 325 | /* do the actual data transfer */ |
325 | if (write) | 326 | if (write) |
326 | hwif->ata_output_data(drive, buf, SECTOR_WORDS); | 327 | hwif->ata_output_data(drive, rq, buf, SECTOR_WORDS); |
327 | else | 328 | else |
328 | hwif->ata_input_data(drive, buf, SECTOR_WORDS); | 329 | hwif->ata_input_data(drive, rq, buf, SECTOR_WORDS); |
329 | 330 | ||
330 | kunmap_atomic(buf, KM_BIO_SRC_IRQ); | 331 | kunmap_atomic(buf, KM_BIO_SRC_IRQ); |
331 | #ifdef CONFIG_HIGHMEM | 332 | #ifdef CONFIG_HIGHMEM |
@@ -333,13 +334,14 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write) | |||
333 | #endif | 334 | #endif |
334 | } | 335 | } |
335 | 336 | ||
336 | static void ide_pio_multi(ide_drive_t *drive, unsigned int write) | 337 | static void ide_pio_multi(ide_drive_t *drive, struct request *rq, |
338 | unsigned int write) | ||
337 | { | 339 | { |
338 | unsigned int nsect; | 340 | unsigned int nsect; |
339 | 341 | ||
340 | nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count); | 342 | nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count); |
341 | while (nsect--) | 343 | while (nsect--) |
342 | ide_pio_sector(drive, write); | 344 | ide_pio_sector(drive, rq, write); |
343 | } | 345 | } |
344 | 346 | ||
345 | static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, | 347 | static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, |
@@ -362,10 +364,10 @@ static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, | |||
362 | switch (drive->hwif->data_phase) { | 364 | switch (drive->hwif->data_phase) { |
363 | case TASKFILE_MULTI_IN: | 365 | case TASKFILE_MULTI_IN: |
364 | case TASKFILE_MULTI_OUT: | 366 | case TASKFILE_MULTI_OUT: |
365 | ide_pio_multi(drive, write); | 367 | ide_pio_multi(drive, rq, write); |
366 | break; | 368 | break; |
367 | default: | 369 | default: |
368 | ide_pio_sector(drive, write); | 370 | ide_pio_sector(drive, rq, write); |
369 | break; | 371 | break; |
370 | } | 372 | } |
371 | 373 | ||
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index 56cdaa0eeea5..32c044b17d45 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c | |||
@@ -44,6 +44,36 @@ | |||
44 | int falconide_intr_lock; | 44 | int falconide_intr_lock; |
45 | EXPORT_SYMBOL(falconide_intr_lock); | 45 | EXPORT_SYMBOL(falconide_intr_lock); |
46 | 46 | ||
47 | static void falconide_atapi_input_bytes(ide_drive_t *drive, void *buf, | ||
48 | unsigned int len) | ||
49 | { | ||
50 | insw_swapw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); | ||
51 | } | ||
52 | |||
53 | static void falconide_atapi_output_bytes(ide_drive_t *drive, void *buf, | ||
54 | unsigned int len) | ||
55 | { | ||
56 | outsw_swapw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); | ||
57 | } | ||
58 | |||
59 | static void falconide_ata_input_data(ide_drive_t *drive, struct request *rq, | ||
60 | void *buf, unsigned int wcount) | ||
61 | { | ||
62 | if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) | ||
63 | return insw(drive->hwif->io_ports.data_addr, buf, wcount * 2); | ||
64 | |||
65 | falconide_atapi_input_bytes(drive, buf, wcount * 4); | ||
66 | } | ||
67 | |||
68 | static void falconide_ata_output_data(ide_drive_t *drive, struct request *rq, | ||
69 | void *buf, unsigned int wcount) | ||
70 | { | ||
71 | if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) | ||
72 | return outsw(drive->hwif->io_ports.data_addr, buf, wcount * 2); | ||
73 | |||
74 | falconide_atapi_output_bytes(drive, buf, wcount * 4); | ||
75 | } | ||
76 | |||
47 | static void __init falconide_setup_ports(hw_regs_t *hw) | 77 | static void __init falconide_setup_ports(hw_regs_t *hw) |
48 | { | 78 | { |
49 | int i; | 79 | int i; |
@@ -90,6 +120,12 @@ static int __init falconide_init(void) | |||
90 | ide_init_port_data(hwif, index); | 120 | ide_init_port_data(hwif, index); |
91 | ide_init_port_hw(hwif, &hw); | 121 | ide_init_port_hw(hwif, &hw); |
92 | 122 | ||
123 | /* Atari has a byte-swapped IDE interface */ | ||
124 | hwif->atapi_input_bytes = falconide_atapi_input_bytes; | ||
125 | hwif->atapi_output_bytes = falconide_atapi_output_bytes; | ||
126 | hwif->ata_input_data = falconide_ata_input_data; | ||
127 | hwif->ata_output_data = falconide_ata_output_data; | ||
128 | |||
93 | ide_get_lock(NULL, NULL); | 129 | ide_get_lock(NULL, NULL); |
94 | ide_device_add(idx, NULL); | 130 | ide_device_add(idx, NULL); |
95 | ide_release_lock(); | 131 | ide_release_lock(); |
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c index f9210458aea0..deae3d2ca65e 100644 --- a/drivers/ide/legacy/q40ide.c +++ b/drivers/ide/legacy/q40ide.c | |||
@@ -72,7 +72,35 @@ static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base, | |||
72 | hw->ack_intr = ack_intr; | 72 | hw->ack_intr = ack_intr; |
73 | } | 73 | } |
74 | 74 | ||
75 | static void q40ide_atapi_input_bytes(ide_drive_t *drive, void *buf, | ||
76 | unsigned int len) | ||
77 | { | ||
78 | insw_swapw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); | ||
79 | } | ||
75 | 80 | ||
81 | static void q40ide_atapi_output_bytes(ide_drive_t *drive, void *buf, | ||
82 | unsigned int len) | ||
83 | { | ||
84 | outsw_swapw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2); | ||
85 | } | ||
86 | |||
87 | static void q40ide_ata_input_data(ide_drive_t *drive, struct request *rq, | ||
88 | void *buf, unsigned int wcount) | ||
89 | { | ||
90 | if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) | ||
91 | return insw(drive->hwif->io_ports.data_addr, buf, wcount * 2); | ||
92 | |||
93 | q40ide_atapi_input_bytes(drive, buf, wcount * 4); | ||
94 | } | ||
95 | |||
96 | static void q40ide_ata_output_data(ide_drive_t *drive, struct request *rq, | ||
97 | void *buf, unsigned int wcount) | ||
98 | { | ||
99 | if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) | ||
100 | return outsw(drive->hwif->io_ports.data_addr, buf, wcount * 2); | ||
101 | |||
102 | q40ide_atapi_output_bytes(drive, buf, wcount * 4); | ||
103 | } | ||
76 | 104 | ||
77 | /* | 105 | /* |
78 | * the static array is needed to have the name reported in /proc/ioports, | 106 | * the static array is needed to have the name reported in /proc/ioports, |
@@ -123,6 +151,12 @@ static int __init q40ide_init(void) | |||
123 | ide_init_port_data(hwif, hwif->index); | 151 | ide_init_port_data(hwif, hwif->index); |
124 | ide_init_port_hw(hwif, &hw); | 152 | ide_init_port_hw(hwif, &hw); |
125 | 153 | ||
154 | /* Q40 has a byte-swapped IDE interface */ | ||
155 | hwif->atapi_input_bytes = q40ide_atapi_input_bytes; | ||
156 | hwif->atapi_output_bytes = q40ide_atapi_output_bytes; | ||
157 | hwif->ata_input_data = q40ide_ata_input_data; | ||
158 | hwif->ata_output_data = q40ide_ata_output_data; | ||
159 | |||
126 | idx[i] = hwif->index; | 160 | idx[i] = hwif->index; |
127 | } | 161 | } |
128 | } | 162 | } |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 32fd77bb4436..0cbc46bf08a5 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -467,8 +467,8 @@ typedef struct hwif_s { | |||
467 | const struct ide_port_ops *port_ops; | 467 | const struct ide_port_ops *port_ops; |
468 | const struct ide_dma_ops *dma_ops; | 468 | const struct ide_dma_ops *dma_ops; |
469 | 469 | ||
470 | void (*ata_input_data)(ide_drive_t *, void *, u32); | 470 | void (*ata_input_data)(ide_drive_t *, struct request *, void *, u32); |
471 | void (*ata_output_data)(ide_drive_t *, void *, u32); | 471 | void (*ata_output_data)(ide_drive_t *, struct request *, void *, u32); |
472 | 472 | ||
473 | void (*atapi_input_bytes)(ide_drive_t *, void *, u32); | 473 | void (*atapi_input_bytes)(ide_drive_t *, void *, u32); |
474 | void (*atapi_output_bytes)(ide_drive_t *, void *, u32); | 474 | void (*atapi_output_bytes)(ide_drive_t *, void *, u32); |