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

📄 jpt_driver.c

📁 这是一个LINUX下多串口驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
#include <linux/config.h>#include <linux/module.h>#include <linux/version.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/serial.h>#include <linux/serial_reg.h>#include <linux/major.h>#include <linux/string.h>#include <linux/fcntl.h>#include <linux/fs.h>#include <linux/ptrace.h>#include <linux/ioport.h>#include <linux/mm.h>#include <linux/smp_lock.h>#include <linux/pci.h>#include <linux/timer.h>#include <linux/syscalls.h>#include <asm/system.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/bitops.h>#include <asm/uaccess.h>#include <asm/delay.h>#include "jpt_core.h"#define		NUART_VERSION		"1.0"#define	PCI_VENDOR_ID_NUART		0x10EE#define PCI_DEVICE_ID_NUART		0x0100#define		NUARTMAJOR 		184#define 	NUART_BOARDS		5	/* Max. boards */#define 	NUART_PORTS		80	/* Max. ports */#define 	NUART_PORTS_PER_BOARD	16	/* Max. ports per board */#define WAKEUP_CHARS		256	#define	VERSION_CODE(ver,rel,seq) ((ver << 16) | (rel << 8) | seq)static char *nuart_typename[] = {	"rs232",	"rs485",	"rs422/rs485",	"rs232/rs422/rs485"};struct nuart_hwconf {	int board_type;	int ports;	unsigned long ioaddr_base;		long baud_base;	struct pci_dev *pdev;};struct nuart_struct {	int port;	unsigned long base;	/* port base address */	int baud_base;		/* max. speed */	int type;	int mode;	int flags;		/* defined in tty.h */	struct tty_struct *tty;	int x_char;		/* xon/xoff character */	int close_delay;	unsigned short closing_wait;	unsigned long	event;	int count;		/* # of fd on device */	int blocked_open;	/* # of blocked opens */	int xmit_fifo_size;	unsigned char *xmit_buf;	int xmit_head;	int xmit_tail;	int xmit_cnt;	unsigned char	rrp;	unsigned char	rwp;	unsigned char	trp;	unsigned char	twp;		char 	wbl[4];		/* register shadow */	struct nuart_reg  reg;	unsigned long read_status_mask;	unsigned long ignore_status_mask;#if (LINUX_VERSION_CODE < VERSION_CODE(2,6,0))		struct tq_struct	tqueue;#else	struct work_struct tqueue;#endif		int cflag;	unsigned long lflag;	/* local flag */#if (LINUX_VERSION_CODE < VERSION_CODE(2,4,0))	struct wait_queue	*open_wait;	struct wait_queue	*close_wait;	struct wait_queue	*delta_msr_wait;#else	wait_queue_head_t open_wait;	wait_queue_head_t close_wait;	wait_queue_head_t delta_msr_wait;#endif	struct async_icount icount;		spinlock_t		lock;	long			session;	/* Session of opening process */	long			pgrp;		/* pgrp of opening process */	int			timeout;	int fifo_size;		void (* receive_func)(struct nuart_struct *, unsigned long);	void (* transmit_func)(struct nuart_struct *);};/* local flag */#define		NUART_LFLAG_MSI		0x01#define		NUART_LFLAG_RLSI	0x02#define 	NUART_LFLAG_THRI	0x04#define 	NUART_LFLAG_RDI		0x08/* REGISTER */#define		NUART_PCR		0x200#define		NUART_XPR		0x204#define		NUART_BR		0x208#define		NUART_MPR		0x20C#define		NUART_PR		0x210/* NUART_PCR */#define		NUART_CHE		(1<<31)#define		NUART_OCLR		(1<<26)#define		NUART_OSUSP		(1<<25)#define		NUART_PXOFF		(1<<24)#define		NUART_PXON		(1<<23)#define		NUART_BC		(1<<22)#define		NUART_BZO		(1<<21)#define		NUART_BZ		(1<<20)#define		NUART_ERRC		(1<<19)#define		NUART_RXX		(1<<18)#define		NUART_IXA		(1<<17)#define		NUART_IX		(1<<16)#define		NUART_CXOFF		(1<<15)#define		NUART_OX		(1<<14)#define		NUART_OCTS		(1<<13)#define		NUART_ODSR		(1<<12)#define		NUART_RTSC_LOW	0#define		NUART_RTSC_HIGH	(1<<10)#define		NUART_RTSC_FLOW	(2<<10)#define		NUART_RTSC_TOG	(3<<10)#define		NUART_RTSC_MASK	(3<<10)#define		NUART_DTRC_LOW	0#define		NUART_DTRC_HIGH	(1<<8)#define		NUART_DTRC_FLOW	(2<<8)#define		NUART_DTRC_TOG	(3<<8)#define		NUART_DTRC_MASK	(3<<8)#define		NUART_OBRK		(1<<7)#define		NUART_P_ODD		0#define		NUART_P_EVEN	(1<<5)#define		NUART_P_MARK	(2<<5)#define		NUART_P_SPACE	(3<<5)#define		NUART_P_MASK	(3<<5)#define		NUART_PEN		(1<<4)#define		NUART_SBITS		(1<<3)/* NUART_MPR */#define		NUART_RXOFF		(1<<24)#define		NUART_TBUSY		(1<<23)#define		NUART_PERR		(1<<22)#define		NUART_FERR		(1<<21)#define		NUART_IBRK		(1<<20)#define		NUART_DCD		(1<<19)#define		NUART_RI		(1<<18)#define		NUART_DSR		(1<<17)#define		NUART_CTS		(1<<16)#define RELEVANT_IFLAG(iflag)	(iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))#define 	PORTNO(x)	((x)->index)#ifndef MIN#define MIN(a,b)	((a) < (b) ? (a) : (b))#endif#define SERIAL_TYPE_NORMAL	1#define NUART_EVENT_TXLOW	1#define NUART_EVENT_HANGUP	2static int ttymajor = NUARTMAJOR;static int verbose = 1;/* Variables for insmod */MODULE_AUTHOR("newtry");MODULE_DESCRIPTION("NewTry");MODULE_LICENSE("GPL");MODULE_PARM(ttymajor, "i");MODULE_PARM(verbose, "i");static struct tty_driver *nuvar_sdriver;static struct nuart_struct nuvar_table[NUART_PORTS];static unsigned char *nuvar_tmp_buf;static struct semaphore nuvar_tmp_buf_sem;static struct timer_list nuart_timer;struct nuart_hwconf nuartcfg[NUART_BOARDS];/* baud max 1.8432MHZ */static int nuart_baud_table[] ={	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,	9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600, 0 };static struct pci_device_id nuart_pcibrds[] = {	{ PCI_VENDOR_ID_NUART, PCI_DEVICE_ID_NUART, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NUART_BOARD_RS232},	{ 0 }};MODULE_DEVICE_TABLE(pci, nuart_pcibrds);static int nuart_open(struct tty_struct *, struct file *);static void nuart_close(struct tty_struct *, struct file *);#if (LINUX_VERSION_CODE < VERSION_CODE(2,6,10))static int nuart_write(struct tty_struct *, int, const unsigned char *, int);#elsestatic int nuart_write(struct tty_struct *, const unsigned char *, int);#endifstatic int nuart_write_room(struct tty_struct *);static void nuart_flush_buffer(struct tty_struct *);static int nuart_chars_in_buffer(struct tty_struct *);static void nuart_flush_chars(struct tty_struct *);static void nuart_put_char(struct tty_struct *, unsigned char);static int nuart_ioctl(struct tty_struct *, struct file *, uint, ulong);static void nuart_throttle(struct tty_struct *);static void nuart_unthrottle(struct tty_struct *);static void nuart_set_termios(struct tty_struct *, struct termios *);static void nuart_stop(struct tty_struct *);static void nuart_start(struct tty_struct *);static void nuart_hangup(struct tty_struct *);static void nuart_receive_chars(struct nuart_struct *, unsigned long);static void nuart_transmit_chars(struct nuart_struct *);static void nuart16_receive_chars(struct nuart_struct *, unsigned long);static void nuart16_transmit_chars(struct nuart_struct *);static int nuart_block_til_ready(struct tty_struct *, struct file *, struct nuart_struct *);static int nuart_startup(struct nuart_struct *);static void nuart_shutdown(struct nuart_struct *);static int nuart_change_speed(struct nuart_struct *, struct termios *old_termios);static int nuart_get_serial_info(struct nuart_struct *, struct serial_struct *);static int nuart_set_serial_info(struct nuart_struct *, struct serial_struct *);static int nuart_get_lsr_info(struct nuart_struct *, unsigned int *);static void nuart_send_break(struct nuart_struct *, int);static int nuart_tiocmget(struct tty_struct * tty, struct file * file);static int nuart_tiocmset(struct tty_struct *tty, struct file * file, unsigned int set, unsigned int clear);//static int nuart_get_modem_info(struct nuart_struct *, unsigned int *);//static int nuart_set_modem_info(struct nuart_struct *, unsigned int, unsigned int *);static void nuart_timeout(unsigned long ptr);static void nuart_do_softint(void *private_);static int nuart_pci_probe(void);static void nuart_check_modem_status(struct nuart_struct *info, unsigned long status){	int delta_dcd = 0;	if((info->reg.mpr & NUART_RI) != (status & NUART_RI))	    info->icount.rng++;	if((info->reg.mpr & NUART_DSR) != (status & NUART_DSR))	    info->icount.dsr++;	if((info->reg.mpr & NUART_DCD) != (status & NUART_DCD))	{	    info->icount.dcd++;		delta_dcd = 1;	}	if((info->reg.mpr & NUART_CTS) != (status & NUART_CTS))	    info->icount.cts++;	wake_up_interruptible(&info->delta_msr_wait);	if ( (info->flags & ASYNC_CHECK_CD) && delta_dcd ) 	{	    if ( status & NUART_DCD )		wake_up_interruptible(&info->open_wait);	    else	    {		set_bit(NUART_EVENT_HANGUP, &info->event);	    	schedule_work(&info->tqueue);	    }	}	if ( info->flags & ASYNC_CTS_FLOW ) 	{	    if ( info->tty->hw_stopped ) 	    {		if (status & NUART_CTS )		{  			info->tty->hw_stopped = 0;			set_bit(NUART_EVENT_TXLOW, &info->event);	   		schedule_work(&info->tqueue);        	}   	    }	    else	    {		if ( !(status & NUART_CTS) )		{		    info->tty->hw_stopped = 1;	   	}	    }	}}static void nuart_receive_chars(struct nuart_struct *info, unsigned long stat){	struct tty_struct *tty = info->tty;	unsigned char rbuf[260];	unsigned long tmprrp;	int count, pad, i;	unsigned long	status = stat;	unsigned long	flags = 0;	count = (info->rwp - info->rrp) & 0xff;	count = MIN(count, TTY_FLIPBUF_SIZE - tty->flip.count);	if(!count)		return;	pad = info->rrp & 3;	tmprrp = info->rrp & (~3);	spin_lock_irqsave(&info->lock, flags);	nuart_read_buf(info->base,tmprrp, rbuf, pad+count);	spin_unlock_irqrestore(&info->lock, flags);		for (i = pad; i < count + pad; i++)	{		tty->flip.count++;		if(status & (NUART_PERR | NUART_FERR | NUART_IBRK))		{			if (status & NUART_IBRK) 			{				*tty->flip.flag_buf_ptr++ = TTY_BREAK;				info->icount.brk++;				if ( info->flags & ASYNC_SAK )				    do_SAK(tty);				status &= ~NUART_IBRK;			} 			else if (status & NUART_PERR) 			{				*tty->flip.flag_buf_ptr++ = TTY_PARITY;				info->icount.parity++;				status &= ~NUART_PERR;			} 			else if (status & NUART_FERR) 			{				*tty->flip.flag_buf_ptr++ = TTY_FRAME;				info->icount.frame++;				status &= ~NUART_FERR;			}			else				*tty->flip.flag_buf_ptr++ = TTY_NORMAL;		} else				*tty->flip.flag_buf_ptr++ = TTY_NORMAL;			*tty->flip.char_buf_ptr++ = rbuf[i];	}	info->icount.rx += count;	info->rrp += count;//	schedule_delayed_work(&tty->flip.work, 1);	tty_flip_buffer_push(tty);	spin_lock_irqsave(&info->lock, flags);	nuart_set_rrp(info->base, &info->reg, info->rrp);	if(stat & (NUART_PERR | NUART_FERR | NUART_IBRK))		nuart_clr_err(info->base, &info->reg);	spin_unlock_irqrestore(&info->lock, flags);	return;}static void nuart16_receive_chars(struct nuart_struct *info, unsigned long stat){	struct tty_struct *tty = info->tty;	unsigned char rbuf[260];	unsigned long tmprrp;	int count, pad, i;	unsigned long	status = stat;	unsigned long	flags = 0;	count = (info->rwp - info->rrp) & 0x7f;	count = MIN(count, TTY_FLIPBUF_SIZE - tty->flip.count);	if(!count)		return;	pad = info->rrp & 3;	tmprrp = info->rrp & (~3);		spin_lock_irqsave(&info->lock, flags);	nuart_read_buf(info->base,tmprrp, rbuf, pad+count);	spin_unlock_irqrestore(&info->lock, flags);		for (i = pad; i < count + pad; i++)	{		tty->flip.count++;		if(status & (NUART_PERR | NUART_FERR | NUART_IBRK))		{			if (status & NUART_IBRK) 			{				*tty->flip.flag_buf_ptr++ = TTY_BREAK;				info->icount.brk++;				if ( info->flags & ASYNC_SAK )				    do_SAK(tty);				status &= ~NUART_IBRK;			} 			else if (status & NUART_PERR) 			{				*tty->flip.flag_buf_ptr++ = TTY_PARITY;				info->icount.parity++;				status &= ~NUART_PERR;			} 			else if (status & NUART_FERR) 			{				*tty->flip.flag_buf_ptr++ = TTY_FRAME;				info->icount.frame++;				status &= ~NUART_FERR;			}			else				*tty->flip.flag_buf_ptr++ = TTY_NORMAL;		} else				*tty->flip.flag_buf_ptr++ = TTY_NORMAL;			*tty->flip.char_buf_ptr++ = rbuf[i];	}	info->icount.rx += count;	info->rrp += count;//	schedule_delayed_work(&tty->flip.work, 1);	tty_flip_buffer_push(tty);	spin_lock_irqsave(&info->lock, flags);	nuart_set_rrp(info->base, &info->reg, info->rrp);	if(stat & (NUART_PERR | NUART_FERR | NUART_IBRK))		nuart_clr_err(info->base, &info->reg);	spin_unlock_irqrestore(&info->lock, flags);	return;}static void nuart_transmit_chars(struct nuart_struct *info){	int count, i;	int wbl_pos;	int buf_pos;	char  tbuf[256];	int c;	unsigned long flags = 0;	count = 248 - ((info->twp - info->trp) & 0xff);	count = MIN(info->xmit_cnt, count);	if(count <= 0)		return;	wbl_pos = info->twp & 3;	buf_pos = info->twp & (~3);	if(wbl_pos)		memcpy(tbuf,info->wbl,wbl_pos);		for(i = wbl_pos;i < count + wbl_pos; i++)	{		c = info->xmit_buf[info->xmit_tail++];

⌨️ 快捷键说明

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