Commit 7d8905d0 authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Greg Kroah-Hartman

serial: 8250_pci: Enable device after we check black list

If the board we are guessing has been listed in black list we don't need
to enable it twice. The associated driver, if any, will take care about
proper initialization.

To achieve this we split out two helper functions, i.e.
serial_pci_is_class_communication() and serial_pci_is_blacklisted() which will
be called before pcim_enable_device(). We can do this since PCI specification
requires class, device and vendor ID registers to be always present in the
configuration space.

As an example what happens before this patch applied
(These are some debug prints, don't search for them in kernel sources):

	serial 0000:00:04.1: Mapped GSI28 to IRQ28
	serial 0000:00:04.2: Mapped GSI29 to IRQ29
	serial 0000:00:04.3: Mapped GSI54 to IRQ54
	8250_mid 0000:00:04.1: Mapped GSI28 to IRQ28
	8250_mid 0000:00:04.2: Mapped GSI29 to IRQ29
	8250_mid 0000:00:04.3: Mapped GSI54 to IRQ54

After we will have just last three lines out of above.

	8250_mid 0000:00:04.1: Mapped GSI28 to IRQ28
	8250_mid 0000:00:04.2: Mapped GSI29 to IRQ29
	8250_mid 0000:00:04.3: Mapped GSI54 to IRQ54

While here, correct a value of error code mentioned in the comment of
serial_pci_guess_board().
Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c7ac15ce
...@@ -3384,17 +3384,8 @@ static const struct pci_device_id blacklist[] = { ...@@ -3384,17 +3384,8 @@ static const struct pci_device_id blacklist[] = {
{ PCI_VDEVICE(COMMTECH, PCI_ANY_ID), }, { PCI_VDEVICE(COMMTECH, PCI_ANY_ID), },
}; };
/* static int serial_pci_is_class_communication(struct pci_dev *dev)
* Given a complete unknown PCI device, try to use some heuristics to
* guess what the configuration might be, based on the pitiful PCI
* serial specs. Returns 0 on success, 1 on failure.
*/
static int
serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
{ {
const struct pci_device_id *bldev;
int num_iomem, num_port, first_port = -1, i;
/* /*
* If it is not a communications device or the programming * If it is not a communications device or the programming
* interface is greater than 6, give up. * interface is greater than 6, give up.
...@@ -3407,6 +3398,13 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) ...@@ -3407,6 +3398,13 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
(dev->class & 0xff) > 6) (dev->class & 0xff) > 6)
return -ENODEV; return -ENODEV;
return 0;
}
static int serial_pci_is_blacklisted(struct pci_dev *dev)
{
const struct pci_device_id *bldev;
/* /*
* Do not access blacklisted devices that are known not to * Do not access blacklisted devices that are known not to
* feature serial ports or are handled by other modules. * feature serial ports or are handled by other modules.
...@@ -3419,6 +3417,19 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) ...@@ -3419,6 +3417,19 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
return -ENODEV; return -ENODEV;
} }
return 0;
}
/*
* Given a complete unknown PCI device, try to use some heuristics to
* guess what the configuration might be, based on the pitiful PCI
* serial specs. Returns 0 on success, -ENODEV on failure.
*/
static int
serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board)
{
int num_iomem, num_port, first_port = -1, i;
num_iomem = num_port = 0; num_iomem = num_port = 0;
for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) {
if (pci_resource_flags(dev, i) & IORESOURCE_IO) { if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
...@@ -3639,6 +3650,14 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent) ...@@ -3639,6 +3650,14 @@ pciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
board = &pci_boards[ent->driver_data]; board = &pci_boards[ent->driver_data];
rc = serial_pci_is_class_communication(dev);
if (rc)
return rc;
rc = serial_pci_is_blacklisted(dev);
if (rc)
return rc;
rc = pcim_enable_device(dev); rc = pcim_enable_device(dev);
pci_save_state(dev); pci_save_state(dev);
if (rc) if (rc)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment