synclinkmp.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,458 行 · 第 1/5 页

C
2,458
字号
/* * $Id: synclinkmp.c,v 4.29 2004/08/27 20:06:41 paulkf Exp $ * * Device driver for Microgate SyncLink Multiport * high speed multiprotocol serial adapter. * * 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 * This code is released under the GNU General Public License (GPL) * * 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))#if defined(__i386__)#  define BREAKPOINT() asm("   int $3");#else#  define BREAKPOINT() { }#endif#define MAX_DEVICES 12#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/slab.h>#include <linux/netdevice.h>#include <linux/vmalloc.h>#include <linux/init.h>#include <asm/serial.h>#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/workqueue.h>#include <linux/hdlc.h>#ifdef CONFIG_HDLC_MODULE#define CONFIG_HDLC 1#endif#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#include <asm/uaccess.h>#include "linux/synclink.h"static MGSL_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; */};/* size in bytes of DMA data buffers */#define SCABUFSIZE 	1024#define SCA_MEM_SIZE	0x40000#define SCA_BASE_SIZE   512#define SCA_REG_SIZE    16#define SCA_MAX_PORTS   4#define SCAMAXDESC 	128#define	BUFFERLISTSIZE	4096/* SCA-I style DMA buffer descriptor */typedef struct _SCADESC{	u16	next;		/* lower l6 bits of next descriptor addr */	u16	buf_ptr;	/* lower 16 bits of buffer addr */	u8	buf_base;	/* upper 8 bits of buffer addr */	u8	pad1;	u16	length;		/* length of buffer */	u8	status;		/* status of buffer */	u8	pad2;} SCADESC, *PSCADESC;typedef struct _SCADESC_EX{	/* device driver bookkeeping section */	char 	*virt_addr;    	/* virtual address of data buffer */	u16	phys_entry;	/* lower 16-bits of physical address of this descriptor */} SCADESC_EX, *PSCADESC_EX;/* The queue of BH actions to be performed */#define BH_RECEIVE  1#define BH_TRANSMIT 2#define BH_STATUS   4#define IO_PIN_SHUTDOWN_LIMIT 100#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))struct	_input_signal_events {	int	ri_up;	int	ri_down;	int	dsr_up;	int	dsr_down;	int	dcd_up;	int	dcd_down;	int	cts_up;	int	cts_down;};/* * Device instance data structure */typedef struct _synclinkmp_info {	void *if_ptr;				/* General purpose pointer (used by SPPP) */	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 tty_struct 	*tty;	int			timeout;	int			x_char;		/* xon/xoff character */	int			blocked_open;	/* # of blocked opens */	u16			read_status_mask1;  /* break detection (SR1 indications) */	u16			read_status_mask2;  /* parity/framing/overun (SR2 indications) */	unsigned char 		ignore_status_mask1;  /* break detection (SR1 indications) */	unsigned char		ignore_status_mask2;  /* parity/framing/overun (SR2 indications) */	unsigned char 		*tx_buf;	int			tx_put;	int			tx_get;	int			tx_count;	wait_queue_head_t	open_wait;	wait_queue_head_t	close_wait;	wait_queue_head_t	status_event_wait_q;	wait_queue_head_t	event_wait_q;	struct timer_list	tx_timer;	/* HDLC transmit timeout timer */	struct _synclinkmp_info	*next_device;	/* device list link */	struct timer_list	status_timer;	/* input signal status check timer */	spinlock_t lock;		/* spinlock for synchronizing with ISR */	struct work_struct task;	 		/* task structure for scheduling bh */	u32 max_frame_size;			/* as set by device config */	u32 pending_bh;	int bh_running;				/* Protection from multiple */	int isr_overflow;	int bh_requested;	int dcd_chkcount;			/* check counts to prevent */	int cts_chkcount;			/* too many IRQs if a signal */	int dsr_chkcount;			/* is floating */	int ri_chkcount;	char *buffer_list;			/* virtual address of Rx & Tx buffer lists */	unsigned long buffer_list_phys;	unsigned int rx_buf_count;		/* count of total allocated Rx buffers */	SCADESC *rx_buf_list;   		/* list of receive buffer entries */	SCADESC_EX rx_buf_list_ex[SCAMAXDESC]; /* list of receive buffer entries */	unsigned int current_rx_buf;	unsigned int tx_buf_count;		/* count of total allocated Tx buffers */	SCADESC *tx_buf_list;		/* list of transmit buffer entries */	SCADESC_EX tx_buf_list_ex[SCAMAXDESC]; /* list of transmit buffer entries */	unsigned int last_tx_buf;	unsigned char *tmp_rx_buf;	unsigned int tmp_rx_buf_count;	int rx_enabled;	int rx_overflow;	int tx_enabled;	int tx_active;	u32 idle_mode;	unsigned char ie0_value;	unsigned char ie1_value;	unsigned char ie2_value;	unsigned char ctrlreg_value;	unsigned char old_signals;	char device_name[25];			/* device instance name */	int port_count;	int adapter_num;	int port_num;	struct _synclinkmp_info *port_array[SCA_MAX_PORTS];	unsigned int bus_type;			/* expansion bus type (ISA,EISA,PCI) */	unsigned int irq_level;			/* interrupt level */	unsigned long irq_flags;	int irq_requested;			/* nonzero if IRQ requested */	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 */	u32 last_mem_alloc;	unsigned char* memory_base;		/* shared memory address (PCI only) */	u32 phys_memory_base;    	int shared_mem_requested;	unsigned char* sca_base;		/* HD64570 SCA Memory address */	u32 phys_sca_base;	u32 sca_offset;	int sca_base_requested;	unsigned char* lcr_base;		/* local config registers (PCI only) */	u32 phys_lcr_base;	u32 lcr_offset;	int lcr_mem_requested;	unsigned char* statctrl_base;		/* status/control register memory */	u32 phys_statctrl_base;	u32 statctrl_offset;	int sca_statctrl_requested;	u32 misc_ctrl_value;	char flag_buf[MAX_ASYNC_BUFFER_SIZE];	char char_buf[MAX_ASYNC_BUFFER_SIZE];	BOOLEAN drop_rts_on_tx_done;	struct	_input_signal_events	input_signal_events;	/* SPPP/Cisco HDLC device parts */	int netcount;	int dosyncppp;	spinlock_t netlock;#ifdef CONFIG_HDLC	struct net_device *netdev;#endif} SLMP_INFO;#define MGSL_MAGIC 0x5401/* * define serial signal status change macros */#define	MISCSTATUS_DCD_LATCHED	(SerialSignal_DCD<<8)	/* indicates change in DCD */#define MISCSTATUS_RI_LATCHED	(SerialSignal_RI<<8)	/* indicates change in RI */#define MISCSTATUS_CTS_LATCHED	(SerialSignal_CTS<<8)	/* indicates change in CTS */#define MISCSTATUS_DSR_LATCHED	(SerialSignal_DSR<<8)	/* change in DSR *//* Common Register macros */#define LPR	0x00#define PABR0	0x02#define PABR1	0x03#define WCRL	0x04#define WCRM	0x05#define WCRH	0x06#define DPCR	0x08#define DMER	0x09#define ISR0	0x10#define ISR1	0x11#define ISR2	0x12#define IER0	0x14#define IER1	0x15#define IER2	0x16#define ITCR	0x18#define INTVR 	0x1a#define IMVR	0x1c/* MSCI Register macros */#define TRB	0x20#define TRBL	0x20#define TRBH	0x21#define SR0	0x22#define SR1	0x23#define SR2	0x24#define SR3	0x25#define FST	0x26#define IE0	0x28#define IE1	0x29#define IE2	0x2a#define FIE	0x2b#define CMD	0x2c#define MD0	0x2e#define MD1	0x2f#define MD2	0x30#define CTL	0x31#define SA0	0x32#define SA1	0x33#define IDL	0x34#define TMC	0x35#define RXS	0x36#define TXS	0x37#define TRC0	0x38#define TRC1	0x39#define RRC	0x3a#define CST0	0x3c#define CST1	0x3d/* Timer Register Macros */#define TCNT	0x60#define TCNTL	0x60#define TCNTH	0x61#define TCONR	0x62#define TCONRL	0x62#define TCONRH	0x63#define TMCS	0x64#define TEPR	0x65/* DMA Controller Register macros */#define DARL	0x80#define DARH	0x81#define DARB	0x82#define BAR	0x80#define BARL	0x80#define BARH	0x81#define BARB	0x82#define SAR	0x84#define SARL	0x84#define SARH	0x85#define SARB	0x86#define CPB	0x86#define CDA	0x88#define CDAL	0x88#define CDAH	0x89#define EDA	0x8a#define EDAL	0x8a#define EDAH	0x8b#define BFL	0x8c#define BFLL	0x8c#define BFLH	0x8d#define BCR	0x8e#define BCRL	0x8e#define BCRH	0x8f#define DSR	0x90#define DMR	0x91#define FCT	0x93#define DIR	0x94#define DCMD	0x95/* combine with timer or DMA register address */#define TIMER0	0x00#define TIMER1	0x08#define TIMER2	0x10#define TIMER3	0x18#define RXDMA 	0x00#define TXDMA 	0x20/* SCA Command Codes */#define NOOP		0x00#define TXRESET		0x01#define TXENABLE	0x02#define TXDISABLE	0x03#define TXCRCINIT	0x04#define TXCRCEXCL	0x05#define TXEOM		0x06#define TXABORT		0x07#define MPON		0x08#define TXBUFCLR	0x09#define RXRESET		0x11#define RXENABLE	0x12#define RXDISABLE	0x13#define RXCRCINIT	0x14#define RXREJECT	0x15#define SEARCHMP	0x16#define RXCRCEXCL	0x17#define RXCRCCALC	0x18#define CHRESET		0x21#define HUNT		0x31/* DMA command codes */#define SWABORT		0x01#define FEICLEAR	0x02/* IE0 */#define TXINTE 		BIT7#define RXINTE 		BIT6#define TXRDYE 		BIT1#define RXRDYE 		BIT0/* IE1 & SR1 */#define UDRN   	BIT7#define IDLE   	BIT6#define SYNCD  	BIT4#define FLGD   	BIT4#define CCTS   	BIT3#define CDCD   	BIT2#define BRKD   	BIT1#define ABTD   	BIT1#define GAPD   	BIT1#define BRKE   	BIT0#define IDLD	BIT0/* IE2 & SR2 */#define EOM	BIT7#define PMP	BIT6#define SHRT	BIT6#define PE	BIT5#define ABT	BIT5#define FRME	BIT4#define RBIT	BIT4#define OVRN	BIT3#define CRCE	BIT2/* * Global linked list of SyncLink devices */static SLMP_INFO *synclinkmp_device_list = NULL;static int synclinkmp_adapter_count = -1;static int synclinkmp_device_count = 0;/* * Set this param to non-zero to load eax with the * .text section address and breakpoint on module load. * This is useful for use with gdb and add-symbol-file command. */static int break_on_load=0;/* * Driver major number, defaults to zero to get auto * assigned major number. May be forced as module parameter. */static int ttymajor=0;/* * Array of user specified options for ISA adapters. */static int debug_level = 0;static int maxframe[MAX_DEVICES] = {0,};static int dosyncppp[MAX_DEVICES] = {0,};MODULE_PARM(break_on_load,"i");MODULE_PARM(ttymajor,"i");MODULE_PARM(debug_level,"i");MODULE_PARM(maxframe,"1-" __MODULE_STRING(MAX_DEVICES) "i");MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_DEVICES) "i");static char *driver_name = "SyncLink MultiPort driver";static char *driver_version = "$Revision: 4.29 $";static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent);

⌨️ 快捷键说明

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