⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 moxa.c

📁 moxa多串口卡linux下的驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************//* *           moxa.c  -- MOXA Intellio family multiport serial driver. * *      Copyright (C) 1999-2001  Moxa Technologies (support@moxa.com.tw). * *      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. * * 	Original Release	12/08/99 * *	02/06/01	Support closing wait. *	02/06/01	Fix the bug for driver initialization of ISA boards. *	02/06/01	Fix the compiling warning when CONFIG_PCI  *			don't be defined.*/#define		VERSION_CODE(ver,rel,seq)	((ver << 16) | (rel << 8) | seq)#ifdef MODULE#ifdef MODVERSIONS#include <linux/modversions.h>#endif#include <linux/module.h>#else#define	MOD_INC_USE_COUNT#define MOD_DEC_USE_COUNT#endif#include <linux/types.h>#include <linux/autoconf.h>#include <linux/version.h>#include <linux/mm.h>#include <linux/ioport.h>#include <linux/errno.h>#include <linux/signal.h>#include <linux/sched.h>#include <linux/timer.h>#include <linux/interrupt.h>#include <linux/tty.h>#include <linux/tty_flip.h>#if (LINUX_VERSION_CODE < VERSION_CODE(2,4,0))#include <linux/config.h>#endif#include <linux/major.h>#include <linux/string.h>#include <linux/fcntl.h>#include <linux/ptrace.h>#include <linux/serial.h>#include <linux/tty_driver.h>#include <linux/delay.h>#include <asm/system.h>#include <asm/io.h>#include <asm/segment.h>#include <asm/bitops.h>#define		MOXA_VERSION		"5.4"#define MOXAMAJOR       31 #define MOXACUMAJOR     37 #ifdef CONFIG_PCI#if (LINUX_VERSION_CODE < VERSION_CODE(2,1,0))#include <linux/bios32.h>#endif#include <linux/pci.h>#endif /* ENABLE_PCI */#if (LINUX_VERSION_CODE < VERSION_CODE(2,1,0))#define copy_from_user memcpy_fromfs#define copy_to_user memcpy_tofs#define put_to_user(arg1, arg2) put_fs_long(arg1, (unsigned long *)arg2)#define get_from_user(arg1, arg2) arg1 = get_fs_long((unsigned long *)arg2)#define ioremap vremap#define iounmap vfree#define schedule_timeout(x) {current->timeout = jiffies + (x); schedule();}#define signal_pending(x) ((x)->signal & ~(x)->blocked)#else#include <asm/uaccess.h>#define put_to_user(arg1, arg2) put_user(arg1, (unsigned long *)arg2)#define get_from_user(arg1, arg2) get_user(arg1, (unsigned int *)arg2)#endif #define MAX_BOARDS 		4	/* Don't change this value */#define MAX_PORTS_PER_BOARD	32	/* Don't change this value */#define MAX_PORTS 		128	/* Don't change this value *//* *	Define the Moxa PCI vendor and device IDs. */#define MOXA_BUS_TYPE_ISA		0#define MOXA_BUS_TYPE_PCI		1#ifndef	PCI_VENDOR_ID_MOXA#define	PCI_VENDOR_ID_MOXA	0x1393#endif#ifndef PCI_DEVICE_ID_CP204J#define PCI_DEVICE_ID_CP204J	0x2040#endif#ifndef PCI_DEVICE_ID_C218#define PCI_DEVICE_ID_C218	0x2180#endif#ifndef PCI_DEVICE_ID_C320#define PCI_DEVICE_ID_C320	0x3200#endifenum	{	MOXA_BOARD_C218_PCI = 1,	MOXA_BOARD_C218_ISA,	MOXA_BOARD_C320_PCI,	MOXA_BOARD_C320_ISA,	MOXA_BOARD_CP204J,};static char *moxa_brdname[] = {	"C218 Turbo PCI series",	"C218 Turbo ISA series",	"C320 Turbo PCI series",	"C320 Turbo ISA series",	"CP-204J series",};#ifdef CONFIG_PCItypedef struct {	unsigned short	vendor_id;	unsigned short	device_id;	unsigned short	board_type;}	moxa_pciinfo;static moxa_pciinfo	moxa_pcibrds[] = {	{PCI_VENDOR_ID_MOXA,PCI_DEVICE_ID_C218 ,MOXA_BOARD_C218_PCI},	{PCI_VENDOR_ID_MOXA,PCI_DEVICE_ID_C320 ,MOXA_BOARD_C320_PCI},	{PCI_VENDOR_ID_MOXA,PCI_DEVICE_ID_CP204J ,MOXA_BOARD_CP204J},};#endiftypedef struct _moxa_isa_board_conf {	int	boardType;	int	numPorts;	unsigned long	baseAddr;} moxa_isa_board_conf;static moxa_isa_board_conf moxa_isa_boards[] =  {	{0,0,0},	{0,0,0},	{0,0,0},	{0,0,0}/*	 {MOXA_BOARD_C218_ISA,8,0xDC000}, */};typedef struct	_moxa_pci_devinfo {	ushort	busNum;	ushort	devNum;} moxa_pci_devinfo;typedef struct _moxa_board_conf {	int			boardType;	int			numPorts;	unsigned long			baseAddr;	int			busType;	moxa_pci_devinfo	pciInfo;} moxa_board_conf;static moxa_board_conf		moxa_boards[MAX_BOARDS];static unsigned long	moxaBaseAddr[MAX_BOARDS];static int	loadstat[MAX_BOARDS]={0,0,0,0};struct moxa_str {        int                     type;	int			port;	int			close_delay;	unsigned short		closing_wait;	int			count;	int			blocked_open;#if (LINUX_VERSION_CODE < VERSION_CODE(2,4,0))	int			event;#else	long			event;#endif	int			asyncflags;	long			session;	long			pgrp;	unsigned long			statusflags;	struct tty_struct	*tty;	struct termios		normal_termios;	struct termios		callout_termios;#if (LINUX_VERSION_CODE < VERSION_CODE(2,4,0))	struct wait_queue	*open_wait;	struct wait_queue	*close_wait;#else	wait_queue_head_t	open_wait;	wait_queue_head_t	close_wait;#endif	struct tq_struct	tqueue;};struct mxser_mstatus{       tcflag_t  cflag;       int  cts;       int  dsr;       int  ri;       int  dcd;};static  struct mxser_mstatus GMStatus[MAX_PORTS];/* statusflags */#define TXSTOPPED	0x1#define LOWWAIT 	0x2#define EMPTYWAIT	0x4#define THROTTLE	0x8/* event */#define MOXA_EVENT_HANGUP	1#define SERIAL_DO_RESTART#define SERIAL_TYPE_NORMAL	1#define SERIAL_TYPE_CALLOUT	2#define WAKEUP_CHARS		256#define PORTNO(x)		(MINOR((x)->device) - (x)->driver.minor_start)static int verbose = 0;static int ttymajor       = MOXAMAJOR;static int calloutmajor   = MOXACUMAJOR;#ifdef MODULE/* Variables for insmod */static int baseaddr[]      = {0, 0, 0, 0};static int type[]         = {0, 0, 0, 0};static int numports[]     = {0, 0, 0, 0};# if (LINUX_VERSION_CODE > VERSION_CODE(2,1,11))MODULE_AUTHOR("William Chen");MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver");MODULE_PARM(type,        "1-4i");MODULE_PARM(baseaddr,     "1-4i");MODULE_PARM(numports,    "1-4i");MODULE_PARM(ttymajor,    "i");MODULE_PARM(calloutmajor,"i");MODULE_PARM(verbose,"i");# endif#endif //MODULEstatic struct tty_driver	moxaDriver;static struct tty_driver	moxaCallout;static struct tty_struct *	moxaTable[MAX_PORTS+1];static struct termios *	moxaTermios[MAX_PORTS+1];static struct termios *	moxaTermiosLocked[MAX_PORTS+1];static struct moxa_str 	moxaChannels[MAX_PORTS];static int			moxaRefcount;static unsigned char * 		moxaXmitBuff;static int		moxaTimer_on;static int		moxaEmptyTimer_on[MAX_PORTS];static struct timer_list	moxaEmptyTimer[MAX_PORTS];static struct timer_list	moxaTimer;#if (LINUX_VERSION_CODE >= VERSION_CODE(2,4,0))static struct semaphore	moxaBuffSem;#elsestatic struct semaphore	moxaBuffSem = MUTEX;#endifint		moxa_init(void);#ifdef MODULEint		init_module(void);void		cleanup_module(void);#endif/* * static functions: */#ifdef	CONFIG_PCIstatic int moxa_get_PCI_conf(int ,int ,int ,moxa_board_conf *);#endifstatic void	do_moxa_softint(void *);static int	moxa_open(struct tty_struct *, struct file *);static void	moxa_close(struct tty_struct *, struct file *);static int	moxa_write(struct tty_struct *, int, const unsigned char *, int);static int	moxa_write_room(struct tty_struct *);static void	moxa_flush_buffer(struct tty_struct *);static int	moxa_chars_in_buffer(struct tty_struct *);static void	moxa_flush_chars(struct tty_struct *);static void	moxa_put_char(struct tty_struct *, unsigned char);static int	moxa_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long);static void	moxa_throttle(struct tty_struct *);static void	moxa_unthrottle(struct tty_struct *);static void	moxa_set_termios(struct tty_struct *, struct termios *);static void	moxa_stop(struct tty_struct *);static void	moxa_start(struct tty_struct *);static void	moxa_hangup(struct tty_struct *);static void	moxa_poll(unsigned long);static void	set_tty_param(struct tty_struct *);static int	block_till_ready(struct tty_struct *, struct file *,				 struct moxa_str *);static void	setup_empty_event(struct tty_struct *);static void	check_xmit_empty(unsigned long);static void	shut_down(struct moxa_str *);static void	receive_data(struct moxa_str *);#if (LINUX_VERSION_CODE > VERSION_CODE(2,1,0))static void mx_wait_until_sent(struct tty_struct *tty, int timeout);#endif/* * moxa board interface functions: */static void MoxaDriverInit(void);static int  MoxaDriverIoctl(unsigned int, unsigned long, int);static int  MoxaDriverPoll(void);static int  MoxaPortsOfCard(int);static int  MoxaPortIsValid(int);static void MoxaPortEnable(int);static void MoxaPortDisable(int);static long MoxaPortGetMaxBaud(int);static long MoxaPortSetBaud(int, long);static int  MoxaPortSetTermio(int, struct termios *);static int  MoxaPortGetLineOut(int, int *, int *);static void MoxaPortLineCtrl(int, int, int);static void MoxaPortFlowCtrl(int, int, int, int, int,int);static int  MoxaPortLineStatus(int);static int  MoxaPortDCDChange(int);static int  MoxaPortDCDON(int);static void MoxaPortFlushData(int, int);static void MoxaPortFlushData2(int, int);static int  MoxaPortWriteData(int, unsigned char *, int);static int  MoxaPortReadData(int, unsigned char *, int);static int  MoxaPortTxQueue(int);static int  MoxaPortRxQueue(int);static int  MoxaPortTxFree(int);static void MoxaPortTxDisable(int);static void MoxaPortTxEnable(int);static int  MoxaPortResetBrkCnt(int);static void MoxaPortSendBreak(int, int);static int  moxa_get_serial_info(struct moxa_str *, struct serial_struct *);static int  moxa_set_serial_info(struct moxa_str *, struct serial_struct *);static void MoxaSetFifo(int port, int enable);#ifdef MODULEint init_module(void){	int ret;	if (verbose)		printk("Loading module moxa ...\n");	ret = moxa_init();	if (verbose)		printk("Done\n");	return (ret);}void cleanup_module(void){	int i;	if (verbose)		printk("Unloading module moxa ...\n");	if (moxaTimer_on)		del_timer(&moxaTimer);	for (i = 0; i < MAX_PORTS; i++)		if (moxaEmptyTimer_on[i])			del_timer(&moxaEmptyTimer[i]);	if (tty_unregister_driver(&moxaCallout))		printk("Couldn't unregister MOXA Intellio family callout driver\n");	if (tty_unregister_driver(&moxaDriver))		printk("Couldn't unregister MOXA Intellio family serial driver\n");	if (verbose)		printk("Done\n");}#endifint moxa_init(void){	int		i,numBoards;	struct moxa_str *ch;        int    ret1,ret2;#ifdef CONFIG_PCI	int		n,index;	unsigned char	busnum,devnum;#endif	printk("MOXA Intellio family driver version %s\n", MOXA_VERSION);#if (LINUX_VERSION_CODE >= VERSION_CODE(2,4,0))	init_MUTEX(&moxaBuffSem);#endif	memset(&moxaDriver, 0, sizeof(struct tty_driver));	memset(&moxaCallout, 0, sizeof(struct tty_driver));	moxaDriver.magic = TTY_DRIVER_MAGIC;	moxaDriver.name = "ttya";	moxaDriver.major = ttymajor;	moxaDriver.minor_start = 0;	moxaDriver.num = MAX_PORTS + 1;	moxaDriver.type = TTY_DRIVER_TYPE_SERIAL;	moxaDriver.subtype = SERIAL_TYPE_NORMAL;	moxaDriver.init_termios = tty_std_termios;	moxaDriver.init_termios.c_iflag = 0;	moxaDriver.init_termios.c_oflag = 0;	moxaDriver.init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;	moxaDriver.init_termios.c_lflag = 0;	moxaDriver.flags = TTY_DRIVER_REAL_RAW;	moxaDriver.refcount = &moxaRefcount;	moxaDriver.table = moxaTable;	moxaDriver.termios = moxaTermios;	moxaDriver.termios_locked = moxaTermiosLocked;	moxaDriver.open = moxa_open;	moxaDriver.close = moxa_close;	moxaDriver.write = moxa_write;	moxaDriver.write_room = moxa_write_room;	moxaDriver.flush_buffer = moxa_flush_buffer;	moxaDriver.chars_in_buffer = moxa_chars_in_buffer;	moxaDriver.flush_chars = moxa_flush_chars;	moxaDriver.put_char = moxa_put_char;	moxaDriver.ioctl = moxa_ioctl;	moxaDriver.throttle = moxa_throttle;	moxaDriver.unthrottle = moxa_unthrottle;	moxaDriver.set_termios = moxa_set_termios;	moxaDriver.stop = moxa_stop;	moxaDriver.start = moxa_start;	moxaDriver.hangup = moxa_hangup;# if (LINUX_VERSION_CODE > VERSION_CODE(2,1,0))	moxaDriver.wait_until_sent = mx_wait_until_sent;#endif	moxaCallout = moxaDriver;	moxaCallout.name = "ttyA";	moxaCallout.major = calloutmajor;	moxaCallout.subtype = SERIAL_TYPE_CALLOUT;	moxaXmitBuff = 0;	for (i = 0, ch = moxaChannels; i < MAX_PORTS; i++, ch++) {            ch->type = PORT_16550A;	    ch->port = i;	    ch->tqueue.routine = do_moxa_softint;	    ch->tqueue.data = ch;	    ch->tty = 0;	    ch->close_delay = 5*HZ/10;	    ch->closing_wait = 0;	    ch->count = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -