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

📄 synclink.c

📁 powerpc内核mpc8241linux系统下char驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * linux/drivers/char/synclink.c * * Device driver for Microgate SyncLink ISA and PCI * high speed multiprotocol serial adapters. * * written by Paul Fulghum for Microgate Corporation * paulkf@microgate.com * * Microgate and SyncLink are trademarks of Microgate Corporation * * Derived from serial.c written by Theodore Ts'o and Linus Torvalds * * Original release 01/11/99 * * This code is released under the GNU General Public License (GPL) * * This driver is primarily intended for use in synchronous * HDLC mode. Asynchronous mode is also provided. * * When operating in synchronous mode, each call to mgsl_write() * contains exactly one complete HDLC frame. Calling mgsl_put_char * will start assembling an HDLC frame that will not be sent until * mgsl_flush_chars or mgsl_write is called. *  * Synchronous receive data is reported as complete frames. To accomplish * this, the TTY flip buffer is bypassed (too small to hold largest * frame and may fragment frames) and the line discipline * receive entry point is called directly. * * This driver has been tested with a slightly modified ppp.c driver * for synchronous PPP. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #define VERSION(ver,rel,seq) (((ver)<<16) | ((rel)<<8) | (seq))#define BREAKPOINT() asm("   int $3");#define MAX_ISA_DEVICES 10#include <linux/config.h>#include <linux/module.h>#include <linux/errno.h>#include <linux/signal.h>#include <linux/sched.h>#include <linux/timer.h>#include <linux/interrupt.h>#include <linux/pci.h>#include <linux/tty.h>#include <linux/tty_flip.h>#include <linux/serial.h>#include <linux/major.h>#include <linux/string.h>#include <linux/fcntl.h>#include <linux/ptrace.h>#include <linux/ioport.h>#include <linux/mm.h>#include <linux/malloc.h>#if LINUX_VERSION_CODE >= VERSION(2,1,0)#include <linux/vmalloc.h>#include <linux/init.h>#include <asm/serial.h>#else#include <linux/bios32.h>#endif#include <linux/delay.h>#include <linux/ioctl.h>#include <asm/system.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/dma.h>#include <asm/bitops.h>#include <asm/types.h>#include <linux/termios.h>#include <linux/tqueue.h>#if LINUX_VERSION_CODE >= VERSION(2,1,4)#include <asm/segment.h>#define GET_USER(error,value,addr) error = get_user(value,addr)#define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0#define PUT_USER(error,value,addr) error = put_user(value,addr)#define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0#if LINUX_VERSION_CODE >= VERSION(2,1,5)#include <asm/uaccess.h>#endif#else  /* 2.0.x and 2.1.x before 2.1.4 */#define GET_USER(error,value,addr)					  \do {									  \	error = verify_area (VERIFY_READ, (void *) addr, sizeof (value)); \	if (error == 0)							  \		value = get_user(addr);					  \} while (0)#define COPY_FROM_USER(error,dest,src,size)				  \do {									  \	error = verify_area (VERIFY_READ, (void *) src, size);		  \	if (error == 0)							  \		memcpy_fromfs (dest, src, size);			  \} while (0)#define PUT_USER(error,value,addr)					   \do {									   \	error = verify_area (VERIFY_WRITE, (void *) addr, sizeof (value)); \	if (error == 0)							   \		put_user (value, addr);					   \} while (0)#define COPY_TO_USER(error,dest,src,size)				  \do {									  \	error = verify_area (VERIFY_WRITE, (void *) dest, size);		  \	if (error == 0)							  \		memcpy_tofs (dest, src, size);				  \} while (0)#endif#if LINUX_VERSION_CODE < VERSION(2,1,0)/* * This is used to figure out the divisor speeds and the timeouts */static int baud_table[] = {	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,	9600, 19200, 38400, 57600, 115200, 230400, 460800, 0 };#define __init#define ioremap(a,b) vremap((a),(b))#define iounmap(a) vfree((a))#define SERIAL_TYPE_NORMAL	1#define SERIAL_TYPE_CALLOUT	2typedef int spinlock_t;#define spin_lock_irqsave(a,b) {save_flags((b));cli();}#define spin_unlock_irqrestore(a,b) {restore_flags((b));}#define spin_lock(a)#define spin_unlock(a)#define schedule_timeout(a){current->timeout = jiffies + (a); schedule();}#define signal_pending(a) ((a)->signal & ~(a)->blocked)#endif#include "linux/synclink.h"#define RCLRVALUE 0xffffMGSL_PARAMS default_params = {	MGSL_MODE_HDLC,			/* unsigned long mode */	0,				/* unsigned char loopback; */	HDLC_FLAG_UNDERRUN_ABORT15,	/* unsigned short flags; */	HDLC_ENCODING_NRZI_SPACE,	/* unsigned char encoding; */	0,				/* unsigned long clock_speed; */	0xff,				/* unsigned char addr_filter; */	HDLC_CRC_16_CCITT,		/* unsigned short crc_type; */	HDLC_PREAMBLE_LENGTH_8BITS,	/* unsigned char preamble_length; */	HDLC_PREAMBLE_PATTERN_NONE,	/* unsigned char preamble; */	9600,				/* unsigned long data_rate; */	8,				/* unsigned char data_bits; */	1,				/* unsigned char stop_bits; */	ASYNC_PARITY_NONE		/* unsigned char parity; */};#define SHARED_MEM_ADDRESS_SIZE 0x40000#define BUFFERLISTSIZE (PAGE_SIZE)#define DMABUFFERSIZE (PAGE_SIZE)#define MAXRXFRAMES 7typedef struct _DMABUFFERENTRY{	u32 phys_addr;	/* 32-bit flat physical address of data buffer */	u16 count;	/* buffer size/data count */	u16 status;	/* Control/status field */	u16 rcc;	/* character count field */	u16 reserved;	/* padding required by 16C32 */	u32 link;	/* 32-bit flat link to next buffer entry */	char *virt_addr;	/* virtual address of data buffer */	u32 phys_entry;	/* physical address of this buffer entry */} DMABUFFERENTRY, *DMAPBUFFERENTRY;/* The queue of BH actions to be performed */#define BH_TYPE_RECEIVE_DATA	1#define BH_TYPE_RECEIVE_STATUS	2#define BH_TYPE_RECEIVE_DMA	3#define BH_TYPE_TRANSMIT_DATA	4#define BH_TYPE_TRANSMIT_STATUS	5#define BH_TYPE_STATUS		6typedef struct _BH_EVENT {	unsigned char type;  /* Set by interrupt routines to reqst */	u16 status;	struct _BH_EVENT *link;	} BH_EVENT, *BH_QUEUE;     /* Queue of BH actions to be done.  */#define MAX_BH_QUEUE_ENTRIES 200#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))/* * Device instance data structure */ struct mgsl_struct {	int			magic;	int			flags;	int			count;		/* count of opens */	int			line;	unsigned short		close_delay;	unsigned short		closing_wait;	/* time to wait before closing */		struct mgsl_icount	icount;		struct termios		normal_termios;	struct termios		callout_termios;		struct tty_struct 	*tty;	int			timeout;	int			x_char;		/* xon/xoff character */	int			blocked_open;	/* # of blocked opens */	long			session;	/* Session of opening process */	long			pgrp;		/* pgrp of opening process */	u16			read_status_mask;	u16			ignore_status_mask;		unsigned char 		*xmit_buf;	int			xmit_head;	int			xmit_tail;	int			xmit_cnt;		struct wait_queue	*open_wait;	struct wait_queue	*close_wait;		struct wait_queue	*status_event_wait_q;	struct wait_queue	*event_wait_q;	struct timer_list	tx_timer;	/* HDLC transmit timeout timer */	struct mgsl_struct	*next_device;	/* device list link */		spinlock_t irq_spinlock;		/* spinlock for synchronizing with ISR */	struct tq_struct task;		/* task structure for scheduling bh */	u32 EventMask;			/* event trigger mask */	u32 RecordedEvents;		/* pending events */	u32 max_frame_size;		/* as set by device config */	BH_EVENT bh_queue[MAX_BH_QUEUE_ENTRIES];		/* Pointer to alloc'ed block */	BH_QUEUE bh_queue_head;	/* Queue of BH actions */	BH_QUEUE bh_queue_tail;	/* Tail of above for perf. */	BH_QUEUE free_bh_queue_head;	/* Queue of Free BH */	BH_QUEUE free_bh_queue_tail;	/* Tail of above for perf. */	BH_QUEUE bh_action;	/* Action for BH */	int bh_running;		/* Protection from multiple */	int isr_overflow;	int bh_requested;	char *buffer_list;		/* virtual address of Rx & Tx buffer lists */	unsigned long buffer_list_phys;	unsigned int rx_buffer_count;	/* count of total allocated Rx buffers */	DMABUFFERENTRY *rx_buffer_list;	/* list of receive buffer entries */	unsigned int current_rx_buffer;	unsigned int tx_buffer_count;	/* count of total allocated Tx buffers */	DMABUFFERENTRY *tx_buffer_list;	/* list of transmit buffer entries */	int rx_enabled;	int rx_overflow;	int tx_enabled;	int tx_active;	u32 idle_mode;	u16 cmr_value;	char device_name[25];		/* device instance name */	unsigned int bus_type;	/* expansion bus type (ISA,EISA,PCI) */	unsigned char bus;		/* expansion bus number (zero based) */	unsigned char function;		/* PCI device number */	unsigned int io_base;		/* base I/O address of adapter */	unsigned int io_addr_size;	/* size of the I/O address range */	int io_addr_requested;		/* nonzero if I/O address requested */		unsigned int irq_level;		/* interrupt level */	unsigned long irq_flags;	int irq_requested;		/* nonzero if IRQ requested */		unsigned int dma_level;		/* DMA channel */	int dma_requested;		/* nonzero if dma channel requested */	u16 mbre_bit;	u16 loopback_bits;	u16 usc_idle_mode;	MGSL_PARAMS params;		/* communications parameters */	unsigned char serial_signals;	/* current serial signal states */	int irq_occurred;		/* for diagnostics use */	unsigned int init_error;	/* Initialization startup error 		(DIAGS)	*/	int	fDiagnosticsmode;	/* Driver in Diagnostic mode?			(DIAGS)	*/	u32 last_mem_alloc;	unsigned char* memory_base;	/* shared memory address (PCI only) */	u32 phys_memory_base;	unsigned char* lcr_base;	/* local config registers (PCI only) */	u32 phys_lcr_base;	u32 lcr_offset;	u32 misc_ctrl_value;	char flag_buf[HDLC_MAX_FRAME_SIZE];	char char_buf[HDLC_MAX_FRAME_SIZE];		BOOLEAN drop_rts_on_tx_done;};#define MGSL_MAGIC 0x5401/* * The size of the serial xmit buffer is 1 page, or 4096 bytes */#define SERIAL_XMIT_SIZE 4096/* * These macros define the offsets used in calculating the * I/O address of the specified USC registers. */#define DCPIN 2		/* Bit 1 of I/O address */#define SDPIN 4		/* Bit 2 of I/O address */#define DCAR 0		/* DMA command/address register */#define CCAR SDPIN		/* channel command/address register */#define DATAREG DCPIN + SDPIN	/* serial data register */#define MSBONLY 0x41#define LSBONLY 0x40/* * These macros define the register address (ordinal number) * used for writing address/value pairs to the USC. */#define CMR	0x02	/* Channel mode Register */#define CCSR	0x04	/* Channel Command/status Register */#define CCR	0x06	/* Channel Control Register */#define PSR	0x08	/* Port status Register */#define PCR	0x0a	/* Port Control Register */#define TMDR	0x0c	/* Test mode Data Register */#define TMCR	0x0e	/* Test mode Control Register */#define CMCR	0x10	/* Clock mode Control Register */#define HCR	0x12	/* Hardware Configuration Register */#define IVR	0x14	/* Interrupt Vector Register */#define IOCR	0x16	/* Input/Output Control Register */#define ICR	0x18	/* Interrupt Control Register */#define DCCR	0x1a	/* Daisy Chain Control Register */#define MISR	0x1c	/* Misc Interrupt status Register */#define SICR	0x1e	/* status Interrupt Control Register */#define RDR	0x20	/* Receive Data Register */#define RMR	0x22	/* Receive mode Register */#define RCSR	0x24	/* Receive Command/status Register */#define RICR	0x26	/* Receive Interrupt Control Register */#define RSR	0x28	/* Receive Sync Register */#define RCLR	0x2a	/* Receive count Limit Register */#define RCCR	0x2c	/* Receive Character count Register */#define TC0R	0x2e	/* Time Constant 0 Register */#define TDR	0x30	/* Transmit Data Register */#define TMR	0x32	/* Transmit mode Register */#define TCSR	0x34	/* Transmit Command/status Register */#define TICR	0x36	/* Transmit Interrupt Control Register */#define TSR	0x38	/* Transmit Sync Register */#define TCLR	0x3a	/* Transmit count Limit Register */#define TCCR	0x3c	/* Transmit Character count Register */#define TC1R	0x3e	/* Time Constant 1 Register *//* * MACRO DEFINITIONS FOR DMA REGISTERS */#define DCR	0x06	/* DMA Control Register (shared) */#define DACR	0x08	/* DMA Array count Register (shared) */#define BDCR	0x12	/* Burst/Dwell Control Register (shared) */#define DIVR	0x14	/* DMA Interrupt Vector Register (shared) */	#define DICR	0x18	/* DMA Interrupt Control Register (shared) */#define CDIR	0x1a	/* Clear DMA Interrupt Register (shared) */#define SDIR	0x1c	/* Set DMA Interrupt Register (shared) */#define TDMR	0x02	/* Transmit DMA mode Register */#define TDIAR	0x1e	/* Transmit DMA Interrupt Arm Register */#define TBCR	0x2a	/* Transmit Byte count Register */#define TARL	0x2c	/* Transmit Address Register (low) */#define TARU	0x2e	/* Transmit Address Register (high) */#define NTBCR	0x3a	/* Next Transmit Byte count Register */#define NTARL	0x3c	/* Next Transmit Address Register (low) */#define NTARU	0x3e	/* Next Transmit Address Register (high) */#define RDMR	0x82	/* Receive DMA mode Register (non-shared) */#define RDIAR	0x9e	/* Receive DMA Interrupt Arm Register */#define RBCR	0xaa	/* Receive Byte count Register */#define RARL	0xac	/* Receive Address Register (low) */#define RARU	0xae	/* Receive Address Register (high) */#define NRBCR	0xba	/* Next Receive Byte count Register */#define NRARL	0xbc	/* Next Receive Address Register (low) */#define NRARU	0xbe	/* Next Receive Address Register (high) *//* * MACRO DEFINITIONS FOR MODEM STATUS BITS */#define MODEMSTATUS_DTR 0x80#define MODEMSTATUS_DSR 0x40#define MODEMSTATUS_RTS 0x20#define MODEMSTATUS_CTS 0x10#define MODEMSTATUS_RI  0x04#define MODEMSTATUS_DCD 0x01/* * Channel Command/Address Register (CCAR) Command Codes */#define RTCmd_Null			0x0000

⌨️ 快捷键说明

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