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: (41 commits)
  PCI: fix pci_ioremap_bar() on s390
  PCI: fix AER capability check
  PCI: use pci_find_ext_capability everywhere
  PCI: remove #ifdef DEBUG around dev_dbg call
  PCI hotplug: fix get_##name return value problem
  PCI: document the pcie_aspm kernel parameter
  PCI: introduce an pci_ioremap(pdev, barnr) function
  powerpc/PCI: Add legacy PCI access via sysfs
  PCI: Add ability to mmap legacy_io on some platforms
  PCI: probing debug message uniformization
  PCI: support PCIe ARI capability
  PCI: centralize the capabilities code in probe.c
  PCI: centralize the capabilities code in pci-sysfs.c
  PCI: fix 64-vbit prefetchable memory resource BARs
  PCI: replace cfg space size (256/4096) by macros.
  PCI: use resource_size() everywhere.
  PCI: use same arg names in PCI_VDEVICE comment
  PCI hotplug: rpaphp: make debug var unique
  PCI: use %pF instead of print_fn_descriptor_symbol() in quirks.c
  PCI: fix hotplug get_##name return value problem
  ...
  • Loading branch information
Linus Torvalds committed Oct 20, 2008
2 parents 92b29b8 + 9649987 commit a0bfb67
Show file tree
Hide file tree
Showing 47 changed files with 1,024 additions and 679 deletions.
6 changes: 2 additions & 4 deletions Documentation/MSI-HOWTO.txt
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,8 @@ software system can set different pages for controlling accesses to the
MSI-X structure. The implementation of MSI support requires the PCI
subsystem, not a device driver, to maintain full control of the MSI-X
table/MSI-X PBA (Pending Bit Array) and MMIO address space of the MSI-X
table/MSI-X PBA. A device driver is prohibited from requesting the MMIO
address space of the MSI-X table/MSI-X PBA. Otherwise, the PCI subsystem
will fail enabling MSI-X on its hardware device when it calls the function
pci_enable_msix().
table/MSI-X PBA. A device driver should not access the MMIO address
space of the MSI-X table/MSI-X PBA.

5.3.2 API pci_enable_msix

Expand Down
4 changes: 4 additions & 0 deletions Documentation/PCI/pci.txt
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ need pass only as many optional fields as necessary:
o class and classmask fields default to 0
o driver_data defaults to 0UL.

Note that driver_data must match the value used by any of the pci_device_id
entries defined in the driver. This makes the driver_data field mandatory
if all the pci_device_id entries have a non-zero driver_data value.

Once added, the driver probe routine will be invoked for any unclaimed
PCI devices listed in its (newly updated) pci_ids list.

Expand Down
11 changes: 3 additions & 8 deletions Documentation/PCI/pcieaer-howto.txt
Original file line number Diff line number Diff line change
Expand Up @@ -203,22 +203,17 @@ to mmio_enabled.

3.3 helper functions

3.3.1 int pci_find_aer_capability(struct pci_dev *dev);
pci_find_aer_capability locates the PCI Express AER capability
in the device configuration space. If the device doesn't support
PCI-Express AER, the function returns 0.

3.3.2 int pci_enable_pcie_error_reporting(struct pci_dev *dev);
3.3.1 int pci_enable_pcie_error_reporting(struct pci_dev *dev);
pci_enable_pcie_error_reporting enables the device to send error
messages to root port when an error is detected. Note that devices
don't enable the error reporting by default, so device drivers need
call this function to enable it.

3.3.3 int pci_disable_pcie_error_reporting(struct pci_dev *dev);
3.3.2 int pci_disable_pcie_error_reporting(struct pci_dev *dev);
pci_disable_pcie_error_reporting disables the device to send error
messages to root port when an error is detected.

3.3.4 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
3.3.3 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
pci_cleanup_aer_uncorrect_error_status cleanups the uncorrectable
error status register.

Expand Down
31 changes: 19 additions & 12 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ parameter is applicable:
X86-64 X86-64 architecture is enabled.
More X86-64 boot options can be found in
Documentation/x86_64/boot-options.txt .
X86 Either 32bit or 64bit x86 (same as X86-32+X86-64)

In addition, the following text indicates that the option:

Expand Down Expand Up @@ -1588,17 +1589,17 @@ and is between 256 and 4096 characters. It is defined in the file
See also Documentation/paride.txt.

pci=option[,option...] [PCI] various PCI subsystem options:
off [X86-32] don't probe for the PCI bus
off [X86] don't probe for the PCI bus
bios [X86-32] force use of PCI BIOS, don't access
the hardware directly. Use this if your machine
has a non-standard PCI host bridge.
nobios [X86-32] disallow use of PCI BIOS, only direct
hardware access methods are allowed. Use this
if you experience crashes upon bootup and you
suspect they are caused by the BIOS.
conf1 [X86-32] Force use of PCI Configuration
conf1 [X86] Force use of PCI Configuration
Mechanism 1.
conf2 [X86-32] Force use of PCI Configuration
conf2 [X86] Force use of PCI Configuration
Mechanism 2.
noaer [PCIE] If the PCIEAER kernel config parameter is
enabled, this kernel boot option can be used to
Expand All @@ -1618,37 +1619,37 @@ and is between 256 and 4096 characters. It is defined in the file
this option if the kernel is unable to allocate
IRQs or discover secondary PCI buses on your
motherboard.
rom [X86-32] Assign address space to expansion ROMs.
rom [X86] Assign address space to expansion ROMs.
Use with caution as certain devices share
address decoders between ROMs and other
resources.
norom [X86-32,X86_64] Do not assign address space to
norom [X86] Do not assign address space to
expansion ROMs that do not already have
BIOS assigned address ranges.
irqmask=0xMMMM [X86-32] Set a bit mask of IRQs allowed to be
irqmask=0xMMMM [X86] Set a bit mask of IRQs allowed to be
assigned automatically to PCI devices. You can
make the kernel exclude IRQs of your ISA cards
this way.
pirqaddr=0xAAAAA [X86-32] Specify the physical address
pirqaddr=0xAAAAA [X86] Specify the physical address
of the PIRQ table (normally generated
by the BIOS) if it is outside the
F0000h-100000h range.
lastbus=N [X86-32] Scan all buses thru bus #N. Can be
lastbus=N [X86] Scan all buses thru bus #N. Can be
useful if the kernel is unable to find your
secondary buses and you want to tell it
explicitly which ones they are.
assign-busses [X86-32] Always assign all PCI bus
assign-busses [X86] Always assign all PCI bus
numbers ourselves, overriding
whatever the firmware may have done.
usepirqmask [X86-32] Honor the possible IRQ mask stored
usepirqmask [X86] Honor the possible IRQ mask stored
in the BIOS $PIR table. This is needed on
some systems with broken BIOSes, notably
some HP Pavilion N5400 and Omnibook XE3
notebooks. This will have no effect if ACPI
IRQ routing is enabled.
noacpi [X86-32] Do not use ACPI for IRQ routing
noacpi [X86] Do not use ACPI for IRQ routing
or for PCI scanning.
use_crs [X86-32] Use _CRS for PCI resource
use_crs [X86] Use _CRS for PCI resource
allocation.
routeirq Do IRQ routing for all PCI devices.
This is normally done in pci_enable_device(),
Expand Down Expand Up @@ -1677,6 +1678,12 @@ and is between 256 and 4096 characters. It is defined in the file
reserved for the CardBus bridge's memory
window. The default value is 64 megabytes.

pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
Management.
off Disable ASPM.
force Enable ASPM even on devices that claim not to support it.
WARNING: Forcing ASPM on may cause system lockups.

pcmv= [HW,PCMCIA] BadgePAD 4

pd. [PARIDE]
Expand Down
12 changes: 2 additions & 10 deletions arch/ia64/include/asm/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,8 @@ extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine);
#define HAVE_PCI_LEGACY
extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
struct vm_area_struct *vma);
extern ssize_t pci_read_legacy_io(struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count);
extern ssize_t pci_write_legacy_io(struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count);
extern int pci_mmap_legacy_mem(struct kobject *kobj,
struct bin_attribute *attr,
struct vm_area_struct *vma);
struct vm_area_struct *vma,
enum pci_mmap_state mmap_state);

#define pci_get_legacy_mem platform_pci_get_legacy_mem
#define pci_legacy_read platform_pci_legacy_read
Expand Down
7 changes: 6 additions & 1 deletion arch/ia64/pci/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,12 +614,17 @@ char *ia64_pci_get_legacy_mem(struct pci_bus *bus)
* vector to get the base address.
*/
int
pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma)
pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state)
{
unsigned long size = vma->vm_end - vma->vm_start;
pgprot_t prot;
char *addr;

/* We only support mmap'ing of legacy memory space */
if (mmap_state != pci_mmap_mem)
return -ENOSYS;

/*
* Avoid attribute aliasing. See Documentation/ia64/aliasing.txt
* for more details.
Expand Down
7 changes: 7 additions & 0 deletions arch/powerpc/include/asm/pci-bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ struct pci_controller {
unsigned long pci_io_size;
#endif

/* Some machines have a special region to forward the ISA
* "memory" cycles such as VGA memory regions. Left to 0
* if unsupported
*/
resource_size_t isa_mem_phys;
resource_size_t isa_mem_size;

struct pci_ops *ops;
unsigned int __iomem *cfg_addr;
void __iomem *cfg_data;
Expand Down
11 changes: 11 additions & 0 deletions arch/powerpc/include/asm/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
#define HAVE_PCI_MMAP 1

extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val,
size_t count);
extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,
size_t count);
extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
struct vm_area_struct *vma,
enum pci_mmap_state mmap_state);

#define HAVE_PCI_LEGACY 1

#if defined(CONFIG_PPC64) || defined(CONFIG_NOT_COHERENT_CACHE)
/*
* For 64-bit kernels, pci_unmap_{single,page} is not a nop.
Expand Down Expand Up @@ -226,5 +236,6 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
extern void pcibios_do_bus_setup(struct pci_bus *bus);
extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus);


#endif /* __KERNEL__ */
#endif /* __ASM_POWERPC_PCI_H */
136 changes: 135 additions & 1 deletion arch/powerpc/kernel/pci-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,8 @@ pgprot_t pci_phys_mem_access_prot(struct file *file,
pci_dev_put(pdev);
}

DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
DBG("non-PCI map for %llx, prot: %lx\n",
(unsigned long long)offset, prot);

return __pgprot(prot);
}
Expand Down Expand Up @@ -490,6 +491,131 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
return ret;
}

/* This provides legacy IO read access on a bus */
int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size)
{
unsigned long offset;
struct pci_controller *hose = pci_bus_to_host(bus);
struct resource *rp = &hose->io_resource;
void __iomem *addr;

/* Check if port can be supported by that bus. We only check
* the ranges of the PHB though, not the bus itself as the rules
* for forwarding legacy cycles down bridges are not our problem
* here. So if the host bridge supports it, we do it.
*/
offset = (unsigned long)hose->io_base_virt - _IO_BASE;
offset += port;

if (!(rp->flags & IORESOURCE_IO))
return -ENXIO;
if (offset < rp->start || (offset + size) > rp->end)
return -ENXIO;
addr = hose->io_base_virt + port;

switch(size) {
case 1:
*((u8 *)val) = in_8(addr);
return 1;
case 2:
if (port & 1)
return -EINVAL;
*((u16 *)val) = in_le16(addr);
return 2;
case 4:
if (port & 3)
return -EINVAL;
*((u32 *)val) = in_le32(addr);
return 4;
}
return -EINVAL;
}

/* This provides legacy IO write access on a bus */
int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size)
{
unsigned long offset;
struct pci_controller *hose = pci_bus_to_host(bus);
struct resource *rp = &hose->io_resource;
void __iomem *addr;

/* Check if port can be supported by that bus. We only check
* the ranges of the PHB though, not the bus itself as the rules
* for forwarding legacy cycles down bridges are not our problem
* here. So if the host bridge supports it, we do it.
*/
offset = (unsigned long)hose->io_base_virt - _IO_BASE;
offset += port;

if (!(rp->flags & IORESOURCE_IO))
return -ENXIO;
if (offset < rp->start || (offset + size) > rp->end)
return -ENXIO;
addr = hose->io_base_virt + port;

/* WARNING: The generic code is idiotic. It gets passed a pointer
* to what can be a 1, 2 or 4 byte quantity and always reads that
* as a u32, which means that we have to correct the location of
* the data read within those 32 bits for size 1 and 2
*/
switch(size) {
case 1:
out_8(addr, val >> 24);
return 1;
case 2:
if (port & 1)
return -EINVAL;
out_le16(addr, val >> 16);
return 2;
case 4:
if (port & 3)
return -EINVAL;
out_le32(addr, val);
return 4;
}
return -EINVAL;
}

/* This provides legacy IO or memory mmap access on a bus */
int pci_mmap_legacy_page_range(struct pci_bus *bus,
struct vm_area_struct *vma,
enum pci_mmap_state mmap_state)
{
struct pci_controller *hose = pci_bus_to_host(bus);
resource_size_t offset =
((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT;
resource_size_t size = vma->vm_end - vma->vm_start;
struct resource *rp;

pr_debug("pci_mmap_legacy_page_range(%04x:%02x, %s @%llx..%llx)\n",
pci_domain_nr(bus), bus->number,
mmap_state == pci_mmap_mem ? "MEM" : "IO",
(unsigned long long)offset,
(unsigned long long)(offset + size - 1));

if (mmap_state == pci_mmap_mem) {
if ((offset + size) > hose->isa_mem_size)
return -ENXIO;
offset += hose->isa_mem_phys;
} else {
unsigned long io_offset = (unsigned long)hose->io_base_virt - _IO_BASE;
unsigned long roffset = offset + io_offset;
rp = &hose->io_resource;
if (!(rp->flags & IORESOURCE_IO))
return -ENXIO;
if (roffset < rp->start || (roffset + size) > rp->end)
return -ENXIO;
offset += hose->io_base_phys;
}
pr_debug(" -> mapping phys %llx\n", (unsigned long long)offset);

vma->vm_pgoff = offset >> PAGE_SHIFT;
vma->vm_page_prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
}

void pci_resource_to_user(const struct pci_dev *dev, int bar,
const struct resource *rsrc,
resource_size_t *start, resource_size_t *end)
Expand Down Expand Up @@ -592,6 +718,12 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
cpu_addr = of_translate_address(dev, ranges + 3);
size = of_read_number(ranges + pna + 3, 2);
ranges += np;

/* If we failed translation or got a zero-sized region
* (some FW try to feed us with non sensical zero sized regions
* such as power3 which look like some kind of attempt at exposing
* the VGA memory hole)
*/
if (cpu_addr == OF_BAD_ADDR || size == 0)
continue;

Expand Down Expand Up @@ -665,6 +797,8 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
isa_hole = memno;
if (primary || isa_mem_base == 0)
isa_mem_base = cpu_addr;
hose->isa_mem_phys = cpu_addr;
hose->isa_mem_size = size;
}

/* We get the PCI/Mem offset from the first range or
Expand Down
Loading

0 comments on commit a0bfb67

Please sign in to comment.