diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2006-02-09 05:15:27 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-02-09 05:15:27 -0500 |
commit | 1fdffbce0332b3e00993d741e76935e7f4f0d40f (patch) | |
tree | d6d5063c7f2f1dfcdaa9868260b3b812e4feca7e /drivers/scsi/libata-core.c | |
parent | 389984cb75a5d26aa6ee9724c343bbd130cb3eec (diff) |
[libata] Move PCI IDE BMDMA-related code to new file libata-bmdma.c.
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r-- | drivers/scsi/libata-core.c | 693 |
1 files changed, 20 insertions, 673 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 14cdbb336dd5..22db73932253 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -83,403 +83,6 @@ MODULE_DESCRIPTION("Library module for ATA devices"); | |||
83 | MODULE_LICENSE("GPL"); | 83 | MODULE_LICENSE("GPL"); |
84 | MODULE_VERSION(DRV_VERSION); | 84 | MODULE_VERSION(DRV_VERSION); |
85 | 85 | ||
86 | /** | ||
87 | * ata_tf_load_pio - send taskfile registers to host controller | ||
88 | * @ap: Port to which output is sent | ||
89 | * @tf: ATA taskfile register set | ||
90 | * | ||
91 | * Outputs ATA taskfile to standard ATA host controller. | ||
92 | * | ||
93 | * LOCKING: | ||
94 | * Inherited from caller. | ||
95 | */ | ||
96 | |||
97 | static void ata_tf_load_pio(struct ata_port *ap, const struct ata_taskfile *tf) | ||
98 | { | ||
99 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
100 | unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; | ||
101 | |||
102 | if (tf->ctl != ap->last_ctl) { | ||
103 | outb(tf->ctl, ioaddr->ctl_addr); | ||
104 | ap->last_ctl = tf->ctl; | ||
105 | ata_wait_idle(ap); | ||
106 | } | ||
107 | |||
108 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { | ||
109 | outb(tf->hob_feature, ioaddr->feature_addr); | ||
110 | outb(tf->hob_nsect, ioaddr->nsect_addr); | ||
111 | outb(tf->hob_lbal, ioaddr->lbal_addr); | ||
112 | outb(tf->hob_lbam, ioaddr->lbam_addr); | ||
113 | outb(tf->hob_lbah, ioaddr->lbah_addr); | ||
114 | VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", | ||
115 | tf->hob_feature, | ||
116 | tf->hob_nsect, | ||
117 | tf->hob_lbal, | ||
118 | tf->hob_lbam, | ||
119 | tf->hob_lbah); | ||
120 | } | ||
121 | |||
122 | if (is_addr) { | ||
123 | outb(tf->feature, ioaddr->feature_addr); | ||
124 | outb(tf->nsect, ioaddr->nsect_addr); | ||
125 | outb(tf->lbal, ioaddr->lbal_addr); | ||
126 | outb(tf->lbam, ioaddr->lbam_addr); | ||
127 | outb(tf->lbah, ioaddr->lbah_addr); | ||
128 | VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", | ||
129 | tf->feature, | ||
130 | tf->nsect, | ||
131 | tf->lbal, | ||
132 | tf->lbam, | ||
133 | tf->lbah); | ||
134 | } | ||
135 | |||
136 | if (tf->flags & ATA_TFLAG_DEVICE) { | ||
137 | outb(tf->device, ioaddr->device_addr); | ||
138 | VPRINTK("device 0x%X\n", tf->device); | ||
139 | } | ||
140 | |||
141 | ata_wait_idle(ap); | ||
142 | } | ||
143 | |||
144 | /** | ||
145 | * ata_tf_load_mmio - send taskfile registers to host controller | ||
146 | * @ap: Port to which output is sent | ||
147 | * @tf: ATA taskfile register set | ||
148 | * | ||
149 | * Outputs ATA taskfile to standard ATA host controller using MMIO. | ||
150 | * | ||
151 | * LOCKING: | ||
152 | * Inherited from caller. | ||
153 | */ | ||
154 | |||
155 | static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) | ||
156 | { | ||
157 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
158 | unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; | ||
159 | |||
160 | if (tf->ctl != ap->last_ctl) { | ||
161 | writeb(tf->ctl, (void __iomem *) ap->ioaddr.ctl_addr); | ||
162 | ap->last_ctl = tf->ctl; | ||
163 | ata_wait_idle(ap); | ||
164 | } | ||
165 | |||
166 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { | ||
167 | writeb(tf->hob_feature, (void __iomem *) ioaddr->feature_addr); | ||
168 | writeb(tf->hob_nsect, (void __iomem *) ioaddr->nsect_addr); | ||
169 | writeb(tf->hob_lbal, (void __iomem *) ioaddr->lbal_addr); | ||
170 | writeb(tf->hob_lbam, (void __iomem *) ioaddr->lbam_addr); | ||
171 | writeb(tf->hob_lbah, (void __iomem *) ioaddr->lbah_addr); | ||
172 | VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", | ||
173 | tf->hob_feature, | ||
174 | tf->hob_nsect, | ||
175 | tf->hob_lbal, | ||
176 | tf->hob_lbam, | ||
177 | tf->hob_lbah); | ||
178 | } | ||
179 | |||
180 | if (is_addr) { | ||
181 | writeb(tf->feature, (void __iomem *) ioaddr->feature_addr); | ||
182 | writeb(tf->nsect, (void __iomem *) ioaddr->nsect_addr); | ||
183 | writeb(tf->lbal, (void __iomem *) ioaddr->lbal_addr); | ||
184 | writeb(tf->lbam, (void __iomem *) ioaddr->lbam_addr); | ||
185 | writeb(tf->lbah, (void __iomem *) ioaddr->lbah_addr); | ||
186 | VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", | ||
187 | tf->feature, | ||
188 | tf->nsect, | ||
189 | tf->lbal, | ||
190 | tf->lbam, | ||
191 | tf->lbah); | ||
192 | } | ||
193 | |||
194 | if (tf->flags & ATA_TFLAG_DEVICE) { | ||
195 | writeb(tf->device, (void __iomem *) ioaddr->device_addr); | ||
196 | VPRINTK("device 0x%X\n", tf->device); | ||
197 | } | ||
198 | |||
199 | ata_wait_idle(ap); | ||
200 | } | ||
201 | |||
202 | |||
203 | /** | ||
204 | * ata_tf_load - send taskfile registers to host controller | ||
205 | * @ap: Port to which output is sent | ||
206 | * @tf: ATA taskfile register set | ||
207 | * | ||
208 | * Outputs ATA taskfile to standard ATA host controller using MMIO | ||
209 | * or PIO as indicated by the ATA_FLAG_MMIO flag. | ||
210 | * Writes the control, feature, nsect, lbal, lbam, and lbah registers. | ||
211 | * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect, | ||
212 | * hob_lbal, hob_lbam, and hob_lbah. | ||
213 | * | ||
214 | * This function waits for idle (!BUSY and !DRQ) after writing | ||
215 | * registers. If the control register has a new value, this | ||
216 | * function also waits for idle after writing control and before | ||
217 | * writing the remaining registers. | ||
218 | * | ||
219 | * May be used as the tf_load() entry in ata_port_operations. | ||
220 | * | ||
221 | * LOCKING: | ||
222 | * Inherited from caller. | ||
223 | */ | ||
224 | void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) | ||
225 | { | ||
226 | if (ap->flags & ATA_FLAG_MMIO) | ||
227 | ata_tf_load_mmio(ap, tf); | ||
228 | else | ||
229 | ata_tf_load_pio(ap, tf); | ||
230 | } | ||
231 | |||
232 | /** | ||
233 | * ata_exec_command_pio - issue ATA command to host controller | ||
234 | * @ap: port to which command is being issued | ||
235 | * @tf: ATA taskfile register set | ||
236 | * | ||
237 | * Issues PIO write to ATA command register, with proper | ||
238 | * synchronization with interrupt handler / other threads. | ||
239 | * | ||
240 | * LOCKING: | ||
241 | * spin_lock_irqsave(host_set lock) | ||
242 | */ | ||
243 | |||
244 | static void ata_exec_command_pio(struct ata_port *ap, const struct ata_taskfile *tf) | ||
245 | { | ||
246 | DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); | ||
247 | |||
248 | outb(tf->command, ap->ioaddr.command_addr); | ||
249 | ata_pause(ap); | ||
250 | } | ||
251 | |||
252 | |||
253 | /** | ||
254 | * ata_exec_command_mmio - issue ATA command to host controller | ||
255 | * @ap: port to which command is being issued | ||
256 | * @tf: ATA taskfile register set | ||
257 | * | ||
258 | * Issues MMIO write to ATA command register, with proper | ||
259 | * synchronization with interrupt handler / other threads. | ||
260 | * | ||
261 | * LOCKING: | ||
262 | * spin_lock_irqsave(host_set lock) | ||
263 | */ | ||
264 | |||
265 | static void ata_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf) | ||
266 | { | ||
267 | DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); | ||
268 | |||
269 | writeb(tf->command, (void __iomem *) ap->ioaddr.command_addr); | ||
270 | ata_pause(ap); | ||
271 | } | ||
272 | |||
273 | |||
274 | /** | ||
275 | * ata_exec_command - issue ATA command to host controller | ||
276 | * @ap: port to which command is being issued | ||
277 | * @tf: ATA taskfile register set | ||
278 | * | ||
279 | * Issues PIO/MMIO write to ATA command register, with proper | ||
280 | * synchronization with interrupt handler / other threads. | ||
281 | * | ||
282 | * LOCKING: | ||
283 | * spin_lock_irqsave(host_set lock) | ||
284 | */ | ||
285 | void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) | ||
286 | { | ||
287 | if (ap->flags & ATA_FLAG_MMIO) | ||
288 | ata_exec_command_mmio(ap, tf); | ||
289 | else | ||
290 | ata_exec_command_pio(ap, tf); | ||
291 | } | ||
292 | |||
293 | /** | ||
294 | * ata_tf_to_host - issue ATA taskfile to host controller | ||
295 | * @ap: port to which command is being issued | ||
296 | * @tf: ATA taskfile register set | ||
297 | * | ||
298 | * Issues ATA taskfile register set to ATA host controller, | ||
299 | * with proper synchronization with interrupt handler and | ||
300 | * other threads. | ||
301 | * | ||
302 | * LOCKING: | ||
303 | * spin_lock_irqsave(host_set lock) | ||
304 | */ | ||
305 | |||
306 | static inline void ata_tf_to_host(struct ata_port *ap, | ||
307 | const struct ata_taskfile *tf) | ||
308 | { | ||
309 | ap->ops->tf_load(ap, tf); | ||
310 | ap->ops->exec_command(ap, tf); | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * ata_tf_read_pio - input device's ATA taskfile shadow registers | ||
315 | * @ap: Port from which input is read | ||
316 | * @tf: ATA taskfile register set for storing input | ||
317 | * | ||
318 | * Reads ATA taskfile registers for currently-selected device | ||
319 | * into @tf. | ||
320 | * | ||
321 | * LOCKING: | ||
322 | * Inherited from caller. | ||
323 | */ | ||
324 | |||
325 | static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf) | ||
326 | { | ||
327 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
328 | |||
329 | tf->command = ata_check_status(ap); | ||
330 | tf->feature = inb(ioaddr->error_addr); | ||
331 | tf->nsect = inb(ioaddr->nsect_addr); | ||
332 | tf->lbal = inb(ioaddr->lbal_addr); | ||
333 | tf->lbam = inb(ioaddr->lbam_addr); | ||
334 | tf->lbah = inb(ioaddr->lbah_addr); | ||
335 | tf->device = inb(ioaddr->device_addr); | ||
336 | |||
337 | if (tf->flags & ATA_TFLAG_LBA48) { | ||
338 | outb(tf->ctl | ATA_HOB, ioaddr->ctl_addr); | ||
339 | tf->hob_feature = inb(ioaddr->error_addr); | ||
340 | tf->hob_nsect = inb(ioaddr->nsect_addr); | ||
341 | tf->hob_lbal = inb(ioaddr->lbal_addr); | ||
342 | tf->hob_lbam = inb(ioaddr->lbam_addr); | ||
343 | tf->hob_lbah = inb(ioaddr->lbah_addr); | ||
344 | } | ||
345 | } | ||
346 | |||
347 | /** | ||
348 | * ata_tf_read_mmio - input device's ATA taskfile shadow registers | ||
349 | * @ap: Port from which input is read | ||
350 | * @tf: ATA taskfile register set for storing input | ||
351 | * | ||
352 | * Reads ATA taskfile registers for currently-selected device | ||
353 | * into @tf via MMIO. | ||
354 | * | ||
355 | * LOCKING: | ||
356 | * Inherited from caller. | ||
357 | */ | ||
358 | |||
359 | static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf) | ||
360 | { | ||
361 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
362 | |||
363 | tf->command = ata_check_status(ap); | ||
364 | tf->feature = readb((void __iomem *)ioaddr->error_addr); | ||
365 | tf->nsect = readb((void __iomem *)ioaddr->nsect_addr); | ||
366 | tf->lbal = readb((void __iomem *)ioaddr->lbal_addr); | ||
367 | tf->lbam = readb((void __iomem *)ioaddr->lbam_addr); | ||
368 | tf->lbah = readb((void __iomem *)ioaddr->lbah_addr); | ||
369 | tf->device = readb((void __iomem *)ioaddr->device_addr); | ||
370 | |||
371 | if (tf->flags & ATA_TFLAG_LBA48) { | ||
372 | writeb(tf->ctl | ATA_HOB, (void __iomem *) ap->ioaddr.ctl_addr); | ||
373 | tf->hob_feature = readb((void __iomem *)ioaddr->error_addr); | ||
374 | tf->hob_nsect = readb((void __iomem *)ioaddr->nsect_addr); | ||
375 | tf->hob_lbal = readb((void __iomem *)ioaddr->lbal_addr); | ||
376 | tf->hob_lbam = readb((void __iomem *)ioaddr->lbam_addr); | ||
377 | tf->hob_lbah = readb((void __iomem *)ioaddr->lbah_addr); | ||
378 | } | ||
379 | } | ||
380 | |||
381 | |||
382 | /** | ||
383 | * ata_tf_read - input device's ATA taskfile shadow registers | ||
384 | * @ap: Port from which input is read | ||
385 | * @tf: ATA taskfile register set for storing input | ||
386 | * | ||
387 | * Reads ATA taskfile registers for currently-selected device | ||
388 | * into @tf. | ||
389 | * | ||
390 | * Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48 | ||
391 | * is set, also reads the hob registers. | ||
392 | * | ||
393 | * May be used as the tf_read() entry in ata_port_operations. | ||
394 | * | ||
395 | * LOCKING: | ||
396 | * Inherited from caller. | ||
397 | */ | ||
398 | void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | ||
399 | { | ||
400 | if (ap->flags & ATA_FLAG_MMIO) | ||
401 | ata_tf_read_mmio(ap, tf); | ||
402 | else | ||
403 | ata_tf_read_pio(ap, tf); | ||
404 | } | ||
405 | |||
406 | /** | ||
407 | * ata_check_status_pio - Read device status reg & clear interrupt | ||
408 | * @ap: port where the device is | ||
409 | * | ||
410 | * Reads ATA taskfile status register for currently-selected device | ||
411 | * and return its value. This also clears pending interrupts | ||
412 | * from this device | ||
413 | * | ||
414 | * LOCKING: | ||
415 | * Inherited from caller. | ||
416 | */ | ||
417 | static u8 ata_check_status_pio(struct ata_port *ap) | ||
418 | { | ||
419 | return inb(ap->ioaddr.status_addr); | ||
420 | } | ||
421 | |||
422 | /** | ||
423 | * ata_check_status_mmio - Read device status reg & clear interrupt | ||
424 | * @ap: port where the device is | ||
425 | * | ||
426 | * Reads ATA taskfile status register for currently-selected device | ||
427 | * via MMIO and return its value. This also clears pending interrupts | ||
428 | * from this device | ||
429 | * | ||
430 | * LOCKING: | ||
431 | * Inherited from caller. | ||
432 | */ | ||
433 | static u8 ata_check_status_mmio(struct ata_port *ap) | ||
434 | { | ||
435 | return readb((void __iomem *) ap->ioaddr.status_addr); | ||
436 | } | ||
437 | |||
438 | |||
439 | /** | ||
440 | * ata_check_status - Read device status reg & clear interrupt | ||
441 | * @ap: port where the device is | ||
442 | * | ||
443 | * Reads ATA taskfile status register for currently-selected device | ||
444 | * and return its value. This also clears pending interrupts | ||
445 | * from this device | ||
446 | * | ||
447 | * May be used as the check_status() entry in ata_port_operations. | ||
448 | * | ||
449 | * LOCKING: | ||
450 | * Inherited from caller. | ||
451 | */ | ||
452 | u8 ata_check_status(struct ata_port *ap) | ||
453 | { | ||
454 | if (ap->flags & ATA_FLAG_MMIO) | ||
455 | return ata_check_status_mmio(ap); | ||
456 | return ata_check_status_pio(ap); | ||
457 | } | ||
458 | |||
459 | |||
460 | /** | ||
461 | * ata_altstatus - Read device alternate status reg | ||
462 | * @ap: port where the device is | ||
463 | * | ||
464 | * Reads ATA taskfile alternate status register for | ||
465 | * currently-selected device and return its value. | ||
466 | * | ||
467 | * Note: may NOT be used as the check_altstatus() entry in | ||
468 | * ata_port_operations. | ||
469 | * | ||
470 | * LOCKING: | ||
471 | * Inherited from caller. | ||
472 | */ | ||
473 | u8 ata_altstatus(struct ata_port *ap) | ||
474 | { | ||
475 | if (ap->ops->check_altstatus) | ||
476 | return ap->ops->check_altstatus(ap); | ||
477 | |||
478 | if (ap->flags & ATA_FLAG_MMIO) | ||
479 | return readb((void __iomem *)ap->ioaddr.altstatus_addr); | ||
480 | return inb(ap->ioaddr.altstatus_addr); | ||
481 | } | ||
482 | |||
483 | 86 | ||
484 | /** | 87 | /** |
485 | * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure | 88 | * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure |
@@ -2009,6 +1612,26 @@ err_out: | |||
2009 | } | 1612 | } |
2010 | 1613 | ||
2011 | /** | 1614 | /** |
1615 | * ata_tf_to_host - issue ATA taskfile to host controller | ||
1616 | * @ap: port to which command is being issued | ||
1617 | * @tf: ATA taskfile register set | ||
1618 | * | ||
1619 | * Issues ATA taskfile register set to ATA host controller, | ||
1620 | * with proper synchronization with interrupt handler and | ||
1621 | * other threads. | ||
1622 | * | ||
1623 | * LOCKING: | ||
1624 | * spin_lock_irqsave(host_set lock) | ||
1625 | */ | ||
1626 | |||
1627 | static inline void ata_tf_to_host(struct ata_port *ap, | ||
1628 | const struct ata_taskfile *tf) | ||
1629 | { | ||
1630 | ap->ops->tf_load(ap, tf); | ||
1631 | ap->ops->exec_command(ap, tf); | ||
1632 | } | ||
1633 | |||
1634 | /** | ||
2012 | * ata_busy_sleep - sleep until BSY clears, or timeout | 1635 | * ata_busy_sleep - sleep until BSY clears, or timeout |
2013 | * @ap: port containing status register to be polled | 1636 | * @ap: port containing status register to be polled |
2014 | * @tmout_pat: impatience timeout | 1637 | * @tmout_pat: impatience timeout |
@@ -5106,32 +4729,6 @@ void ata_std_ports(struct ata_ioports *ioaddr) | |||
5106 | ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD; | 4729 | ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD; |
5107 | } | 4730 | } |
5108 | 4731 | ||
5109 | static struct ata_probe_ent * | ||
5110 | ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) | ||
5111 | { | ||
5112 | struct ata_probe_ent *probe_ent; | ||
5113 | |||
5114 | probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); | ||
5115 | if (!probe_ent) { | ||
5116 | printk(KERN_ERR DRV_NAME "(%s): out of memory\n", | ||
5117 | kobject_name(&(dev->kobj))); | ||
5118 | return NULL; | ||
5119 | } | ||
5120 | |||
5121 | INIT_LIST_HEAD(&probe_ent->node); | ||
5122 | probe_ent->dev = dev; | ||
5123 | |||
5124 | probe_ent->sht = port->sht; | ||
5125 | probe_ent->host_flags = port->host_flags; | ||
5126 | probe_ent->pio_mask = port->pio_mask; | ||
5127 | probe_ent->mwdma_mask = port->mwdma_mask; | ||
5128 | probe_ent->udma_mask = port->udma_mask; | ||
5129 | probe_ent->port_ops = port->port_ops; | ||
5130 | |||
5131 | return probe_ent; | ||
5132 | } | ||
5133 | |||
5134 | |||
5135 | 4732 | ||
5136 | #ifdef CONFIG_PCI | 4733 | #ifdef CONFIG_PCI |
5137 | 4734 | ||
@@ -5143,256 +4740,6 @@ void ata_pci_host_stop (struct ata_host_set *host_set) | |||
5143 | } | 4740 | } |
5144 | 4741 | ||
5145 | /** | 4742 | /** |
5146 | * ata_pci_init_native_mode - Initialize native-mode driver | ||
5147 | * @pdev: pci device to be initialized | ||
5148 | * @port: array[2] of pointers to port info structures. | ||
5149 | * @ports: bitmap of ports present | ||
5150 | * | ||
5151 | * Utility function which allocates and initializes an | ||
5152 | * ata_probe_ent structure for a standard dual-port | ||
5153 | * PIO-based IDE controller. The returned ata_probe_ent | ||
5154 | * structure can be passed to ata_device_add(). The returned | ||
5155 | * ata_probe_ent structure should then be freed with kfree(). | ||
5156 | * | ||
5157 | * The caller need only pass the address of the primary port, the | ||
5158 | * secondary will be deduced automatically. If the device has non | ||
5159 | * standard secondary port mappings this function can be called twice, | ||
5160 | * once for each interface. | ||
5161 | */ | ||
5162 | |||
5163 | struct ata_probe_ent * | ||
5164 | ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports) | ||
5165 | { | ||
5166 | struct ata_probe_ent *probe_ent = | ||
5167 | ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); | ||
5168 | int p = 0; | ||
5169 | |||
5170 | if (!probe_ent) | ||
5171 | return NULL; | ||
5172 | |||
5173 | probe_ent->irq = pdev->irq; | ||
5174 | probe_ent->irq_flags = SA_SHIRQ; | ||
5175 | probe_ent->private_data = port[0]->private_data; | ||
5176 | |||
5177 | if (ports & ATA_PORT_PRIMARY) { | ||
5178 | probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0); | ||
5179 | probe_ent->port[p].altstatus_addr = | ||
5180 | probe_ent->port[p].ctl_addr = | ||
5181 | pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; | ||
5182 | probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4); | ||
5183 | ata_std_ports(&probe_ent->port[p]); | ||
5184 | p++; | ||
5185 | } | ||
5186 | |||
5187 | if (ports & ATA_PORT_SECONDARY) { | ||
5188 | probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2); | ||
5189 | probe_ent->port[p].altstatus_addr = | ||
5190 | probe_ent->port[p].ctl_addr = | ||
5191 | pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; | ||
5192 | probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8; | ||
5193 | ata_std_ports(&probe_ent->port[p]); | ||
5194 | p++; | ||
5195 | } | ||
5196 | |||
5197 | probe_ent->n_ports = p; | ||
5198 | return probe_ent; | ||
5199 | } | ||
5200 | |||
5201 | static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info *port, int port_num) | ||
5202 | { | ||
5203 | struct ata_probe_ent *probe_ent; | ||
5204 | |||
5205 | probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); | ||
5206 | if (!probe_ent) | ||
5207 | return NULL; | ||
5208 | |||
5209 | probe_ent->legacy_mode = 1; | ||
5210 | probe_ent->n_ports = 1; | ||
5211 | probe_ent->hard_port_no = port_num; | ||
5212 | probe_ent->private_data = port->private_data; | ||
5213 | |||
5214 | switch(port_num) | ||
5215 | { | ||
5216 | case 0: | ||
5217 | probe_ent->irq = 14; | ||
5218 | probe_ent->port[0].cmd_addr = 0x1f0; | ||
5219 | probe_ent->port[0].altstatus_addr = | ||
5220 | probe_ent->port[0].ctl_addr = 0x3f6; | ||
5221 | break; | ||
5222 | case 1: | ||
5223 | probe_ent->irq = 15; | ||
5224 | probe_ent->port[0].cmd_addr = 0x170; | ||
5225 | probe_ent->port[0].altstatus_addr = | ||
5226 | probe_ent->port[0].ctl_addr = 0x376; | ||
5227 | break; | ||
5228 | } | ||
5229 | probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4) + 8 * port_num; | ||
5230 | ata_std_ports(&probe_ent->port[0]); | ||
5231 | return probe_ent; | ||
5232 | } | ||
5233 | |||
5234 | /** | ||
5235 | * ata_pci_init_one - Initialize/register PCI IDE host controller | ||
5236 | * @pdev: Controller to be initialized | ||
5237 | * @port_info: Information from low-level host driver | ||
5238 | * @n_ports: Number of ports attached to host controller | ||
5239 | * | ||
5240 | * This is a helper function which can be called from a driver's | ||
5241 | * xxx_init_one() probe function if the hardware uses traditional | ||
5242 | * IDE taskfile registers. | ||
5243 | * | ||
5244 | * This function calls pci_enable_device(), reserves its register | ||
5245 | * regions, sets the dma mask, enables bus master mode, and calls | ||
5246 | * ata_device_add() | ||
5247 | * | ||
5248 | * LOCKING: | ||
5249 | * Inherited from PCI layer (may sleep). | ||
5250 | * | ||
5251 | * RETURNS: | ||
5252 | * Zero on success, negative on errno-based value on error. | ||
5253 | */ | ||
5254 | |||
5255 | int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | ||
5256 | unsigned int n_ports) | ||
5257 | { | ||
5258 | struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL; | ||
5259 | struct ata_port_info *port[2]; | ||
5260 | u8 tmp8, mask; | ||
5261 | unsigned int legacy_mode = 0; | ||
5262 | int disable_dev_on_err = 1; | ||
5263 | int rc; | ||
5264 | |||
5265 | DPRINTK("ENTER\n"); | ||
5266 | |||
5267 | port[0] = port_info[0]; | ||
5268 | if (n_ports > 1) | ||
5269 | port[1] = port_info[1]; | ||
5270 | else | ||
5271 | port[1] = port[0]; | ||
5272 | |||
5273 | if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0 | ||
5274 | && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { | ||
5275 | /* TODO: What if one channel is in native mode ... */ | ||
5276 | pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); | ||
5277 | mask = (1 << 2) | (1 << 0); | ||
5278 | if ((tmp8 & mask) != mask) | ||
5279 | legacy_mode = (1 << 3); | ||
5280 | } | ||
5281 | |||
5282 | /* FIXME... */ | ||
5283 | if ((!legacy_mode) && (n_ports > 2)) { | ||
5284 | printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n"); | ||
5285 | n_ports = 2; | ||
5286 | /* For now */ | ||
5287 | } | ||
5288 | |||
5289 | /* FIXME: Really for ATA it isn't safe because the device may be | ||
5290 | multi-purpose and we want to leave it alone if it was already | ||
5291 | enabled. Secondly for shared use as Arjan says we want refcounting | ||
5292 | |||
5293 | Checking dev->is_enabled is insufficient as this is not set at | ||
5294 | boot for the primary video which is BIOS enabled | ||
5295 | */ | ||
5296 | |||
5297 | rc = pci_enable_device(pdev); | ||
5298 | if (rc) | ||
5299 | return rc; | ||
5300 | |||
5301 | rc = pci_request_regions(pdev, DRV_NAME); | ||
5302 | if (rc) { | ||
5303 | disable_dev_on_err = 0; | ||
5304 | goto err_out; | ||
5305 | } | ||
5306 | |||
5307 | /* FIXME: Should use platform specific mappers for legacy port ranges */ | ||
5308 | if (legacy_mode) { | ||
5309 | if (!request_region(0x1f0, 8, "libata")) { | ||
5310 | struct resource *conflict, res; | ||
5311 | res.start = 0x1f0; | ||
5312 | res.end = 0x1f0 + 8 - 1; | ||
5313 | conflict = ____request_resource(&ioport_resource, &res); | ||
5314 | if (!strcmp(conflict->name, "libata")) | ||
5315 | legacy_mode |= (1 << 0); | ||
5316 | else { | ||
5317 | disable_dev_on_err = 0; | ||
5318 | printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n"); | ||
5319 | } | ||
5320 | } else | ||
5321 | legacy_mode |= (1 << 0); | ||
5322 | |||
5323 | if (!request_region(0x170, 8, "libata")) { | ||
5324 | struct resource *conflict, res; | ||
5325 | res.start = 0x170; | ||
5326 | res.end = 0x170 + 8 - 1; | ||
5327 | conflict = ____request_resource(&ioport_resource, &res); | ||
5328 | if (!strcmp(conflict->name, "libata")) | ||
5329 | legacy_mode |= (1 << 1); | ||
5330 | else { | ||
5331 | disable_dev_on_err = 0; | ||
5332 | printk(KERN_WARNING "ata: 0x170 IDE port busy\n"); | ||
5333 | } | ||
5334 | } else | ||
5335 | legacy_mode |= (1 << 1); | ||
5336 | } | ||
5337 | |||
5338 | /* we have legacy mode, but all ports are unavailable */ | ||
5339 | if (legacy_mode == (1 << 3)) { | ||
5340 | rc = -EBUSY; | ||
5341 | goto err_out_regions; | ||
5342 | } | ||
5343 | |||
5344 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | ||
5345 | if (rc) | ||
5346 | goto err_out_regions; | ||
5347 | rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); | ||
5348 | if (rc) | ||
5349 | goto err_out_regions; | ||
5350 | |||
5351 | if (legacy_mode) { | ||
5352 | if (legacy_mode & (1 << 0)) | ||
5353 | probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0); | ||
5354 | if (legacy_mode & (1 << 1)) | ||
5355 | probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1); | ||
5356 | } else { | ||
5357 | if (n_ports == 2) | ||
5358 | probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); | ||
5359 | else | ||
5360 | probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY); | ||
5361 | } | ||
5362 | if (!probe_ent && !probe_ent2) { | ||
5363 | rc = -ENOMEM; | ||
5364 | goto err_out_regions; | ||
5365 | } | ||
5366 | |||
5367 | pci_set_master(pdev); | ||
5368 | |||
5369 | /* FIXME: check ata_device_add return */ | ||
5370 | if (legacy_mode) { | ||
5371 | if (legacy_mode & (1 << 0)) | ||
5372 | ata_device_add(probe_ent); | ||
5373 | if (legacy_mode & (1 << 1)) | ||
5374 | ata_device_add(probe_ent2); | ||
5375 | } else | ||
5376 | ata_device_add(probe_ent); | ||
5377 | |||
5378 | kfree(probe_ent); | ||
5379 | kfree(probe_ent2); | ||
5380 | |||
5381 | return 0; | ||
5382 | |||
5383 | err_out_regions: | ||
5384 | if (legacy_mode & (1 << 0)) | ||
5385 | release_region(0x1f0, 8); | ||
5386 | if (legacy_mode & (1 << 1)) | ||
5387 | release_region(0x170, 8); | ||
5388 | pci_release_regions(pdev); | ||
5389 | err_out: | ||
5390 | if (disable_dev_on_err) | ||
5391 | pci_disable_device(pdev); | ||
5392 | return rc; | ||
5393 | } | ||
5394 | |||
5395 | /** | ||
5396 | * ata_pci_remove_one - PCI layer callback for device removal | 4743 | * ata_pci_remove_one - PCI layer callback for device removal |
5397 | * @pdev: PCI device that was removed | 4744 | * @pdev: PCI device that was removed |
5398 | * | 4745 | * |