📄 istallion.c
字号:
/*****************************************************************************//* * istallion.c -- stallion intelligent multiport serial driver. * * Copyright (C) 1996-1999 Stallion Technologies (support@stallion.oz.au). * Copyright (C) 1994-1996 Greg Ungerer. * * This code is loosely based on the Linux serial driver, written by * Linus Torvalds, Theodore T'so and others. * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. *//*****************************************************************************/#include <linux/config.h>#include <linux/module.h>#include <linux/malloc.h>#include <linux/interrupt.h>#include <linux/tty_flip.h>#include <linux/serial.h>#include <linux/cdk.h>#include <linux/comstats.h>#include <linux/version.h>#include <linux/istallion.h>#include <linux/ioport.h>#include <linux/delay.h>#include <linux/init.h>#include <linux/devfs_fs_kernel.h>#include <asm/io.h>#include <asm/uaccess.h>#ifdef CONFIG_PCI#include <linux/pci.h>#endif/*****************************************************************************//* * Define different board types. Not all of the following board types * are supported by this driver. But I will use the standard "assigned" * board numbers. Currently supported boards are abbreviated as: * ECP = EasyConnection 8/64, ONB = ONboard, BBY = Brumby and * STAL = Stallion. */#define BRD_UNKNOWN 0#define BRD_STALLION 1#define BRD_BRUMBY4 2#define BRD_ONBOARD2 3#define BRD_ONBOARD 4#define BRD_BRUMBY8 5#define BRD_BRUMBY16 6#define BRD_ONBOARDE 7#define BRD_ONBOARD32 9#define BRD_ONBOARD2_32 10#define BRD_ONBOARDRS 11#define BRD_EASYIO 20#define BRD_ECH 21#define BRD_ECHMC 22#define BRD_ECP 23#define BRD_ECPE 24#define BRD_ECPMC 25#define BRD_ECHPCI 26#define BRD_ECH64PCI 27#define BRD_EASYIOPCI 28#define BRD_ECPPCI 29#define BRD_BRUMBY BRD_BRUMBY4/* * Define a configuration structure to hold the board configuration. * Need to set this up in the code (for now) with the boards that are * to be configured into the system. This is what needs to be modified * when adding/removing/modifying boards. Each line entry in the * stli_brdconf[] array is a board. Each line contains io/irq/memory * ranges for that board (as well as what type of board it is). * Some examples: * { BRD_ECP, 0x2a0, 0, 0xcc000, 0, 0 }, * This line will configure an EasyConnection 8/64 at io address 2a0, * and shared memory address of cc000. Multiple EasyConnection 8/64 * boards can share the same shared memory address space. No interrupt * is required for this board type. * Another example: * { BRD_ECPE, 0x5000, 0, 0x80000000, 0, 0 }, * This line will configure an EasyConnection 8/64 EISA in slot 5 and * shared memory address of 0x80000000 (2 GByte). Multiple * EasyConnection 8/64 EISA boards can share the same shared memory * address space. No interrupt is required for this board type. * Another example: * { BRD_ONBOARD, 0x240, 0, 0xd0000, 0, 0 }, * This line will configure an ONboard (ISA type) at io address 240, * and shared memory address of d0000. Multiple ONboards can share * the same shared memory address space. No interrupt required. * Another example: * { BRD_BRUMBY4, 0x360, 0, 0xc8000, 0, 0 }, * This line will configure a Brumby board (any number of ports!) at * io address 360 and shared memory address of c8000. All Brumby boards * configured into a system must have their own separate io and memory * addresses. No interrupt is required. * Another example: * { BRD_STALLION, 0x330, 0, 0xd0000, 0, 0 }, * This line will configure an original Stallion board at io address 330 * and shared memory address d0000 (this would only be valid for a "V4.0" * or Rev.O Stallion board). All Stallion boards configured into the * system must have their own separate io and memory addresses. No * interrupt is required. */typedef struct { int brdtype; int ioaddr1; int ioaddr2; unsigned long memaddr; int irq; int irqtype;} stlconf_t;static stlconf_t stli_brdconf[] = { /*{ BRD_ECP, 0x2a0, 0, 0xcc000, 0, 0 },*/};static int stli_nrbrds = sizeof(stli_brdconf) / sizeof(stlconf_t);/* * There is some experimental EISA board detection code in this driver. * By default it is disabled, but for those that want to try it out, * then set the define below to be 1. */#define STLI_EISAPROBE 0static devfs_handle_t devfs_handle;/*****************************************************************************//* * Define some important driver characteristics. Device major numbers * allocated as per Linux Device Registry. */#ifndef STL_SIOMEMMAJOR#define STL_SIOMEMMAJOR 28#endif#ifndef STL_SERIALMAJOR#define STL_SERIALMAJOR 24#endif#ifndef STL_CALLOUTMAJOR#define STL_CALLOUTMAJOR 25#endif#define STL_DRVTYPSERIAL 1#define STL_DRVTYPCALLOUT 2/*****************************************************************************//* * Define our local driver identity first. Set up stuff to deal with * all the local structures required by a serial tty driver. */static char *stli_drvtitle = "Stallion Intelligent Multiport Serial Driver";static char *stli_drvname = "istallion";static char *stli_drvversion = "5.6.0";static char *stli_serialname = "ttyE";static char *stli_calloutname = "cue";static struct tty_driver stli_serial;static struct tty_driver stli_callout;static struct tty_struct *stli_ttys[STL_MAXDEVS];static struct termios *stli_termios[STL_MAXDEVS];static struct termios *stli_termioslocked[STL_MAXDEVS];static int stli_refcount;/* * We will need to allocate a temporary write buffer for chars that * come direct from user space. The problem is that a copy from user * space might cause a page fault (typically on a system that is * swapping!). All ports will share one buffer - since if the system * is already swapping a shared buffer won't make things any worse. */static char *stli_tmpwritebuf;static DECLARE_MUTEX(stli_tmpwritesem);#define STLI_TXBUFSIZE 4096/* * Use a fast local buffer for cooked characters. Typically a whole * bunch of cooked characters come in for a port, 1 at a time. So we * save those up into a local buffer, then write out the whole lot * with a large memcpy. Just use 1 buffer for all ports, since its * use it is only need for short periods of time by each port. */static char *stli_txcookbuf;static int stli_txcooksize;static int stli_txcookrealsize;static struct tty_struct *stli_txcooktty;/* * Define a local default termios struct. All ports will be created * with this termios initially. Basically all it defines is a raw port * at 9600 baud, 8 data bits, no parity, 1 stop bit. */static struct termios stli_deftermios = { 0, 0, (B9600 | CS8 | CREAD | HUPCL | CLOCAL), 0, 0, INIT_C_CC};/* * Define global stats structures. Not used often, and can be * re-used for each stats call. */static comstats_t stli_comstats;static combrd_t stli_brdstats;static asystats_t stli_cdkstats;static stlibrd_t stli_dummybrd;static stliport_t stli_dummyport;/*****************************************************************************/static stlibrd_t *stli_brds[STL_MAXBRDS];static int stli_shared;/* * Per board state flags. Used with the state field of the board struct. * Not really much here... All we need to do is keep track of whether * the board has been detected, and whether it is actually running a slave * or not. */#define BST_FOUND 0x1#define BST_STARTED 0x2/* * Define the set of port state flags. These are marked for internal * state purposes only, usually to do with the state of communications * with the slave. Most of them need to be updated atomically, so always * use the bit setting operations (unless protected by cli/sti). */#define ST_INITIALIZING 1#define ST_OPENING 2#define ST_CLOSING 3#define ST_CMDING 4#define ST_TXBUSY 5#define ST_RXING 6#define ST_DOFLUSHRX 7#define ST_DOFLUSHTX 8#define ST_DOSIGS 9#define ST_RXSTOP 10#define ST_GETSIGS 11/* * Define an array of board names as printable strings. Handy for * referencing boards when printing trace and stuff. */static char *stli_brdnames[] = { "Unknown", "Stallion", "Brumby", "ONboard-MC", "ONboard", "Brumby", "Brumby", "ONboard-EI", (char *) NULL, "ONboard", "ONboard-MC", "ONboard-MC", (char *) NULL, (char *) NULL, (char *) NULL, (char *) NULL, (char *) NULL, (char *) NULL, (char *) NULL, (char *) NULL, "EasyIO", "EC8/32-AT", "EC8/32-MC", "EC8/64-AT", "EC8/64-EI", "EC8/64-MC", "EC8/32-PCI", "EC8/64-PCI", "EasyIO-PCI", "EC/RA-PCI",};/*****************************************************************************/#ifdef MODULE/* * Define some string labels for arguments passed from the module * load line. These allow for easy board definitions, and easy * modification of the io, memory and irq resoucres. */static char *board0[8];static char *board1[8];static char *board2[8];static char *board3[8];static char **stli_brdsp[] = { (char **) &board0, (char **) &board1, (char **) &board2, (char **) &board3};/* * Define a set of common board names, and types. This is used to * parse any module arguments. */typedef struct stlibrdtype { char *name; int type;} stlibrdtype_t;static stlibrdtype_t stli_brdstr[] = { { "stallion", BRD_STALLION }, { "1", BRD_STALLION }, { "brumby", BRD_BRUMBY }, { "brumby4", BRD_BRUMBY }, { "brumby/4", BRD_BRUMBY }, { "brumby-4", BRD_BRUMBY }, { "brumby8", BRD_BRUMBY }, { "brumby/8", BRD_BRUMBY }, { "brumby-8", BRD_BRUMBY }, { "brumby16", BRD_BRUMBY }, { "brumby/16", BRD_BRUMBY }, { "brumby-16", BRD_BRUMBY }, { "2", BRD_BRUMBY }, { "onboard2", BRD_ONBOARD2 }, { "onboard-2", BRD_ONBOARD2 }, { "onboard/2", BRD_ONBOARD2 }, { "onboard-mc", BRD_ONBOARD2 }, { "onboard/mc", BRD_ONBOARD2 }, { "onboard-mca", BRD_ONBOARD2 }, { "onboard/mca", BRD_ONBOARD2 }, { "3", BRD_ONBOARD2 }, { "onboard", BRD_ONBOARD }, { "onboardat", BRD_ONBOARD }, { "4", BRD_ONBOARD }, { "onboarde", BRD_ONBOARDE }, { "onboard-e", BRD_ONBOARDE }, { "onboard/e", BRD_ONBOARDE }, { "onboard-ei", BRD_ONBOARDE }, { "onboard/ei", BRD_ONBOARDE }, { "7", BRD_ONBOARDE }, { "ecp", BRD_ECP }, { "ecpat", BRD_ECP }, { "ec8/64", BRD_ECP }, { "ec8/64-at", BRD_ECP }, { "ec8/64-isa", BRD_ECP }, { "23", BRD_ECP }, { "ecpe", BRD_ECPE }, { "ecpei", BRD_ECPE }, { "ec8/64-e", BRD_ECPE }, { "ec8/64-ei", BRD_ECPE }, { "24", BRD_ECPE }, { "ecpmc", BRD_ECPMC }, { "ec8/64-mc", BRD_ECPMC }, { "ec8/64-mca", BRD_ECPMC }, { "25", BRD_ECPMC }, { "ecppci", BRD_ECPPCI }, { "ec/ra", BRD_ECPPCI }, { "ec/ra-pc", BRD_ECPPCI }, { "ec/ra-pci", BRD_ECPPCI }, { "29", BRD_ECPPCI },};/* * Define the module agruments. */MODULE_AUTHOR("Greg Ungerer");MODULE_DESCRIPTION("Stallion Intelligent Multiport Serial Driver");MODULE_PARM(board0, "1-3s");MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,memaddr]");MODULE_PARM(board1, "1-3s");MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,memaddr]");MODULE_PARM(board2, "1-3s");MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,memaddr]");MODULE_PARM(board3, "1-3s");MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,memaddr]");#endif/* * Set up a default memory address table for EISA board probing. * The default addresses are all bellow 1Mbyte, which has to be the * case anyway. They should be safe, since we only read values from * them, and interrupts are disabled while we do it. If the higher * memory support is compiled in then we also try probing around * the 1Gb, 2Gb and 3Gb areas as well... */static unsigned long stli_eisamemprobeaddrs[] = { 0xc0000, 0xd0000, 0xe0000, 0xf0000, 0x80000000, 0x80010000, 0x80020000, 0x80030000, 0x40000000, 0x40010000, 0x40020000, 0x40030000, 0xc0000000, 0xc0010000, 0xc0020000, 0xc0030000, 0xff000000, 0xff010000, 0xff020000, 0xff030000,};static int stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long);int stli_eisaprobe = STLI_EISAPROBE;/* * Define the Stallion PCI vendor and device IDs. */#ifdef CONFIG_PCI#ifndef PCI_VENDOR_ID_STALLION#define PCI_VENDOR_ID_STALLION 0x124d#endif#ifndef PCI_DEVICE_ID_ECRA#define PCI_DEVICE_ID_ECRA 0x0004#endif#endif/*****************************************************************************//* * Hardware configuration info for ECP boards. These defines apply * to the directly accessible io ports of the ECP. There is a set of * defines for each ECP board type, ISA, EISA, MCA and PCI. */#define ECP_IOSIZE 4#define ECP_MEMSIZE (128 * 1024)#define ECP_PCIMEMSIZE (256 * 1024)#define ECP_ATPAGESIZE (4 * 1024)#define ECP_MCPAGESIZE (4 * 1024)#define ECP_EIPAGESIZE (64 * 1024)#define ECP_PCIPAGESIZE (64 * 1024)#define STL_EISAID 0x8c4e/* * Important defines for the ISA class of ECP board. */#define ECP_ATIREG 0#define ECP_ATCONFR 1#define ECP_ATMEMAR 2#define ECP_ATMEMPR 3#define ECP_ATSTOP 0x1#define ECP_ATINTENAB 0x10#define ECP_ATENABLE 0x20#define ECP_ATDISABLE 0x00#define ECP_ATADDRMASK 0x3f000#define ECP_ATADDRSHFT 12/* * Important defines for the EISA class of ECP board. */#define ECP_EIIREG 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -