diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 15:14:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 15:14:47 -0500 |
commit | 193c0d682525987db59ac3a24531a77e4947aa95 (patch) | |
tree | 7b58346171c4d07e2c2ee6c3c469c325495149a4 /drivers/pci/iov.c | |
parent | 8b0cab14951fbf8126795ab301835a8f8126a988 (diff) | |
parent | 1cb73f8c479e66541fefd3f7fa547b1fa56cdc54 (diff) |
Merge tag 'for-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI update from Bjorn Helgaas:
"Host bridge hotplug:
- Untangle _PRT from struct pci_bus (Bjorn Helgaas)
- Request _OSC control before scanning root bus (Taku Izumi)
- Assign resources when adding host bridge (Yinghai Lu)
- Remove root bus when removing host bridge (Yinghai Lu)
- Remove _PRT during hot remove (Yinghai Lu)
SRIOV
- Add sysfs knobs to control numVFs (Don Dutile)
Power management
- Notify devices when power resource turned on (Huang Ying)
Bug fixes
- Work around broken _SEG on HP xw9300 (Bjorn Helgaas)
- Keep runtime PM enabled for unbound PCI devices (Huang Ying)
- Fix Optimus dual-GPU runtime D3 suspend issue (Dave Airlie)
- Fix xen frontend shutdown issue (David Vrabel)
- Work around PLX PCI 9050 BAR alignment erratum (Ian Abbott)
Miscellaneous
- Add GPL license for drivers/pci/ioapic (Andrew Cooks)
- Add standard PCI-X, PCIe ASPM register #defines (Bjorn Helgaas)
- NumaChip remote PCI support (Daniel Blueman)
- Fix PCIe Link Capabilities Supported Link Speed definition (Jingoo
Han)
- Convert dev_printk() to dev_info(), etc (Joe Perches)
- Add support for non PCI BAR ROM data (Matthew Garrett)
- Add x86 support for host bridge translation offset (Mike Yoknis)
- Report success only when every driver supports AER (Vijay
Pandarathil)"
Fix up trivial conflicts.
* tag 'for-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (48 commits)
PCI: Use phys_addr_t for physical ROM address
x86/PCI: Add NumaChip remote PCI support
ath9k: Use standard #defines for PCIe Capability ASPM fields
iwlwifi: Use standard #defines for PCIe Capability ASPM fields
iwlwifi: collapse wrapper for pcie_capability_read_word()
iwlegacy: Use standard #defines for PCIe Capability ASPM fields
iwlegacy: collapse wrapper for pcie_capability_read_word()
cxgb3: Use standard #defines for PCIe Capability ASPM fields
PCI: Add standard PCIe Capability Link ASPM field names
PCI/portdrv: Use PCI Express Capability accessors
PCI: Use standard PCIe Capability Link register field names
x86: Use PCI setup data
PCI: Add support for non-BAR ROMs
PCI: Add pcibios_add_device
EFI: Stash ROMs if they're not in the PCI BAR
PCI: Add and use standard PCI-X Capability register names
PCI/PM: Keep runtime PM enabled for unbound PCI devices
xen-pcifront: Handle backend CLOSED without CLOSING
PCI: SRIOV control and status via sysfs (documentation)
PCI/AER: Report success only when every device has AER-aware driver
...
Diffstat (limited to 'drivers/pci/iov.c')
-rw-r--r-- | drivers/pci/iov.c | 87 |
1 files changed, 67 insertions, 20 deletions
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index aeccc911abb8..bafd2bbcaf65 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -106,7 +106,7 @@ static int virtfn_add(struct pci_dev *dev, int id, int reset) | |||
106 | virtfn->resource[i].name = pci_name(virtfn); | 106 | virtfn->resource[i].name = pci_name(virtfn); |
107 | virtfn->resource[i].flags = res->flags; | 107 | virtfn->resource[i].flags = res->flags; |
108 | size = resource_size(res); | 108 | size = resource_size(res); |
109 | do_div(size, iov->total); | 109 | do_div(size, iov->total_VFs); |
110 | virtfn->resource[i].start = res->start + size * id; | 110 | virtfn->resource[i].start = res->start + size * id; |
111 | virtfn->resource[i].end = virtfn->resource[i].start + size - 1; | 111 | virtfn->resource[i].end = virtfn->resource[i].start + size - 1; |
112 | rc = request_resource(res, &virtfn->resource[i]); | 112 | rc = request_resource(res, &virtfn->resource[i]); |
@@ -194,7 +194,7 @@ static int sriov_migration(struct pci_dev *dev) | |||
194 | u16 status; | 194 | u16 status; |
195 | struct pci_sriov *iov = dev->sriov; | 195 | struct pci_sriov *iov = dev->sriov; |
196 | 196 | ||
197 | if (!iov->nr_virtfn) | 197 | if (!iov->num_VFs) |
198 | return 0; | 198 | return 0; |
199 | 199 | ||
200 | if (!(iov->cap & PCI_SRIOV_CAP_VFM)) | 200 | if (!(iov->cap & PCI_SRIOV_CAP_VFM)) |
@@ -216,7 +216,7 @@ static void sriov_migration_task(struct work_struct *work) | |||
216 | u16 status; | 216 | u16 status; |
217 | struct pci_sriov *iov = container_of(work, struct pci_sriov, mtask); | 217 | struct pci_sriov *iov = container_of(work, struct pci_sriov, mtask); |
218 | 218 | ||
219 | for (i = iov->initial; i < iov->nr_virtfn; i++) { | 219 | for (i = iov->initial_VFs; i < iov->num_VFs; i++) { |
220 | state = readb(iov->mstate + i); | 220 | state = readb(iov->mstate + i); |
221 | if (state == PCI_SRIOV_VFM_MI) { | 221 | if (state == PCI_SRIOV_VFM_MI) { |
222 | writeb(PCI_SRIOV_VFM_AV, iov->mstate + i); | 222 | writeb(PCI_SRIOV_VFM_AV, iov->mstate + i); |
@@ -244,7 +244,7 @@ static int sriov_enable_migration(struct pci_dev *dev, int nr_virtfn) | |||
244 | resource_size_t pa; | 244 | resource_size_t pa; |
245 | struct pci_sriov *iov = dev->sriov; | 245 | struct pci_sriov *iov = dev->sriov; |
246 | 246 | ||
247 | if (nr_virtfn <= iov->initial) | 247 | if (nr_virtfn <= iov->initial_VFs) |
248 | return 0; | 248 | return 0; |
249 | 249 | ||
250 | pci_read_config_dword(dev, iov->pos + PCI_SRIOV_VFM, &table); | 250 | pci_read_config_dword(dev, iov->pos + PCI_SRIOV_VFM, &table); |
@@ -294,15 +294,15 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
294 | if (!nr_virtfn) | 294 | if (!nr_virtfn) |
295 | return 0; | 295 | return 0; |
296 | 296 | ||
297 | if (iov->nr_virtfn) | 297 | if (iov->num_VFs) |
298 | return -EINVAL; | 298 | return -EINVAL; |
299 | 299 | ||
300 | pci_read_config_word(dev, iov->pos + PCI_SRIOV_INITIAL_VF, &initial); | 300 | pci_read_config_word(dev, iov->pos + PCI_SRIOV_INITIAL_VF, &initial); |
301 | if (initial > iov->total || | 301 | if (initial > iov->total_VFs || |
302 | (!(iov->cap & PCI_SRIOV_CAP_VFM) && (initial != iov->total))) | 302 | (!(iov->cap & PCI_SRIOV_CAP_VFM) && (initial != iov->total_VFs))) |
303 | return -EIO; | 303 | return -EIO; |
304 | 304 | ||
305 | if (nr_virtfn < 0 || nr_virtfn > iov->total || | 305 | if (nr_virtfn < 0 || nr_virtfn > iov->total_VFs || |
306 | (!(iov->cap & PCI_SRIOV_CAP_VFM) && (nr_virtfn > initial))) | 306 | (!(iov->cap & PCI_SRIOV_CAP_VFM) && (nr_virtfn > initial))) |
307 | return -EINVAL; | 307 | return -EINVAL; |
308 | 308 | ||
@@ -359,7 +359,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
359 | msleep(100); | 359 | msleep(100); |
360 | pci_cfg_access_unlock(dev); | 360 | pci_cfg_access_unlock(dev); |
361 | 361 | ||
362 | iov->initial = initial; | 362 | iov->initial_VFs = initial; |
363 | if (nr_virtfn < initial) | 363 | if (nr_virtfn < initial) |
364 | initial = nr_virtfn; | 364 | initial = nr_virtfn; |
365 | 365 | ||
@@ -376,7 +376,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
376 | } | 376 | } |
377 | 377 | ||
378 | kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE); | 378 | kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE); |
379 | iov->nr_virtfn = nr_virtfn; | 379 | iov->num_VFs = nr_virtfn; |
380 | 380 | ||
381 | return 0; | 381 | return 0; |
382 | 382 | ||
@@ -401,13 +401,13 @@ static void sriov_disable(struct pci_dev *dev) | |||
401 | int i; | 401 | int i; |
402 | struct pci_sriov *iov = dev->sriov; | 402 | struct pci_sriov *iov = dev->sriov; |
403 | 403 | ||
404 | if (!iov->nr_virtfn) | 404 | if (!iov->num_VFs) |
405 | return; | 405 | return; |
406 | 406 | ||
407 | if (iov->cap & PCI_SRIOV_CAP_VFM) | 407 | if (iov->cap & PCI_SRIOV_CAP_VFM) |
408 | sriov_disable_migration(dev); | 408 | sriov_disable_migration(dev); |
409 | 409 | ||
410 | for (i = 0; i < iov->nr_virtfn; i++) | 410 | for (i = 0; i < iov->num_VFs; i++) |
411 | virtfn_remove(dev, i, 0); | 411 | virtfn_remove(dev, i, 0); |
412 | 412 | ||
413 | iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); | 413 | iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE); |
@@ -419,7 +419,7 @@ static void sriov_disable(struct pci_dev *dev) | |||
419 | if (iov->link != dev->devfn) | 419 | if (iov->link != dev->devfn) |
420 | sysfs_remove_link(&dev->dev.kobj, "dep_link"); | 420 | sysfs_remove_link(&dev->dev.kobj, "dep_link"); |
421 | 421 | ||
422 | iov->nr_virtfn = 0; | 422 | iov->num_VFs = 0; |
423 | } | 423 | } |
424 | 424 | ||
425 | static int sriov_init(struct pci_dev *dev, int pos) | 425 | static int sriov_init(struct pci_dev *dev, int pos) |
@@ -496,7 +496,7 @@ found: | |||
496 | iov->pos = pos; | 496 | iov->pos = pos; |
497 | iov->nres = nres; | 497 | iov->nres = nres; |
498 | iov->ctrl = ctrl; | 498 | iov->ctrl = ctrl; |
499 | iov->total = total; | 499 | iov->total_VFs = total; |
500 | iov->offset = offset; | 500 | iov->offset = offset; |
501 | iov->stride = stride; | 501 | iov->stride = stride; |
502 | iov->pgsz = pgsz; | 502 | iov->pgsz = pgsz; |
@@ -529,7 +529,7 @@ failed: | |||
529 | 529 | ||
530 | static void sriov_release(struct pci_dev *dev) | 530 | static void sriov_release(struct pci_dev *dev) |
531 | { | 531 | { |
532 | BUG_ON(dev->sriov->nr_virtfn); | 532 | BUG_ON(dev->sriov->num_VFs); |
533 | 533 | ||
534 | if (dev != dev->sriov->dev) | 534 | if (dev != dev->sriov->dev) |
535 | pci_dev_put(dev->sriov->dev); | 535 | pci_dev_put(dev->sriov->dev); |
@@ -554,7 +554,7 @@ static void sriov_restore_state(struct pci_dev *dev) | |||
554 | pci_update_resource(dev, i); | 554 | pci_update_resource(dev, i); |
555 | 555 | ||
556 | pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz); | 556 | pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz); |
557 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, iov->nr_virtfn); | 557 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, iov->num_VFs); |
558 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); | 558 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); |
559 | if (iov->ctrl & PCI_SRIOV_CTRL_VFE) | 559 | if (iov->ctrl & PCI_SRIOV_CTRL_VFE) |
560 | msleep(100); | 560 | msleep(100); |
@@ -661,7 +661,7 @@ int pci_iov_bus_range(struct pci_bus *bus) | |||
661 | list_for_each_entry(dev, &bus->devices, bus_list) { | 661 | list_for_each_entry(dev, &bus->devices, bus_list) { |
662 | if (!dev->is_physfn) | 662 | if (!dev->is_physfn) |
663 | continue; | 663 | continue; |
664 | busnr = virtfn_bus(dev, dev->sriov->total - 1); | 664 | busnr = virtfn_bus(dev, dev->sriov->total_VFs - 1); |
665 | if (busnr > max) | 665 | if (busnr > max) |
666 | max = busnr; | 666 | max = busnr; |
667 | } | 667 | } |
@@ -729,9 +729,56 @@ EXPORT_SYMBOL_GPL(pci_sriov_migration); | |||
729 | */ | 729 | */ |
730 | int pci_num_vf(struct pci_dev *dev) | 730 | int pci_num_vf(struct pci_dev *dev) |
731 | { | 731 | { |
732 | if (!dev || !dev->is_physfn) | 732 | if (!dev->is_physfn) |
733 | return 0; | 733 | return 0; |
734 | else | 734 | |
735 | return dev->sriov->nr_virtfn; | 735 | return dev->sriov->num_VFs; |
736 | } | 736 | } |
737 | EXPORT_SYMBOL_GPL(pci_num_vf); | 737 | EXPORT_SYMBOL_GPL(pci_num_vf); |
738 | |||
739 | /** | ||
740 | * pci_sriov_set_totalvfs -- reduce the TotalVFs available | ||
741 | * @dev: the PCI PF device | ||
742 | * numvfs: number that should be used for TotalVFs supported | ||
743 | * | ||
744 | * Should be called from PF driver's probe routine with | ||
745 | * device's mutex held. | ||
746 | * | ||
747 | * Returns 0 if PF is an SRIOV-capable device and | ||
748 | * value of numvfs valid. If not a PF with VFS, return -EINVAL; | ||
749 | * if VFs already enabled, return -EBUSY. | ||
750 | */ | ||
751 | int pci_sriov_set_totalvfs(struct pci_dev *dev, u16 numvfs) | ||
752 | { | ||
753 | if (!dev->is_physfn || (numvfs > dev->sriov->total_VFs)) | ||
754 | return -EINVAL; | ||
755 | |||
756 | /* Shouldn't change if VFs already enabled */ | ||
757 | if (dev->sriov->ctrl & PCI_SRIOV_CTRL_VFE) | ||
758 | return -EBUSY; | ||
759 | else | ||
760 | dev->sriov->driver_max_VFs = numvfs; | ||
761 | |||
762 | return 0; | ||
763 | } | ||
764 | EXPORT_SYMBOL_GPL(pci_sriov_set_totalvfs); | ||
765 | |||
766 | /** | ||
767 | * pci_sriov_get_totalvfs -- get total VFs supported on this devic3 | ||
768 | * @dev: the PCI PF device | ||
769 | * | ||
770 | * For a PCIe device with SRIOV support, return the PCIe | ||
771 | * SRIOV capability value of TotalVFs or the value of driver_max_VFs | ||
772 | * if the driver reduced it. Otherwise, -EINVAL. | ||
773 | */ | ||
774 | int pci_sriov_get_totalvfs(struct pci_dev *dev) | ||
775 | { | ||
776 | if (!dev->is_physfn) | ||
777 | return -EINVAL; | ||
778 | |||
779 | if (dev->sriov->driver_max_VFs) | ||
780 | return dev->sriov->driver_max_VFs; | ||
781 | |||
782 | return dev->sriov->total_VFs; | ||
783 | } | ||
784 | EXPORT_SYMBOL_GPL(pci_sriov_get_totalvfs); | ||