1. 11 9月, 2014 1 次提交
    • B
      PCI: Add pci_ignore_hotplug() to ignore hotplug events for a device · b440bde7
      Bjorn Helgaas 提交于
      Powering off a hot-pluggable device, e.g., with pci_set_power_state(D3cold),
      normally generates a hot-remove event that unbinds the driver.
      
      Some drivers expect to remain bound to a device even while they power it
      off and back on again.  This can be dangerous, because if the device is
      removed or replaced while it is powered off, the driver doesn't know that
      anything changed.  But some drivers accept that risk.
      
      Add pci_ignore_hotplug() for use by drivers that know their device cannot
      be removed.  Using pci_ignore_hotplug() tells the PCI core that hot-plug
      events for the device should be ignored.
      
      The radeon and nouveau drivers use this to switch between a low-power,
      integrated GPU and a higher-power, higher-performance discrete GPU.  They
      power off the unused GPU, but they want to remain bound to it.
      
      This is a reimplementation of f244d8b6 ("ACPIPHP / radeon / nouveau:
      Fix VGA switcheroo problem related to hotplug") but extends it to work with
      both acpiphp and pciehp.
      
      This fixes a problem where systems with dual GPUs using the radeon drivers
      become unusable, freezing every few seconds (see bugzillas below).  The
      resume of the radeon device may also fail, e.g.,
      
      This fixes problems on dual GPU systems where the radeon driver becomes
      unusable because of problems while suspending the device, as in bug 79701:
      
          [drm] radeon: finishing device.
          radeon 0000:01:00.0: Userspace still has active objects !
          radeon 0000:01:00.0: ffff8800cb4ec288 ffff8800cb4ec000 16384 4294967297 force free
          ...
          WARNING: CPU: 0 PID: 67 at /home/apw/COD/linux/drivers/gpu/drm/radeon/radeon_gart.c:234 radeon_gart_unbind+0xd2/0xe0 [radeon]()
          trying to unbind memory from uninitialized GART !
      
      or while resuming it, as in bug 77261:
      
          radeon 0000:01:00.0: ring 0 stalled for more than 10158msec
          radeon 0000:01:00.0: GPU lockup ...
          radeon 0000:01:00.0: GPU pci config reset
          pciehp 0000:00:01.0:pcie04: Card not present on Slot(1-1)
          radeon 0000:01:00.0: GPU reset succeeded, trying to resume
          *ERROR* radeon: dpm resume failed
          radeon 0000:01:00.0: Wait for MC idle timedout !
      
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=77261
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=79701Reported-by: NShawn Starr <shawn.starr@rogers.com>
      Reported-by: NJose P. <lbdkmjdf@sharklasers.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Acked-by: NAlex Deucher <alexander.deucher@amd.com>
      Acked-by: NRajat Jain <rajatxjain@gmail.com>
      Acked-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      Acked-by: NDave Airlie <airlied@redhat.com>
      CC: stable@vger.kernel.org	# v3.15+
      b440bde7
  2. 17 7月, 2014 1 次提交
  3. 04 7月, 2014 1 次提交
  4. 20 6月, 2014 1 次提交
  5. 30 5月, 2014 1 次提交
  6. 29 5月, 2014 5 次提交
    • A
      PCI: Introduce new device binding path using pci_dev.driver_override · 782a985d
      Alex Williamson 提交于
      The driver_override field allows us to specify the driver for a device
      rather than relying on the driver to provide a positive match of the
      device.  This shortcuts the existing process of looking up the vendor and
      device ID, adding them to the driver new_id, binding the device, then
      removing the ID, but it also provides a couple advantages.
      
      First, the above existing process allows the driver to bind to any device
      matching the new_id for the window where it's enabled.  This is often not
      desired, such as the case of trying to bind a single device to a meta
      driver like pci-stub or vfio-pci.  Using driver_override we can do this
      deterministically using:
      
        echo pci-stub > /sys/bus/pci/devices/0000:03:00.0/driver_override
        echo 0000:03:00.0 > /sys/bus/pci/devices/0000:03:00.0/driver/unbind
        echo 0000:03:00.0 > /sys/bus/pci/drivers_probe
      
      Previously we could not invoke drivers_probe after adding a device to
      new_id for a driver as we get non-deterministic behavior whether the driver
      we intend or the standard driver will claim the device.  Now it becomes a
      deterministic process, only the driver matching driver_override will probe
      the device.
      
      To return the device to the standard driver, we simply clear the
      driver_override and reprobe the device:
      
        echo > /sys/bus/pci/devices/0000:03:00.0/driver_override
        echo 0000:03:00.0 > /sys/bus/pci/devices/0000:03:00.0/driver/unbind
        echo 0000:03:00.0 > /sys/bus/pci/drivers_probe
      
      Another advantage to this approach is that we can specify a driver override
      to force a specific binding or prevent any binding.  For instance when an
      IOMMU group is exposed to userspace through VFIO we require that all
      devices within that group are owned by VFIO.  However, devices can be
      hot-added into an IOMMU group, in which case we want to prevent the device
      from binding to any driver (override driver = "none") or perhaps have it
      automatically bind to vfio-pci.  With driver_override it's a simple matter
      for this field to be set internally when the device is first discovered to
      prevent driver matches.
      Signed-off-by: NAlex Williamson <alex.williamson@redhat.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Reviewed-by: NKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
      Reviewed-by: NAlexander Graf <agraf@suse.de>
      Acked-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      782a985d
    • A
      PCI: Add support for PCIe-to-PCI bridge DMA alias quirks · c8fe16e3
      Alex Williamson 提交于
      Several PCIe-to-PCI bridges fail to provide a PCIe capability, causing us
      to handle them as conventional PCI devices when they really use the
      requester ID of the secondary bus.  We need to differentiate these from
      PCIe-to-PCI bridges that actually use the conventional PCI ID when a PCIe
      capability is not present, such as those found on the root complex of may
      Intel chipsets.  Add a dev_flag bit to identify devices to be handled as
      standard PCIe-to-PCI bridges.
      Signed-off-by: NAlex Williamson <alex.williamson@redhat.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      c8fe16e3
    • A
      PCI: Add support for DMA alias quirks · 31c2b815
      Alex Williamson 提交于
      Some devices are broken and use a requester ID other than their physical
      devfn.  Add a byte, using an existing gap in the pci_dev structure, to
      store an alternate "alias" devfn.  A bit in the dev_flags tells us when
      this is valid.  We then add the alias as one more step in the
      pci_for_each_dma_alias() iterator.
      Tested-by: NGeorge Spelvin <linux@horizon.com>
      Tested-by: NPat Erley <pat-lkml@erley.org>
      Signed-off-by: NAlex Williamson <alex.williamson@redhat.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      31c2b815
    • A
      PCI: Convert pci_dev_flags definitions to bit shifts · 6b121592
      Alex Williamson 提交于
      Convert the pci_dev_flags definitions from decimal constants to bit shifts.
      We're only a few entries away from where using the decimal value becomes
      cumbersome.  No functional change.
      Tested-by: NGeorge Spelvin <linux@horizon.com>
      Tested-by: NPat Erley <pat-lkml@erley.org>
      Signed-off-by: NAlex Williamson <alex.williamson@redhat.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      6b121592
    • A
      PCI: Add DMA alias iterator · c25dc828
      Alex Williamson 提交于
      In a mixed PCI/PCI-X/PCIe topology, bridges can take ownership of
      transactions, replacing the original requester ID with their own.
      Sometimes we just want to know the resulting device or resulting alias;
      other times we want each step in the chain.  This iterator allows either
      usage.  When an endpoint is connected via an unbroken chain of PCIe
      switches and root ports, it has no alias and its requester ID is visible to
      the root bus.  When PCI/X get in the way, we pick up aliases for bridges.
      
      The reason why we potentially care about each step in the path is because
      of PCI-X.  PCI-X has the concept of a requester ID, but bridges may or may
      not take ownership of various types of transactions.  We therefore leave it
      to the consumer of this function to prune out what they don't care about
      rather than attempt to flatten the alias ourselves.
      Tested-by: NGeorge Spelvin <linux@horizon.com>
      Tested-by: NPat Erley <pat-lkml@erley.org>
      Signed-off-by: NAlex Williamson <alex.williamson@redhat.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      c25dc828
  7. 28 5月, 2014 4 次提交
  8. 23 5月, 2014 1 次提交
  9. 01 5月, 2014 1 次提交
    • A
      PCI/MSI: Remove pci_enable_msi_block() · 034cd97e
      Alexander Gordeev 提交于
      There are no users of pci_enable_msi_block() function left.  Obsolete it in
      favor of pci_enable_msi_range() and pci_enable_msi_exact() functions.
      
      Previously, we called arch_setup_msi_irqs() once, requesting the same
      vector count we passed to arch_msi_check_device().  Now we may call it
      several times: if it returns failure, we may retry and request fewer
      vectors.
      
      We don't keep track of the vector count we initially passed to
      arch_msi_check_device().  We only keep track of the number of vectors
      successfully set up by arch_setup_msi_irqs(), and this is what we use to
      clean things up when disabling MSI.  Therefore, we assume that
      arch_msi_check_device() does nothing that will have to be cleaned up later.
      
      [bhelgaas: changelog]
      Signed-off-by: NAlexander Gordeev <agordeev@redhat.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      034cd97e
  10. 25 4月, 2014 1 次提交
  11. 20 3月, 2014 1 次提交
  12. 20 2月, 2014 1 次提交
  13. 15 2月, 2014 1 次提交
  14. 14 2月, 2014 2 次提交
  15. 12 2月, 2014 2 次提交
  16. 15 1月, 2014 1 次提交
    • A
      PCI: Add pci_try_reset_function(), pci_try_reset_slot(), pci_try_reset_bus() · 61cf16d8
      Alex Williamson 提交于
      When doing a function/slot/bus reset PCI grabs the device_lock for each
      device to block things like suspend and driver probes, but call paths exist
      where this lock may already be held.  This creates an opportunity for
      deadlock.  For instance, vfio allows userspace to issue resets so long as
      it owns the device(s).  If a driver unbind .remove callback races with
      userspace issuing a reset, we have a deadlock as userspace gets stuck
      waiting on device_lock while another thread has device_lock and waits for
      .remove to complete.  To resolve this, we can make a version of the reset
      interfaces which use trylock.  With this, we can safely attempt a reset and
      return error to userspace if there is contention.
      
      [bhelgaas: the deadlock happens when A (userspace) has a file descriptor for
      the device, and B waits in this path:
      
        driver_detach
          device_lock                     # take device_lock
          __device_release_driver
            pci_device_remove             # pci_bus_type.remove
              vfio_pci_remove             # pci_driver .remove
                vfio_del_group_dev
                  wait_event(vfio.release_q, !vfio_dev_present)   # wait (holding device_lock)
      
      Now B is stuck until A gives up the file descriptor.  If A tries to acquire
      device_lock for any reason, we deadlock because A is waiting for B to release
      the lock, and B is waiting for A to release the file descriptor.]
      Signed-off-by: NAlex Williamson <alex.williamson@redhat.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      61cf16d8
  17. 14 1月, 2014 8 次提交
  18. 11 1月, 2014 3 次提交
  19. 08 1月, 2014 1 次提交
    • Y
      PCI: Enforce bus address limits in resource allocation · f75b99d5
      Yinghai Lu 提交于
      When allocating space for 32-bit BARs, we previously limited RESOURCE
      addresses so they would fit in 32 bits.  However, the BUS address need not
      be the same as the resource address, and it's the bus address that must fit
      in the 32-bit BAR.
      
      This patch adds:
      
        - pci_clip_resource_to_region(), which clips a resource so it contains
          only the range that maps to the specified bus address region, e.g., to
          clip a resource to 32-bit bus addresses, and
      
        - pci_bus_alloc_from_region(), which allocates space for a resource from
          the specified bus address region,
      
      and changes pci_bus_alloc_resource() to allocate space for 64-bit BARs from
      the entire bus address region, and space for 32-bit BARs from only the bus
      address region below 4GB.
      
      If we had this window:
      
        pci_root HWP0002:0a: host bridge window [mem 0xf0180000000-0xf01fedfffff] (bus address [0x80000000-0xfedfffff])
      
      we previously could not put a 32-bit BAR there, because the CPU addresses
      don't fit in 32 bits.  This patch fixes this, so we can use this space for
      32-bit BARs.
      
      It's also possible (though unlikely) to have resources with 32-bit CPU
      addresses but bus addresses above 4GB.  In this case the previous code
      would allocate space that a 32-bit BAR could not map.
      
      Remove PCIBIOS_MAX_MEM_32, which is no longer used.
      
      [bhelgaas: reworked starting from http://lkml.kernel.org/r/1386658484-15774-3-git-send-email-yinghai@kernel.org]
      Signed-off-by: NYinghai Lu <yinghai@kernel.org>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      f75b99d5
  20. 04 1月, 2014 3 次提交
    • A
      PCI/MSI: Add pci_enable_msi_range() and pci_enable_msix_range() · 302a2523
      Alexander Gordeev 提交于
      This adds pci_enable_msi_range(), which supersedes the pci_enable_msi()
      and pci_enable_msi_block() MSI interfaces.
      
      It also adds pci_enable_msix_range(), which supersedes the
      pci_enable_msix() MSI-X interface.
      
      The old interfaces have three categories of return values:
      
          negative: failure; caller should not retry
          positive: failure; value indicates number of interrupts that *could*
      	have been allocated, and caller may retry with a smaller request
          zero: success; at least as many interrupts allocated as requested
      
      It is error-prone to handle these three cases correctly in drivers.
      
      The new functions return either a negative error code or a number of
      successfully allocated MSI/MSI-X interrupts, which is expected to lead to
      clearer device driver code.
      
      pci_enable_msi(), pci_enable_msi_block() and pci_enable_msix() still exist
      unchanged, but are deprecated and may be removed after callers are updated.
      
      [bhelgaas: tweak changelog]
      Suggested-by: NBen Hutchings <bhutchings@solarflare.com>
      Signed-off-by: NAlexander Gordeev <agordeev@redhat.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Reviewed-by: NTejun Heo <tj@kernel.org>
      302a2523
    • A
      PCI/MSI: Add pci_msix_vec_count() · ff1aa430
      Alexander Gordeev 提交于
      This creates an MSI-X counterpart for pci_msi_vec_count().  Device drivers
      can use this function to obtain maximum number of MSI-X interrupts the
      device supports and use that number in a subsequent call to
      pci_enable_msix().
      
      pci_msix_vec_count() supersedes pci_msix_table_size() and returns a
      negative errno if device does not support MSI-X interrupts.  After this
      update, callers must always check the returned value.
      
      The only user of pci_msix_table_size() was the PCI-Express port driver,
      which is also updated by this change.
      Signed-off-by: NAlexander Gordeev <agordeev@redhat.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Reviewed-by: NTejun Heo <tj@kernel.org>
      ff1aa430
    • A
      PCI/MSI: Remove pci_enable_msi_block_auto() · 7b92b4f6
      Alexander Gordeev 提交于
      The new pci_msi_vec_count() interface makes pci_enable_msi_block_auto()
      superfluous.
      
      Drivers can use pci_msi_vec_count() to learn the maximum number of MSIs
      supported by the device, and then call pci_enable_msi_block().
      
      pci_enable_msi_block_auto() was introduced recently, and its only user is
      the AHCI driver, which is also updated by this change.
      Signed-off-by: NAlexander Gordeev <agordeev@redhat.com>
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      Acked-by: NTejun Heo <tj@kernel.org>
      7b92b4f6