diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2006-02-09 05:15:47 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-02-09 05:15:47 -0500 |
commit | a0819750024a0056d760a936d72f76882a7e393f (patch) | |
tree | 4d3e5a22b13e5a8ac3553fca1cedd9c689235138 /drivers | |
parent | 41232d3ecac9df8eb94ff27330eb84b8baccc6b7 (diff) | |
parent | 1fdffbce0332b3e00993d741e76935e7f4f0d40f (diff) |
Merge branch 'upstream'
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 59d8dd025107..8e31d4b0a5b7 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -84,403 +84,6 @@ MODULE_DESCRIPTION("Library module for ATA devices"); | |||
84 | MODULE_LICENSE("GPL"); | 84 | MODULE_LICENSE("GPL"); |
85 | MODULE_VERSION(DRV_VERSION); | 85 | MODULE_VERSION(DRV_VERSION); |
86 | 86 | ||
87 | /** | ||
88 | * ata_tf_load_pio - send taskfile registers to host controller | ||
89 | * @ap: Port to which output is sent | ||
90 | * @tf: ATA taskfile register set | ||
91 | * | ||
92 | * Outputs ATA taskfile to standard ATA host controller. | ||
93 | * | ||
94 | * LOCKING: | ||
95 | * Inherited from caller. | ||
96 | */ | ||
97 | |||
98 | static void ata_tf_load_pio(struct ata_port *ap, const struct ata_taskfile *tf) | ||
99 | { | ||
100 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
101 | unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; | ||
102 | |||
103 | if (tf->ctl != ap->last_ctl) { | ||
104 | outb(tf->ctl, ioaddr->ctl_addr); | ||
105 | ap->last_ctl = tf->ctl; | ||
106 | ata_wait_idle(ap); | ||
107 | } | ||
108 | |||
109 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { | ||
110 | outb(tf->hob_feature, ioaddr->feature_addr); | ||
111 | outb(tf->hob_nsect, ioaddr->nsect_addr); | ||
112 | outb(tf->hob_lbal, ioaddr->lbal_addr); | ||
113 | outb(tf->hob_lbam, ioaddr->lbam_addr); | ||
114 | outb(tf->hob_lbah, ioaddr->lbah_addr); | ||
115 | VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", | ||
116 | tf->hob_feature, | ||
117 | tf->hob_nsect, | ||
118 | tf->hob_lbal, | ||
119 | tf->hob_lbam, | ||
120 | tf->hob_lbah); | ||
121 | } | ||
122 | |||
123 | if (is_addr) { | ||
124 | outb(tf->feature, ioaddr->feature_addr); | ||
125 | outb(tf->nsect, ioaddr->nsect_addr); | ||
126 | outb(tf->lbal, ioaddr->lbal_addr); | ||
127 | outb(tf->lbam, ioaddr->lbam_addr); | ||
128 | outb(tf->lbah, ioaddr->lbah_addr); | ||
129 | VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", | ||
130 | tf->feature, | ||
131 | tf->nsect, | ||
132 | tf->lbal, | ||
133 | tf->lbam, | ||
134 | tf->lbah); | ||
135 | } | ||
136 | |||
137 | if (tf->flags & ATA_TFLAG_DEVICE) { | ||
138 | outb(tf->device, ioaddr->device_addr); | ||
139 | VPRINTK("device 0x%X\n", tf->device); | ||
140 | } | ||
141 | |||
142 | ata_wait_idle(ap); | ||
143 | } | ||
144 | |||
145 | /** | ||
146 | * ata_tf_load_mmio - send taskfile registers to host controller | ||
147 | * @ap: Port to which output is sent | ||
148 | * @tf: ATA taskfile register set | ||
149 | * | ||
150 | * Outputs ATA taskfile to standard ATA host controller using MMIO. | ||
151 | * | ||
152 | * LOCKING: | ||
153 | * Inherited from caller. | ||
154 | */ | ||
155 | |||
156 | static void ata_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf) | ||
157 | { | ||
158 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
159 | unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; | ||
160 | |||
161 | if (tf->ctl != ap->last_ctl) { | ||
162 | writeb(tf->ctl, (void __iomem *) ap->ioaddr.ctl_addr); | ||
163 | ap->last_ctl = tf->ctl; | ||
164 | ata_wait_idle(ap); | ||
165 | } | ||
166 | |||
167 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { | ||
168 | writeb(tf->hob_feature, (void __iomem *) ioaddr->feature_addr); | ||
169 | writeb(tf->hob_nsect, (void __iomem *) ioaddr->nsect_addr); | ||
170 | writeb(tf->hob_lbal, (void __iomem *) ioaddr->lbal_addr); | ||
171 | writeb(tf->hob_lbam, (void __iomem *) ioaddr->lbam_addr); | ||
172 | writeb(tf->hob_lbah, (void __iomem *) ioaddr->lbah_addr); | ||
173 | VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", | ||
174 | tf->hob_feature, | ||
175 | tf->hob_nsect, | ||
176 | tf->hob_lbal, | ||
177 | tf->hob_lbam, | ||
178 | tf->hob_lbah); | ||
179 | } | ||
180 | |||
181 | if (is_addr) { | ||
182 | writeb(tf->feature, (void __iomem *) ioaddr->feature_addr); | ||
183 | writeb(tf->nsect, (void __iomem *) ioaddr->nsect_addr); | ||
184 | writeb(tf->lbal, (void __iomem *) ioaddr->lbal_addr); | ||
185 | writeb(tf->lbam, (void __iomem *) ioaddr->lbam_addr); | ||
186 | writeb(tf->lbah, (void __iomem *) ioaddr->lbah_addr); | ||
187 | VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", | ||
188 | tf->feature, | ||
189 | tf->nsect, | ||
190 | tf->lbal, | ||
191 | tf->lbam, | ||
192 | tf->lbah); | ||
193 | } | ||
194 | |||
195 | if (tf->flags & ATA_TFLAG_DEVICE) { | ||
196 | writeb(tf->device, (void __iomem *) ioaddr->device_addr); | ||
197 | VPRINTK("device 0x%X\n", tf->device); | ||
198 | } | ||
199 | |||
200 | ata_wait_idle(ap); | ||
201 | } | ||
202 | |||
203 | |||
204 | /** | ||
205 | * ata_tf_load - send taskfile registers to host controller | ||
206 | * @ap: Port to which output is sent | ||
207 | * @tf: ATA taskfile register set | ||
208 | * | ||
209 | * Outputs ATA taskfile to standard ATA host controller using MMIO | ||
210 | * or PIO as indicated by the ATA_FLAG_MMIO flag. | ||
211 | * Writes the control, feature, nsect, lbal, lbam, and lbah registers. | ||
212 | * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect, | ||
213 | * hob_lbal, hob_lbam, and hob_lbah. | ||
214 | * | ||
215 | * This function waits for idle (!BUSY and !DRQ) after writing | ||
216 | * registers. If the control register has a new value, this | ||
217 | * function also waits for idle after writing control and before | ||
218 | * writing the remaining registers. | ||
219 | * | ||
220 | * May be used as the tf_load() entry in ata_port_operations. | ||
221 | * | ||
222 | * LOCKING: | ||
223 | * Inherited from caller. | ||
224 | */ | ||
225 | void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) | ||
226 | { | ||
227 | if (ap->flags & ATA_FLAG_MMIO) | ||
228 | ata_tf_load_mmio(ap, tf); | ||
229 | else | ||
230 | ata_tf_load_pio(ap, tf); | ||
231 | } | ||
232 | |||
233 | /** | ||
234 | * ata_exec_command_pio - issue ATA command to host controller | ||
235 | * @ap: port to which command is being issued | ||
236 | * @tf: ATA taskfile register set | ||
237 | * | ||
238 | * Issues PIO write to ATA command register, with proper | ||
239 | * synchronization with interrupt handler / other threads. | ||
240 | * | ||
241 | * LOCKING: | ||
242 | * spin_lock_irqsave(host_set lock) | ||
243 | */ | ||
244 | |||
245 | static void ata_exec_command_pio(struct ata_port *ap, const struct ata_taskfile *tf) | ||
246 | { | ||
247 | DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); | ||
248 | |||
249 | outb(tf->command, ap->ioaddr.command_addr); | ||
250 | ata_pause(ap); | ||
251 | } | ||
252 | |||
253 | |||
254 | /** | ||
255 | * ata_exec_command_mmio - issue ATA command to host controller | ||
256 | * @ap: port to which command is being issued | ||
257 | * @tf: ATA taskfile register set | ||
258 | * | ||
259 | * Issues MMIO write to ATA command register, with proper | ||
260 | * synchronization with interrupt handler / other threads. | ||
261 | * | ||
262 | * LOCKING: | ||
263 | * spin_lock_irqsave(host_set lock) | ||
264 | */ | ||
265 | |||
266 | static void ata_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf) | ||
267 | { | ||
268 | DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command); | ||
269 | |||
270 | writeb(tf->command, (void __iomem *) ap->ioaddr.command_addr); | ||
271 | ata_pause(ap); | ||
272 | } | ||
273 | |||
274 | |||
275 | /** | ||
276 | * ata_exec_command - issue ATA command to host controller | ||
277 | * @ap: port to which command is being issued | ||
278 | * @tf: ATA taskfile register set | ||
279 | * | ||
280 | * Issues PIO/MMIO write to ATA command register, with proper | ||
281 | * synchronization with interrupt handler / other threads. | ||
282 | * | ||
283 | * LOCKING: | ||
284 | * spin_lock_irqsave(host_set lock) | ||
285 | */ | ||
286 | void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) | ||
287 | { | ||
288 | if (ap->flags & ATA_FLAG_MMIO) | ||
289 | ata_exec_command_mmio(ap, tf); | ||
290 | else | ||
291 | ata_exec_command_pio(ap, tf); | ||
292 | } | ||
293 | |||
294 | /** | ||
295 | * ata_tf_to_host - issue ATA taskfile to host controller | ||
296 | * @ap: port to which command is being issued | ||
297 | * @tf: ATA taskfile register set | ||
298 | * | ||
299 | * Issues ATA taskfile register set to ATA host controller, | ||
300 | * with proper synchronization with interrupt handler and | ||
301 | * other threads. | ||
302 | * | ||
303 | * LOCKING: | ||
304 | * spin_lock_irqsave(host_set lock) | ||
305 | */ | ||
306 | |||
307 | static inline void ata_tf_to_host(struct ata_port *ap, | ||
308 | const struct ata_taskfile *tf) | ||
309 | { | ||
310 | ap->ops->tf_load(ap, tf); | ||
311 | ap->ops->exec_command(ap, tf); | ||
312 | } | ||
313 | |||
314 | /** | ||
315 | * ata_tf_read_pio - input device's ATA taskfile shadow registers | ||
316 | * @ap: Port from which input is read | ||
317 | * @tf: ATA taskfile register set for storing input | ||
318 | * | ||
319 | * Reads ATA taskfile registers for currently-selected device | ||
320 | * into @tf. | ||
321 | * | ||
322 | * LOCKING: | ||
323 | * Inherited from caller. | ||
324 | */ | ||
325 | |||
326 | static void ata_tf_read_pio(struct ata_port *ap, struct ata_taskfile *tf) | ||
327 | { | ||
328 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
329 | |||
330 | tf->command = ata_check_status(ap); | ||
331 | tf->feature = inb(ioaddr->error_addr); | ||
332 | tf->nsect = inb(ioaddr->nsect_addr); | ||
333 | tf->lbal = inb(ioaddr->lbal_addr); | ||
334 | tf->lbam = inb(ioaddr->lbam_addr); | ||
335 | tf->lbah = inb(ioaddr->lbah_addr); | ||
336 | tf->device = inb(ioaddr->device_addr); | ||
337 | |||
338 | if (tf->flags & ATA_TFLAG_LBA48) { | ||
339 | outb(tf->ctl | ATA_HOB, ioaddr->ctl_addr); | ||
340 | tf->hob_feature = inb(ioaddr->error_addr); | ||
341 | tf->hob_nsect = inb(ioaddr->nsect_addr); | ||
342 | tf->hob_lbal = inb(ioaddr->lbal_addr); | ||
343 | tf->hob_lbam = inb(ioaddr->lbam_addr); | ||
344 | tf->hob_lbah = inb(ioaddr->lbah_addr); | ||
345 | } | ||
346 | } | ||
347 | |||
348 | /** | ||
349 | * ata_tf_read_mmio - input device's ATA taskfile shadow registers | ||
350 | * @ap: Port from which input is read | ||
351 | * @tf: ATA taskfile register set for storing input | ||
352 | * | ||
353 | * Reads ATA taskfile registers for currently-selected device | ||
354 | * into @tf via MMIO. | ||
355 | * | ||
356 | * LOCKING: | ||
357 | * Inherited from caller. | ||
358 | */ | ||
359 | |||
360 | static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf) | ||
361 | { | ||
362 | struct ata_ioports *ioaddr = &ap->ioaddr; | ||
363 | |||
364 | tf->command = ata_check_status(ap); | ||
365 | tf->feature = readb((void __iomem *)ioaddr->error_addr); | ||
366 | tf->nsect = readb((void __iomem *)ioaddr->nsect_addr); | ||
367 | tf->lbal = readb((void __iomem *)ioaddr->lbal_addr); | ||
368 | tf->lbam = readb((void __iomem *)ioaddr->lbam_addr); | ||
369 | tf->lbah = readb((void __iomem *)ioaddr->lbah_addr); | ||
370 | tf->device = readb((void __iomem *)ioaddr->device_addr); | ||
371 | |||
372 | if (tf->flags & ATA_TFLAG_LBA48) { | ||
373 | writeb(tf->ctl | ATA_HOB, (void __iomem *) ap->ioaddr.ctl_addr); | ||
374 | tf->hob_feature = readb((void __iomem *)ioaddr->error_addr); | ||
375 | tf->hob_nsect = readb((void __iomem *)ioaddr->nsect_addr); | ||
376 | tf->hob_lbal = readb((void __iomem *)ioaddr->lbal_addr); | ||
377 | tf->hob_lbam = readb((void __iomem *)ioaddr->lbam_addr); | ||
378 | tf->hob_lbah = readb((void __iomem *)ioaddr->lbah_addr); | ||
379 | } | ||
380 | } | ||
381 | |||
382 | |||
383 | /** | ||
384 | * ata_tf_read - input device's ATA taskfile shadow registers | ||
385 | * @ap: Port from which input is read | ||
386 | * @tf: ATA taskfile register set for storing input | ||
387 | * | ||
388 | * Reads ATA taskfile registers for currently-selected device | ||
389 | * into @tf. | ||
390 | * | ||
391 | * Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48 | ||
392 | * is set, also reads the hob registers. | ||
393 | * | ||
394 | * May be used as the tf_read() entry in ata_port_operations. | ||
395 | * | ||
396 | * LOCKING: | ||
397 | * Inherited from caller. | ||
398 | */ | ||
399 | void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | ||
400 | { | ||
401 | if (ap->flags & ATA_FLAG_MMIO) | ||
402 | ata_tf_read_mmio(ap, tf); | ||
403 | else | ||
404 | ata_tf_read_pio(ap, tf); | ||
405 | } | ||
406 | |||
407 | /** | ||
408 | * ata_check_status_pio - Read device status reg & clear interrupt | ||
409 | * @ap: port where the device is | ||
410 | * | ||
411 | * Reads ATA taskfile status register for currently-selected device | ||
412 | * and return its value. This also clears pending interrupts | ||
413 | * from this device | ||
414 | * | ||
415 | * LOCKING: | ||
416 | * Inherited from caller. | ||
417 | */ | ||
418 | static u8 ata_check_status_pio(struct ata_port *ap) | ||
419 | { | ||
420 | return inb(ap->ioaddr.status_addr); | ||
421 | } | ||
422 | |||
423 | /** | ||
424 | * ata_check_status_mmio - Read device status reg & clear interrupt | ||
425 | * @ap: port where the device is | ||
426 | * | ||
427 | * Reads ATA taskfile status register for currently-selected device | ||
428 | * via MMIO and return its value. This also clears pending interrupts | ||
429 | * from this device | ||
430 | * | ||
431 | * LOCKING: | ||
432 | * Inherited from caller. | ||
433 | */ | ||
434 | static u8 ata_check_status_mmio(struct ata_port *ap) | ||
435 | { | ||
436 | return readb((void __iomem *) ap->ioaddr.status_addr); | ||
437 | } | ||
438 | |||
439 | |||
440 | /** | ||
441 | * ata_check_status - Read device status reg & clear interrupt | ||
442 | * @ap: port where the device is | ||
443 | * | ||
444 | * Reads ATA taskfile status register for currently-selected device | ||
445 | * and return its value. This also clears pending interrupts | ||
446 | * from this device | ||
447 | * | ||
448 | * May be used as the check_status() entry in ata_port_operations. | ||
449 | * | ||
450 | * LOCKING: | ||
451 | * Inherited from caller. | ||
452 | */ | ||
453 | u8 ata_check_status(struct ata_port *ap) | ||
454 | { | ||
455 | if (ap->flags & ATA_FLAG_MMIO) | ||
456 | return ata_check_status_mmio(ap); | ||
457 | return ata_check_status_pio(ap); | ||
458 | } | ||
459 | |||
460 | |||
461 | /** | ||
462 | * ata_altstatus - Read device alternate status reg | ||
463 | * @ap: port where the device is | ||
464 | * | ||
465 | * Reads ATA taskfile alternate status register for | ||
466 | * currently-selected device and return its value. | ||
467 | * | ||
468 | * Note: may NOT be used as the check_altstatus() entry in | ||
469 | * ata_port_operations. | ||
470 | * | ||
471 | * LOCKING: | ||
472 | * Inherited from caller. | ||
473 | */ | ||
474 | u8 ata_altstatus(struct ata_port *ap) | ||
475 | { | ||
476 | if (ap->ops->check_altstatus) | ||
477 | return ap->ops->check_altstatus(ap); | ||
478 | |||
479 | if (ap->flags & ATA_FLAG_MMIO) | ||
480 | return readb((void __iomem *)ap->ioaddr.altstatus_addr); | ||
481 | return inb(ap->ioaddr.altstatus_addr); | ||
482 | } | ||
483 | |||
484 | 87 | ||
485 | /** | 88 | /** |
486 | * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure | 89 | * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure |
@@ -2011,6 +1614,26 @@ err_out: | |||
2011 | } | 1614 | } |
2012 | 1615 | ||
2013 | /** | 1616 | /** |
1617 | * ata_tf_to_host - issue ATA taskfile to host controller | ||
1618 | * @ap: port to which command is being issued | ||
1619 | * @tf: ATA taskfile register set | ||
1620 | * | ||
1621 | * Issues ATA taskfile register set to ATA host controller, | ||
1622 | * with proper synchronization with interrupt handler and | ||
1623 | * other threads. | ||
1624 | * | ||
1625 | * LOCKING: | ||
1626 | * spin_lock_irqsave(host_set lock) | ||
1627 | */ | ||
1628 | |||
1629 | static inline void ata_tf_to_host(struct ata_port *ap, | ||
1630 | const struct ata_taskfile *tf) | ||
1631 | { | ||
1632 | ap->ops->tf_load(ap, tf); | ||
1633 | ap->ops->exec_command(ap, tf); | ||
1634 | } | ||
1635 | |||
1636 | /** | ||
2014 | * ata_busy_sleep - sleep until BSY clears, or timeout | 1637 | * ata_busy_sleep - sleep until BSY clears, or timeout |
2015 | * @ap: port containing status register to be polled | 1638 | * @ap: port containing status register to be polled |
2016 | * @tmout_pat: impatience timeout | 1639 | * @tmout_pat: impatience timeout |
@@ -5383,32 +5006,6 @@ void ata_std_ports(struct ata_ioports *ioaddr) | |||
5383 | ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD; | 5006 | ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD; |
5384 | } | 5007 | } |
5385 | 5008 | ||
5386 | static struct ata_probe_ent * | ||
5387 | ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) | ||
5388 | { | ||
5389 | struct ata_probe_ent *probe_ent; | ||
5390 | |||
5391 | probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); | ||
5392 | if (!probe_ent) { | ||
5393 | printk(KERN_ERR DRV_NAME "(%s): out of memory\n", | ||
5394 | kobject_name(&(dev->kobj))); | ||
5395 | return NULL; | ||
5396 | } | ||
5397 | |||
5398 | INIT_LIST_HEAD(&probe_ent->node); | ||
5399 | probe_ent->dev = dev; | ||
5400 | |||
5401 | probe_ent->sht = port->sht; | ||
5402 | probe_ent->host_flags = port->host_flags; | ||
5403 | probe_ent->pio_mask = port->pio_mask; | ||
5404 | probe_ent->mwdma_mask = port->mwdma_mask; | ||
5405 | probe_ent->udma_mask = port->udma_mask; | ||
5406 | probe_ent->port_ops = port->port_ops; | ||
5407 | |||
5408 | return probe_ent; | ||
5409 | } | ||
5410 | |||
5411 | |||
5412 | 5009 | ||
5413 | #ifdef CONFIG_PCI | 5010 | #ifdef CONFIG_PCI |
5414 | 5011 | ||
@@ -5420,256 +5017,6 @@ void ata_pci_host_stop (struct ata_host_set *host_set) | |||
5420 | } | 5017 | } |
5421 | 5018 | ||
5422 | /** | 5019 | /** |
5423 | * ata_pci_init_native_mode - Initialize native-mode driver | ||
5424 | * @pdev: pci device to be initialized | ||
5425 | * @port: array[2] of pointers to port info structures. | ||
5426 | * @ports: bitmap of ports present | ||
5427 | * | ||
5428 | * Utility function which allocates and initializes an | ||
5429 | * ata_probe_ent structure for a standard dual-port | ||
5430 | * PIO-based IDE controller. The returned ata_probe_ent | ||
5431 | * structure can be passed to ata_device_add(). The returned | ||
5432 | * ata_probe_ent structure should then be freed with kfree(). | ||
5433 | * | ||
5434 | * The caller need only pass the address of the primary port, the | ||
5435 | * secondary will be deduced automatically. If the device has non | ||
5436 | * standard secondary port mappings this function can be called twice, | ||
5437 | * once for each interface. | ||
5438 | */ | ||
5439 | |||
5440 | struct ata_probe_ent * | ||
5441 | ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports) | ||
5442 | { | ||
5443 | struct ata_probe_ent *probe_ent = | ||
5444 | ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); | ||
5445 | int p = 0; | ||
5446 | |||
5447 | if (!probe_ent) | ||
5448 | return NULL; | ||
5449 | |||
5450 | probe_ent->irq = pdev->irq; | ||
5451 | probe_ent->irq_flags = SA_SHIRQ; | ||
5452 | probe_ent->private_data = port[0]->private_data; | ||
5453 | |||
5454 | if (ports & ATA_PORT_PRIMARY) { | ||
5455 | probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0); | ||
5456 | probe_ent->port[p].altstatus_addr = | ||
5457 | probe_ent->port[p].ctl_addr = | ||
5458 | pci_resource_start(pdev, 1) | ATA_PCI_CTL_OFS; | ||
5459 | probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4); | ||
5460 | ata_std_ports(&probe_ent->port[p]); | ||
5461 | p++; | ||
5462 | } | ||
5463 | |||
5464 | if (ports & ATA_PORT_SECONDARY) { | ||
5465 | probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 2); | ||
5466 | probe_ent->port[p].altstatus_addr = | ||
5467 | probe_ent->port[p].ctl_addr = | ||
5468 | pci_resource_start(pdev, 3) | ATA_PCI_CTL_OFS; | ||
5469 | probe_ent->port[p].bmdma_addr = pci_resource_start(pdev, 4) + 8; | ||
5470 | ata_std_ports(&probe_ent->port[p]); | ||
5471 | p++; | ||
5472 | } | ||
5473 | |||
5474 | probe_ent->n_ports = p; | ||
5475 | return probe_ent; | ||
5476 | } | ||
5477 | |||
5478 | static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, struct ata_port_info *port, int port_num) | ||
5479 | { | ||
5480 | struct ata_probe_ent *probe_ent; | ||
5481 | |||
5482 | probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); | ||
5483 | if (!probe_ent) | ||
5484 | return NULL; | ||
5485 | |||
5486 | probe_ent->legacy_mode = 1; | ||
5487 | probe_ent->n_ports = 1; | ||
5488 | probe_ent->hard_port_no = port_num; | ||
5489 | probe_ent->private_data = port->private_data; | ||
5490 | |||
5491 | switch(port_num) | ||
5492 | { | ||
5493 | case 0: | ||
5494 | probe_ent->irq = 14; | ||
5495 | probe_ent->port[0].cmd_addr = 0x1f0; | ||
5496 | probe_ent->port[0].altstatus_addr = | ||
5497 | probe_ent->port[0].ctl_addr = 0x3f6; | ||
5498 | break; | ||
5499 | case 1: | ||
5500 | probe_ent->irq = 15; | ||
5501 | probe_ent->port[0].cmd_addr = 0x170; | ||
5502 | probe_ent->port[0].altstatus_addr = | ||
5503 | probe_ent->port[0].ctl_addr = 0x376; | ||
5504 | break; | ||
5505 | } | ||
5506 | probe_ent->port[0].bmdma_addr = pci_resource_start(pdev, 4) + 8 * port_num; | ||
5507 | ata_std_ports(&probe_ent->port[0]); | ||
5508 | return probe_ent; | ||
5509 | } | ||
5510 | |||
5511 | /** | ||
5512 | * ata_pci_init_one - Initialize/register PCI IDE host controller | ||
5513 | * @pdev: Controller to be initialized | ||
5514 | * @port_info: Information from low-level host driver | ||
5515 | * @n_ports: Number of ports attached to host controller | ||
5516 | * | ||
5517 | * This is a helper function which can be called from a driver's | ||
5518 | * xxx_init_one() probe function if the hardware uses traditional | ||
5519 | * IDE taskfile registers. | ||
5520 | * | ||
5521 | * This function calls pci_enable_device(), reserves its register | ||
5522 | * regions, sets the dma mask, enables bus master mode, and calls | ||
5523 | * ata_device_add() | ||
5524 | * | ||
5525 | * LOCKING: | ||
5526 | * Inherited from PCI layer (may sleep). | ||
5527 | * | ||
5528 | * RETURNS: | ||
5529 | * Zero on success, negative on errno-based value on error. | ||
5530 | */ | ||
5531 | |||
5532 | int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, | ||
5533 | unsigned int n_ports) | ||
5534 | { | ||
5535 | struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL; | ||
5536 | struct ata_port_info *port[2]; | ||
5537 | u8 tmp8, mask; | ||
5538 | unsigned int legacy_mode = 0; | ||
5539 | int disable_dev_on_err = 1; | ||
5540 | int rc; | ||
5541 | |||
5542 | DPRINTK("ENTER\n"); | ||
5543 | |||
5544 | port[0] = port_info[0]; | ||
5545 | if (n_ports > 1) | ||
5546 | port[1] = port_info[1]; | ||
5547 | else | ||
5548 | port[1] = port[0]; | ||
5549 | |||
5550 | if ((port[0]->host_flags & ATA_FLAG_NO_LEGACY) == 0 | ||
5551 | && (pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) { | ||
5552 | /* TODO: What if one channel is in native mode ... */ | ||
5553 | pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8); | ||
5554 | mask = (1 << 2) | (1 << 0); | ||
5555 | if ((tmp8 & mask) != mask) | ||
5556 | legacy_mode = (1 << 3); | ||
5557 | } | ||
5558 | |||
5559 | /* FIXME... */ | ||
5560 | if ((!legacy_mode) && (n_ports > 2)) { | ||
5561 | printk(KERN_ERR "ata: BUG: native mode, n_ports > 2\n"); | ||
5562 | n_ports = 2; | ||
5563 | /* For now */ | ||
5564 | } | ||
5565 | |||
5566 | /* FIXME: Really for ATA it isn't safe because the device may be | ||
5567 | multi-purpose and we want to leave it alone if it was already | ||
5568 | enabled. Secondly for shared use as Arjan says we want refcounting | ||
5569 | |||
5570 | Checking dev->is_enabled is insufficient as this is not set at | ||
5571 | boot for the primary video which is BIOS enabled | ||
5572 | */ | ||
5573 | |||
5574 | rc = pci_enable_device(pdev); | ||
5575 | if (rc) | ||
5576 | return rc; | ||
5577 | |||
5578 | rc = pci_request_regions(pdev, DRV_NAME); | ||
5579 | if (rc) { | ||
5580 | disable_dev_on_err = 0; | ||
5581 | goto err_out; | ||
5582 | } | ||
5583 | |||
5584 | /* FIXME: Should use platform specific mappers for legacy port ranges */ | ||
5585 | if (legacy_mode) { | ||
5586 | if (!request_region(0x1f0, 8, "libata")) { | ||
5587 | struct resource *conflict, res; | ||
5588 | res.start = 0x1f0; | ||
5589 | res.end = 0x1f0 + 8 - 1; | ||
5590 | conflict = ____request_resource(&ioport_resource, &res); | ||
5591 | if (!strcmp(conflict->name, "libata")) | ||
5592 | legacy_mode |= (1 << 0); | ||
5593 | else { | ||
5594 | disable_dev_on_err = 0; | ||
5595 | printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n"); | ||
5596 | } | ||
5597 | } else | ||
5598 | legacy_mode |= (1 << 0); | ||
5599 | |||
5600 | if (!request_region(0x170, 8, "libata")) { | ||
5601 | struct resource *conflict, res; | ||
5602 | res.start = 0x170; | ||
5603 | res.end = 0x170 + 8 - 1; | ||
5604 | conflict = ____request_resource(&ioport_resource, &res); | ||
5605 | if (!strcmp(conflict->name, "libata")) | ||
5606 | legacy_mode |= (1 << 1); | ||
5607 | else { | ||
5608 | disable_dev_on_err = 0; | ||
5609 | printk(KERN_WARNING "ata: 0x170 IDE port busy\n"); | ||
5610 | } | ||
5611 | } else | ||
5612 | legacy_mode |= (1 << 1); | ||
5613 | } | ||
5614 | |||
5615 | /* we have legacy mode, but all ports are unavailable */ | ||
5616 | if (legacy_mode == (1 << 3)) { | ||
5617 | rc = -EBUSY; | ||
5618 | goto err_out_regions; | ||
5619 | } | ||
5620 | |||
5621 | rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); | ||
5622 | if (rc) | ||
5623 | goto err_out_regions; | ||
5624 | rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); | ||
5625 | if (rc) | ||
5626 | goto err_out_regions; | ||
5627 | |||
5628 | if (legacy_mode) { | ||
5629 | if (legacy_mode & (1 << 0)) | ||
5630 | probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0); | ||
5631 | if (legacy_mode & (1 << 1)) | ||
5632 | probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1); | ||
5633 | } else { | ||
5634 | if (n_ports == 2) | ||
5635 | probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); | ||
5636 | else | ||
5637 | probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY); | ||
5638 | } | ||
5639 | if (!probe_ent && !probe_ent2) { | ||
5640 | rc = -ENOMEM; | ||
5641 | goto err_out_regions; | ||
5642 | } | ||
5643 | |||
5644 | pci_set_master(pdev); | ||
5645 | |||
5646 | /* FIXME: check ata_device_add return */ | ||
5647 | if (legacy_mode) { | ||
5648 | if (legacy_mode & (1 << 0)) | ||
5649 | ata_device_add(probe_ent); | ||
5650 | if (legacy_mode & (1 << 1)) | ||
5651 | ata_device_add(probe_ent2); | ||
5652 | } else | ||
5653 | ata_device_add(probe_ent); | ||
5654 | |||
5655 | kfree(probe_ent); | ||
5656 | kfree(probe_ent2); | ||
5657 | |||
5658 | return 0; | ||
5659 | |||
5660 | err_out_regions: | ||
5661 | if (legacy_mode & (1 << 0)) | ||
5662 | release_region(0x1f0, 8); | ||
5663 | if (legacy_mode & (1 << 1)) | ||
5664 | release_region(0x170, 8); | ||
5665 | pci_release_regions(pdev); | ||
5666 | err_out: | ||
5667 | if (disable_dev_on_err) | ||
5668 | pci_disable_device(pdev); | ||
5669 | return rc; | ||
5670 | } | ||
5671 | |||
5672 | /** | ||
5673 | * ata_pci_remove_one - PCI layer callback for device removal | 5020 | * ata_pci_remove_one - PCI layer callback for device removal |
5674 | * @pdev: PCI device that was removed | 5021 | * @pdev: PCI device that was removed |
5675 | * | 5022 | * |