?? synclink.c
字號:
/* * linux/drivers/char/synclink.c * * $Id: synclink.c,v 3.12 2001/07/18 19:14:21 paulkf Exp $ * * 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. * * 2000/02/16 * Added interface for syncppp.c driver (an alternate synchronous PPP * implementation that also supports Cisco HDLC). Each device instance * registers as a tty device AND a network device (if dosyncppp option * is set for the device). The functionality is determined by which * device interface is opened. * * 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_ISA_DEVICES 10#define MAX_PCI_DEVICES 10#define MAX_TOTAL_DEVICES 20#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/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/tqueue.h>#ifdef CONFIG_SYNCLINK_SYNCPPP_MODULE#define CONFIG_SYNCLINK_SYNCPPP 1#endif#ifdef CONFIG_SYNCLINK_SYNCPPP#if LINUX_VERSION_CODE < VERSION(2,4,3) #include "../net/wan/syncppp.h"#else#include <net/syncppp.h>#endif#endif#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#include <asm/uaccess.h>#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_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;};/* transmit holding buffer definitions*/#define MAX_TX_HOLDING_BUFFERS 5struct tx_holding_buffer { int buffer_size; unsigned char * buffer;};/* * Device instance data structure */ struct mgsl_struct { 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 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; 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 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 */ 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_buffer_count; /* count of total allocated Rx buffers */ DMABUFFERENTRY *rx_buffer_list; /* list of receive buffer entries */ unsigned int current_rx_buffer; int num_tx_dma_buffers; /* number of tx dma frames required */ int tx_dma_buffers_used; unsigned int tx_buffer_count; /* count of total allocated Tx buffers */ DMABUFFERENTRY *tx_buffer_list; /* list of transmit buffer entries */ int start_tx_dma_buffer; /* tx dma buffer to start tx dma operation */ int current_tx_buffer; /* next tx dma buffer to be loaded */ unsigned char *intermediate_rxbuffer; int num_tx_holding_buffers; /* number of tx holding buffer allocated */ int get_tx_holding_index; /* next tx holding buffer for adapter to load */ int put_tx_holding_index; /* next tx holding buffer to store user request */ int tx_holding_count; /* number of tx holding buffers waiting */ struct tx_holding_buffer tx_holding_buffers[MAX_TX_HOLDING_BUFFERS]; int rx_enabled; int rx_overflow; int tx_enabled; int tx_active; u32 idle_mode; u16 cmr_value; u16 tcsr_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; int shared_mem_requested; unsigned char* lcr_base; /* local config registers (PCI only) */ u32 phys_lcr_base; u32 lcr_offset; int lcr_mem_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; BOOLEAN loopmode_insert_requested; BOOLEAN loopmode_send_done_requested; struct _input_signal_events input_signal_events; /* SPPP/Cisco HDLC device parts */ int netcount; int dosyncppp; spinlock_t netlock;#ifdef CONFIG_SYNCLINK_SYNCPPP struct ppp_device pppdev; char netname[10]; struct net_device *netdev; struct net_device_stats netstats; struct net_device netdevice;#endif};#define MGSL_MAGIC 0x5401/* * The size of the serial xmit buffer is 1 page, or 4096 bytes */#ifndef SERIAL_XMIT_SIZE#define SERIAL_XMIT_SIZE 4096#endif/* * 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) */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -