diff options
| author | Dmitry Torokhov <dtor@insightbb.com> | 2007-05-01 00:24:54 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dtor@insightbb.com> | 2007-05-01 00:24:54 -0400 |
| commit | bc95f3669f5e6f63cf0b84fe4922c3c6dd4aa775 (patch) | |
| tree | 427fcf2a7287c16d4b5aa6cbf494d59579a6a8b1 /drivers/pci/pci.c | |
| parent | 3d29cdff999c37b3876082278a8134a0642a02cd (diff) | |
| parent | dc87c3985e9b442c60994308a96f887579addc39 (diff) | |
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/usb/input/Makefile
drivers/usb/input/gtco.c
Diffstat (limited to 'drivers/pci/pci.c')
| -rw-r--r-- | drivers/pci/pci.c | 133 |
1 files changed, 93 insertions, 40 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 8b44cff2c176..2a458279327a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
| 16 | #include <linux/pm.h> | ||
| 16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 17 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
| 18 | #include <linux/string.h> | 19 | #include <linux/string.h> |
| @@ -21,6 +22,12 @@ | |||
| 21 | 22 | ||
| 22 | unsigned int pci_pm_d3_delay = 10; | 23 | unsigned int pci_pm_d3_delay = 10; |
| 23 | 24 | ||
| 25 | #define DEFAULT_CARDBUS_IO_SIZE (256) | ||
| 26 | #define DEFAULT_CARDBUS_MEM_SIZE (64*1024*1024) | ||
| 27 | /* pci=cbmemsize=nnM,cbiosize=nn can override this */ | ||
| 28 | unsigned long pci_cardbus_io_size = DEFAULT_CARDBUS_IO_SIZE; | ||
| 29 | unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE; | ||
| 30 | |||
| 24 | /** | 31 | /** |
| 25 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children | 32 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children |
| 26 | * @bus: pointer to PCI bus structure to search | 33 | * @bus: pointer to PCI bus structure to search |
| @@ -545,7 +552,9 @@ static int pci_save_pcie_state(struct pci_dev *dev) | |||
| 545 | if (pos <= 0) | 552 | if (pos <= 0) |
| 546 | return 0; | 553 | return 0; |
| 547 | 554 | ||
| 548 | save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL); | 555 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); |
| 556 | if (!save_state) | ||
| 557 | save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL); | ||
| 549 | if (!save_state) { | 558 | if (!save_state) { |
| 550 | dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); | 559 | dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); |
| 551 | return -ENOMEM; | 560 | return -ENOMEM; |
| @@ -576,8 +585,6 @@ static void pci_restore_pcie_state(struct pci_dev *dev) | |||
| 576 | pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]); | 585 | pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]); |
| 577 | pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]); | 586 | pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]); |
| 578 | pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]); | 587 | pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]); |
| 579 | pci_remove_saved_cap(save_state); | ||
| 580 | kfree(save_state); | ||
| 581 | } | 588 | } |
| 582 | 589 | ||
| 583 | 590 | ||
| @@ -591,7 +598,9 @@ static int pci_save_pcix_state(struct pci_dev *dev) | |||
| 591 | if (pos <= 0) | 598 | if (pos <= 0) |
| 592 | return 0; | 599 | return 0; |
| 593 | 600 | ||
| 594 | save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL); | 601 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); |
| 602 | if (!save_state) | ||
| 603 | save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL); | ||
| 595 | if (!save_state) { | 604 | if (!save_state) { |
| 596 | dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); | 605 | dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); |
| 597 | return -ENOMEM; | 606 | return -ENOMEM; |
| @@ -616,8 +625,6 @@ static void pci_restore_pcix_state(struct pci_dev *dev) | |||
| 616 | cap = (u16 *)&save_state->data[0]; | 625 | cap = (u16 *)&save_state->data[0]; |
| 617 | 626 | ||
| 618 | pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]); | 627 | pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]); |
| 619 | pci_remove_saved_cap(save_state); | ||
| 620 | kfree(save_state); | ||
| 621 | } | 628 | } |
| 622 | 629 | ||
| 623 | 630 | ||
| @@ -632,8 +639,6 @@ pci_save_state(struct pci_dev *dev) | |||
| 632 | /* XXX: 100% dword access ok here? */ | 639 | /* XXX: 100% dword access ok here? */ |
| 633 | for (i = 0; i < 16; i++) | 640 | for (i = 0; i < 16; i++) |
| 634 | pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); | 641 | pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); |
| 635 | if ((i = pci_save_msi_state(dev)) != 0) | ||
| 636 | return i; | ||
| 637 | if ((i = pci_save_pcie_state(dev)) != 0) | 642 | if ((i = pci_save_pcie_state(dev)) != 0) |
| 638 | return i; | 643 | return i; |
| 639 | if ((i = pci_save_pcix_state(dev)) != 0) | 644 | if ((i = pci_save_pcix_state(dev)) != 0) |
| @@ -751,7 +756,8 @@ int pci_enable_device(struct pci_dev *dev) | |||
| 751 | * when a device is enabled using managed PCI device enable interface. | 756 | * when a device is enabled using managed PCI device enable interface. |
| 752 | */ | 757 | */ |
| 753 | struct pci_devres { | 758 | struct pci_devres { |
| 754 | unsigned int disable:1; | 759 | unsigned int enabled:1; |
| 760 | unsigned int pinned:1; | ||
| 755 | unsigned int orig_intx:1; | 761 | unsigned int orig_intx:1; |
| 756 | unsigned int restore_intx:1; | 762 | unsigned int restore_intx:1; |
| 757 | u32 region_mask; | 763 | u32 region_mask; |
| @@ -775,7 +781,7 @@ static void pcim_release(struct device *gendev, void *res) | |||
| 775 | if (this->restore_intx) | 781 | if (this->restore_intx) |
| 776 | pci_intx(dev, this->orig_intx); | 782 | pci_intx(dev, this->orig_intx); |
| 777 | 783 | ||
| 778 | if (this->disable) | 784 | if (this->enabled && !this->pinned) |
| 779 | pci_disable_device(dev); | 785 | pci_disable_device(dev); |
| 780 | } | 786 | } |
| 781 | 787 | ||
| @@ -814,12 +820,12 @@ int pcim_enable_device(struct pci_dev *pdev) | |||
| 814 | dr = get_pci_dr(pdev); | 820 | dr = get_pci_dr(pdev); |
| 815 | if (unlikely(!dr)) | 821 | if (unlikely(!dr)) |
| 816 | return -ENOMEM; | 822 | return -ENOMEM; |
| 817 | WARN_ON(!!dr->disable); | 823 | WARN_ON(!!dr->enabled); |
| 818 | 824 | ||
| 819 | rc = pci_enable_device(pdev); | 825 | rc = pci_enable_device(pdev); |
| 820 | if (!rc) { | 826 | if (!rc) { |
| 821 | pdev->is_managed = 1; | 827 | pdev->is_managed = 1; |
| 822 | dr->disable = 1; | 828 | dr->enabled = 1; |
| 823 | } | 829 | } |
| 824 | return rc; | 830 | return rc; |
| 825 | } | 831 | } |
| @@ -837,9 +843,9 @@ void pcim_pin_device(struct pci_dev *pdev) | |||
| 837 | struct pci_devres *dr; | 843 | struct pci_devres *dr; |
| 838 | 844 | ||
| 839 | dr = find_pci_dr(pdev); | 845 | dr = find_pci_dr(pdev); |
| 840 | WARN_ON(!dr || !dr->disable); | 846 | WARN_ON(!dr || !dr->enabled); |
| 841 | if (dr) | 847 | if (dr) |
| 842 | dr->disable = 0; | 848 | dr->pinned = 1; |
| 843 | } | 849 | } |
| 844 | 850 | ||
| 845 | /** | 851 | /** |
| @@ -870,18 +876,11 @@ pci_disable_device(struct pci_dev *dev) | |||
| 870 | 876 | ||
| 871 | dr = find_pci_dr(dev); | 877 | dr = find_pci_dr(dev); |
| 872 | if (dr) | 878 | if (dr) |
| 873 | dr->disable = 0; | 879 | dr->enabled = 0; |
| 874 | 880 | ||
| 875 | if (atomic_sub_return(1, &dev->enable_cnt) != 0) | 881 | if (atomic_sub_return(1, &dev->enable_cnt) != 0) |
| 876 | return; | 882 | return; |
| 877 | 883 | ||
| 878 | if (dev->msi_enabled) | ||
| 879 | disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), | ||
| 880 | PCI_CAP_ID_MSI); | ||
| 881 | if (dev->msix_enabled) | ||
| 882 | disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), | ||
| 883 | PCI_CAP_ID_MSIX); | ||
| 884 | |||
| 885 | pci_read_config_word(dev, PCI_COMMAND, &pci_command); | 884 | pci_read_config_word(dev, PCI_COMMAND, &pci_command); |
| 886 | if (pci_command & PCI_COMMAND_MASTER) { | 885 | if (pci_command & PCI_COMMAND_MASTER) { |
| 887 | pci_command &= ~PCI_COMMAND_MASTER; | 886 | pci_command &= ~PCI_COMMAND_MASTER; |
| @@ -893,31 +892,48 @@ pci_disable_device(struct pci_dev *dev) | |||
| 893 | } | 892 | } |
| 894 | 893 | ||
| 895 | /** | 894 | /** |
| 896 | * pci_enable_wake - enable device to generate PME# when suspended | 895 | * pci_enable_wake - enable PCI device as wakeup event source |
| 897 | * @dev: - PCI device to operate on | 896 | * @dev: PCI device affected |
| 898 | * @state: - Current state of device. | 897 | * @state: PCI state from which device will issue wakeup events |
| 899 | * @enable: - Flag to enable or disable generation | 898 | * @enable: True to enable event generation; false to disable |
| 900 | * | ||
| 901 | * Set the bits in the device's PM Capabilities to generate PME# when | ||
| 902 | * the system is suspended. | ||
| 903 | * | 899 | * |
| 904 | * -EIO is returned if device doesn't have PM Capabilities. | 900 | * This enables the device as a wakeup event source, or disables it. |
| 905 | * -EINVAL is returned if device supports it, but can't generate wake events. | 901 | * When such events involves platform-specific hooks, those hooks are |
| 906 | * 0 if operation is successful. | 902 | * called automatically by this routine. |
| 907 | * | 903 | * |
| 904 | * Devices with legacy power management (no standard PCI PM capabilities) | ||
| 905 | * always require such platform hooks. Depending on the platform, devices | ||
| 906 | * supporting the standard PCI PME# signal may require such platform hooks; | ||
| 907 | * they always update bits in config space to allow PME# generation. | ||
| 908 | * | ||
| 909 | * -EIO is returned if the device can't ever be a wakeup event source. | ||
| 910 | * -EINVAL is returned if the device can't generate wakeup events from | ||
| 911 | * the specified PCI state. Returns zero if the operation is successful. | ||
| 908 | */ | 912 | */ |
| 909 | int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) | 913 | int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) |
| 910 | { | 914 | { |
| 911 | int pm; | 915 | int pm; |
| 916 | int status; | ||
| 912 | u16 value; | 917 | u16 value; |
| 913 | 918 | ||
| 919 | /* Note that drivers should verify device_may_wakeup(&dev->dev) | ||
| 920 | * before calling this function. Platform code should report | ||
| 921 | * errors when drivers try to enable wakeup on devices that | ||
| 922 | * can't issue wakeups, or on which wakeups were disabled by | ||
| 923 | * userspace updating the /sys/devices.../power/wakeup file. | ||
| 924 | */ | ||
| 925 | |||
| 926 | status = call_platform_enable_wakeup(&dev->dev, enable); | ||
| 927 | |||
| 914 | /* find PCI PM capability in list */ | 928 | /* find PCI PM capability in list */ |
| 915 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); | 929 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); |
| 916 | 930 | ||
| 917 | /* If device doesn't support PM Capabilities, but request is to disable | 931 | /* If device doesn't support PM Capabilities, but caller wants to |
| 918 | * wake events, it's a nop; otherwise fail */ | 932 | * disable wake events, it's a NOP. Otherwise fail unless the |
| 919 | if (!pm) | 933 | * platform hooks handled this legacy device already. |
| 920 | return enable ? -EIO : 0; | 934 | */ |
| 935 | if (!pm) | ||
| 936 | return enable ? status : 0; | ||
| 921 | 937 | ||
| 922 | /* Check device's ability to generate PME# */ | 938 | /* Check device's ability to generate PME# */ |
| 923 | pci_read_config_word(dev,pm+PCI_PM_PMC,&value); | 939 | pci_read_config_word(dev,pm+PCI_PM_PMC,&value); |
| @@ -926,8 +942,14 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) | |||
| 926 | value >>= ffs(PCI_PM_CAP_PME_MASK) - 1; /* First bit of mask */ | 942 | value >>= ffs(PCI_PM_CAP_PME_MASK) - 1; /* First bit of mask */ |
| 927 | 943 | ||
| 928 | /* Check if it can generate PME# from requested state. */ | 944 | /* Check if it can generate PME# from requested state. */ |
| 929 | if (!value || !(value & (1 << state))) | 945 | if (!value || !(value & (1 << state))) { |
| 946 | /* if it can't, revert what the platform hook changed, | ||
| 947 | * always reporting the base "EINVAL, can't PME#" error | ||
| 948 | */ | ||
| 949 | if (enable) | ||
| 950 | call_platform_enable_wakeup(&dev->dev, 0); | ||
| 930 | return enable ? -EINVAL : 0; | 951 | return enable ? -EINVAL : 0; |
| 952 | } | ||
| 931 | 953 | ||
| 932 | pci_read_config_word(dev, pm + PCI_PM_CTRL, &value); | 954 | pci_read_config_word(dev, pm + PCI_PM_CTRL, &value); |
| 933 | 955 | ||
| @@ -938,7 +960,7 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) | |||
| 938 | value &= ~PCI_PM_CTRL_PME_ENABLE; | 960 | value &= ~PCI_PM_CTRL_PME_ENABLE; |
| 939 | 961 | ||
| 940 | pci_write_config_word(dev, pm + PCI_PM_CTRL, value); | 962 | pci_write_config_word(dev, pm + PCI_PM_CTRL, value); |
| 941 | 963 | ||
| 942 | return 0; | 964 | return 0; |
| 943 | } | 965 | } |
| 944 | 966 | ||
| @@ -1271,6 +1293,33 @@ pci_intx(struct pci_dev *pdev, int enable) | |||
| 1271 | } | 1293 | } |
| 1272 | } | 1294 | } |
| 1273 | 1295 | ||
| 1296 | /** | ||
| 1297 | * pci_msi_off - disables any msi or msix capabilities | ||
| 1298 | * @pdev: the PCI device to operate on | ||
| 1299 | * | ||
| 1300 | * If you want to use msi see pci_enable_msi and friends. | ||
| 1301 | * This is a lower level primitive that allows us to disable | ||
| 1302 | * msi operation at the device level. | ||
| 1303 | */ | ||
| 1304 | void pci_msi_off(struct pci_dev *dev) | ||
| 1305 | { | ||
| 1306 | int pos; | ||
| 1307 | u16 control; | ||
| 1308 | |||
| 1309 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | ||
| 1310 | if (pos) { | ||
| 1311 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); | ||
| 1312 | control &= ~PCI_MSI_FLAGS_ENABLE; | ||
| 1313 | pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); | ||
| 1314 | } | ||
| 1315 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | ||
| 1316 | if (pos) { | ||
| 1317 | pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); | ||
| 1318 | control &= ~PCI_MSIX_FLAGS_ENABLE; | ||
| 1319 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | ||
| 1320 | } | ||
| 1321 | } | ||
| 1322 | |||
| 1274 | #ifndef HAVE_ARCH_PCI_SET_DMA_MASK | 1323 | #ifndef HAVE_ARCH_PCI_SET_DMA_MASK |
| 1275 | /* | 1324 | /* |
| 1276 | * These can be overridden by arch-specific implementations | 1325 | * These can be overridden by arch-specific implementations |
| @@ -1300,7 +1349,7 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) | |||
| 1300 | 1349 | ||
| 1301 | /** | 1350 | /** |
| 1302 | * pci_select_bars - Make BAR mask from the type of resource | 1351 | * pci_select_bars - Make BAR mask from the type of resource |
| 1303 | * @pdev: the PCI device for which BAR mask is made | 1352 | * @dev: the PCI device for which BAR mask is made |
| 1304 | * @flags: resource type mask to be selected | 1353 | * @flags: resource type mask to be selected |
| 1305 | * | 1354 | * |
| 1306 | * This helper routine makes bar mask from the type of resource. | 1355 | * This helper routine makes bar mask from the type of resource. |
| @@ -1333,6 +1382,10 @@ static int __devinit pci_setup(char *str) | |||
| 1333 | if (*str && (str = pcibios_setup(str)) && *str) { | 1382 | if (*str && (str = pcibios_setup(str)) && *str) { |
| 1334 | if (!strcmp(str, "nomsi")) { | 1383 | if (!strcmp(str, "nomsi")) { |
| 1335 | pci_no_msi(); | 1384 | pci_no_msi(); |
| 1385 | } else if (!strncmp(str, "cbiosize=", 9)) { | ||
| 1386 | pci_cardbus_io_size = memparse(str + 9, &str); | ||
| 1387 | } else if (!strncmp(str, "cbmemsize=", 10)) { | ||
| 1388 | pci_cardbus_mem_size = memparse(str + 10, &str); | ||
| 1336 | } else { | 1389 | } else { |
| 1337 | printk(KERN_ERR "PCI: Unknown option `%s'\n", | 1390 | printk(KERN_ERR "PCI: Unknown option `%s'\n", |
| 1338 | str); | 1391 | str); |
