diff options
| author | David S. Miller <davem@davemloft.net> | 2010-04-03 18:49:14 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-04-03 18:49:14 -0400 |
| commit | 87e8b821ed8db3dab03d96cd542e29666bf210aa (patch) | |
| tree | 0027060473aafbbb125655ba027319c8a1a665fc /drivers/pci/pci.c | |
| parent | 33cd9dfa3a13e3d8e41aef225a9f98169816723b (diff) | |
| parent | 5e11611a5d22252f3f9c169a3c9377eac0c32033 (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.c | 124 |
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 | } |
| 304 | EXPORT_SYMBOL_GPL(pci_find_ext_capability); | 304 | EXPORT_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 | */ | ||
| 319 | int 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 | |||
| 306 | static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap) | 349 | static 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 | */ | ||
| 2260 | int | ||
| 2261 | pci_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 | |||
| 2272 | int | ||
| 2273 | pci_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 |
| 2286 | int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size) | 2302 | int 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); |
| 2466 | done: | 2482 | done: |
| 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 | */ |
| 2561 | int pcix_get_max_mmrbc(struct pci_dev *dev) | 2577 | int 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 | } |
| 2576 | EXPORT_SYMBOL(pcix_get_max_mmrbc); | 2591 | EXPORT_SYMBOL(pcix_get_max_mmrbc); |
| 2577 | 2592 | ||
| @@ -2584,18 +2599,17 @@ EXPORT_SYMBOL(pcix_get_max_mmrbc); | |||
| 2584 | */ | 2599 | */ |
| 2585 | int pcix_get_mmrbc(struct pci_dev *dev) | 2600 | int 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 | } |
| 2600 | EXPORT_SYMBOL(pcix_get_mmrbc); | 2614 | EXPORT_SYMBOL(pcix_get_mmrbc); |
| 2601 | 2615 | ||
| @@ -2610,28 +2624,27 @@ EXPORT_SYMBOL(pcix_get_mmrbc); | |||
| 2610 | */ | 2624 | */ |
| 2611 | int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) | 2625 | int 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 | } |
| 2646 | out: | 2660 | return 0; |
| 2647 | return err; | ||
| 2648 | } | 2661 | } |
| 2649 | EXPORT_SYMBOL(pcix_set_mmrbc); | 2662 | EXPORT_SYMBOL(pcix_set_mmrbc); |
| 2650 | 2663 | ||
| @@ -3007,7 +3020,6 @@ EXPORT_SYMBOL(pcim_pin_device); | |||
| 3007 | EXPORT_SYMBOL(pci_disable_device); | 3020 | EXPORT_SYMBOL(pci_disable_device); |
| 3008 | EXPORT_SYMBOL(pci_find_capability); | 3021 | EXPORT_SYMBOL(pci_find_capability); |
| 3009 | EXPORT_SYMBOL(pci_bus_find_capability); | 3022 | EXPORT_SYMBOL(pci_bus_find_capability); |
| 3010 | EXPORT_SYMBOL(pci_register_set_vga_state); | ||
| 3011 | EXPORT_SYMBOL(pci_release_regions); | 3023 | EXPORT_SYMBOL(pci_release_regions); |
| 3012 | EXPORT_SYMBOL(pci_request_regions); | 3024 | EXPORT_SYMBOL(pci_request_regions); |
| 3013 | EXPORT_SYMBOL(pci_request_regions_exclusive); | 3025 | EXPORT_SYMBOL(pci_request_regions_exclusive); |
| @@ -3023,8 +3035,6 @@ EXPORT_SYMBOL(pci_set_mwi); | |||
| 3023 | EXPORT_SYMBOL(pci_try_set_mwi); | 3035 | EXPORT_SYMBOL(pci_try_set_mwi); |
| 3024 | EXPORT_SYMBOL(pci_clear_mwi); | 3036 | EXPORT_SYMBOL(pci_clear_mwi); |
| 3025 | EXPORT_SYMBOL_GPL(pci_intx); | 3037 | EXPORT_SYMBOL_GPL(pci_intx); |
| 3026 | EXPORT_SYMBOL(pci_set_dma_mask); | ||
| 3027 | EXPORT_SYMBOL(pci_set_consistent_dma_mask); | ||
| 3028 | EXPORT_SYMBOL(pci_assign_resource); | 3038 | EXPORT_SYMBOL(pci_assign_resource); |
| 3029 | EXPORT_SYMBOL(pci_find_parent_resource); | 3039 | EXPORT_SYMBOL(pci_find_parent_resource); |
| 3030 | EXPORT_SYMBOL(pci_select_bars); | 3040 | EXPORT_SYMBOL(pci_select_bars); |
