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 | |
parent | 389984cb75a5d26aa6ee9724c343bbd130cb3eec (diff) |
[libata] Move PCI IDE BMDMA-related code to new file libata-bmdma.c.
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/Makefile | 2 | ||||
-rw-r--r-- | drivers/scsi/libata-bmdma.c | 703 | ||||
-rw-r--r-- | drivers/scsi/libata-core.c | 693 |
3 files changed, 724 insertions, 674 deletions
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 320e765fa0cd..15dc2e00e1b2 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile | |||
@@ -163,7 +163,7 @@ ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \ | |||
163 | CFLAGS_ncr53c8xx.o := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m) | 163 | CFLAGS_ncr53c8xx.o := $(ncr53c8xx-flags-y) $(ncr53c8xx-flags-m) |
164 | zalon7xx-objs := zalon.o ncr53c8xx.o | 164 | zalon7xx-objs := zalon.o ncr53c8xx.o |
165 | NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o | 165 | NCR_Q720_mod-objs := NCR_Q720.o ncr53c8xx.o |
166 | libata-objs := libata-core.o libata-scsi.o | 166 | libata-objs := libata-core.o libata-scsi.o libata-bmdma.o |
167 | oktagon_esp_mod-objs := oktagon_esp.o oktagon_io.o | 167 | oktagon_esp_mod-objs := oktagon_esp.o oktagon_io.o |
168 | 168 | ||
169 | # Files generated that shall be removed upon make clean | 169 | # Files generated that shall be removed upon make clean |
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c new file mode 100644 index 000000000000..a93336adcd23 --- /dev/null +++ b/drivers/scsi/libata-bmdma.c | |||
@@ -0,0 +1,703 @@ | |||
1 | /* | ||
2 | * libata-bmdma.c - helper library for PCI IDE BMDMA | ||
3 | * | ||
4 | * Maintained by: Jeff Garzik <jgarzik@pobox.com> | ||
5 | * Please ALWAYS copy linux-ide@vger.kernel.org | ||
6 | * on emails. | ||
7 | * | ||
8 | * Copyright 2003-2006 Red Hat, Inc. All rights reserved. | ||
9 | * Copyright 2003-2006 Jeff Garzik | ||
10 | * | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2, or (at your option) | ||
15 | * any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; see the file COPYING. If not, write to | ||
24 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | * | ||
26 | * | ||
27 | * libata documentation is available via 'make {ps|pdf}docs', | ||
28 | * as Documentation/DocBook/libata.* | ||
29 | * | ||
30 | * Hardware documentation available from http://www.t13.org/ and | ||
31 | * http://www.sata-io.org/ | ||
32 | * | ||
33 | */ | ||
34 | |||
35 | #include <linux/config.h> | ||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/pci.h> | ||
38 | #include <linux/libata.h> | ||
39 | |||
40 | #include "libata.h" | ||
41 | |||
42 | /** | ||
43 | * ata_tf_load_pio - send taskfile registers to host controller | ||
44 | * @ap: Port to which output is sent | ||
45 | * @tf: ATA taskfile register set | ||
46 | * | ||
47 | * Outputs ATA taskfile to standard ATA host controller. | ||
48 | * | ||
49 | * LOCKING: | ||
50 | * Inherited from caller. | ||
51 | */ | ||
52 | |||
53 | static void ata_tf_load_pio(struct ata_port *ap, const struct ata_taskfile *tf) | ||
54 | { | ||
55 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
56 | unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; | ||
57 | |||
58 | if (tf->ctl != ap->last_ctl) { | ||
59 | outb(tf->ctl, ioaddr->ctl_addr); | ||
60 | ap->last_ctl = tf->ctl; | ||
61 | ata_wait_idle(ap); | ||
62 | } | ||
63 | |||
64 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { | ||
65 | outb(tf->hob_feature, ioaddr->feature_addr); | ||
66 | outb(tf->hob_nsect, ioaddr->nsect_addr); | ||
67 | outb(tf->hob_lbal, ioaddr->lbal_addr); | ||
68 | outb(tf->hob_lbam, ioaddr->lbam_addr); | ||
69 | outb(tf->hob_lbah, ioaddr->lbah_addr); | ||
70 | VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", | ||
71 | tf->hob_feature, | ||
72 | tf->hob_nsect, | ||
73 | tf->hob_lbal, | ||
74 | tf->hob_lbam, | ||
75 | tf->hob_lbah); | ||
76 | } | ||
77 | |||
78 | if (is_addr) { | ||
79 | outb(tf->feature, ioaddr->feature_addr); | ||
80 | outb(tf->nsect, ioaddr->nsect_addr); | ||
81 | outb(tf->lbal, ioaddr->lbal_addr); | ||
82 | outb(tf->lbam, ioaddr->lbam_addr); | ||
83 | outb(tf->lbah, ioaddr->lbah_addr); | ||
84 | VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", | ||
85 | tf->feature, | ||
86 | tf->nsect, | ||
87 | tf->lbal, | ||
88 | tf->lbam, | ||
89 | tf->lbah); | ||
90 | } | ||
91 | |||
92 | if (tf->flags & ATA_TFLAG_DEVICE) { | ||
93 | outb(tf->device, ioaddr->device_addr); | ||
94 | VPRINTK("device 0x%X\n", tf->device); | ||
95 | } | ||
96 | |||
97 | ata_wait_idle(ap); | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * ata_tf_load_mmio - send taskfile registers to host controller | ||
102 | * @ap: Port to which output is sent | ||
103 | * @tf: ATA taskfile register set | ||
104 | * | ||
105 | * Outputs ATA taskfile to standard ATA host controller using MMIO. | ||
106 | * | ||
107 | * LOCKING: | ||
108 | * Inherited from caller. | ||
109 | */ | ||
110 | |||
111 | static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) | ||
112 | { | ||
113 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
114 | unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; | ||
115 | |||
116 | if (tf->ctl != ap->last_ctl) { | ||
117 | writeb(tf->ctl, (void __iomem *) ap->ioaddr.ctl_addr); | ||
118 | ap->last_ctl = tf->ctl; | ||
119 | ata_wait_idle(ap); | ||
120 | } | ||
121 | |||
122 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { | ||
123 | writeb(tf->hob_feature, (void __iomem *) ioaddr->feature_addr); | ||
124 | writeb(tf->hob_nsect, (void __iomem *) ioaddr->nsect_addr); | ||
125 | writeb(tf->hob_lbal, (void __iomem *) ioaddr->lbal_addr); | ||
126 | writeb(tf->hob_lbam, (void __iomem *) ioaddr->lbam_addr); | ||
127 | writeb(tf->hob_lbah, (void __iomem *) ioaddr->lbah_addr); | ||
128 | VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", | ||
129 | tf->hob_feature, | ||
130 | tf->hob_nsect, | ||
131 | tf->hob_lbal, | ||
132 | tf->hob_lbam, | ||
133 | tf->hob_lbah); | ||
134 | } | ||
135 | |||
136 | if (is_addr) { | ||
137 | writeb(tf->feature, (void __iomem *) ioaddr->feature_addr); | ||
138 | writeb(tf->nsect, (void __iomem *) ioaddr->nsect_addr); | ||
139 | writeb(tf->lbal, (void __iomem *) ioaddr->lbal_addr); | ||
140 | writeb(tf->lbam, (void __iomem *) ioaddr->lbam_addr); | ||
141 | writeb(tf->lbah, (void __iomem *) ioaddr->lbah_addr); | ||
142 | VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", | ||
143 | tf->feature, | ||
144 | tf->nsect, | ||
145 | tf->lbal, | ||
146 | tf->lbam, | ||
147 | tf->lbah); | ||
148 | } | ||
149 | |||
150 | if (tf->flags & ATA_TFLAG_DEVICE) { | ||
151 | writeb(tf->device, (void __iomem *) ioaddr->device_addr); | ||
152 | VPRINTK("device 0x%X\n", tf->device); | ||
153 | } | ||
154 | |||
155 | ata_wait_idle(ap); | ||
156 | } | ||
157 | |||
158 | |||
159 | /** | ||
160 | * ata_tf_load - send taskfile registers to host controller | ||
161 | * @ap: Port to which output is sent | ||
162 | * @tf: ATA taskfile register set | ||
163 | * | ||
164 | * Outputs ATA taskfile to standard ATA host controller using MMIO | ||
165 | * or PIO as indicated by the ATA_FLAG_MMIO flag. | ||
166 | * Writes the control, feature, nsect, lbal, lbam, and lbah registers. | ||
167 | * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect, | ||
168 | * hob_lbal, hob_lbam, and hob_lbah. | ||
169 | * | ||
170 | * This function waits for idle (!BUSY and !DRQ) after writing | ||
171 | * registers. If the control register has a new value, this | ||
172 | * function also waits for idle after writing control and before | ||
173 | * writing the remaining registers. | ||
174 | * | ||
175 | * May be used as the tf_load() entry in ata_port_operations. | ||
176 | * | ||
177 | * LOCKING: | ||
178 | * Inherited from caller. | ||
179 | */ | ||
180 | void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) | ||
181 | { | ||
182 | if (ap->flags & ATA_FLAG_MMIO) | ||
183 | ata_tf_load_mmio(ap, tf); | ||
184 | else | ||
185 | ata_tf_load_pio(ap, tf); | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * ata_exec_command_pio - issue ATA command to host controller | ||
190 | * @ap: port to which command is being issued | ||
191 | * @tf: ATA taskfile register set | ||
192 | * | ||
193 | * Issues PIO write to ATA command register, with proper | ||
194 | * synchronization with interrupt handler / other threads. | ||
195 | * | ||
196 | * LOCKING: | ||
197 | * spin_lock_irqsave(host_set lock) | ||
198 | */ | ||
199 | |||
200 | static void ata_exec_command_pio(struct ata_port *ap, const struct ata_taskfile *tf) | ||
201 | { | ||
202 | DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); | ||
203 | |||
204 | outb(tf->command, ap->ioaddr.command_addr); | ||
205 | ata_pause(ap); | ||
206 | } | ||
207 | |||
208 | |||
209 | /** | ||
210 | * ata_exec_command_mmio - issue ATA command to host controller | ||
211 | * @ap: port to which command is being issued | ||
212 | * @tf: ATA taskfile register set | ||
213 | * | ||
214 | * Issues MMIO write to ATA command register, with proper | ||
215 | * synchronization with interrupt handler / other threads. | ||
216 | * | ||
217 | * LOCKING: | ||
218 | * spin_lock_irqsave(host_set lock) | ||
219 | */ | ||
220 | |||
221 | static void ata_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf) | ||
222 | { | ||
223 | DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); | ||
224 | |||
225 | writeb(tf->command, (void __iomem *) ap->ioaddr.command_addr); | ||
226 | ata_pause(ap); | ||
227 | } | ||
228 | |||
229 | |||
230 | /** | ||
231 | * ata_exec_command - issue ATA command to host controller | ||
232 | * @ap: port to which command is being issued | ||
233 | * @tf: ATA taskfile register set | ||
234 | * | ||
235 | * Issues PIO/MMIO write to ATA command register, with proper | ||
236 | * synchronization with interrupt handler / other threads. | ||
237 | * | ||
238 | * LOCKING: | ||
239 | * spin_lock_irqsave(host_set lock) | ||
240 | */ | ||
241 | void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) | ||
242 | { | ||
243 | if (ap->flags & ATA_FLAG_MMIO) | ||
244 | ata_exec_command_mmio(ap, tf); | ||
245 | else | ||
246 | ata_exec_command_pio(ap, tf); | ||
247 | } | ||
248 | |||
249 | /** | ||
250 | * ata_tf_read_pio - input device's ATA taskfile shadow registers | ||
251 | * @ap: Port from which input is read | ||
252 | * @tf: ATA taskfile register set for storing input | ||
253 | * | ||
254 | * Reads ATA taskfile registers for currently-selected device | ||
255 | * into @tf. | ||
256 | * | ||
257 | * LOCKING: | ||
258 | * Inherited from caller. | ||
259 | */ | ||
260 | |||
261 | static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf) | ||
262 | { | ||
263 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
264 | |||
265 | tf->command = ata_check_status(ap); | ||
266 | tf->feature = inb(ioaddr->error_addr); | ||
267 | tf->nsect = inb(ioaddr->nsect_addr); | ||
268 | tf->lbal = inb(ioaddr->lbal_addr); | ||
269 | tf->lbam = inb(ioaddr->lbam_addr); | ||
270 | tf->lbah = inb(ioaddr->lbah_addr); | ||
271 | tf->device = inb(ioaddr->device_addr); | ||
272 | |||
273 | if (tf->flags & ATA_TFLAG_LBA48) { | ||
274 | outb(tf->ctl | ATA_HOB, ioaddr->ctl_addr); | ||
275 | tf->hob_feature = inb(ioaddr->error_addr); | ||
276 | tf->hob_nsect = inb(ioaddr->nsect_addr); | ||
277 | tf->hob_lbal = inb(ioaddr->lbal_addr); | ||
278 | tf->hob_lbam = inb(ioaddr->lbam_addr); | ||
279 | tf->hob_lbah = inb(ioaddr->lbah_addr); | ||
280 | } | ||
281 | } | ||
282 | |||
283 | /** | ||
284 | * ata_tf_read_mmio - input device's ATA taskfile shadow registers | ||
285 | * @ap: Port from which input is read | ||
286 | * @tf: ATA taskfile register set for storing input | ||
287 | * | ||
288 | * Reads ATA taskfile registers for currently-selected device | ||
289 | * into @tf via MMIO. | ||
290 | * | ||
291 | * LOCKING: | ||
292 | * Inherited from caller. | ||
293 | */ | ||
294 | |||
295 | static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf) | ||
296 | { | ||
297 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
298 | |||
299 | tf->command = ata_check_status(ap); | ||
300 | tf->feature = readb((void __iomem *)ioaddr->error_addr); | ||
301 | tf->nsect = readb((void __iomem *)ioaddr->nsect_addr); | ||
302 | tf->lbal = readb((void __iomem *)ioaddr->lbal_addr); | ||
303 | tf->lbam = readb((void __iomem *)ioaddr->lbam_addr); | ||
304 | tf->lbah = readb((void __iomem *)ioaddr->lbah_addr); | ||
305 | tf->device = readb((void __iomem *)ioaddr->device_addr); | ||
306 | |||
307 | if (tf->flags & ATA_TFLAG_LBA48) { | ||
308 | writeb(tf->ctl | ATA_HOB, (void __iomem *) ap->ioaddr.ctl_addr); | ||
309 | tf->hob_feature = readb((void __iomem *)ioaddr->error_addr); | ||
310 | tf->hob_nsect = readb((void __iomem *)ioaddr->nsect_addr); | ||
311 | tf->hob_lbal = readb((void __iomem *)ioaddr->lbal_addr); | ||
312 | tf->hob_lbam = readb((void __iomem *)ioaddr->lbam_addr); | ||
313 | tf->hob_lbah = readb((void __iomem *)ioaddr->lbah_addr); | ||
314 | } | ||
315 | } | ||
316 | |||
317 | |||
318 | /** | ||
319 | * ata_tf_read - input device's ATA taskfile shadow registers | ||
320 | * @ap: Port from which input is read | ||
321 | * @tf: ATA taskfile register set for storing input | ||
322 | * | ||
323 | * Reads ATA taskfile registers for currently-selected device | ||
324 | * into @tf. | ||
325 | * | ||
326 | * Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48 | ||
327 | * is set, also reads the hob registers. | ||
328 | * | ||
329 | * May be used as the tf_read() entry in ata_port_operations. | ||
330 | * | ||
331 | * LOCKING: | ||
332 | * Inherited from caller. | ||
333 | */ | ||
334 | void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | ||
335 | { | ||
336 | if (ap->flags & ATA_FLAG_MMIO) | ||
337 | ata_tf_read_mmio(ap, tf); | ||
338 | else | ||
339 | ata_tf_read_pio(ap, tf); | ||
340 | } | ||
341 | |||
342 | /** | ||
343 | * ata_check_status_pio - Read device status reg & clear interrupt | ||
344 | * @ap: port where the device is | ||
345 | * | ||
346 | * Reads ATA taskfile status register for currently-selected device | ||
347 | * and return its value. This also clears pending interrupts | ||
348 | * from this device | ||
349 | * | ||
350 | * LOCKING: | ||
351 | * Inherited from caller. | ||
352 | */ | ||
353 | static u8 ata_check_status_pio(struct ata_port *ap) | ||
354 | { | ||
355 | return inb(ap->ioaddr.status_addr); | ||
356 | } | ||
357 | |||
358 | /** | ||
359 | * ata_check_status_mmio - Read device status reg & clear interrupt | ||
360 | * @ap: port where the device is | ||
361 | * | ||
362 | * Reads ATA taskfile status register for currently-selected device | ||
363 | * via MMIO and return its value. This also clears pending interrupts | ||
364 | * from this device | ||
365 | * | ||
366 | * LOCKING: | ||
367 | * Inherited from caller. | ||
368 | */ | ||
369 | static u8 ata_check_status_mmio(struct ata_port *ap) | ||
370 | { | ||
371 | return readb((void __iomem *) ap->ioaddr.status_addr); | ||
372 | } | ||
373 | |||
374 | |||
375 | /** | ||
376 | * ata_check_status - Read device status reg & clear interrupt | ||
377 | * @ap: port where the device is | ||
378 | * | ||
379 | * Reads ATA taskfile status register for currently-selected device | ||
380 | * and return its value. This also clears pending interrupts | ||
381 | * from this device | ||
382 | * | ||
383 | * May be used as the check_status() entry in ata_port_operations. | ||
384 | * | ||
385 | * LOCKING: | ||
386 | * Inherited from caller. | ||
387 | */ | ||
388 | u8 ata_check_status(struct ata_port *ap) | ||
389 | { | ||
390 | if (ap->flags & ATA_FLAG_MMIO) | ||
391 | return ata_check_status_mmio(ap); | ||
392 | return ata_check_status_pio(ap); | ||
393 | } | ||
394 | |||
395 | |||
396 | /** | ||
397 | * ata_altstatus - Read device alternate status reg | ||
398 | * @ap: port where the device is | ||
399 | * | ||
400 | * Reads ATA taskfile alternate status register for | ||
401 | * currently-selected device and return its value. | ||
402 | * | ||
403 | * Note: may NOT be used as the check_altstatus() entry in | ||
404 | * ata_port_operations. | ||
405 | * | ||
406 | * LOCKING: | ||
407 | * Inherited from caller. | ||
408 | */ | ||
409 | u8 ata_altstatus(struct ata_port *ap) | ||
410 | { | ||
411 | if (ap->ops->check_altstatus) | ||
412 | return ap->ops->check_altstatus(ap); | ||
413 | |||
414 | if (ap->flags & ATA_FLAG_MMIO) | ||
415 | return readb((void __iomem *)ap->ioaddr.altstatus_addr); | ||
416 | return inb(ap->ioaddr.altstatus_addr); | ||
417 | } | ||
418 | |||
419 | #ifdef CONFIG_PCI | ||
420 | static struct ata_probe_ent * | ||
421 | ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) | ||
422 | { | ||
423 | struct ata_probe_ent *probe_ent; | ||
424 | |||
425 | probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); | ||
426 | if (!probe_ent) { | ||
427 | printk(KERN_ERR DRV_NAME "(%s): out of memory\n", | ||
428 | kobject_name(&(dev->kobj))); | ||
429 | return NULL; | ||
430 | } | ||
431 | |||
432 | INIT_LIST_HEAD(&probe_ent->node); | ||
433 | probe_ent->dev = dev; | ||
434 | |||
435 | probe_ent->sht = port->sht; | ||
436 | probe_ent->host_flags = port->host_flags; | ||
437 | probe_ent->pio_mask = port->pio_mask; | ||
438 | probe_ent->mwdma_mask = port->mwdma_mask; | ||
439 | probe_ent->udma_mask = port->udma_mask; | ||
440 | probe_ent->port_ops = port->port_ops; | ||
441 | |||
442 | return probe_ent; | ||
443 | } | ||
444 | |||
445 | |||
446 | /** | ||
447 | * ata_pci_init_native_mode - Initialize native-mode driver | ||
448 | * @pdev: pci device to be initialized | ||
449 | * @port: array[2] of pointers to port info structures. | ||
450 | * @ports: bitmap of ports present | ||
451 | * | ||
452 | * Utility function which allocates and initializes an | ||
453 | * ata_probe_ent structure for a standard dual-port | ||
454 | * PIO-based IDE controller. The returned ata_probe_ent | ||
455 | * structure can be passed to ata_device_add(). The returned | ||
456 | * ata_probe_ent structure should then be freed with kfree(). | ||
457 | * | ||
458 | * The caller need only pass the address of the primary port, the | ||
459 | * secondary will be deduced automatically. If the device has non | ||
460 | * standard secondary port mappings this function can be called twice, | ||
461 | * once for each interface. | ||
462 | */ | ||
463 | |||
464 | struct ata_probe_ent * | ||
465 | ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports) | ||
466 | { | ||
467 | struct ata_probe_ent *probe_ent = | ||
468 | ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); | ||
469 | int p = 0; | ||
470 | |||
471 | if (!probe_ent) | ||
472 | return NULL; | ||
473 | |||
474 | probe_ent->irq = pdev->irq; | ||
475 | probe_ent->irq_flags = SA_SHIRQ; | ||
476 | probe_ent->private_data = port[0]->private_data; | ||
477 | |||
478 | if (ports & ATA_PORT_PRIMARY) { | ||
479 | probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0); | ||
480 | probe_ent->port[p].altstatus_addr = | ||
481 | probe_ent->port[p].ctl_addr = | ||
482 | pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; | ||
483 | probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4); | ||
484 | ata_std_ports(&probe_ent->port[p]); | ||
485 | p++; | ||
486 | } | ||
487 | |||
488 | if (ports & ATA_PORT_SECONDARY) { | ||
489 | probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2); | ||
490 | probe_ent->port[p].altstatus_addr = | ||
491 | probe_ent->port[p].ctl_addr = | ||
492 | pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; | ||
493 | probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8; | ||
494 | ata_std_ports(&probe_ent->port[p]); | ||
495 | p++; | ||
496 | } | ||
497 | |||
498 | probe_ent->n_ports = p; | ||
499 | return probe_ent; | ||
500 | } | ||
501 | |||
502 | |||
503 | static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, | ||
504 | struct ata_port_info *port, int port_num) | ||
505 | { | ||
506 | struct ata_probe_ent *probe_ent; | ||
507 | |||
508 | probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); | ||
509 | if (!probe_ent) | ||
510 | return NULL; | ||
511 | |||
512 | probe_ent->legacy_mode = 1; | ||
513 | probe_ent->n_ports = 1; | ||
514 | probe_ent->hard_port_no = port_num; | ||
515 | probe_ent->private_data = port->private_data; | ||
516 | |||
517 | switch(port_num) | ||
518 | { | ||
519 | case 0: | ||
520 | probe_ent->irq = 14; | ||
521 | probe_ent->port[0].cmd_addr = 0x1f0; | ||
522 | probe_ent->port[0].altstatus_addr = | ||
523 | probe_ent->port[0].ctl_addr = 0x3f6; | ||
524 | break; | ||
525 | case 1: | ||
526 | probe_ent->irq = 15; | ||
527 | probe_ent->port[0].cmd_addr = 0x170; | ||
528 | probe_ent->port[0].altstatus_addr = | ||
529 | probe_ent->port[0].ctl_addr = 0x376; | ||
530 | break; | ||
531 | } | ||
532 | |||
533 | probe_ent->port[0].bmdma_addr = | ||
534 | pci_resource_start(pdev, 4) + 8 * port_num; | ||
535 | ata_std_ports(&probe_ent->port[0]); | ||
536 | |||
537 | return probe_ent; | ||
538 | } | ||
539 | |||
540 | |||
541 | /** | ||
542 | * ata_pci_init_one - Initialize/register PCI IDE host controller | ||
543 | * @pdev: Controller to be initialized | ||
544 | * @port_info: Information from low-level host driver | ||
545 | * @n_ports: Number of ports attached to host controller | ||
546 | * | ||
547 | * This is a helper function which can be called from a driver's | ||
548 | * xxx_init_one() probe function if the hardware uses traditional | ||
549 | * IDE taskfile registers. | ||
550 | * | ||
551 | * This function calls pci_enable_device(), reserves its register | ||
552 | * regions, sets the dma mask, enables bus master mode, and calls | ||
553 | * ata_device_add() | ||
554 | * | ||
555 | * LOCKING: | ||
556 | * Inherited from PCI layer (may sleep). | ||
557 | * | ||
558 | * RETURNS: | ||
559 | * Zero on success, negative on errno-based value on error. | ||
560 | */ | ||
561 | |||
562 | int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | ||
563 | unsigned int n_ports) | ||
564 | { | ||
565 | struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL; | ||
566 | struct ata_port_info *port[2]; | ||
567 | u8 tmp8, mask; | ||
568 | unsigned int legacy_mode = 0; | ||
569 | int disable_dev_on_err = 1; | ||
570 | int rc; | ||
571 | |||
572 | DPRINTK("ENTER\n"); | ||
573 | |||
574 | port[0] = port_info[0]; | ||
575 | if (n_ports > 1) | ||
576 | port[1] = port_info[1]; | ||
577 | else | ||
578 | port[1] = port[0]; | ||
579 | |||
580 | if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0 | ||
581 | && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { | ||
582 | /* TODO: What if one channel is in native mode ... */ | ||
583 | pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); | ||
584 | mask = (1 << 2) | (1 << 0); | ||
585 | if ((tmp8 & mask) != mask) | ||
586 | legacy_mode = (1 << 3); | ||
587 | } | ||
588 | |||
589 | /* FIXME... */ | ||
590 | if ((!legacy_mode) && (n_ports > 2)) { | ||
591 | printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n"); | ||
592 | n_ports = 2; | ||
593 | /* For now */ | ||
594 | } | ||
595 | |||
596 | /* FIXME: Really for ATA it isn't safe because the device may be | ||
597 | multi-purpose and we want to leave it alone if it was already | ||
598 | enabled. Secondly for shared use as Arjan says we want refcounting | ||
599 | |||
600 | Checking dev->is_enabled is insufficient as this is not set at | ||
601 | boot for the primary video which is BIOS enabled | ||
602 | */ | ||
603 | |||
604 | rc = pci_enable_device(pdev); | ||
605 | if (rc) | ||
606 | return rc; | ||
607 | |||
608 | rc = pci_request_regions(pdev, DRV_NAME); | ||
609 | if (rc) { | ||
610 | disable_dev_on_err = 0; | ||
611 | goto err_out; | ||
612 | } | ||
613 | |||
614 | /* FIXME: Should use platform specific mappers for legacy port ranges */ | ||
615 | if (legacy_mode) { | ||
616 | if (!request_region(0x1f0, 8, "libata")) { | ||
617 | struct resource *conflict, res; | ||
618 | res.start = 0x1f0; | ||
619 | res.end = 0x1f0 + 8 - 1; | ||
620 | conflict = ____request_resource(&ioport_resource, &res); | ||
621 | if (!strcmp(conflict->name, "libata")) | ||
622 | legacy_mode |= (1 << 0); | ||
623 | else { | ||
624 | disable_dev_on_err = 0; | ||
625 | printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n"); | ||
626 | } | ||
627 | } else | ||
628 | legacy_mode |= (1 << 0); | ||
629 | |||
630 | if (!request_region(0x170, 8, "libata")) { | ||
631 | struct resource *conflict, res; | ||
632 | res.start = 0x170; | ||
633 | res.end = 0x170 + 8 - 1; | ||
634 | conflict = ____request_resource(&ioport_resource, &res); | ||
635 | if (!strcmp(conflict->name, "libata")) | ||
636 | legacy_mode |= (1 << 1); | ||
637 | else { | ||
638 | disable_dev_on_err = 0; | ||
639 | printk(KERN_WARNING "ata: 0x170 IDE port busy\n"); | ||
640 | } | ||
641 | } else | ||
642 | legacy_mode |= (1 << 1); | ||
643 | } | ||
644 | |||
645 | /* we have legacy mode, but all ports are unavailable */ | ||
646 | if (legacy_mode == (1 << 3)) { | ||
647 | rc = -EBUSY; | ||
648 | goto err_out_regions; | ||
649 | } | ||
650 | |||
651 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | ||
652 | if (rc) | ||
653 | goto err_out_regions; | ||
654 | rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); | ||
655 | if (rc) | ||
656 | goto err_out_regions; | ||
657 | |||
658 | if (legacy_mode) { | ||
659 | if (legacy_mode & (1 << 0)) | ||
660 | probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0); | ||
661 | if (legacy_mode & (1 << 1)) | ||
662 | probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1); | ||
663 | } else { | ||
664 | if (n_ports == 2) | ||
665 | probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); | ||
666 | else | ||
667 | probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY); | ||
668 | } | ||
669 | if (!probe_ent && !probe_ent2) { | ||
670 | rc = -ENOMEM; | ||
671 | goto err_out_regions; | ||
672 | } | ||
673 | |||
674 | pci_set_master(pdev); | ||
675 | |||
676 | /* FIXME: check ata_device_add return */ | ||
677 | if (legacy_mode) { | ||
678 | if (legacy_mode & (1 << 0)) | ||
679 | ata_device_add(probe_ent); | ||
680 | if (legacy_mode & (1 << 1)) | ||
681 | ata_device_add(probe_ent2); | ||
682 | } else | ||
683 | ata_device_add(probe_ent); | ||
684 | |||
685 | kfree(probe_ent); | ||
686 | kfree(probe_ent2); | ||
687 | |||
688 | return 0; | ||
689 | |||
690 | err_out_regions: | ||
691 | if (legacy_mode & (1 << 0)) | ||
692 | release_region(0x1f0, 8); | ||
693 | if (legacy_mode & (1 << 1)) | ||
694 | release_region(0x170, 8); | ||
695 | pci_release_regions(pdev); | ||
696 | err_out: | ||
697 | if (disable_dev_on_err) | ||
698 | pci_disable_device(pdev); | ||
699 | return rc; | ||
700 | } | ||
701 | |||
702 | #endif /* CONFIG_PCI */ | ||
703 | |||
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 | * |