Blame view
drivers/ide/setup-pci.c
16.6 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 10 11 |
#include <linux/types.h> #include <linux/kernel.h> #include <linux/pci.h> #include <linux/init.h> |
1da177e4c Linux-2.6.12-rc2 |
12 13 14 15 16 |
#include <linux/interrupt.h> #include <linux/ide.h> #include <linux/dma-mapping.h> #include <asm/io.h> |
1da177e4c Linux-2.6.12-rc2 |
17 |
|
1da177e4c Linux-2.6.12-rc2 |
18 19 20 21 22 23 24 |
/** * 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... |
25 |
* Returns 0 on success or an errno code. |
1da177e4c Linux-2.6.12-rc2 |
26 27 28 29 |
* * 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... |
30 31 |
static int ide_setup_pci_baseregs(struct pci_dev *dev, const char *name) |
1da177e4c Linux-2.6.12-rc2 |
32 33 34 35 36 37 38 39 40 |
{ 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 ... |
41 42 43 |
printk(KERN_INFO "%s %s: device not capable of full " "native PCI mode ", name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
44 45 |
return -EOPNOTSUPP; } |
28cfd8af5 ide: include PCI ... |
46 47 48 |
printk(KERN_INFO "%s %s: placing both ports into native PCI " "mode ", name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
49 50 51 |
(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 ... |
52 53 54 55 |
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 |
56 57 58 59 60 61 62 |
return -EOPNOTSUPP; } } return 0; } #ifdef CONFIG_BLK_DEV_IDEDMA_PCI |
28cfd8af5 ide: include PCI ... |
63 |
static int ide_pci_clear_simplex(unsigned long dma_base, const char *name) |
8ac2b42a4 ide: add IDE_HFLA... |
64 65 66 67 68 |
{ u8 dma_stat = inb(dma_base + 2); outb(dma_stat & 0x60, dma_base + 2); dma_stat = inb(dma_base + 2); |
28cfd8af5 ide: include PCI ... |
69 70 |
return (dma_stat & 0x80) ? 1 : 0; |
8ac2b42a4 ide: add IDE_HFLA... |
71 |
} |
1da177e4c Linux-2.6.12-rc2 |
72 |
/** |
b123f56e0 ide: do complete ... |
73 |
* ide_pci_dma_base - setup BMIBA |
039788e15 ide: replace ide_... |
74 |
* @hwif: IDE interface |
b123f56e0 ide: do complete ... |
75 |
* @d: IDE port info |
1da177e4c Linux-2.6.12-rc2 |
76 |
* |
c58e79dd4 ide: remove CONFI... |
77 |
* Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space. |
1da177e4c Linux-2.6.12-rc2 |
78 |
*/ |
b123f56e0 ide: do complete ... |
79 |
unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d) |
1da177e4c Linux-2.6.12-rc2 |
80 |
{ |
36501650e ide: keep pointer... |
81 82 |
struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long dma_base = 0; |
1da177e4c Linux-2.6.12-rc2 |
83 |
|
135721446 ide: remove ->mmi... |
84 |
if (hwif->host_flags & IDE_HFLAG_MMIO) |
1da177e4c Linux-2.6.12-rc2 |
85 86 87 88 89 |
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... |
90 91 92 |
u8 baridx = (d->host_flags & IDE_HFLAG_CS5520) ? 2 : 4; dma_base = pci_resource_start(dev, baridx); |
aea5d3756 ide: (hopefully) ... |
93 |
if (dma_base == 0) { |
28cfd8af5 ide: include PCI ... |
94 95 96 |
printk(KERN_ERR "%s %s: DMA base is invalid ", d->name, pci_name(dev)); |
aea5d3756 ide: (hopefully) ... |
97 98 |
return 0; } |
1da177e4c Linux-2.6.12-rc2 |
99 |
} |
aea5d3756 ide: (hopefully) ... |
100 101 |
if (hwif->channel) dma_base += 8; |
ebb00fb55 ide: factor out s... |
102 103 104 105 106 107 |
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 ... |
108 |
struct pci_dev *dev = to_pci_dev(hwif->dev); |
ebb00fb55 ide: factor out s... |
109 110 111 |
u8 dma_stat; if (d->host_flags & (IDE_HFLAG_MMIO | IDE_HFLAG_CS5520)) |
8ac2b42a4 ide: add IDE_HFLA... |
112 113 114 |
goto out; if (d->host_flags & IDE_HFLAG_CLEAR_SIMPLEX) { |
28cfd8af5 ide: include PCI ... |
115 116 117 118 |
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... |
119 120 121 122 123 124 125 126 127 128 129 130 131 |
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... |
132 |
dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); |
8ac2b42a4 ide: add IDE_HFLA... |
133 |
if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) { |
28cfd8af5 ide: include PCI ... |
134 135 136 |
printk(KERN_INFO "%s %s: simplex device: DMA disabled ", d->name, pci_name(dev)); |
ebb00fb55 ide: factor out s... |
137 |
return -1; |
1da177e4c Linux-2.6.12-rc2 |
138 |
} |
8ac2b42a4 ide: add IDE_HFLA... |
139 |
out: |
ebb00fb55 ide: factor out s... |
140 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
141 |
} |
ebb00fb55 ide: factor out s... |
142 |
EXPORT_SYMBOL_GPL(ide_pci_check_simplex); |
d54452fbf ide: factor out s... |
143 144 145 146 |
/* * Set up BM-DMA capability (PnP BIOS should have done this) */ |
b123f56e0 ide: do complete ... |
147 |
int ide_pci_set_master(struct pci_dev *dev, const char *name) |
d54452fbf ide: factor out s... |
148 149 150 151 152 153 154 155 156 157 |
{ 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 ... |
158 159 160 |
printk(KERN_ERR "%s %s: error updating PCICMD ", name, pci_name(dev)); |
d54452fbf ide: factor out s... |
161 162 163 164 165 166 |
return -EIO; } } return 0; } |
b123f56e0 ide: do complete ... |
167 |
EXPORT_SYMBOL_GPL(ide_pci_set_master); |
1da177e4c Linux-2.6.12-rc2 |
168 |
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ |
856204360 ide: constify str... |
169 |
void ide_setup_pci_noise(struct pci_dev *dev, const struct ide_port_info *d) |
1da177e4c Linux-2.6.12-rc2 |
170 |
{ |
28cfd8af5 ide: include PCI ... |
171 172 173 174 |
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 |
175 |
} |
1da177e4c Linux-2.6.12-rc2 |
176 177 178 179 180 181 |
EXPORT_SYMBOL_GPL(ide_setup_pci_noise); /** * ide_pci_enable - do PCI enables * @dev: PCI device |
039788e15 ide: replace ide_... |
182 |
* @d: IDE port info |
1da177e4c Linux-2.6.12-rc2 |
183 184 |
* * Enable the IDE PCI device. We attempt to enable the device in full |
094839164 PCI: Remove users... |
185 186 187 |
* 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... |
188 |
* |
1da177e4c Linux-2.6.12-rc2 |
189 190 |
* Returns zero on success or an error code */ |
039788e15 ide: replace ide_... |
191 |
|
856204360 ide: constify str... |
192 |
static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d) |
1da177e4c Linux-2.6.12-rc2 |
193 |
{ |
0d1bad216 ide: manage resou... |
194 |
int ret, bars; |
1da177e4c Linux-2.6.12-rc2 |
195 196 |
if (pci_enable_device(dev)) { |
094839164 PCI: Remove users... |
197 |
ret = pci_enable_device_io(dev); |
1da177e4c Linux-2.6.12-rc2 |
198 |
if (ret < 0) { |
28cfd8af5 ide: include PCI ... |
199 200 201 |
printk(KERN_WARNING "%s %s: couldn't enable device ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
202 203 |
goto out; } |
28cfd8af5 ide: include PCI ... |
204 205 206 |
printk(KERN_WARNING "%s %s: BIOS configuration fixed ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
207 208 209 |
} /* |
039788e15 ide: replace ide_... |
210 211 212 |
* 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 |
213 |
*/ |
284901a90 dma-mapping: repl... |
214 |
ret = pci_set_dma_mask(dev, DMA_BIT_MASK(32)); |
1da177e4c Linux-2.6.12-rc2 |
215 |
if (ret < 0) { |
28cfd8af5 ide: include PCI ... |
216 217 218 |
printk(KERN_ERR "%s %s: can't set DMA mask ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
219 220 |
goto out; } |
0d1bad216 ide: manage resou... |
221 222 223 224 |
if (d->host_flags & IDE_HFLAG_SINGLE) bars = (1 << 2) - 1; else bars = (1 << 4) - 1; |
1da177e4c Linux-2.6.12-rc2 |
225 |
|
0d1bad216 ide: manage resou... |
226 227 228 229 230 231 232 233 234 |
if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) { if (d->host_flags & IDE_HFLAG_CS5520) bars |= (1 << 2); else bars |= (1 << 4); } ret = pci_request_selected_regions(dev, bars, d->name); if (ret < 0) |
28cfd8af5 ide: include PCI ... |
235 236 237 |
printk(KERN_ERR "%s %s: can't reserve resources ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
238 239 240 241 242 243 244 |
out: return ret; } /** * ide_pci_configure - configure an unconfigured device * @dev: PCI device |
039788e15 ide: replace ide_... |
245 |
* @d: IDE port info |
1da177e4c Linux-2.6.12-rc2 |
246 247 248 249 |
* * Enable and configure the PCI device we have been passed. * Returns zero on success or an error code. */ |
039788e15 ide: replace ide_... |
250 |
|
856204360 ide: constify str... |
251 |
static int ide_pci_configure(struct pci_dev *dev, const struct ide_port_info *d) |
1da177e4c Linux-2.6.12-rc2 |
252 253 254 255 256 257 258 259 260 |
{ 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... |
261 262 |
if (ide_setup_pci_baseregs(dev, d->name) || pci_write_config_word(dev, PCI_COMMAND, pcicmd | PCI_COMMAND_IO)) { |
28cfd8af5 ide: include PCI ... |
263 264 265 |
printk(KERN_INFO "%s %s: device disabled (BIOS) ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
266 267 268 |
return -ENODEV; } if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd)) { |
28cfd8af5 ide: include PCI ... |
269 270 271 |
printk(KERN_ERR "%s %s: error accessing PCI regs ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
272 273 274 |
return -EIO; } if (!(pcicmd & PCI_COMMAND_IO)) { |
28cfd8af5 ide: include PCI ... |
275 276 277 |
printk(KERN_ERR "%s %s: unable to enable IDE controller ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
278 279 280 281 282 283 284 |
return -ENXIO; } return 0; } /** * ide_pci_check_iomem - check a register is I/O |
039788e15 ide: replace ide_... |
285 286 287 |
* @dev: PCI device * @d: IDE port info * @bar: BAR number |
1da177e4c Linux-2.6.12-rc2 |
288 |
* |
1baccff8a ide: make ide_pci... |
289 290 |
* 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 |
291 |
*/ |
039788e15 ide: replace ide_... |
292 |
|
1baccff8a ide: make ide_pci... |
293 294 |
static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *d, int bar) |
1da177e4c Linux-2.6.12-rc2 |
295 296 |
{ ulong flags = pci_resource_flags(dev, bar); |
846bb88ae IDE: Coding Style... |
297 |
|
1da177e4c Linux-2.6.12-rc2 |
298 299 300 |
/* Unconfigured ? */ if (!flags || pci_resource_len(dev, bar) == 0) return 0; |
1baccff8a ide: make ide_pci... |
301 302 |
/* I/O space */ if (flags & IORESOURCE_IO) |
1da177e4c Linux-2.6.12-rc2 |
303 |
return 0; |
846bb88ae IDE: Coding Style... |
304 |
|
1da177e4c Linux-2.6.12-rc2 |
305 |
/* Bad */ |
1da177e4c Linux-2.6.12-rc2 |
306 307 308 309 |
return -EINVAL; } /** |
9f36d3143 ide: remove hw_re... |
310 |
* ide_hw_configure - configure a struct ide_hw instance |
1da177e4c Linux-2.6.12-rc2 |
311 |
* @dev: PCI device holding interface |
039788e15 ide: replace ide_... |
312 |
* @d: IDE port info |
1ebf74936 ide: separate PCI... |
313 |
* @port: port number |
9f36d3143 ide: remove hw_re... |
314 |
* @hw: struct ide_hw instance corresponding to this port |
1da177e4c Linux-2.6.12-rc2 |
315 316 317 318 319 |
* * 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... |
320 |
* Returns zero on success or an error code. |
1da177e4c Linux-2.6.12-rc2 |
321 |
*/ |
039788e15 ide: replace ide_... |
322 |
|
48c3c1072 ide: add struct i... |
323 |
static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d, |
9f36d3143 ide: remove hw_re... |
324 |
unsigned int port, struct ide_hw *hw) |
1da177e4c Linux-2.6.12-rc2 |
325 326 |
{ unsigned long ctl = 0, base = 0; |
1da177e4c Linux-2.6.12-rc2 |
327 |
|
a5d8c5c83 ide: add ide_pci_... |
328 |
if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) { |
1baccff8a ide: make ide_pci... |
329 330 |
if (ide_pci_check_iomem(dev, d, 2 * port) || ide_pci_check_iomem(dev, d, 2 * port + 1)) { |
28cfd8af5 ide: include PCI ... |
331 332 333 334 |
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... |
335 |
return -EINVAL; |
1baccff8a ide: make ide_pci... |
336 |
} |
846bb88ae IDE: Coding Style... |
337 |
|
1da177e4c Linux-2.6.12-rc2 |
338 339 |
ctl = pci_resource_start(dev, 2*port+1); base = pci_resource_start(dev, 2*port); |
c1da678b5 ide: tighten chec... |
340 |
} else { |
1da177e4c Linux-2.6.12-rc2 |
341 342 343 344 |
/* Use default values */ ctl = port ? 0x374 : 0x3f4; base = port ? 0x170 : 0x1f0; } |
bad7c825c ide: cleanup ide_... |
345 |
|
c1da678b5 ide: tighten chec... |
346 |
if (!base || !ctl) { |
28cfd8af5 ide: include PCI ... |
347 348 349 |
printk(KERN_ERR "%s %s: bad PCI BARs for port %d, skipping ", d->name, pci_name(dev), port); |
48c3c1072 ide: add struct i... |
350 |
return -EINVAL; |
c1da678b5 ide: tighten chec... |
351 |
} |
c97c6aca7 ide: pass hw_regs... |
352 |
memset(hw, 0, sizeof(*hw)); |
c97c6aca7 ide: pass hw_regs... |
353 |
hw->dev = &dev->dev; |
c97c6aca7 ide: pass hw_regs... |
354 |
ide_std_init_ports(hw, base, ctl | 2); |
48c3c1072 ide: add struct i... |
355 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
356 |
} |
c413b9b94 ide: add struct i... |
357 |
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI |
1da177e4c Linux-2.6.12-rc2 |
358 359 |
/** * ide_hwif_setup_dma - configure DMA interface |
039788e15 ide: replace ide_... |
360 |
* @hwif: IDE interface |
c413b9b94 ide: add struct i... |
361 |
* @d: IDE port info |
1da177e4c Linux-2.6.12-rc2 |
362 363 364 365 366 |
* * 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_... |
367 |
|
b123f56e0 ide: do complete ... |
368 |
int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d) |
1da177e4c Linux-2.6.12-rc2 |
369 |
{ |
c413b9b94 ide: add struct i... |
370 |
struct pci_dev *dev = to_pci_dev(hwif->dev); |
1da177e4c Linux-2.6.12-rc2 |
371 |
|
47b687882 ide: add IDE_HFLA... |
372 |
if ((d->host_flags & IDE_HFLAG_NO_AUTODMA) == 0 || |
1da177e4c Linux-2.6.12-rc2 |
373 374 |
((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) { |
b123f56e0 ide: do complete ... |
375 |
unsigned long base = ide_pci_dma_base(hwif, d); |
d54452fbf ide: factor out s... |
376 |
|
ebb00fb55 ide: factor out s... |
377 378 379 380 |
if (base == 0) return -1; hwif->dma_base = base; |
592b53152 ide: move read_sf... |
381 382 |
if (hwif->dma_ops == NULL) hwif->dma_ops = &sff_dma_ops; |
ebb00fb55 ide: factor out s... |
383 384 385 386 |
if (ide_pci_check_simplex(hwif, d) < 0) return -1; if (ide_pci_set_master(dev, d->name) < 0) |
b123f56e0 ide: do complete ... |
387 |
return -1; |
d54452fbf ide: factor out s... |
388 |
|
135721446 ide: remove ->mmi... |
389 |
if (hwif->host_flags & IDE_HFLAG_MMIO) |
63158d5c2 ide: cleanup ide_... |
390 391 392 393 394 395 396 397 |
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 ... |
398 399 |
if (ide_allocate_dma_engine(hwif)) return -1; |
b123f56e0 ide: do complete ... |
400 |
} |
d54452fbf ide: factor out s... |
401 |
|
b123f56e0 ide: do complete ... |
402 |
return 0; |
039788e15 ide: replace ide_... |
403 |
} |
c413b9b94 ide: add struct i... |
404 |
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ |
1da177e4c Linux-2.6.12-rc2 |
405 406 407 408 |
/** * ide_setup_pci_controller - set up IDE PCI * @dev: PCI device |
039788e15 ide: replace ide_... |
409 |
* @d: IDE port info |
1da177e4c Linux-2.6.12-rc2 |
410 |
* @noisy: verbose flag |
1da177e4c Linux-2.6.12-rc2 |
411 412 413 414 415 |
* * 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_... |
416 |
|
a95925a30 ide: respect dev-... |
417 418 |
static int ide_setup_pci_controller(struct pci_dev *dev, const struct ide_port_info *d, int noisy) |
1da177e4c Linux-2.6.12-rc2 |
419 420 |
{ int ret; |
1da177e4c Linux-2.6.12-rc2 |
421 422 423 424 425 426 427 428 429 430 431 |
u16 pcicmd; if (noisy) ide_setup_pci_noise(dev, d); ret = ide_pci_enable(dev, d); if (ret < 0) goto out; ret = pci_read_config_word(dev, PCI_COMMAND, &pcicmd); if (ret < 0) { |
28cfd8af5 ide: include PCI ... |
432 433 434 |
printk(KERN_ERR "%s %s: error accessing PCI regs ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
435 436 437 438 439 440 |
goto out; } if (!(pcicmd & PCI_COMMAND_IO)) { /* is device disabled? */ ret = ide_pci_configure(dev, d); if (ret < 0) goto out; |
28cfd8af5 ide: include PCI ... |
441 442 443 |
printk(KERN_INFO "%s %s: device enabled (Linux) ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
444 |
} |
1da177e4c Linux-2.6.12-rc2 |
445 446 447 448 449 450 451 |
out: return ret; } /** * ide_pci_setup_ports - configure ports/devices on PCI IDE * @dev: PCI device |
039788e15 ide: replace ide_... |
452 |
* @d: IDE port info |
9f36d3143 ide: remove hw_re... |
453 454 |
* @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 |
455 456 457 458 459 460 461 462 463 |
* * 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... |
464 |
|
c97c6aca7 ide: pass hw_regs... |
465 |
void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, |
9f36d3143 ide: remove hw_re... |
466 |
struct ide_hw *hw, struct ide_hw **hws) |
1da177e4c Linux-2.6.12-rc2 |
467 |
{ |
a5d8c5c83 ide: add ide_pci_... |
468 |
int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port; |
1da177e4c Linux-2.6.12-rc2 |
469 |
u8 tmp; |
1da177e4c Linux-2.6.12-rc2 |
470 471 472 |
/* * Set up the IDE ports */ |
cf6e854ef ide: fix disabled... |
473 |
|
a5d8c5c83 ide: add ide_pci_... |
474 |
for (port = 0; port < channels; ++port) { |
c0ae50234 ide: remove ide_p... |
475 |
const struct ide_pci_enablebit *e = &d->enablebits[port]; |
856204360 ide: constify str... |
476 |
|
1da177e4c Linux-2.6.12-rc2 |
477 |
if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || |
cf6e854ef ide: fix disabled... |
478 |
(tmp & e->mask) != e->val)) { |
28cfd8af5 ide: include PCI ... |
479 480 481 |
printk(KERN_INFO "%s %s: IDE port disabled ", d->name, pci_name(dev)); |
1da177e4c Linux-2.6.12-rc2 |
482 |
continue; /* port not enabled */ |
cf6e854ef ide: fix disabled... |
483 |
} |
1da177e4c Linux-2.6.12-rc2 |
484 |
|
86ccf37c6 ide: remove pciir... |
485 |
if (ide_hw_configure(dev, d, port, hw + port)) |
1da177e4c Linux-2.6.12-rc2 |
486 |
continue; |
c97c6aca7 ide: pass hw_regs... |
487 |
*(hws + port) = hw + port; |
1ebf74936 ide: separate PCI... |
488 |
} |
1da177e4c Linux-2.6.12-rc2 |
489 |
} |
1da177e4c Linux-2.6.12-rc2 |
490 491 492 493 494 495 496 497 498 |
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_... |
499 |
* we "know" about, this information is in the struct ide_port_info; |
1da177e4c Linux-2.6.12-rc2 |
500 501 |
* for all other chipsets, we just assume both interfaces are enabled. */ |
039788e15 ide: replace ide_... |
502 |
static int do_ide_setup_pci_device(struct pci_dev *dev, |
856204360 ide: constify str... |
503 |
const struct ide_port_info *d, |
51d87ed0a ide: move ide_pci... |
504 |
u8 noisy) |
1da177e4c Linux-2.6.12-rc2 |
505 |
{ |
1da177e4c Linux-2.6.12-rc2 |
506 |
int pciirq, ret; |
1da177e4c Linux-2.6.12-rc2 |
507 508 509 510 |
/* * Can we trust the reported IRQ? */ pciirq = dev->irq; |
708e5f9eb ide: always call ... |
511 512 513 514 515 516 |
/* * 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' ... |
517 |
ret = d->init_chipset ? d->init_chipset(dev) : 0; |
708e5f9eb ide: always call ... |
518 519 |
if (ret < 0) goto out; |
8c6de94cf ide: use ide_pci_... |
520 |
if (ide_pci_is_in_compatibility_mode(dev)) { |
1da177e4c Linux-2.6.12-rc2 |
521 |
if (noisy) |
28cfd8af5 ide: include PCI ... |
522 523 524 |
printk(KERN_INFO "%s %s: not 100%% native mode: will " "probe irqs later ", d->name, pci_name(dev)); |
2ed0ef543 ide: fix ->init_c... |
525 |
pciirq = 0; |
28cfd8af5 ide: include PCI ... |
526 527 528 529 530 531 532 533 |
} 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 |
534 |
} |
51d87ed0a ide: move ide_pci... |
535 |
ret = pciirq; |
1da177e4c Linux-2.6.12-rc2 |
536 537 538 |
out: return ret; } |
6cdf6eb35 ide: add ->dev an... |
539 540 |
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 |
541 542 |
{ struct pci_dev *pdev[] = { dev1, dev2 }; |
6cdf6eb35 ide: add ->dev an... |
543 |
struct ide_host *host; |
ad7c52d09 ide: re-implement... |
544 |
int ret, i, n_ports = dev2 ? 4 : 2; |
9f36d3143 ide: remove hw_re... |
545 |
struct ide_hw hw[4], *hws[] = { NULL, NULL, NULL, NULL }; |
1da177e4c Linux-2.6.12-rc2 |
546 |
|
ad7c52d09 ide: re-implement... |
547 |
for (i = 0; i < n_ports / 2; i++) { |
a742d6cf0 ide: move ide_set... |
548 549 550 |
ret = ide_setup_pci_controller(pdev[i], d, !i); if (ret < 0) goto out; |
86ccf37c6 ide: remove pciir... |
551 |
ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]); |
6cdf6eb35 ide: add ->dev an... |
552 |
} |
8c2eece50 ide: call ide_pci... |
553 |
|
ad7c52d09 ide: re-implement... |
554 |
host = ide_host_alloc(d, hws, n_ports); |
6cdf6eb35 ide: add ->dev an... |
555 556 557 558 559 560 |
if (host == NULL) { ret = -ENOMEM; goto out; } host->dev[0] = &dev1->dev; |
ad7c52d09 ide: re-implement... |
561 562 |
if (dev2) host->dev[1] = &dev2->dev; |
6cdf6eb35 ide: add ->dev an... |
563 564 |
host->host_priv = priv; |
255115fb3 ide: allow host d... |
565 |
host->irq_flags = IRQF_SHARED; |
ef0b04276 ide: add ide_pci_... |
566 |
pci_set_drvdata(pdev[0], host); |
ad7c52d09 ide: re-implement... |
567 568 |
if (dev2) pci_set_drvdata(pdev[1], host); |
6cdf6eb35 ide: add ->dev an... |
569 |
|
ad7c52d09 ide: re-implement... |
570 |
for (i = 0; i < n_ports / 2; i++) { |
51d87ed0a ide: move ide_pci... |
571 |
ret = do_ide_setup_pci_device(pdev[i], d, !i); |
1da177e4c Linux-2.6.12-rc2 |
572 573 574 575 576 577 |
/* * FIXME: Mom, mom, they stole me the helper function to undo * do_ide_setup_pci_device() on the first device! */ if (ret < 0) goto out; |
51d87ed0a ide: move ide_pci... |
578 |
|
8c2eece50 ide: call ide_pci... |
579 |
/* fixup IRQ */ |
f65dedfd7 ide: use ide_pci_... |
580 |
if (ide_pci_is_in_compatibility_mode(pdev[i])) { |
5bae8bf45 ide: use pci_get_... |
581 582 |
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_... |
583 584 |
} else hw[i*2 + 1].irq = hw[i*2].irq = ret; |
1da177e4c Linux-2.6.12-rc2 |
585 |
} |
6cdf6eb35 ide: add ->dev an... |
586 587 588 |
ret = ide_host_register(host, d, hws); if (ret) ide_host_free(host); |
1da177e4c Linux-2.6.12-rc2 |
589 590 591 |
out: return ret; } |
6cdf6eb35 ide: add ->dev an... |
592 |
EXPORT_SYMBOL_GPL(ide_pci_init_two); |
ef0b04276 ide: add ide_pci_... |
593 |
|
ad7c52d09 ide: re-implement... |
594 595 596 597 598 599 |
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_... |
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 |
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... |
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 |
#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 |