📄 istallion.c
字号:
/*****************************************************************************//* * istallion.c -- stallion intelligent multiport serial driver. * * Copyright (C) 1996-1999 Stallion Technologies * 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. * *//*****************************************************************************/#include <linux/module.h>#include <linux/slab.h>#include <linux/interrupt.h>#include <linux/tty.h>#include <linux/tty_flip.h>#include <linux/serial.h>#include <linux/cdk.h>#include <linux/comstats.h>#include <linux/istallion.h>#include <linux/ioport.h>#include <linux/delay.h>#include <linux/init.h>#include <linux/device.h>#include <linux/wait.h>#include <linux/eisa.h>#include <linux/ctype.h>#include <asm/io.h>#include <asm/uaccess.h>#include <linux/pci.h>/*****************************************************************************//* * 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_ONBOARDE 7#define BRD_ECP 23#define BRD_ECPE 24#define BRD_ECPMC 25#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. */struct stlconf { int brdtype; int ioaddr1; int ioaddr2; unsigned long memaddr; int irq; int irqtype;};static unsigned int stli_nrbrds;/* stli_lock must NOT be taken holding brd_lock */static spinlock_t stli_lock; /* TTY logic lock */static spinlock_t brd_lock; /* Board logic lock *//* * 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 0/*****************************************************************************//* * 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 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 struct tty_driver *stli_serial;#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 ktermios stli_deftermios = { .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL), .c_cc = INIT_C_CC, .c_ispeed = 9600, .c_ospeed = 9600,};/* * 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 struct asystats stli_cdkstats;/*****************************************************************************/static DEFINE_MUTEX(stli_brdslock);static struct stlibrd *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 BST_PROBED 0x4/* * 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", NULL, "ONboard", "ONboard-MC", "ONboard-MC", NULL, NULL, NULL, NULL, NULL, NULL, NULL, 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",};/*****************************************************************************//* * 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. */static struct stlibrdtype { char *name; int type;} 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_LICENSE("GPL");module_param_array(board0, charp, NULL, 0);MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,memaddr]");module_param_array(board1, charp, NULL, 0);MODULE_PARM_DESC(board1, "Board 1 config -> name[,ioaddr[,memaddr]");module_param_array(board2, charp, NULL, 0);MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,memaddr]");module_param_array(board3, charp, NULL, 0);MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,memaddr]");#if STLI_EISAPROBE != 0/* * 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 = ARRAY_SIZE(stli_eisamemprobeaddrs);#endif/* * Define the Stallion PCI vendor and device IDs. */#ifndef PCI_DEVICE_ID_ECRA#define PCI_DEVICE_ID_ECRA 0x0004#endifstatic struct pci_device_id istallion_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA), }, { 0 }};MODULE_DEVICE_TABLE(pci, istallion_pci_tbl);static struct pci_driver stli_pcidriver;/*****************************************************************************//* * 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#define ECP_EIMEMARL 1#define ECP_EICONFR 2#define ECP_EIMEMARH 3#define ECP_EIENABLE 0x1#define ECP_EIDISABLE 0x0#define ECP_EISTOP 0x4#define ECP_EIEDGE 0x00#define ECP_EILEVEL 0x80#define ECP_EIADDRMASKL 0x00ff0000#define ECP_EIADDRSHFTL 16#define ECP_EIADDRMASKH 0xff000000#define ECP_EIADDRSHFTH 24#define ECP_EIBRDENAB 0xc84#define ECP_EISAID 0x4/* * Important defines for the Micro-channel class of ECP board. * (It has a lot in common with the ISA boards.) */#define ECP_MCIREG 0#define ECP_MCCONFR 1#define ECP_MCSTOP 0x20#define ECP_MCENABLE 0x80#define ECP_MCDISABLE 0x00/* * Important defines for the PCI class of ECP board. * (It has a lot in common with the other ECP boards.)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -