diff options
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 08a95b369d85..0ce67423a0a3 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -77,6 +77,8 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE; | |||
77 | unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE; | 77 | unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE; |
78 | unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE; | 78 | unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE; |
79 | 79 | ||
80 | enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PERFORMANCE; | ||
81 | |||
80 | /* | 82 | /* |
81 | * The default CLS is used if arch didn't set CLS explicitly and not | 83 | * The default CLS is used if arch didn't set CLS explicitly and not |
82 | * all pci devices agree on the same value. Arch can override either | 84 | * all pci devices agree on the same value. Arch can override either |
@@ -3223,6 +3225,67 @@ out: | |||
3223 | EXPORT_SYMBOL(pcie_set_readrq); | 3225 | EXPORT_SYMBOL(pcie_set_readrq); |
3224 | 3226 | ||
3225 | /** | 3227 | /** |
3228 | * pcie_get_mps - get PCI Express maximum payload size | ||
3229 | * @dev: PCI device to query | ||
3230 | * | ||
3231 | * Returns maximum payload size in bytes | ||
3232 | * or appropriate error value. | ||
3233 | */ | ||
3234 | int pcie_get_mps(struct pci_dev *dev) | ||
3235 | { | ||
3236 | int ret, cap; | ||
3237 | u16 ctl; | ||
3238 | |||
3239 | cap = pci_pcie_cap(dev); | ||
3240 | if (!cap) | ||
3241 | return -EINVAL; | ||
3242 | |||
3243 | ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl); | ||
3244 | if (!ret) | ||
3245 | ret = 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); | ||
3246 | |||
3247 | return ret; | ||
3248 | } | ||
3249 | |||
3250 | /** | ||
3251 | * pcie_set_mps - set PCI Express maximum payload size | ||
3252 | * @dev: PCI device to query | ||
3253 | * @mps: maximum payload size in bytes | ||
3254 | * valid values are 128, 256, 512, 1024, 2048, 4096 | ||
3255 | * | ||
3256 | * If possible sets maximum payload size | ||
3257 | */ | ||
3258 | int pcie_set_mps(struct pci_dev *dev, int mps) | ||
3259 | { | ||
3260 | int cap, err = -EINVAL; | ||
3261 | u16 ctl, v; | ||
3262 | |||
3263 | if (mps < 128 || mps > 4096 || !is_power_of_2(mps)) | ||
3264 | goto out; | ||
3265 | |||
3266 | v = ffs(mps) - 8; | ||
3267 | if (v > dev->pcie_mpss) | ||
3268 | goto out; | ||
3269 | v <<= 5; | ||
3270 | |||
3271 | cap = pci_pcie_cap(dev); | ||
3272 | if (!cap) | ||
3273 | goto out; | ||
3274 | |||
3275 | err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl); | ||
3276 | if (err) | ||
3277 | goto out; | ||
3278 | |||
3279 | if ((ctl & PCI_EXP_DEVCTL_PAYLOAD) != v) { | ||
3280 | ctl &= ~PCI_EXP_DEVCTL_PAYLOAD; | ||
3281 | ctl |= v; | ||
3282 | err = pci_write_config_word(dev, cap + PCI_EXP_DEVCTL, ctl); | ||
3283 | } | ||
3284 | out: | ||
3285 | return err; | ||
3286 | } | ||
3287 | |||
3288 | /** | ||
3226 | * pci_select_bars - Make BAR mask from the type of resource | 3289 | * pci_select_bars - Make BAR mask from the type of resource |
3227 | * @dev: the PCI device for which BAR mask is made | 3290 | * @dev: the PCI device for which BAR mask is made |
3228 | * @flags: resource type mask to be selected | 3291 | * @flags: resource type mask to be selected |
@@ -3505,6 +3568,10 @@ static int __init pci_setup(char *str) | |||
3505 | pci_hotplug_io_size = memparse(str + 9, &str); | 3568 | pci_hotplug_io_size = memparse(str + 9, &str); |
3506 | } else if (!strncmp(str, "hpmemsize=", 10)) { | 3569 | } else if (!strncmp(str, "hpmemsize=", 10)) { |
3507 | pci_hotplug_mem_size = memparse(str + 10, &str); | 3570 | pci_hotplug_mem_size = memparse(str + 10, &str); |
3571 | } else if (!strncmp(str, "pcie_bus_safe", 13)) { | ||
3572 | pcie_bus_config = PCIE_BUS_SAFE; | ||
3573 | } else if (!strncmp(str, "pcie_bus_perf", 13)) { | ||
3574 | pcie_bus_config = PCIE_BUS_PERFORMANCE; | ||
3508 | } else { | 3575 | } else { |
3509 | printk(KERN_ERR "PCI: Unknown option `%s'\n", | 3576 | printk(KERN_ERR "PCI: Unknown option `%s'\n", |
3510 | str); | 3577 | str); |