Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Jan 2017 16:30:27 +0000 (UTC)
From:      Bruce M Simpson <bms@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r311987 - head/sys/dev/uart
Message-ID:  <201701121630.v0CGURes049619@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bms
Date: Thu Jan 12 16:30:27 2017
New Revision: 311987
URL: https://svnweb.freebsd.org/changeset/base/311987

Log:
  Allow uart(4) to use MSI interrupts on single-port PCI instances.
  
  Do this here as puc(4) disallows single-port instances; at least
  one multi-port PCIe UART chip (in this case, the ASIX MCS9922)
  present separate PCI configuration space (functions) for each UART.
  
  Tested using lrzsz and a null-modem cable. The ExpressCard/34
  variants containing the MCS9922 should also use MSI with this change.
  
  Reviewed by:		jhb, imp, rpokala
  MFC after:		2 weeks
  Differential Revision:	https://reviews.freebsd.org/D9123

Modified:
  head/sys/dev/uart/uart_bus_pci.c
  head/sys/dev/uart/uart_core.c

Modified: head/sys/dev/uart/uart_bus_pci.c
==============================================================================
--- head/sys/dev/uart/uart_bus_pci.c	Thu Jan 12 16:24:10 2017	(r311986)
+++ head/sys/dev/uart/uart_bus_pci.c	Thu Jan 12 16:30:27 2017	(r311987)
@@ -45,12 +45,14 @@ __FBSDID("$FreeBSD$");
 #define	DEFAULT_RCLK	1843200
 
 static int uart_pci_probe(device_t dev);
+static int uart_pci_attach(device_t dev);
+static int uart_pci_detach(device_t dev);
 
 static device_method_t uart_pci_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		uart_pci_probe),
-	DEVMETHOD(device_attach,	uart_bus_attach),
-	DEVMETHOD(device_detach,	uart_bus_detach),
+	DEVMETHOD(device_attach,	uart_pci_attach),
+	DEVMETHOD(device_detach,	uart_pci_detach),
 	DEVMETHOD(device_resume,	uart_bus_resume),
 	DEVMETHOD_END
 };
@@ -209,4 +211,40 @@ uart_pci_probe(device_t dev)
 	return (result);
 }
 
+static int
+uart_pci_attach(device_t dev)
+{
+	struct uart_softc *sc;
+	int count;
+
+	sc = device_get_softc(dev);
+
+	/*
+	 * Use MSI in preference to legacy IRQ if available.
+	 * Whilst some PCIe UARTs support >1 MSI vector, use only the first.
+	 */
+	if (pci_msi_count(dev) > 0) {
+		count = 1;
+		if (pci_alloc_msi(dev, &count) == 0) {
+			sc->sc_irid = 1;
+			device_printf(dev, "Using %d MSI message\n", count);
+		}
+	}
+
+	return (uart_bus_attach(dev));
+}
+
+static int
+uart_pci_detach(device_t dev)
+{
+	struct uart_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	if (sc->sc_irid != 0)
+		pci_release_msi(dev);
+
+	return (uart_bus_detach(dev));
+}
+
 DRIVER_MODULE(uart, pci, uart_pci_driver, uart_devclass, NULL, NULL);

Modified: head/sys/dev/uart/uart_core.c
==============================================================================
--- head/sys/dev/uart/uart_core.c	Thu Jan 12 16:24:10 2017	(r311986)
+++ head/sys/dev/uart/uart_core.c	Thu Jan 12 16:30:27 2017	(r311987)
@@ -677,7 +677,6 @@ uart_bus_attach(device_t dev)
 	 * safest thing to do.
 	 */
 	if (filt != FILTER_SCHEDULE_THREAD && !uart_force_poll) {
-		sc->sc_irid = 0;
 		sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ,
 		    &sc->sc_irid, RF_ACTIVE | RF_SHAREABLE);
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201701121630.v0CGURes049619>