Received: by 2002:ac0:8845:0:0:0:0:0 with SMTP id g63csp1477771img; Tue, 26 Feb 2019 23:19:37 -0800 (PST) X-Google-Smtp-Source: AHgI3IbrMjBjkrx5apBUR1Sus2rtGJOM7VuRccS4XDByG7pgnEL8ukmq9QXFL07SHe3PaNpbQUuQ X-Received: by 2002:a17:902:b7c7:: with SMTP id v7mr703143plz.148.1551251977271; Tue, 26 Feb 2019 23:19:37 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551251977; cv=none; d=google.com; s=arc-20160816; b=KuyUmNCjDFIIl25qgQT3RXITlZoKCpRpq7SXvfcWvF0tp1q6o/hixlsOre1N4ryDkK HlLQJYNtkNsPvMSJcS+4ZxW8nMHYPRsIc2C+qiBDwkMjQ1IGRkGM1LGkpUiH9Bq1owF5 jpn5mNDCx0K2JaoBS8nfAjs8W9fPQsiD1eFXNVr92hpRwlMvh9R7kMYUPKPXI59Sd7LT Zi1U+GYCGoyuNlXvmEJmYBzf5NSvhvmDedsYThlBLwDbdgL7XpByJnr/eqnj+dL0tn1s 6jS8oEgXruHoKP2GSWogQgpEqzMOoqoQoI7zs61oHZBJeaWyEVjTEu3Qq2SBefeVnw68 lJzQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature; bh=Da5tQhPKvi+o4qXUAz8lCtG79b54Y9j5iTHmAjO0FQs=; b=s9MlL36tBP8Cs5RH8zVXAtQa7BlOWT/y+Qcd8Ubu78U/ViM4ZKu5IOrlpcp1zK0SkO x82W4+1iG33X+xDUjoGKzm8zS/2IORS1WAt0/HPwyyEXZyJMSScCd4zVfJ4ROheo4lwa KSyjyVCbR8HYXTmthdzcDB24jVnxlXKNlxW1EMbXEQR1Ay0XiGnzX212lrjnpY1XT5l7 0EHESVtIyD7vz/KokjU3Kn+Kp0HozZ8vBGQzfk0S2c6cW7Wgcpl166gkfYtLsK4Z7XIy tHZjhDYb9JQ1WP7Hg/7PWNTOVyVSznOF/eGctuRhZKsIccaJL8AH0m6oz1eDCYPOM/YZ k1ow== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=QwqnNbmq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z8si9670677pgu.224.2019.02.26.23.19.21; Tue, 26 Feb 2019 23:19:37 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=QwqnNbmq; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729702AbfB0HSf (ORCPT + 99 others); Wed, 27 Feb 2019 02:18:35 -0500 Received: from mail-pl1-f193.google.com ([209.85.214.193]:43219 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725925AbfB0HSf (ORCPT ); Wed, 27 Feb 2019 02:18:35 -0500 Received: by mail-pl1-f193.google.com with SMTP id m10so7538809plt.10 for ; Tue, 26 Feb 2019 23:18:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=Da5tQhPKvi+o4qXUAz8lCtG79b54Y9j5iTHmAjO0FQs=; b=QwqnNbmqrfAfKNtLpjKt57D9ljNtqXtwDBNNbqz/Y1GLrS1YAAY1uPT5CisVOEUeAb Zhmd9EXvBTQLpUu/56fhPdnmMQZr4cqe+vH6GZuJFl9KaeAHYgbbIK98ESJ8KNN9J30h 20BaiHTxWbj8Bw9Vjc5TEc4ioGqiSLkZFmotwjGAgQeBauda1snek83itkWsN1BOH5iS 6CEYHx+EpJyxXODfzqgyap762VT/o/LNB51hYB8/Y1s4CUy7r6xJ1xtdBOJcaBiDMvbj /TOjVguHbsx5C7hq0CG2RL4ntmgQEXUy0KgDVh/SCQmeYmGZyhT4MMRo4Lj9OanMulru lTFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=Da5tQhPKvi+o4qXUAz8lCtG79b54Y9j5iTHmAjO0FQs=; b=OuAFZ8urGqkcuRLOXXw/ZRVCFI8NRo4ojm4XLevYIHlTILR/XkJ7jFK3GKP6nQs2NR ExwgN+7PrwQwal6JBXj2XD37xg1O5SXvNbMn/nhnE4JW0AFtTYWjKNuS+8nHF5km6YNf jM4ZhlYoSvjh/uIe2dmTAcPT38WoTJpuvezmv0SojJ6Y15gMH4HoLrsM0x1Hcmz33diB in4tWoN37F6Y/X8WiF0ydNezzPy+N9vc8i35LF/bsqj/R1emlawTxFgarHJAc92ZYeDj 2OplBBKaD4SFaew9zp4aEy0uPfQCKXR9cnj+Gg3ehEALpBh/9fWPunufY5TtUD/OnVxY WrBA== X-Gm-Message-State: AHQUAubDWgV+7LocfEOBH3HkMm9W6jpc7wAtxHSaw8cYTfpVddqS+NWk QujBbxby8AH//fAERgg7MqBLwwb8eH8= X-Received: by 2002:a17:902:a03:: with SMTP id 3mr709087plo.306.1551251911104; Tue, 26 Feb 2019 23:18:31 -0800 (PST) Received: from test-System-Product-Name.sunix.com.tw (114-36-235-188.dynamic-ip.hinet.net. [114.36.235.188]) by smtp.gmail.com with ESMTPSA id k64sm45868509pfj.69.2019.02.26.23.18.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 Feb 2019 23:18:30 -0800 (PST) From: Morris Ku To: gregkh@linuxfoundation.org Cc: morris_ku@sunix.com, linux-kernel@vger.kernel.org, Morris Ku Subject: [PATCH 3/5] Add SUNIX Multi-I/O board driver Date: Wed, 27 Feb 2019 15:18:09 +0800 Message-Id: <20190227071809.4204-1-saumah@gmail.com> X-Mailer: git-send-email 2.17.1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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