Blame view
drivers/ide/setup-pci.c
17 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
59bca8cc9 ide: update/add m... |
2 3 |
* Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 1995-1998 Mark Lord |
ad7c52d09 ide: re-implement... |
4 |
* Copyright (C) 2007-2009 Bartlomiej Zolnierkiewicz |
58f189fcc ide: delete filen... |
5 |
* |
1da177e4c Linux-2.6.12-rc2 |
6 |
* May be copied or modified under the terms of the GNU General Public License |
1da177e4c Linux-2.6.12-rc2 |
7 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
8 9 |
#include <linux/types.h> #include <linux/kernel.h> |
38789fda2 ide/ata: Add expo... |
10 |
#include <linux/export.h> |
1da177e4c Linux-2.6.12-rc2 |
11 12 |
#include <linux/pci.h> #include <linux/init.h> |
1da177e4c Linux-2.6.12-rc2 |
13 14 15 16 17 |
#include <linux/interrupt.h> #include <linux/ide.h> #include <linux/dma-mapping.h> #include <asm/io.h> |
1da177e4c Linux-2.6.12-rc2 |
18 |
|
1da177e4c Linux-2.6.12-rc2 |
19 20 21 22 23 24 25 |
/** * ide_setup_pci_baseregs - place a PCI IDE controller native * @dev: PCI device of interface to switch native * @name: Name of interface * * We attempt to place the PCI interface into PCI native mode. If * we succeed the BARs are ok and the controller is in PCI mode. |
846bb88ae IDE: Coding Style... |
26 |
* Returns 0 on success or an errno code. |
1da177e4c Linux-2.6.12-rc2 |
27 28 29 30 |
* * FIXME: if we program the interface and then fail to set the BARS * we don't switch it back to legacy mode. Do we actually care ?? */ |
846bb88ae IDE: Coding Style... |
31 32 |
static int ide_setup_pci_baseregs(struct pci_dev *dev, const char *name) |
1da177e4c Linux-2.6.12-rc2 |
33 34 35 36 37 38 39 40 41 |
{ u8 progif = 0; /* * Place both IDE interfaces into PCI "native" mode: */ if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) || (progif & 5) != 5) { if ((progif & 0xa) != 0xa) { |
28cfd8af5 ide: include PCI ... |
42 43 44 |
printk(KERN_INFO "%s %s: device not capable of full " "native PCI mode ", name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
45 46 |
return -EOPNOTSUPP; } |
28cfd8af5 ide: include PCI ... |
47 48 49 |
printk(KERN_INFO "%s %s: placing both ports into native PCI " "mode ", name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
50 51 52 |
(void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5); if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) || (progif & 5) != 5) { |
28cfd8af5 ide: include PCI ... |
53 54 55 56 |
printk(KERN_ERR "%s %s: rewrite of PROGIF failed, " "wanted 0x%04x, got 0x%04x ", name, pci_name(dev), progif | 5, progif); |
1da177e4c Linux-2.6.12-rc2 |
57 58 59 60 61 62 63 |
return -EOPNOTSUPP; } } return 0; } #ifdef CONFIG_BLK_DEV_IDEDMA_PCI |
28cfd8af5 ide: include PCI ... |
64 |
static int ide_pci_clear_simplex(unsigned long dma_base, const char *name) |
8ac2b42a4 ide: add IDE_HFLA... |
65 66 67 68 69 |
{ u8 dma_stat = inb(dma_base + 2); outb(dma_stat & 0x60, dma_base + 2); dma_stat = inb(dma_base + 2); |
28cfd8af5 ide: include PCI ... |
70 71 |
return (dma_stat & 0x80) ? 1 : 0; |
8ac2b42a4 ide: add IDE_HFLA... |
72 |
} |
1da177e4c Linux-2.6.12-rc2 |
73 |
/** |
b123f56e0 ide: do complete ... |
74 |
* ide_pci_dma_base - setup BMIBA |
039788e15 ide: replace ide_... |
75 |
* @hwif: IDE interface |
b123f56e0 ide: do complete ... |
76 |
* @d: IDE port info |
1da177e4c Linux-2.6.12-rc2 |
77 |
* |
c58e79dd4 ide: remove CONFI... |
78 |
* Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space. |
1da177e4c Linux-2.6.12-rc2 |
79 |
*/ |
b123f56e0 ide: do complete ... |
80 |
unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d) |
1da177e4c Linux-2.6.12-rc2 |
81 |
{ |
36501650e ide: keep pointer... |
82 83 |
struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long dma_base = 0; |
1da177e4c Linux-2.6.12-rc2 |
84 |
|
135721446 ide: remove ->mmi... |
85 |
if (hwif->host_flags & IDE_HFLAG_MMIO) |
1da177e4c Linux-2.6.12-rc2 |
86 87 88 89 90 |
return hwif->dma_base; if (hwif->mate && hwif->mate->dma_base) { dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8); } else { |
9ffcf364f ide: remove ->ini... |
91 92 93 |
u8 baridx = (d->host_flags & IDE_HFLAG_CS5520) ? 2 : 4; dma_base = pci_resource_start(dev, baridx); |
aea5d3756 ide: (hopefully) ... |
94 |
if (dma_base == 0) { |
28cfd8af5 ide: include PCI ... |
95 96 97 |
printk(KERN_ERR "%s %s: DMA base is invalid ", d->name, pci_name(dev)); |
aea5d3756 ide: (hopefully) ... |
98 99 |
return 0; } |
1da177e4c Linux-2.6.12-rc2 |
100 |
} |
aea5d3756 ide: (hopefully) ... |
101 102 |
if (hwif->channel) dma_base += 8; |
ebb00fb55 ide: factor out s... |
103 104 105 106 107 108 |
return dma_base; } EXPORT_SYMBOL_GPL(ide_pci_dma_base); int ide_pci_check_simplex(ide_hwif_t *hwif, const struct ide_port_info *d) { |
28cfd8af5 ide: include PCI ... |
109 |
struct pci_dev *dev = to_pci_dev(hwif->dev); |
ebb00fb55 ide: factor out s... |
110 111 112 |
u8 dma_stat; if (d->host_flags & (IDE_HFLAG_MMIO | IDE_HFLAG_CS5520)) |
8ac2b42a4 ide: add IDE_HFLA... |
113 114 115 |
goto out; if (d->host_flags & IDE_HFLAG_CLEAR_SIMPLEX) { |
28cfd8af5 ide: include PCI ... |
116 117 118 119 |
if (ide_pci_clear_simplex(hwif->dma_base, d->name)) printk(KERN_INFO "%s %s: simplex device: DMA forced ", d->name, pci_name(dev)); |
8ac2b42a4 ide: add IDE_HFLA... |
120 121 122 123 124 125 126 127 128 129 130 131 132 |
goto out; } /* * If the device claims "simplex" DMA, this means that only one of * the two interfaces can be trusted with DMA at any point in time * (so we should enable DMA only on one of the two interfaces). * * FIXME: At this point we haven't probed the drives so we can't make * the appropriate decision. Really we should defer this problem until * we tune the drive then try to grab DMA ownership if we want to be * the DMA end. This has to be become dynamic to handle hot-plug. */ |
592b53152 ide: move read_sf... |
133 |
dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); |
8ac2b42a4 ide: add IDE_HFLA... |
134 |
if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) { |
28cfd8af5 ide: include PCI ... |
135 136 137 |
printk(KERN_INFO "%s %s: simplex device: DMA disabled ", d->name, pci_name(dev)); |
ebb00fb55 ide: factor out s... |
138 |
return -1; |
1da177e4c Linux-2.6.12-rc2 |
139 |
} |
8ac2b42a4 ide: add IDE_HFLA... |
140 |
out: |
ebb00fb55 ide: factor out s... |
141 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
142 |
} |
ebb00fb55 ide: factor out s... |
143 |
EXPORT_SYMBOL_GPL(ide_pci_check_simplex); |
d54452fbf ide: factor out s... |
144 145 146 147 |
/* * Set up BM-DMA capability (PnP BIOS should have done this) */ |
b123f56e0 ide: do complete ... |
148 |
int ide_pci_set_master(struct pci_dev *dev, const char *name) |
d54452fbf ide: factor out s... |
149 150 151 152 153 154 155 156 157 158 |
{ u16 pcicmd; pci_read_config_word(dev, PCI_COMMAND, &pcicmd); if ((pcicmd & PCI_COMMAND_MASTER) == 0) { pci_set_master(dev); if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd) || (pcicmd & PCI_COMMAND_MASTER) == 0) { |
28cfd8af5 ide: include PCI ... |
159 160 161 |
printk(KERN_ERR "%s %s: error updating PCICMD ", name, pci_name(dev)); |
d54452fbf ide: factor out s... |
162 163 164 165 166 167 |
return -EIO; } } return 0; } |
b123f56e0 ide: do complete ... |
168 |
EXPORT_SYMBOL_GPL(ide_pci_set_master); |
1da177e4c Linux-2.6.12-rc2 |
169 |
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ |
856204360 ide: constify str... |
170 |
void ide_setup_pci_noise(struct pci_dev *dev, const struct ide_port_info *d) |
1da177e4c Linux-2.6.12-rc2 |
171 |
{ |
28cfd8af5 ide: include PCI ... |
172 173 174 175 |
printk(KERN_INFO "%s %s: IDE controller (0x%04x:0x%04x rev 0x%02x) ", d->name, pci_name(dev), dev->vendor, dev->device, dev->revision); |
1da177e4c Linux-2.6.12-rc2 |
176 |
} |
1da177e4c Linux-2.6.12-rc2 |
177 178 179 180 181 182 |
EXPORT_SYMBOL_GPL(ide_setup_pci_noise); /** * ide_pci_enable - do PCI enables * @dev: PCI device |
a06876a76 ide: pci: free PC... |
183 |
* @bars: PCI BARs mask |
039788e15 ide: replace ide_... |
184 |
* @d: IDE port info |
1da177e4c Linux-2.6.12-rc2 |
185 186 |
* * Enable the IDE PCI device. We attempt to enable the device in full |
094839164 PCI: Remove users... |
187 188 189 |
* but if that fails then we only need IO space. The PCI code should * have setup the proper resources for us already for controllers in * legacy mode. |
846bb88ae IDE: Coding Style... |
190 |
* |
1da177e4c Linux-2.6.12-rc2 |
191 192 |
* Returns zero on success or an error code */ |
039788e15 ide: replace ide_... |
193 |
|
a06876a76 ide: pci: free PC... |
194 195 |
static int ide_pci_enable(struct pci_dev *dev, int bars, const struct ide_port_info *d) |
1da177e4c Linux-2.6.12-rc2 |
196 |
{ |
a06876a76 ide: pci: free PC... |
197 |
int ret; |
1da177e4c Linux-2.6.12-rc2 |
198 199 |
if (pci_enable_device(dev)) { |
094839164 PCI: Remove users... |
200 |
ret = pci_enable_device_io(dev); |
1da177e4c Linux-2.6.12-rc2 |
201 |
if (ret < 0) { |
28cfd8af5 ide: include PCI ... |
202 203 204 |
printk(KERN_WARNING "%s %s: couldn't enable device ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
205 206 |
goto out; } |
28cfd8af5 ide: include PCI ... |
207 208 209 |
printk(KERN_WARNING "%s %s: BIOS configuration fixed ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
210 211 212 |
} /* |
039788e15 ide: replace ide_... |
213 214 215 |
* assume all devices can do 32-bit DMA for now, we can add * a DMA mask field to the struct ide_port_info if we need it * (or let lower level driver set the DMA mask) |
1da177e4c Linux-2.6.12-rc2 |
216 |
*/ |
d681f1166 ide: remove depre... |
217 |
ret = dma_set_mask(&dev->dev, DMA_BIT_MASK(32)); |
1da177e4c Linux-2.6.12-rc2 |
218 |
if (ret < 0) { |
28cfd8af5 ide: include PCI ... |
219 220 221 |
printk(KERN_ERR "%s %s: can't set DMA mask ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
222 223 |
goto out; } |
0d1bad216 ide: manage resou... |
224 225 |
ret = pci_request_selected_regions(dev, bars, d->name); if (ret < 0) |
28cfd8af5 ide: include PCI ... |
226 227 228 |
printk(KERN_ERR "%s %s: can't reserve resources ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
229 230 231 232 233 234 235 |
out: return ret; } /** * ide_pci_configure - configure an unconfigured device * @dev: PCI device |
039788e15 ide: replace ide_... |
236 |
* @d: IDE port info |
1da177e4c Linux-2.6.12-rc2 |
237 238 239 240 |
* * Enable and configure the PCI device we have been passed. * Returns zero on success or an error code. */ |
039788e15 ide: replace ide_... |
241 |
|
856204360 ide: constify str... |
242 |
static int ide_pci_configure(struct pci_dev *dev, const struct ide_port_info *d) |
1da177e4c Linux-2.6.12-rc2 |
243 244 245 246 247 248 249 250 251 |
{ u16 pcicmd = 0; /* * PnP BIOS was *supposed* to have setup this device, but we * can do it ourselves, so long as the BIOS has assigned an IRQ * (or possibly the device is using a "legacy header" for IRQs). * Maybe the user deliberately *disabled* the device, * but we'll eventually ignore it again if no drives respond. */ |
846bb88ae IDE: Coding Style... |
252 253 |
if (ide_setup_pci_baseregs(dev, d->name) || pci_write_config_word(dev, PCI_COMMAND, pcicmd | PCI_COMMAND_IO)) { |
28cfd8af5 ide: include PCI ... |
254 255 256 |
printk(KERN_INFO "%s %s: device disabled (BIOS) ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
257 258 259 |
return -ENODEV; } if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd)) { |
28cfd8af5 ide: include PCI ... |
260 261 262 |
printk(KERN_ERR "%s %s: error accessing PCI regs ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
263 264 265 |
return -EIO; } if (!(pcicmd & PCI_COMMAND_IO)) { |
28cfd8af5 ide: include PCI ... |
266 267 268 |
printk(KERN_ERR "%s %s: unable to enable IDE controller ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
269 270 271 272 273 274 275 |
return -ENXIO; } return 0; } /** * ide_pci_check_iomem - check a register is I/O |
039788e15 ide: replace ide_... |
276 277 278 |
* @dev: PCI device * @d: IDE port info * @bar: BAR number |
1da177e4c Linux-2.6.12-rc2 |
279 |
* |
1baccff8a ide: make ide_pci... |
280 281 |
* Checks if a BAR is configured and points to MMIO space. If so, * return an error code. Otherwise return 0 |
1da177e4c Linux-2.6.12-rc2 |
282 |
*/ |
039788e15 ide: replace ide_... |
283 |
|
1baccff8a ide: make ide_pci... |
284 285 |
static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *d, int bar) |
1da177e4c Linux-2.6.12-rc2 |
286 287 |
{ ulong flags = pci_resource_flags(dev, bar); |
846bb88ae IDE: Coding Style... |
288 |
|
1da177e4c Linux-2.6.12-rc2 |
289 290 291 |
/* Unconfigured ? */ if (!flags || pci_resource_len(dev, bar) == 0) return 0; |
1baccff8a ide: make ide_pci... |
292 293 |
/* I/O space */ if (flags & IORESOURCE_IO) |
1da177e4c Linux-2.6.12-rc2 |
294 |
return 0; |
846bb88ae IDE: Coding Style... |
295 |
|
1da177e4c Linux-2.6.12-rc2 |
296 |
/* Bad */ |
1da177e4c Linux-2.6.12-rc2 |
297 298 299 300 |
return -EINVAL; } /** |
9f36d3143 ide: remove hw_re... |
301 |
* ide_hw_configure - configure a struct ide_hw instance |
1da177e4c Linux-2.6.12-rc2 |
302 |
* @dev: PCI device holding interface |
039788e15 ide: replace ide_... |
303 |
* @d: IDE port info |
1ebf74936 ide: separate PCI... |
304 |
* @port: port number |
9f36d3143 ide: remove hw_re... |
305 |
* @hw: struct ide_hw instance corresponding to this port |
1da177e4c Linux-2.6.12-rc2 |
306 307 308 309 310 |
* * Perform the initial set up for the hardware interface structure. This * is done per interface port rather than per PCI device. There may be * more than one port per device. * |
48c3c1072 ide: add struct i... |
311 |
* Returns zero on success or an error code. |
1da177e4c Linux-2.6.12-rc2 |
312 |
*/ |
039788e15 ide: replace ide_... |
313 |
|
48c3c1072 ide: add struct i... |
314 |
static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d, |
9f36d3143 ide: remove hw_re... |
315 |
unsigned int port, struct ide_hw *hw) |
1da177e4c Linux-2.6.12-rc2 |
316 317 |
{ unsigned long ctl = 0, base = 0; |
1da177e4c Linux-2.6.12-rc2 |
318 |
|
a5d8c5c83 ide: add ide_pci_... |
319 |
if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) { |
1baccff8a ide: make ide_pci... |
320 321 |
if (ide_pci_check_iomem(dev, d, 2 * port) || ide_pci_check_iomem(dev, d, 2 * port + 1)) { |
28cfd8af5 ide: include PCI ... |
322 323 324 325 |
printk(KERN_ERR "%s %s: I/O baseregs (BIOS) are " "reported as MEM for port %d! ", d->name, pci_name(dev), port); |
48c3c1072 ide: add struct i... |
326 |
return -EINVAL; |
1baccff8a ide: make ide_pci... |
327 |
} |
846bb88ae IDE: Coding Style... |
328 |
|
1da177e4c Linux-2.6.12-rc2 |
329 330 |
ctl = pci_resource_start(dev, 2*port+1); base = pci_resource_start(dev, 2*port); |
c1da678b5 ide: tighten chec... |
331 |
} else { |
1da177e4c Linux-2.6.12-rc2 |
332 333 334 335 |
/* Use default values */ ctl = port ? 0x374 : 0x3f4; base = port ? 0x170 : 0x1f0; } |
bad7c825c ide: cleanup ide_... |
336 |
|
c1da678b5 ide: tighten chec... |
337 |
if (!base || !ctl) { |
28cfd8af5 ide: include PCI ... |
338 339 340 |
printk(KERN_ERR "%s %s: bad PCI BARs for port %d, skipping ", d->name, pci_name(dev), port); |
48c3c1072 ide: add struct i... |
341 |
return -EINVAL; |
c1da678b5 ide: tighten chec... |
342 |
} |
c97c6aca7 ide: pass hw_regs... |
343 |
memset(hw, 0, sizeof(*hw)); |
c97c6aca7 ide: pass hw_regs... |
344 |
hw->dev = &dev->dev; |
c97c6aca7 ide: pass hw_regs... |
345 |
ide_std_init_ports(hw, base, ctl | 2); |
48c3c1072 ide: add struct i... |
346 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
347 |
} |
c413b9b94 ide: add struct i... |
348 |
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI |
1da177e4c Linux-2.6.12-rc2 |
349 350 |
/** * ide_hwif_setup_dma - configure DMA interface |
039788e15 ide: replace ide_... |
351 |
* @hwif: IDE interface |
c413b9b94 ide: add struct i... |
352 |
* @d: IDE port info |
1da177e4c Linux-2.6.12-rc2 |
353 354 355 356 357 |
* * Set up the DMA base for the interface. Enable the master bits as * necessary and attempt to bring the device DMA into a ready to use * state */ |
039788e15 ide: replace ide_... |
358 |
|
b123f56e0 ide: do complete ... |
359 |
int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) |
1da177e4c Linux-2.6.12-rc2 |
360 |
{ |
c413b9b94 ide: add struct i... |
361 |
struct pci_dev *dev = to_pci_dev(hwif->dev); |
1da177e4c Linux-2.6.12-rc2 |
362 |
|
47b687882 ide: add IDE_HFLA... |
363 |
if ((d->host_flags & IDE_HFLAG_NO_AUTODMA) == 0 || |
1da177e4c Linux-2.6.12-rc2 |
364 365 |
((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) { |
b123f56e0 ide: do complete ... |
366 |
unsigned long base = ide_pci_dma_base(hwif, d); |
d54452fbf ide: factor out s... |
367 |
|
ebb00fb55 ide: factor out s... |
368 369 370 371 |
if (base == 0) return -1; hwif->dma_base = base; |
592b53152 ide: move read_sf... |
372 373 |
if (hwif->dma_ops == NULL) hwif->dma_ops = &sff_dma_ops; |
ebb00fb55 ide: factor out s... |
374 375 376 377 |
if (ide_pci_check_simplex(hwif, d) < 0) return -1; if (ide_pci_set_master(dev, d->name) < 0) |
b123f56e0 ide: do complete ... |
378 |
return -1; |
d54452fbf ide: factor out s... |
379 |
|
135721446 ide: remove ->mmi... |
380 |
if (hwif->host_flags & IDE_HFLAG_MMIO) |
63158d5c2 ide: cleanup ide_... |
381 382 383 384 385 386 387 388 |
printk(KERN_INFO " %s: MMIO-DMA ", hwif->name); else printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx ", hwif->name, base, base + 7); hwif->extra_base = base + (hwif->channel ? 8 : 16); |
b123f56e0 ide: do complete ... |
389 390 |
if (ide_allocate_dma_engine(hwif)) return -1; |
b123f56e0 ide: do complete ... |
391 |
} |
d54452fbf ide: factor out s... |
392 |
|
b123f56e0 ide: do complete ... |
393 |
return 0; |
039788e15 ide: replace ide_... |
394 |
} |
c413b9b94 ide: add struct i... |
395 |
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ |
1da177e4c Linux-2.6.12-rc2 |
396 397 398 399 |
/** * ide_setup_pci_controller - set up IDE PCI * @dev: PCI device |
a06876a76 ide: pci: free PC... |
400 |
* @bars: PCI BARs mask |
039788e15 ide: replace ide_... |
401 |
* @d: IDE port info |
1da177e4c Linux-2.6.12-rc2 |
402 |
* @noisy: verbose flag |
1da177e4c Linux-2.6.12-rc2 |
403 404 405 406 407 |
* * Set up the PCI and controller side of the IDE interface. This brings * up the PCI side of the device, checks that the device is enabled * and enables it if need be */ |
039788e15 ide: replace ide_... |
408 |
|
a06876a76 ide: pci: free PC... |
409 |
static int ide_setup_pci_controller(struct pci_dev *dev, int bars, |
a95925a30 ide: respect dev-... |
410 |
const struct ide_port_info *d, int noisy) |
1da177e4c Linux-2.6.12-rc2 |
411 412 |
{ int ret; |
1da177e4c Linux-2.6.12-rc2 |
413 414 415 416 |
u16 pcicmd; if (noisy) ide_setup_pci_noise(dev, d); |
a06876a76 ide: pci: free PC... |
417 |
ret = ide_pci_enable(dev, bars, d); |
1da177e4c Linux-2.6.12-rc2 |
418 419 420 421 422 |
if (ret < 0) goto out; ret = pci_read_config_word(dev, PCI_COMMAND, &pcicmd); if (ret < 0) { |
28cfd8af5 ide: include PCI ... |
423 424 425 |
printk(KERN_ERR "%s %s: error accessing PCI regs ", d->name, pci_name(dev)); |
a06876a76 ide: pci: free PC... |
426 |
goto out_free_bars; |
1da177e4c Linux-2.6.12-rc2 |
427 428 429 430 |
} if (!(pcicmd & PCI_COMMAND_IO)) { /* is device disabled? */ ret = ide_pci_configure(dev, d); if (ret < 0) |
a06876a76 ide: pci: free PC... |
431 |
goto out_free_bars; |
28cfd8af5 ide: include PCI ... |
432 433 434 |
printk(KERN_INFO "%s %s: device enabled (Linux) ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
435 |
} |
a06876a76 ide: pci: free PC... |
436 437 438 439 |
goto out; out_free_bars: pci_release_selected_regions(dev, bars); |
1da177e4c Linux-2.6.12-rc2 |
440 441 442 443 444 445 446 |
out: return ret; } /** * ide_pci_setup_ports - configure ports/devices on PCI IDE * @dev: PCI device |
039788e15 ide: replace ide_... |
447 |
* @d: IDE port info |
9f36d3143 ide: remove hw_re... |
448 449 |
* @hw: struct ide_hw instances corresponding to this PCI IDE device * @hws: struct ide_hw pointers table to update |
1da177e4c Linux-2.6.12-rc2 |
450 451 452 453 454 455 456 457 458 |
* * Scan the interfaces attached to this device and do any * necessary per port setup. Attach the devices and ask the * generic DMA layer to do its work for us. * * Normally called automaticall from do_ide_pci_setup_device, * but is also used directly as a helper function by some controllers * where the chipset setup is not the default PCI IDE one. */ |
8447d9d52 ide: add ide_devi... |
459 |
|
c97c6aca7 ide: pass hw_regs... |
460 |
void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, |
9f36d3143 ide: remove hw_re... |
461 |
struct ide_hw *hw, struct ide_hw **hws) |
1da177e4c Linux-2.6.12-rc2 |
462 |
{ |
a5d8c5c83 ide: add ide_pci_... |
463 |
int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port; |
1da177e4c Linux-2.6.12-rc2 |
464 |
u8 tmp; |
1da177e4c Linux-2.6.12-rc2 |
465 466 467 |
/* * Set up the IDE ports */ |
cf6e854ef ide: fix disabled... |
468 |
|
a5d8c5c83 ide: add ide_pci_... |
469 |
for (port = 0; port < channels; ++port) { |
c0ae50234 ide: remove ide_p... |
470 |
const struct ide_pci_enablebit *e = &d->enablebits[port]; |
856204360 ide: constify str... |
471 |
|
1da177e4c Linux-2.6.12-rc2 |
472 |
if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || |
cf6e854ef ide: fix disabled... |
473 |
(tmp & e->mask) != e->val)) { |
28cfd8af5 ide: include PCI ... |
474 475 476 |
printk(KERN_INFO "%s %s: IDE port disabled ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
477 |
continue; /* port not enabled */ |
cf6e854ef ide: fix disabled... |
478 |
} |
1da177e4c Linux-2.6.12-rc2 |
479 |
|
86ccf37c6 ide: remove pciir... |
480 |
if (ide_hw_configure(dev, d, port, hw + port)) |
1da177e4c Linux-2.6.12-rc2 |
481 |
continue; |
c97c6aca7 ide: pass hw_regs... |
482 |
*(hws + port) = hw + port; |
1ebf74936 ide: separate PCI... |
483 |
} |
1da177e4c Linux-2.6.12-rc2 |
484 |
} |
1da177e4c Linux-2.6.12-rc2 |
485 486 487 488 489 490 491 492 493 |
EXPORT_SYMBOL_GPL(ide_pci_setup_ports); /* * ide_setup_pci_device() looks at the primary/secondary interfaces * on a PCI IDE device and, if they are enabled, prepares the IDE driver * for use with them. This generic code works for most PCI chipsets. * * One thing that is not standardized is the location of the * primary/secondary interface "enable/disable" bits. For chipsets that |
039788e15 ide: replace ide_... |
494 |
* we "know" about, this information is in the struct ide_port_info; |
1da177e4c Linux-2.6.12-rc2 |
495 496 |
* for all other chipsets, we just assume both interfaces are enabled. */ |
039788e15 ide: replace ide_... |
497 |
static int do_ide_setup_pci_device(struct pci_dev *dev, |
856204360 ide: constify str... |
498 |
const struct ide_port_info *d, |
51d87ed0a ide: move ide_pci... |
499 |
u8 noisy) |
1da177e4c Linux-2.6.12-rc2 |
500 |
{ |
1da177e4c Linux-2.6.12-rc2 |
501 |
int pciirq, ret; |
1da177e4c Linux-2.6.12-rc2 |
502 503 504 505 |
/* * Can we trust the reported IRQ? */ pciirq = dev->irq; |
708e5f9eb ide: always call ... |
506 507 508 509 510 511 |
/* * This allows offboard ide-pci cards the enable a BIOS, * verify interrupt settings of split-mirror pci-config * space, place chipset into init-mode, and/or preserve * an interrupt if the card is not native ide support. */ |
a326b02b0 ide: drop 'name' ... |
512 |
ret = d->init_chipset ? d->init_chipset(dev) : 0; |
708e5f9eb ide: always call ... |
513 514 |
if (ret < 0) goto out; |
8c6de94cf ide: use ide_pci_... |
515 |
if (ide_pci_is_in_compatibility_mode(dev)) { |
1da177e4c Linux-2.6.12-rc2 |
516 |
if (noisy) |
28cfd8af5 ide: include PCI ... |
517 518 519 |
printk(KERN_INFO "%s %s: not 100%% native mode: will " "probe irqs later ", d->name, pci_name(dev)); |
2ed0ef543 ide: fix ->init_c... |
520 |
pciirq = 0; |
28cfd8af5 ide: include PCI ... |
521 522 523 524 525 526 527 528 |
} else if (!pciirq && noisy) { printk(KERN_WARNING "%s %s: bad irq (%d): will probe later ", d->name, pci_name(dev), pciirq); } else if (noisy) { printk(KERN_INFO "%s %s: 100%% native mode on irq %d ", d->name, pci_name(dev), pciirq); |
1da177e4c Linux-2.6.12-rc2 |
529 |
} |
51d87ed0a ide: move ide_pci... |
530 |
ret = pciirq; |
1da177e4c Linux-2.6.12-rc2 |
531 532 533 |
out: return ret; } |
6cdf6eb35 ide: add ->dev an... |
534 535 |
int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2, const struct ide_port_info *d, void *priv) |
1da177e4c Linux-2.6.12-rc2 |
536 537 |
{ struct pci_dev *pdev[] = { dev1, dev2 }; |
6cdf6eb35 ide: add ->dev an... |
538 |
struct ide_host *host; |
a06876a76 ide: pci: free PC... |
539 |
int ret, i, n_ports = dev2 ? 4 : 2, bars; |
9f36d3143 ide: remove hw_re... |
540 |
struct ide_hw hw[4], *hws[] = { NULL, NULL, NULL, NULL }; |
1da177e4c Linux-2.6.12-rc2 |
541 |
|
a06876a76 ide: pci: free PC... |
542 543 544 545 546 547 548 549 550 551 552 |
if (d->host_flags & IDE_HFLAG_SINGLE) bars = (1 << 2) - 1; else bars = (1 << 4) - 1; if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) { if (d->host_flags & IDE_HFLAG_CS5520) bars |= (1 << 2); else bars |= (1 << 4); } |
ad7c52d09 ide: re-implement... |
553 |
for (i = 0; i < n_ports / 2; i++) { |
a06876a76 ide: pci: free PC... |
554 555 556 557 |
ret = ide_setup_pci_controller(pdev[i], bars, d, !i); if (ret < 0) { if (i == 1) pci_release_selected_regions(pdev[0], bars); |
a742d6cf0 ide: move ide_set... |
558 |
goto out; |
a06876a76 ide: pci: free PC... |
559 |
} |
a742d6cf0 ide: move ide_set... |
560 |
|
86ccf37c6 ide: remove pciir... |
561 |
ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]); |
6cdf6eb35 ide: add ->dev an... |
562 |
} |
8c2eece50 ide: call ide_pci... |
563 |
|
ad7c52d09 ide: re-implement... |
564 |
host = ide_host_alloc(d, hws, n_ports); |
6cdf6eb35 ide: add ->dev an... |
565 566 |
if (host == NULL) { ret = -ENOMEM; |
a06876a76 ide: pci: free PC... |
567 |
goto out_free_bars; |
6cdf6eb35 ide: add ->dev an... |
568 569 570 |
} host->dev[0] = &dev1->dev; |
ad7c52d09 ide: re-implement... |
571 572 |
if (dev2) host->dev[1] = &dev2->dev; |
6cdf6eb35 ide: add ->dev an... |
573 574 |
host->host_priv = priv; |
255115fb3 ide: allow host d... |
575 |
host->irq_flags = IRQF_SHARED; |
ef0b04276 ide: add ide_pci_... |
576 |
pci_set_drvdata(pdev[0], host); |
ad7c52d09 ide: re-implement... |
577 578 |
if (dev2) pci_set_drvdata(pdev[1], host); |
6cdf6eb35 ide: add ->dev an... |
579 |
|
ad7c52d09 ide: re-implement... |
580 |
for (i = 0; i < n_ports / 2; i++) { |
51d87ed0a ide: move ide_pci... |
581 |
ret = do_ide_setup_pci_device(pdev[i], d, !i); |
1da177e4c Linux-2.6.12-rc2 |
582 583 584 585 586 |
/* * FIXME: Mom, mom, they stole me the helper function to undo * do_ide_setup_pci_device() on the first device! */ if (ret < 0) |
a06876a76 ide: pci: free PC... |
587 |
goto out_free_bars; |
51d87ed0a ide: move ide_pci... |
588 |
|
8c2eece50 ide: call ide_pci... |
589 |
/* fixup IRQ */ |
f65dedfd7 ide: use ide_pci_... |
590 |
if (ide_pci_is_in_compatibility_mode(pdev[i])) { |
5bae8bf45 ide: use pci_get_... |
591 592 |
hw[i*2].irq = pci_get_legacy_ide_irq(pdev[i], 0); hw[i*2 + 1].irq = pci_get_legacy_ide_irq(pdev[i], 1); |
f65dedfd7 ide: use ide_pci_... |
593 594 |
} else hw[i*2 + 1].irq = hw[i*2].irq = ret; |
1da177e4c Linux-2.6.12-rc2 |
595 |
} |
6cdf6eb35 ide: add ->dev an... |
596 597 598 |
ret = ide_host_register(host, d, hws); if (ret) ide_host_free(host); |
a06876a76 ide: pci: free PC... |
599 600 601 602 603 604 605 |
else goto out; out_free_bars: i = n_ports / 2; while (i--) pci_release_selected_regions(pdev[i], bars); |
1da177e4c Linux-2.6.12-rc2 |
606 607 608 |
out: return ret; } |
6cdf6eb35 ide: add ->dev an... |
609 |
EXPORT_SYMBOL_GPL(ide_pci_init_two); |
ef0b04276 ide: add ide_pci_... |
610 |
|
ad7c52d09 ide: re-implement... |
611 612 613 614 615 616 |
int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d, void *priv) { return ide_pci_init_two(dev, NULL, d, priv); } EXPORT_SYMBOL_GPL(ide_pci_init_one); |
ef0b04276 ide: add ide_pci_... |
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 |
void ide_pci_remove(struct pci_dev *dev) { struct ide_host *host = pci_get_drvdata(dev); struct pci_dev *dev2 = host->dev[1] ? to_pci_dev(host->dev[1]) : NULL; int bars; if (host->host_flags & IDE_HFLAG_SINGLE) bars = (1 << 2) - 1; else bars = (1 << 4) - 1; if ((host->host_flags & IDE_HFLAG_NO_DMA) == 0) { if (host->host_flags & IDE_HFLAG_CS5520) bars |= (1 << 2); else bars |= (1 << 4); } ide_host_remove(host); if (dev2) pci_release_selected_regions(dev2, bars); pci_release_selected_regions(dev, bars); if (dev2) pci_disable_device(dev2); pci_disable_device(dev); } EXPORT_SYMBOL_GPL(ide_pci_remove); |
feb22b7f8 ide: add proper P... |
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 |
#ifdef CONFIG_PM int ide_pci_suspend(struct pci_dev *dev, pm_message_t state) { pci_save_state(dev); pci_disable_device(dev); pci_set_power_state(dev, pci_choose_state(dev, state)); return 0; } EXPORT_SYMBOL_GPL(ide_pci_suspend); int ide_pci_resume(struct pci_dev *dev) { struct ide_host *host = pci_get_drvdata(dev); int rc; pci_set_power_state(dev, PCI_D0); rc = pci_enable_device(dev); if (rc) return rc; pci_restore_state(dev); pci_set_master(dev); if (host->init_chipset) host->init_chipset(dev); return 0; } EXPORT_SYMBOL_GPL(ide_pci_resume); #endif |