Page MenuHomeFreeBSD

D34703.id104315.diff
No OneTemporary

D34703.id104315.diff

Index: sys/dev/uart/uart_bus_pci.c
===================================================================
--- sys/dev/uart/uart_bus_pci.c
+++ sys/dev/uart/uart_bus_pci.c
@@ -43,6 +43,7 @@
#include <dev/uart/uart.h>
#include <dev/uart/uart_bus.h>
+#include <dev/uart/uart_cpu.h>
#define DEFAULT_RCLK 1843200
@@ -76,6 +77,11 @@
int regshft;
};
+struct pci_unique_id {
+ uint16_t vendor;
+ uint16_t device;
+};
+
#define PCI_NO_MSI 0x40000000
#define PCI_RID_MASK 0x0000ffff
@@ -214,6 +220,44 @@
return ((id->vendor == vendor && id->device == device) ? id : NULL);
}
+extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs;
+
+static const struct pci_unique_id pci_unique_devices[] = {
+{ 0x1d0f, 0x8250 },
+{ 0xffff, 0}
+};
+
+static void
+uart_pci_unique_console_match(device_t dev)
+{
+ struct uart_softc *sc;
+ struct uart_devinfo * sysdev;
+ const struct pci_unique_id * id;
+ uint16_t vendor, device;
+
+ sc = device_get_softc(dev);
+ vendor = pci_get_vendor(dev);
+ device = pci_get_device(dev);
+
+ /* Is this a device known to exist only once in a system? */
+ for (id = pci_unique_devices; id->vendor != 0xffff; id++) {
+ if (id->vendor == vendor && id->device == device)
+ break;
+ }
+ if (id->vendor == 0xffff)
+ return;
+
+ /* If it matches a console, it must be the same device. */
+ SLIST_FOREACH(sysdev, &uart_sysdevs, next) {
+ if (sysdev->pci_info.vendor == vendor &&
+ sysdev->pci_info.device == device &&
+ sysdev->pci_info.valid) {
+ sc->sc_sysdev = sysdev;
+ sysdev->bas.rclk = sc->sc_bas.rclk;
+ }
+ }
+}
+
static int
uart_pci_probe(device_t dev)
{
@@ -251,6 +295,13 @@
/* Bail out on error. */
if (result > 0)
return (result);
+ /*
+ * If we haven't already matched this to a console, check if it's a
+ * PCI device which is known to only exist once in any given system
+ * and we can match it that way.
+ */
+ if (sc->sc_sysdev == NULL)
+ uart_pci_unique_console_match(dev);
/* Set/override the device description. */
if (id->desc)
device_set_desc(dev, id->desc);
Index: sys/dev/uart/uart_cpu.h
===================================================================
--- sys/dev/uart/uart_cpu.h
+++ sys/dev/uart/uart_cpu.h
@@ -52,6 +52,15 @@
extern bus_space_tag_t uart_bus_space_io;
extern bus_space_tag_t uart_bus_space_mem;
+/*
+ * PCI ID used for matching "unique" devices to a console.
+ */
+struct uart_pci_info {
+ uint16_t vendor;
+ uint16_t device;
+ int valid;
+};
+
/*
* Console and debug port device info.
*/
@@ -72,6 +81,7 @@
void *cookie; /* Type dependent use. */
struct mtx *hwmtx;
struct uart_softc *sc; /* valid only from start of attach */
+ struct uart_pci_info pci_info;
};
int uart_cpu_eqres(struct uart_bas *, struct uart_bas *);
Index: sys/dev/uart/uart_cpu_acpi.c
===================================================================
--- sys/dev/uart/uart_cpu_acpi.c
+++ sys/dev/uart/uart_cpu_acpi.c
@@ -36,6 +36,8 @@
#include <machine/bus.h>
+#include <dev/pci/pcireg.h>
+
#include <dev/uart/uart.h>
#include <dev/uart/uart_bus.h>
#include <dev/uart/uart_cpu.h>
@@ -182,6 +184,12 @@
(int)spcr->BaudRate);
goto out;
}
+ if (spcr->PciVendorId != PCIV_INVALID &&
+ spcr->PciDeviceId != PCIV_INVALID) {
+ di->pci_info.vendor = spcr->PciVendorId;
+ di->pci_info.device = spcr->PciDeviceId;
+ di->pci_info.valid = 1;
+ }
/* Apply device tweaks. */
if ((cd->cd_quirks & UART_F_IGNORE_SPCR_REGSHFT) ==

File Metadata

Mime Type
text/plain
Expires
Fri, May 2, 3:10 AM (1 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17897036
Default Alt Text
D34703.id104315.diff (3 KB)

Event Timeline