aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-04-03 18:49:14 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-03 18:49:14 -0400
commit87e8b821ed8db3dab03d96cd542e29666bf210aa (patch)
tree0027060473aafbbb125655ba027319c8a1a665fc /drivers/pci/pci.c
parent33cd9dfa3a13e3d8e41aef225a9f98169816723b (diff)
parent5e11611a5d22252f3f9c169a3c9377eac0c32033 (diff)
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c124
1 files changed, 67 insertions, 57 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 5b548aee9cbc..1531f3a49879 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -303,6 +303,49 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
303} 303}
304EXPORT_SYMBOL_GPL(pci_find_ext_capability); 304EXPORT_SYMBOL_GPL(pci_find_ext_capability);
305 305
306/**
307 * pci_bus_find_ext_capability - find an extended capability
308 * @bus: the PCI bus to query
309 * @devfn: PCI device to query
310 * @cap: capability code
311 *
312 * Like pci_find_ext_capability() but works for pci devices that do not have a
313 * pci_dev structure set up yet.
314 *
315 * Returns the address of the requested capability structure within the
316 * device's PCI configuration space or 0 in case the device does not
317 * support it.
318 */
319int pci_bus_find_ext_capability(struct pci_bus *bus, unsigned int devfn,
320 int cap)
321{
322 u32 header;
323 int ttl;
324 int pos = PCI_CFG_SPACE_SIZE;
325
326 /* minimum 8 bytes per capability */
327 ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
328
329 if (!pci_bus_read_config_dword(bus, devfn, pos, &header))
330 return 0;
331 if (header == 0xffffffff || header == 0)
332 return 0;
333
334 while (ttl-- > 0) {
335 if (PCI_EXT_CAP_ID(header) == cap)
336 return pos;
337
338 pos = PCI_EXT_CAP_NEXT(header);
339 if (pos < PCI_CFG_SPACE_SIZE)
340 break;
341
342 if (!pci_bus_read_config_dword(bus, devfn, pos, &header))
343 break;
344 }
345
346 return 0;
347}
348
306static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) 349static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap)
307{ 350{
308 int rc, ttl = PCI_FIND_CAP_TTL; 351 int rc, ttl = PCI_FIND_CAP_TTL;
@@ -1540,8 +1583,10 @@ void pci_pm_init(struct pci_dev *dev)
1540 int pm; 1583 int pm;
1541 u16 pmc; 1584 u16 pmc;
1542 1585
1586 pm_runtime_forbid(&dev->dev);
1543 device_enable_async_suspend(&dev->dev); 1587 device_enable_async_suspend(&dev->dev);
1544 dev->wakeup_prepared = false; 1588 dev->wakeup_prepared = false;
1589
1545 dev->pm_cap = 0; 1590 dev->pm_cap = 0;
1546 1591
1547 /* find PCI PM capability in list */ 1592 /* find PCI PM capability in list */
@@ -2253,35 +2298,6 @@ void pci_msi_off(struct pci_dev *dev)
2253 } 2298 }
2254} 2299}
2255 2300
2256#ifndef HAVE_ARCH_PCI_SET_DMA_MASK
2257/*
2258 * These can be overridden by arch-specific implementations
2259 */
2260int
2261pci_set_dma_mask(struct pci_dev *dev, u64 mask)
2262{
2263 if (!pci_dma_supported(dev, mask))
2264 return -EIO;
2265
2266 dev->dma_mask = mask;
2267 dev_dbg(&dev->dev, "using %dbit DMA mask\n", fls64(mask));
2268
2269 return 0;
2270}
2271
2272int
2273pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
2274{
2275 if (!pci_dma_supported(dev, mask))
2276 return -EIO;
2277
2278 dev->dev.coherent_dma_mask = mask;
2279 dev_dbg(&dev->dev, "using %dbit consistent DMA mask\n", fls64(mask));
2280
2281 return 0;
2282}
2283#endif
2284
2285#ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE 2301#ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE
2286int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size) 2302int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size)
2287{ 2303{
@@ -2443,7 +2459,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe)
2443 if (!probe) { 2459 if (!probe) {
2444 pci_block_user_cfg_access(dev); 2460 pci_block_user_cfg_access(dev);
2445 /* block PM suspend, driver probe, etc. */ 2461 /* block PM suspend, driver probe, etc. */
2446 down(&dev->dev.sem); 2462 device_lock(&dev->dev);
2447 } 2463 }
2448 2464
2449 rc = pci_dev_specific_reset(dev, probe); 2465 rc = pci_dev_specific_reset(dev, probe);
@@ -2465,7 +2481,7 @@ static int pci_dev_reset(struct pci_dev *dev, int probe)
2465 rc = pci_parent_bus_reset(dev, probe); 2481 rc = pci_parent_bus_reset(dev, probe);
2466done: 2482done:
2467 if (!probe) { 2483 if (!probe) {
2468 up(&dev->dev.sem); 2484 device_unlock(&dev->dev);
2469 pci_unblock_user_cfg_access(dev); 2485 pci_unblock_user_cfg_access(dev);
2470 } 2486 }
2471 2487
@@ -2560,18 +2576,17 @@ EXPORT_SYMBOL_GPL(pci_reset_function);
2560 */ 2576 */
2561int pcix_get_max_mmrbc(struct pci_dev *dev) 2577int pcix_get_max_mmrbc(struct pci_dev *dev)
2562{ 2578{
2563 int err, cap; 2579 int cap;
2564 u32 stat; 2580 u32 stat;
2565 2581
2566 cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); 2582 cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
2567 if (!cap) 2583 if (!cap)
2568 return -EINVAL; 2584 return -EINVAL;
2569 2585
2570 err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); 2586 if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat))
2571 if (err)
2572 return -EINVAL; 2587 return -EINVAL;
2573 2588
2574 return (stat & PCI_X_STATUS_MAX_READ) >> 12; 2589 return 512 << ((stat & PCI_X_STATUS_MAX_READ) >> 21);
2575} 2590}
2576EXPORT_SYMBOL(pcix_get_max_mmrbc); 2591EXPORT_SYMBOL(pcix_get_max_mmrbc);
2577 2592
@@ -2584,18 +2599,17 @@ EXPORT_SYMBOL(pcix_get_max_mmrbc);
2584 */ 2599 */
2585int pcix_get_mmrbc(struct pci_dev *dev) 2600int pcix_get_mmrbc(struct pci_dev *dev)
2586{ 2601{
2587 int ret, cap; 2602 int cap;
2588 u32 cmd; 2603 u16 cmd;
2589 2604
2590 cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); 2605 cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
2591 if (!cap) 2606 if (!cap)
2592 return -EINVAL; 2607 return -EINVAL;
2593 2608
2594 ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); 2609 if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd))
2595 if (!ret) 2610 return -EINVAL;
2596 ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2);
2597 2611
2598 return ret; 2612 return 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2);
2599} 2613}
2600EXPORT_SYMBOL(pcix_get_mmrbc); 2614EXPORT_SYMBOL(pcix_get_mmrbc);
2601 2615
@@ -2610,28 +2624,27 @@ EXPORT_SYMBOL(pcix_get_mmrbc);
2610 */ 2624 */
2611int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) 2625int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc)
2612{ 2626{
2613 int cap, err = -EINVAL; 2627 int cap;
2614 u32 stat, cmd, v, o; 2628 u32 stat, v, o;
2629 u16 cmd;
2615 2630
2616 if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc)) 2631 if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc))
2617 goto out; 2632 return -EINVAL;
2618 2633
2619 v = ffs(mmrbc) - 10; 2634 v = ffs(mmrbc) - 10;
2620 2635
2621 cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); 2636 cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
2622 if (!cap) 2637 if (!cap)
2623 goto out; 2638 return -EINVAL;
2624 2639
2625 err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); 2640 if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat))
2626 if (err) 2641 return -EINVAL;
2627 goto out;
2628 2642
2629 if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21) 2643 if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21)
2630 return -E2BIG; 2644 return -E2BIG;
2631 2645
2632 err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); 2646 if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd))
2633 if (err) 2647 return -EINVAL;
2634 goto out;
2635 2648
2636 o = (cmd & PCI_X_CMD_MAX_READ) >> 2; 2649 o = (cmd & PCI_X_CMD_MAX_READ) >> 2;
2637 if (o != v) { 2650 if (o != v) {
@@ -2641,10 +2654,10 @@ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc)
2641 2654
2642 cmd &= ~PCI_X_CMD_MAX_READ; 2655 cmd &= ~PCI_X_CMD_MAX_READ;
2643 cmd |= v << 2; 2656 cmd |= v << 2;
2644 err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd); 2657 if (pci_write_config_word(dev, cap + PCI_X_CMD, cmd))
2658 return -EIO;
2645 } 2659 }
2646out: 2660 return 0;
2647 return err;
2648} 2661}
2649EXPORT_SYMBOL(pcix_set_mmrbc); 2662EXPORT_SYMBOL(pcix_set_mmrbc);
2650 2663
@@ -3007,7 +3020,6 @@ EXPORT_SYMBOL(pcim_pin_device);
3007EXPORT_SYMBOL(pci_disable_device); 3020EXPORT_SYMBOL(pci_disable_device);
3008EXPORT_SYMBOL(pci_find_capability); 3021EXPORT_SYMBOL(pci_find_capability);
3009EXPORT_SYMBOL(pci_bus_find_capability); 3022EXPORT_SYMBOL(pci_bus_find_capability);
3010EXPORT_SYMBOL(pci_register_set_vga_state);
3011EXPORT_SYMBOL(pci_release_regions); 3023EXPORT_SYMBOL(pci_release_regions);
3012EXPORT_SYMBOL(pci_request_regions); 3024EXPORT_SYMBOL(pci_request_regions);
3013EXPORT_SYMBOL(pci_request_regions_exclusive); 3025EXPORT_SYMBOL(pci_request_regions_exclusive);
@@ -3023,8 +3035,6 @@ EXPORT_SYMBOL(pci_set_mwi);
3023EXPORT_SYMBOL(pci_try_set_mwi); 3035EXPORT_SYMBOL(pci_try_set_mwi);
3024EXPORT_SYMBOL(pci_clear_mwi); 3036EXPORT_SYMBOL(pci_clear_mwi);
3025EXPORT_SYMBOL_GPL(pci_intx); 3037EXPORT_SYMBOL_GPL(pci_intx);
3026EXPORT_SYMBOL(pci_set_dma_mask);
3027EXPORT_SYMBOL(pci_set_consistent_dma_mask);
3028EXPORT_SYMBOL(pci_assign_resource); 3038EXPORT_SYMBOL(pci_assign_resource);
3029EXPORT_SYMBOL(pci_find_parent_resource); 3039EXPORT_SYMBOL(pci_find_parent_resource);
3030EXPORT_SYMBOL(pci_select_bars); 3040EXPORT_SYMBOL(pci_select_bars);