Deleted Added
sdiff udiff text old ( 252315 ) new ( 253120 )
full compact
1/*-
2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
3 * Copyright (c) 2000, Michael Smith <msmith@freebsd.org>
4 * Copyright (c) 2000, BSDi
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 13 unchanged lines hidden (view full) ---

22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/dev/pci/pci.c 252315 2013-06-27 20:21:54Z jhb $");
31
32#include "opt_bus.h"
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/malloc.h>
37#include <sys/module.h>
38#include <sys/linker.h>

--- 34 unchanged lines hidden (view full) ---

73#if (BUS_SPACE_MAXADDR > 0xFFFFFFFF)
74#define PCI_DMA_BOUNDARY 0x100000000
75#endif
76
77#define PCIR_IS_BIOS(cfg, reg) \
78 (((cfg)->hdrtype == PCIM_HDRTYPE_NORMAL && reg == PCIR_BIOS) || \
79 ((cfg)->hdrtype == PCIM_HDRTYPE_BRIDGE && reg == PCIR_BIOS_1))
80
81static pci_addr_t pci_mapbase(uint64_t mapreg);
82static const char *pci_maptype(uint64_t mapreg);
83static int pci_mapsize(uint64_t testval);
84static int pci_maprange(uint64_t mapreg);
85static pci_addr_t pci_rombase(uint64_t mapreg);
86static int pci_romsize(uint64_t testval);
87static void pci_fixancient(pcicfgregs *cfg);
88static int pci_printf(pcicfgregs *cfg, const char *fmt, ...);

--- 25 unchanged lines hidden (view full) ---

114static void pci_disable_msi(device_t dev);
115static void pci_enable_msi(device_t dev, uint64_t address,
116 uint16_t data);
117static void pci_enable_msix(device_t dev, u_int index,
118 uint64_t address, uint32_t data);
119static void pci_mask_msix(device_t dev, u_int index);
120static void pci_unmask_msix(device_t dev, u_int index);
121static int pci_msi_blacklisted(void);
122static void pci_resume_msi(device_t dev);
123static void pci_resume_msix(device_t dev);
124static int pci_remap_intr_method(device_t bus, device_t dev,
125 u_int irq);
126
127static device_method_t pci_methods[] = {
128 /* Device interface */
129 DEVMETHOD(device_probe, pci_probe),

--- 50 unchanged lines hidden (view full) ---

180 DEVMETHOD(pci_msix_count, pci_msix_count_method),
181
182 DEVMETHOD_END
183};
184
185DEFINE_CLASS_0(pci, pci_driver, pci_methods, sizeof(struct pci_softc));
186
187static devclass_t pci_devclass;
188DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, 0);
189MODULE_VERSION(pci, 1);
190
191static char *pci_vendordata;
192static size_t pci_vendordata_size;
193
194struct pci_quirk {
195 uint32_t devid; /* Vendor/device of the card */
196 int type;
197#define PCI_QUIRK_MAP_REG 1 /* PCI map register in weird place */
198#define PCI_QUIRK_DISABLE_MSI 2 /* MSI/MSI-X doesn't work */
199#define PCI_QUIRK_ENABLE_MSI_VM 3 /* Older chipset in VM where MSI works */
200#define PCI_QUIRK_UNMAP_REG 4 /* Ignore PCI map register */
201 int arg1;
202 int arg2;
203};
204
205static const struct pci_quirk pci_quirks[] = {
206 /* The Intel 82371AB and 82443MX has a map register at offset 0x90. */
207 { 0x71138086, PCI_QUIRK_MAP_REG, 0x90, 0 },
208 { 0x719b8086, PCI_QUIRK_MAP_REG, 0x90, 0 },
209 /* As does the Serverworks OSB4 (the SMBus mapping register) */
210 { 0x02001166, PCI_QUIRK_MAP_REG, 0x90, 0 },
211
212 /*
213 * MSI doesn't work with the ServerWorks CNB20-HE Host Bridge
214 * or the CMIC-SL (AKA ServerWorks GC_LE).

--- 18 unchanged lines hidden (view full) ---

233 * bridge.
234 */
235 { 0x74501022, PCI_QUIRK_DISABLE_MSI, 0, 0 },
236
237 /*
238 * MSI-X allocation doesn't work properly for devices passed through
239 * by VMware up to at least ESXi 5.1.
240 */
241 { 0x079015ad, PCI_QUIRK_DISABLE_MSI, 0, 0 }, /* PCI/PCI-X */
242 { 0x07a015ad, PCI_QUIRK_DISABLE_MSI, 0, 0 }, /* PCIe */
243
244 /*
245 * Some virtualization environments emulate an older chipset
246 * but support MSI just fine. QEMU uses the Intel 82440.
247 */
248 { 0x12378086, PCI_QUIRK_ENABLE_MSI_VM, 0, 0 },
249
250 /*

--- 65 unchanged lines hidden (view full) ---

316static int pci_do_msix = 1;
317TUNABLE_INT("hw.pci.enable_msix", &pci_do_msix);
318SYSCTL_INT(_hw_pci, OID_AUTO, enable_msix, CTLFLAG_RW, &pci_do_msix, 1,
319 "Enable support for MSI-X interrupts");
320
321static int pci_honor_msi_blacklist = 1;
322TUNABLE_INT("hw.pci.honor_msi_blacklist", &pci_honor_msi_blacklist);
323SYSCTL_INT(_hw_pci, OID_AUTO, honor_msi_blacklist, CTLFLAG_RD,
324 &pci_honor_msi_blacklist, 1, "Honor chipset blacklist for MSI");
325
326#if defined(__i386__) || defined(__amd64__)
327static int pci_usb_takeover = 1;
328#else
329static int pci_usb_takeover = 0;
330#endif
331TUNABLE_INT("hw.pci.usb_early_takeover", &pci_usb_takeover);
332SYSCTL_INT(_hw_pci, OID_AUTO, usb_early_takeover, CTLFLAG_RDTUN,
333 &pci_usb_takeover, 1, "Enable early takeover of USB controllers.\n\
334Disable this if you depend on BIOS emulation of USB devices, that is\n\
335you use USB devices (like keyboard or mouse) but do not load USB drivers");
336
337/* Find a device_t by bus/slot/function in domain 0 */
338
339device_t
340pci_find_bsf(uint8_t bus, uint8_t slot, uint8_t func)
341{
342
343 return (pci_find_dbsf(0, bus, slot, func));
344}

--- 1076 unchanged lines hidden (view full) ---

1421 rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, 0);
1422 if (rle != NULL && rle->res != NULL)
1423 return (ENXIO);
1424
1425 /* Already have allocated messages? */
1426 if (cfg->msi.msi_alloc != 0 || cfg->msix.msix_alloc != 0)
1427 return (ENXIO);
1428
1429 /* If MSI is blacklisted for this system, fail. */
1430 if (pci_msi_blacklisted())
1431 return (ENXIO);
1432
1433 /* MSI-X capability present? */
1434 if (cfg->msix.msix_location == 0 || !pci_do_msix)
1435 return (ENODEV);
1436
1437 /* Make sure the appropriate BARs are mapped. */
1438 rle = resource_list_find(&dinfo->resources, SYS_RES_MEMORY,

--- 539 unchanged lines hidden (view full) ---

1978
1979/*
1980 * Returns true if the specified device is blacklisted because MSI
1981 * doesn't work.
1982 */
1983int
1984pci_msi_device_blacklisted(device_t dev)
1985{
1986 const struct pci_quirk *q;
1987
1988 if (!pci_honor_msi_blacklist)
1989 return (0);
1990
1991 for (q = &pci_quirks[0]; q->devid; q++) {
1992 if (q->devid == pci_get_devid(dev) &&
1993 q->type == PCI_QUIRK_DISABLE_MSI)
1994 return (1);
1995 }
1996 return (0);
1997}
1998
1999/*
2000 * Returns true if a specified chipset supports MSI when it is
2001 * emulated hardware in a virtual machine.
2002 */
2003static int
2004pci_msi_vm_chipset(device_t dev)
2005{
2006 const struct pci_quirk *q;
2007
2008 for (q = &pci_quirks[0]; q->devid; q++) {
2009 if (q->devid == pci_get_devid(dev) &&
2010 q->type == PCI_QUIRK_ENABLE_MSI_VM)
2011 return (1);
2012 }
2013 return (0);
2014}
2015
2016/*
2017 * Determine if MSI is blacklisted globally on this sytem. Currently,
2018 * we just check for blacklisted chipsets as represented by the
2019 * host-PCI bridge at device 0:0:0. In the future, it may become
2020 * necessary to check other system attributes, such as the kenv values
2021 * that give the motherboard manufacturer and model number.
2022 */
2023static int
2024pci_msi_blacklisted(void)
2025{
2026 device_t dev;
2027
2028 if (!pci_honor_msi_blacklist)
2029 return (0);
2030
2031 /* Blacklist all non-PCI-express and non-PCI-X chipsets. */
2032 if (!(pcie_chipset || pcix_chipset)) {
2033 if (vm_guest != VM_GUEST_NO) {
2034 dev = pci_find_bsf(0, 0, 0);
2035 if (dev != NULL)
2036 return (pci_msi_vm_chipset(dev) == 0);
2037 }
2038 return (1);
2039 }
2040
2041 dev = pci_find_bsf(0, 0, 0);
2042 if (dev != NULL)
2043 return (pci_msi_device_blacklisted(dev));
2044 return (0);
2045}
2046
2047/*
2048 * Attempt to allocate *count MSI messages. The actual number allocated is
2049 * returned in *count. After this function returns, each message will be
2050 * available to the driver as SYS_RES_IRQ resources starting at a rid 1.
2051 */
2052int
2053pci_alloc_msi_method(device_t dev, device_t child, int *count)
2054{
2055 struct pci_devinfo *dinfo = device_get_ivars(child);

--- 2706 unchanged lines hidden ---