Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 Apr 2011 19:19:25 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r221182 - head/sys/dev/puc
Message-ID:  <201104281919.p3SJJPK4051952@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Thu Apr 28 19:19:25 2011
New Revision: 221182
URL: http://svn.freebsd.org/changeset/base/221182

Log:
  Add support for Oxford PCI Express Expresso family devices.
  For these devices, the number of supported ports is read from a register
  in BAR 0.
  
  PR:		kern/134878
  Submitted by:	David Wood  david of wood2 org uk
  MFC after:	1 week

Modified:
  head/sys/dev/puc/pucdata.c

Modified: head/sys/dev/puc/pucdata.c
==============================================================================
--- head/sys/dev/puc/pucdata.c	Thu Apr 28 19:08:31 2011	(r221181)
+++ head/sys/dev/puc/pucdata.c	Thu Apr 28 19:19:25 2011	(r221182)
@@ -56,6 +56,7 @@ static puc_config_f puc_config_syba;
 static puc_config_f puc_config_siig;
 static puc_config_f puc_config_timedia;
 static puc_config_f puc_config_titan;
+static puc_config_f puc_config_oxford_pcie;
 
 const struct puc_cfg puc_pci_devices[] = {
 
@@ -619,7 +620,7 @@ const struct puc_cfg puc_pci_devices[] =
 	 * Boards with an Oxford Semiconductor chip.
 	 *
 	 * Oxford Semiconductor provides documentation for their chip at:
-	 * <URL:http://www.oxsemi.com/products/uarts/index.html>;
+	 * <URL:http://www.plxtech.com/products/uart/>;
 	 *
 	 * As sold by Kouwell <URL:http://www.kouwell.com/>.
 	 * I/O Flex PCI I/O Card Model-223 with 4 serial and 1 parallel ports.
@@ -679,6 +680,63 @@ const struct puc_cfg puc_pci_devices[] =
 	    PUC_PORT_4S, 0x10, 0, 8,
 	},
 
+	/*
+	 * Oxford Semiconductor PCI Express Expresso family
+	 *
+	 * Found in many 'native' PCI Express serial boards such as:
+	 *
+	 * eMegatech MP954ER4 (4 port) and MP958ER8 (8 port)
+	 * <URL:http://www.emegatech.com.tw/pdrs232pcie.html>;
+	 *
+	 * Lindy 51189 (4 port)
+	 * <URL:http://www.lindy.com>; <URL:http://tinyurl.com/lindy-51189>;
+	 * 
+	 * StarTech.com PEX4S952 (4 port) and PEX8S952 (8 port)
+	 * <URL:http://www.startech.com>;
+	 */
+
+	{   0x1415, 0xc158, 0xffff, 0,
+	    "Oxford Semiconductor OXPCIe952 UARTs",
+	    DEFAULT_RCLK * 0x22,
+	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
+	    .config_function = puc_config_oxford_pcie
+	},
+
+	{   0x1415, 0xc15d, 0xffff, 0,
+	    "Oxford Semiconductor OXPCIe952 UARTs (function 1)",
+	    DEFAULT_RCLK * 0x22,
+	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
+	    .config_function = puc_config_oxford_pcie
+	},
+
+	{   0x1415, 0xc208, 0xffff, 0,
+	    "Oxford Semiconductor OXPCIe954 UARTs",
+	    DEFAULT_RCLK * 0x22,
+	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
+	    .config_function = puc_config_oxford_pcie
+	},
+
+	{   0x1415, 0xc20d, 0xffff, 0,
+	    "Oxford Semiconductor OXPCIe954 UARTs (function 1)",
+	    DEFAULT_RCLK * 0x22,
+	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
+	    .config_function = puc_config_oxford_pcie
+	},
+
+	{   0x1415, 0xc308, 0xffff, 0,
+	    "Oxford Semiconductor OXPCIe958 UARTs",
+	    DEFAULT_RCLK * 0x22,
+	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
+	    .config_function = puc_config_oxford_pcie
+	},
+
+	{   0x1415, 0xc30d, 0xffff, 0,
+	    "Oxford Semiconductor OXPCIe958 UARTs (function 1)",
+	    DEFAULT_RCLK * 0x22,
+	    PUC_PORT_NONSTANDARD, 0x10, 0, -1,
+	    .config_function = puc_config_oxford_pcie
+	},
+
 	{   0x14d2, 0x8010, 0xffff, 0,
 	    "VScom PCI-100L",
 	    DEFAULT_RCLK * 8,
@@ -1253,6 +1311,81 @@ puc_config_timedia(struct puc_softc *sc,
 }
 
 static int
+puc_config_oxford_pcie(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
+    intptr_t *res)
+{
+	const struct puc_cfg *cfg = sc->sc_cfg;
+	int idx;
+	struct puc_bar *bar;
+	uint8_t value;
+
+	switch (cmd) {
+	case PUC_CFG_SETUP:
+		device_printf(sc->sc_dev, "%d UARTs detected\n",
+			sc->sc_nports);
+
+		/* Set UARTs to enhanced mode */
+		bar = puc_get_bar(sc, cfg->rid);
+		if (bar == NULL)
+			return (ENXIO);
+
+		for (idx = 0; idx < sc->sc_nports; idx++) {
+			value = bus_read_1(bar->b_res, 0x1000 + (idx << 9)
+				+ 0x92);
+			bus_write_1(bar->b_res, 0x1000 + (idx << 9) + 0x92,
+				value | 0x10);
+		}
+
+		return (0);
+	case PUC_CFG_GET_LEN:
+		*res = 0x200;
+		return (0);
+	case PUC_CFG_GET_NPORTS:
+		/*
+		 * Check if we are being called from puc_bfe_attach()
+		 * or puc_bfe_probe(). If puc_bfe_probe(), we cannot
+		 * puc_get_bar(), so we return a value of 16. This has cosmetic
+		 * side-effects at worst; in PUC_CFG_GET_DESC,
+		 * (int)sc->sc_cfg_data will not contain the true number of
+		 * ports in PUC_CFG_GET_DESC, but we are not implementing that
+		 * call for this device family anyway.
+		 *
+		 * The check is for initialisation of sc->sc_bar[idx], which is
+		 * only done in puc_bfe_attach().
+		 */
+		idx = 0;
+		do {
+			if (sc->sc_bar[idx++].b_rid != -1) {
+				sc->sc_cfg_data = 16;
+				*res = sc->sc_cfg_data;
+				return (0);
+			}
+		} while (idx < PUC_PCI_BARS);
+
+		bar = puc_get_bar(sc, cfg->rid);
+		if (bar == NULL)
+			return (ENXIO);
+
+		value = bus_read_1(bar->b_res, 0x04);
+		if (value == 0)
+			return (ENXIO);
+
+		sc->sc_cfg_data = value;
+		*res = sc->sc_cfg_data;
+		return (0);
+	case PUC_CFG_GET_OFS:
+		*res = 0x1000 + (port << 9);
+		return (0);
+	case PUC_CFG_GET_TYPE:
+		*res = PUC_TYPE_SERIAL;
+		return (0);
+	default:
+		break;
+	}
+	return (ENXIO);
+}
+
+static int
 puc_config_titan(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
     intptr_t *res)
 {



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