[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20190227071809.4204-1-saumah@gmail.com>
Date: Wed, 27 Feb 2019 15:18:09 +0800
From: Morris Ku <saumah@...il.com>
To: gregkh@...uxfoundation.org
Cc: morris_ku@...ix.com, linux-kernel@...r.kernel.org,
Morris Ku <saumah@...il.com>
Subject: [PATCH 3/5] Add SUNIX Multi-I/O board driver
Add driver, Kconfig and Makefile entry.
---
char/snx/Kconfig | 7 +
char/snx/Makefile | 9 +
char/snx/snx_devtable.c | 669 +++++++++++++++++
char/snx/snx_main.c | 1583 +++++++++++++++++++++++++++++++++++++++
4 files changed, 2268 insertions(+)
create mode 100644 char/snx/Kconfig
create mode 100644 char/snx/Makefile
create mode 100644 char/snx/snx_devtable.c
create mode 100644 char/snx/snx_main.c
diff --git a/char/snx/Kconfig b/char/snx/Kconfig
new file mode 100644
index 00000000..d203c850
--- /dev/null
+++ b/char/snx/Kconfig
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Character device configuration
+#
+
+config SNX
+ tristate "SUNIX Multi-IO Board Drvier"
diff --git a/char/snx/Makefile b/char/snx/Makefile
new file mode 100644
index 00000000..47348926
--- /dev/null
+++ b/char/snx/Makefile
@@ -0,0 +1,9 @@
+#
+# drivers/char/snx/Makefile
+#
+# Makefile for the sunix multi-io device drivers.
+#
+
+obj-$(CONFIG_SNX) += snx.o
+
+snx-y := snx_main.o snx_devtable.o snx_serial.o snx_parallel.o snx_share.o snx_ieee1284.o snx_ieee1284_ops.o snx_ppdev.o snx_lp.o
diff --git a/char/snx/snx_devtable.c b/char/snx/snx_devtable.c
new file mode 100644
index 00000000..9084f006
--- /dev/null
+++ b/char/snx/snx_devtable.c
@@ -0,0 +1,669 @@
+#include "snx_common.h"
+
+
+PCI_BOARD snx_pci_board_conf[] = {
+ // mode none
+ {
+ // VenID DevID SubVenID SubSysID SerPort ParPort IntrBar IntrOffset Name BoardFlag part_number
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_TEST, 0, 0, 0, 0x00, "none", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 'n', -1, 0, 0, -1, 0, 0, 0x0000, SUNNONE_HWID },
+ },
+ },
+
+ // mode 4027A
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4027A, 1, 0, 0, 0x1C, "4027", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ },
+ },
+
+ // mode 4027D
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4027D, 1, 0, 0, 0x00, "4027", BOARDFLAG_REMAP, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 2, 0, 8, -1, 0, 0, 0x0000, SUN1699_HWID },
+ },
+ },
+
+ // mode 4037A, 4037AL
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4037A, 2, 0, 0, 0x1C, "4037", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ },
+ },
+
+ // mode 4037D
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4037D, 2, 0, 0, 0x00, "4037", BOARDFLAG_REMAP, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 2, 0, 8, -1, 0, 0, 0x0000, SUN1699_HWID },
+ { 's', 3, 0, 8, -1, 0, 0, 0x0000, SUN1699_HWID },
+ },
+ },
+
+ // mode 4036A3V
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4036A3V, 2, 0, 0, 0x1C, "4036", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ },
+ },
+
+
+ // mode 4056A, 4056P
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4056A, 4, 0, 0, 0x1C, "4056", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ { 's', 1, 0, 8, -1, 0, 0, 0x0004, SUN1699_HWID },
+ { 's', 1, 8, 8, -1, 0, 0, 0x0008, SUN1699_HWID },
+ },
+ },
+
+
+ // mode 4056D
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4056D, 4, 0, 0, 0x00, "4056", BOARDFLAG_REMAP, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 2, 0, 8, -1, 0, 0, 0x0000, SUN1699_HWID },
+ { 's', 3, 0, 8, -1, 0, 0, 0x0000, SUN1699_HWID },
+ { 's', 4, 0, 8, -1, 0, 0, 0x0000, SUN1699_HWID },
+ { 's', 5, 0, 8, -1, 0, 0, 0x0000, SUN1699_HWID },
+ },
+ },
+
+ // mode 4055WN, 4056WN, 4056DW
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4056DW, 4, 0, 0, 0x1C, "4056", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ { 's', 1, 0, 8, -1, 0, 0, 0x0004, SUN1699_HWID },
+ { 's', 1, 8, 8, -1, 0, 0, 0x0008, SUN1699_HWID },
+ },
+ },
+
+ // mode 4066A
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4066A, 8, 0, 0, 0x1C, "4066", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ { 's', 1, 0, 8, -1, 0, 0, 0x0004, SUN1699_HWID },
+ { 's', 1, 8, 8, -1, 0, 0, 0x0008, SUN1699_HWID },
+ { 's', 2, 0, 8, -1, 0, 0, 0x0010, SUN1699_HWID },
+ { 's', 3, 0, 8, -1, 0, 0, 0x0020, SUN1699_HWID },
+ { 's', 4, 0, 8, -1, 0, 0, 0x0040, SUN1699_HWID },
+ { 's', 5, 0, 8, -1, 0, 0, 0x0080, SUN1699_HWID },
+ },
+ },
+
+ // mode 4066R
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4066R, 8, 0, 0, 0x1C, "4066", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ { 's', 1, 0, 8, -1, 0, 0, 0x0004, SUN1699_HWID },
+ { 's', 1, 8, 8, -1, 0, 0, 0x0008, SUN1699_HWID },
+ { 's', 2, 0, 8, -1, 0, 0, 0x0010, SUN1699_HWID },
+ { 's', 3, 0, 8, -1, 0, 0, 0x0020, SUN1699_HWID },
+ { 's', 4, 0, 8, -1, 0, 0, 0x0040, SUN1699_HWID },
+ { 's', 5, 0, 8, -1, 0, 0, 0x0080, SUN1699_HWID },
+ },
+ },
+
+ // mode 8139
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8139, 2, 0, 0, 0x1C, "8139", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ },
+ },
+
+ // mode 8139S, 8139SI
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8139S, 2, 0, 0, 0x1C, "8139", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ },
+ },
+
+ // mode 8159
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8159, 4, 0, 0, 0x1C, "8159", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ { 's', 1, 0, 8, -1, 0, 0, 0x0004, SUN1699_HWID },
+ { 's', 1, 8, 8, -1, 0, 0, 0x0008, SUN1699_HWID },
+ },
+ },
+
+// mode 8159S, 8159SI
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8159S, 4, 0, 0, 0x1C, "8159", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ { 's', 1, 0, 8, -1, 0, 0, 0x0004, SUN1699_HWID },
+ { 's', 1, 8, 8, -1, 0, 0, 0x0008, SUN1699_HWID },
+ },
+ },
+
+ // mode 8169
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8169, 8, 0, 0, 0x1C, "8169", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ { 's', 1, 0, 8, -1, 0, 0, 0x0004, SUN1699_HWID },
+ { 's', 1, 8, 8, -1, 0, 0, 0x0008, SUN1699_HWID },
+ { 's', 2, 0, 8, -1, 0, 0, 0x0010, SUN1699_HWID },
+ { 's', 3, 0, 8, -1, 0, 0, 0x0020, SUN1699_HWID },
+ { 's', 4, 0, 8, -1, 0, 0, 0x0040, SUN1699_HWID },
+ { 's', 5, 0, 8, -1, 0, 0, 0x0080, SUN1699_HWID },
+ },
+ },
+
+ // mode 8169S, 8169SI
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8169S, 8, 0, 0, 0x1C, "8169", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ { 's', 1, 0, 8, -1, 0, 0, 0x0004, SUN1699_HWID },
+ { 's', 1, 8, 8, -1, 0, 0, 0x0008, SUN1699_HWID },
+ { 's', 2, 0, 8, -1, 0, 0, 0x0010, SUN1699_HWID },
+ { 's', 3, 0, 8, -1, 0, 0, 0x0020, SUN1699_HWID },
+ { 's', 4, 0, 8, -1, 0, 0, 0x0040, SUN1699_HWID },
+ { 's', 5, 0, 8, -1, 0, 0, 0x0080, SUN1699_HWID },
+ },
+ },
+
+
+ /* support by system parport_pc driver
+ // mode 4008A
+ {
+ VENID_GOLDEN, DEVID_G_PARALL, SUBVENID_GOLDEN, SUBDEVID_4008A, 0, 1, 0, 0x00, "4008", BOARDFLAG_NONE, PART_NUMBER_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 'p', 0, 0, 8, 1, 0, 8, 0x0000, SUN1888_HWID },
+ },
+ },
+
+ // mode 4018A
+ {
+ VENID_GOLDEN, DEVID_G_PARALL, SUBVENID_GOLDEN, SUBDEVID_4018A, 0, 2, 0, 0x00, "4018", BOARDFLAG_NONE, PART_NUMBER_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 'p', 0, 0, 8, 1, 0, 8, 0x0000, SUN1888_HWID },
+ { 'p', 2, 0, 8, 3, 0, 8, 0x0000, SUN1888_HWID },
+ },
+ },
+ */
+
+ // mode 4079A
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4079A, 2, 1, 0, 0x1C, "4079", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ { 'p', 2, 0, 8, 3, 0, 8, 0x0000, SUN1689_HWID },
+ },
+ },
+
+ // mode 4089A
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4089A, 2, 2, 0, 0x1C, "4089", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ { 'p', 2, 0, 8, 3, 0, 8, 0x0000, SUN1689_HWID },
+ { 'p', 4, 0, 8, 5, 0, 8, 0x0000, SUN1689_HWID },
+ },
+ },
+
+ // mode 4096A
+ {
+ VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4096A, 4, 2, 0, 0x1C, "4096", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1889_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1889_HWID },
+ { 's', 1, 0, 8, -1, 0, 0, 0x0004, SUN1699_HWID },
+ { 's', 1, 8, 8, -1, 0, 0, 0x0008, SUN1699_HWID },
+ { 'p', 2, 0, 8, 3, 0, 8, 0x0000, SUN1689_HWID },
+ { 'p', 4, 0, 8, 5, 0, 8, 0x0000, SUN1689_HWID },
+ },
+ },
+
+ // mode P1002
+ {
+ VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P1002, 2, 0, 1, 0x00, "1002", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUNMATX_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUNMATX_HWID },
+ },
+ },
+
+ // mode P1004
+ {
+ VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P1004, 4, 0, 1, 0x00, "1004", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUNMATX_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUNMATX_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUNMATX_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUNMATX_HWID },
+ },
+ },
+
+ // mode P1008
+ {
+ VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P1008, 8, 0, 1, 0x00, "1008", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUNMATX_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUNMATX_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUNMATX_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUNMATX_HWID },
+ { 's', 0, 32, 8, -1, 0, 0, 0x0010, SUNMATX_HWID },
+ { 's', 0, 40, 8, -1, 0, 0, 0x0020, SUNMATX_HWID },
+ { 's', 0, 48, 8, -1, 0, 0, 0x0040, SUNMATX_HWID },
+ { 's', 0, 56, 8, -1, 0, 0, 0x0080, SUNMATX_HWID },
+ },
+ },
+
+ // mode P1016
+ {
+ VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P1016, 16, 0, 1, 0x00, "1016", BOARDFLAG_NONE | BOARDFLAG_16PORTS, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUNMATX_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUNMATX_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUNMATX_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUNMATX_HWID },
+ { 's', 0, 32, 8, -1, 0, 0, 0x0010, SUNMATX_HWID },
+ { 's', 0, 40, 8, -1, 0, 0, 0x0020, SUNMATX_HWID },
+ { 's', 0, 48, 8, -1, 0, 0, 0x0040, SUNMATX_HWID },
+ { 's', 0, 56, 8, -1, 0, 0, 0x0080, SUNMATX_HWID },
+ { 's', 0, 64, 8, -1, 0, 0, 0x0100, SUNMATX_HWID },
+ { 's', 0, 72, 8, -1, 0, 0, 0x0200, SUNMATX_HWID },
+ { 's', 0, 80, 8, -1, 0, 0, 0x0400, SUNMATX_HWID },
+ { 's', 0, 88, 8, -1, 0, 0, 0x0800, SUNMATX_HWID },
+ { 's', 0, 96, 8, -1, 0, 0, 0x1000, SUNMATX_HWID },
+ { 's', 0, 104, 8, -1, 0, 0, 0x2000, SUNMATX_HWID },
+ { 's', 0, 112, 8, -1, 0, 0, 0x4000, SUNMATX_HWID },
+ { 's', 0, 120, 8, -1, 0, 0, 0x8000, SUNMATX_HWID },
+ },
+ },
+
+ // mode P2002
+ {
+ VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P2002, 2, 0, 1, 0x00, "2002", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUNMATX_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUNMATX_HWID },
+ },
+ },
+
+ // mode P2004
+ {
+ VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P2004, 4, 0, 1, 0x00, "2004", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUNMATX_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUNMATX_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUNMATX_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUNMATX_HWID },
+ },
+ },
+
+ // mode P2008
+ {
+ VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P2008, 8, 0, 1, 0x00, "2008", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUNMATX_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUNMATX_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUNMATX_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUNMATX_HWID },
+ { 's', 0, 32, 8, -1, 0, 0, 0x0010, SUNMATX_HWID },
+ { 's', 0, 40, 8, -1, 0, 0, 0x0020, SUNMATX_HWID },
+ { 's', 0, 48, 8, -1, 0, 0, 0x0040, SUNMATX_HWID },
+ { 's', 0, 56, 8, -1, 0, 0, 0x0080, SUNMATX_HWID },
+ },
+ },
+
+ // mode P3002
+ {
+ VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P3002, 2, 0, 1, 0x00, "3002", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUNMATX_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUNMATX_HWID },
+ },
+ },
+
+ // mode P3004
+ {
+ VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P3004, 4, 0, 1, 0x00, "3004", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUNMATX_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUNMATX_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUNMATX_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUNMATX_HWID },
+ },
+ },
+
+ // mode P3008
+ {
+ VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P3008, 8, 0, 1, 0x00, "3008", BOARDFLAG_NONE, PART_NUMBER_NONE, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUNMATX_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUNMATX_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUNMATX_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUNMATX_HWID },
+ { 's', 0, 32, 8, -1, 0, 0, 0x0010, SUNMATX_HWID },
+ { 's', 0, 40, 8, -1, 0, 0, 0x0020, SUNMATX_HWID },
+ { 's', 0, 48, 8, -1, 0, 0, 0x0040, SUNMATX_HWID },
+ { 's', 0, 56, 8, -1, 0, 0, 0x0080, SUNMATX_HWID },
+ },
+ },
+
+
+ // mode 5027A
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5027A, 1, 0, 3, 0x00, "5027", BOARDFLAG_NONE, 0x01, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ },
+ },
+
+ // mode 5037A
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5037A, 2, 0, 3, 0x00, "5037", BOARDFLAG_NONE, 0x02, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ },
+ },
+
+ // mode 5056A
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5056A, 4, 0, 3, 0x00, "5056", BOARDFLAG_NONE, 0x04, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ },
+ },
+
+ // mode 5066A
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5066A, 8, 0, 3, 0x00, "5066", BOARDFLAG_NONE, 0x08, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ { 's', 1, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 1, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 1, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 1, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ },
+ },
+
+ // mode 5016
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5016A, 16, 0, 3, 0x00, "5016", BOARDFLAG_NONE | BOARDFLAG_16PORTS, 0x10, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ { 's', 1, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 1, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 1, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 1, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ { 's', 1, 64, 8, -1, 0, 0, 0x0010, SUN1999_HWID },
+ { 's', 1, 72, 8, -1, 0, 0, 0x0020, SUN1999_HWID },
+ { 's', 1, 80, 8, -1, 0, 0, 0x0040, SUN1999_HWID },
+ { 's', 1, 88, 8, -1, 0, 0, 0x0080, SUN1999_HWID },
+ { 's', 1, 128, 8, -1, 0, 0, 0x0100, SUN1999_HWID },
+ { 's', 1, 136, 8, -1, 0, 0, 0x0200, SUN1999_HWID },
+ { 's', 1, 144, 8, -1, 0, 0, 0x0400, SUN1999_HWID },
+ { 's', 1, 152, 8, -1, 0, 0, 0x0800, SUN1999_HWID },
+ },
+ },
+
+ // mode 5069A 5069H
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5069A, 1, 1, 3, 0x00, "5069", BOARDFLAG_NONE, 0x01, 0x00, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 'p', 1, 0, 8, 2, 0, 0, 0x0000, SUN1999_HWID },
+ },
+ },
+
+
+ // mode 5079A
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5079A, 2, 1, 3, 0x00, "5079", BOARDFLAG_NONE, 0x02, 0x00, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 'p', 1, 0, 8, 2, 0, 0, 0x0000, SUN1999_HWID },
+ },
+ },
+
+ // mode 5099A
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5099A, 4, 1, 3, 0x00, "5099", BOARDFLAG_NONE, 0x04, 0x00, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ { 'p', 1, 0, 8, 2, 0, 0, 0x0000, SUN1999_HWID },
+ },
+ },
+
+ // mode 5008A
+ {
+ VENID_SUN1999, DEVID_S_PARALL, SUBVENID_SUN1999, SUBDEVID_5008A, 0, 1, 0, 0x00, "5008", BOARDFLAG_NONE, 0x00, 0x00, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+
+ { 'p', 1, 0, 8, 2, 0, 0, 0x0000, SUN1999_HWID },
+ },
+ },
+
+ // mode P2102
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P2102, 2, 0, 3, 0x00, "P2102", BOARDFLAG_NONE, 0x42, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ },
+ },
+
+ // mode P2104
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P2104, 4, 0, 3, 0x00, "P2104", BOARDFLAG_NONE, 0x44, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ },
+ },
+
+ // mode P2108
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P2108, 8, 0, 3, 0x00, "P2108", BOARDFLAG_NONE, 0x48, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ { 's', 1, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 1, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 1, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 1, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ },
+ },
+
+ // mode P2116
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P2116, 16, 0, 3, 0x00, "P2116", BOARDFLAG_NONE | BOARDFLAG_16PORTS, 0x50, CARD_TYPE_UART_ONLY, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ { 's', 1, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 1, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 1, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 1, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ { 's', 1, 64, 8, -1, 0, 0, 0x0010, SUN1999_HWID },
+ { 's', 1, 72, 8, -1, 0, 0, 0x0020, SUN1999_HWID },
+ { 's', 1, 80, 8, -1, 0, 0, 0x0040, SUN1999_HWID },
+ { 's', 1, 88, 8, -1, 0, 0, 0x0080, SUN1999_HWID },
+ { 's', 1, 128, 8, -1, 0, 0, 0x0100, SUN1999_HWID },
+ { 's', 1, 136, 8, -1, 0, 0, 0x0200, SUN1999_HWID },
+ { 's', 1, 144, 8, -1, 0, 0, 0x0400, SUN1999_HWID },
+ { 's', 1, 152, 8, -1, 0, 0, 0x0800, SUN1999_HWID },
+ },
+ },
+
+ // mode IPC-P3104
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P3104, 4, 0, 3, 0x00, "P3104", BOARDFLAG_NONE, 0x84, 0x00, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ },
+ },
+
+ // mode IPC-P3108
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P3108, 8, 0, 3, 0x00, "P3108", BOARDFLAG_NONE, 0x88, 0x00, GPIO_NONE,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ { 's', 1, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 1, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 1, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 1, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ },
+ },
+
+ // CDK1037
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_CASH_2S, 2, 0, 3, 0x00, "CDK1037", BOARDFLAG_NONE, 0x02, CARD_TYPE_UART_GINTR, INTR_GPIO_6PORT,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ },
+ },
+
+ // CDK1056
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_CASH_4S, 4, 0, 3, 0x00, "CDK1056", BOARDFLAG_NONE, 0x04, CARD_TYPE_UART_GINTR, INTR_GPIO_6PORT,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ },
+ },
+
+ // mode DIO-0802
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_DIO0802, 2, 0, 3, 0x00, "DIO0802", BOARDFLAG_NONE, 0x02, CARD_TYPE_UART_GEXTR, EXTR_GPIO_8PORT,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ },
+ },
+
+// mode DIO-1604
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_DIO1604, 4, 0, 3, 0x00, "DIO1604", BOARDFLAG_NONE, 0x04, CARD_TYPE_UART_GEXTR, EXTR_GPIO_16PORT,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ },
+ },
+
+ // mode DIO-3204
+ {
+ VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_DIO3204, 4, 0, 3, 0x00, "DIO3204", BOARDFLAG_NONE, 0x04, CARD_TYPE_UART_GEXTR, EXTR_GPIO_32PORT,
+ {
+ // type bar1 ofs1 len1 bar2 ofs2 len2 intmask flags
+ { 's', 0, 0, 8, -1, 0, 0, 0x0001, SUN1999_HWID },
+ { 's', 0, 8, 8, -1, 0, 0, 0x0002, SUN1999_HWID },
+ { 's', 0, 16, 8, -1, 0, 0, 0x0004, SUN1999_HWID },
+ { 's', 0, 24, 8, -1, 0, 0, 0x0008, SUN1999_HWID },
+ },
+ },
+};
+
diff --git a/char/snx/snx_main.c b/char/snx/snx_main.c
new file mode 100644
index 00000000..5a29be14
--- /dev/null
+++ b/char/snx/snx_main.c
@@ -0,0 +1,1583 @@
+/*
+ *
+ * SUNIX Multi-I/O Board Device Driver
+ *
+ *
+ *
+ * Driver for SUNIX Multi-I/O Board device driver
+ * Based on drivers/char/serial.c, parport_pc.c, ppdev.c and lp.c
+ * by Linus Torvalds, Theodore Ts'o.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * Version: 2.0.4.5
+ * Date: 2018/11/20
+ */
+#include "snx_common.h"
+#include "driver_extd.h"
+
+
+MODULE_AUTHOR(SNX_DRIVER_AUTHOR);
+MODULE_DESCRIPTION(SNX_DRIVER_DESC);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 18))
+MODULE_LICENSE("GPL");
+#endif
+
+extern struct sunix_board sunix_board_table[SNX_BOARDS_MAX];
+extern struct sunix_ser_port sunix_ser_table[SNX_SER_TOTAL_MAX + 1];
+extern struct sunix_par_port sunix_par_table[SNX_PAR_TOTAL_MAX];
+
+char snx_ser_ic_table[SNX_SER_PORT_MAX_UART][10] = {
+ {"UNKNOWN"},
+ {"SUN1889"},
+ {"SUN1699"},
+ {"SUNMATX"},
+ {"SUN1999"}
+};
+
+char snx_par_ic_table[SNX_PAR_PORT_MAX_UART][10] = {
+ {"UNKNOWN"},
+ {"SUN1888"},
+ {"SUN1689"},
+ {"SUNMATX"},
+ {"SUN1999"}
+};
+
+char snx_port_remap[2][10] = {
+ {"NON-REMAP"},
+ {"REMAP"}
+};
+
+enum{
+// golden-serial
+ GOLDEN_BOARD_TEST = 0,
+ GOLDEN_BOARD_4027A,
+ GOLDEN_BOARD_4027D,
+ GOLDEN_BOARD_4037A,
+ GOLDEN_BOARD_4037D,
+ GOLDEN_BOARD_4036A3V,
+ GOLDEN_BOARD_4056A,
+ GOLDEN_BOARD_4056D,
+ GOLDEN_BOARD_4056DW,
+ GOLDEN_BOARD_4066A,
+ GOLDEN_BOARD_4066R,
+ GOLDEN_BOARD_8139,
+ GOLDEN_BOARD_8139S,
+ GOLDEN_BOARD_8159,
+ GOLDEN_BOARD_8159S,
+ GOLDEN_BOARD_8169,
+ GOLDEN_BOARD_8169S,
+
+// golden-parallel, support by system parport_pc driver
+/*
+ GOLDEN_BOARD_4008A,
+ GOLDEN_BOARD_4018A,
+*/
+
+// golden-multi I/O
+ GOLDEN_BOARD_4079A,
+ GOLDEN_BOARD_4089A,
+ GOLDEN_BOARD_4096A,
+
+// matrix-serial
+ MATRIX_BOARD_P1002,
+ MATRIX_BOARD_P1004,
+ MATRIX_BOARD_P1008,
+ MATRIX_BOARD_P1016,
+ MATRIX_BOARD_P2002,
+ MATRIX_BOARD_P2004,
+ MATRIX_BOARD_P2008,
+ MATRIX_BOARD_P3002,
+ MATRIX_BOARD_P3004,
+ MATRIX_BOARD_P3008,
+
+// sun1999-serial RS232
+ SUN1999_BOARD_5027A,
+ SUN1999_BOARD_5037A,
+ SUN1999_BOARD_5056A,
+ SUN1999_BOARD_5066A,
+ SUN1999_BOARD_5016A,
+
+ //sun1999-multi I/O
+ SUN1999_BOARD_5069A,
+ SUN1999_BOARD_5079A,
+ SUN1999_BOARD_5099A,
+
+ //sun1999-parallel
+
+ SUN1999_BOARD_5008A,
+
+ //sun1999-serial RS422/485
+ SUN1999_BOARD_P2102,
+ SUN1999_BOARD_P2104,
+ SUN1999_BOARD_P2108,
+ SUN1999_BOARD_P2116,
+
+ //sun1999 3_in_1
+ SUN1999_BOARD_P3104,
+ SUN1999_BOARD_P3108,
+
+ //cash drawer card
+ SUN1999_BOARD_CASH_2S,
+ SUN1999_BOARD_CASH_4S,
+
+ //DIO
+ SUN1999_BOARD_DIO0802,
+ SUN1999_BOARD_DIO1604,
+ SUN1999_BOARD_DIO3204,
+
+};
+
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+static struct pci_device_id sunix_pci_board_id[] = {
+// golden-serial
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_TEST, 0, 0, GOLDEN_BOARD_TEST},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4027A, 0, 0, GOLDEN_BOARD_4027A},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4027D, 0, 0, GOLDEN_BOARD_4027D},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4037A, 0, 0, GOLDEN_BOARD_4037A},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4037D, 0, 0, GOLDEN_BOARD_4037D},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4036A3V, 0, 0, GOLDEN_BOARD_4036A3V},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4056A, 0, 0, GOLDEN_BOARD_4056A},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4056D, 0, 0, GOLDEN_BOARD_4056D},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4056DW, 0, 0, GOLDEN_BOARD_4056DW},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4066A, 0, 0, GOLDEN_BOARD_4066A},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4066R, 0, 0, GOLDEN_BOARD_4066R},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8139, 0, 0, GOLDEN_BOARD_8139},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8139S, 0, 0, GOLDEN_BOARD_8139S},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8159, 0, 0, GOLDEN_BOARD_8159},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8159S, 0, 0, GOLDEN_BOARD_8159S},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8169, 0, 0, GOLDEN_BOARD_8169},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8169S, 0, 0, GOLDEN_BOARD_8169S},
+
+// golden-parallel, support by system parport_pc driver
+/*
+ {VENID_GOLDEN, DEVID_G_PARALL, SUBVENID_GOLDEN, SUBDEVID_4008A, 0, 0, GOLDEN_BOARD_4008A},
+ {VENID_GOLDEN, DEVID_G_PARALL, SUBVENID_GOLDEN, SUBDEVID_4018A, 0, 0, GOLDEN_BOARD_4018A},
+*/
+
+// golden-multi I/O
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4079A, 0, 0, GOLDEN_BOARD_4079A},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4089A, 0, 0, GOLDEN_BOARD_4089A},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4096A, 0, 0, GOLDEN_BOARD_4096A},
+
+// matrix-serial
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P1002, 0, 0, MATRIX_BOARD_P1002},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P1004, 0, 0, MATRIX_BOARD_P1004},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P1008, 0, 0, MATRIX_BOARD_P1008},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P1016, 0, 0, MATRIX_BOARD_P1016},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P2002, 0, 0, MATRIX_BOARD_P2002},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P2004, 0, 0, MATRIX_BOARD_P2004},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P2008, 0, 0, MATRIX_BOARD_P2008},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P3002, 0, 0, MATRIX_BOARD_P3002},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P3004, 0, 0, MATRIX_BOARD_P3004},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P3008, 0, 0, MATRIX_BOARD_P3008},
+
+ // sun1999-serial RS232
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5027A, 0, 0, SUN1999_BOARD_5027A},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5037A, 0, 0, SUN1999_BOARD_5037A},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5056A, 0, 0, SUN1999_BOARD_5056A},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5066A, 0, 0, SUN1999_BOARD_5066A},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5016A, 0, 0, SUN1999_BOARD_5016A},
+
+ // sun1999-multi I/O
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5069A, 0, 0, SUN1999_BOARD_5069A},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5079A, 0, 0, SUN1999_BOARD_5079A},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5099A, 0, 0, SUN1999_BOARD_5099A},
+
+ // sun1999-parallel
+ {VENID_SUN1999, DEVID_S_PARALL, SUBVENID_SUN1999, SUBDEVID_5008A, 0, 0, SUN1999_BOARD_5008A},
+
+ // sun1999-serial RS422/485
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P2102, 0, 0, SUN1999_BOARD_P2102},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P2104, 0, 0, SUN1999_BOARD_P2104},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P2108, 0, 0, SUN1999_BOARD_P2108},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P2116, 0, 0, SUN1999_BOARD_P2116},
+
+ // sun1999 3_in_1
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P3104, 0, 0, SUN1999_BOARD_P3104},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P3108, 0, 0, SUN1999_BOARD_P3108},
+
+ //cash drawer card 2S
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_CASH_2S, 0, 0, SUN1999_BOARD_CASH_2S},
+
+ //cash drawer card 4S
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_CASH_4S, 0, 0, SUN1999_BOARD_CASH_4S},
+
+ //DIO
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_DIO0802, 0, 0, SUN1999_BOARD_DIO0802},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_DIO1604, 0, 0, SUN1999_BOARD_DIO1604},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_DIO3204, 0, 0, SUN1999_BOARD_DIO3204},
+
+ {0}
+};
+MODULE_DEVICE_TABLE(pci, sunix_pci_board_id);
+#else
+typedef struct{
+ unsigned short vendor;
+ unsigned short device;
+ unsigned short subvendor;
+ unsigned short subdevice;
+ unsigned short driver_data;
+ unsigned short part_number;
+} sunix_pciInfo;
+
+static sunix_pciInfo sunix_pci_board_id[] = {
+// golden-serial
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_TEST, GOLDEN_BOARD_TEST},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4027A, GOLDEN_BOARD_4027A},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4027D, GOLDEN_BOARD_4027D},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4037A, GOLDEN_BOARD_4037A},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4037D, GOLDEN_BOARD_4037D},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4036A3V, GOLDEN_BOARD_4036A3V},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4056A, GOLDEN_BOARD_4056A},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4056D, GOLDEN_BOARD_4056D},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4056DW, GOLDEN_BOARD_4056DW},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4066A, GOLDEN_BOARD_4066A},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4066R, GOLDEN_BOARD_4066R},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8139, GOLDEN_BOARD_8139},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8139S, GOLDEN_BOARD_8139S},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8159, GOLDEN_BOARD_8159},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8159S, GOLDEN_BOARD_8159S},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8169, GOLDEN_BOARD_8169},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_8169S, GOLDEN_BOARD_8169S},
+
+// golden-parallel, support by system parport_pc driver
+/*
+ {VENID_GOLDEN, DEVID_G_PARALL, SUBVENID_GOLDEN, SUBDEVID_4008A, GOLDEN_BOARD_4008A},
+ {VENID_GOLDEN, DEVID_G_PARALL, SUBVENID_GOLDEN, SUBDEVID_4018A, GOLDEN_BOARD_4018A},
+*/
+
+// golden-multi I/O
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4079A, GOLDEN_BOARD_4079A},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4089A, GOLDEN_BOARD_4089A},
+ {VENID_GOLDEN, DEVID_G_SERIAL, SUBVENID_GOLDEN, SUBDEVID_4096A, GOLDEN_BOARD_4096A},
+
+// matrix-serial
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P1002, MATRIX_BOARD_P1002},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P1004, MATRIX_BOARD_P1004},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P1008, MATRIX_BOARD_P1008},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P1016, MATRIX_BOARD_P1016},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P2002, MATRIX_BOARD_P2002},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P2004, MATRIX_BOARD_P2004},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P2008, MATRIX_BOARD_P2008},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P3002, MATRIX_BOARD_P3002},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P3004, MATRIX_BOARD_P3004},
+ {VENID_MATRIX, DEVID_M_SERIAL, SUBVENID_MATRIX, SUBDEVID_P3008, MATRIX_BOARD_P3008},
+
+ // sun1999-serial
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5027A, SUN1999_BOARD_5027A},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5037A, SUN1999_BOARD_5037A},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5056A, SUN1999_BOARD_5056A},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5066A, SUN1999_BOARD_5066A},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5016A, SUN1999_BOARD_5016A},
+
+ // sun1999-multi I/O
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5069A, SUN1999_BOARD_5069A},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5079A, SUN1999_BOARD_5079A},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_5099A, SUN1999_BOARD_5099A},
+
+ // sun1999-parallel
+ {VENID_SUN1999, DEVID_S_PARALL, SUBVENID_SUN1999, SUBDEVID_5008A, SUN1999_BOARD_5008A},
+
+ // sun1999-serial RS422/485
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P2102, SUN1999_BOARD_P2102},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P2104, SUN1999_BOARD_P2104},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P2108, SUN1999_BOARD_P2108},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P2116, SUN1999_BOARD_P2116},
+
+ // sun1999 3_in_1
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P3104, SUN1999_BOARD_P3104},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_P3108, SUN1999_BOARD_P3108},
+
+ //cash drawer card
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_CASH_2S, SUN1999_BOARD_CASH_2S},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_CASH_4S, SUN1999_BOARD_CASH_4S},
+
+ //DIO
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_DIO0802, SUN1999_BOARD_DIO0802},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_DIO1604, SUN1999_BOARD_DIO1604},
+ {VENID_SUN1999, DEVID_S_SERIAL, SUBVENID_SUN1999, SUBDEVID_DIO3204, SUN1999_BOARD_DIO3204},
+
+ {0}
+};
+#endif
+
+
+struct sunix_board sunix_board_table[SNX_BOARDS_MAX];
+struct sunix_ser_port sunix_ser_table[SNX_SER_TOTAL_MAX + 1];
+struct sunix_par_port sunix_par_table[SNX_PAR_TOTAL_MAX];
+
+static int snx_ser_port_total_cnt;
+static int snx_par_port_total_cnt;
+
+int snx_board_count;
+
+static struct snx_ser_driver sunix_ser_reg = {
+ .dev_name = "ttySNX",
+ .major = 0,
+ .minor = 0,
+ .nr = (SNX_SER_TOTAL_MAX + 1),
+};
+
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
+static irqreturn_t sunix_interrupt(int irq, void *dev_id)
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+static irqreturn_t sunix_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+#else
+static void sunix_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+#endif
+{
+ struct sunix_ser_port *sp = NULL;
+ struct sunix_par_port *pp = NULL;
+ struct sunix_board *sb = NULL;
+ int i;
+ int status = 0;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+ int handled = IRQ_NONE;
+#endif
+
+ for (i = 0; i < SNX_BOARDS_MAX; i++) {
+
+ if (dev_id == &(sunix_board_table[i])) {
+ sb = dev_id;
+ break;
+ }
+ }
+
+ if (i == SNX_BOARDS_MAX)
+ status = 1;
+
+ if (!sb)
+ status = 1;
+
+ if (sb->board_enum <= 0)
+ status = 1;
+
+ if (status != 0) {
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+ return handled;
+#else
+ return;
+#endif
+ }
+
+ if ((sb->ser_port > 0) && (sb->ser_isr != NULL)) {
+ sp = &sunix_ser_table[sb->ser_port_index];
+
+ if (!sp) {
+ status = 1;
+ }
+ status = sb->ser_isr(sb, sp);
+ }
+
+ if ((sb->par_port > 0) && (sb->par_isr != NULL)) {
+ pp = &sunix_par_table[sb->par_port_index];
+
+ if (!pp)
+ status = 1;
+
+ status = sb->par_isr(sb, pp);
+ }
+
+ if (status != 0) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+ return handled;
+#else
+ return;
+#endif
+ }
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+ handled = IRQ_HANDLED;
+ return handled;
+#endif
+}
+
+static int snx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ return 0;
+}
+
+static int snx_suspend_one(struct pci_dev *pdev, pm_message_t state)
+{
+ return 0;
+}
+
+static int snx_set_port_termios(struct snx_ser_state *state)
+{
+ struct tty_struct *tty = state->info->tty;
+ struct SNXTERMIOS *termios;
+
+ int retval = 0;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
+ termios = &tty->termios;
+#else
+ termios = tty->termios;
+#endif
+
+ retval = snx_ser_startup(state, 0);
+
+ if (retval == 0)
+ snx_ser_update_termios(state);
+
+ return 0;
+}
+
+static int snx_resume_port_termios(struct snx_ser_info *info)
+{
+ struct snx_ser_state *state = NULL;
+ struct tty_struct *tty = info->tty ;
+
+ state = tty->driver_data;
+ snx_set_port_termios(state);
+
+ return 0;
+}
+
+
+static int snx_resume_port(struct sunix_ser_port *sp)
+{
+ struct snx_ser_port *port = &sp->port;
+ struct snx_ser_info *info = port->info;
+
+ if (info)
+ snx_resume_port_termios(info);
+
+ return 0;
+}
+
+static int snx_resume_one(struct pci_dev *pdev)
+{
+ struct sunix_board *sb = pci_get_drvdata(pdev);
+ struct sunix_ser_port *sp = NULL;
+ int j;
+
+ if (sb == NULL)
+ return 0;
+
+ for (j = 0; j < sb->ser_port; j++) {
+ sp = &sunix_ser_table[j];
+
+ if (sp == NULL)
+ return 0;
+
+ if (sp->port.suspended == 1)
+ snx_resume_port(sp);
+ }
+
+ return 0;
+}
+
+
+static int sunix_pci_board_probe(void)
+{
+ struct sunix_board *sb;
+ struct pci_dev *pdev = NULL;
+ struct pci_dev *pdev_array[4] = {NULL, NULL, NULL, NULL};
+
+ int sunix_pci_board_id_cnt;
+ int tablecnt;
+ int boardcnt;
+ int i;
+ unsigned short int sub_device_id;
+ unsigned short int device_part_number;
+ unsigned int bar3_base_add;
+
+ int status;
+ unsigned int bar3_Byte5;
+ unsigned int bar3_Byte6;
+ unsigned int bar3_Byte7;
+ unsigned int oem_id;
+ unsigned char uart_type;
+ unsigned char gpio_type;
+ unsigned char gpio_card_type;
+ int gpio_ch_cnt;
+
+ // clear and init some variable
+ memset(sunix_board_table, 0, SNX_BOARDS_MAX * sizeof(struct sunix_board));
+
+ for (i = 0; i < SNX_BOARDS_MAX; i++) {
+ sunix_board_table[i].board_enum = -1;
+ sunix_board_table[i].board_number = -1;
+ }
+
+ sunix_pci_board_id_cnt = (sizeof(sunix_pci_board_id) / sizeof(sunix_pci_board_id[0])) - 1;
+
+ // search golden serial and multi-I/O board
+ pdev = NULL;
+ tablecnt = 0;
+ boardcnt = 0;
+ sub_device_id = 0;
+ status = 0;
+
+ while (tablecnt < sunix_pci_board_id_cnt) {
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+ pdev = pci_get_device(VENID_GOLDEN, DEVID_G_SERIAL, pdev);
+#else
+ pdev = pci_find_device(VENID_GOLDEN, DEVID_G_SERIAL, pdev);
+#endif
+
+ if (pdev == NULL) {
+ tablecnt++;
+ continue;
+ }
+
+ if ((tablecnt > 0) && ((pdev == pdev_array[0]) ||
+ (pdev == pdev_array[1]) ||
+ (pdev == pdev_array[2]) ||
+ (pdev == pdev_array[3]))) {
+ continue;
+ }
+
+ pci_read_config_word(pdev, 0x2e, &sub_device_id);
+
+ if (sub_device_id == 0) {
+ printk("SNX Error: SUNIX Board (bus:%d device:%d), in configuration space,\n", pdev->bus->number, PCI_SLOT(pdev->devfn));
+ printk(" subdevice id isn't vaild.\n\n");
+ status = -EIO;
+ return status;
+ }
+
+ if (sub_device_id != sunix_pci_board_id[tablecnt].subdevice)
+ continue;
+
+ if (pdev == NULL) {
+ printk("SNX Error: PCI device object is an NULL pointer !\n\n");
+ status = -EIO;
+ return status;
+ } else {
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 3))
+ pci_disable_device(pdev);
+#endif
+ status = pci_enable_device(pdev);
+
+ if (status != 0) {
+ printk("SNX Error: SUNIX Board Enable Fail !\n\n");
+ status = -ENXIO;
+ return status;
+ }
+ }
+
+ if (snx_pci_board_conf[tablecnt].part_number != 0x00) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 3))
+ pci_disable_device(pdev);
+#endif
+ continue;
+ }
+
+ boardcnt++;
+ if (boardcnt > SNX_BOARDS_MAX) {
+ printk("\n");
+ printk("SNX Error: SUNIX Driver Module Support Four Boards In Maximum !\n\n");
+ status = -ENOSPC;
+ return status;
+ }
+
+ sb = &sunix_board_table[boardcnt-1];
+ pdev_array[boardcnt-1] = pdev;
+ sb->pdev = pdev;
+ sb->bus_number = pdev->bus->number;
+ sb->dev_number = PCI_SLOT(pdev->devfn);
+ sb->board_enum = (int)sunix_pci_board_id[tablecnt].driver_data;
+ sb->pb_info = snx_pci_board_conf[sb->board_enum];
+ sb->board_flag = sb->pb_info.board_flag;
+ sb->board_number = boardcnt - 1;
+ }
+
+ // search golden parallel board
+ pdev = NULL;
+ tablecnt = 0;
+ sub_device_id = 0;
+ status = 0;
+
+ while (tablecnt < sunix_pci_board_id_cnt) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+ pdev = pci_get_device(VENID_GOLDEN, DEVID_G_PARALL, pdev);
+#else
+ pdev = pci_find_device(VENID_GOLDEN, DEVID_G_PARALL, pdev);
+#endif
+ if (pdev == NULL) {
+ tablecnt++;
+ continue;
+ }
+
+ if ((tablecnt > 0) && ((pdev == pdev_array[0]) ||
+ (pdev == pdev_array[1]) ||
+ (pdev == pdev_array[2]) ||
+ (pdev == pdev_array[3]))) {
+ continue;
+ }
+
+ pci_read_config_word(pdev, 0x2e, &sub_device_id);
+
+ if (sub_device_id == 0) {
+ printk("SNX Error: SUNIX Board (bus:%d device:%d), in configuration space,\n", pdev->bus->number, PCI_SLOT(pdev->devfn));
+ printk(" subdevice id isn't vaild.\n\n");
+ status = -EIO;
+ return status;
+ }
+
+ if (sub_device_id != sunix_pci_board_id[tablecnt].subdevice) {
+ continue;
+ }
+
+ if (pdev == NULL) {
+ printk("SNX Error: PCI device object is an NULL pointer !\n\n");
+ status = -EIO;
+ return status;
+ } else {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 3))
+ pci_disable_device(pdev);
+#endif
+ status = pci_enable_device(pdev);
+
+ if (status != 0) {
+ printk("SNX Error: SUNIX Board Enable Fail !\n\n");
+ status = -ENXIO;
+ return status;
+ }
+ }
+
+ boardcnt++;
+ if (boardcnt > SNX_BOARDS_MAX) {
+ printk("\n");
+ printk("SNX Error: SUNIX Driver Module Support Four Boards In Maximum !\n\n");
+ status = -ENOSPC;
+ return status;
+ }
+
+ sb = &sunix_board_table[boardcnt-1];
+ pdev_array[boardcnt-1] = pdev;
+ sb->pdev = pdev;
+ sb->bus_number = pdev->bus->number;
+ sb->dev_number = PCI_SLOT(pdev->devfn);
+ sb->board_enum = (int)sunix_pci_board_id[tablecnt].driver_data;
+ sb->pb_info = snx_pci_board_conf[sb->board_enum];
+ sb->board_flag = sb->pb_info.board_flag;
+ sb->board_number = boardcnt - 1;
+ }
+
+ // search matrix serial board
+ pdev = NULL;
+ tablecnt = 0;
+ sub_device_id = 0;
+ status = 0;
+
+ while (tablecnt < sunix_pci_board_id_cnt) {
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+ pdev = pci_get_device(VENID_MATRIX, DEVID_M_SERIAL, pdev);
+#else
+ pdev = pci_find_device(VENID_MATRIX, DEVID_M_SERIAL, pdev);
+#endif
+
+ if (pdev == NULL) {
+ tablecnt++;
+ continue;
+ }
+
+ if ((tablecnt > 0) && ((pdev == pdev_array[0]) ||
+ (pdev == pdev_array[1]) ||
+ (pdev == pdev_array[2]) ||
+ (pdev == pdev_array[3]))) {
+ continue;
+ }
+
+ pci_read_config_word(pdev, 0x2e, &sub_device_id);
+
+ if (sub_device_id == 0) {
+ printk("SNX Error: SUNIX Board (bus:%d device:%d), in configuration space,\n", pdev->bus->number, PCI_SLOT(pdev->devfn));
+ printk(" subdevice id isn't vaild.\n\n");
+ status = -EIO;
+ return status;
+ }
+
+ if (sub_device_id != sunix_pci_board_id[tablecnt].subdevice)
+ continue;
+ if (pdev == NULL) {
+ printk("SNX Error: PCI device object is an NULL pointer !\n\n");
+ status = -EIO;
+ return status;
+ } else {
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
+
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 3))
+ pci_disable_device(pdev);
+#endif
+
+ status = pci_enable_device(pdev);
+
+ if (status != 0) {
+ printk("SNX Error: SUNIX Board Enable Fail !\n\n");
+ status = -ENXIO;
+ return status;
+ }
+ }
+
+ boardcnt++;
+ if (boardcnt > SNX_BOARDS_MAX) {
+ printk("\n");
+ printk("SNX Error: SUNIX Driver Module Support Four Boards In Maximum !\n\n");
+ status = -ENOSPC;
+ return status;
+ }
+
+ sb = &sunix_board_table[boardcnt-1];
+ pdev_array[boardcnt-1] = pdev;
+ sb->pdev = pdev;
+ sb->bus_number = pdev->bus->number;
+ sb->dev_number = PCI_SLOT(pdev->devfn);
+ sb->board_enum = (int)sunix_pci_board_id[tablecnt].driver_data;
+ sb->pb_info = snx_pci_board_conf[sb->board_enum];
+ sb->board_flag = sb->pb_info.board_flag;
+ sb->board_number = boardcnt - 1;
+ }
+
+ // search sun1999 muti I/O board
+ pdev = NULL;
+ tablecnt = 0;
+ sub_device_id = 0;
+ status = 0;
+ device_part_number = 0;
+ bar3_base_add = 0;
+ bar3_Byte5 = 0;
+ bar3_Byte6 = 0;
+ bar3_Byte7 = 0;
+ oem_id = 0;
+ uart_type = 0;
+ gpio_type = 0;
+ gpio_card_type = 0;
+ gpio_ch_cnt = 0;
+
+ while (tablecnt < sunix_pci_board_id_cnt) {
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+ pdev = pci_get_device(VENID_SUN1999, DEVID_S_SERIAL, pdev);
+#else
+ pdev = pci_find_device(VENID_SUN1999, DEVID_S_SERIAL, pdev);
+#endif
+
+ if (pdev == NULL) {
+ tablecnt++;
+ continue;
+ }
+
+ if ((tablecnt > 0) &&
+ ((pdev == pdev_array[0]) ||
+ (pdev == pdev_array[1]) ||
+ (pdev == pdev_array[2]) ||
+ (pdev == pdev_array[3]))) {
+ continue;
+ }
+
+ pci_read_config_word(pdev, 0x2e, &sub_device_id);
+
+ if (sub_device_id == 0) {
+ printk("SNX Error: SUNIX Board (bus:%d device:%d), in configuration space,\n", pdev->bus->number, PCI_SLOT(pdev->devfn));
+ printk(" subdevice id isn't vaild.\n\n");
+ status = -EIO;
+ return status;
+ }
+
+ if (sub_device_id != sunix_pci_board_id[tablecnt].subdevice)
+ continue;
+
+ if (pdev == NULL) {
+ printk("SNX Error: PCI device object is an NULL pointer !\n\n");
+ status = -EIO;
+ return status;
+ } else {
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 3))
+ pci_disable_device(pdev);
+#endif
+ status = pci_enable_device(pdev);
+
+ if (status != 0) {
+ printk("SNX Error: SUNIX Board Enable Fail !\n\n");
+ status = -ENXIO;
+ return status;
+ }
+ }
+
+ bar3_base_add = pci_resource_start(pdev, 3);
+ device_part_number = inb(bar3_base_add + 5);
+ bar3_Byte5 = device_part_number;
+ bar3_Byte6 = inb(bar3_base_add + 0x06);
+ bar3_Byte7 = inb(bar3_base_add + 0x07);
+ gpio_card_type = ((bar3_Byte7 & 0x18)>>3);
+ oem_id = (bar3_Byte5 | (bar3_Byte6 << 8) | (bar3_Byte7 << 16));
+ uart_type = ((bar3_Byte5 & 0xc0)>>6);
+ gpio_ch_cnt = ((bar3_Byte7 & 0x60)>>5);
+ gpio_type = ((bar3_Byte7 & 0x80)>>7);
+
+ if ((gpio_ch_cnt == 0x00) && (gpio_card_type == 0x01)) {
+ gpio_ch_cnt = 6 ;
+ } else if ((gpio_ch_cnt == 0x00) && (gpio_card_type == 0x02)) {
+ gpio_ch_cnt = 8 ;
+ } else if (gpio_ch_cnt == 0x01) {
+ gpio_ch_cnt = 16 ;
+ } else if (gpio_ch_cnt == 0x02) {
+ gpio_ch_cnt = 32 ;
+ }
+
+ if (device_part_number != snx_pci_board_conf[tablecnt].part_number) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 3))
+ pci_disable_device(pdev);
+#endif
+ continue;
+ } else if (gpio_card_type != snx_pci_board_conf[tablecnt].card_type) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 3))
+ pci_disable_device(pdev);
+#endif
+ continue;
+ } else if (gpio_ch_cnt != snx_pci_board_conf[tablecnt].gpio_ch_cnt) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 3))
+ pci_disable_device(pdev);
+#endif
+ continue;
+ }
+
+ boardcnt++;
+ if (boardcnt > SNX_BOARDS_MAX) {
+ printk("\n");
+ printk("SNX Error: SUNIX Driver Module Support Four Boards In Maximum !\n\n");
+ status = -ENOSPC;
+ return status;
+ }
+
+ sb = &sunix_board_table[boardcnt-1];
+ pdev_array[boardcnt-1] = pdev;
+ sb->pdev = pdev;
+ sb->bus_number = pdev->bus->number;
+ sb->dev_number = PCI_SLOT(pdev->devfn);
+ sb->board_enum = (int)sunix_pci_board_id[tablecnt].driver_data;
+ sb->pb_info = snx_pci_board_conf[sb->board_enum];
+ sb->board_flag = sb->pb_info.board_flag;
+ sb->board_number = boardcnt - 1;
+ sb->oem_id = oem_id ;
+ sb->uart_cnt = sb->pb_info.num_serport ;
+ sb->gpio_chl_cnt = gpio_ch_cnt ;
+ sb->board_uart_type = uart_type ;
+ sb->board_gpio_card_type = gpio_card_type ;
+ sb->board_gpio_type = gpio_type ;
+ }
+
+ // search SUN1999 parallel board
+ pdev = NULL;
+ tablecnt = 0;
+ sub_device_id = 0;
+ status = 0;
+
+ while (tablecnt < sunix_pci_board_id_cnt) {
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+ pdev = pci_get_device(VENID_SUN1999, DEVID_S_PARALL, pdev);
+#else
+ pdev = pci_find_device(VENID_SUN1999, DEVID_S_PARALL, pdev);
+#endif
+
+ if (pdev == NULL) {
+ tablecnt++;
+ continue;
+ }
+
+ if ((tablecnt > 0) &&
+ ((pdev == pdev_array[0]) ||
+ (pdev == pdev_array[1]) ||
+ (pdev == pdev_array[2]) ||
+ (pdev == pdev_array[3]))) {
+ continue;
+ }
+
+ pci_read_config_word(pdev, 0x2e, &sub_device_id);
+
+ if (sub_device_id == 0) {
+ printk("SNX Error: SUNIX Board (bus:%d device:%d), in configuration space,\n", pdev->bus->number, PCI_SLOT(pdev->devfn));
+ printk(" subdevice id isn't vaild.\n\n");
+ status = -EIO;
+ return status;
+ }
+
+ if (sub_device_id != sunix_pci_board_id[tablecnt].subdevice)
+ continue;
+
+ if (pdev == NULL) {
+ printk("SNX Error: PCI device object is an NULL pointer !\n\n");
+ status = -EIO;
+ return status;
+ } else {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 3))
+ pci_disable_device(pdev);
+#endif
+ status = pci_enable_device(pdev);
+
+ if (status != 0) {
+ printk("SNX Error: SUNIX Board Enable Fail !\n\n");
+ status = -ENXIO;
+ return status;
+ }
+ }
+
+ boardcnt++;
+ if (boardcnt > SNX_BOARDS_MAX) {
+ printk("\n");
+ printk("SNX Error: SUNIX Driver Module Support Four Boards In Maximum !\n\n");
+ status = -ENOSPC;
+ return status;
+ }
+
+ sb = &sunix_board_table[boardcnt-1];
+ pdev_array[boardcnt-1] = pdev;
+ sb->pdev = pdev;
+ sb->bus_number = pdev->bus->number;
+ sb->dev_number = PCI_SLOT(pdev->devfn);
+ sb->board_enum = (int)sunix_pci_board_id[tablecnt].driver_data;
+ sb->pb_info = snx_pci_board_conf[sb->board_enum];
+ sb->board_flag = sb->pb_info.board_flag;
+ sb->board_number = boardcnt - 1;
+ }
+
+ // print info
+ if (boardcnt == 0) {
+ printk("SNX Info : No SUNIX Multi-I/O Board Found !\n\n");
+ status = -ENXIO;
+ return status;
+ } else {
+
+ for (i = 0; i < SNX_BOARDS_MAX; i++) {
+ sb = &sunix_board_table[i];
+
+ if (sb->board_enum > 0) {
+ printk("\n");
+
+ if ((sb->pb_info.num_serport > 0) && (sb->pb_info.num_parport > 0)) {
+ printk("SNX Info : Found SUNIX %s Series Board (%dS%dP),\n", sb->pb_info.board_name, sb->pb_info.num_serport, sb->pb_info.num_parport);
+ } else if ((sb->pb_info.num_serport) > 0) {
+ printk("SNX Info : Found SUNIX %s Series Board (%dS),\n", sb->pb_info.board_name, sb->pb_info.num_serport);
+ } else {
+ printk("SNX Info : Found SUNIX %s Series Board (%dP),\n", sb->pb_info.board_name, sb->pb_info.num_parport);
+ }
+ printk(" bus number:%d, device number:%d\n\n", sb->bus_number, sb->dev_number);
+ }
+ }
+ snx_board_count = boardcnt ;
+ }
+
+ return status;
+}
+
+
+static int sunix_get_pci_board_conf(void)
+{
+ struct sunix_board *sb = NULL;
+ struct pci_dev *pdev = NULL;
+ int status = 0;
+ int i;
+ int j;
+
+ for (i = 0; i < SNX_BOARDS_MAX; i++) {
+ sb = &sunix_board_table[i];
+
+ if (sb->board_enum > 0) {
+ pdev = sb->pdev;
+ sb->ports = sb->pb_info.num_serport + sb->pb_info.num_parport;
+ sb->ser_port = sb->pb_info.num_serport;
+ sb->par_port = sb->pb_info.num_parport;
+ snx_ser_port_total_cnt = snx_ser_port_total_cnt + sb->ser_port;
+ snx_par_port_total_cnt = snx_par_port_total_cnt + sb->par_port;
+
+ if (snx_ser_port_total_cnt > SNX_SER_TOTAL_MAX) {
+ printk("SNX Error: Too much serial port, maximum %d ports can be supported !\n\n", SNX_SER_TOTAL_MAX);
+ status = -EIO;
+ return status;
+ }
+
+ if (snx_par_port_total_cnt > SNX_PAR_SUPPORT_MAX) {
+ printk("SNX Error: Too much parallel port, maximum %d ports can be supported !\n\n", SNX_PAR_SUPPORT_MAX);
+ status = -EIO;
+ return status;
+ }
+
+ for (j = 0; j < SNX_PCICFG_BAR_TOTAL; j++) {
+ sb->bar_addr[j] = pci_resource_start(pdev, j);
+ }
+
+ sb->irq = sb->pdev->irq;
+
+ if (sb->irq <= 0) {
+ printk("SNX Error: SUNIX Board %s Series (bus:%d device:%d), in configuartion space, irq isn't valid !\n\n",
+ sb->pb_info.board_name,
+ sb->bus_number,
+ sb->dev_number);
+
+ status = -EIO;
+ return status;
+ }
+ }
+ }
+
+ return status;
+}
+
+
+static int sunix_assign_resource(void)
+{
+ struct sunix_board *sb = NULL;
+ struct sunix_ser_port *sp = NULL;
+ struct sunix_par_port *pp = NULL;
+
+ int status = 0;
+ int i;
+ int j;
+ int k;
+ int ser_n;
+ int ser_port_index = 0;
+
+ memset(sunix_ser_table, 0, (SNX_SER_TOTAL_MAX + 1) * sizeof(struct sunix_ser_port));
+ memset(sunix_par_table, 0, (SNX_PAR_TOTAL_MAX) * sizeof(struct sunix_par_port));
+
+ for (i = 0; i < SNX_BOARDS_MAX; i++) {
+ sb = &sunix_board_table[i];
+
+ if (sb->board_enum > 0) {
+ if (sb->ser_port > 0) {
+ sb->vector_mask = 0;
+
+ // assign serial port resource
+ ser_n = sb->ser_port_index = ser_port_index;
+
+ sp = &sunix_ser_table[ser_n];
+
+ if (sp == NULL) {
+ status = -ENXIO;
+ printk("SNX Error: Serial port table address error !\n");
+ return status;
+ }
+
+ for (j = 0; j < sb->ser_port; j++, ser_n++, sp++) {
+ sp->port.chip_flag = sb->pb_info.port[j].chip_flag;
+ sp->port.iobase = sb->bar_addr[sb->pb_info.port[j].bar1] + sb->pb_info.port[j].offset1;
+
+ if ((sb->board_flag & BOARDFLAG_REMAP) == BOARDFLAG_REMAP) {
+ sp->port.vector = 0;
+ sb->vector_mask = 0x00;
+ } else {
+
+ sp->port.vector = sb->bar_addr[sb->pb_info.intr_vector_bar] + sb->pb_info.intr_vector_offset;
+ sb->vector_mask |= (1 << j);
+ }
+ }
+
+ ser_port_index = ser_port_index + sb->ser_port;
+ }
+
+
+ // assign parallel port resource
+ if (sb->par_port > 0) {
+ k = 0;
+
+ for (j = 0; j < SNX_PAR_TOTAL_MAX; j++) {
+ if ((k + 1) > sb->par_port)
+ break;
+
+ if (j >= SNX_PAR_TOTAL_MAX) {
+ status = -EACCES;
+ printk("SNX Error: Too much parallel port, maximum %d ports can be supported !\n\n", SNX_PAR_TOTAL_MAX);
+ return status;
+ }
+
+ pp = &sunix_par_table[j];
+
+ if (pp == NULL) {
+ status = -ENXIO;
+ printk("SNX Error: Parallel port table address error !\n");
+ return status;
+ }
+
+ if (pp->chip_flag != SUNNONE_HWID) {
+ continue;
+ } else {
+ pp->chip_flag = sb->pb_info.port[k + sb->ser_port].chip_flag;
+
+ pp->base = sb->bar_addr[sb->pb_info.port[k + sb->ser_port].bar1] + sb->pb_info.port[k + sb->ser_port].offset1;
+ pp->base_hi = sb->bar_addr[sb->pb_info.port[k + sb->ser_port].bar2] + sb->pb_info.port[k + sb->ser_port].offset2;
+
+ pp->bus_number = sb->bus_number;
+ pp->dev_number = sb->dev_number;
+ pp->board_enum = sb->board_enum;
+ k++;
+ }
+ }
+ }
+ }
+ }
+
+ return status;
+}
+
+
+static int sunix_ser_port_table_init(void)
+{
+ struct sunix_board *sb = NULL;
+ struct sunix_ser_port *sp = NULL;
+ int status = 0;
+ int i;
+ int j;
+ int n;
+ int AHDC_State = 0;
+ int RS422_State = 0;
+
+ for (i = 0; i < SNX_BOARDS_MAX; i++) {
+
+ sb = &sunix_board_table[i];
+
+ if (sb == NULL) {
+ status = -ENXIO;
+ printk("SNX Error: Board table pointer error !\n");
+ return status;
+ }
+
+ if ((sb->board_enum > 0) && (sb->ser_port > 0)) {
+ n = sb->ser_port_index;
+ sp = &sunix_ser_table[n];
+
+ if (sp == NULL) {
+ status = -ENXIO;
+ printk("SNX Error: Serial port table pointer error !\n");
+ return status;
+ }
+
+ for (j = 0; j < sb->ser_port; j++, n++, sp++) {
+ if (j < 4) {
+ AHDC_State = inb(sb->bar_addr[3]+2) & 0x0F & (0x01 << (((j+1)-1) % 4));
+ RS422_State = inb(sb->bar_addr[3]+3) & 0xF0 & (0x10 << (((j+1)-1) % 4));
+ } else if (j < 8) {
+ AHDC_State = inb(sb->bar_addr[1] + 0x32) & 0x0F & (0x01 << (((j+1)-1) % 4)) ;
+ RS422_State = inb(sb->bar_addr[1] + 0x33) & 0xF0 & (0x10 << (((j+1)-1) % 4)) ;
+ }
+
+ RS422_State = ((RS422_State & 0xF0) >> 4);
+ sp->port.AHDC_State = AHDC_State >> (((j+1)-1)%4);
+ sp->port.RS422_State = RS422_State >> (((j+1)-1)%4);
+
+ sp->port.board_enum = sb->board_enum;
+ sp->port.bus_number = sb->bus_number;
+ sp->port.dev_number = sb->dev_number;
+ sp->port.baud_base = 921600;
+ sp->port.pb_info = sb->pb_info;
+ sp->port.irq = sb->irq;
+ sp->port.line = n;
+ sp->port.uartclk = sp->port.baud_base * 16;
+ sp->port.iotype = SNX_UPIO_PORT;
+ sp->port.flags = ASYNC_SHARE_IRQ;
+ sp->port.ldisc_stop_rx = 0;
+ spin_lock_init(&sp->port.lock);
+
+ if (sp->port.chip_flag == SUN1889_HWID) {
+ sp->port.snx_type = SNX_SER_PORT_SUN1889;
+ sp->port.type = PORT_SER_16650V2;
+ sp->port.fifosize = SUN1889_FIFOSIZE_SET;
+ sp->port.rx_trigger = SUN1889_TRIGGER_LEVEL_SET;
+ } else if (sp->port.chip_flag == SUN1699_HWID) {
+ sp->port.snx_type = SNX_SER_PORT_SUN1699;
+ sp->port.type = PORT_SER_16650V2;
+ sp->port.fifosize = SUN1699_FIFOSIZE_SET;
+ sp->port.rx_trigger = SUN1699_TRIGGER_LEVEL_SET;
+ } else if (sp->port.chip_flag == SUNMATX_HWID) {
+ sp->port.snx_type = SNX_SER_PORT_SUNMATX;
+ sp->port.type = PORT_SER_16750;
+ sp->port.fifosize = SUNMATX_FIFOSIZE_SET;
+ sp->port.rx_trigger = SUNMATX_TRIGGER_LEVEL_SET;
+ } else if (sp->port.chip_flag == SUN1999_HWID) {
+ sp->port.snx_type = SNX_SER_PORT_SUN1999;
+ sp->port.type = PORT_SER_16750;
+ sp->port.fifosize = SUN1999_FIFOSIZE_SET;
+ sp->port.rx_trigger = SUN1999_TRIGGER_LEVEL_SET;
+ } else {
+ sp->port.snx_type = SNX_SER_PORT_UNKNOWN;
+ sp->port.type = PORT_SER_16450;
+ sp->port.fifosize = DEFAULT_FIFOSIZE;
+ sp->port.rx_trigger = DEFAULT_TRIGGER_LEVEL;
+ }
+
+
+ if ((sb->pb_info.board_flag & BOARDFLAG_REMAP) == BOARDFLAG_REMAP) {
+ sp->port.vector_mask = 0;
+ sp->port.port_flag = PORTFLAG_REMAP;
+ } else {
+ sp->port.vector_mask = sb->vector_mask;
+ sp->port.port_flag = PORTFLAG_NONE;
+ }
+
+ if ((sb->pb_info.board_flag & BOARDFLAG_16PORTS) == BOARDFLAG_16PORTS) {
+ sp->port.port_flag |= PORTFLAG_16PORTS;
+ }
+
+ sp->port.setserial_flag = SNX_SER_BAUD_NOTSETSER;
+ }
+
+ sb->ser_isr = sunix_ser_interrupt;
+ } else {
+ sb->ser_isr = NULL;
+ }
+ }
+
+
+ // release io resource
+ for (i = 0; i < SNX_SER_TOTAL_MAX; i++) {
+ sp = &sunix_ser_table[i];
+
+ if (sp->port.iobase > 0) {
+ release_region(sp->port.iobase, SNX_SER_ADDRESS_LENGTH);
+ }
+ }
+ return status;
+}
+
+
+static int sunix_par_port_table_init(void)
+{
+ struct sunix_board *sb = NULL;
+ struct sunix_par_port *pp = NULL;
+ int status = 0;
+ int i;
+ int j;
+ int k;
+
+ for (i = 0; i < SNX_BOARDS_MAX; i++) {
+ sb = &sunix_board_table[i];
+
+ if (sb == NULL) {
+ status = -ENXIO;
+ printk("SNX Error: Board table pointer error !\n");
+ return status;
+ }
+
+ if ((sb->board_enum > 0) && (sb->par_port > 0)) {
+ k = 0;
+ for (j = 0; j < SNX_PAR_TOTAL_MAX; j++) {
+ pp = &sunix_par_table[j];
+
+ if (pp == NULL) {
+ status = -ENXIO;
+ printk("SNX Error: Parallel port table pointer error !\n");
+ return status;
+ }
+
+ if ((k + 1) > sb->par_port) {
+ break;
+ }
+
+
+ if ((pp->bus_number == sb->bus_number) &&
+ (pp->dev_number == sb->dev_number) &&
+ (pp->board_enum == sb->board_enum)) {
+
+ pp->pb_info = sb->pb_info;
+ //pp->irq = sb->irq;
+ pp->irq = PARPORT_IRQ_NONE;
+ pp->portnum = j;
+
+ if (pp->chip_flag == SUN1888_HWID) {
+ pp->snx_type =
+ SNX_PAR_PORT_SUN1888;
+ } else if (pp->chip_flag ==
+ SUN1689_HWID) {
+ pp->snx_type =
+ SNX_PAR_PORT_SUN1689;
+ } else if (pp->chip_flag ==
+ SUNMATX_HWID) {
+ pp->snx_type =
+ SNX_PAR_PORT_SUNMATX;
+ } else if (pp->chip_flag ==
+ SUN1999_HWID) {
+ pp->snx_type =
+ SNX_PAR_PORT_SUN1999;
+ } else {
+ pp->snx_type =
+ SNX_PAR_PORT_UNKNOWN;
+ }
+
+ if ((sb->pb_info.board_flag &
+ BOARDFLAG_REMAP) ==
+ BOARDFLAG_REMAP) {
+ pp->port_flag = PORTFLAG_REMAP;
+ } else {
+ pp->port_flag = PORTFLAG_NONE;
+ }
+ sb->par_isr = NULL;
+ k++;
+ }
+ }
+ }
+ }
+
+
+ // release io resource
+ for (i = 0; i < SNX_PAR_TOTAL_MAX; i++) {
+ pp = &sunix_par_table[i];
+
+ if (pp->base > 0) {
+ release_region(pp->base, SNX_PAR_ADDRESS_LENGTH);
+
+
+ release_region(pp->base, SNX_PAR_STD_ADDR_LENGTH);
+
+ release_region(pp->base +
+ SNX_PAR_STD_ADDR_LENGTH,
+ SNX_PAR_ETD_ADDR_LENGTH);
+
+ if (pp->base_hi > 0) {
+ release_region(pp->base_hi,
+ SNX_PAR_ADDRESS_LENGTH);
+
+ release_region(pp->base_hi,
+ SNX_PAR_STD_ADDR_LENGTH);
+
+ release_region(pp->base_hi +
+ SNX_PAR_STD_ADDR_LENGTH,
+ SNX_PAR_ETD_ADDR_LENGTH);
+ }
+ }
+ }
+
+ return status;
+}
+
+int sunix_register_irq(void)
+{
+ struct sunix_board *sb = NULL;
+ int status = 0;
+ int i;
+
+ for (i = 0; i < SNX_BOARDS_MAX; i++) {
+ sb = &sunix_board_table[i];
+
+ if (sb == NULL) {
+ status = -ENXIO;
+ pr_err("SNX Error: Board table pointer error !\n");
+ return status;
+ }
+
+ if (sb->board_enum > 0) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
+ status = request_irq(sb->irq,
+ sunix_interrupt,
+ IRQF_SHARED,
+ "snx", sb);
+#else
+ status = request_irq(sb->irq,
+ sunix_interrupt,
+ SA_SHIRQ,
+ "snx", sb);
+#endif
+
+ if (status) {
+ pr_err("SNX Error: SUNIX Multi-I/O %s Board(bus:%d device:%d), request\n",
+ sb->pb_info.board_name,
+ sb->bus_number,
+ sb->dev_number);
+ pr_err(" IRQ %d fail, IRQ %d may be conflit with another device.\n",
+ sb->irq, sb->irq);
+ return status;
+ }
+ }
+ }
+
+ return status;
+}
+
+
+void sunix_release_irq(void)
+{
+
+ struct sunix_board *sb = NULL;
+ int i;
+
+ for (i = 0; i < SNX_BOARDS_MAX; i++) {
+ sb = &sunix_board_table[i];
+
+ if (sb->board_enum > 0)
+ free_irq(sb->irq, sb);
+ }
+}
+
+static struct pci_driver snx_pci_driver = {
+ .name = "snx",
+ .probe = snx_pci_probe,
+ .suspend = snx_suspend_one,
+ .resume = snx_resume_one,
+ .id_table = sunix_pci_board_id,
+};
+
+static int __init snx_init(void)
+{
+ int status = 0;
+
+ pr_err("\n\n");
+ pr_err("===================== SUNIX Device Driver Module Install =====================\n");
+ pr_err("\n");
+ pr_err("SNX Info : Loading SUNIX Multi-I/O Board Driver Module\n");
+ pr_err(" -- Date : %s\n",
+ SNX_DRIVER_DATE);
+ pr_err(" -- Version : %s\n\n",
+ SNX_DRIVER_VERSION);
+
+ snx_ser_port_total_cnt = snx_par_port_total_cnt = 0;
+
+ status = sunix_pci_board_probe();
+ if (status != 0)
+ goto step1_fail;
+
+ status = sunix_get_pci_board_conf();
+ if (status != 0)
+ goto step1_fail;
+
+ status = sunix_assign_resource();
+ if (status != 0)
+ goto step1_fail;
+
+ status = sunix_ser_port_table_init();
+ if (status != 0)
+ goto step1_fail;
+
+ status = sunix_par_port_table_init();
+ if (status != 0)
+ goto step1_fail;
+
+ status = sunix_register_irq();
+ if (status != 0)
+ goto step1_fail;
+
+ status = sunix_ser_register_driver(&sunix_ser_reg);
+ if (status != 0)
+ goto step2_fail;
+
+ status = sunix_ser_register_ports(&sunix_ser_reg);
+ if (status != 0)
+ goto step3_fail;
+
+ status = pci_register_driver(&snx_pci_driver);
+ if (status != 0)
+ goto step7_fail;
+
+ if (snx_par_port_total_cnt > 0) {
+ status = sunix_par_parport_init();
+ if (status != 0)
+ goto step4_fail;
+
+ status = sunix_par_ppdev_init();
+ if (status != 0)
+ goto step5_fail;
+
+ status = sunix_par_lp_init();
+ if (status != 0)
+ goto step6_fail;
+ }
+
+#if SNX_DBG
+ sunix_debug();
+#endif
+
+
+ pr_err("================================================================================\n");
+ return status;
+
+
+ if (snx_par_port_total_cnt > 0) {
+step7_fail:
+
+ pci_unregister_driver(&snx_pci_driver);
+step6_fail:
+
+ sunix_par_ppdev_exit();
+
+
+step5_fail:
+
+ sunix_par_parport_exit();
+
+
+step4_fail:
+
+ sunix_ser_unregister_ports(&sunix_ser_reg);
+ }
+
+step3_fail:
+
+ sunix_ser_unregister_driver(&sunix_ser_reg);
+
+
+step2_fail:
+
+ sunix_release_irq();
+
+
+step1_fail:
+
+ pr_err("SNX Error: Couldn't Loading SUNIX Multi-I/O Board Driver Module correctly,\n");
+ pr_err(" please reboot system and try again. If still can't loading driver,\n");
+ pr_err(" contact support.\n\n");
+ pr_err("================================================================================\n");
+ return status;
+
+}
+
+
+static void __exit snx_exit(void)
+{
+ pr_err("\n\n");
+ pr_err("==================== SUNIX Device Driver Module Uninstall ====================\n");
+ pr_err("\n");
+
+ if (snx_par_port_total_cnt > 0) {
+ sunix_par_lp_exit();
+
+ sunix_par_ppdev_exit();
+
+ sunix_par_parport_exit();
+ }
+
+ sunix_ser_unregister_ports(&sunix_ser_reg);
+
+ sunix_ser_unregister_driver(&sunix_ser_reg);
+
+ sunix_release_irq();
+ pci_unregister_driver(&snx_pci_driver);
+ pr_err("SNX Info : Unload SUNIX Multi-I/O Board Driver Module Done.\n");
+ pr_err("================================================================================\n");
+}
+
+module_init(snx_init);
+module_exit(snx_exit);
+
--
2.17.1
Powered by blists - more mailing lists