aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-04-28 17:44:36 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-04-28 17:44:36 -0400
commit92d3ab27e8fd23d1a9dc3b69d17b2afb83e5c6f5 (patch)
treee58076cb0102443dfe76401931a41931f97053cf
parent284aa76b5339ce79d5ad2ac1c7cbf717082816a7 (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.c14
-rw-r--r--drivers/ide/ide-io.c2
-rw-r--r--drivers/ide/ide-iops.c26
-rw-r--r--drivers/ide/ide-probe.c2
-rw-r--r--drivers/ide/ide-taskfile.c16
-rw-r--r--drivers/ide/legacy/falconide.c36
-rw-r--r--drivers/ide/legacy/q40ide.c34
-rw-r--r--include/linux/ide.h4
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
676static void cris_ide_input_data (ide_drive_t *drive, void *, unsigned int); 676static void cris_ide_input_data(ide_drive_t *, struct request *,
677static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int); 677 void *, unsigned int);
678static void cris_ide_output_data(ide_drive_t *, struct request *,
679 void *, unsigned int);
678static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int); 680static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
679static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int); 681static 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 */
903static void 905static void cris_ide_input_data(ide_drive_t *drive, struct request *rq,
904cris_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 */
912static void 914static void cris_ide_output_data(ide_drive_t *drive, struct request *,
913cris_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 */
195static void ata_input_data(ide_drive_t *drive, void *buffer, u32 wcount) 195static 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 */
218static void ata_output_data(ide_drive_t *drive, void *buffer, u32 wcount) 219static 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
286static void ide_pio_sector(ide_drive_t *drive, unsigned int write) 286static 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
336static void ide_pio_multi(ide_drive_t *drive, unsigned int write) 337static 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
345static void ide_pio_datablock(ide_drive_t *drive, struct request *rq, 347static 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 @@
44int falconide_intr_lock; 44int falconide_intr_lock;
45EXPORT_SYMBOL(falconide_intr_lock); 45EXPORT_SYMBOL(falconide_intr_lock);
46 46
47static 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
53static 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
59static 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
68static 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
47static void __init falconide_setup_ports(hw_regs_t *hw) 77static 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
75static 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
81static 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
87static 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
96static 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);