diff options
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 87 |
1 files changed, 53 insertions, 34 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 1b27b5af3d55..e7982af9a5d8 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -890,8 +890,8 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
890 | 890 | ||
891 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); | 891 | pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); |
892 | dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); | 892 | dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); |
893 | if (dev->current_state != state && printk_ratelimit()) | 893 | if (dev->current_state != state) |
894 | pci_info(dev, "Refused to change power state, currently in D%d\n", | 894 | pci_info_ratelimited(dev, "Refused to change power state, currently in D%d\n", |
895 | dev->current_state); | 895 | dev->current_state); |
896 | 896 | ||
897 | /* | 897 | /* |
@@ -1443,7 +1443,7 @@ static void pci_restore_rebar_state(struct pci_dev *pdev) | |||
1443 | pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl); | 1443 | pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl); |
1444 | bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX; | 1444 | bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX; |
1445 | res = pdev->resource + bar_idx; | 1445 | res = pdev->resource + bar_idx; |
1446 | size = order_base_2((resource_size(res) >> 20) | 1) - 1; | 1446 | size = ilog2(resource_size(res)) - 20; |
1447 | ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE; | 1447 | ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE; |
1448 | ctrl |= size << PCI_REBAR_CTRL_BAR_SHIFT; | 1448 | ctrl |= size << PCI_REBAR_CTRL_BAR_SHIFT; |
1449 | pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl); | 1449 | pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl); |
@@ -3581,7 +3581,7 @@ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask) | |||
3581 | } | 3581 | } |
3582 | 3582 | ||
3583 | /* Ensure upstream ports don't block AtomicOps on egress */ | 3583 | /* Ensure upstream ports don't block AtomicOps on egress */ |
3584 | if (!bridge->has_secondary_link) { | 3584 | if (pci_pcie_type(bridge) == PCI_EXP_TYPE_UPSTREAM) { |
3585 | pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2, | 3585 | pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2, |
3586 | &ctl2); | 3586 | &ctl2); |
3587 | if (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK) | 3587 | if (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK) |
@@ -5923,8 +5923,19 @@ resource_size_t __weak pcibios_default_alignment(void) | |||
5923 | return 0; | 5923 | return 0; |
5924 | } | 5924 | } |
5925 | 5925 | ||
5926 | #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE | 5926 | /* |
5927 | static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; | 5927 | * Arches that don't want to expose struct resource to userland as-is in |
5928 | * sysfs and /proc can implement their own pci_resource_to_user(). | ||
5929 | */ | ||
5930 | void __weak pci_resource_to_user(const struct pci_dev *dev, int bar, | ||
5931 | const struct resource *rsrc, | ||
5932 | resource_size_t *start, resource_size_t *end) | ||
5933 | { | ||
5934 | *start = rsrc->start; | ||
5935 | *end = rsrc->end; | ||
5936 | } | ||
5937 | |||
5938 | static char *resource_alignment_param; | ||
5928 | static DEFINE_SPINLOCK(resource_alignment_lock); | 5939 | static DEFINE_SPINLOCK(resource_alignment_lock); |
5929 | 5940 | ||
5930 | /** | 5941 | /** |
@@ -5945,7 +5956,7 @@ static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev, | |||
5945 | 5956 | ||
5946 | spin_lock(&resource_alignment_lock); | 5957 | spin_lock(&resource_alignment_lock); |
5947 | p = resource_alignment_param; | 5958 | p = resource_alignment_param; |
5948 | if (!*p && !align) | 5959 | if (!p || !*p) |
5949 | goto out; | 5960 | goto out; |
5950 | if (pci_has_flag(PCI_PROBE_ONLY)) { | 5961 | if (pci_has_flag(PCI_PROBE_ONLY)) { |
5951 | align = 0; | 5962 | align = 0; |
@@ -6109,35 +6120,41 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev) | |||
6109 | } | 6120 | } |
6110 | } | 6121 | } |
6111 | 6122 | ||
6112 | static ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) | 6123 | static ssize_t resource_alignment_show(struct bus_type *bus, char *buf) |
6113 | { | 6124 | { |
6114 | if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) | 6125 | size_t count = 0; |
6115 | count = RESOURCE_ALIGNMENT_PARAM_SIZE - 1; | ||
6116 | spin_lock(&resource_alignment_lock); | ||
6117 | strncpy(resource_alignment_param, buf, count); | ||
6118 | resource_alignment_param[count] = '\0'; | ||
6119 | spin_unlock(&resource_alignment_lock); | ||
6120 | return count; | ||
6121 | } | ||
6122 | 6126 | ||
6123 | static ssize_t pci_get_resource_alignment_param(char *buf, size_t size) | ||
6124 | { | ||
6125 | size_t count; | ||
6126 | spin_lock(&resource_alignment_lock); | 6127 | spin_lock(&resource_alignment_lock); |
6127 | count = snprintf(buf, size, "%s", resource_alignment_param); | 6128 | if (resource_alignment_param) |
6129 | count = snprintf(buf, PAGE_SIZE, "%s", resource_alignment_param); | ||
6128 | spin_unlock(&resource_alignment_lock); | 6130 | spin_unlock(&resource_alignment_lock); |
6129 | return count; | ||
6130 | } | ||
6131 | 6131 | ||
6132 | static ssize_t resource_alignment_show(struct bus_type *bus, char *buf) | 6132 | /* |
6133 | { | 6133 | * When set by the command line, resource_alignment_param will not |
6134 | return pci_get_resource_alignment_param(buf, PAGE_SIZE); | 6134 | * have a trailing line feed, which is ugly. So conditionally add |
6135 | * it here. | ||
6136 | */ | ||
6137 | if (count >= 2 && buf[count - 2] != '\n' && count < PAGE_SIZE - 1) { | ||
6138 | buf[count - 1] = '\n'; | ||
6139 | buf[count++] = 0; | ||
6140 | } | ||
6141 | |||
6142 | return count; | ||
6135 | } | 6143 | } |
6136 | 6144 | ||
6137 | static ssize_t resource_alignment_store(struct bus_type *bus, | 6145 | static ssize_t resource_alignment_store(struct bus_type *bus, |
6138 | const char *buf, size_t count) | 6146 | const char *buf, size_t count) |
6139 | { | 6147 | { |
6140 | return pci_set_resource_alignment_param(buf, count); | 6148 | char *param = kstrndup(buf, count, GFP_KERNEL); |
6149 | |||
6150 | if (!param) | ||
6151 | return -ENOMEM; | ||
6152 | |||
6153 | spin_lock(&resource_alignment_lock); | ||
6154 | kfree(resource_alignment_param); | ||
6155 | resource_alignment_param = param; | ||
6156 | spin_unlock(&resource_alignment_lock); | ||
6157 | return count; | ||
6141 | } | 6158 | } |
6142 | 6159 | ||
6143 | static BUS_ATTR_RW(resource_alignment); | 6160 | static BUS_ATTR_RW(resource_alignment); |
@@ -6266,8 +6283,7 @@ static int __init pci_setup(char *str) | |||
6266 | } else if (!strncmp(str, "cbmemsize=", 10)) { | 6283 | } else if (!strncmp(str, "cbmemsize=", 10)) { |
6267 | pci_cardbus_mem_size = memparse(str + 10, &str); | 6284 | pci_cardbus_mem_size = memparse(str + 10, &str); |
6268 | } else if (!strncmp(str, "resource_alignment=", 19)) { | 6285 | } else if (!strncmp(str, "resource_alignment=", 19)) { |
6269 | pci_set_resource_alignment_param(str + 19, | 6286 | resource_alignment_param = str + 19; |
6270 | strlen(str + 19)); | ||
6271 | } else if (!strncmp(str, "ecrc=", 5)) { | 6287 | } else if (!strncmp(str, "ecrc=", 5)) { |
6272 | pcie_ecrc_get_policy(str + 5); | 6288 | pcie_ecrc_get_policy(str + 5); |
6273 | } else if (!strncmp(str, "hpiosize=", 9)) { | 6289 | } else if (!strncmp(str, "hpiosize=", 9)) { |
@@ -6302,15 +6318,18 @@ static int __init pci_setup(char *str) | |||
6302 | early_param("pci", pci_setup); | 6318 | early_param("pci", pci_setup); |
6303 | 6319 | ||
6304 | /* | 6320 | /* |
6305 | * 'disable_acs_redir_param' is initialized in pci_setup(), above, to point | 6321 | * 'resource_alignment_param' and 'disable_acs_redir_param' are initialized |
6306 | * to data in the __initdata section which will be freed after the init | 6322 | * in pci_setup(), above, to point to data in the __initdata section which |
6307 | * sequence is complete. We can't allocate memory in pci_setup() because some | 6323 | * will be freed after the init sequence is complete. We can't allocate memory |
6308 | * architectures do not have any memory allocation service available during | 6324 | * in pci_setup() because some architectures do not have any memory allocation |
6309 | * an early_param() call. So we allocate memory and copy the variable here | 6325 | * service available during an early_param() call. So we allocate memory and |
6310 | * before the init section is freed. | 6326 | * copy the variable here before the init section is freed. |
6327 | * | ||
6311 | */ | 6328 | */ |
6312 | static int __init pci_realloc_setup_params(void) | 6329 | static int __init pci_realloc_setup_params(void) |
6313 | { | 6330 | { |
6331 | resource_alignment_param = kstrdup(resource_alignment_param, | ||
6332 | GFP_KERNEL); | ||
6314 | disable_acs_redir_param = kstrdup(disable_acs_redir_param, GFP_KERNEL); | 6333 | disable_acs_redir_param = kstrdup(disable_acs_redir_param, GFP_KERNEL); |
6315 | 6334 | ||
6316 | return 0; | 6335 | return 0; |