Skip to content

Commit

Permalink
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kerne…
Browse files Browse the repository at this point in the history
…l/git/jbarnes/pci-2.6

* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (27 commits)
  PCI: Don't use dmi_name_in_vendors in quirk
  PCI: remove unused AER functions
  PCI/sysfs: move bus cpuaffinity to class dev_attrs
  PCI: add rescan to /sys/.../pci_bus/.../
  PCI: update bridge resources to get more big ranges when allocating space (again)
  KVM: Use pci_store/load_saved_state() around VM device usage
  PCI: Add interfaces to store and load the device saved state
  PCI: Track the size of each saved capability data area
  PCI/e1000e: Add and use pci_disable_link_state_locked()
  x86/PCI: derive pcibios_last_bus from ACPI MCFG
  PCI: add latency tolerance reporting enable/disable support
  PCI: add OBFF enable/disable support
  PCI: add ID-based ordering enable/disable support
  PCI hotplug: acpiphp: assume device is in state D0 after powering on a slot.
  PCI: Set PCIE maxpayload for card during hotplug insertion
  PCI/ACPI: Report _OSC control mask returned on failure to get control
  x86/PCI: irq and pci_ids patch for Intel Panther Point DeviceIDs
  PCI: handle positive error codes
  PCI: check pci_vpd_pci22_wait() return
  PCI: Use ICH6_GPIO_EN in ich6_lpc_acpi_gpio
  ...

Fix up trivial conflicts in include/linux/pci_ids.h: commit a6e5e2b
moved the intel SMBUS ID definitons to the i2c-i801.c driver.
  • Loading branch information
torvalds committed May 23, 2011
2 parents a77febb + 9251bac commit 5e152b4
Show file tree
Hide file tree
Showing 30 changed files with 818 additions and 177 deletions.
9 changes: 9 additions & 0 deletions Documentation/ABI/testing/sysfs-bus-pci
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ Description:
hot-remove the PCI device and any of its children.
Depends on CONFIG_HOTPLUG.

What: /sys/bus/pci/devices/.../pci_bus/.../rescan
Date: May 2011
Contact: Linux PCI developers <[email protected]>
Description:
Writing a non-zero value to this attribute will
force a rescan of the bus and all child buses,
and re-discover devices removed earlier from this
part of the device tree. Depends on CONFIG_HOTPLUG.

What: /sys/bus/pci/devices/.../rescan
Date: January 2009
Contact: Linux PCI developers <[email protected]>
Expand Down
2 changes: 0 additions & 2 deletions arch/x86/include/asm/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,6 @@ void default_teardown_msi_irqs(struct pci_dev *dev);
#include "pci_64.h"
#endif

void dma32_reserve_bootmem(void);

/* implement the pci_ DMA API in terms of the generic device dma_ one */
#include <asm-generic/pci-dma-compat.h>

Expand Down
64 changes: 0 additions & 64 deletions arch/x86/kernel/pci-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,74 +68,10 @@ int dma_set_mask(struct device *dev, u64 mask)
}
EXPORT_SYMBOL(dma_set_mask);

#if defined(CONFIG_X86_64) && !defined(CONFIG_NUMA)
static __initdata void *dma32_bootmem_ptr;
static unsigned long dma32_bootmem_size __initdata = (128ULL<<20);

static int __init parse_dma32_size_opt(char *p)
{
if (!p)
return -EINVAL;
dma32_bootmem_size = memparse(p, &p);
return 0;
}
early_param("dma32_size", parse_dma32_size_opt);

void __init dma32_reserve_bootmem(void)
{
unsigned long size, align;
if (max_pfn <= MAX_DMA32_PFN)
return;

/*
* check aperture_64.c allocate_aperture() for reason about
* using 512M as goal
*/
align = 64ULL<<20;
size = roundup(dma32_bootmem_size, align);
dma32_bootmem_ptr = __alloc_bootmem_nopanic(size, align,
512ULL<<20);
/*
* Kmemleak should not scan this block as it may not be mapped via the
* kernel direct mapping.
*/
kmemleak_ignore(dma32_bootmem_ptr);
if (dma32_bootmem_ptr)
dma32_bootmem_size = size;
else
dma32_bootmem_size = 0;
}
static void __init dma32_free_bootmem(void)
{

if (max_pfn <= MAX_DMA32_PFN)
return;

if (!dma32_bootmem_ptr)
return;

free_bootmem(__pa(dma32_bootmem_ptr), dma32_bootmem_size);

dma32_bootmem_ptr = NULL;
dma32_bootmem_size = 0;
}
#else
void __init dma32_reserve_bootmem(void)
{
}
static void __init dma32_free_bootmem(void)
{
}

#endif

void __init pci_iommu_alloc(void)
{
struct iommu_table_entry *p;

/* free the range so iommu could get some range less than 4G */
dma32_free_bootmem();

sort_iommu_table(__iommu_table, __iommu_table_end);
check_iommu_entries(__iommu_table, __iommu_table_end);

Expand Down
1 change: 0 additions & 1 deletion arch/x86/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,6 @@ void __init setup_arch(char **cmdline_p)

initmem_init();
memblock_find_dma_reserve();
dma32_reserve_bootmem();

#ifdef CONFIG_KVM_CLOCK
kvmclock_init();
Expand Down
17 changes: 6 additions & 11 deletions arch/x86/pci/direct.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,29 +280,24 @@ void __init pci_direct_init(int type)

int __init pci_direct_probe(void)
{
struct resource *region, *region2;

if ((pci_probe & PCI_PROBE_CONF1) == 0)
goto type2;
region = request_region(0xCF8, 8, "PCI conf1");
if (!region)
if (!request_region(0xCF8, 8, "PCI conf1"))
goto type2;

if (pci_check_type1()) {
raw_pci_ops = &pci_direct_conf1;
port_cf9_safe = true;
return 1;
}
release_resource(region);
release_region(0xCF8, 8);

type2:
if ((pci_probe & PCI_PROBE_CONF2) == 0)
return 0;
region = request_region(0xCF8, 4, "PCI conf2");
if (!region)
if (!request_region(0xCF8, 4, "PCI conf2"))
return 0;
region2 = request_region(0xC000, 0x1000, "PCI conf2");
if (!region2)
if (!request_region(0xC000, 0x1000, "PCI conf2"))
goto fail2;

if (pci_check_type2()) {
Expand All @@ -311,8 +306,8 @@ int __init pci_direct_probe(void)
return 2;
}

release_resource(region2);
release_region(0xC000, 0x1000);
fail2:
release_resource(region);
release_region(0xCF8, 4);
return 0;
}
4 changes: 3 additions & 1 deletion arch/x86/pci/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,9 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
|| (device >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN &&
device <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX)
|| (device >= PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN &&
device <= PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX)) {
device <= PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX)
|| (device >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN &&
device <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX)) {
r->name = "PIIX/ICH";
r->get = pirq_piix_get;
r->set = pirq_piix_set;
Expand Down
10 changes: 10 additions & 0 deletions arch/x86/pci/mmconfig-shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,16 @@ static void __init __pci_mmcfg_init(int early)
if (list_empty(&pci_mmcfg_list))
return;

if (pcibios_last_bus < 0) {
const struct pci_mmcfg_region *cfg;

list_for_each_entry(cfg, &pci_mmcfg_list, list) {
if (cfg->segment)
break;
pcibios_last_bus = cfg->end_bus;
}
}

if (pci_mmcfg_arch_init())
pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
else {
Expand Down
14 changes: 10 additions & 4 deletions drivers/acpi/pci_root.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,12 +596,18 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
dev_info(root->bus->bridge,
"ACPI _OSC control (0x%02x) granted\n", flags);
} else {
dev_dbg(root->bus->bridge,
"ACPI _OSC request failed (code %d)\n", status);
printk(KERN_INFO "Unable to assume _OSC PCIe control. "
"Disabling ASPM\n");
dev_info(root->bus->bridge,
"ACPI _OSC request failed (%s), "
"returned control mask: 0x%02x\n",
acpi_format_exception(status), flags);
pr_info("ACPI _OSC control for PCIe not granted, "
"disabling ASPM\n");
pcie_no_aspm();
}
} else {
dev_info(root->bus->bridge,
"Unable to request _OSC control "
"(_OSC support mask: 0x%02x)\n", flags);
}

pci_acpi_add_bus_pm_notifier(device, root->bus);
Expand Down
1 change: 1 addition & 0 deletions drivers/i2c/busses/i2c-i801.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@
/* Older devices have their ID defined in <linux/pci_ids.h> */
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22
#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS 0x1e22
/* Patsburg also has three 'Integrated Device Function' SMBus controllers */
#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0 0x1d70
#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/e1000e/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -5361,7 +5361,7 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep,
#ifdef CONFIG_PCIEASPM
static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
{
pci_disable_link_state(pdev, state);
pci_disable_link_state_locked(pdev, state);
}
#else
static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
Expand Down
18 changes: 15 additions & 3 deletions drivers/pci/access.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,33 +143,41 @@ static noinline void pci_wait_ucfg(struct pci_dev *dev)
__remove_wait_queue(&pci_ucfg_wait, &wait);
}

/* Returns 0 on success, negative values indicate error. */
#define PCI_USER_READ_CONFIG(size,type) \
int pci_user_read_config_##size \
(struct pci_dev *dev, int pos, type *val) \
{ \
int ret = 0; \
u32 data = -1; \
if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
if (PCI_##size##_BAD) \
return -EINVAL; \
raw_spin_lock_irq(&pci_lock); \
if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \
ret = dev->bus->ops->read(dev->bus, dev->devfn, \
pos, sizeof(type), &data); \
raw_spin_unlock_irq(&pci_lock); \
*val = (type)data; \
if (ret > 0) \
ret = -EINVAL; \
return ret; \
}

/* Returns 0 on success, negative values indicate error. */
#define PCI_USER_WRITE_CONFIG(size,type) \
int pci_user_write_config_##size \
(struct pci_dev *dev, int pos, type val) \
{ \
int ret = -EIO; \
if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
if (PCI_##size##_BAD) \
return -EINVAL; \
raw_spin_lock_irq(&pci_lock); \
if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev); \
ret = dev->bus->ops->write(dev->bus, dev->devfn, \
pos, sizeof(type), val); \
raw_spin_unlock_irq(&pci_lock); \
if (ret > 0) \
ret = -EINVAL; \
return ret; \
}

Expand Down Expand Up @@ -197,6 +205,8 @@ struct pci_vpd_pci22 {
* This code has to spin since there is no other notification from the PCI
* hardware. Since the VPD is often implemented by serial attachment to an
* EEPROM, it may take many milliseconds to complete.
*
* Returns 0 on success, negative values indicate error.
*/
static int pci_vpd_pci22_wait(struct pci_dev *dev)
{
Expand All @@ -212,7 +222,7 @@ static int pci_vpd_pci22_wait(struct pci_dev *dev)
for (;;) {
ret = pci_user_read_config_word(dev, vpd->cap + PCI_VPD_ADDR,
&status);
if (ret)
if (ret < 0)
return ret;

if ((status & PCI_VPD_ADDR_F) == vpd->flag) {
Expand Down Expand Up @@ -324,6 +334,8 @@ static ssize_t pci_vpd_pci22_write(struct pci_dev *dev, loff_t pos, size_t count
vpd->busy = true;
vpd->flag = 0;
ret = pci_vpd_pci22_wait(dev);
if (ret < 0)
break;

pos += sizeof(u32);
}
Expand Down
6 changes: 0 additions & 6 deletions drivers/pci/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,6 @@ int pci_bus_add_child(struct pci_bus *bus)

bus->is_added = 1;

retval = device_create_file(&bus->dev, &dev_attr_cpuaffinity);
if (retval)
return retval;

retval = device_create_file(&bus->dev, &dev_attr_cpulistaffinity);

/* Create legacy_io and legacy_mem files for this bus */
pci_create_legacy_files(bus);

Expand Down
7 changes: 7 additions & 0 deletions drivers/pci/hotplug/acpiphp_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,13 @@ static int __ref enable_device(struct acpiphp_slot *slot)
acpiphp_set_hpp_values(bus);
acpiphp_set_acpi_region(slot);
pci_enable_bridges(bus);

list_for_each_entry(dev, &bus->devices, bus_list) {
/* Assume that newly added devices are powered on already. */
if (!dev->is_added)
dev->current_state = PCI_D0;
}

pci_bus_add_devices(bus);

list_for_each_entry(func, &slot->funcs, sibling) {
Expand Down
45 changes: 45 additions & 0 deletions drivers/pci/hotplug/pcihp_slot.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,47 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
*/
}

/* Program PCIE MaxPayload setting on device: ensure parent maxpayload <= device */
static int pci_set_payload(struct pci_dev *dev)
{
int pos, ppos;
u16 pctl, psz;
u16 dctl, dsz, dcap, dmax;
struct pci_dev *parent;

parent = dev->bus->self;
pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
if (!pos)
return 0;

/* Read Device MaxPayload capability and setting */
pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &dctl);
pci_read_config_word(dev, pos + PCI_EXP_DEVCAP, &dcap);
dsz = (dctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5;
dmax = (dcap & PCI_EXP_DEVCAP_PAYLOAD);

/* Read Parent MaxPayload setting */
ppos = pci_find_capability(parent, PCI_CAP_ID_EXP);
if (!ppos)
return 0;
pci_read_config_word(parent, ppos + PCI_EXP_DEVCTL, &pctl);
psz = (pctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5;

/* If parent payload > device max payload -> error
* If parent payload > device payload -> set speed
* If parent payload <= device payload -> do nothing
*/
if (psz > dmax)
return -1;
else if (psz > dsz) {
dev_info(&dev->dev, "Setting MaxPayload to %d\n", 128 << psz);
pci_write_config_word(dev, pos + PCI_EXP_DEVCTL,
(dctl & ~PCI_EXP_DEVCTL_PAYLOAD) +
(psz << 5));
}
return 0;
}

void pci_configure_slot(struct pci_dev *dev)
{
struct pci_dev *cdev;
Expand All @@ -169,6 +210,10 @@ void pci_configure_slot(struct pci_dev *dev)
(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
return;

ret = pci_set_payload(dev);
if (ret)
dev_warn(&dev->dev, "could not set device max payload\n");

memset(&hpp, 0, sizeof(hpp));
ret = pci_get_hp_params(dev, &hpp);
if (ret)
Expand Down
Loading

0 comments on commit 5e152b4

Please sign in to comment.