aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-iops.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-iops.c')
-rw-r--r--drivers/ide/ide-iops.c114
1 files changed, 48 insertions, 66 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index fbbbb30ae964..1789fbab2daf 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -42,16 +42,6 @@ static u16 ide_inw (unsigned long port)
42 return (u16) inw(port); 42 return (u16) inw(port);
43} 43}
44 44
45static void ide_insw (unsigned long port, void *addr, u32 count)
46{
47 insw(port, addr, count);
48}
49
50static void ide_insl (unsigned long port, void *addr, u32 count)
51{
52 insl(port, addr, count);
53}
54
55static void ide_outb (u8 val, unsigned long port) 45static void ide_outb (u8 val, unsigned long port)
56{ 46{
57 outb(val, port); 47 outb(val, port);
@@ -67,27 +57,13 @@ static void ide_outw (u16 val, unsigned long port)
67 outw(val, port); 57 outw(val, port);
68} 58}
69 59
70static void ide_outsw (unsigned long port, void *addr, u32 count)
71{
72 outsw(port, addr, count);
73}
74
75static void ide_outsl (unsigned long port, void *addr, u32 count)
76{
77 outsl(port, addr, count);
78}
79
80void default_hwif_iops (ide_hwif_t *hwif) 60void default_hwif_iops (ide_hwif_t *hwif)
81{ 61{
82 hwif->OUTB = ide_outb; 62 hwif->OUTB = ide_outb;
83 hwif->OUTBSYNC = ide_outbsync; 63 hwif->OUTBSYNC = ide_outbsync;
84 hwif->OUTW = ide_outw; 64 hwif->OUTW = ide_outw;
85 hwif->OUTSW = ide_outsw;
86 hwif->OUTSL = ide_outsl;
87 hwif->INB = ide_inb; 65 hwif->INB = ide_inb;
88 hwif->INW = ide_inw; 66 hwif->INW = ide_inw;
89 hwif->INSW = ide_insw;
90 hwif->INSL = ide_insl;
91} 67}
92 68
93/* 69/*
@@ -104,16 +80,6 @@ static u16 ide_mm_inw (unsigned long port)
104 return (u16) readw((void __iomem *) port); 80 return (u16) readw((void __iomem *) port);
105} 81}
106 82
107static void ide_mm_insw (unsigned long port, void *addr, u32 count)
108{
109 __ide_mm_insw((void __iomem *) port, addr, count);
110}
111
112static void ide_mm_insl (unsigned long port, void *addr, u32 count)
113{
114 __ide_mm_insl((void __iomem *) port, addr, count);
115}
116
117static void ide_mm_outb (u8 value, unsigned long port) 83static void ide_mm_outb (u8 value, unsigned long port)
118{ 84{
119 writeb(value, (void __iomem *) port); 85 writeb(value, (void __iomem *) port);
@@ -129,16 +95,6 @@ static void ide_mm_outw (u16 value, unsigned long port)
129 writew(value, (void __iomem *) port); 95 writew(value, (void __iomem *) port);
130} 96}
131 97
132static void ide_mm_outsw (unsigned long port, void *addr, u32 count)
133{
134 __ide_mm_outsw((void __iomem *) port, addr, count);
135}
136
137static void ide_mm_outsl (unsigned long port, void *addr, u32 count)
138{
139 __ide_mm_outsl((void __iomem *) port, addr, count);
140}
141
142void default_hwif_mmiops (ide_hwif_t *hwif) 98void default_hwif_mmiops (ide_hwif_t *hwif)
143{ 99{
144 hwif->OUTB = ide_mm_outb; 100 hwif->OUTB = ide_mm_outb;
@@ -146,12 +102,8 @@ void default_hwif_mmiops (ide_hwif_t *hwif)
146 this one is controller specific! */ 102 this one is controller specific! */
147 hwif->OUTBSYNC = ide_mm_outbsync; 103 hwif->OUTBSYNC = ide_mm_outbsync;
148 hwif->OUTW = ide_mm_outw; 104 hwif->OUTW = ide_mm_outw;
149 hwif->OUTSW = ide_mm_outsw;
150 hwif->OUTSL = ide_mm_outsl;
151 hwif->INB = ide_mm_inb; 105 hwif->INB = ide_mm_inb;
152 hwif->INW = ide_mm_inw; 106 hwif->INW = ide_mm_inw;
153 hwif->INSW = ide_mm_insw;
154 hwif->INSL = ide_mm_insl;
155} 107}
156 108
157EXPORT_SYMBOL(default_hwif_mmiops); 109EXPORT_SYMBOL(default_hwif_mmiops);
@@ -203,24 +155,39 @@ static void ata_input_data(ide_drive_t *drive, struct request *rq,
203 struct ide_io_ports *io_ports = &hwif->io_ports; 155 struct ide_io_ports *io_ports = &hwif->io_ports;
204 unsigned long data_addr = io_ports->data_addr; 156 unsigned long data_addr = io_ports->data_addr;
205 u8 io_32bit = drive->io_32bit; 157 u8 io_32bit = drive->io_32bit;
158 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
206 159
207 len++; 160 len++;
208 161
209 if (io_32bit) { 162 if (io_32bit) {
210 if (io_32bit & 2) { 163 unsigned long uninitialized_var(flags);
211 unsigned long flags;
212 164
165 if (io_32bit & 2) {
213 local_irq_save(flags); 166 local_irq_save(flags);
214 ata_vlb_sync(drive, io_ports->nsect_addr); 167 ata_vlb_sync(drive, io_ports->nsect_addr);
215 hwif->INSL(data_addr, buf, len / 4); 168 }
169
170 if (mmio)
171 __ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
172 else
173 insl(data_addr, buf, len / 4);
174
175 if (io_32bit & 2)
216 local_irq_restore(flags); 176 local_irq_restore(flags);
217 } else
218 hwif->INSL(data_addr, buf, len / 4);
219 177
220 if ((len & 3) >= 2) 178 if ((len & 3) >= 2) {
221 hwif->INSW(data_addr, (u8 *)buf + (len & ~3), 1); 179 if (mmio)
222 } else 180 __ide_mm_insw((void __iomem *)data_addr,
223 hwif->INSW(data_addr, buf, len / 2); 181 (u8 *)buf + (len & ~3), 1);
182 else
183 insw(data_addr, (u8 *)buf + (len & ~3), 1);
184 }
185 } else {
186 if (mmio)
187 __ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
188 else
189 insw(data_addr, buf, len / 2);
190 }
224} 191}
225 192
226/* 193/*
@@ -233,22 +200,37 @@ static void ata_output_data(ide_drive_t *drive, struct request *rq,
233 struct ide_io_ports *io_ports = &hwif->io_ports; 200 struct ide_io_ports *io_ports = &hwif->io_ports;
234 unsigned long data_addr = io_ports->data_addr; 201 unsigned long data_addr = io_ports->data_addr;
235 u8 io_32bit = drive->io_32bit; 202 u8 io_32bit = drive->io_32bit;
203 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
236 204
237 if (io_32bit) { 205 if (io_32bit) {
238 if (io_32bit & 2) { 206 unsigned long uninitialized_var(flags);
239 unsigned long flags;
240 207
208 if (io_32bit & 2) {
241 local_irq_save(flags); 209 local_irq_save(flags);
242 ata_vlb_sync(drive, io_ports->nsect_addr); 210 ata_vlb_sync(drive, io_ports->nsect_addr);
243 hwif->OUTSL(data_addr, buf, len / 4); 211 }
212
213 if (mmio)
214 __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
215 else
216 outsl(data_addr, buf, len / 4);
217
218 if (io_32bit & 2)
244 local_irq_restore(flags); 219 local_irq_restore(flags);
245 } else
246 hwif->OUTSL(data_addr, buf, len / 4);
247 220
248 if ((len & 3) >= 2) 221 if ((len & 3) >= 2) {
249 hwif->OUTSW(data_addr, (u8 *)buf + (len & ~3), 1); 222 if (mmio)
250 } else 223 __ide_mm_outsw((void __iomem *)data_addr,
251 hwif->OUTSW(data_addr, buf, len / 2); 224 (u8 *)buf + (len & ~3), 1);
225 else
226 outsw(data_addr, (u8 *)buf + (len & ~3), 1);
227 }
228 } else {
229 if (mmio)
230 __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
231 else
232 outsw(data_addr, buf, len / 2);
233 }
252} 234}
253 235
254void default_hwif_transport(ide_hwif_t *hwif) 236void default_hwif_transport(ide_hwif_t *hwif)