提交 644a544f 编写于 作者: K Koehrer Mathias (ETAS/ESW5) 提交者: Bjorn Helgaas

PCI: Extending pci=resource_alignment to specify device/vendor IDs

Some uio-based PCI drivers, e.g., uio_cif do not work if the assigned PCI
memory resources are not page aligned.

By using the kernel option "pci=resource_alignment" it is possible to force
single PCI boards to use page alignment for their memory resources.
However, this is fairly cumbersome if several of these boards are in use
as the specification of the cards has to be done via PCI bus/slot/function
number which might change, e.g., by adding another board.

Extend the kernel option "pci=resource_alignment" to allow specification of
relevant devices via PCI device/vendor (and subdevice/subvendor) IDs.  The
specification of the devices via device/vendor is indicated by a leading
string "pci:" as argument to "pci=resource_alignment".  The format of the
specification is pci:<vendor>:<device>[:<subvendor>:<subdevice>]
Signed-off-by: NMathias Koehrer <mathias.koehrer@etas.com>
Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
上级 3b146b24
...@@ -2998,6 +2998,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ...@@ -2998,6 +2998,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
resource_alignment= resource_alignment=
Format: Format:
[<order of align>@][<domain>:]<bus>:<slot>.<func>[; ...] [<order of align>@][<domain>:]<bus>:<slot>.<func>[; ...]
[<order of align>@]pci:<vendor>:<device>\
[:<subvendor>:<subdevice>][; ...]
Specifies alignment and device to reassign Specifies alignment and device to reassign
aligned memory resources. aligned memory resources.
If <order of align> is not specified, If <order of align> is not specified,
......
...@@ -4755,6 +4755,7 @@ static DEFINE_SPINLOCK(resource_alignment_lock); ...@@ -4755,6 +4755,7 @@ static DEFINE_SPINLOCK(resource_alignment_lock);
static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev)
{ {
int seg, bus, slot, func, align_order, count; int seg, bus, slot, func, align_order, count;
unsigned short vendor, device, subsystem_vendor, subsystem_device;
resource_size_t align = 0; resource_size_t align = 0;
char *p; char *p;
...@@ -4768,28 +4769,55 @@ static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev) ...@@ -4768,28 +4769,55 @@ static resource_size_t pci_specified_resource_alignment(struct pci_dev *dev)
} else { } else {
align_order = -1; align_order = -1;
} }
if (sscanf(p, "%x:%x:%x.%x%n", if (strncmp(p, "pci:", 4) == 0) {
&seg, &bus, &slot, &func, &count) != 4) { /* PCI vendor/device (subvendor/subdevice) ids are specified */
seg = 0; p += 4;
if (sscanf(p, "%x:%x.%x%n", if (sscanf(p, "%hx:%hx:%hx:%hx%n",
&bus, &slot, &func, &count) != 3) { &vendor, &device, &subsystem_vendor, &subsystem_device, &count) != 4) {
/* Invalid format */ if (sscanf(p, "%hx:%hx%n", &vendor, &device, &count) != 2) {
printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n", printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: pci:%s\n",
p); 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; break;
} }
} }
p += count; else {
if (seg == pci_domain_nr(dev->bus) && if (sscanf(p, "%x:%x:%x.%x%n",
bus == dev->bus->number && &seg, &bus, &slot, &func, &count) != 4) {
slot == PCI_SLOT(dev->devfn) && seg = 0;
func == PCI_FUNC(dev->devfn)) { if (sscanf(p, "%x:%x.%x%n",
if (align_order == -1) &bus, &slot, &func, &count) != 3) {
align = PAGE_SIZE; /* Invalid format */
else printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n",
align = 1 << align_order; p);
/* Found */ break;
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 != ',') { if (*p != ';' && *p != ',') {
/* End of param or invalid format */ /* End of param or invalid format */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册