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

📄 moxa.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************//* *           moxa.c  -- MOXA Intellio family multiport serial driver. * *      Copyright (C) 1999-2000  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. *//* *    MOXA Intellio Series Driver *      for             : LINUX *      date            : 1999/1/7 *      version         : 5.1 */#include <linux/config.h>#include <linux/module.h>#include <linux/types.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>#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 <linux/pci.h>#include <linux/init.h>#include <asm/system.h>#include <asm/io.h>#include <asm/bitops.h>#include <asm/uaccess.h>#define		MOXA_VERSION		"5.1k"#define MOXAMAJOR       172#define MOXACUMAJOR     173#define put_to_user(arg1, arg2) put_user(arg1, (unsigned long *)arg2)#define get_from_user(arg1, arg2) get_user(arg1, (unsigned int *)arg2)#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_PCIstatic struct pci_device_id moxa_pcibrds[] = {	{ PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C218, PCI_ANY_ID, PCI_ANY_ID, 	  0, 0, MOXA_BOARD_C218_PCI },	{ PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_C320, PCI_ANY_ID, PCI_ANY_ID, 	  0, 0, MOXA_BOARD_C320_PCI },	{ PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_CP204J, PCI_ANY_ID, PCI_ANY_ID, 	  0, 0, MOXA_BOARD_CP204J },	{ 0 }};MODULE_DEVICE_TABLE(pci, moxa_pcibrds);#endif /* CONFIG_PCI */typedef struct _moxa_isa_board_conf {	int boardType;	int numPorts;	unsigned long baseAddr;} moxa_isa_board_conf;static moxa_isa_board_conf moxa_isa_boards[] ={/*       {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];struct moxa_str {	int type;	int port;	int close_delay;	unsigned short closing_wait;	int count;	int blocked_open;	long event; /* long req'd for set_bit --RR */	int asyncflags;	unsigned long statusflags;	struct tty_struct *tty;	int cflag;	wait_queue_head_t open_wait;	wait_queue_head_t close_wait;	struct work_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 WAKEUP_CHARS		256#define PORTNO(x)		((x)->index)static int verbose = 0;static int ttymajor = MOXAMAJOR;/* Variables for insmod */#ifdef MODULEstatic int baseaddr[] 	= 	{0, 0, 0, 0};static int type[]	=	{0, 0, 0, 0};static int numports[] 	=	{0, 0, 0, 0};#endifMODULE_AUTHOR("William Chen");MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver");MODULE_LICENSE("GPL");MODULE_PARM(type, "1-4i");MODULE_PARM(baseaddr, "1-4i");MODULE_PARM(numports, "1-4i");MODULE_PARM(ttymajor, "i");MODULE_PARM(verbose, "i");static struct tty_driver *moxaDriver;static struct moxa_str moxaChannels[MAX_PORTS];static unsigned char *moxaXmitBuff;static int moxaTimer_on;static struct timer_list moxaTimer;static int moxaEmptyTimer_on[MAX_PORTS];static struct timer_list moxaEmptyTimer[MAX_PORTS];static struct semaphore moxaBuffSem;/* * static functions: */static 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 int moxa_tiocmget(struct tty_struct *tty, struct file *file);static int moxa_tiocmset(struct tty_struct *tty, struct file *file,			 unsigned int set, unsigned int clear);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 *);/* * 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 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 __user *);static int moxa_set_serial_info(struct moxa_str *, struct serial_struct __user *);static void MoxaSetFifo(int port, int enable);static struct tty_operations moxa_ops = {	.open = moxa_open,	.close = moxa_close,	.write = moxa_write,	.write_room = moxa_write_room,	.flush_buffer = moxa_flush_buffer,	.chars_in_buffer = moxa_chars_in_buffer,	.flush_chars = moxa_flush_chars,	.put_char = moxa_put_char,	.ioctl = moxa_ioctl,	.throttle = moxa_throttle,	.unthrottle = moxa_unthrottle,	.set_termios = moxa_set_termios,	.stop = moxa_stop,	.start = moxa_start,	.hangup = moxa_hangup,	.tiocmget = moxa_tiocmget,	.tiocmset = moxa_tiocmset,};#ifdef CONFIG_PCIstatic int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board){	board->baseAddr = pci_resource_start (p, 2);	board->boardType = board_type;	switch (board_type) {	case MOXA_BOARD_C218_ISA:	case MOXA_BOARD_C218_PCI:		board->numPorts = 8;		break;	case MOXA_BOARD_CP204J:		board->numPorts = 4;		break;	default:		board->numPorts = 0;		break;	}	board->busType = MOXA_BUS_TYPE_PCI;	board->pciInfo.busNum = p->bus->number;	board->pciInfo.devNum = p->devfn >> 3;	return (0);}#endif /* CONFIG_PCI */static int __init moxa_init(void){	int i, numBoards;	struct moxa_str *ch;	printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION);	moxaDriver = alloc_tty_driver(MAX_PORTS + 1);	if (!moxaDriver)		return -ENOMEM;	init_MUTEX(&moxaBuffSem);	moxaDriver->owner = THIS_MODULE;	moxaDriver->name = "ttya";	moxaDriver->devfs_name = "tts/a";	moxaDriver->major = ttymajor;	moxaDriver->minor_start = 0;	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;	tty_set_operations(moxaDriver, &moxa_ops);	moxaXmitBuff = NULL;	for (i = 0, ch = moxaChannels; i < MAX_PORTS; i++, ch++) {		ch->type = PORT_16550A;		ch->port = i;		INIT_WORK(&ch->tqueue, do_moxa_softint, ch);		ch->tty = NULL;		ch->close_delay = 5 * HZ / 10;		ch->closing_wait = 30 * HZ;		ch->count = 0;		ch->blocked_open = 0;		ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;		init_waitqueue_head(&ch->open_wait);		init_waitqueue_head(&ch->close_wait);	}	for (i = 0; i < MAX_BOARDS; i++) {		moxa_boards[i].boardType = 0;		moxa_boards[i].numPorts = 0;		moxa_boards[i].baseAddr = 0;		moxa_boards[i].busType = 0;		moxa_boards[i].pciInfo.busNum = 0;		moxa_boards[i].pciInfo.devNum = 0;	}	MoxaDriverInit();	printk("Tty devices major number = %d\n", ttymajor);	if (tty_register_driver(moxaDriver)) {		printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n");		put_tty_driver(moxaDriver);		return -1;	}	for (i = 0; i < MAX_PORTS; i++) {		init_timer(&moxaEmptyTimer[i]);		moxaEmptyTimer[i].function = check_xmit_empty;		moxaEmptyTimer[i].data = (unsigned long) & moxaChannels[i];		moxaEmptyTimer_on[i] = 0;	}	init_timer(&moxaTimer);	moxaTimer.function = moxa_poll;	moxaTimer.expires = jiffies + (HZ / 50);	moxaTimer_on = 1;	add_timer(&moxaTimer);	/* Find the boards defined in source code */	numBoards = 0;	for (i = 0; i < MAX_BOARDS; i++) {		if ((moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA) ||		 (moxa_isa_boards[i].boardType == MOXA_BOARD_C320_ISA)) {			moxa_boards[numBoards].boardType = moxa_isa_boards[i].boardType;			if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA)				moxa_boards[numBoards].numPorts = 8;			else				moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts;			moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA;			moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr;			if (verbose)				printk("Board %2d: %s board(baseAddr=%lx)\n",				       numBoards + 1,				       moxa_brdname[moxa_boards[numBoards].boardType - 1],				       moxa_boards[numBoards].baseAddr);			numBoards++;		}	}	/* Find the boards defined form module args. */#ifdef MODULE	for (i = 0; i < MAX_BOARDS; i++) {		if ((type[i] == MOXA_BOARD_C218_ISA) ||		    (type[i] == MOXA_BOARD_C320_ISA)) {			if (verbose)				printk("Board %2d: %s board(baseAddr=%lx)\n",				       numBoards + 1,				       moxa_brdname[type[i] - 1],				       (unsigned long) baseaddr[i]);			if (numBoards >= MAX_BOARDS) {				if (verbose)					printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS);				continue;			}			moxa_boards[numBoards].boardType = type[i];			if (moxa_isa_boards[i].boardType == MOXA_BOARD_C218_ISA)				moxa_boards[numBoards].numPorts = 8;			else				moxa_boards[numBoards].numPorts = numports[i];			moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA;			moxa_boards[numBoards].baseAddr = baseaddr[i];			numBoards++;		}	}#endif	/* Find PCI boards here */#ifdef CONFIG_PCI	{		struct pci_dev *p = NULL;		int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1;		i = 0;		while (i < n) {			while ((p = pci_find_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL)			{				if (pci_enable_device(p))					continue;				if (numBoards >= MAX_BOARDS) {					if (verbose)						printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS);				} else {					moxa_get_PCI_conf(p, moxa_pcibrds[i].driver_data,						&moxa_boards[numBoards]);					numBoards++;				}			}			i++;		}	}#endif	for (i = 0; i < numBoards; i++) {		moxaBaseAddr[i] = (unsigned long) ioremap((unsigned long) moxa_boards[i].baseAddr, 0x4000);	}	return (0);}static void __exit moxa_exit(void){	int i;	if (verbose)		printk("Unloading module moxa ...\n");

⌨️ 快捷键说明

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