Merge branch 'pci/resource' into next

* pci/resource:
  unicore32/PCI: Remove pci=firmware command line parameter handling
  ARM/PCI: Remove arch-specific pcibios_enable_device()
  ARM64/PCI: Remove arch-specific pcibios_enable_device()
  MIPS/PCI: Claim bus resources on PCI_PROBE_ONLY set-ups
  ARM/PCI: Claim bus resources on PCI_PROBE_ONLY set-ups
  PCI: generic: Claim bus resources on PCI_PROBE_ONLY set-ups
  PCI: Add generic pci_bus_claim_resources()
  alx: Use pci_(request|release)_mem_regions
  ethernet/intel: Use pci_(request|release)_mem_regions
  GenWQE: Use pci_(request|release)_mem_regions
  lpfc: Use pci_(request|release)_mem_regions
  NVMe: Use pci_(request|release)_mem_regions
  PCI: Add helpers to request/release memory and I/O regions
  PCI: Extending pci=resource_alignment to specify device/vendor IDs
  sparc/PCI: Implement pci_resource_to_user() with pcibios_resource_to_bus()
  powerpc/pci: Implement pci_resource_to_user() with pcibios_resource_to_bus()
  microblaze/PCI: Implement pci_resource_to_user() with pcibios_resource_to_bus()
  PCI: Unify pci_resource_to_user() declarations
  microblaze/PCI: Remove useless __pci_mmap_set_pgprot()
  powerpc/pci: Remove __pci_mmap_set_pgprot()
  PCI: Ignore write combining when mapping I/O port space
This commit is contained in:
Bjorn Helgaas 2016-08-01 12:23:44 -05:00
commit 3efc702378
26 changed files with 271 additions and 282 deletions

View file

@ -154,7 +154,14 @@ int pci_host_common_probe(struct platform_device *pdev,
pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
if (!pci_has_flag(PCI_PROBE_ONLY)) {
/*
* We insert PCI resources into the iomem_resource and
* ioport_resource trees in either pci_bus_claim_resources()
* or pci_bus_assign_resources().
*/
if (pci_has_flag(PCI_PROBE_ONLY)) {
pci_bus_claim_resources(bus);
} else {
pci_bus_size_bridges(bus);
pci_bus_assign_resources(bus);

View file

@ -4953,6 +4953,7 @@ static DEFINE_SPINLOCK(resource_alignment_lock);
static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev)
{
int seg, bus, slot, func, align_order, count;
unsigned short vendor, device, subsystem_vendor, subsystem_device;
resource_size_t align = 0;
char *p;
@ -4966,28 +4967,55 @@ static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev)
} else {
align_order = -1;
}
if (sscanf(p, "%x:%x:%x.%x%n",
&seg, &bus, &slot, &func, &count) != 4) {
seg = 0;
if (sscanf(p, "%x:%x.%x%n",
&bus, &slot, &func, &count) != 3) {
/* Invalid format */
printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n",
p);
if (strncmp(p, "pci:", 4) == 0) {
/* PCI vendor/device (subvendor/subdevice) ids are specified */
p += 4;
if (sscanf(p, "%hx:%hx:%hx:%hx%n",
&vendor, &device, &subsystem_vendor, &subsystem_device, &count) != 4) {
if (sscanf(p, "%hx:%hx%n", &vendor, &device, &count) != 2) {
printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: pci:%s\n",
p);
break;
}
subsystem_vendor = subsystem_device = 0;
}
p += count;
if ((!vendor || (vendor == dev->vendor)) &&
(!device || (device == dev->device)) &&
(!subsystem_vendor || (subsystem_vendor == dev->subsystem_vendor)) &&
(!subsystem_device || (subsystem_device == dev->subsystem_device))) {
if (align_order == -1)
align = PAGE_SIZE;
else
align = 1 << align_order;
/* Found */
break;
}
}
p += count;
if (seg == pci_domain_nr(dev->bus) &&
bus == dev->bus->number &&
slot == PCI_SLOT(dev->devfn) &&
func == PCI_FUNC(dev->devfn)) {
if (align_order == -1)
align = PAGE_SIZE;
else
align = 1 << align_order;
/* Found */
break;
else {
if (sscanf(p, "%x:%x:%x.%x%n",
&seg, &bus, &slot, &func, &count) != 4) {
seg = 0;
if (sscanf(p, "%x:%x.%x%n",
&bus, &slot, &func, &count) != 3) {
/* Invalid format */
printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n",
p);
break;
}
}
p += count;
if (seg == pci_domain_nr(dev->bus) &&
bus == dev->bus->number &&
slot == PCI_SLOT(dev->devfn) &&
func == PCI_FUNC(dev->devfn)) {
if (align_order == -1)
align = PAGE_SIZE;
else
align = 1 << align_order;
/* Found */
break;
}
}
if (*p != ';' && *p != ',') {
/* End of param or invalid format */

View file

@ -231,7 +231,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
{
struct pci_dev *dev = PDE_DATA(file_inode(file));
struct pci_filp_private *fpriv = file->private_data;
int i, ret;
int i, ret, write_combine;
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
@ -245,9 +245,12 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
if (i >= PCI_ROM_RESOURCE)
return -ENODEV;
if (fpriv->mmap_state == pci_mmap_mem)
write_combine = fpriv->write_combine;
else
write_combine = 0;
ret = pci_mmap_page_range(dev, vma,
fpriv->mmap_state,
fpriv->write_combine);
fpriv->mmap_state, write_combine);
if (ret < 0)
return ret;

View file

@ -1423,6 +1423,74 @@ void pci_bus_assign_resources(const struct pci_bus *bus)
}
EXPORT_SYMBOL(pci_bus_assign_resources);
static void pci_claim_device_resources(struct pci_dev *dev)
{
int i;
for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
struct resource *r = &dev->resource[i];
if (!r->flags || r->parent)
continue;
pci_claim_resource(dev, i);
}
}
static void pci_claim_bridge_resources(struct pci_dev *dev)
{
int i;
for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
struct resource *r = &dev->resource[i];
if (!r->flags || r->parent)
continue;
pci_claim_bridge_resource(dev, i);
}
}
static void pci_bus_allocate_dev_resources(struct pci_bus *b)
{
struct pci_dev *dev;
struct pci_bus *child;
list_for_each_entry(dev, &b->devices, bus_list) {
pci_claim_device_resources(dev);
child = dev->subordinate;
if (child)
pci_bus_allocate_dev_resources(child);
}
}
static void pci_bus_allocate_resources(struct pci_bus *b)
{
struct pci_bus *child;
/*
* Carry out a depth-first search on the PCI bus
* tree to allocate bridge apertures. Read the
* programmed bridge bases and recursively claim
* the respective bridge resources.
*/
if (b->self) {
pci_read_bridge_bases(b);
pci_claim_bridge_resources(b->self);
}
list_for_each_entry(child, &b->children, node)
pci_bus_allocate_resources(child);
}
void pci_bus_claim_resources(struct pci_bus *b)
{
pci_bus_allocate_resources(b);
pci_bus_allocate_dev_resources(b);
}
EXPORT_SYMBOL(pci_bus_claim_resources);
static void __pci_bridge_assign_resources(const struct pci_dev *bridge,
struct list_head *add_head,
struct list_head *fail_head)