svn commit: r221182 - head/sys/dev/puc
John Baldwin
jhb at FreeBSD.org
Thu Apr 28 19:19:25 UTC 2011
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)
{
More information about the svn-src-head
mailing list