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 + -
显示快捷键?