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

📄 synclink_gt.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * $Id: synclink_gt.c,v 4.50 2007/07/25 19:29:25 paulkf Exp $ * * Device driver for Microgate SyncLink GT serial adapters. * * written by Paul Fulghum for Microgate Corporation * paulkf@microgate.com * * Microgate and SyncLink are trademarks of Microgate Corporation * * 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. *//* * DEBUG OUTPUT DEFINITIONS * * uncomment lines below to enable specific types of debug output * * DBGINFO   information - most verbose output * DBGERR    serious errors * DBGBH     bottom half service routine debugging * DBGISR    interrupt service routine debugging * DBGDATA   output receive and transmit data * DBGTBUF   output transmit DMA buffers and registers * DBGRBUF   output receive DMA buffers and registers */#define DBGINFO(fmt) if (debug_level >= DEBUG_LEVEL_INFO) printk fmt#define DBGERR(fmt) if (debug_level >= DEBUG_LEVEL_ERROR) printk fmt#define DBGBH(fmt) if (debug_level >= DEBUG_LEVEL_BH) printk fmt#define DBGISR(fmt) if (debug_level >= DEBUG_LEVEL_ISR) printk fmt#define DBGDATA(info, buf, size, label) if (debug_level >= DEBUG_LEVEL_DATA) trace_block((info), (buf), (size), (label))//#define DBGTBUF(info) dump_tbufs(info)//#define DBGRBUF(info) dump_rbufs(info)#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/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 <linux/delay.h>#include <linux/ioctl.h>#include <linux/termios.h>#include <linux/bitops.h>#include <linux/workqueue.h>#include <linux/hdlc.h>#include <asm/system.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/dma.h>#include <asm/types.h>#include <asm/uaccess.h>#include "linux/synclink.h"#if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_GT_MODULE))#define SYNCLINK_GENERIC_HDLC 1#else#define SYNCLINK_GENERIC_HDLC 0#endif/* * module identification */static char *driver_name     = "SyncLink GT";static char *driver_version  = "$Revision: 4.50 $";static char *tty_driver_name = "synclink_gt";static char *tty_dev_prefix  = "ttySLG";MODULE_LICENSE("GPL");#define MGSL_MAGIC 0x5401#define MAX_DEVICES 32static struct pci_device_id pci_table[] = {	{PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},	{PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT2_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},	{PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT4_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},	{PCI_VENDOR_ID_MICROGATE, SYNCLINK_AC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},	{0,}, /* terminate list */};MODULE_DEVICE_TABLE(pci, pci_table);static int  init_one(struct pci_dev *dev,const struct pci_device_id *ent);static void remove_one(struct pci_dev *dev);static struct pci_driver pci_driver = {	.name		= "synclink_gt",	.id_table	= pci_table,	.probe		= init_one,	.remove		= __devexit_p(remove_one),};static int pci_registered;/* * module configuration and status */static struct slgt_info *slgt_device_list;static int slgt_device_count;static int ttymajor;static int debug_level;static int maxframe[MAX_DEVICES];static int dosyncppp[MAX_DEVICES];module_param(ttymajor, int, 0);module_param(debug_level, int, 0);module_param_array(maxframe, int, NULL, 0);module_param_array(dosyncppp, int, NULL, 0);MODULE_PARM_DESC(ttymajor, "TTY major device number override: 0=auto assigned");MODULE_PARM_DESC(debug_level, "Debug syslog output: 0=disabled, 1 to 5=increasing detail");MODULE_PARM_DESC(maxframe, "Maximum frame size used by device (4096 to 65535)");MODULE_PARM_DESC(dosyncppp, "Enable synchronous net device, 0=disable 1=enable");/* * tty support and callbacks */static struct tty_driver *serial_driver;static int  open(struct tty_struct *tty, struct file * filp);static void close(struct tty_struct *tty, struct file * filp);static void hangup(struct tty_struct *tty);static void set_termios(struct tty_struct *tty, struct ktermios *old_termios);static int  write(struct tty_struct *tty, const unsigned char *buf, int count);static void put_char(struct tty_struct *tty, unsigned char ch);static void send_xchar(struct tty_struct *tty, char ch);static void wait_until_sent(struct tty_struct *tty, int timeout);static int  write_room(struct tty_struct *tty);static void flush_chars(struct tty_struct *tty);static void flush_buffer(struct tty_struct *tty);static void tx_hold(struct tty_struct *tty);static void tx_release(struct tty_struct *tty);static int  ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);static int  read_proc(char *page, char **start, off_t off, int count,int *eof, void *data);static int  chars_in_buffer(struct tty_struct *tty);static void throttle(struct tty_struct * tty);static void unthrottle(struct tty_struct * tty);static void set_break(struct tty_struct *tty, int break_state);/* * generic HDLC support and callbacks */#if SYNCLINK_GENERIC_HDLC#define dev_to_port(D) (dev_to_hdlc(D)->priv)static void hdlcdev_tx_done(struct slgt_info *info);static void hdlcdev_rx(struct slgt_info *info, char *buf, int size);static int  hdlcdev_init(struct slgt_info *info);static void hdlcdev_exit(struct slgt_info *info);#endif/* * device specific structures, macros and functions */#define SLGT_MAX_PORTS 4#define SLGT_REG_SIZE  256/* * conditional wait facility */struct cond_wait {	struct cond_wait *next;	wait_queue_head_t q;	wait_queue_t wait;	unsigned int data;};static void init_cond_wait(struct cond_wait *w, unsigned int data);static void add_cond_wait(struct cond_wait **head, struct cond_wait *w);static void remove_cond_wait(struct cond_wait **head, struct cond_wait *w);static void flush_cond_wait(struct cond_wait **head);/* * DMA buffer descriptor and access macros */struct slgt_desc{	__le16 count;	__le16 status;	__le32 pbuf;  /* physical address of data buffer */	__le32 next;  /* physical address of next descriptor */	/* driver book keeping */	char *buf;          /* virtual  address of data buffer */    	unsigned int pdesc; /* physical address of this descriptor */	dma_addr_t buf_dma_addr;};#define set_desc_buffer(a,b) (a).pbuf = cpu_to_le32((unsigned int)(b))#define set_desc_next(a,b) (a).next   = cpu_to_le32((unsigned int)(b))#define set_desc_count(a,b)(a).count  = cpu_to_le16((unsigned short)(b))#define set_desc_eof(a,b)  (a).status = cpu_to_le16((b) ? (le16_to_cpu((a).status) | BIT0) : (le16_to_cpu((a).status) & ~BIT0))#define desc_count(a)      (le16_to_cpu((a).count))#define desc_status(a)     (le16_to_cpu((a).status))#define desc_complete(a)   (le16_to_cpu((a).status) & BIT15)#define desc_eof(a)        (le16_to_cpu((a).status) & BIT2)#define desc_crc_error(a)  (le16_to_cpu((a).status) & BIT1)#define desc_abort(a)      (le16_to_cpu((a).status) & BIT0)#define desc_residue(a)    ((le16_to_cpu((a).status) & 0x38) >> 3)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 */struct slgt_info {	void *if_ptr;		/* General purpose pointer (used by SPPP) */	struct slgt_info *next_device;	/* device list link */	int magic;	int flags;	char device_name[25];	struct pci_dev *pdev;	int port_count;  /* count of ports on adapter */	int adapter_num; /* adapter instance number */	int port_num;    /* port instance number */	/* array of pointers to port contexts on this adapter */	struct slgt_info *port_array[SLGT_MAX_PORTS];	int			count;		/* count of opens */	int			line;		/* tty line instance number */	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 */	unsigned int		read_status_mask;	unsigned int 		ignore_status_mask;	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;	struct timer_list	rx_timer;	unsigned int            gpio_present;	struct cond_wait        *gpio_wait_q;	spinlock_t lock;	/* spinlock for synchronizing with ISR */	struct work_struct task;	u32 pending_bh;	int bh_requested;	int bh_running;	int isr_overflow;	int irq_requested;	/* nonzero if IRQ requested */	int irq_occurred;	/* for diagnostics use */	/* device configuration */	unsigned int bus_type;	unsigned int irq_level;	unsigned long irq_flags;	unsigned char __iomem * reg_addr;  /* memory mapped registers address */	u32 phys_reg_addr;	int reg_addr_requested;	MGSL_PARAMS params;       /* communications parameters */	u32 idle_mode;	u32 max_frame_size;       /* as set by device config */	unsigned int raw_rx_size;	unsigned int if_mode;	/* device status */	int rx_enabled;	int rx_restart;	int tx_enabled;	int tx_active;	unsigned char signals;    /* serial signal states */	int init_error;  /* initialization error */	unsigned char *tx_buf;	int tx_count;	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;	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 *bufs;		/* virtual address of DMA buffer lists */	dma_addr_t bufs_dma_addr; /* physical address of buffer descriptors */	unsigned int rbuf_count;	struct slgt_desc *rbufs;	unsigned int rbuf_current;	unsigned int rbuf_index;	unsigned int tbuf_count;	struct slgt_desc *tbufs;	unsigned int tbuf_current;	unsigned int tbuf_start;	unsigned char *tmp_rbuf;	unsigned int tmp_rbuf_count;	/* SPPP/Cisco HDLC device parts */	int netcount;	int dosyncppp;	spinlock_t netlock;#if SYNCLINK_GENERIC_HDLC	struct net_device *netdev;#endif};static MGSL_PARAMS default_params = {	.mode            = MGSL_MODE_HDLC,	.loopback        = 0,	.flags           = HDLC_FLAG_UNDERRUN_ABORT15,	.encoding        = HDLC_ENCODING_NRZI_SPACE,	.clock_speed     = 0,	.addr_filter     = 0xff,	.crc_type        = HDLC_CRC_16_CCITT,	.preamble_length = HDLC_PREAMBLE_LENGTH_8BITS,	.preamble        = HDLC_PREAMBLE_PATTERN_NONE,	.data_rate       = 9600,	.data_bits       = 8,	.stop_bits       = 1,	.parity          = ASYNC_PARITY_NONE};#define BH_RECEIVE  1#define BH_TRANSMIT 2#define BH_STATUS   4#define IO_PIN_SHUTDOWN_LIMIT 100#define DMABUFSIZE 256#define DESC_LIST_SIZE 4096#define MASK_PARITY  BIT1#define MASK_FRAMING BIT0#define MASK_BREAK   BIT14#define MASK_OVERRUN BIT4#define GSR   0x00 /* global status */#define JCR   0x04 /* JTAG control */#define IODR  0x08 /* GPIO direction */#define IOER  0x0c /* GPIO interrupt enable */#define IOVR  0x10 /* GPIO value */#define IOSR  0x14 /* GPIO interrupt status */#define TDR   0x80 /* tx data */#define RDR   0x80 /* rx data */#define TCR   0x82 /* tx control */#define TIR   0x84 /* tx idle */#define TPR   0x85 /* tx preamble */#define RCR   0x86 /* rx control */#define VCR   0x88 /* V.24 control */#define CCR   0x89 /* clock control */#define BDR   0x8a /* baud divisor */#define SCR   0x8c /* serial control */#define SSR   0x8e /* serial status */#define RDCSR 0x90 /* rx DMA control/status */#define TDCSR 0x94 /* tx DMA control/status */#define RDDAR 0x98 /* rx DMA descriptor address */#define TDDAR 0x9c /* tx DMA descriptor address */#define RXIDLE      BIT14#define RXBREAK     BIT14#define IRQ_TXDATA  BIT13#define IRQ_TXIDLE  BIT12#define IRQ_TXUNDER BIT11 /* HDLC */#define IRQ_RXDATA  BIT10#define IRQ_RXIDLE  BIT9  /* HDLC */#define IRQ_RXBREAK BIT9  /* async */#define IRQ_RXOVER  BIT8#define IRQ_DSR     BIT7#define IRQ_CTS     BIT6#define IRQ_DCD     BIT5#define IRQ_RI      BIT4#define IRQ_ALL     0x3ff0#define IRQ_MASTER  BIT0#define slgt_irq_on(info, mask) \	wr_reg16((info), SCR, (unsigned short)(rd_reg16((info), SCR) | (mask)))#define slgt_irq_off(info, mask) \	wr_reg16((info), SCR, (unsigned short)(rd_reg16((info), SCR) & ~(mask)))static __u8  rd_reg8(struct slgt_info *info, unsigned int addr);static void  wr_reg8(struct slgt_info *info, unsigned int addr, __u8 value);static __u16 rd_reg16(struct slgt_info *info, unsigned int addr);static void  wr_reg16(struct slgt_info *info, unsigned int addr, __u16 value);static __u32 rd_reg32(struct slgt_info *info, unsigned int addr);static void  wr_reg32(struct slgt_info *info, unsigned int addr, __u32 value);static void  msc_set_vcr(struct slgt_info *info);static int  startup(struct slgt_info *info);static int  block_til_ready(struct tty_struct *tty, struct file * filp,struct slgt_info *info);static void shutdown(struct slgt_info *info);static void program_hw(struct slgt_info *info);static void change_params(struct slgt_info *info);static int  register_test(struct slgt_info *info);static int  irq_test(struct slgt_info *info);static int  loopback_test(struct slgt_info *info);static int  adapter_test(struct slgt_info *info);static void reset_adapter(struct slgt_info *info);static void reset_port(struct slgt_info *info);static void async_mode(struct slgt_info *info);static void sync_mode(struct slgt_info *info);static void rx_stop(struct slgt_info *info);static void rx_start(struct slgt_info *info);static void reset_rbufs(struct slgt_info *info);static void free_rbufs(struct slgt_info *info, unsigned int first, unsigned int last);static void rdma_reset(struct slgt_info *info);static int  rx_get_frame(struct slgt_info *info);static int  rx_get_buf(struct slgt_info *info);static void tx_start(struct slgt_info *info);static void tx_stop(struct slgt_info *info);static void tx_set_idle(struct slgt_info *info);static unsigned int free_tbuf_count(struct slgt_info *info);static void reset_tbufs(struct slgt_info *info);static void tdma_reset(struct slgt_info *info);static void tdma_start(struct slgt_info *info);static void tx_load(struct slgt_info *info, const char *buf, unsigned int count);static void get_signals(struct slgt_info *info);static void set_signals(struct slgt_info *info);

⌨️ 快捷键说明

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