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.c130
1 files changed, 54 insertions, 76 deletions
diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c
index 2d9c6dc3f956..9cac281d82c4 100644
--- a/drivers/ide/ide-io-std.c
+++ b/drivers/ide/ide-io-std.c
@@ -64,23 +64,26 @@ u8 ide_read_altstatus(ide_hwif_t *hwif)
64} 64}
65EXPORT_SYMBOL_GPL(ide_read_altstatus); 65EXPORT_SYMBOL_GPL(ide_read_altstatus);
66 66
67void ide_set_irq(ide_hwif_t *hwif, int on) 67void ide_write_devctl(ide_hwif_t *hwif, u8 ctl)
68{ 68{
69 u8 ctl = ATA_DEVCTL_OBS;
70
71 if (on == 4) { /* hack for SRST */
72 ctl |= 4;
73 on &= ~4;
74 }
75
76 ctl |= on ? 0 : 2;
77
78 if (hwif->host_flags & IDE_HFLAG_MMIO) 69 if (hwif->host_flags & IDE_HFLAG_MMIO)
79 writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr); 70 writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
80 else 71 else
81 outb(ctl, hwif->io_ports.ctl_addr); 72 outb(ctl, hwif->io_ports.ctl_addr);
82} 73}
83EXPORT_SYMBOL_GPL(ide_set_irq); 74EXPORT_SYMBOL_GPL(ide_write_devctl);
75
76void ide_dev_select(ide_drive_t *drive)
77{
78 ide_hwif_t *hwif = drive->hwif;
79 u8 select = drive->select | ATA_DEVICE_OBS;
80
81 if (hwif->host_flags & IDE_HFLAG_MMIO)
82 writeb(select, (void __iomem *)hwif->io_ports.device_addr);
83 else
84 outb(select, hwif->io_ports.device_addr);
85}
86EXPORT_SYMBOL_GPL(ide_dev_select);
84 87
85void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) 88void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
86{ 89{
@@ -99,15 +102,6 @@ void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
99 if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) 102 if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
100 HIHI = 0xFF; 103 HIHI = 0xFF;
101 104
102 if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
103 u16 data = (tf->hob_data << 8) | tf->data;
104
105 if (mmio)
106 writew(data, (void __iomem *)io_ports->data_addr);
107 else
108 outw(data, io_ports->data_addr);
109 }
110
111 if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) 105 if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
112 tf_outb(tf->hob_feature, io_ports->feature_addr); 106 tf_outb(tf->hob_feature, io_ports->feature_addr);
113 if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) 107 if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
@@ -153,23 +147,11 @@ void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
153 tf_inb = ide_inb; 147 tf_inb = ide_inb;
154 } 148 }
155 149
156 if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
157 u16 data;
158
159 if (mmio)
160 data = readw((void __iomem *)io_ports->data_addr);
161 else
162 data = inw(io_ports->data_addr);
163
164 tf->data = data & 0xff;
165 tf->hob_data = (data >> 8) & 0xff;
166 }
167
168 /* be sure we're looking at the low order bits */ 150 /* be sure we're looking at the low order bits */
169 tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr); 151 tf_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
170 152
171 if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE) 153 if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
172 tf->feature = tf_inb(io_ports->feature_addr); 154 tf->error = tf_inb(io_ports->feature_addr);
173 if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) 155 if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
174 tf->nsect = tf_inb(io_ports->nsect_addr); 156 tf->nsect = tf_inb(io_ports->nsect_addr);
175 if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) 157 if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
@@ -182,18 +164,18 @@ void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
182 tf->device = tf_inb(io_ports->device_addr); 164 tf->device = tf_inb(io_ports->device_addr);
183 165
184 if (cmd->tf_flags & IDE_TFLAG_LBA48) { 166 if (cmd->tf_flags & IDE_TFLAG_LBA48) {
185 tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr); 167 tf_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
186 168
187 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE) 169 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
188 tf->hob_feature = tf_inb(io_ports->feature_addr); 170 tf->hob_error = tf_inb(io_ports->feature_addr);
189 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) 171 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
190 tf->hob_nsect = tf_inb(io_ports->nsect_addr); 172 tf->hob_nsect = tf_inb(io_ports->nsect_addr);
191 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) 173 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
192 tf->hob_lbal = tf_inb(io_ports->lbal_addr); 174 tf->hob_lbal = tf_inb(io_ports->lbal_addr);
193 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) 175 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
194 tf->hob_lbam = tf_inb(io_ports->lbam_addr); 176 tf->hob_lbam = tf_inb(io_ports->lbam_addr);
195 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) 177 if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
196 tf->hob_lbah = tf_inb(io_ports->lbah_addr); 178 tf->hob_lbah = tf_inb(io_ports->lbah_addr);
197 } 179 }
198} 180}
199EXPORT_SYMBOL_GPL(ide_tf_read); 181EXPORT_SYMBOL_GPL(ide_tf_read);
@@ -225,11 +207,10 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
225 ide_hwif_t *hwif = drive->hwif; 207 ide_hwif_t *hwif = drive->hwif;
226 struct ide_io_ports *io_ports = &hwif->io_ports; 208 struct ide_io_ports *io_ports = &hwif->io_ports;
227 unsigned long data_addr = io_ports->data_addr; 209 unsigned long data_addr = io_ports->data_addr;
210 unsigned int words = (len + 1) >> 1;
228 u8 io_32bit = drive->io_32bit; 211 u8 io_32bit = drive->io_32bit;
229 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; 212 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
230 213
231 len++;
232
233 if (io_32bit) { 214 if (io_32bit) {
234 unsigned long uninitialized_var(flags); 215 unsigned long uninitialized_var(flags);
235 216
@@ -238,27 +219,26 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
238 ata_vlb_sync(io_ports->nsect_addr); 219 ata_vlb_sync(io_ports->nsect_addr);
239 } 220 }
240 221
222 words >>= 1;
241 if (mmio) 223 if (mmio)
242 __ide_mm_insl((void __iomem *)data_addr, buf, len / 4); 224 __ide_mm_insl((void __iomem *)data_addr, buf, words);
243 else 225 else
244 insl(data_addr, buf, len / 4); 226 insl(data_addr, buf, words);
245 227
246 if ((io_32bit & 2) && !mmio) 228 if ((io_32bit & 2) && !mmio)
247 local_irq_restore(flags); 229 local_irq_restore(flags);
248 230
249 if ((len & 3) >= 2) { 231 if (((len + 1) & 3) < 2)
250 if (mmio) 232 return;
251 __ide_mm_insw((void __iomem *)data_addr, 233
252 (u8 *)buf + (len & ~3), 1); 234 buf += len & ~3;
253 else 235 words = 1;
254 insw(data_addr, (u8 *)buf + (len & ~3), 1);
255 }
256 } else {
257 if (mmio)
258 __ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
259 else
260 insw(data_addr, buf, len / 2);
261 } 236 }
237
238 if (mmio)
239 __ide_mm_insw((void __iomem *)data_addr, buf, words);
240 else
241 insw(data_addr, buf, words);
262} 242}
263EXPORT_SYMBOL_GPL(ide_input_data); 243EXPORT_SYMBOL_GPL(ide_input_data);
264 244
@@ -271,11 +251,10 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
271 ide_hwif_t *hwif = drive->hwif; 251 ide_hwif_t *hwif = drive->hwif;
272 struct ide_io_ports *io_ports = &hwif->io_ports; 252 struct ide_io_ports *io_ports = &hwif->io_ports;
273 unsigned long data_addr = io_ports->data_addr; 253 unsigned long data_addr = io_ports->data_addr;
254 unsigned int words = (len + 1) >> 1;
274 u8 io_32bit = drive->io_32bit; 255 u8 io_32bit = drive->io_32bit;
275 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; 256 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
276 257
277 len++;
278
279 if (io_32bit) { 258 if (io_32bit) {
280 unsigned long uninitialized_var(flags); 259 unsigned long uninitialized_var(flags);
281 260
@@ -284,27 +263,26 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
284 ata_vlb_sync(io_ports->nsect_addr); 263 ata_vlb_sync(io_ports->nsect_addr);
285 } 264 }
286 265
266 words >>= 1;
287 if (mmio) 267 if (mmio)
288 __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4); 268 __ide_mm_outsl((void __iomem *)data_addr, buf, words);
289 else 269 else
290 outsl(data_addr, buf, len / 4); 270 outsl(data_addr, buf, words);
291 271
292 if ((io_32bit & 2) && !mmio) 272 if ((io_32bit & 2) && !mmio)
293 local_irq_restore(flags); 273 local_irq_restore(flags);
294 274
295 if ((len & 3) >= 2) { 275 if (((len + 1) & 3) < 2)
296 if (mmio) 276 return;
297 __ide_mm_outsw((void __iomem *)data_addr, 277
298 (u8 *)buf + (len & ~3), 1); 278 buf += len & ~3;
299 else 279 words = 1;
300 outsw(data_addr, (u8 *)buf + (len & ~3), 1);
301 }
302 } else {
303 if (mmio)
304 __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
305 else
306 outsw(data_addr, buf, len / 2);
307 } 280 }
281
282 if (mmio)
283 __ide_mm_outsw((void __iomem *)data_addr, buf, words);
284 else
285 outsw(data_addr, buf, words);
308} 286}
309EXPORT_SYMBOL_GPL(ide_output_data); 287EXPORT_SYMBOL_GPL(ide_output_data);
310 288
@@ -312,9 +290,9 @@ const struct ide_tp_ops default_tp_ops = {
312 .exec_command = ide_exec_command, 290 .exec_command = ide_exec_command,
313 .read_status = ide_read_status, 291 .read_status = ide_read_status,
314 .read_altstatus = ide_read_altstatus, 292 .read_altstatus = ide_read_altstatus,
293 .write_devctl = ide_write_devctl,
315 294
316 .set_irq = ide_set_irq, 295 .dev_select = ide_dev_select,
317
318 .tf_load = ide_tf_load, 296 .tf_load = ide_tf_load,
319 .tf_read = ide_tf_read, 297 .tf_read = ide_tf_read,
320 298