diff options
Diffstat (limited to 'drivers/ide/ide-iops.c')
-rw-r--r-- | drivers/ide/ide-iops.c | 344 |
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 | ||
40 | static u16 ide_inw (unsigned long port) | ||
41 | { | ||
42 | return (u16) inw(port); | ||
43 | } | ||
44 | |||
45 | static void ide_insw (unsigned long port, void *addr, u32 count) | ||
46 | { | ||
47 | insw(port, addr, count); | ||
48 | } | ||
49 | |||
50 | static void ide_insl (unsigned long port, void *addr, u32 count) | ||
51 | { | ||
52 | insl(port, addr, count); | ||
53 | } | ||
54 | |||
55 | static void ide_outb (u8 val, unsigned long port) | 40 | static 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 | ||
65 | static void ide_outw (u16 val, unsigned long port) | ||
66 | { | ||
67 | outw(val, port); | ||
68 | } | ||
69 | |||
70 | static void ide_outsw (unsigned long port, void *addr, u32 count) | ||
71 | { | ||
72 | outsw(port, addr, count); | ||
73 | } | ||
74 | |||
75 | static void ide_outsl (unsigned long port, void *addr, u32 count) | ||
76 | { | ||
77 | outsl(port, addr, count); | ||
78 | } | ||
79 | |||
80 | void default_hwif_iops (ide_hwif_t *hwif) | 50 | void 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 | ||
102 | static u16 ide_mm_inw (unsigned long port) | ||
103 | { | ||
104 | return (u16) readw((void __iomem *) port); | ||
105 | } | ||
106 | |||
107 | static void ide_mm_insw (unsigned long port, void *addr, u32 count) | ||
108 | { | ||
109 | __ide_mm_insw((void __iomem *) port, addr, count); | ||
110 | } | ||
111 | |||
112 | static void ide_mm_insl (unsigned long port, void *addr, u32 count) | ||
113 | { | ||
114 | __ide_mm_insl((void __iomem *) port, addr, count); | ||
115 | } | ||
116 | |||
117 | static void ide_mm_outb (u8 value, unsigned long port) | 66 | static 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 | ||
127 | static void ide_mm_outw (u16 value, unsigned long port) | ||
128 | { | ||
129 | writew(value, (void __iomem *) port); | ||
130 | } | ||
131 | |||
132 | static void ide_mm_outsw (unsigned long port, void *addr, u32 count) | ||
133 | { | ||
134 | __ide_mm_outsw((void __iomem *) port, addr, count); | ||
135 | } | ||
136 | |||
137 | static void ide_mm_outsl (unsigned long port, void *addr, u32 count) | ||
138 | { | ||
139 | __ide_mm_outsl((void __iomem *) port, addr, count); | ||
140 | } | ||
141 | |||
142 | void default_hwif_mmiops (ide_hwif_t *hwif) | 76 | void 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 | ||
157 | EXPORT_SYMBOL(default_hwif_mmiops); | 85 | EXPORT_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 | ||
106 | static 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 | |||
164 | static 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 | */ |
185 | static void ata_vlb_sync(ide_drive_t *drive, unsigned long port) | 230 | static 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 | */ |
195 | static void ata_input_data(ide_drive_t *drive, void *buffer, u32 wcount) | 244 | static 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 | */ |
218 | static void ata_output_data(ide_drive_t *drive, void *buffer, u32 wcount) | 289 | static 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 | |||
246 | static 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 | ||
264 | static 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 | ||
282 | void default_hwif_transport(ide_hwif_t *hwif) | 329 | void 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 | ||
290 | void ide_fix_driveid (struct hd_driveid *id) | 338 | void 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 | |||
853 | EXPORT_SYMBOL(ide_execute_command); | 902 | EXPORT_SYMBOL(ide_execute_command); |
854 | 903 | ||
904 | void 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 | } | ||
914 | EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd); | ||
855 | 915 | ||
856 | /* needed below */ | 916 | /* needed below */ |
857 | static ide_startstop_t do_reset1 (ide_drive_t *, int); | 917 | static ide_startstop_t do_reset1 (ide_drive_t *, int); |