Commit Graph

413 Commits

Author SHA1 Message Date
John Baldwin
54a03acb86 Partially revert previous change. Drop the quirk to disable MSI for HT
chipsets that do not have an HT slave at 0:0:0:0.  The Linux quirk is
actually specific to Nvidia chipsets and the check I had added was in
the wrong place.

Prodded by:	nathanw
2011-03-18 14:06:12 +00:00
John Baldwin
8081bab70b Fix a few issues with HyperTransport devices and MSI interrupts:
- Always enable the HyperTransport MSI mapping window for HyperTransport
  to PCI bridges (these show up as HyperTransport slave devices).
  The mapping windows in PCI-PCI bridges are enabled by existing code
  in the PCI-PCI bridge driver as MSI requests propagate up the device
  tree, but Host-PCI bridges don't really show up in that tree.
- If the PCI device at domain 0 bus 0 slot 0 function 0 is not a
  HyperTransport device, then blacklist MSI on any other HT devices in
  the system.  Linux has a similar quirk.

PR:		kern/155442
Tested by:	Zack Dannar  zdannar of gmail
MFC after:	1 week
2011-03-18 12:13:04 +00:00
John Baldwin
6e2b68aab6 Properly handle BARs bigger than 4G. The '1' was treated as an int
causing the size calculation to be truncated to the size of an int
(32-bits on all current architectures).

Submitted by:	Anish  akgupt3 of gmail
MFC after:	1 week
2011-02-23 12:58:50 +00:00
Marcel Moolenaar
bba39e1034 Use the preload_fetch_addr() and preload_fetch_size() convenience
functions to obtain the address and size of the PCI vendor data.

Sponsored by: Juniper Networks.
2011-02-13 19:26:51 +00:00
Jung-uk Kim
f68ff88c87 Resume critical PCI devices (and their children) first, then everything else
later.  This give us better chance to catch device driver problems.
2010-11-22 21:58:00 +00:00
Nathan Whitehorn
495ed64c16 The EHCI_CAPLENGTH and EHCI_HCIVERSION registers are actually sub-registers
within the first 4 bytes of the EHCI memory space. For controllers that
use big-endian MMIO, reading them with 1- and 2-byte reads would then
return the wrong values. Instead, read the combined register with a 4-byte
read and mask out the interesting quantities.
2010-10-25 15:51:43 +00:00
John Baldwin
ba577448a2 - Add a new PCI quirk to whitelist an old chipset that doesn't support
PCI-express or PCI-X capabilities if we are running in a virtual machine.
- Whitelist the Intel 82440 chipset used by QEMU.

Tested by:	jfv
MFC after:	1 week
2010-10-22 11:42:02 +00:00
John Baldwin
fb2439a6f6 Clarify a misleading comment. The test in pci_reserve_map() was meant to
ignore BARs that are invalid due to having a size of zero, not to ignore
BARs with an existing base of zero.  While here, reorganize the code
slightly to make the intent clearer.

Reported by:	avg
MFC after:	1 week
2010-10-21 17:46:23 +00:00
Jung-uk Kim
d815d0abb7 Update PCI power management registers per PCI Bus Power Management Interface
Specification Rev. 1.2.  Rename pp_pcmcsr field of PM capabilities to pp_bse
to avoid further confusions and adjust some comments accordingly.  The real
PMCSR (Power Management Control/Status Register) is PCIR_POWER_STATUS and
it is actually BSE (PCI-to-PCI Bridge Support Extensions) register.
2010-10-20 23:41:16 +00:00
Jung-uk Kim
f3e0b10973 Introduce a new tunable 'hw.pci.do_power_suspend'. This tunable lets you
avoid PCI power state transition from D0 to D3 for suspending case.  Default
is 1 or enabled.
2010-10-20 16:47:09 +00:00
Jung-uk Kim
6d018c85e1 Remove PCI header type 0 restriction from power state changes. PCI config.
registers for bridges are saved and restored since r200341.

OK'ed by:	imp, jhb
2010-10-19 17:15:22 +00:00
Jung-uk Kim
b56b75259b Do not apply do_power_resume for suspending case. When do_powerstate was
splitted into do_power_resume and do_power_nodriver, it became stale.
2010-10-19 17:05:51 +00:00
Jung-uk Kim
debfe32ccd Remove unnecessary castings and fix couple of style(9) nits. 2010-10-15 21:41:59 +00:00
Jung-uk Kim
6e877573df Move setting power state for children into a separate function as they were
essentially the same.  This also restores hw.pci.do_power_resume tunable,
which was broken since r211430.

Reviewed by:	jhb
2010-10-15 21:39:51 +00:00
John Baldwin
62508c531e Add a new method to the PCI bridge interface, PCIB_POWER_FOR_SLEEP(). This
method is used by the PCI bus driver to query the power management system
to determine the proper device state to be used for a device during suspend
and resume.  For the ACPI PCI bridge drivers this calls
acpi_device_pwr_for_sleep().  This removes ACPI-specific knowledge from
the PCI and PCI-PCI bridge drivers.

Reviewed by:	jkim
2010-08-17 15:44:52 +00:00
Pyun YongHyeon
f39cf57f91 Consistently check header type after reading PCIR_HDRTYPE register.
While I'm here use defined macro instead of using magic numbers for
header type.

Reviewed by:	jhb
2010-07-29 20:42:38 +00:00
Alexander Motin
93fc07b434 Virtualize pci_remap_msi_irq() call from general MSI code. It allows MSI
(FSB interrupts) to be used by non-PCI devices, such as HPET.
2010-06-14 07:10:37 +00:00
Alexander Motin
75f5385157 Honor hw.pci.do_power_nodriver on resume. Power-down devices without
driver attached.
2010-05-22 03:19:30 +00:00
Nathan Whitehorn
ca2c19312e Add support for the U4 PCI-Express bridge chipset used in late-generation
Powermac G5 systems. MSI and several other things are not presently
supported.

The U3/U4 internal device support portions of this change were contributed
by Andreas Tobler.

MFC after:	1 week
2010-05-16 15:18:25 +00:00
Alexander Motin
24d6a5ed27 Add pci_get|set_max_read_req() helper functions to control maximum PCIe
read request size.

Reviewed by:	jhb@
2010-02-05 17:18:48 +00:00
John Baldwin
af827f9642 Move the PCI-specific logic of removing a cardbus device into a
pci_delete_child() function called by the cardbus driver.  The new function
uses resource_list_unreserve() to release the BARs decoded by the device
being removed.

Reviewed by:	imp
Tested by:	brooks
2010-01-05 20:42:25 +00:00
John Baldwin
4e8790e943 Teach the PCI bus driver to handle PCIR_BIOS BARs properly and remove special
handling for the PCIR_BIOS decoding enable bit from the cardbus driver.
The PCIR_BIOS BAR does include type bits like other BARs.  Instead, it is
always a 32-bit non-prefetchable memory BAR where the low bit is used as a
flag to enable decoding.

Reviewed by:	imp
2009-12-30 20:47:14 +00:00
John Baldwin
1280c1198d Remove no longer used pci_release_resource(). 2009-12-30 19:46:09 +00:00
Jung-uk Kim
e36af2929a Implement a rudimentary suspend/resume methods for PCI P2P bridge.
Reviewed by:	jhb, imp
2009-12-10 01:01:53 +00:00
John Baldwin
42a346fa63 For some buses, devices may have active resources assigned even though they
are not allocated by the device driver.  These resources should still appear
allocated from the system's perspective so that their assigned ranges are
not reused by other resource requests.  The PCI bus driver has used a hack
to effect this for a while now where it uses rman_set_device() to assign
devices to the PCI bus when they are first encountered and later assigns
them to the actual device when a driver allocates a BAR.  A few downsides of
this approach is that it results in somewhat confusing devinfo -r output as
well as not being very easily portable to other bus drivers.

This commit adds generic support for "reserved" resources to the resource
list API used by many bus drivers to manage the resources of child devices.
A resource may be reserved via resource_list_reserve().  This will allocate
the resource from the bus' parent without activating it.
resource_list_alloc() recognizes an attempt to allocate a reserved resource.
When this happens it activates the resource (if requested) and then returns
the reserved resource.  Similarly, when a reserved resource is released via
resource_list_release(), it is deactivated (if it is active) and the
resource is then marked reserved again, but is left allocated from the
bus' parent.  To completely remove a reserved resource, a bus driver may
use resource_list_unreserve().  A bus driver may use resource_list_busy()
to determine if a reserved resource is allocated by a child device or if
it can be unreserved.

The PCI bus driver has been changed to use this framework instead of
abusing rman_set_device() to keep track of reserved vs allocated resources.

Submitted by:	imp (an older version many moons ago)
MFC after:	1 month
2009-12-09 21:52:53 +00:00
Andrew Thompson
e6af527c11 Disable interrupts after doing early takeover of the usb controller in case usb
isnt actually compiled in (or kldloaded) as the controller could cause spurious
interrupts.

Tested by:	Florian Smeets
2009-11-25 20:50:43 +00:00
Marcel Moolenaar
d6eb44c8b0 BIOSes, buggy or otherwise, are i386 or amd64 specific.
Have the early USB takeover enabled for i386 and amd64
by default.
This also avoids a panic on PowerPC where the resource
isn't released properly and we find a busy resource
when the USB host controller wants to allocate it...
2009-10-23 22:53:01 +00:00
Andrew Thompson
1def609a63 Workaround buggy BIOS code in USB regard. By doing the BIOS to OS handover for
all host controllers at the same time, we avoid problems where the BIOS will
actually write to the USB registers of all the USB host controllers every time
we handover one of them, and consequently reset the OS programmed values.

Submitted by:	avg
Reviewed by:	jhb
2009-10-15 20:07:08 +00:00
John Baldwin
ce95033db7 Don't reread the command register to see if enabling I/O or memory
decoding "took".  Other OS's that I checked do not do this and it breaks
some amdpm(4) devices.  Prior to 7.2 we did not honor the error returned
when this failed anyway, so this in effect restores previous behavior.

PR:		kern/137668
Tested by:	Aurelien Mere  aurelien.mere  amc-os.com
MFC after:	3 days
2009-09-22 15:43:03 +00:00
Marius Strobl
fada2a867d Add a MD __PCI_BAR_ZERO_VALID which denotes that BARs containing 0
actually specify valid bases that should be treated just as normal.
The PCI specifications have no indication that 0 would be a magic value
indicating a disabled BAR as commonly used on at least amd64 and i386
but not sparc64. It's unclear what to do in pci_delete_resource()
instead of writing 0 to a BAR though as there's no (other) way do
disable individual BARs so its decoding is left enabled in case of
__PCI_BAR_ZERO_VALID for now.

Approved by:	re (kib), jhb
MFC after:	1 week
2009-07-21 19:06:39 +00:00
John Baldwin
d456f534c9 Enable MSI in the MSI capability registers any time that the first message
in an MSI group is enabled, not just if the address/data pair are not
initialized.

Reported by:	rnoland
MFC after:	1 week
2009-06-22 20:08:06 +00:00
Jung-uk Kim
129d3046ef Import ACPICA 20090521. 2009-06-05 18:44:36 +00:00
John Baldwin
11632ace3a Include <machine/stdarg.h> for va_*(). I'm not sure how this compiled
on amd64 without this.
2009-06-02 12:35:04 +00:00
John Baldwin
287078dd8e Add an internal pci_printf() routine similar to device_printf() except
that it prefixes the output with 'pci<domain>:<bus>:<device>:<function>: '.
2009-06-01 20:30:00 +00:00
Warner Losh
89c81b88f1 Revert junk from last commit. These are WIP and not ready (and don't
match the description of the last commit).
2009-05-20 22:00:39 +00:00
Warner Losh
00b4e54ae7 We no longer need to use d_thread_t, migrate to struct thread *. 2009-05-20 17:29:21 +00:00
John Baldwin
bfee0576cb - Consolidate duplicated code for reading and sizing BARs and writing base
addresses to BARs into new pci_read_bar() and pci_write_bar() routines.
  pci_add_map(), pci_alloc_map(), and pci_delete_resource() now use these
  routines to work with BARs.
- Just pass the device_t for the new PCI device to various routines instead
  of passing the device, bus, slot, and function.

Reviewed by:	imp
2009-04-14 18:32:37 +00:00
Stanislav Sedov
c130439940 - Fix spacing in the comment.
Reported by:	jhb
2009-04-03 13:35:54 +00:00
Stanislav Sedov
3dc489ee95 - Correct the comment.
MFC after:	3 days
2009-04-03 10:15:00 +00:00
Marcel Moolenaar
d175be464e Fix a buglet in revision 189401: when restoring a 64-bit BAR,
write the upper 32-bits in the adjacent bar. The consequences
of the buglet were severe enough though: a machine check.
2009-03-10 06:21:52 +00:00
Robert Noland
41b3a23249 Invert the logic error for the MSI/MSIX vs INTx case.
Pointyhat to:	me

MFC after:	3 days
2009-03-06 11:24:42 +00:00
John Baldwin
c4e8c9df9e Always read/write the full 64-bit value of 64-bit BARs. Specifically,
when determining the size of a BAR by writing all 1's to the BAR and
reading back the result, always operate on the full 64-bit size.

Reviewed by:	imp
MFC after:	1 month
2009-03-05 15:33:04 +00:00
John Baldwin
d004885d3a Honor the prefetchable flag in memory BARs by setting the RF_PREFETCHABLE
flag when calling bus_alloc_resource() to allocate resources from a parent
PCI bridge.  For PCI-PCI bridges this asks the bridge to satisfy the
request using the prefetchable memory range rather than the normal
memory range.

Reviewed by:	imp
Reported by:	scottl
MFC after:	1 week
2009-03-05 15:28:46 +00:00
Robert Noland
a9f33b974a Extend the management of PCIM_CMD_INTxDIS.
We now explicitly enable INTx during bus_setup_intr() if it is needed.
Several of the ata drivers were managing this bit internally.  This is
better handled in pci and it should work for all drivers now.

We also mask INTx during bus_teardown_intr() by setting this bit.

Reviewed by:	jhb
MFC after:	3 days
2009-03-04 18:23:48 +00:00
John Baldwin
6b0ff427a5 Further refine the handling of resources for BARs in the PCI bus driver.
A while back, Warner changed the PCI bus code to reserve resources when
enumerating devices and simply give devices the previously allocated
resources when they call bus_alloc_resource().  This ensures that address
ranges being decoded by a BAR are always allocated in the nexus0 device
(or whatever device the PCI bus gets its address space from) even if a
device driver is not attached to the device.  This patch extends this
behavior further:
- To let the PCI bus distinguish between a resource being allocated by
  a device driver vs. merely being allocated by the bus, use
  rman_set_device() to assign the device to the bus when it is owned
  by the bus and to the child device when it is allocated by the child
  device's driver.  We can now prevent a device driver from allocating
  the same device twice.  Doing so could result in odd things like
  allocating duplicate virtual memory to map the resource on some
  archs and leaking the original mapping.
- When a PCI device driver releases a resource, don't pass the request
  all the way up the tree and release it in the nexus (or similar device)
  since the BAR is still active and decoding.  Otherwise, another device
  could later allocate the same range even though it is still in use.
  Instead, deactivate the resource and assign it back to the PCI bus
  using rman_set_device().
- pci_delete_resource() will actually completely free a BAR including
  attemping to disable it.
- Disable BAR decoding via the command register when sizing a BAR in
  pci_alloc_map() which is used to allocate resources for a BAR when
  the BIOS/firmware did not assign a usable resource range during boot.
  This mirrors an earlier fix to pci_add_map() which is used when to
  size BARs during boot.
- Move the activation of I/O decoding in the PCI command register into
  pci_activate_resource() instead of doing it in pci_alloc_resource().
  Previously we could actually enable decoding before a BAR was
  initialized via pci_alloc_map().

Glanced at by:	bsdimp
2009-03-03 16:38:59 +00:00
Robert Noland
5884a846e7 Disable INTx when enabling MSI/MSIX
This addresses interrupt storms that were noticed after enabling MSI
in drm.  I think this is due to a loose interpretation of the PCI 2.3
spec, which states that a function using MSI is prohibitted from using
INTx.  It appears that some vendors interpretted that to mean that they
should handle it in hardware, while others felt it was the drivers
responsibility.

This fix will also likely resolve interrupt storm related issues with
devices other than drm.

Reviewed by:	jhb@
MFC after:	3 days
2009-03-02 19:00:41 +00:00
John Baldwin
34a839f108 Don't throw away upper 32-bits of the HT MSI address window. In practice
this is harmless since the address window for MSI on x86 is in the lower
4 GB.

Submitted by:	mav
MFC after:	1 week
2009-02-26 14:32:14 +00:00
Nathan Whitehorn
f5a78b2f7e Change the probe priority for PCI and I2C generic bus modules from
numerical constants to BUS_PROBE_GENERIC.

Suggested by:	jhb
2009-01-20 00:05:43 +00:00
John Baldwin
589d604bf9 Disable decoding of BARs by devices before we trash the value in the BAR
by writing all 1's to it to determine its length.  This fixes issues with
MCFG on at least some machines where a trashed BAR claimed subsequent
attempts at PCI config transactions because the addresses in the MCFG
window fell in the decoding range of the BAR.

In general it is a bad idea to leave the BARs enabled while we are
frobbing with them in this manner.

Sleuthing by:  tegge
MFC after:     1 week
2009-01-16 22:22:30 +00:00
Alexander Motin
2e013ce0e3 Add ADMA, SATA and SAS mass storage subclasses reporting. 2008-11-13 19:57:33 +00:00