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

📄 moxa.c

📁 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. *//* *    MOXA Intellio Series Driver *      for             : LINUX *      date            : 1999/1/7 *      version         : 5.1 */#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 <linux/bitops.h>#include <linux/completion.h>#include <asm/system.h>#include <asm/io.h>#include <asm/uaccess.h>#define MOXA_VERSION		"5.1k"#define MOXAMAJOR		172#define MOXACUMAJOR		173#define MAX_BOARDS		4	/* Don't change this value */#define MAX_PORTS_PER_BOARD	32	/* Don't change this value */#define MAX_PORTS		(MAX_BOARDS * MAX_PORTS_PER_BOARD)/* *    Define the Moxa PCI vendor and device IDs. */#define MOXA_BUS_TYPE_ISA	0#define MOXA_BUS_TYPE_PCI	1enum {	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_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C218),		.driver_data = MOXA_BOARD_C218_PCI },	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C320),		.driver_data = MOXA_BOARD_C320_PCI },	{ PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP204J),		.driver_data = MOXA_BOARD_CP204J },	{ 0 }};MODULE_DEVICE_TABLE(pci, moxa_pcibrds);#endif /* CONFIG_PCI */struct moxa_isa_board_conf {	int boardType;	int numPorts;	unsigned long baseAddr;};static struct moxa_isa_board_conf moxa_isa_boards[] ={/*       {MOXA_BOARD_C218_ISA,8,0xDC000}, */};static struct moxa_board_conf {	int boardType;	int numPorts;	unsigned long baseAddr;	int busType;	int loadstat;	void __iomem *basemem;	void __iomem *intNdx;	void __iomem *intPend;	void __iomem *intTable;} moxa_boards[MAX_BOARDS];struct mxser_mstatus {	tcflag_t cflag;	int cts;	int dsr;	int ri;	int dcd;};struct moxaq_str {	int inq;	int outq;};struct moxa_port {	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;	struct completion close_wait;	struct timer_list emptyTimer;	char chkPort;	char lineCtrl;	void __iomem *tableAddr;	long curBaud;	char DCDState;	char lowChkFlag;	ushort breakCnt;};/* statusflags */#define TXSTOPPED	0x1#define LOWWAIT 	0x2#define EMPTYWAIT	0x4#define THROTTLE	0x8#define SERIAL_DO_RESTART#define WAKEUP_CHARS		256static int ttymajor = MOXAMAJOR;/* Variables for insmod */#ifdef MODULEstatic int baseaddr[4];static int type[4];static int numports[4];#endifMODULE_AUTHOR("William Chen");MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver");MODULE_LICENSE("GPL");#ifdef MODULEmodule_param_array(type, int, NULL, 0);module_param_array(baseaddr, int, NULL, 0);module_param_array(numports, int, NULL, 0);#endifmodule_param(ttymajor, int, 0);/* * static functions: */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 *, 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 ktermios *);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 moxa_set_tty_param(struct tty_struct *);static int moxa_block_till_ready(struct tty_struct *, struct file *,			    struct moxa_port *);static void moxa_setup_empty_event(struct tty_struct *);static void moxa_check_xmit_empty(unsigned long);static void moxa_shut_down(struct moxa_port *);static void moxa_receive_data(struct moxa_port *);/* * 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 ktermios *, speed_t);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, struct tty_struct *tty);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_port *, struct serial_struct __user *);static int moxa_set_serial_info(struct moxa_port *, struct serial_struct __user *);static void MoxaSetFifo(int port, int enable);static const 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,};static struct tty_driver *moxaDriver;static struct moxa_port moxa_ports[MAX_PORTS];static DEFINE_TIMER(moxaTimer, moxa_poll, 0, 0);static DEFINE_SPINLOCK(moxa_lock);#ifdef CONFIG_PCIstatic int __devinit moxa_pci_probe(struct pci_dev *pdev,		const struct pci_device_id *ent){	struct moxa_board_conf *board;	unsigned int i;	int board_type = ent->driver_data;	int retval;	retval = pci_enable_device(pdev);	if (retval) {		dev_err(&pdev->dev, "can't enable pci device\n");		goto err;	}	for (i = 0; i < MAX_BOARDS; i++)		if (moxa_boards[i].basemem == NULL)			break;	retval = -ENODEV;	if (i >= MAX_BOARDS) {		dev_warn(&pdev->dev, "more than %u MOXA Intellio family boards "				"found. Board is ignored.\n", MAX_BOARDS);		goto err;	}	board = &moxa_boards[i];	board->basemem = pci_iomap(pdev, 2, 0x4000);	if (board->basemem == NULL) {		dev_err(&pdev->dev, "can't remap io space 2\n");		goto err;	}	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;	pci_set_drvdata(pdev, board);	return (0);err:	return retval;}static void __devexit moxa_pci_remove(struct pci_dev *pdev){	struct moxa_board_conf *brd = pci_get_drvdata(pdev);	pci_iounmap(pdev, brd->basemem);	brd->basemem = NULL;}static struct pci_driver moxa_pci_driver = {	.name = "moxa",	.id_table = moxa_pcibrds,	.probe = moxa_pci_probe,	.remove = __devexit_p(moxa_pci_remove)};#endif /* CONFIG_PCI */static int __init moxa_init(void){	int i, numBoards, retval = 0;	struct moxa_port *ch;	printk(KERN_INFO "MOXA Intellio family driver version %s\n",			MOXA_VERSION);	moxaDriver = alloc_tty_driver(MAX_PORTS + 1);	if (!moxaDriver)		return -ENOMEM;	moxaDriver->owner = THIS_MODULE;	moxaDriver->name = "ttyMX";	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_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;	moxaDriver->init_termios.c_ispeed = 9600;	moxaDriver->init_termios.c_ospeed = 9600;	moxaDriver->flags = TTY_DRIVER_REAL_RAW;	tty_set_operations(moxaDriver, &moxa_ops);	for (i = 0, ch = moxa_ports; i < MAX_PORTS; i++, ch++) {		ch->type = PORT_16550A;		ch->port = i;		ch->close_delay = 5 * HZ / 10;		ch->closing_wait = 30 * HZ;		ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;		init_waitqueue_head(&ch->open_wait);		init_completion(&ch->close_wait);		setup_timer(&ch->emptyTimer, moxa_check_xmit_empty,				(unsigned long)ch);	}	pr_debug("Moxa 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;	}	mod_timer(&moxaTimer, jiffies + HZ / 50);	/* 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;			pr_debug("Moxa 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)) {			pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n",			       numBoards + 1, moxa_brdname[type[i] - 1],			       (unsigned long)baseaddr[i]);			if (numBoards >= MAX_BOARDS) {				printk(KERN_WARNING "More than %d MOXA "					"Intellio family boards found. Board "					"is ignored.\n", 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#ifdef CONFIG_PCI	retval = pci_register_driver(&moxa_pci_driver);	if (retval) {		printk(KERN_ERR "Can't register moxa pci driver!\n");		if (numBoards)			retval = 0;	}#endif	for (i = 0; i < numBoards; i++) {		moxa_boards[i].basemem = ioremap(moxa_boards[i].baseAddr,				0x4000);	}	return retval;}static void __exit moxa_exit(void){	int i;	del_timer_sync(&moxaTimer);	for (i = 0; i < MAX_PORTS; i++)		del_timer_sync(&moxa_ports[i].emptyTimer);	if (tty_unregister_driver(moxaDriver))		printk(KERN_ERR "Couldn't unregister MOXA Intellio family "				"serial driver\n");	put_tty_driver(moxaDriver);#ifdef CONFIG_PCI	pci_unregister_driver(&moxa_pci_driver);#endif	for (i = 0; i < MAX_BOARDS; i++)		if (moxa_boards[i].basemem)			iounmap(moxa_boards[i].basemem);}module_init(moxa_init);module_exit(moxa_exit);static int moxa_open(struct tty_struct *tty, struct file *filp){	struct moxa_port *ch;	int port;	int retval;	port = tty->index;	if (port == MAX_PORTS) {		return (0);

⌨️ 快捷键说明

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