Commit Graph

423 Commits

Author SHA1 Message Date
hselasky
83fc4e3c92 Add missing XHCI early takeover code. The XHCI takeover code
is supposed to disable the BIOS from using the XHCI controller
after bootup.

Approved by:	re (kib)
Reported by:	Mike Tancsa
MFC after:	1 week
2011-07-22 15:37:23 +00:00
marius
0aa6cb935c PCIB_ALLOC_MSIX() may already fail on the first pass, f.e. when the PCI-PCI
bridge is blacklisted. In that case just return from pci_alloc_msix_method(),
otherwise we continue without a single MSI-X resource, causing subsequent
attempts to use the seemingly available resource to fail or when booting
verbose a NULL-pointer dereference of rle->start when trying to print the
IRQ in pci_alloc_msix_method().

Reviewed by:	jhb
MFC after:	1 week
2011-07-13 18:35:47 +00:00
kib
26ea307b06 Implement pci_find_class(9), the function to find a pci device by its class.
Sponsored by:	The FreeBSD Foundation
Reviewed by:	jhb
MFC after:	1 week
2011-07-09 14:30:13 +00:00
jhb
51b09ade32 Minor whitespace and style fixes. 2011-06-21 19:31:31 +00:00
jhb
970967dd97 More properly handle Cardbus cards that that store their CIS in a BAR after
the recent changes to track BAR state explicitly.  The code would now
attempt to add the same BAR twice in this case.  Instead, change this so
that it recognizes this case and only adds it once and do not delete the
BAR outright after parsing the CIS.

Tested by:	bschmidt
2011-06-06 13:21:11 +00:00
jhb
51bd96b572 Reimplement how PCI-PCI bridges manage their I/O windows. Previously the
driver would verify that requests for child devices were confined to any
existing I/O windows, but the driver relied on the firmware to initialize
the windows and would never grow the windows for new requests.  Now the
driver actively manages the I/O windows.

This is implemented by allocating a bus resource for each I/O window from
the parent PCI bus and suballocating that resource to child devices.  The
suballocations are managed by creating an rman for each I/O window.  The
suballocated resources are mapped by passing the bus_activate_resource()
call up to the parent PCI bus.  Windows are grown when needed by using
bus_adjust_resource() to adjust the resource allocated from the parent PCI
bus.  If the adjust request succeeds, the window is adjusted and the
suballocation request for the child device is retried.

When growing a window, the rman_first_free_region() and
rman_last_free_region() routines are used to determine if the front or
end of the existing I/O window is free.  From using that, the smallest
ranges that need to be added to either the front or back of the window
are computed.  The driver will first try to grow the window in whichever
direction requires the smallest growth first followed by the other
direction if that fails.

Subtractive bridges will first attempt to satisfy requests for child
resources from I/O windows (including attempts to grow the windows).  If
that fails, the request is passed up to the parent PCI bus directly
however.

The PCI-PCI bridge driver will try to use firmware-assigned ranges for
child BARs first and only allocate a "fresh" range if that specific range
cannot be accommodated in the I/O window.  This allows systems where the
firmware assigns resources during boot but later wipes the I/O windows
(some ACPI BIOSen are known to do this) to "rediscover" the original I/O
window ranges.

The ACPI Host-PCI bridge driver has been adjusted to correctly honor
hw.acpi.host_mem_start and the I/O port equivalent when a PCI-PCI bridge
makes a wildcard request for an I/O window range.

The new PCI-PCI bridge driver is only enabled if the NEW_PCIB kernel option
is enabled.  This is a transition aide to allow platforms that do not
yet support bus_activate_resource() and bus_adjust_resource() in their
Host-PCI bridge drivers (and possibly other drivers as needed) to use the
old driver for now.  Once all platforms support the new driver, the
kernel option and old driver will be removed.

PR:		kern/143874 kern/149306
Tested by:	mav
2011-05-03 17:37:24 +00:00
jhb
3e97a80649 Add implementations of BUS_ADJUST_RESOURCE() to the PCI bus driver,
generic PCI-PCI bridge driver, x86 nexus driver, and x86 Host to PCI bridge
drivers.
2011-05-02 14:13:12 +00:00
jhb
da3b304fc1 Only align MSI message groups based on the number of messages being
allocated, not the maximum number of messages the device supports.  The
spec only requires the former, and I believe I implemented the latter due
to misunderstanding an e-mail.  In particular, this fixes an issue where
having several devices that all support 16 messages can run out of
IDT vectors on x86 even though the driver only uses a single message.

Submitted by:	Bret Ketchum  bcketchum of gmail
MFC after:	1 week
2011-04-27 20:08:44 +00:00
jhb
94327c7382 Explicitly track the state of all known BARs for each PCI device. The PCI
bus driver will now remember the size of a BAR obtained during the initial
bus scan and use that size when doing lazy resource allocation rather than
resizing the BAR.  The bus driver will now also report unallocated BARs to
userland for display by 'pciconf -lb'.  Psuedo-resources that are not BARs
(such as the implicit I/O port resources for master/slave ATA controllers)
will no longer be listed as BARs in 'pciconf -lb'.  During resume, BARs are
restored from their new saved state instead of having the raw registers
saved and restored across resume.  This also fixes restoring BARs at
unusual loactions if said BAR has been allocated by a driver.

Add a constant for the offset of the ROM BIOS BAR in PCI-PCI bridges and
properly handle ROM BIOS BARs in PCI-PCI bridges.  The PCI bus now also
properly handles the lack of a ROM BIOS BAR in a PCI-Cardbus bridge.

Tested by:	jkim
2011-03-31 13:22:12 +00:00
jhb
3929fadffc Rename pci_find_extcap() to pci_find_cap(). PCI now uses the term
"extended capabilities" to refer to the new set of capability structures
starting at offset 0x100 in config space for PCI-express devices.  For now
both function names will still work.  I will merge this to older branches
to ease driver portability, but 9.0 will ship with a new pci_find_extcap()
function that locates extended capabilities instead.

Reviewed by:	imp
MFC after:	1 week
2011-03-22 12:05:49 +00:00
jhb
0abc92bd66 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
jhb
359e81dc46 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
jhb
53ab29d183 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
88337282fe 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
jkim
858709918c 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
nwhitehorn
53d1ac9cef 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
jhb
97a61d6656 - 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
jhb
eaaaed5d4b 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
jkim
987ad790da 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
jkim
0ed43ce056 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
jkim
470249586e 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
jkim
1254c47e76 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
jkim
b42e5fcb8e Remove unnecessary castings and fix couple of style(9) nits. 2010-10-15 21:41:59 +00:00
jkim
59bb6f5773 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
jhb
bdd8e8fe81 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
yongari
b81b36fb71 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
mav
ea954fa396 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
mav
d785fc2581 Honor hw.pci.do_power_nodriver on resume. Power-down devices without
driver attached.
2010-05-22 03:19:30 +00:00
nwhitehorn
95e9f935c7 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
mav
89887095f9 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
jhb
2dd11a3eaa 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
jhb
9b53c8050d 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
jhb
1dadd0cd8c Remove no longer used pci_release_resource(). 2009-12-30 19:46:09 +00:00
jkim
e1aa0311d0 Implement a rudimentary suspend/resume methods for PCI P2P bridge.
Reviewed by:	jhb, imp
2009-12-10 01:01:53 +00:00
jhb
2f9d87159f 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
thompsa
4a162c052d 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
305f44a5b1 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
thompsa
9ffd1abaff 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
jhb
335809a00b 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
109d6f3c87 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
jhb
3237867ed5 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
jkim
6d358bddff Import ACPICA 20090521. 2009-06-05 18:44:36 +00:00
jhb
0937475a4f 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
jhb
4de098dcff 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
imp
cf4102fe7f 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
imp
3ca3ea7190 We no longer need to use d_thread_t, migrate to struct thread *. 2009-05-20 17:29:21 +00:00
jhb
e76ae1ccf3 - 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
stas
fc57d2304c - Fix spacing in the comment.
Reported by:	jhb
2009-04-03 13:35:54 +00:00
stas
fe4ba0b754 - Correct the comment.
MFC after:	3 days
2009-04-03 10:15:00 +00:00
marcel
a1ed5a2e81 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