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.c344
1 files changed, 202 insertions, 142 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 5425d3038ec2..57d9a9a79a6f 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -37,21 +37,6 @@ static u8 ide_inb (unsigned long port)
37 return (u8) inb(port); 37 return (u8) inb(port);
38} 38}
39 39
40static u16 ide_inw (unsigned long port)
41{
42 return (u16) inw(port);
43}
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) 40static void ide_outb (u8 val, unsigned long port)
56{ 41{
57 outb(val, port); 42 outb(val, port);
@@ -62,32 +47,11 @@ static void ide_outbsync (ide_drive_t *drive, u8 addr, unsigned long port)
62 outb(addr, port); 47 outb(addr, port);
63} 48}
64 49
65static void ide_outw (u16 val, unsigned long port)
66{
67 outw(val, port);
68}
69
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) 50void default_hwif_iops (ide_hwif_t *hwif)
81{ 51{
82 hwif->OUTB = ide_outb; 52 hwif->OUTB = ide_outb;
83 hwif->OUTBSYNC = ide_outbsync; 53 hwif->OUTBSYNC = ide_outbsync;
84 hwif->OUTW = ide_outw;
85 hwif->OUTSW = ide_outsw;
86 hwif->OUTSL = ide_outsl;
87 hwif->INB = ide_inb; 54 hwif->INB = ide_inb;
88 hwif->INW = ide_inw;
89 hwif->INSW = ide_insw;
90 hwif->INSL = ide_insl;
91} 55}
92 56
93/* 57/*
@@ -99,21 +63,6 @@ static u8 ide_mm_inb (unsigned long port)
99 return (u8) readb((void __iomem *) port); 63 return (u8) readb((void __iomem *) port);
100} 64}
101 65
102static u16 ide_mm_inw (unsigned long port)
103{
104 return (u16) readw((void __iomem *) port);
105}
106
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) 66static void ide_mm_outb (u8 value, unsigned long port)
118{ 67{
119 writeb(value, (void __iomem *) port); 68 writeb(value, (void __iomem *) port);
@@ -124,34 +73,13 @@ static void ide_mm_outbsync (ide_drive_t *drive, u8 value, unsigned long port)
124 writeb(value, (void __iomem *) port); 73 writeb(value, (void __iomem *) port);
125} 74}
126 75
127static void ide_mm_outw (u16 value, unsigned long port)
128{
129 writew(value, (void __iomem *) port);
130}
131
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) 76void default_hwif_mmiops (ide_hwif_t *hwif)
143{ 77{
144 hwif->OUTB = ide_mm_outb; 78 hwif->OUTB = ide_mm_outb;
145 /* Most systems will need to override OUTBSYNC, alas however 79 /* Most systems will need to override OUTBSYNC, alas however
146 this one is controller specific! */ 80 this one is controller specific! */
147 hwif->OUTBSYNC = ide_mm_outbsync; 81 hwif->OUTBSYNC = ide_mm_outbsync;
148 hwif->OUTW = ide_mm_outw;
149 hwif->OUTSW = ide_mm_outsw;
150 hwif->OUTSL = ide_mm_outsl;
151 hwif->INB = ide_mm_inb; 82 hwif->INB = ide_mm_inb;
152 hwif->INW = ide_mm_inw;
153 hwif->INSW = ide_mm_insw;
154 hwif->INSL = ide_mm_insl;
155} 83}
156 84
157EXPORT_SYMBOL(default_hwif_mmiops); 85EXPORT_SYMBOL(default_hwif_mmiops);
@@ -175,6 +103,123 @@ void SELECT_MASK (ide_drive_t *drive, int mask)
175 port_ops->maskproc(drive, mask); 103 port_ops->maskproc(drive, mask);
176} 104}
177 105
106static void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
107{
108 ide_hwif_t *hwif = drive->hwif;
109 struct ide_io_ports *io_ports = &hwif->io_ports;
110 struct ide_taskfile *tf = &task->tf;
111 void (*tf_outb)(u8 addr, unsigned long port);
112 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
113 u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
114
115 if (mmio)
116 tf_outb = ide_mm_outb;
117 else
118 tf_outb = ide_outb;
119
120 if (task->tf_flags & IDE_TFLAG_FLAGGED)
121 HIHI = 0xFF;
122
123 ide_set_irq(drive, 1);
124
125 if ((task->tf_flags & IDE_TFLAG_NO_SELECT_MASK) == 0)
126 SELECT_MASK(drive, 0);
127
128 if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
129 u16 data = (tf->hob_data << 8) | tf->data;
130
131 if (mmio)
132 writew(data, (void __iomem *)io_ports->data_addr);
133 else
134 outw(data, io_ports->data_addr);
135 }
136
137 if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
138 tf_outb(tf->hob_feature, io_ports->feature_addr);
139 if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
140 tf_outb(tf->hob_nsect, io_ports->nsect_addr);
141 if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
142 tf_outb(tf->hob_lbal, io_ports->lbal_addr);
143 if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
144 tf_outb(tf->hob_lbam, io_ports->lbam_addr);
145 if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
146 tf_outb(tf->hob_lbah, io_ports->lbah_addr);
147
148 if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
149 tf_outb(tf->feature, io_ports->feature_addr);
150 if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
151 tf_outb(tf->nsect, io_ports->nsect_addr);
152 if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
153 tf_outb(tf->lbal, io_ports->lbal_addr);
154 if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
155 tf_outb(tf->lbam, io_ports->lbam_addr);
156 if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
157 tf_outb(tf->lbah, io_ports->lbah_addr);
158
159 if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
160 tf_outb((tf->device & HIHI) | drive->select.all,
161 io_ports->device_addr);
162}
163
164static void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
165{
166 ide_hwif_t *hwif = drive->hwif;
167 struct ide_io_ports *io_ports = &hwif->io_ports;
168 struct ide_taskfile *tf = &task->tf;
169 void (*tf_outb)(u8 addr, unsigned long port);
170 u8 (*tf_inb)(unsigned long port);
171 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
172
173 if (mmio) {
174 tf_outb = ide_mm_outb;
175 tf_inb = ide_mm_inb;
176 } else {
177 tf_outb = ide_outb;
178 tf_inb = ide_inb;
179 }
180
181 if (task->tf_flags & IDE_TFLAG_IN_DATA) {
182 u16 data;
183
184 if (mmio)
185 data = readw((void __iomem *)io_ports->data_addr);
186 else
187 data = inw(io_ports->data_addr);
188
189 tf->data = data & 0xff;
190 tf->hob_data = (data >> 8) & 0xff;
191 }
192
193 /* be sure we're looking at the low order bits */
194 tf_outb(drive->ctl & ~0x80, io_ports->ctl_addr);
195
196 if (task->tf_flags & IDE_TFLAG_IN_NSECT)
197 tf->nsect = tf_inb(io_ports->nsect_addr);
198 if (task->tf_flags & IDE_TFLAG_IN_LBAL)
199 tf->lbal = tf_inb(io_ports->lbal_addr);
200 if (task->tf_flags & IDE_TFLAG_IN_LBAM)
201 tf->lbam = tf_inb(io_ports->lbam_addr);
202 if (task->tf_flags & IDE_TFLAG_IN_LBAH)
203 tf->lbah = tf_inb(io_ports->lbah_addr);
204 if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
205 tf->device = tf_inb(io_ports->device_addr);
206
207 if (task->tf_flags & IDE_TFLAG_LBA48) {
208 tf_outb(drive->ctl | 0x80, io_ports->ctl_addr);
209
210 if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
211 tf->hob_feature = tf_inb(io_ports->feature_addr);
212 if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
213 tf->hob_nsect = tf_inb(io_ports->nsect_addr);
214 if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
215 tf->hob_lbal = tf_inb(io_ports->lbal_addr);
216 if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
217 tf->hob_lbam = tf_inb(io_ports->lbam_addr);
218 if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
219 tf->hob_lbah = tf_inb(io_ports->lbah_addr);
220 }
221}
222
178/* 223/*
179 * Some localbus EIDE interfaces require a special access sequence 224 * Some localbus EIDE interfaces require a special access sequence
180 * when using 32-bit I/O instructions to transfer data. We call this 225 * when using 32-bit I/O instructions to transfer data. We call this
@@ -182,109 +227,112 @@ void SELECT_MASK (ide_drive_t *drive, int mask)
182 * of the sector count register location, with interrupts disabled 227 * of the sector count register location, with interrupts disabled
183 * to ensure that the reads all happen together. 228 * to ensure that the reads all happen together.
184 */ 229 */
185static void ata_vlb_sync(ide_drive_t *drive, unsigned long port) 230static void ata_vlb_sync(unsigned long port)
186{ 231{
187 (void) HWIF(drive)->INB(port); 232 (void)inb(port);
188 (void) HWIF(drive)->INB(port); 233 (void)inb(port);
189 (void) HWIF(drive)->INB(port); 234 (void)inb(port);
190} 235}
191 236
192/* 237/*
193 * This is used for most PIO data transfers *from* the IDE interface 238 * This is used for most PIO data transfers *from* the IDE interface
239 *
240 * These routines will round up any request for an odd number of bytes,
241 * so if an odd len is specified, be sure that there's at least one
242 * extra byte allocated for the buffer.
194 */ 243 */
195static void ata_input_data(ide_drive_t *drive, void *buffer, u32 wcount) 244static void ata_input_data(ide_drive_t *drive, struct request *rq,
245 void *buf, unsigned int len)
196{ 246{
197 ide_hwif_t *hwif = drive->hwif; 247 ide_hwif_t *hwif = drive->hwif;
198 struct ide_io_ports *io_ports = &hwif->io_ports; 248 struct ide_io_ports *io_ports = &hwif->io_ports;
249 unsigned long data_addr = io_ports->data_addr;
199 u8 io_32bit = drive->io_32bit; 250 u8 io_32bit = drive->io_32bit;
251 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
252
253 len++;
200 254
201 if (io_32bit) { 255 if (io_32bit) {
202 if (io_32bit & 2) { 256 unsigned long uninitialized_var(flags);
203 unsigned long flags;
204 257
258 if ((io_32bit & 2) && !mmio) {
205 local_irq_save(flags); 259 local_irq_save(flags);
206 ata_vlb_sync(drive, io_ports->nsect_addr); 260 ata_vlb_sync(io_ports->nsect_addr);
207 hwif->INSL(io_ports->data_addr, buffer, wcount); 261 }
262
263 if (mmio)
264 __ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
265 else
266 insl(data_addr, buf, len / 4);
267
268 if ((io_32bit & 2) && !mmio)
208 local_irq_restore(flags); 269 local_irq_restore(flags);
209 } else 270
210 hwif->INSL(io_ports->data_addr, buffer, wcount); 271 if ((len & 3) >= 2) {
211 } else 272 if (mmio)
212 hwif->INSW(io_ports->data_addr, buffer, wcount << 1); 273 __ide_mm_insw((void __iomem *)data_addr,
274 (u8 *)buf + (len & ~3), 1);
275 else
276 insw(data_addr, (u8 *)buf + (len & ~3), 1);
277 }
278 } else {
279 if (mmio)
280 __ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
281 else
282 insw(data_addr, buf, len / 2);
283 }
213} 284}
214 285
215/* 286/*
216 * This is used for most PIO data transfers *to* the IDE interface 287 * This is used for most PIO data transfers *to* the IDE interface
217 */ 288 */
218static void ata_output_data(ide_drive_t *drive, void *buffer, u32 wcount) 289static void ata_output_data(ide_drive_t *drive, struct request *rq,
290 void *buf, unsigned int len)
219{ 291{
220 ide_hwif_t *hwif = drive->hwif; 292 ide_hwif_t *hwif = drive->hwif;
221 struct ide_io_ports *io_ports = &hwif->io_ports; 293 struct ide_io_ports *io_ports = &hwif->io_ports;
294 unsigned long data_addr = io_ports->data_addr;
222 u8 io_32bit = drive->io_32bit; 295 u8 io_32bit = drive->io_32bit;
296 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
223 297
224 if (io_32bit) { 298 if (io_32bit) {
225 if (io_32bit & 2) { 299 unsigned long uninitialized_var(flags);
226 unsigned long flags;
227 300
301 if ((io_32bit & 2) && !mmio) {
228 local_irq_save(flags); 302 local_irq_save(flags);
229 ata_vlb_sync(drive, io_ports->nsect_addr); 303 ata_vlb_sync(io_ports->nsect_addr);
230 hwif->OUTSL(io_ports->data_addr, buffer, wcount); 304 }
231 local_irq_restore(flags);
232 } else
233 hwif->OUTSL(io_ports->data_addr, buffer, wcount);
234 } else
235 hwif->OUTSW(io_ports->data_addr, buffer, wcount << 1);
236}
237
238/*
239 * The following routines are mainly used by the ATAPI drivers.
240 *
241 * These routines will round up any request for an odd number of bytes,
242 * so if an odd bytecount is specified, be sure that there's at least one
243 * extra byte allocated for the buffer.
244 */
245
246static void atapi_input_bytes(ide_drive_t *drive, void *buffer, u32 bytecount)
247{
248 ide_hwif_t *hwif = HWIF(drive);
249 305
250 ++bytecount; 306 if (mmio)
251#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) 307 __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
252 if (MACH_IS_ATARI || MACH_IS_Q40) { 308 else
253 /* Atari has a byte-swapped IDE interface */ 309 outsl(data_addr, buf, len / 4);
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)
260 hwif->INSW(hwif->io_ports.data_addr,
261 (u8 *)buffer + (bytecount & ~0x03), 1);
262}
263 310
264static void atapi_output_bytes(ide_drive_t *drive, void *buffer, u32 bytecount) 311 if ((io_32bit & 2) && !mmio)
265{ 312 local_irq_restore(flags);
266 ide_hwif_t *hwif = HWIF(drive);
267 313
268 ++bytecount; 314 if ((len & 3) >= 2) {
269#if defined(CONFIG_ATARI) || defined(CONFIG_Q40) 315 if (mmio)
270 if (MACH_IS_ATARI || MACH_IS_Q40) { 316 __ide_mm_outsw((void __iomem *)data_addr,
271 /* Atari has a byte-swapped IDE interface */ 317 (u8 *)buf + (len & ~3), 1);
272 outsw_swapw(hwif->io_ports.data_addr, buffer, bytecount / 2); 318 else
273 return; 319 outsw(data_addr, (u8 *)buf + (len & ~3), 1);
320 }
321 } else {
322 if (mmio)
323 __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
324 else
325 outsw(data_addr, buf, len / 2);
274 } 326 }
275#endif /* CONFIG_ATARI || CONFIG_Q40 */
276 hwif->ata_output_data(drive, buffer, bytecount / 4);
277 if ((bytecount & 0x03) >= 2)
278 hwif->OUTSW(hwif->io_ports.data_addr,
279 (u8 *)buffer + (bytecount & ~0x03), 1);
280} 327}
281 328
282void default_hwif_transport(ide_hwif_t *hwif) 329void default_hwif_transport(ide_hwif_t *hwif)
283{ 330{
284 hwif->ata_input_data = ata_input_data; 331 hwif->tf_load = ide_tf_load;
285 hwif->ata_output_data = ata_output_data; 332 hwif->tf_read = ide_tf_read;
286 hwif->atapi_input_bytes = atapi_input_bytes; 333
287 hwif->atapi_output_bytes = atapi_output_bytes; 334 hwif->input_data = ata_input_data;
335 hwif->output_data = ata_output_data;
288} 336}
289 337
290void ide_fix_driveid (struct hd_driveid *id) 338void ide_fix_driveid (struct hd_driveid *id)
@@ -577,6 +625,8 @@ static const struct drive_list_entry ivb_list[] = {
577 { "TSSTcorp CDDVDW SH-S202J" , "SB01" }, 625 { "TSSTcorp CDDVDW SH-S202J" , "SB01" },
578 { "TSSTcorp CDDVDW SH-S202N" , "SB00" }, 626 { "TSSTcorp CDDVDW SH-S202N" , "SB00" },
579 { "TSSTcorp CDDVDW SH-S202N" , "SB01" }, 627 { "TSSTcorp CDDVDW SH-S202N" , "SB01" },
628 { "TSSTcorp CDDVDW SH-S202H" , "SB00" },
629 { "TSSTcorp CDDVDW SH-S202H" , "SB01" },
580 { NULL , NULL } 630 { NULL , NULL }
581}; 631};
582 632
@@ -641,7 +691,7 @@ int ide_driveid_update(ide_drive_t *drive)
641 SELECT_MASK(drive, 1); 691 SELECT_MASK(drive, 1);
642 ide_set_irq(drive, 1); 692 ide_set_irq(drive, 1);
643 msleep(50); 693 msleep(50);
644 hwif->OUTB(WIN_IDENTIFY, hwif->io_ports.command_addr); 694 hwif->OUTBSYNC(drive, WIN_IDENTIFY, hwif->io_ports.command_addr);
645 timeout = jiffies + WAIT_WORSTCASE; 695 timeout = jiffies + WAIT_WORSTCASE;
646 do { 696 do {
647 if (time_after(jiffies, timeout)) { 697 if (time_after(jiffies, timeout)) {
@@ -668,7 +718,7 @@ int ide_driveid_update(ide_drive_t *drive)
668 local_irq_restore(flags); 718 local_irq_restore(flags);
669 return 0; 719 return 0;
670 } 720 }
671 hwif->ata_input_data(drive, id, SECTOR_WORDS); 721 hwif->input_data(drive, NULL, id, SECTOR_SIZE);
672 (void)ide_read_status(drive); /* clear drive IRQ */ 722 (void)ide_read_status(drive); /* clear drive IRQ */
673 local_irq_enable(); 723 local_irq_enable();
674 local_irq_restore(flags); 724 local_irq_restore(flags);
@@ -849,9 +899,19 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
849 ndelay(400); 899 ndelay(400);
850 spin_unlock_irqrestore(&ide_lock, flags); 900 spin_unlock_irqrestore(&ide_lock, flags);
851} 901}
852
853EXPORT_SYMBOL(ide_execute_command); 902EXPORT_SYMBOL(ide_execute_command);
854 903
904void ide_execute_pkt_cmd(ide_drive_t *drive)
905{
906 ide_hwif_t *hwif = drive->hwif;
907 unsigned long flags;
908
909 spin_lock_irqsave(&ide_lock, flags);
910 hwif->OUTBSYNC(drive, WIN_PACKETCMD, hwif->io_ports.command_addr);
911 ndelay(400);
912 spin_unlock_irqrestore(&ide_lock, flags);
913}
914EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd);
855 915
856/* needed below */ 916/* needed below */
857static ide_startstop_t do_reset1 (ide_drive_t *, int); 917static ide_startstop_t do_reset1 (ide_drive_t *, int);