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

📄 moxa.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 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/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>#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 <asm/system.h>#include <asm/io.h>#include <asm/segment.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",};typedef 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},};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;	long session;	long pgrp;	unsigned long statusflags;	struct tty_struct *tty;	struct termios normal_termios;	struct termios callout_termios;	wait_queue_head_t open_wait;	wait_queue_head_t close_wait;	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};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				//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 struct timer_list moxaTimer;static int moxaEmptyTimer_on[MAX_PORTS];static struct timer_list moxaEmptyTimer[MAX_PORTS];static struct semaphore moxaBuffSem;int moxa_init(void);#ifdef MODULEint init_module(void);void cleanup_module(void);#endif/* * static functions: */static int moxa_get_PCI_conf(struct pci_dev *, int, moxa_board_conf *);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 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 *);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, n, numBoards;	struct moxa_str *ch;	int ret1, ret2;	printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION);	init_MUTEX(&moxaBuffSem);	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;	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 = 30 * HZ;		ch->count = 0;		ch->blocked_open = 0;		ch->callout_termios = moxaCallout.init_termios;		ch->normal_termios = moxaDriver.init_termios;		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, callout devices major number = %d\n", ttymajor, calloutmajor);	ret1 = 0;	ret2 = 0;	if ((ret1 = tty_register_driver(&moxaDriver))) {		printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n");	} else if ((ret2 = tty_register_driver(&moxaCallout))) {		tty_unregister_driver(&moxaDriver);		printk(KERN_ERR "Couldn't install MOXA Smartio family callout driver !\n");	}	if (ret1 || ret2) {		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)

⌨️ 快捷键说明

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