Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-1.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * $Id: synclinkmp.c,v 4.38 2005/07/15 13:29:44 paulkf Exp $
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Device driver for Microgate SyncLink Multiport
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * high speed multiprotocol serial adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * written by Paul Fulghum for Microgate Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * paulkf@microgate.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * Microgate and SyncLink are trademarks of Microgate Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * Derived from serial.c written by Theodore Ts'o and Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23)  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24)  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25)  * OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #define VERSION(ver,rel,seq) (((ver)<<16) | ((rel)<<8) | (seq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #if defined(__i386__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #  define BREAKPOINT() asm("   int $3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #  define BREAKPOINT() { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #define MAX_DEVICES 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #include <linux/major.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #include <linux/ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #include <asm/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #include <linux/termios.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #include <linux/hdlc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #include <linux/synclink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINKMP_MODULE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #define SYNCLINK_GENERIC_HDLC 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #define SYNCLINK_GENERIC_HDLC 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define GET_USER(error,value,addr) error = get_user(value,addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define PUT_USER(error,value,addr) error = put_user(value,addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) static MGSL_PARAMS default_params = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	MGSL_MODE_HDLC,			/* unsigned long mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	0,				/* unsigned char loopback; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	HDLC_FLAG_UNDERRUN_ABORT15,	/* unsigned short flags; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	HDLC_ENCODING_NRZI_SPACE,	/* unsigned char encoding; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	0,				/* unsigned long clock_speed; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	0xff,				/* unsigned char addr_filter; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	HDLC_CRC_16_CCITT,		/* unsigned short crc_type; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	HDLC_PREAMBLE_LENGTH_8BITS,	/* unsigned char preamble_length; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	HDLC_PREAMBLE_PATTERN_NONE,	/* unsigned char preamble; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	9600,				/* unsigned long data_rate; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	8,				/* unsigned char data_bits; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	1,				/* unsigned char stop_bits; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	ASYNC_PARITY_NONE		/* unsigned char parity; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) /* size in bytes of DMA data buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) #define SCABUFSIZE 	1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) #define SCA_MEM_SIZE	0x40000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) #define SCA_BASE_SIZE   512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) #define SCA_REG_SIZE    16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) #define SCA_MAX_PORTS   4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) #define SCAMAXDESC 	128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) #define	BUFFERLISTSIZE	4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) /* SCA-I style DMA buffer descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) typedef struct _SCADESC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	u16	next;		/* lower l6 bits of next descriptor addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	u16	buf_ptr;	/* lower 16 bits of buffer addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	u8	buf_base;	/* upper 8 bits of buffer addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	u8	pad1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	u16	length;		/* length of buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	u8	status;		/* status of buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	u8	pad2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) } SCADESC, *PSCADESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) typedef struct _SCADESC_EX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	/* device driver bookkeeping section */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	char 	*virt_addr;    	/* virtual address of data buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	u16	phys_entry;	/* lower 16-bits of physical address of this descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) } SCADESC_EX, *PSCADESC_EX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) /* The queue of BH actions to be performed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) #define BH_RECEIVE  1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) #define BH_TRANSMIT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) #define BH_STATUS   4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) #define IO_PIN_SHUTDOWN_LIMIT 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) struct	_input_signal_events {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	int	ri_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	int	ri_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	int	dsr_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	int	dsr_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	int	dcd_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	int	dcd_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	int	cts_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	int	cts_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149)  * Device instance data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) typedef struct _synclinkmp_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	void *if_ptr;				/* General purpose pointer (used by SPPP) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	int			magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	struct tty_port		port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	int			line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	unsigned short		close_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	unsigned short		closing_wait;	/* time to wait before closing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	struct mgsl_icount	icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	int			timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	int			x_char;		/* xon/xoff character */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	u16			read_status_mask1;  /* break detection (SR1 indications) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	u16			read_status_mask2;  /* parity/framing/overun (SR2 indications) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	unsigned char 		ignore_status_mask1;  /* break detection (SR1 indications) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	unsigned char		ignore_status_mask2;  /* parity/framing/overun (SR2 indications) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	unsigned char 		*tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	int			tx_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	int			tx_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	int			tx_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	wait_queue_head_t	status_event_wait_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	wait_queue_head_t	event_wait_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	struct timer_list	tx_timer;	/* HDLC transmit timeout timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	struct _synclinkmp_info	*next_device;	/* device list link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	struct timer_list	status_timer;	/* input signal status check timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	spinlock_t lock;		/* spinlock for synchronizing with ISR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	struct work_struct task;	 		/* task structure for scheduling bh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	u32 max_frame_size;			/* as set by device config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	u32 pending_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	bool bh_running;				/* Protection from multiple */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	int isr_overflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	bool bh_requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	int dcd_chkcount;			/* check counts to prevent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	int cts_chkcount;			/* too many IRQs if a signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	int dsr_chkcount;			/* is floating */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	int ri_chkcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	char *buffer_list;			/* virtual address of Rx & Tx buffer lists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	unsigned long buffer_list_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	unsigned int rx_buf_count;		/* count of total allocated Rx buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	SCADESC *rx_buf_list;   		/* list of receive buffer entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	SCADESC_EX rx_buf_list_ex[SCAMAXDESC]; /* list of receive buffer entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	unsigned int current_rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	unsigned int tx_buf_count;		/* count of total allocated Tx buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	SCADESC *tx_buf_list;		/* list of transmit buffer entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	SCADESC_EX tx_buf_list_ex[SCAMAXDESC]; /* list of transmit buffer entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	unsigned int last_tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	unsigned char *tmp_rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	unsigned int tmp_rx_buf_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	bool rx_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	bool rx_overflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	bool tx_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	bool tx_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	u32 idle_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	unsigned char ie0_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	unsigned char ie1_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	unsigned char ie2_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	unsigned char ctrlreg_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	unsigned char old_signals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	char device_name[25];			/* device instance name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	int port_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	int adapter_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	int port_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	struct _synclinkmp_info *port_array[SCA_MAX_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	unsigned int bus_type;			/* expansion bus type (ISA,EISA,PCI) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	unsigned int irq_level;			/* interrupt level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	unsigned long irq_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	bool irq_requested;			/* true if IRQ requested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	MGSL_PARAMS params;			/* communications parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	unsigned char serial_signals;		/* current serial signal states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	bool irq_occurred;			/* for diagnostics use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	unsigned int init_error;		/* Initialization startup error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	u32 last_mem_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	unsigned char* memory_base;		/* shared memory address (PCI only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	u32 phys_memory_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247)     	int shared_mem_requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	unsigned char* sca_base;		/* HD64570 SCA Memory address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	u32 phys_sca_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	u32 sca_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	bool sca_base_requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	unsigned char* lcr_base;		/* local config registers (PCI only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	u32 phys_lcr_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	u32 lcr_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	int lcr_mem_requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	unsigned char* statctrl_base;		/* status/control register memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	u32 phys_statctrl_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	u32 statctrl_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	bool sca_statctrl_requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	u32 misc_ctrl_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	char *flag_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	bool drop_rts_on_tx_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	struct	_input_signal_events	input_signal_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	/* SPPP/Cisco HDLC device parts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	int netcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	spinlock_t netlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	struct net_device *netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) } SLMP_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) #define MGSL_MAGIC 0x5401
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283)  * define serial signal status change macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) #define	MISCSTATUS_DCD_LATCHED	(SerialSignal_DCD<<8)	/* indicates change in DCD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) #define MISCSTATUS_RI_LATCHED	(SerialSignal_RI<<8)	/* indicates change in RI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) #define MISCSTATUS_CTS_LATCHED	(SerialSignal_CTS<<8)	/* indicates change in CTS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) #define MISCSTATUS_DSR_LATCHED	(SerialSignal_DSR<<8)	/* change in DSR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) /* Common Register macros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) #define LPR	0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) #define PABR0	0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) #define PABR1	0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) #define WCRL	0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) #define WCRM	0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) #define WCRH	0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) #define DPCR	0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) #define DMER	0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) #define ISR0	0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) #define ISR1	0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) #define ISR2	0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) #define IER0	0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) #define IER1	0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) #define IER2	0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) #define ITCR	0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) #define INTVR 	0x1a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) #define IMVR	0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) /* MSCI Register macros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) #define TRB	0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) #define TRBL	0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) #define TRBH	0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) #define SR0	0x22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) #define SR1	0x23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) #define SR2	0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) #define SR3	0x25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) #define FST	0x26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) #define IE0	0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) #define IE1	0x29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) #define IE2	0x2a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) #define FIE	0x2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) #define CMD	0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) #define MD0	0x2e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) #define MD1	0x2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) #define MD2	0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) #define CTL	0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) #define SA0	0x32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) #define SA1	0x33
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) #define IDL	0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) #define TMC	0x35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) #define RXS	0x36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) #define TXS	0x37
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) #define TRC0	0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) #define TRC1	0x39
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) #define RRC	0x3a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) #define CST0	0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) #define CST1	0x3d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) /* Timer Register Macros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) #define TCNT	0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) #define TCNTL	0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) #define TCNTH	0x61
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) #define TCONR	0x62
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) #define TCONRL	0x62
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) #define TCONRH	0x63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) #define TMCS	0x64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) #define TEPR	0x65
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) /* DMA Controller Register macros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) #define DARL	0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) #define DARH	0x81
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) #define DARB	0x82
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) #define BAR	0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) #define BARL	0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) #define BARH	0x81
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) #define BARB	0x82
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) #define SAR	0x84
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) #define SARL	0x84
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) #define SARH	0x85
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) #define SARB	0x86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) #define CPB	0x86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) #define CDA	0x88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) #define CDAL	0x88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) #define CDAH	0x89
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) #define EDA	0x8a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) #define EDAL	0x8a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) #define EDAH	0x8b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) #define BFL	0x8c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) #define BFLL	0x8c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) #define BFLH	0x8d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) #define BCR	0x8e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) #define BCRL	0x8e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) #define BCRH	0x8f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) #define DSR	0x90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) #define DMR	0x91
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) #define FCT	0x93
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) #define DIR	0x94
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) #define DCMD	0x95
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) /* combine with timer or DMA register address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) #define TIMER0	0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) #define TIMER1	0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) #define TIMER2	0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) #define TIMER3	0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) #define RXDMA 	0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) #define TXDMA 	0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) /* SCA Command Codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) #define NOOP		0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) #define TXRESET		0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) #define TXENABLE	0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) #define TXDISABLE	0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) #define TXCRCINIT	0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) #define TXCRCEXCL	0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) #define TXEOM		0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) #define TXABORT		0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) #define MPON		0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) #define TXBUFCLR	0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) #define RXRESET		0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) #define RXENABLE	0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) #define RXDISABLE	0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) #define RXCRCINIT	0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) #define RXREJECT	0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) #define SEARCHMP	0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) #define RXCRCEXCL	0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) #define RXCRCCALC	0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) #define CHRESET		0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) #define HUNT		0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) /* DMA command codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) #define SWABORT		0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) #define FEICLEAR	0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) /* IE0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) #define TXINTE 		BIT7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) #define RXINTE 		BIT6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) #define TXRDYE 		BIT1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) #define RXRDYE 		BIT0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) /* IE1 & SR1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) #define UDRN   	BIT7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) #define IDLE   	BIT6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) #define SYNCD  	BIT4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) #define FLGD   	BIT4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) #define CCTS   	BIT3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) #define CDCD   	BIT2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) #define BRKD   	BIT1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) #define ABTD   	BIT1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) #define GAPD   	BIT1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) #define BRKE   	BIT0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) #define IDLD	BIT0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) /* IE2 & SR2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) #define EOM	BIT7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) #define PMP	BIT6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) #define SHRT	BIT6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) #define PE	BIT5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) #define ABT	BIT5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) #define FRME	BIT4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) #define RBIT	BIT4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) #define OVRN	BIT3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) #define CRCE	BIT2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446)  * Global linked list of SyncLink devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) static SLMP_INFO *synclinkmp_device_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) static int synclinkmp_adapter_count = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) static int synclinkmp_device_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453)  * Set this param to non-zero to load eax with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454)  * .text section address and breakpoint on module load.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455)  * This is useful for use with gdb and add-symbol-file command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) static bool break_on_load = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460)  * Driver major number, defaults to zero to get auto
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461)  * assigned major number. May be forced as module parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) static int ttymajor = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466)  * Array of user specified options for ISA adapters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) static int debug_level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) static int maxframe[MAX_DEVICES] = {0,};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) module_param(break_on_load, bool, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) module_param(ttymajor, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) module_param(debug_level, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) module_param_array(maxframe, int, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) static char *driver_name = "SyncLink MultiPort driver";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) static char *driver_version = "$Revision: 4.38 $";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) static int synclinkmp_init_one(struct pci_dev *dev,const struct pci_device_id *ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) static void synclinkmp_remove_one(struct pci_dev *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) static const struct pci_device_id synclinkmp_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	{ PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_SCA, PCI_ANY_ID, PCI_ANY_ID, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	{ 0, }, /* terminate list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) MODULE_DEVICE_TABLE(pci, synclinkmp_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) static struct pci_driver synclinkmp_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	.name		= "synclinkmp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	.id_table	= synclinkmp_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	.probe		= synclinkmp_init_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	.remove		= synclinkmp_remove_one,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) static struct tty_driver *serial_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) /* number of characters left in xmit buffer before we ask for more */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) #define WAKEUP_CHARS 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) /* tty callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) static int  open(struct tty_struct *tty, struct file * filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) static void close(struct tty_struct *tty, struct file * filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) static void hangup(struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) static void set_termios(struct tty_struct *tty, struct ktermios *old_termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) static int  write(struct tty_struct *tty, const unsigned char *buf, int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) static int put_char(struct tty_struct *tty, unsigned char ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) static void send_xchar(struct tty_struct *tty, char ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) static void wait_until_sent(struct tty_struct *tty, int timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) static int  write_room(struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) static void flush_chars(struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) static void flush_buffer(struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) static void tx_hold(struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) static void tx_release(struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) static int  ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) static int  chars_in_buffer(struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) static void throttle(struct tty_struct * tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) static void unthrottle(struct tty_struct * tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) static int set_break(struct tty_struct *tty, int break_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) #define dev_to_port(D) (dev_to_hdlc(D)->priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) static void hdlcdev_tx_done(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) static int  hdlcdev_init(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) static void hdlcdev_exit(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) /* ioctl handlers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) static int  get_stats(SLMP_INFO *info, struct mgsl_icount __user *user_icount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) static int  get_params(SLMP_INFO *info, MGSL_PARAMS __user *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) static int  set_params(SLMP_INFO *info, MGSL_PARAMS __user *params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) static int  get_txidle(SLMP_INFO *info, int __user *idle_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) static int  set_txidle(SLMP_INFO *info, int idle_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) static int  tx_enable(SLMP_INFO *info, int enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) static int  tx_abort(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) static int  rx_enable(SLMP_INFO *info, int enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) static int  modem_input_wait(SLMP_INFO *info,int arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) static int  wait_mgsl_event(SLMP_INFO *info, int __user *mask_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) static int  tiocmget(struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) static int  tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 			unsigned int set, unsigned int clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) static int  set_break(struct tty_struct *tty, int break_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) static int  add_device(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) static int  device_init(int adapter_num, struct pci_dev *pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) static int  claim_resources(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) static void release_resources(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) static int  startup(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) static int  block_til_ready(struct tty_struct *tty, struct file * filp,SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) static int carrier_raised(struct tty_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) static void shutdown(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) static void program_hw(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) static void change_params(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) static bool init_adapter(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) static bool register_test(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) static bool irq_test(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) static bool loopback_test(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) static int  adapter_test(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) static bool memory_test(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) static void reset_adapter(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) static void reset_port(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) static void async_mode(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) static void hdlc_mode(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) static void rx_stop(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) static void rx_start(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) static void rx_reset_buffers(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) static void rx_free_frame_buffers(SLMP_INFO *info, unsigned int first, unsigned int last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) static bool rx_get_frame(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) static void tx_start(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) static void tx_stop(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) static void tx_load_fifo(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) static void tx_set_idle(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) static void tx_load_dma_buffer(SLMP_INFO *info, const char *buf, unsigned int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) static void get_signals(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) static void set_signals(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) static void enable_loopback(SLMP_INFO *info, int enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) static void set_rate(SLMP_INFO *info, u32 data_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) static int  bh_action(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) static void bh_handler(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) static void bh_receive(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) static void bh_transmit(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) static void bh_status(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) static void isr_timer(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) static void isr_rxint(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) static void isr_rxrdy(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) static void isr_txint(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) static void isr_txrdy(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) static void isr_rxdmaok(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) static void isr_rxdmaerror(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) static void isr_txdmaok(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) static void isr_txdmaerror(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) static void isr_io_pin(SLMP_INFO *info, u16 status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) static int  alloc_dma_bufs(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) static void free_dma_bufs(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) static int  alloc_buf_list(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) static int  alloc_frame_bufs(SLMP_INFO *info, SCADESC *list, SCADESC_EX *list_ex,int count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) static int  alloc_tmp_rx_buf(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) static void free_tmp_rx_buf(SLMP_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) static void load_pci_memory(SLMP_INFO *info, char* dest, const char* src, unsigned short count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) static void trace_block(SLMP_INFO *info, const char* data, int count, int xmit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) static void tx_timeout(struct timer_list *t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) static void status_timeout(struct timer_list *t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) static unsigned char read_reg(SLMP_INFO *info, unsigned char addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) static void write_reg(SLMP_INFO *info, unsigned char addr, unsigned char val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) static u16 read_reg16(SLMP_INFO *info, unsigned char addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) static void write_reg16(SLMP_INFO *info, unsigned char addr, u16 val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) static unsigned char read_status_reg(SLMP_INFO * info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) static void write_control_reg(SLMP_INFO * info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) static unsigned char rx_active_fifo_level = 16;	// rx request FIFO activation level in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) static unsigned char tx_active_fifo_level = 16;	// tx request FIFO activation level in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) static unsigned char tx_negate_fifo_level = 32;	// tx request FIFO negation level in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) static u32 misc_ctrl_value = 0x007e4040;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) static u32 lcr1_brdr_value = 0x00800028;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) static u32 read_ahead_count = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) /* DPCR, DMA Priority Control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640)  * 07..05  Not used, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641)  * 04      BRC, bus release condition: 0=all transfers complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642)  *              1=release after 1 xfer on all channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643)  * 03      CCC, channel change condition: 0=every cycle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644)  *              1=after each channel completes all xfers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645)  * 02..00  PR<2..0>, priority 100=round robin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647)  * 00000100 = 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) static unsigned char dma_priority = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) // Number of bytes that can be written to shared RAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) // in a single write operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) static u32 sca_pci_load_interval = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656)  * 1st function defined in .text section. Calling this function in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657)  * init_module() followed by a breakpoint allows a remote debugger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658)  * (gdb) to get the .text address for the add-symbol-file command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659)  * This allows remote debugging of dynamically loadable modules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) static void* synclinkmp_get_text_ptr(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) static void* synclinkmp_get_text_ptr(void) {return synclinkmp_get_text_ptr;}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) static inline int sanity_check(SLMP_INFO *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 			       char *name, const char *routine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) #ifdef SANITY_CHECK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	static const char *badmagic =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		"Warning: bad magic number for synclinkmp_struct (%s) in %s\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	static const char *badinfo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		"Warning: null synclinkmp_struct for (%s) in %s\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	if (!info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		printk(badinfo, name, routine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	if (info->magic != MGSL_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		printk(badmagic, name, routine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689)  * line discipline callback wrappers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691)  * The wrappers maintain line discipline references
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692)  * while calling into the line discipline.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694)  * ldisc_receive_buf  - pass receive data to line discipline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) static void ldisc_receive_buf(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 			      const __u8 *data, char *flags, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	struct tty_ldisc *ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	if (!tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	ld = tty_ldisc_ref(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	if (ld) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		if (ld->ops->receive_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 			ld->ops->receive_buf(tty, data, flags, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		tty_ldisc_deref(ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) /* tty callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) static int install(struct tty_driver *driver, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	SLMP_INFO *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	int line = tty->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	if (line >= synclinkmp_device_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		printk("%s(%d): open with invalid line #%d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 			__FILE__,__LINE__,line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	info = synclinkmp_device_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	while (info && info->line != line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		info = info->next_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	if (sanity_check(info, tty->name, "open"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	if (info->init_error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		printk("%s(%d):%s device is not allocated, init error=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 			__FILE__, __LINE__, info->device_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 			info->init_error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	tty->driver_data = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	return tty_port_install(&info->port, driver, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) /* Called when a port is opened.  Init and enable port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) static int open(struct tty_struct *tty, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	info->port.tty = tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		printk("%s(%d):%s open(), old ref count = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 			 __FILE__,__LINE__,tty->driver->name, info->port.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	info->port.low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	spin_lock_irqsave(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	if (info->netcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		retval = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		spin_unlock_irqrestore(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	info->port.count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	spin_unlock_irqrestore(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	if (info->port.count == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		/* 1st open on this device, init hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		retval = startup(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 			goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	retval = block_til_ready(tty, filp, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 			printk("%s(%d):%s block_til_ready() returned %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 				 __FILE__,__LINE__, info->device_name, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		printk("%s(%d):%s open() success\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 			 __FILE__,__LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		if (tty->count == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 			info->port.tty = NULL; /* tty layer will release tty struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		if(info->port.count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 			info->port.count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) /* Called when port is closed. Wait for remaining data to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798)  * sent. Disable port and free resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) static void close(struct tty_struct *tty, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	SLMP_INFO * info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	if (sanity_check(info, tty->name, "close"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		printk("%s(%d):%s close() entry, count=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 			 __FILE__,__LINE__, info->device_name, info->port.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	if (tty_port_close_start(&info->port, tty, filp) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	mutex_lock(&info->port.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	if (tty_port_initialized(&info->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816)  		wait_until_sent(tty, info->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	flush_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	tty_ldisc_flush(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	shutdown(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	mutex_unlock(&info->port.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	tty_port_close_end(&info->port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	info->port.tty = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 		printk("%s(%d):%s close() exit, count=%d\n", __FILE__,__LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 			tty->driver->name, info->port.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) /* Called by tty_hangup() when a hangup is signaled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832)  * This is the same as closing all open descriptors for the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) static void hangup(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		printk("%s(%d):%s hangup()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 			 __FILE__,__LINE__, info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	if (sanity_check(info, tty->name, "hangup"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	mutex_lock(&info->port.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	flush_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	shutdown(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	spin_lock_irqsave(&info->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	info->port.count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	info->port.tty = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	spin_unlock_irqrestore(&info->port.lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	tty_port_set_active(&info->port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	mutex_unlock(&info->port.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	wake_up_interruptible(&info->port.open_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) /* Set new termios settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 		printk("%s(%d):%s set_termios()\n", __FILE__,__LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 			tty->driver->name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	change_params(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	/* Handle transition to B0 status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	if ((old_termios->c_cflag & CBAUD) && !C_BAUD(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	 	set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	/* Handle transition away from B0 status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		info->serial_signals |= SerialSignal_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		if (!C_CRTSCTS(tty) || !tty_throttled(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 			info->serial_signals |= SerialSignal_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	 	set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	/* Handle turning off CRTSCTS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	if (old_termios->c_cflag & CRTSCTS && !C_CRTSCTS(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		tty->hw_stopped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		tx_release(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) /* Send a block of data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900)  * Arguments:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902)  * 	tty		pointer to tty information structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903)  * 	buf		pointer to buffer containing send data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904)  * 	count		size of send data in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906)  * Return Value:	number of characters written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) static int write(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		 const unsigned char *buf, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	int	c, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 		printk("%s(%d):%s write() count=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		       __FILE__,__LINE__,info->device_name,count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	if (sanity_check(info, tty->name, "write"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	if (!info->tx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	if (info->params.mode == MGSL_MODE_HDLC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		if (count > info->max_frame_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 			ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 			goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		if (info->tx_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 			goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		if (info->tx_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 			/* send accumulated data from send_char() calls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 			/* as frame and wait before accepting more data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 			tx_load_dma_buffer(info, info->tx_buf, info->tx_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 			goto start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		ret = info->tx_count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		tx_load_dma_buffer(info, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		goto start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		c = min_t(int, count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 			min(info->max_frame_size - info->tx_count - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 			    info->max_frame_size - info->tx_put));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		if (c <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 			
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		memcpy(info->tx_buf + info->tx_put, buf, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		info->tx_put += c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		if (info->tx_put >= info->max_frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 			info->tx_put -= info->max_frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 		info->tx_count += c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 		spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		buf += c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		count -= c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		ret += c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	if (info->params.mode == MGSL_MODE_HDLC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		if (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 			ret = info->tx_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 			goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		tx_load_dma_buffer(info, info->tx_buf, info->tx_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) start:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972)  	if (info->tx_count && !tty->stopped && !tty->hw_stopped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		if (!info->tx_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		 	tx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977)  	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		printk( "%s(%d):%s write() returning=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 			__FILE__,__LINE__,info->device_name,ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) /* Add a character to the transmit buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) static int put_char(struct tty_struct *tty, unsigned char ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	if ( debug_level >= DEBUG_LEVEL_INFO ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		printk( "%s(%d):%s put_char(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 			__FILE__,__LINE__,info->device_name,ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	if (sanity_check(info, tty->name, "put_char"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	if (!info->tx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	if ( (info->params.mode != MGSL_MODE_HDLC) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	     !info->tx_active ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		if (info->tx_count < info->max_frame_size - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 			info->tx_buf[info->tx_put++] = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 			if (info->tx_put >= info->max_frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 				info->tx_put -= info->max_frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 			info->tx_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 			ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) /* Send a high-priority XON/XOFF character
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) static void send_xchar(struct tty_struct *tty, char ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		printk("%s(%d):%s send_xchar(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 			 __FILE__,__LINE__, info->device_name, ch );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	if (sanity_check(info, tty->name, "send_xchar"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	info->x_char = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	if (ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		/* Make sure transmit interrupts are on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		if (!info->tx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		 	tx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) /* Wait until the transmitter is empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) static void wait_until_sent(struct tty_struct *tty, int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	SLMP_INFO * info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	unsigned long orig_jiffies, char_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	if (!info )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		printk("%s(%d):%s wait_until_sent() entry\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 			 __FILE__,__LINE__, info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	if (sanity_check(info, tty->name, "wait_until_sent"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	if (!tty_port_initialized(&info->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	orig_jiffies = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	/* Set check interval to 1/5 of estimated time to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	 * send a character, and make it at least 1. The check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	 * interval should also be less than the timeout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	 * Note: use tight timings here to satisfy the NIST-PCTS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	if ( info->params.data_rate ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	       	char_time = info->timeout/(32 * 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		if (!char_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 			char_time++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		char_time = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	if (timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		char_time = min_t(unsigned long, char_time, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	if ( info->params.mode == MGSL_MODE_HDLC ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		while (info->tx_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 			msleep_interruptible(jiffies_to_msecs(char_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 			if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 			if (timeout && time_after(jiffies, orig_jiffies + timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		 * TODO: determine if there is something similar to USC16C32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		 * 	 TXSTATUS_ALL_SENT status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		while ( info->tx_active && info->tx_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 			msleep_interruptible(jiffies_to_msecs(char_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 			if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 			if (timeout && time_after(jiffies, orig_jiffies + timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 		printk("%s(%d):%s wait_until_sent() exit\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 			 __FILE__,__LINE__, info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) /* Return the count of free bytes in transmit buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) static int write_room(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	if (sanity_check(info, tty->name, "write_room"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	if (info->params.mode == MGSL_MODE_HDLC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		ret = info->max_frame_size - info->tx_count - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 			ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 		printk("%s(%d):%s write_room()=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 		       __FILE__, __LINE__, info->device_name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) /* enable transmitter and send remaining buffered characters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) static void flush_chars(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	if ( debug_level >= DEBUG_LEVEL_INFO )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 		printk( "%s(%d):%s flush_chars() entry tx_count=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 			__FILE__,__LINE__,info->device_name,info->tx_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	if (sanity_check(info, tty->name, "flush_chars"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	if (info->tx_count <= 0 || tty->stopped || tty->hw_stopped ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	    !info->tx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	if ( debug_level >= DEBUG_LEVEL_INFO )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 		printk( "%s(%d):%s flush_chars() entry, starting transmitter\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 			__FILE__,__LINE__,info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	if (!info->tx_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		if ( (info->params.mode == MGSL_MODE_HDLC) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 			info->tx_count ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 			/* operating in synchronous (frame oriented) mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 			/* copy data from circular tx_buf to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 			/* transmit DMA buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 			tx_load_dma_buffer(info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 				 info->tx_buf,info->tx_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	 	tx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) /* Discard all data in the send buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) static void flush_buffer(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		printk("%s(%d):%s flush_buffer() entry\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 			 __FILE__,__LINE__, info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	if (sanity_check(info, tty->name, "flush_buffer"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	info->tx_count = info->tx_put = info->tx_get = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	del_timer(&info->tx_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	tty_wakeup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) /* throttle (stop) transmitter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) static void tx_hold(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	if (sanity_check(info, tty->name, "tx_hold"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	if ( debug_level >= DEBUG_LEVEL_INFO )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		printk("%s(%d):%s tx_hold()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 			__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	if (info->tx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	 	tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) /* release (start) transmitter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) static void tx_release(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	if (sanity_check(info, tty->name, "tx_release"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	if ( debug_level >= DEBUG_LEVEL_INFO )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 		printk("%s(%d):%s tx_release()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 			__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	if (!info->tx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	 	tx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) /* Service an IOCTL request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)  * Arguments:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)  * 	tty	pointer to tty instance data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)  * 	cmd	IOCTL command code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)  * 	arg	command argument/context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)  * Return Value:	0 if success, otherwise error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) static int ioctl(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 		 unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 		printk("%s(%d):%s ioctl() cmd=%08X\n", __FILE__,__LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 			info->device_name, cmd );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	if (sanity_check(info, tty->name, "ioctl"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	if (cmd != TIOCMIWAIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 		if (tty_io_error(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 		    return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	case MGSL_IOCGPARAMS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 		return get_params(info, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	case MGSL_IOCSPARAMS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 		return set_params(info, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	case MGSL_IOCGTXIDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 		return get_txidle(info, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	case MGSL_IOCSTXIDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 		return set_txidle(info, (int)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	case MGSL_IOCTXENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 		return tx_enable(info, (int)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	case MGSL_IOCRXENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 		return rx_enable(info, (int)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	case MGSL_IOCTXABORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 		return tx_abort(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	case MGSL_IOCGSTATS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 		return get_stats(info, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	case MGSL_IOCWAITEVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 		return wait_mgsl_event(info, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	case MGSL_IOCLOOPTXDONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 		return 0; // TODO: Not supported, need to document
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 		/* Wait for modem input (DCD,RI,DSR,CTS) change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 		 * as specified by mask in arg (TIOCM_RNG/DSR/CD/CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	case TIOCMIWAIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 		return modem_input_wait(info,(int)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 		
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 		 * Return: write counters to the user passed counter struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 		 * NB: both 1->0 and 0->1 transitions are counted except for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 		 *     RI where only 0->1 is counted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 		return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) static int get_icount(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 				struct serial_icounter_struct *icount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	struct mgsl_icount cnow;	/* kernel counter temps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	cnow = info->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	icount->cts = cnow.cts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	icount->dsr = cnow.dsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	icount->rng = cnow.rng;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	icount->dcd = cnow.dcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	icount->rx = cnow.rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	icount->tx = cnow.tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	icount->frame = cnow.frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	icount->overrun = cnow.overrun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	icount->parity = cnow.parity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	icount->brk = cnow.brk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	icount->buf_overrun = cnow.buf_overrun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)  * /proc fs routines....
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) static inline void line_info(struct seq_file *m, SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	char	stat_buf[30];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	seq_printf(m, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 		       "\tIRQ=%d MaxFrameSize=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		info->device_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 		info->phys_sca_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 		info->phys_memory_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 		info->phys_statctrl_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 		info->phys_lcr_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 		info->irq_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 		info->max_frame_size );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	/* output current serial signal states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)  	get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	stat_buf[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	stat_buf[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	if (info->serial_signals & SerialSignal_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 		strcat(stat_buf, "|RTS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	if (info->serial_signals & SerialSignal_CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		strcat(stat_buf, "|CTS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	if (info->serial_signals & SerialSignal_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 		strcat(stat_buf, "|DTR");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	if (info->serial_signals & SerialSignal_DSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 		strcat(stat_buf, "|DSR");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	if (info->serial_signals & SerialSignal_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 		strcat(stat_buf, "|CD");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	if (info->serial_signals & SerialSignal_RI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		strcat(stat_buf, "|RI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	if (info->params.mode == MGSL_MODE_HDLC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 		seq_printf(m, "\tHDLC txok:%d rxok:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 			      info->icount.txok, info->icount.rxok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 		if (info->icount.txunder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 			seq_printf(m, " txunder:%d", info->icount.txunder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 		if (info->icount.txabort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 			seq_printf(m, " txabort:%d", info->icount.txabort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		if (info->icount.rxshort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 			seq_printf(m, " rxshort:%d", info->icount.rxshort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 		if (info->icount.rxlong)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 			seq_printf(m, " rxlong:%d", info->icount.rxlong);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 		if (info->icount.rxover)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 			seq_printf(m, " rxover:%d", info->icount.rxover);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 		if (info->icount.rxcrc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 			seq_printf(m, " rxlong:%d", info->icount.rxcrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 		seq_printf(m, "\tASYNC tx:%d rx:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 			      info->icount.tx, info->icount.rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		if (info->icount.frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 			seq_printf(m, " fe:%d", info->icount.frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 		if (info->icount.parity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 			seq_printf(m, " pe:%d", info->icount.parity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 		if (info->icount.brk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 			seq_printf(m, " brk:%d", info->icount.brk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 		if (info->icount.overrun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 			seq_printf(m, " oe:%d", info->icount.overrun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	/* Append serial signal status to end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	seq_printf(m, " %s\n", stat_buf+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	 info->tx_active,info->bh_requested,info->bh_running,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	 info->pending_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) /* Called to print information about devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) static int synclinkmp_proc_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	SLMP_INFO *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	seq_printf(m, "synclinkmp driver:%s\n", driver_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	info = synclinkmp_device_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	while( info ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 		line_info(m, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 		info = info->next_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) /* Return the count of bytes in transmit buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) static int chars_in_buffer(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	if (sanity_check(info, tty->name, "chars_in_buffer"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 		printk("%s(%d):%s chars_in_buffer()=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 		       __FILE__, __LINE__, info->device_name, info->tx_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	return info->tx_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) /* Signal remote device to throttle send data (our receive data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) static void throttle(struct tty_struct * tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 		printk("%s(%d):%s throttle() entry\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 			 __FILE__,__LINE__, info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 	if (sanity_check(info, tty->name, "throttle"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	if (I_IXOFF(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 		send_xchar(tty, STOP_CHAR(tty));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	if (C_CRTSCTS(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 		spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 		info->serial_signals &= ~SerialSignal_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 		set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 		spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) /* Signal remote device to stop throttling send data (our receive data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) static void unthrottle(struct tty_struct * tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		printk("%s(%d):%s unthrottle() entry\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 			 __FILE__,__LINE__, info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	if (sanity_check(info, tty->name, "unthrottle"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 	if (I_IXOFF(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 		if (info->x_char)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 			info->x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 			send_xchar(tty, START_CHAR(tty));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	if (C_CRTSCTS(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 		spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 		info->serial_signals |= SerialSignal_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 		set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 		spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) /* set or clear transmit break condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)  * break_state	-1=set break condition, 0=clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) static int set_break(struct tty_struct *tty, int break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	unsigned char RegValue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	SLMP_INFO * info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 		printk("%s(%d):%s set_break(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 			 __FILE__,__LINE__, info->device_name, break_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	if (sanity_check(info, tty->name, "set_break"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	RegValue = read_reg(info, CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)  	if (break_state == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 		RegValue |= BIT3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 		RegValue &= ~BIT3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	write_reg(info, CTL, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)  * hdlcdev_attach - called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)  * @dev:      pointer to network device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)  * @encoding: serial encoding setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)  * @parity:   FCS setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)  * Set encoding and frame check sequence (FCS) options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)  * Return: 0 if success, otherwise error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 			  unsigned short parity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	SLMP_INFO *info = dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	unsigned char  new_encoding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	unsigned short new_crctype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	/* return error if TTY interface open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	if (info->port.count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	switch (encoding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	case ENCODING_NRZ:        new_encoding = HDLC_ENCODING_NRZ; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	case ENCODING_NRZI:       new_encoding = HDLC_ENCODING_NRZI_SPACE; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	case ENCODING_FM_MARK:    new_encoding = HDLC_ENCODING_BIPHASE_MARK; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 	case ENCODING_FM_SPACE:   new_encoding = HDLC_ENCODING_BIPHASE_SPACE; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 	case ENCODING_MANCHESTER: new_encoding = HDLC_ENCODING_BIPHASE_LEVEL; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	default: return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	switch (parity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	case PARITY_NONE:            new_crctype = HDLC_CRC_NONE; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	case PARITY_CRC16_PR1_CCITT: new_crctype = HDLC_CRC_16_CCITT; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	case PARITY_CRC32_PR1_CCITT: new_crctype = HDLC_CRC_32_CCITT; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	default: return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	info->params.encoding = new_encoding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	info->params.crc_type = new_crctype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	/* if network interface up, reprogram hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	if (info->netcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 		program_hw(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)  * hdlcdev_xmit - called by generic HDLC layer to send frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)  * @skb: socket buffer containing HDLC frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)  * @dev: pointer to network device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 				      struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	SLMP_INFO *info = dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 		printk(KERN_INFO "%s:hdlc_xmit(%s)\n",__FILE__,dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	/* stop sending until this frame completes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	/* copy data to device buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	info->tx_count = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	tx_load_dma_buffer(info, skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	/* update network statistics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	dev->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	dev->stats.tx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	/* done with socket buffer, so free it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	/* save start time for transmit timeout detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	netif_trans_update(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 	/* start hardware transmitter if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	if (!info->tx_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	 	tx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)  * hdlcdev_open - called by network layer when interface enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)  * @dev: pointer to network device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)  * Claim resources and initialize hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)  * Return: 0 if success, otherwise error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) static int hdlcdev_open(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	SLMP_INFO *info = dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 		printk("%s:hdlcdev_open(%s)\n",__FILE__,dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 	/* generic HDLC layer open processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 	rc = hdlc_open(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 	if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	/* arbitrate between network and tty opens */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	spin_lock_irqsave(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	if (info->port.count != 0 || info->netcount != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 		printk(KERN_WARNING "%s: hdlc_open returning busy\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 		spin_unlock_irqrestore(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	info->netcount=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	spin_unlock_irqrestore(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	/* claim resources and init adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	if ((rc = startup(info)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 		spin_lock_irqsave(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 		info->netcount=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 		spin_unlock_irqrestore(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	/* assert RTS and DTR, apply hardware settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	program_hw(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 	/* enable network layer transmit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	netif_trans_update(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	netif_start_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	/* inform generic HDLC layer of current DCD status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 	if (info->serial_signals & SerialSignal_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 		netif_carrier_on(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 		netif_carrier_off(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)  * hdlcdev_close - called by network layer when interface is disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)  * @dev: pointer to network device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)  * Shutdown hardware and release resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)  * Return: 0 if success, otherwise error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) static int hdlcdev_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	SLMP_INFO *info = dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 		printk("%s:hdlcdev_close(%s)\n",__FILE__,dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	/* shutdown adapter and release resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	shutdown(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	hdlc_close(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	spin_lock_irqsave(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	info->netcount=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	spin_unlock_irqrestore(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)  * hdlcdev_ioctl - called by network layer to process IOCTL call to network device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)  * @dev: pointer to network device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)  * @ifr: pointer to network interface request structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)  * @cmd: IOCTL command code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)  * Return: 0 if success, otherwise error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 	const size_t size = sizeof(sync_serial_settings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 	sync_serial_settings new_line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 	sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	SLMP_INFO *info = dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 	unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 		printk("%s:hdlcdev_ioctl(%s)\n",__FILE__,dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	/* return error if TTY interface open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 	if (info->port.count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	if (cmd != SIOCWANDEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 		return hdlc_ioctl(dev, ifr, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	switch(ifr->ifr_settings.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	case IF_GET_IFACE: /* return current sync_serial_settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 		ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 		if (ifr->ifr_settings.size < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 			ifr->ifr_settings.size = size; /* data size wanted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 			return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 		flags = info->params.flags & (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 					      HDLC_FLAG_RXC_BRG    | HDLC_FLAG_RXC_TXCPIN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 					      HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 					      HDLC_FLAG_TXC_BRG    | HDLC_FLAG_TXC_RXCPIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 		memset(&new_line, 0, sizeof(new_line));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 		switch (flags){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 		case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN): new_line.clock_type = CLOCK_EXT; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 		case (HDLC_FLAG_RXC_BRG    | HDLC_FLAG_TXC_BRG):    new_line.clock_type = CLOCK_INT; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 		case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG):    new_line.clock_type = CLOCK_TXINT; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 		case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN): new_line.clock_type = CLOCK_TXFROMRX; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 		default: new_line.clock_type = CLOCK_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 		new_line.clock_rate = info->params.clock_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 		new_line.loopback   = info->params.loopback ? 1:0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 		if (copy_to_user(line, &new_line, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 	case IF_IFACE_SYNC_SERIAL: /* set sync_serial_settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 		if(!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 			return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 		if (copy_from_user(&new_line, line, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 		switch (new_line.clock_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 		case CLOCK_EXT:      flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 		case CLOCK_TXFROMRX: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 		case CLOCK_INT:      flags = HDLC_FLAG_RXC_BRG    | HDLC_FLAG_TXC_BRG;    break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 		case CLOCK_TXINT:    flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG;    break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 		case CLOCK_DEFAULT:  flags = info->params.flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 					     (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 					      HDLC_FLAG_RXC_BRG    | HDLC_FLAG_RXC_TXCPIN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 					      HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 					      HDLC_FLAG_TXC_BRG    | HDLC_FLAG_TXC_RXCPIN); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 		default: return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 		if (new_line.loopback != 0 && new_line.loopback != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 		info->params.flags &= ~(HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 					HDLC_FLAG_RXC_BRG    | HDLC_FLAG_RXC_TXCPIN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 					HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 					HDLC_FLAG_TXC_BRG    | HDLC_FLAG_TXC_RXCPIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 		info->params.flags |= flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 		info->params.loopback = new_line.loopback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 		if (flags & (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 			info->params.clock_speed = new_line.clock_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 			info->params.clock_speed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 		/* if network interface up, reprogram hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 		if (info->netcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 			program_hw(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 		return hdlc_ioctl(dev, ifr, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)  * hdlcdev_tx_timeout - called by network layer when transmit timeout is detected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)  * @dev: pointer to network device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 	SLMP_INFO *info = dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 		printk("hdlcdev_tx_timeout(%s)\n",dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	dev->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	dev->stats.tx_aborted_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)  * hdlcdev_tx_done - called by device driver when transmit completes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)  * @info: pointer to device instance information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)  * Reenable network layer transmit if stopped.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) static void hdlcdev_tx_done(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	if (netif_queue_stopped(info->netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 		netif_wake_queue(info->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838)  * hdlcdev_rx - called by device driver when frame received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)  * @info: pointer to device instance information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)  * @buf:  pointer to buffer contianing frame data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)  * @size: count of data bytes in buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)  * Pass frame to network layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 	struct sk_buff *skb = dev_alloc_skb(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	struct net_device *dev = info->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 		printk("hdlcdev_rx(%s)\n",dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 	if (skb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 		printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 		       dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 		dev->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 	skb_put_data(skb, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 	skb->protocol = hdlc_type_trans(skb, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	dev->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 	dev->stats.rx_bytes += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 	netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) static const struct net_device_ops hdlcdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 	.ndo_open       = hdlcdev_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 	.ndo_stop       = hdlcdev_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	.ndo_start_xmit = hdlc_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 	.ndo_do_ioctl   = hdlcdev_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 	.ndo_tx_timeout = hdlcdev_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)  * hdlcdev_init - called by device driver when adding device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)  * @info: pointer to device instance information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882)  * Do generic HDLC initialization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)  * Return: 0 if success, otherwise error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) static int hdlcdev_init(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 	struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 	hdlc_device *hdlc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 	/* allocate and initialize network and HDLC layer objects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	dev = alloc_hdlcdev(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 		printk(KERN_ERR "%s:hdlc device allocation failure\n",__FILE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 	/* for network layer reporting purposes only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 	dev->mem_start = info->phys_sca_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	dev->mem_end   = info->phys_sca_base + SCA_BASE_SIZE - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	dev->irq       = info->irq_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 	/* network layer callbacks and settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 	dev->netdev_ops	    = &hdlcdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 	dev->watchdog_timeo = 10 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 	dev->tx_queue_len   = 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 	/* generic HDLC layer callbacks and settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	hdlc         = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 	hdlc->attach = hdlcdev_attach;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	hdlc->xmit   = hdlcdev_xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 	/* register objects with HDLC layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 	rc = register_hdlc_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 		printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 		free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 	info->netdev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)  * hdlcdev_exit - called by device driver when removing device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)  * @info: pointer to device instance information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)  * Do generic HDLC cleanup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) static void hdlcdev_exit(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 	unregister_hdlc_device(info->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 	free_netdev(info->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 	info->netdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) #endif /* CONFIG_HDLC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) /* Return next bottom half action to perform.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)  * Return Value:	BH action code or 0 if nothing to do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) static int bh_action(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	if (info->pending_bh & BH_RECEIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 		info->pending_bh &= ~BH_RECEIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 		rc = BH_RECEIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	} else if (info->pending_bh & BH_TRANSMIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 		info->pending_bh &= ~BH_TRANSMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 		rc = BH_TRANSMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	} else if (info->pending_bh & BH_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 		info->pending_bh &= ~BH_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 		rc = BH_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 	if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 		/* Mark BH routine as complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 		info->bh_running = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 		info->bh_requested = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) /* Perform bottom half processing of work items queued by ISR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) static void bh_handler(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	SLMP_INFO *info = container_of(work, SLMP_INFO, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	int action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	if ( debug_level >= DEBUG_LEVEL_BH )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 		printk( "%s(%d):%s bh_handler() entry\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 			__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 	info->bh_running = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 	while((action = bh_action(info)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 		/* Process work item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 		if ( debug_level >= DEBUG_LEVEL_BH )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 			printk( "%s(%d):%s bh_handler() work item action=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 				__FILE__,__LINE__,info->device_name, action);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 		switch (action) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 		case BH_RECEIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 			bh_receive(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 		case BH_TRANSMIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 			bh_transmit(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 		case BH_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 			bh_status(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 			/* unknown work item ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 			printk("%s(%d):%s Unknown work item ID=%08X!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 				__FILE__,__LINE__,info->device_name,action);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 	if ( debug_level >= DEBUG_LEVEL_BH )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 		printk( "%s(%d):%s bh_handler() exit\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 			__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) static void bh_receive(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 	if ( debug_level >= DEBUG_LEVEL_BH )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 		printk( "%s(%d):%s bh_receive()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 			__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 	while( rx_get_frame(info) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) static void bh_transmit(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 	struct tty_struct *tty = info->port.tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 	if ( debug_level >= DEBUG_LEVEL_BH )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 		printk( "%s(%d):%s bh_transmit() entry\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 			__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	if (tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 		tty_wakeup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) static void bh_status(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	if ( debug_level >= DEBUG_LEVEL_BH )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 		printk( "%s(%d):%s bh_status() entry\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 			__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 	info->ri_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	info->dsr_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 	info->dcd_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 	info->cts_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) static void isr_timer(SLMP_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 	unsigned char timer = (info->port_num & 1) ? TIMER2 : TIMER0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) 	/* IER2<7..4> = timer<3..0> interrupt enables (0=disabled) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 	write_reg(info, IER2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) 	/* TMCS, Timer Control/Status Register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 	 * 07      CMF, Compare match flag (read only) 1=match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) 	 * 06      ECMI, CMF Interrupt Enable: 0=disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 	 * 05      Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 	 * 04      TME, Timer Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	 * 03..00  Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 	 * 0000 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	write_reg(info, (unsigned char)(timer + TMCS), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 	info->irq_occurred = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 		printk("%s(%d):%s isr_timer()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 			__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) static void isr_rxint(SLMP_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080)  	struct tty_struct *tty = info->port.tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081)  	struct	mgsl_icount *icount = &info->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 	unsigned char status = read_reg(info, SR1) & info->ie1_value & (FLGD + IDLD + CDCD + BRKD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 	unsigned char status2 = read_reg(info, SR2) & info->ie2_value & OVRN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 	/* clear status bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 		write_reg(info, SR1, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 	if (status2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 		write_reg(info, SR2, status2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 	if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 		printk("%s(%d):%s isr_rxint status=%02X %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 			__FILE__,__LINE__,info->device_name,status,status2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 	if (info->params.mode == MGSL_MODE_ASYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 		if (status & BRKD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 			icount->brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 			/* process break detection if tty control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 			 * is not set to ignore it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 			if (!(status & info->ignore_status_mask1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 				if (info->read_status_mask1 & BRKD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 					tty_insert_flip_char(&info->port, 0, TTY_BREAK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 					if (tty && (info->port.flags & ASYNC_SAK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 						do_SAK(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 		if (status & (FLGD|IDLD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 			if (status & FLGD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 				info->icount.exithunt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 			else if (status & IDLD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 				info->icount.rxidle++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 			wake_up_interruptible(&info->event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 	if (status & CDCD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 		/* simulate a common modem status change interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 		 * for our handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 		get_signals( info );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 		isr_io_pin(info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 			MISCSTATUS_DCD_LATCHED|(info->serial_signals&SerialSignal_DCD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)  * handle async rx data interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) static void isr_rxrdy(SLMP_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	u16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 	unsigned char DataByte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)  	struct	mgsl_icount *icount = &info->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 	if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 		printk("%s(%d):%s isr_rxrdy\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 			__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 	while((status = read_reg(info,CST0)) & BIT0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 		int flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 		bool over = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 		DataByte = read_reg(info,TRB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 		icount->rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 		if ( status & (PE + FRME + OVRN) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 			printk("%s(%d):%s rxerr=%04X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 				__FILE__,__LINE__,info->device_name,status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 			/* update error statistics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 			if (status & PE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 				icount->parity++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 			else if (status & FRME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 				icount->frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 			else if (status & OVRN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 				icount->overrun++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 			/* discard char if tty control flags say so */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 			if (status & info->ignore_status_mask2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 			status &= info->read_status_mask2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 			if (status & PE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 				flag = TTY_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 			else if (status & FRME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 				flag = TTY_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 			if (status & OVRN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 				/* Overrun is special, since it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 				 * reported immediately, and doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 				 * affect the current character
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 				over = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 		}	/* end of if (error) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 		tty_insert_flip_char(&info->port, DataByte, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 		if (over)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 			tty_insert_flip_char(&info->port, 0, TTY_OVERRUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) 	if ( debug_level >= DEBUG_LEVEL_ISR ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) 		printk("%s(%d):%s rx=%d brk=%d parity=%d frame=%d overrun=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 			__FILE__,__LINE__,info->device_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 			icount->rx,icount->brk,icount->parity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 			icount->frame,icount->overrun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	tty_flip_buffer_push(&info->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) static void isr_txeom(SLMP_INFO * info, unsigned char status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 	if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 		printk("%s(%d):%s isr_txeom status=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 			__FILE__,__LINE__,info->device_name,status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 	write_reg(info, TXDMA + DIR, 0x00); /* disable Tx DMA IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 	write_reg(info, TXDMA + DSR, 0xc0); /* clear IRQs and disable DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	write_reg(info, TXDMA + DCMD, SWABORT);	/* reset/init DMA channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 	if (status & UDRN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 		write_reg(info, CMD, TXRESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 		write_reg(info, CMD, TXENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 		write_reg(info, CMD, TXBUFCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 	/* disable and clear tx interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 	info->ie0_value &= ~TXRDYE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 	info->ie1_value &= ~(IDLE + UDRN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	write_reg16(info, IE0, (unsigned short)((info->ie1_value << 8) + info->ie0_value));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 	write_reg(info, SR1, (unsigned char)(UDRN + IDLE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	if ( info->tx_active ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 		if (info->params.mode != MGSL_MODE_ASYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 			if (status & UDRN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 				info->icount.txunder++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 			else if (status & IDLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 				info->icount.txok++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 		info->tx_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 		info->tx_count = info->tx_put = info->tx_get = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 		del_timer(&info->tx_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 		if (info->params.mode != MGSL_MODE_ASYNC && info->drop_rts_on_tx_done ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 			info->serial_signals &= ~SerialSignal_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 			info->drop_rts_on_tx_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 			set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 		if (info->netcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 			hdlcdev_tx_done(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 			if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 				tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 			info->pending_bh |= BH_TRANSMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257)  * handle tx status interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) static void isr_txint(SLMP_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	unsigned char status = read_reg(info, SR1) & info->ie1_value & (UDRN + IDLE + CCTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 	/* clear status bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 	write_reg(info, SR1, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 	if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 		printk("%s(%d):%s isr_txint status=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 			__FILE__,__LINE__,info->device_name,status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 	if (status & (UDRN + IDLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 		isr_txeom(info, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 	if (status & CCTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 		/* simulate a common modem status change interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 		 * for our handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 		get_signals( info );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 		isr_io_pin(info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 			MISCSTATUS_CTS_LATCHED|(info->serial_signals&SerialSignal_CTS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)  * handle async tx data interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) static void isr_txrdy(SLMP_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 		printk("%s(%d):%s isr_txrdy() tx_count=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 			__FILE__,__LINE__,info->device_name,info->tx_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 	if (info->params.mode != MGSL_MODE_ASYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 		/* disable TXRDY IRQ, enable IDLE IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 		info->ie0_value &= ~TXRDYE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 		info->ie1_value |= IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 		write_reg16(info, IE0, (unsigned short)((info->ie1_value << 8) + info->ie0_value));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 		tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	if ( info->tx_count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 		tx_load_fifo( info );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 		info->tx_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 		info->ie0_value &= ~TXRDYE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 		write_reg(info, IE0, info->ie0_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 	if (info->tx_count < WAKEUP_CHARS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 		info->pending_bh |= BH_TRANSMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) static void isr_rxdmaok(SLMP_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 	/* BIT7 = EOT (end of transfer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 	 * BIT6 = EOM (end of message/frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	unsigned char status = read_reg(info,RXDMA + DSR) & 0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	/* clear IRQ (BIT0 must be 1 to prevent clearing DE bit) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 	write_reg(info, RXDMA + DSR, (unsigned char)(status | 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 	if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 		printk("%s(%d):%s isr_rxdmaok(), status=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 			__FILE__,__LINE__,info->device_name,status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 	info->pending_bh |= BH_RECEIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) static void isr_rxdmaerror(SLMP_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 	/* BIT5 = BOF (buffer overflow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	 * BIT4 = COF (counter overflow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	unsigned char status = read_reg(info,RXDMA + DSR) & 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	/* clear IRQ (BIT0 must be 1 to prevent clearing DE bit) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 	write_reg(info, RXDMA + DSR, (unsigned char)(status | 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 	if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 		printk("%s(%d):%s isr_rxdmaerror(), status=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 			__FILE__,__LINE__,info->device_name,status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 	info->rx_overflow = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 	info->pending_bh |= BH_RECEIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) static void isr_txdmaok(SLMP_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 	unsigned char status_reg1 = read_reg(info, SR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 	write_reg(info, TXDMA + DIR, 0x00);	/* disable Tx DMA IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 	write_reg(info, TXDMA + DSR, 0xc0); /* clear IRQs and disable DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 	write_reg(info, TXDMA + DCMD, SWABORT);	/* reset/init DMA channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 		printk("%s(%d):%s isr_txdmaok(), status=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 			__FILE__,__LINE__,info->device_name,status_reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 	/* program TXRDY as FIFO empty flag, enable TXRDY IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 	write_reg16(info, TRC0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 	info->ie0_value |= TXRDYE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	write_reg(info, IE0, info->ie0_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) static void isr_txdmaerror(SLMP_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 	/* BIT5 = BOF (buffer overflow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 	 * BIT4 = COF (counter overflow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 	unsigned char status = read_reg(info,TXDMA + DSR) & 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 	/* clear IRQ (BIT0 must be 1 to prevent clearing DE bit) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	write_reg(info, TXDMA + DSR, (unsigned char)(status | 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 	if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 		printk("%s(%d):%s isr_txdmaerror(), status=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 			__FILE__,__LINE__,info->device_name,status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) /* handle input serial signal changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) static void isr_io_pin( SLMP_INFO *info, u16 status )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)  	struct	mgsl_icount *icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 		printk("%s(%d):isr_io_pin status=%04X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 			__FILE__,__LINE__,status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 	if (status & (MISCSTATUS_CTS_LATCHED | MISCSTATUS_DCD_LATCHED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 	              MISCSTATUS_DSR_LATCHED | MISCSTATUS_RI_LATCHED) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 		icount = &info->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 		/* update input line counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 		if (status & MISCSTATUS_RI_LATCHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 			icount->rng++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 			if ( status & SerialSignal_RI )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 				info->input_signal_events.ri_up++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 				info->input_signal_events.ri_down++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 		if (status & MISCSTATUS_DSR_LATCHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 			icount->dsr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 			if ( status & SerialSignal_DSR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 				info->input_signal_events.dsr_up++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 				info->input_signal_events.dsr_down++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 		if (status & MISCSTATUS_DCD_LATCHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 			if ((info->dcd_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 				info->ie1_value &= ~CDCD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 				write_reg(info, IE1, info->ie1_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 			icount->dcd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 			if (status & SerialSignal_DCD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 				info->input_signal_events.dcd_up++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 				info->input_signal_events.dcd_down++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 			if (info->netcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 				if (status & SerialSignal_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 					netif_carrier_on(info->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 					netif_carrier_off(info->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 		if (status & MISCSTATUS_CTS_LATCHED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 			if ((info->cts_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 				info->ie1_value &= ~CCTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 				write_reg(info, IE1, info->ie1_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 			icount->cts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 			if ( status & SerialSignal_CTS )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 				info->input_signal_events.cts_up++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 				info->input_signal_events.cts_down++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 		wake_up_interruptible(&info->status_event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 		wake_up_interruptible(&info->event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 		if (tty_port_check_carrier(&info->port) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 		     (status & MISCSTATUS_DCD_LATCHED) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 			if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 				printk("%s CD now %s...", info->device_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 				       (status & SerialSignal_DCD) ? "on" : "off");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 			if (status & SerialSignal_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 				wake_up_interruptible(&info->port.open_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 				if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 					printk("doing serial hangup...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 				if (info->port.tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 					tty_hangup(info->port.tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 		if (tty_port_cts_enabled(&info->port) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 		     (status & MISCSTATUS_CTS_LATCHED) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 			if ( info->port.tty ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 				if (info->port.tty->hw_stopped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 					if (status & SerialSignal_CTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 						if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 							printk("CTS tx start...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 						info->port.tty->hw_stopped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 						tx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 						info->pending_bh |= BH_TRANSMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 						return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 				} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 					if (!(status & SerialSignal_CTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 						if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 							printk("CTS tx stop...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 						info->port.tty->hw_stopped = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 						tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 	info->pending_bh |= BH_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) /* Interrupt service routine entry point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492)  * Arguments:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)  * 	irq		interrupt number that caused interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494)  * 	dev_id		device ID supplied during interrupt registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495)  * 	regs		interrupted processor context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) static irqreturn_t synclinkmp_interrupt(int dummy, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 	SLMP_INFO *info = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 	unsigned char status, status0, status1=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 	unsigned char dmastatus, dmastatus0, dmastatus1=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 	unsigned char timerstatus0, timerstatus1=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 	unsigned char shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 	unsigned short tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 	if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 		printk(KERN_DEBUG "%s(%d): synclinkmp_interrupt(%d)entry.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 			__FILE__, __LINE__, info->irq_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 	spin_lock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	for(;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 		/* get status for SCA0 (ports 0-1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 		tmp = read_reg16(info, ISR0);	/* get ISR0 and ISR1 in one read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 		status0 = (unsigned char)tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 		dmastatus0 = (unsigned char)(tmp>>8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 		timerstatus0 = read_reg(info, ISR2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 		if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 			printk(KERN_DEBUG "%s(%d):%s status0=%02x, dmastatus0=%02x, timerstatus0=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 				__FILE__, __LINE__, info->device_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 				status0, dmastatus0, timerstatus0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 		if (info->port_count == 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 			/* get status for SCA1 (ports 2-3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 			tmp = read_reg16(info->port_array[2], ISR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 			status1 = (unsigned char)tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 			dmastatus1 = (unsigned char)(tmp>>8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 			timerstatus1 = read_reg(info->port_array[2], ISR2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 			if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 				printk("%s(%d):%s status1=%02x, dmastatus1=%02x, timerstatus1=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 					__FILE__,__LINE__,info->device_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 					status1,dmastatus1,timerstatus1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 		if (!status0 && !dmastatus0 && !timerstatus0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 			 !status1 && !dmastatus1 && !timerstatus1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 		for(i=0; i < info->port_count ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 			if (info->port_array[i] == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 			if (i < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 				status = status0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 				dmastatus = dmastatus0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 				status = status1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 				dmastatus = dmastatus1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 			shift = i & 1 ? 4 :0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 			if (status & BIT0 << shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 				isr_rxrdy(info->port_array[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 			if (status & BIT1 << shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 				isr_txrdy(info->port_array[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 			if (status & BIT2 << shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 				isr_rxint(info->port_array[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 			if (status & BIT3 << shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 				isr_txint(info->port_array[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 			if (dmastatus & BIT0 << shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 				isr_rxdmaerror(info->port_array[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 			if (dmastatus & BIT1 << shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 				isr_rxdmaok(info->port_array[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 			if (dmastatus & BIT2 << shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 				isr_txdmaerror(info->port_array[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 			if (dmastatus & BIT3 << shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 				isr_txdmaok(info->port_array[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 		if (timerstatus0 & (BIT5 | BIT4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 			isr_timer(info->port_array[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 		if (timerstatus0 & (BIT7 | BIT6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 			isr_timer(info->port_array[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 		if (timerstatus1 & (BIT5 | BIT4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 			isr_timer(info->port_array[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 		if (timerstatus1 & (BIT7 | BIT6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 			isr_timer(info->port_array[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 	for(i=0; i < info->port_count ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 		SLMP_INFO * port = info->port_array[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 		/* Request bottom half processing if there's something
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 		 * for it to do and the bh is not already running.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 		 * Note: startup adapter diags require interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 		 * do not request bottom half processing if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 		 * device is not open in a normal mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 		if ( port && (port->port.count || port->netcount) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 		     port->pending_bh && !port->bh_running &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 		     !port->bh_requested ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 			if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 				printk("%s(%d):%s queueing bh task.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 					__FILE__,__LINE__,port->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 			schedule_work(&port->task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 			port->bh_requested = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 	spin_unlock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) 	if ( debug_level >= DEBUG_LEVEL_ISR )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) 		printk(KERN_DEBUG "%s(%d):synclinkmp_interrupt(%d)exit.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) 			__FILE__, __LINE__, info->irq_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) /* Initialize and start device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) static int startup(SLMP_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 	if ( debug_level >= DEBUG_LEVEL_INFO )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 		printk("%s(%d):%s tx_releaseup()\n",__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 	if (tty_port_initialized(&info->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 	if (!info->tx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 		info->tx_buf = kmalloc(info->max_frame_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 		if (!info->tx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 			printk(KERN_ERR"%s(%d):%s can't allocate transmit buffer\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 				__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 	info->pending_bh = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	memset(&info->icount, 0, sizeof(info->icount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 	/* program hardware for current parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 	reset_port(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 	change_params(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 	mod_timer(&info->status_timer, jiffies + msecs_to_jiffies(10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 	if (info->port.tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 		clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 	tty_port_set_initialized(&info->port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) /* Called by close() and hangup() to shutdown hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) static void shutdown(SLMP_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	if (!tty_port_initialized(&info->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 		printk("%s(%d):%s synclinkmp_shutdown()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 			 __FILE__,__LINE__, info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 	/* clear status wait queue because status changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 	/* can't happen after shutting down the hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 	wake_up_interruptible(&info->status_event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 	wake_up_interruptible(&info->event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 	del_timer(&info->tx_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 	del_timer(&info->status_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	kfree(info->tx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 	info->tx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 	reset_port(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680)  	if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 		info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 		set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 	if (info->port.tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 		set_bit(TTY_IO_ERROR, &info->port.tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 	tty_port_set_initialized(&info->port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) static void program_hw(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 	rx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 	tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 	info->tx_count = info->tx_put = info->tx_get = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 	if (info->params.mode == MGSL_MODE_HDLC || info->netcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 		hdlc_mode(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 		async_mode(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 	set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 	info->dcd_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 	info->cts_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 	info->ri_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 	info->dsr_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 	info->ie1_value |= (CDCD|CCTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 	write_reg(info, IE1, info->ie1_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 	get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 	if (info->netcount || (info->port.tty && info->port.tty->termios.c_cflag & CREAD) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 		rx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) /* Reconfigure adapter based on new parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) static void change_params(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 	unsigned cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 	int bits_per_char;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 	if (!info->port.tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 		printk("%s(%d):%s change_params()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 			 __FILE__,__LINE__, info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 	cflag = info->port.tty->termios.c_cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 	/* if B0 rate (hangup) specified then negate RTS and DTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 	/* otherwise assert RTS and DTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745)  	if (cflag & CBAUD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 		info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 		info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 	/* byte size and parity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 	switch (cflag & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 	      case CS5: info->params.data_bits = 5; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 	      case CS6: info->params.data_bits = 6; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 	      case CS7: info->params.data_bits = 7; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 	      case CS8: info->params.data_bits = 8; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 	      /* Never happens, but GCC is too dumb to figure it out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 	      default:  info->params.data_bits = 7; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 	      }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 	if (cflag & CSTOPB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 		info->params.stop_bits = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 		info->params.stop_bits = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 	info->params.parity = ASYNC_PARITY_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 	if (cflag & PARENB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 		if (cflag & PARODD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 			info->params.parity = ASYNC_PARITY_ODD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 			info->params.parity = ASYNC_PARITY_EVEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) #ifdef CMSPAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 		if (cflag & CMSPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 			info->params.parity = ASYNC_PARITY_SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 	/* calculate number of jiffies to transmit a full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 	 * FIFO (32 bytes) at specified data rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 	bits_per_char = info->params.data_bits +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 			info->params.stop_bits + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 	/* if port data rate is set to 460800 or less then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 	 * allow tty settings to override, otherwise keep the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 	 * current data rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 	if (info->params.data_rate <= 460800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 		info->params.data_rate = tty_get_baud_rate(info->port.tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) 	if ( info->params.data_rate ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 		info->timeout = (32*HZ*bits_per_char) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 				info->params.data_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 	info->timeout += HZ/50;		/* Add .02 seconds of slop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 	tty_port_set_cts_flow(&info->port, cflag & CRTSCTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 	tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 	/* process tty input control flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 	info->read_status_mask2 = OVRN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 	if (I_INPCK(info->port.tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 		info->read_status_mask2 |= PE | FRME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 	if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 		info->read_status_mask1 |= BRKD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 	if (I_IGNPAR(info->port.tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 		info->ignore_status_mask2 |= PE | FRME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 	if (I_IGNBRK(info->port.tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 		info->ignore_status_mask1 |= BRKD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 		/* If ignoring parity and break indicators, ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 		 * overruns too.  (For real raw support).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 		if (I_IGNPAR(info->port.tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 			info->ignore_status_mask2 |= OVRN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	program_hw(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) static int get_stats(SLMP_INFO * info, struct mgsl_icount __user *user_icount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 		printk("%s(%d):%s get_params()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 			 __FILE__,__LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 	if (!user_icount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 		memset(&info->icount, 0, sizeof(info->icount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 		mutex_lock(&info->port.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 		COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 		mutex_unlock(&info->port.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 			return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) static int get_params(SLMP_INFO * info, MGSL_PARAMS __user *user_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 		printk("%s(%d):%s get_params()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 			 __FILE__,__LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 	mutex_lock(&info->port.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 	COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 	mutex_unlock(&info->port.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 		if ( debug_level >= DEBUG_LEVEL_INFO )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 			printk( "%s(%d):%s get_params() user buffer copy failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 				__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) static int set_params(SLMP_INFO * info, MGSL_PARAMS __user *new_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865)  	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 	MGSL_PARAMS tmp_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) 		printk("%s(%d):%s set_params\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 			__FILE__,__LINE__,info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 	COPY_FROM_USER(err,&tmp_params, new_params, sizeof(MGSL_PARAMS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) 		if ( debug_level >= DEBUG_LEVEL_INFO )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) 			printk( "%s(%d):%s set_params() user buffer copy failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) 				__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 	mutex_lock(&info->port.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 	memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885)  	change_params(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 	mutex_unlock(&info->port.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) static int get_txidle(SLMP_INFO * info, int __user *idle_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 		printk("%s(%d):%s get_txidle()=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 			 __FILE__,__LINE__, info->device_name, info->idle_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 	COPY_TO_USER(err,idle_mode, &info->idle_mode, sizeof(int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 		if ( debug_level >= DEBUG_LEVEL_INFO )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 			printk( "%s(%d):%s get_txidle() user buffer copy failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 				__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) static int set_txidle(SLMP_INFO * info, int idle_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912)  	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 		printk("%s(%d):%s set_txidle(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 			__FILE__,__LINE__,info->device_name, idle_mode );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 	info->idle_mode = idle_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 	tx_set_idle( info );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) static int tx_enable(SLMP_INFO * info, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927)  	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 		printk("%s(%d):%s tx_enable(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 			__FILE__,__LINE__,info->device_name, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 	if ( enable ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 		if ( !info->tx_enabled ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 			tx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 		if ( info->tx_enabled )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 			tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) /* abort send HDLC frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) static int tx_abort(SLMP_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950)  	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 		printk("%s(%d):%s tx_abort()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 			__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 	if ( info->tx_active && info->params.mode == MGSL_MODE_HDLC ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 		info->ie1_value &= ~UDRN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 		info->ie1_value |= IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 		write_reg(info, IE1, info->ie1_value);	/* disable tx status interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 		write_reg(info, SR1, (unsigned char)(IDLE + UDRN));	/* clear pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 		write_reg(info, TXDMA + DSR, 0);		/* disable DMA channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 		write_reg(info, TXDMA + DCMD, SWABORT);	/* reset/init DMA channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966)    		write_reg(info, CMD, TXABORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) static int rx_enable(SLMP_INFO * info, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974)  	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) 		printk("%s(%d):%s rx_enable(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) 			__FILE__,__LINE__,info->device_name,enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 	if ( enable ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 		if ( !info->rx_enabled )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 			rx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 		if ( info->rx_enabled )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 			rx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) /* wait for specified event to occur
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) static int wait_mgsl_event(SLMP_INFO * info, int __user *mask_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996)  	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 	int s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 	int rc=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 	struct mgsl_icount cprev, cnow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 	int events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 	int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 	struct	_input_signal_events oldsigs, newsigs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	DECLARE_WAITQUEUE(wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 	COPY_FROM_USER(rc,&mask, mask_ptr, sizeof(int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 		return  -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 		printk("%s(%d):%s wait_mgsl_event(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 			__FILE__,__LINE__,info->device_name,mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	/* return immediately if state matches requested events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 	get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 	s = info->serial_signals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 	events = mask &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 		( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022)  		  ((s & SerialSignal_DCD) ? MgslEvent_DcdActive:MgslEvent_DcdInactive) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 		  ((s & SerialSignal_CTS) ? MgslEvent_CtsActive:MgslEvent_CtsInactive) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 		  ((s & SerialSignal_RI)  ? MgslEvent_RiActive :MgslEvent_RiInactive) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 	if (events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) 		spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) 	/* save current irq counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 	cprev = info->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 	oldsigs = info->input_signal_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 	/* enable hunt and idle irqs if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 	if (mask & (MgslEvent_ExitHuntMode+MgslEvent_IdleReceived)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 		unsigned char oldval = info->ie1_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 		unsigned char newval = oldval +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 			 (mask & MgslEvent_ExitHuntMode ? FLGD:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 			 (mask & MgslEvent_IdleReceived ? IDLD:0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 		if ( oldval != newval ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 			info->ie1_value = newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 			write_reg(info, IE1, info->ie1_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 	set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 	add_wait_queue(&info->event_wait_q, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 	for(;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 		schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 		if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 			rc = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 		/* get current irq counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 		spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 		cnow = info->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 		newsigs = info->input_signal_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 		set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 		spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 		/* if no change, wait aborted for some reason */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 		if (newsigs.dsr_up   == oldsigs.dsr_up   &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 		    newsigs.dsr_down == oldsigs.dsr_down &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 		    newsigs.dcd_up   == oldsigs.dcd_up   &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 		    newsigs.dcd_down == oldsigs.dcd_down &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 		    newsigs.cts_up   == oldsigs.cts_up   &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 		    newsigs.cts_down == oldsigs.cts_down &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 		    newsigs.ri_up    == oldsigs.ri_up    &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 		    newsigs.ri_down  == oldsigs.ri_down  &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 		    cnow.exithunt    == cprev.exithunt   &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 		    cnow.rxidle      == cprev.rxidle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 			rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 		events = mask &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 			( (newsigs.dsr_up   != oldsigs.dsr_up   ? MgslEvent_DsrActive:0)   +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 			  (newsigs.dsr_down != oldsigs.dsr_down ? MgslEvent_DsrInactive:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 			  (newsigs.dcd_up   != oldsigs.dcd_up   ? MgslEvent_DcdActive:0)   +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 			  (newsigs.dcd_down != oldsigs.dcd_down ? MgslEvent_DcdInactive:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 			  (newsigs.cts_up   != oldsigs.cts_up   ? MgslEvent_CtsActive:0)   +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 			  (newsigs.cts_down != oldsigs.cts_down ? MgslEvent_CtsInactive:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 			  (newsigs.ri_up    != oldsigs.ri_up    ? MgslEvent_RiActive:0)    +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 			  (newsigs.ri_down  != oldsigs.ri_down  ? MgslEvent_RiInactive:0)  +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 			  (cnow.exithunt    != cprev.exithunt   ? MgslEvent_ExitHuntMode:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 			  (cnow.rxidle      != cprev.rxidle     ? MgslEvent_IdleReceived:0) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 		if (events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 		cprev = cnow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 		oldsigs = newsigs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 	remove_wait_queue(&info->event_wait_q, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 	set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 	if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 		spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 		if (!waitqueue_active(&info->event_wait_q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 			/* disable enable exit hunt mode/idle rcvd IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 			info->ie1_value &= ~(FLGD|IDLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 			write_reg(info, IE1, info->ie1_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 		spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 	if ( rc == 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 		PUT_USER(rc, events, mask_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) static int modem_input_wait(SLMP_INFO *info,int arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120)  	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 	struct mgsl_icount cprev, cnow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 	DECLARE_WAITQUEUE(wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 	/* save current irq counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 	cprev = info->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 	add_wait_queue(&info->status_event_wait_q, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 	set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 	for(;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 		schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 		if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 			rc = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 		/* get new irq counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 		spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 		cnow = info->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 		set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 		spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 		/* if no change, wait aborted for some reason */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 		if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 		    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 			rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 		/* check for change in caller specified modem input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 		if ((arg & TIOCM_RNG && cnow.rng != cprev.rng) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 		    (arg & TIOCM_DSR && cnow.dsr != cprev.dsr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 		    (arg & TIOCM_CD  && cnow.dcd != cprev.dcd) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 		    (arg & TIOCM_CTS && cnow.cts != cprev.cts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 			rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 		cprev = cnow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 	remove_wait_queue(&info->status_event_wait_q, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 	set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) /* return the state of the serial control and status signals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) static int tiocmget(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) 	unsigned int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174)  	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 	get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 	result = ((info->serial_signals & SerialSignal_RTS) ? TIOCM_RTS : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 		 ((info->serial_signals & SerialSignal_DTR) ? TIOCM_DTR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 		 ((info->serial_signals & SerialSignal_DCD) ? TIOCM_CAR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 		 ((info->serial_signals & SerialSignal_RI)  ? TIOCM_RNG : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) 		 ((info->serial_signals & SerialSignal_DSR) ? TIOCM_DSR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 		 ((info->serial_signals & SerialSignal_CTS) ? TIOCM_CTS : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 		printk("%s(%d):%s tiocmget() value=%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 			 __FILE__,__LINE__, info->device_name, result );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) /* set modem control signals (DTR/RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) static int tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 					unsigned int set, unsigned int clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 	SLMP_INFO *info = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199)  	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 		printk("%s(%d):%s tiocmset(%x,%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 			__FILE__,__LINE__,info->device_name, set, clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 	if (set & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 		info->serial_signals |= SerialSignal_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 	if (set & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 		info->serial_signals |= SerialSignal_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 	if (clear & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 		info->serial_signals &= ~SerialSignal_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 	if (clear & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 		info->serial_signals &= ~SerialSignal_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 	set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) static int carrier_raised(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 	SLMP_INFO *info = container_of(port, SLMP_INFO, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 	get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 	return (info->serial_signals & SerialSignal_DCD) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) static void dtr_rts(struct tty_port *port, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 	SLMP_INFO *info = container_of(port, SLMP_INFO, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 	if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) 		info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 		info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 	set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) /* Block the current process until the specified port is ready to open.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) static int block_til_ready(struct tty_struct *tty, struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 			   SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 	DECLARE_WAITQUEUE(wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 	int		retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 	bool		do_clocal = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 	unsigned long	flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 	int		cd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 	struct tty_port *port = &info->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 		printk("%s(%d):%s block_til_ready()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 			 __FILE__,__LINE__, tty->driver->name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 	if (filp->f_flags & O_NONBLOCK || tty_io_error(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 		/* nonblock mode is set or port is not enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) 		/* just verify that callout device is not active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 		tty_port_set_active(port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 	if (C_CLOCAL(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 		do_clocal = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 	/* Wait for carrier detect and the line to become
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 	 * free (i.e., not in use by the callout).  While we are in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 	 * this loop, port->count is dropped by one, so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 	 * close() knows when to free things.  We restore it upon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 	 * exit, either normal or abnormal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 	retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 	add_wait_queue(&port->open_wait, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 		printk("%s(%d):%s block_til_ready() before block, count=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 			 __FILE__,__LINE__, tty->driver->name, port->count );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 	spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 	port->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 	spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 	port->blocked_open++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 		if (C_BAUD(tty) && tty_port_initialized(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 			tty_port_raise_dtr_rts(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 		set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 		if (tty_hung_up_p(filp) || !tty_port_initialized(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 			retval = (port->flags & ASYNC_HUP_NOTIFY) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 					-EAGAIN : -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 		cd = tty_port_carrier_raised(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 		if (do_clocal || cd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 		if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 			retval = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 		if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 			printk("%s(%d):%s block_til_ready() count=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 				 __FILE__,__LINE__, tty->driver->name, port->count );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 		tty_unlock(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 		schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 		tty_lock(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 	set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 	remove_wait_queue(&port->open_wait, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 	if (!tty_hung_up_p(filp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 		port->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) 	port->blocked_open--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) 	if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 		printk("%s(%d):%s block_til_ready() after, count=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 			 __FILE__,__LINE__, tty->driver->name, port->count );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 	if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 		tty_port_set_active(port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 	return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) static int alloc_dma_bufs(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 	unsigned short BuffersPerFrame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 	unsigned short BufferCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 	// Force allocation to start at 64K boundary for each port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 	// This is necessary because *all* buffer descriptors for a port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 	// *must* be in the same 64K block. All descriptors on a port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 	// share a common 'base' address (upper 8 bits of 24 bits) programmed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 	// into the CBP register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 	info->port_array[0]->last_mem_alloc = (SCA_MEM_SIZE/4) * info->port_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 	/* Calculate the number of DMA buffers necessary to hold the */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 	/* largest allowable frame size. Note: If the max frame size is */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 	/* not an even multiple of the DMA buffer size then we need to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 	/* round the buffer count per frame up one. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 	BuffersPerFrame = (unsigned short)(info->max_frame_size/SCABUFSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 	if ( info->max_frame_size % SCABUFSIZE )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 		BuffersPerFrame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 	/* calculate total number of data buffers (SCABUFSIZE) possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 	 * in one ports memory (SCA_MEM_SIZE/4) after allocating memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 	 * for the descriptor list (BUFFERLISTSIZE).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 	BufferCount = (SCA_MEM_SIZE/4 - BUFFERLISTSIZE)/SCABUFSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 	/* limit number of buffers to maximum amount of descriptors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 	if (BufferCount > BUFFERLISTSIZE/sizeof(SCADESC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 		BufferCount = BUFFERLISTSIZE/sizeof(SCADESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 	/* use enough buffers to transmit one max size frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 	info->tx_buf_count = BuffersPerFrame + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 	/* never use more than half the available buffers for transmit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 	if (info->tx_buf_count > (BufferCount/2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 		info->tx_buf_count = BufferCount/2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 	if (info->tx_buf_count > SCAMAXDESC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 		info->tx_buf_count = SCAMAXDESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 	/* use remaining buffers for receive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 	info->rx_buf_count = BufferCount - info->tx_buf_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 	if (info->rx_buf_count > SCAMAXDESC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 		info->rx_buf_count = SCAMAXDESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 	if ( debug_level >= DEBUG_LEVEL_INFO )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 		printk("%s(%d):%s Allocating %d TX and %d RX DMA buffers.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) 			__FILE__,__LINE__, info->device_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) 			info->tx_buf_count,info->rx_buf_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) 	if ( alloc_buf_list( info ) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 		alloc_frame_bufs(info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) 		  			info->rx_buf_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 		  			info->rx_buf_list_ex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) 					info->rx_buf_count) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) 		alloc_frame_bufs(info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) 					info->tx_buf_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 					info->tx_buf_list_ex,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) 					info->tx_buf_count) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 		alloc_tmp_rx_buf(info) < 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) 		printk("%s(%d):%s Can't allocate DMA buffer memory\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) 			__FILE__,__LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) 	rx_reset_buffers( info );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) /* Allocate DMA buffers for the transmit and receive descriptor lists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) static int alloc_buf_list(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 	/* build list in adapter shared memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 	info->buffer_list = info->memory_base + info->port_array[0]->last_mem_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 	info->buffer_list_phys = info->port_array[0]->last_mem_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 	info->port_array[0]->last_mem_alloc += BUFFERLISTSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) 	memset(info->buffer_list, 0, BUFFERLISTSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 	/* Save virtual address pointers to the receive and */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 	/* transmit buffer lists. (Receive 1st). These pointers will */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 	/* be used by the processor to access the lists. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 	info->rx_buf_list = (SCADESC *)info->buffer_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 	info->tx_buf_list = (SCADESC *)info->buffer_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 	info->tx_buf_list += info->rx_buf_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 	/* Build links for circular buffer entry lists (tx and rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 	 * Note: links are physical addresses read by the SCA device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 	 * to determine the next buffer entry to use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 	for ( i = 0; i < info->rx_buf_count; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 		/* calculate and store physical address of this buffer entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 		info->rx_buf_list_ex[i].phys_entry =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 			info->buffer_list_phys + (i * SCABUFSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 		/* calculate and store physical address of */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 		/* next entry in cirular list of entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 		info->rx_buf_list[i].next = info->buffer_list_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 		if ( i < info->rx_buf_count - 1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) 			info->rx_buf_list[i].next += (i + 1) * sizeof(SCADESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 		info->rx_buf_list[i].length = SCABUFSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 	for ( i = 0; i < info->tx_buf_count; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 		/* calculate and store physical address of this buffer entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 		info->tx_buf_list_ex[i].phys_entry = info->buffer_list_phys +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 			((info->rx_buf_count + i) * sizeof(SCADESC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 		/* calculate and store physical address of */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 		/* next entry in cirular list of entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) 		info->tx_buf_list[i].next = info->buffer_list_phys +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 			info->rx_buf_count * sizeof(SCADESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 		if ( i < info->tx_buf_count - 1 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 			info->tx_buf_list[i].next += (i + 1) * sizeof(SCADESC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) /* Allocate the frame DMA buffers used by the specified buffer list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) static int alloc_frame_bufs(SLMP_INFO *info, SCADESC *buf_list,SCADESC_EX *buf_list_ex,int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) 	unsigned long phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) 	for ( i = 0; i < count; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 		buf_list_ex[i].virt_addr = info->memory_base + info->port_array[0]->last_mem_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) 		phys_addr = info->port_array[0]->last_mem_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) 		info->port_array[0]->last_mem_alloc += SCABUFSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) 		buf_list[i].buf_ptr  = (unsigned short)phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) 		buf_list[i].buf_base = (unsigned char)(phys_addr >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) static void free_dma_bufs(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) 	info->buffer_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) 	info->rx_buf_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 	info->tx_buf_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) /* allocate buffer large enough to hold max_frame_size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496)  * This buffer is used to pass an assembled frame to the line discipline.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) static int alloc_tmp_rx_buf(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 	info->tmp_rx_buf = kmalloc(info->max_frame_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 	if (info->tmp_rx_buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 	/* unused flag buffer to satisfy receive_buf calling interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 	info->flag_buf = kzalloc(info->max_frame_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 	if (!info->flag_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 		kfree(info->tmp_rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 		info->tmp_rx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) static void free_tmp_rx_buf(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 	kfree(info->tmp_rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 	info->tmp_rx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 	kfree(info->flag_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) 	info->flag_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) static int claim_resources(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 	if (request_mem_region(info->phys_memory_base,SCA_MEM_SIZE,"synclinkmp") == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 		printk( "%s(%d):%s mem addr conflict, Addr=%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 			__FILE__,__LINE__,info->device_name, info->phys_memory_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 		info->init_error = DiagStatus_AddressConflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 		info->shared_mem_requested = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 	if (request_mem_region(info->phys_lcr_base + info->lcr_offset,128,"synclinkmp") == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) 		printk( "%s(%d):%s lcr mem addr conflict, Addr=%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) 			__FILE__,__LINE__,info->device_name, info->phys_lcr_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 		info->init_error = DiagStatus_AddressConflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 		info->lcr_mem_requested = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 	if (request_mem_region(info->phys_sca_base + info->sca_offset,SCA_BASE_SIZE,"synclinkmp") == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 		printk( "%s(%d):%s sca mem addr conflict, Addr=%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 			__FILE__,__LINE__,info->device_name, info->phys_sca_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) 		info->init_error = DiagStatus_AddressConflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 		info->sca_base_requested = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 	if (request_mem_region(info->phys_statctrl_base + info->statctrl_offset,SCA_REG_SIZE,"synclinkmp") == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) 		printk( "%s(%d):%s stat/ctrl mem addr conflict, Addr=%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 			__FILE__,__LINE__,info->device_name, info->phys_statctrl_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) 		info->init_error = DiagStatus_AddressConflict;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) 		info->sca_statctrl_requested = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 	info->memory_base = ioremap(info->phys_memory_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 								SCA_MEM_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 	if (!info->memory_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 		printk( "%s(%d):%s Can't map shared memory, MemAddr=%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 			__FILE__,__LINE__,info->device_name, info->phys_memory_base );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) 		info->init_error = DiagStatus_CantAssignPciResources;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) 	info->lcr_base = ioremap(info->phys_lcr_base, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) 	if (!info->lcr_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) 		printk( "%s(%d):%s Can't map LCR memory, MemAddr=%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) 			__FILE__,__LINE__,info->device_name, info->phys_lcr_base );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) 		info->init_error = DiagStatus_CantAssignPciResources;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) 	info->lcr_base += info->lcr_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) 	info->sca_base = ioremap(info->phys_sca_base, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 	if (!info->sca_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 		printk( "%s(%d):%s Can't map SCA memory, MemAddr=%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) 			__FILE__,__LINE__,info->device_name, info->phys_sca_base );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) 		info->init_error = DiagStatus_CantAssignPciResources;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 	info->sca_base += info->sca_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 	info->statctrl_base = ioremap(info->phys_statctrl_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 								PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 	if (!info->statctrl_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 		printk( "%s(%d):%s Can't map SCA Status/Control memory, MemAddr=%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 			__FILE__,__LINE__,info->device_name, info->phys_statctrl_base );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 		info->init_error = DiagStatus_CantAssignPciResources;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 	info->statctrl_base += info->statctrl_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) 	if ( !memory_test(info) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) 		printk( "%s(%d):Shared Memory Test failed for device %s MemAddr=%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 			__FILE__,__LINE__,info->device_name, info->phys_memory_base );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 		info->init_error = DiagStatus_MemoryError;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 		goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) errout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) 	release_resources( info );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) static void release_resources(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 	if ( debug_level >= DEBUG_LEVEL_INFO )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 		printk( "%s(%d):%s release_resources() entry\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 			__FILE__,__LINE__,info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 	if ( info->irq_requested ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) 		free_irq(info->irq_level, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 		info->irq_requested = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) 	if ( info->shared_mem_requested ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 		release_mem_region(info->phys_memory_base,SCA_MEM_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 		info->shared_mem_requested = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 	if ( info->lcr_mem_requested ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 		release_mem_region(info->phys_lcr_base + info->lcr_offset,128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) 		info->lcr_mem_requested = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 	if ( info->sca_base_requested ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) 		release_mem_region(info->phys_sca_base + info->sca_offset,SCA_BASE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) 		info->sca_base_requested = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) 	if ( info->sca_statctrl_requested ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) 		release_mem_region(info->phys_statctrl_base + info->statctrl_offset,SCA_REG_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 		info->sca_statctrl_requested = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 	if (info->memory_base){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) 		iounmap(info->memory_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 		info->memory_base = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 	if (info->sca_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) 		iounmap(info->sca_base - info->sca_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 		info->sca_base=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) 	if (info->statctrl_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) 		iounmap(info->statctrl_base - info->statctrl_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 		info->statctrl_base=NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 	if (info->lcr_base){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) 		iounmap(info->lcr_base - info->lcr_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 		info->lcr_base = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) 	if ( debug_level >= DEBUG_LEVEL_INFO )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) 		printk( "%s(%d):%s release_resources() exit\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) 			__FILE__,__LINE__,info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) /* Add the specified device instance data structure to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664)  * global linked list of devices and increment the device count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) static int add_device(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 	info->next_device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 	info->line = synclinkmp_device_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 	sprintf(info->device_name,"ttySLM%dp%d",info->adapter_num,info->port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 	if (info->line < MAX_DEVICES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) 		if (maxframe[info->line])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) 			info->max_frame_size = maxframe[info->line];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 	synclinkmp_device_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) 	if ( !synclinkmp_device_list )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) 		synclinkmp_device_list = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) 		SLMP_INFO *current_dev = synclinkmp_device_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) 		while( current_dev->next_device )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) 			current_dev = current_dev->next_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 		current_dev->next_device = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) 	if ( info->max_frame_size < 4096 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) 		info->max_frame_size = 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) 	else if ( info->max_frame_size > 65535 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) 		info->max_frame_size = 65535;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) 	printk( "SyncLink MultiPort %s: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) 		"Mem=(%08x %08X %08x %08X) IRQ=%d MaxFrameSize=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) 		info->device_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) 		info->phys_sca_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) 		info->phys_memory_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) 		info->phys_statctrl_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) 		info->phys_lcr_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) 		info->irq_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) 		info->max_frame_size );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) 	return hdlcdev_init(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) static const struct tty_port_operations port_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 	.carrier_raised = carrier_raised,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) 	.dtr_rts = dtr_rts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) /* Allocate and initialize a device instance structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717)  * Return Value:	pointer to SLMP_INFO if success, otherwise NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 	SLMP_INFO *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 	info = kzalloc(sizeof(SLMP_INFO),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 		 GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) 	if (!info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) 		printk("%s(%d) Error can't allocate device instance data for adapter %d, port %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) 			__FILE__,__LINE__, adapter_num, port_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) 		tty_port_init(&info->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) 		info->port.ops = &port_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) 		info->magic = MGSL_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) 		INIT_WORK(&info->task, bh_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 		info->max_frame_size = 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 		info->port.close_delay = 5*HZ/10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) 		info->port.closing_wait = 30*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 		init_waitqueue_head(&info->status_event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 		init_waitqueue_head(&info->event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) 		spin_lock_init(&info->netlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 		memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 		info->idle_mode = HDLC_TXIDLE_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) 		info->adapter_num = adapter_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) 		info->port_num = port_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) 		/* Copy configuration info to device instance data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) 		info->irq_level = pdev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 		info->phys_lcr_base = pci_resource_start(pdev,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) 		info->phys_sca_base = pci_resource_start(pdev,2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) 		info->phys_memory_base = pci_resource_start(pdev,3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) 		info->phys_statctrl_base = pci_resource_start(pdev,4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) 		/* Because veremap only works on page boundaries we must map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) 		 * a larger area than is actually implemented for the LCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) 		 * memory range. We map a full page starting at the page boundary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) 		info->lcr_offset    = info->phys_lcr_base & (PAGE_SIZE-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) 		info->phys_lcr_base &= ~(PAGE_SIZE-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) 		info->sca_offset    = info->phys_sca_base & (PAGE_SIZE-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) 		info->phys_sca_base &= ~(PAGE_SIZE-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) 		info->statctrl_offset    = info->phys_statctrl_base & (PAGE_SIZE-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) 		info->phys_statctrl_base &= ~(PAGE_SIZE-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 		info->bus_type = MGSL_BUS_TYPE_PCI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) 		info->irq_flags = IRQF_SHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) 		timer_setup(&info->tx_timer, tx_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) 		timer_setup(&info->status_timer, status_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) 		/* Store the PCI9050 misc control register value because a flaw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 		 * in the PCI9050 prevents LCR registers from being read if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) 		 * BIOS assigns an LCR base address with bit 7 set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) 		 * Only the misc control register is accessed for which only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) 		 * write access is needed, so set an initial value and change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) 		 * bits to the device instance data as we write the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 		 * to the actual misc control register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 		info->misc_ctrl_value = 0x087e4546;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 		/* initial port state is unknown - if startup errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 		 * occur, init_error will be set to indicate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 		 * problem. Once the port is fully initialized,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) 		 * this value will be set to 0 to indicate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) 		 * port is available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 		info->init_error = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) 	return info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) static int device_init(int adapter_num, struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) 	SLMP_INFO *port_array[SCA_MAX_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) 	int port, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) 	/* allocate device instances for up to SCA_MAX_PORTS devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 	for ( port = 0; port < SCA_MAX_PORTS; ++port ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 		port_array[port] = alloc_dev(adapter_num,port,pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) 		if( port_array[port] == NULL ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 			for (--port; port >= 0; --port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) 				tty_port_destroy(&port_array[port]->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 				kfree(port_array[port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) 	/* give copy of port_array to all ports and add to device list  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) 	for ( port = 0; port < SCA_MAX_PORTS; ++port ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) 		memcpy(port_array[port]->port_array,port_array,sizeof(port_array));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) 		rc = add_device( port_array[port] );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) 			goto err_add;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) 		spin_lock_init(&port_array[port]->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) 	/* Allocate and claim adapter resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 	if ( !claim_resources(port_array[0]) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) 		alloc_dma_bufs(port_array[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) 		/* copy resource information from first port to others */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) 		for ( port = 1; port < SCA_MAX_PORTS; ++port ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 			port_array[port]->lock  = port_array[0]->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) 			port_array[port]->irq_level     = port_array[0]->irq_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) 			port_array[port]->memory_base   = port_array[0]->memory_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) 			port_array[port]->sca_base      = port_array[0]->sca_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) 			port_array[port]->statctrl_base = port_array[0]->statctrl_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) 			port_array[port]->lcr_base      = port_array[0]->lcr_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) 			alloc_dma_bufs(port_array[port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) 		rc = request_irq(port_array[0]->irq_level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) 					synclinkmp_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) 					port_array[0]->irq_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) 					port_array[0]->device_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) 					port_array[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) 		if ( rc ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) 			printk( "%s(%d):%s Can't request interrupt, IRQ=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) 				__FILE__,__LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 				port_array[0]->device_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 				port_array[0]->irq_level );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 			goto err_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) 		port_array[0]->irq_requested = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) 		adapter_test(port_array[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) err_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) 	release_resources( port_array[0] );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) err_add:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) 	for ( port = 0; port < SCA_MAX_PORTS; ++port ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) 		tty_port_destroy(&port_array[port]->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) 		kfree(port_array[port]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) static const struct tty_operations ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) 	.install = install,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) 	.open = open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) 	.close = close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) 	.write = write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) 	.put_char = put_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) 	.flush_chars = flush_chars,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) 	.write_room = write_room,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) 	.chars_in_buffer = chars_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) 	.flush_buffer = flush_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) 	.ioctl = ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) 	.throttle = throttle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) 	.unthrottle = unthrottle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) 	.send_xchar = send_xchar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) 	.break_ctl = set_break,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) 	.wait_until_sent = wait_until_sent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) 	.set_termios = set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) 	.stop = tx_hold,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) 	.start = tx_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) 	.hangup = hangup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) 	.tiocmget = tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 	.tiocmset = tiocmset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) 	.get_icount = get_icount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) 	.proc_show = synclinkmp_proc_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) static void synclinkmp_cleanup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) 	SLMP_INFO *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) 	SLMP_INFO *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) 	printk("Unloading %s %s\n", driver_name, driver_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) 	if (serial_driver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) 		rc = tty_unregister_driver(serial_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) 		if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) 			printk("%s(%d) failed to unregister tty driver err=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) 			       __FILE__,__LINE__,rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) 		put_tty_driver(serial_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 	/* reset devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) 	info = synclinkmp_device_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 	while(info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) 		reset_port(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 		info = info->next_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 	/* release devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) 	info = synclinkmp_device_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) 	while(info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) 		hdlcdev_exit(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) 		free_dma_bufs(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) 		free_tmp_rx_buf(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) 		if ( info->port_num == 0 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) 			if (info->sca_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) 				write_reg(info, LPR, 1); /* set low power mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) 			release_resources(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) 		tmp = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) 		info = info->next_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) 		tty_port_destroy(&tmp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) 		kfree(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) 	pci_unregister_driver(&synclinkmp_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) /* Driver initialization entry point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) static int __init synclinkmp_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) 	if (break_on_load) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) 	 	synclinkmp_get_text_ptr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943)   		BREAKPOINT();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946)  	printk("%s %s\n", driver_name, driver_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) 	if ((rc = pci_register_driver(&synclinkmp_pci_driver)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) 		printk("%s:failed to register PCI driver, error=%d\n",__FILE__,rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) 	serial_driver = alloc_tty_driver(128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) 	if (!serial_driver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) 		rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) 	/* Initialize the tty_driver structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) 	serial_driver->driver_name = "synclinkmp";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) 	serial_driver->name = "ttySLM";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) 	serial_driver->major = ttymajor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) 	serial_driver->minor_start = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) 	serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) 	serial_driver->subtype = SERIAL_TYPE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) 	serial_driver->init_termios = tty_std_termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) 	serial_driver->init_termios.c_cflag =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) 		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) 	serial_driver->init_termios.c_ispeed = 9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 	serial_driver->init_termios.c_ospeed = 9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 	serial_driver->flags = TTY_DRIVER_REAL_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 	tty_set_operations(serial_driver, &ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 	if ((rc = tty_register_driver(serial_driver)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 		printk("%s(%d):Couldn't register serial driver\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 			__FILE__,__LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 		put_tty_driver(serial_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 		serial_driver = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982)  	printk("%s %s, tty major#%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 		driver_name, driver_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 		serial_driver->major);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) 	synclinkmp_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) static void __exit synclinkmp_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 	synclinkmp_cleanup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) module_init(synclinkmp_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) module_exit(synclinkmp_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) /* Set the port for internal loopback mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002)  * The TxCLK and RxCLK signals are generated from the BRG and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003)  * the TxD is looped back to the RxD internally.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) static void enable_loopback(SLMP_INFO *info, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) 	if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 		/* MD2 (Mode Register 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) 		 * 01..00  CNCT<1..0> Channel Connection 11=Local Loopback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) 		write_reg(info, MD2, (unsigned char)(read_reg(info, MD2) | (BIT1 + BIT0)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) 		/* degate external TxC clock source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) 		info->port_array[0]->ctrlreg_value |= (BIT0 << (info->port_num * 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) 		write_control_reg(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) 		/* RXS/TXS (Rx/Tx clock source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) 		 * 07      Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) 		 * 06..04  Clock Source, 100=BRG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 		 * 03..00  Clock Divisor, 0000=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) 		write_reg(info, RXS, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 		write_reg(info, TXS, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 		/* MD2 (Mode Register 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) 	 	 * 01..00  CNCT<1..0> Channel connection, 0=normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 		write_reg(info, MD2, (unsigned char)(read_reg(info, MD2) & ~(BIT1 + BIT0)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) 		/* RXS/TXS (Rx/Tx clock source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 		 * 07      Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 		 * 06..04  Clock Source, 000=RxC/TxC Pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) 		 * 03..00  Clock Divisor, 0000=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) 		write_reg(info, RXS, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) 		write_reg(info, TXS, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) 	/* set LinkSpeed if available, otherwise default to 2Mbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) 	if (info->params.clock_speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 		set_rate(info, info->params.clock_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) 		set_rate(info, 3686400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) /* Set the baud rate register to the desired speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049)  *	data_rate	data rate of clock in bits per second
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050)  *			A data rate of 0 disables the AUX clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) static void set_rate( SLMP_INFO *info, u32 data_rate )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054)        	u32 TMCValue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055)        	unsigned char BRValue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) 	u32 Divisor=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) 	/* fBRG = fCLK/(TMC * 2^BR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) 	if (data_rate != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) 		Divisor = 14745600/data_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) 		if (!Divisor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) 			Divisor = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) 		TMCValue = Divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) 		BRValue = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) 		if (TMCValue != 1 && TMCValue != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) 			/* BRValue of 0 provides 50/50 duty cycle *only* when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) 			 * TMCValue is 1 or 2. BRValue of 1 to 9 always provides
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) 			 * 50/50 duty cycle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) 			BRValue = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) 			TMCValue >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) 		/* while TMCValue is too big for TMC register, divide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) 		 * by 2 and increment BR exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) 		for(; TMCValue > 256 && BRValue < 10; BRValue++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) 			TMCValue >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) 		write_reg(info, TXS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) 			(unsigned char)((read_reg(info, TXS) & 0xf0) | BRValue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) 		write_reg(info, RXS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) 			(unsigned char)((read_reg(info, RXS) & 0xf0) | BRValue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) 		write_reg(info, TMC, (unsigned char)TMCValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) 		write_reg(info, TXS,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) 		write_reg(info, RXS,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) 		write_reg(info, TMC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) /* Disable receiver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) static void rx_stop(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) 	if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) 		printk("%s(%d):%s rx_stop()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) 			 __FILE__,__LINE__, info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) 	write_reg(info, CMD, RXRESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) 	info->ie0_value &= ~RXRDYE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) 	write_reg(info, IE0, info->ie0_value);	/* disable Rx data interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) 	write_reg(info, RXDMA + DSR, 0);	/* disable Rx DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) 	write_reg(info, RXDMA + DCMD, SWABORT);	/* reset/init Rx DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) 	write_reg(info, RXDMA + DIR, 0);	/* disable Rx DMA interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) 	info->rx_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) 	info->rx_overflow = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) /* enable the receiver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) static void rx_start(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) 	if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) 		printk("%s(%d):%s rx_start()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) 			 __FILE__,__LINE__, info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) 	write_reg(info, CMD, RXRESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) 	if ( info->params.mode == MGSL_MODE_HDLC ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) 		/* HDLC, disabe IRQ on rxdata */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) 		info->ie0_value &= ~RXRDYE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) 		write_reg(info, IE0, info->ie0_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) 		/* Reset all Rx DMA buffers and program rx dma */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) 		write_reg(info, RXDMA + DSR, 0);		/* disable Rx DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) 		write_reg(info, RXDMA + DCMD, SWABORT);	/* reset/init Rx DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) 		for (i = 0; i < info->rx_buf_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) 			info->rx_buf_list[i].status = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) 			// throttle to 4 shared memory writes at a time to prevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) 			// hogging local bus (keep latency time for DMA requests low).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) 			if (!(i % 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) 				read_status_reg(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) 		info->current_rx_buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) 		/* set current/1st descriptor address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) 		write_reg16(info, RXDMA + CDA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) 			info->rx_buf_list_ex[0].phys_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) 		/* set new last rx descriptor address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) 		write_reg16(info, RXDMA + EDA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) 			info->rx_buf_list_ex[info->rx_buf_count - 1].phys_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) 		/* set buffer length (shared by all rx dma data buffers) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) 		write_reg16(info, RXDMA + BFL, SCABUFSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) 		write_reg(info, RXDMA + DIR, 0x60);	/* enable Rx DMA interrupts (EOM/BOF) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) 		write_reg(info, RXDMA + DSR, 0xf2);	/* clear Rx DMA IRQs, enable Rx DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) 		/* async, enable IRQ on rxdata */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) 		info->ie0_value |= RXRDYE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) 		write_reg(info, IE0, info->ie0_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) 	write_reg(info, CMD, RXENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) 	info->rx_overflow = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) 	info->rx_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) /* Enable the transmitter and send a transmit frame if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174)  * one is loaded in the DMA buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) static void tx_start(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) 	if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) 		printk("%s(%d):%s tx_start() tx_count=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) 			 __FILE__,__LINE__, info->device_name,info->tx_count );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) 	if (!info->tx_enabled ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) 		write_reg(info, CMD, TXRESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) 		write_reg(info, CMD, TXENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) 		info->tx_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) 	if ( info->tx_count ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) 		/* If auto RTS enabled and RTS is inactive, then assert */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) 		/* RTS and set a flag indicating that the driver should */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) 		/* negate RTS when the transmission completes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) 		info->drop_rts_on_tx_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) 		if (info->params.mode != MGSL_MODE_ASYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) 			if ( info->params.flags & HDLC_FLAG_AUTO_RTS ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) 				get_signals( info );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) 				if ( !(info->serial_signals & SerialSignal_RTS) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) 					info->serial_signals |= SerialSignal_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) 					set_signals( info );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) 					info->drop_rts_on_tx_done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) 			write_reg16(info, TRC0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) 				(unsigned short)(((tx_negate_fifo_level-1)<<8) + tx_active_fifo_level));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) 			write_reg(info, TXDMA + DSR, 0); 		/* disable DMA channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) 			write_reg(info, TXDMA + DCMD, SWABORT);	/* reset/init DMA channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) 			/* set TX CDA (current descriptor address) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) 			write_reg16(info, TXDMA + CDA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) 				info->tx_buf_list_ex[0].phys_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) 			/* set TX EDA (last descriptor address) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) 			write_reg16(info, TXDMA + EDA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) 				info->tx_buf_list_ex[info->last_tx_buf].phys_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) 			/* enable underrun IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) 			info->ie1_value &= ~IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) 			info->ie1_value |= UDRN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) 			write_reg(info, IE1, info->ie1_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) 			write_reg(info, SR1, (unsigned char)(IDLE + UDRN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) 			write_reg(info, TXDMA + DIR, 0x40);		/* enable Tx DMA interrupts (EOM) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) 			write_reg(info, TXDMA + DSR, 0xf2);		/* clear Tx DMA IRQs, enable Tx DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) 			mod_timer(&info->tx_timer, jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) 					msecs_to_jiffies(5000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) 			tx_load_fifo(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) 			/* async, enable IRQ on txdata */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) 			info->ie0_value |= TXRDYE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) 			write_reg(info, IE0, info->ie0_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) 		info->tx_active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) /* stop the transmitter and DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) static void tx_stop( SLMP_INFO *info )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) 	if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) 		printk("%s(%d):%s tx_stop()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) 			 __FILE__,__LINE__, info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) 	del_timer(&info->tx_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) 	write_reg(info, TXDMA + DSR, 0);		/* disable DMA channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) 	write_reg(info, TXDMA + DCMD, SWABORT);	/* reset/init DMA channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) 	write_reg(info, CMD, TXRESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) 	info->ie1_value &= ~(UDRN + IDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) 	write_reg(info, IE1, info->ie1_value);	/* disable tx status interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) 	write_reg(info, SR1, (unsigned char)(IDLE + UDRN));	/* clear pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) 	info->ie0_value &= ~TXRDYE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) 	write_reg(info, IE0, info->ie0_value);	/* disable tx data interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) 	info->tx_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) 	info->tx_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) /* Fill the transmit FIFO until the FIFO is full or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271)  * there is no more data to load.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) static void tx_load_fifo(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) 	u8 TwoBytes[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) 	/* do nothing is now tx data available and no XON/XOFF pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) 	if ( !info->tx_count && !info->x_char )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) 	/* load the Transmit FIFO until FIFOs full or all data sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) 	while( info->tx_count && (read_reg(info,SR0) & BIT1) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) 		/* there is more space in the transmit FIFO and */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) 		/* there is more data in transmit buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) 		if ( (info->tx_count > 1) && !info->x_char ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290)  			/* write 16-bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) 			TwoBytes[0] = info->tx_buf[info->tx_get++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) 			if (info->tx_get >= info->max_frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) 				info->tx_get -= info->max_frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) 			TwoBytes[1] = info->tx_buf[info->tx_get++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) 			if (info->tx_get >= info->max_frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) 				info->tx_get -= info->max_frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) 			write_reg16(info, TRB, *((u16 *)TwoBytes));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) 			info->tx_count -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) 			info->icount.tx += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) 			/* only 1 byte left to transmit or 1 FIFO slot left */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) 			if (info->x_char) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) 				/* transmit pending high priority char */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) 				write_reg(info, TRB, info->x_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) 				info->x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) 				write_reg(info, TRB, info->tx_buf[info->tx_get++]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) 				if (info->tx_get >= info->max_frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) 					info->tx_get -= info->max_frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) 				info->tx_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) 			info->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320) /* Reset a port to a known state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322) static void reset_port(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324) 	if (info->sca_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326) 		tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327) 		rx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329) 		info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330) 		set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332) 		/* disable all port interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333) 		info->ie0_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334) 		info->ie1_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335) 		info->ie2_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336) 		write_reg(info, IE0, info->ie0_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337) 		write_reg(info, IE1, info->ie1_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338) 		write_reg(info, IE2, info->ie2_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340) 		write_reg(info, CMD, CHRESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) /* Reset all the ports to a known state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) static void reset_adapter(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) 	for ( i=0; i < SCA_MAX_PORTS; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) 		if (info->port_array[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) 			reset_port(info->port_array[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) /* Program port for asynchronous communications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) static void async_mode(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361)   	unsigned char RegValue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) 	tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) 	rx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) 	/* MD0, Mode Register 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) 	 * 07..05  PRCTL<2..0>, Protocol Mode, 000=async
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) 	 * 04      AUTO, Auto-enable (RTS/CTS/DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) 	 * 03      Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) 	 * 02      CRCCC, CRC Calculation, 0=disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) 	 * 01..00  STOP<1..0> Stop bits (00=1,10=2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) 	 * 0000 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) 	RegValue = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) 	if (info->params.stop_bits != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) 		RegValue |= BIT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) 	write_reg(info, MD0, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) 	/* MD1, Mode Register 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) 	 * 07..06  BRATE<1..0>, bit rate, 00=1/1 01=1/16 10=1/32 11=1/64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) 	 * 05..04  TXCHR<1..0>, tx char size, 00=8 bits,01=7,10=6,11=5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) 	 * 03..02  RXCHR<1..0>, rx char size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) 	 * 01..00  PMPM<1..0>, Parity mode, 00=none 10=even 11=odd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) 	 * 0100 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) 	RegValue = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) 	switch (info->params.data_bits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) 	case 7: RegValue |= BIT4 + BIT2; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) 	case 6: RegValue |= BIT5 + BIT3; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) 	case 5: RegValue |= BIT5 + BIT4 + BIT3 + BIT2; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) 	if (info->params.parity != ASYNC_PARITY_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) 		RegValue |= BIT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) 		if (info->params.parity == ASYNC_PARITY_ODD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) 			RegValue |= BIT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) 	write_reg(info, MD1, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) 	/* MD2, Mode Register 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) 	 * 07..02  Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) 	 * 01..00  CNCT<1..0> Channel connection, 00=normal 11=local loopback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) 	 * 0000 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) 	RegValue = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) 	if (info->params.loopback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) 		RegValue |= (BIT1 + BIT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) 	write_reg(info, MD2, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) 	/* RXS, Receive clock source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) 	 * 07      Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) 	 * 06..04  RXCS<2..0>, clock source, 000=RxC Pin, 100=BRG, 110=DPLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) 	 * 03..00  RXBR<3..0>, rate divisor, 0000=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) 	RegValue=BIT6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) 	write_reg(info, RXS, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) 	/* TXS, Transmit clock source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) 	 * 07      Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) 	 * 06..04  RXCS<2..0>, clock source, 000=TxC Pin, 100=BRG, 110=Receive Clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) 	 * 03..00  RXBR<3..0>, rate divisor, 0000=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) 	RegValue=BIT6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) 	write_reg(info, TXS, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) 	/* Control Register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) 	 * 6,4,2,0  CLKSEL<3..0>, 0 = TcCLK in, 1 = Auxclk out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) 	info->port_array[0]->ctrlreg_value |= (BIT0 << (info->port_num * 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) 	write_control_reg(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) 	tx_set_idle(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) 	/* RRC Receive Ready Control 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) 	 * 07..05  Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) 	 * 04..00  RRC<4..0> Rx FIFO trigger active 0x00 = 1 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) 	write_reg(info, RRC, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) 	/* TRC0 Transmit Ready Control 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) 	 * 07..05  Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) 	 * 04..00  TRC<4..0> Tx FIFO trigger active 0x10 = 16 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) 	write_reg(info, TRC0, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456) 	/* TRC1 Transmit Ready Control 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458) 	 * 07..05  Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459) 	 * 04..00  TRC<4..0> Tx FIFO trigger inactive 0x1e = 31 bytes (full-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) 	write_reg(info, TRC1, 0x1e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) 	/* CTL, MSCI control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) 	 * 07..06  Reserved, set to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) 	 * 05      UDRNC, underrun control, 0=abort 1=CRC+flag (HDLC/BSC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) 	 * 04      IDLC, idle control, 0=mark 1=idle register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) 	 * 03      BRK, break, 0=off 1 =on (async)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) 	 * 02      SYNCLD, sync char load enable (BSC) 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) 	 * 01      GOP, go active on poll (LOOP mode) 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) 	 * 00      RTS, RTS output control, 0=active 1=inactive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) 	 * 0001 0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) 	RegValue = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) 	if (!(info->serial_signals & SerialSignal_RTS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) 		RegValue |= 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) 	write_reg(info, CTL, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) 	/* enable status interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481) 	info->ie0_value |= TXINTE + RXINTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482) 	write_reg(info, IE0, info->ie0_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484) 	/* enable break detect interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485) 	info->ie1_value = BRKD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) 	write_reg(info, IE1, info->ie1_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) 	/* enable rx overrun interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) 	info->ie2_value = OVRN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) 	write_reg(info, IE2, info->ie2_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) 	set_rate( info, info->params.data_rate * 16 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) /* Program the SCA for HDLC communications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) static void hdlc_mode(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) 	unsigned char RegValue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) 	u32 DpllDivisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) 	// Can't use DPLL because SCA outputs recovered clock on RxC when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) 	// DPLL mode selected. This causes output contention with RxC receiver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) 	// Use of DPLL would require external hardware to disable RxC receiver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) 	// when DPLL mode selected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) 	info->params.flags &= ~(HDLC_FLAG_TXC_DPLL + HDLC_FLAG_RXC_DPLL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) 	/* disable DMA interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) 	write_reg(info, TXDMA + DIR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) 	write_reg(info, RXDMA + DIR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512) 	/* MD0, Mode Register 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514) 	 * 07..05  PRCTL<2..0>, Protocol Mode, 100=HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) 	 * 04      AUTO, Auto-enable (RTS/CTS/DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) 	 * 03      Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) 	 * 02      CRCCC, CRC Calculation, 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) 	 * 01      CRC1, CRC selection, 0=CRC-16,1=CRC-CCITT-16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) 	 * 00      CRC0, CRC initial value, 1 = all 1s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) 	 * 1000 0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) 	RegValue = 0x81;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) 	if (info->params.flags & HDLC_FLAG_AUTO_CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) 		RegValue |= BIT4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) 	if (info->params.flags & HDLC_FLAG_AUTO_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) 		RegValue |= BIT4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) 	if (info->params.crc_type == HDLC_CRC_16_CCITT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) 		RegValue |= BIT2 + BIT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530) 	write_reg(info, MD0, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532) 	/* MD1, Mode Register 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) 	 * 07..06  ADDRS<1..0>, Address detect, 00=no addr check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) 	 * 05..04  TXCHR<1..0>, tx char size, 00=8 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) 	 * 03..02  RXCHR<1..0>, rx char size, 00=8 bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) 	 * 01..00  PMPM<1..0>, Parity mode, 00=no parity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) 	 * 0000 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) 	RegValue = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) 	write_reg(info, MD1, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) 	/* MD2, Mode Register 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) 	 * 07      NRZFM, 0=NRZ, 1=FM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) 	 * 06..05  CODE<1..0> Encoding, 00=NRZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) 	 * 04..03  DRATE<1..0> DPLL Divisor, 00=8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) 	 * 02      Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) 	 * 01..00  CNCT<1..0> Channel connection, 0=normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) 	 * 0000 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) 	RegValue = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) 	switch(info->params.encoding) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) 	case HDLC_ENCODING_NRZI:	  RegValue |= BIT5; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) 	case HDLC_ENCODING_BIPHASE_MARK:  RegValue |= BIT7 + BIT5; break; /* aka FM1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) 	case HDLC_ENCODING_BIPHASE_SPACE: RegValue |= BIT7 + BIT6; break; /* aka FM0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) 	case HDLC_ENCODING_BIPHASE_LEVEL: RegValue |= BIT7; break; 	/* aka Manchester */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) 	case HDLC_ENCODING_NRZB:	       				/* not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) 	case HDLC_ENCODING_NRZI_MARK:          				/* not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) 	case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: 				/* not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) 	if ( info->params.flags & HDLC_FLAG_DPLL_DIV16 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) 		DpllDivisor = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) 		RegValue |= BIT3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) 	} else if ( info->params.flags & HDLC_FLAG_DPLL_DIV8 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) 		DpllDivisor = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) 		DpllDivisor = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) 		RegValue |= BIT4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) 	write_reg(info, MD2, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) 	/* RXS, Receive clock source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) 	 * 07      Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) 	 * 06..04  RXCS<2..0>, clock source, 000=RxC Pin, 100=BRG, 110=DPLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) 	 * 03..00  RXBR<3..0>, rate divisor, 0000=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) 	RegValue=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) 	if (info->params.flags & HDLC_FLAG_RXC_BRG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) 		RegValue |= BIT6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) 	if (info->params.flags & HDLC_FLAG_RXC_DPLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) 		RegValue |= BIT6 + BIT5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) 	write_reg(info, RXS, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) 	/* TXS, Transmit clock source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) 	 * 07      Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) 	 * 06..04  RXCS<2..0>, clock source, 000=TxC Pin, 100=BRG, 110=Receive Clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) 	 * 03..00  RXBR<3..0>, rate divisor, 0000=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) 	RegValue=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) 	if (info->params.flags & HDLC_FLAG_TXC_BRG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) 		RegValue |= BIT6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) 	if (info->params.flags & HDLC_FLAG_TXC_DPLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) 		RegValue |= BIT6 + BIT5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) 	write_reg(info, TXS, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) 	if (info->params.flags & HDLC_FLAG_RXC_DPLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) 		set_rate(info, info->params.clock_speed * DpllDivisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607) 		set_rate(info, info->params.clock_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609) 	/* GPDATA (General Purpose I/O Data Register)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611) 	 * 6,4,2,0  CLKSEL<3..0>, 0 = TcCLK in, 1 = Auxclk out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613) 	if (info->params.flags & HDLC_FLAG_TXC_BRG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614) 		info->port_array[0]->ctrlreg_value |= (BIT0 << (info->port_num * 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616) 		info->port_array[0]->ctrlreg_value &= ~(BIT0 << (info->port_num * 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617) 	write_control_reg(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619) 	/* RRC Receive Ready Control 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621) 	 * 07..05  Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622) 	 * 04..00  RRC<4..0> Rx FIFO trigger active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624) 	write_reg(info, RRC, rx_active_fifo_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) 	/* TRC0 Transmit Ready Control 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) 	 * 07..05  Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) 	 * 04..00  TRC<4..0> Tx FIFO trigger active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) 	write_reg(info, TRC0, tx_active_fifo_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) 	/* TRC1 Transmit Ready Control 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) 	 * 07..05  Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) 	 * 04..00  TRC<4..0> Tx FIFO trigger inactive 0x1f = 32 bytes (full)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) 	write_reg(info, TRC1, (unsigned char)(tx_negate_fifo_level - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) 	/* DMR, DMA Mode Register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) 	 * 07..05  Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) 	 * 04      TMOD, Transfer Mode: 1=chained-block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) 	 * 03      Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) 	 * 02      NF, Number of Frames: 1=multi-frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) 	 * 01      CNTE, Frame End IRQ Counter enable: 0=disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) 	 * 00      Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) 	 * 0001 0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) 	write_reg(info, TXDMA + DMR, 0x14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) 	write_reg(info, RXDMA + DMR, 0x14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) 	/* Set chain pointer base (upper 8 bits of 24 bit addr) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) 	write_reg(info, RXDMA + CPB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) 		(unsigned char)(info->buffer_list_phys >> 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) 	/* Set chain pointer base (upper 8 bits of 24 bit addr) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) 	write_reg(info, TXDMA + CPB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) 		(unsigned char)(info->buffer_list_phys >> 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) 	/* enable status interrupts. other code enables/disables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) 	 * the individual sources for these two interrupt classes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) 	info->ie0_value |= TXINTE + RXINTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) 	write_reg(info, IE0, info->ie0_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) 	/* CTL, MSCI control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) 	 * 07..06  Reserved, set to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) 	 * 05      UDRNC, underrun control, 0=abort 1=CRC+flag (HDLC/BSC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) 	 * 04      IDLC, idle control, 0=mark 1=idle register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) 	 * 03      BRK, break, 0=off 1 =on (async)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) 	 * 02      SYNCLD, sync char load enable (BSC) 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) 	 * 01      GOP, go active on poll (LOOP mode) 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) 	 * 00      RTS, RTS output control, 0=active 1=inactive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) 	 * 0001 0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) 	RegValue = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) 	if (!(info->serial_signals & SerialSignal_RTS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) 		RegValue |= 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) 	write_reg(info, CTL, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) 	/* preamble not supported ! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) 	tx_set_idle(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) 	tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) 	rx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) 	set_rate(info, info->params.clock_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) 	if (info->params.loopback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) 		enable_loopback(info,1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) /* Set the transmit HDLC idle mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) static void tx_set_idle(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) 	unsigned char RegValue = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) 	/* Map API idle mode to SCA register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) 	switch(info->idle_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) 	case HDLC_TXIDLE_FLAGS:			RegValue = 0x7e; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) 	case HDLC_TXIDLE_ALT_ZEROS_ONES:	RegValue = 0xaa; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) 	case HDLC_TXIDLE_ZEROS:			RegValue = 0x00; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) 	case HDLC_TXIDLE_ONES:			RegValue = 0xff; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) 	case HDLC_TXIDLE_ALT_MARK_SPACE:	RegValue = 0xaa; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) 	case HDLC_TXIDLE_SPACE:			RegValue = 0x00; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) 	case HDLC_TXIDLE_MARK:			RegValue = 0xff; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) 	write_reg(info, IDL, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) /* Query the adapter for the state of the V24 status (input) signals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) static void get_signals(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) 	u16 status = read_reg(info, SR3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) 	u16 gpstatus = read_status_reg(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) 	u16 testbit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) 	/* clear all serial signals except RTS and DTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) 	info->serial_signals &= SerialSignal_RTS | SerialSignal_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) 	/* set serial signal bits to reflect MISR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) 	if (!(status & BIT3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) 		info->serial_signals |= SerialSignal_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) 	if ( !(status & BIT2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) 		info->serial_signals |= SerialSignal_DCD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) 	testbit = BIT1 << (info->port_num * 2); // Port 0..3 RI is GPDATA<1,3,5,7>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) 	if (!(gpstatus & testbit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) 		info->serial_signals |= SerialSignal_RI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) 	testbit = BIT0 << (info->port_num * 2); // Port 0..3 DSR is GPDATA<0,2,4,6>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) 	if (!(gpstatus & testbit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) 		info->serial_signals |= SerialSignal_DSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) /* Set the state of RTS and DTR based on contents of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746)  * serial_signals member of device context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) static void set_signals(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) 	unsigned char RegValue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) 	u16 EnableBit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) 	RegValue = read_reg(info, CTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) 	if (info->serial_signals & SerialSignal_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) 		RegValue &= ~BIT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) 		RegValue |= BIT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) 	write_reg(info, CTL, RegValue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) 	// Port 0..3 DTR is ctrl reg <1,3,5,7>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) 	EnableBit = BIT1 << (info->port_num*2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762) 	if (info->serial_signals & SerialSignal_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763) 		info->port_array[0]->ctrlreg_value &= ~EnableBit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765) 		info->port_array[0]->ctrlreg_value |= EnableBit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766) 	write_control_reg(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) /*******************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) /* DMA Buffer Code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) /*******************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) /* Set the count for all receive buffers to SCABUFSIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774)  * and set the current buffer to the first buffer. This effectively
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775)  * makes all buffers free and discards any data in buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) static void rx_reset_buffers(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) 	rx_free_frame_buffers(info, 0, info->rx_buf_count - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) /* Free the buffers used by a received frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784)  * info   pointer to device instance data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785)  * first  index of 1st receive buffer of frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786)  * last   index of last receive buffer of frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) static void rx_free_frame_buffers(SLMP_INFO *info, unsigned int first, unsigned int last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) 	bool done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) 	while(!done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) 	        /* reset current buffer for reuse */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) 		info->rx_buf_list[first].status = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) 	        if (first == last) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) 	                done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) 	                /* set new last rx descriptor address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) 			write_reg16(info, RXDMA + EDA, info->rx_buf_list_ex[first].phys_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) 	        }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) 	        first++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) 		if (first == info->rx_buf_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) 			first = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) 	/* set current buffer to next buffer after last buffer of frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) 	info->current_rx_buf = first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) /* Return a received frame from the receive DMA buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812)  * Only frames received without errors are returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814)  * Return Value:	true if frame returned, otherwise false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) static bool rx_get_frame(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818) 	unsigned int StartIndex, EndIndex;	/* index of 1st and last buffers of Rx frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819) 	unsigned short status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) 	unsigned int framesize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) 	bool ReturnCode = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) 	struct tty_struct *tty = info->port.tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) 	unsigned char addr_field = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825)    	SCADESC *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) 	SCADESC_EX *desc_ex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) CheckAgain:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) 	/* assume no frame returned, set zero length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) 	framesize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) 	addr_field = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) 	 * current_rx_buf points to the 1st buffer of the next available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) 	 * receive frame. To find the last buffer of the frame look for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) 	 * a non-zero status field in the buffer entries. (The status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) 	 * field is set by the 16C32 after completing a receive frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) 	StartIndex = EndIndex = info->current_rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) 	for ( ;; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) 		desc = &info->rx_buf_list[EndIndex];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) 		desc_ex = &info->rx_buf_list_ex[EndIndex];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) 		if (desc->status == 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) 			goto Cleanup;	/* current desc still in use, no frames available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) 		if (framesize == 0 && info->params.addr_filter != 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) 			addr_field = desc_ex->virt_addr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) 		framesize += desc->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) 		/* Status != 0 means last buffer of frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) 		if (desc->status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) 		EndIndex++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) 		if (EndIndex == info->rx_buf_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) 			EndIndex = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) 		if (EndIndex == info->current_rx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) 			/* all buffers have been 'used' but none mark	   */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) 			/* the end of a frame. Reset buffers and receiver. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) 			if ( info->rx_enabled ){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) 				spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) 				rx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) 				spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) 			goto Cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) 	/* check status of receive frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) 	/* frame status is byte stored after frame data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) 	 * 7 EOM (end of msg), 1 = last buffer of frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) 	 * 6 Short Frame, 1 = short frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) 	 * 5 Abort, 1 = frame aborted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) 	 * 4 Residue, 1 = last byte is partial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) 	 * 3 Overrun, 1 = overrun occurred during frame reception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) 	 * 2 CRC,     1 = CRC error detected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) 	status = desc->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) 	/* ignore CRC bit if not using CRC (bit is undefined) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) 	/* Note:CRC is not save to data buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) 	if (info->params.crc_type == HDLC_CRC_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) 		status &= ~BIT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) 	if (framesize == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) 		 (addr_field != 0xff && addr_field != info->params.addr_filter)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) 		/* discard 0 byte frames, this seems to occur sometime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) 		 * when remote is idling flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) 		rx_free_frame_buffers(info, StartIndex, EndIndex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) 		goto CheckAgain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) 	if (framesize < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) 		status |= BIT6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) 	if (status & (BIT6+BIT5+BIT3+BIT2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) 		/* received frame has errors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) 		 * update counts and mark frame size as 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) 		if (status & BIT6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) 			info->icount.rxshort++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) 		else if (status & BIT5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) 			info->icount.rxabort++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) 		else if (status & BIT3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) 			info->icount.rxover++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) 			info->icount.rxcrc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) 		framesize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) 			info->netdev->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) 			info->netdev->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4924) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4925) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4927) 	if ( debug_level >= DEBUG_LEVEL_BH )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4928) 		printk("%s(%d):%s rx_get_frame() status=%04X size=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4929) 			__FILE__,__LINE__,info->device_name,status,framesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4931) 	if ( debug_level >= DEBUG_LEVEL_DATA )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4932) 		trace_block(info,info->rx_buf_list_ex[StartIndex].virt_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4933) 			min_t(unsigned int, framesize, SCABUFSIZE), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4935) 	if (framesize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4936) 		if (framesize > info->max_frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4937) 			info->icount.rxlong++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4938) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4939) 			/* copy dma buffer(s) to contiguous intermediate buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4940) 			int copy_count = framesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4941) 			int index = StartIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4942) 			unsigned char *ptmp = info->tmp_rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4943) 			info->tmp_rx_buf_count = framesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4945) 			info->icount.rxok++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4947) 			while(copy_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4948) 				int partial_count = min(copy_count,SCABUFSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4949) 				memcpy( ptmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4950) 					info->rx_buf_list_ex[index].virt_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4951) 					partial_count );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4952) 				ptmp += partial_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4953) 				copy_count -= partial_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4955) 				if ( ++index == info->rx_buf_count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4956) 					index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4957) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4959) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4960) 			if (info->netcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4961) 				hdlcdev_rx(info,info->tmp_rx_buf,framesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4962) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4963) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4964) 				ldisc_receive_buf(tty,info->tmp_rx_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4965) 						  info->flag_buf, framesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4966) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4967) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4968) 	/* Free the buffers used by this frame. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4969) 	rx_free_frame_buffers( info, StartIndex, EndIndex );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4971) 	ReturnCode = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4973) Cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4974) 	if ( info->rx_enabled && info->rx_overflow ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4975) 		/* Receiver is enabled, but needs to restarted due to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4976) 		 * rx buffer overflow. If buffers are empty, restart receiver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4977) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4978) 		if (info->rx_buf_list[EndIndex].status == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4979) 			spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4980) 			rx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4981) 			spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4982) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4983) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4985) 	return ReturnCode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4988) /* load the transmit DMA buffer with data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4989)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4990) static void tx_load_dma_buffer(SLMP_INFO *info, const char *buf, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4992) 	unsigned short copy_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4993) 	unsigned int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4994) 	SCADESC *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4995) 	SCADESC_EX *desc_ex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4997) 	if ( debug_level >= DEBUG_LEVEL_DATA )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4998) 		trace_block(info, buf, min_t(unsigned int, count, SCABUFSIZE), 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5000) 	/* Copy source buffer to one or more DMA buffers, starting with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5001) 	 * the first transmit dma buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5002) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5003) 	for(i=0;;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5004) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5005) 		copy_count = min_t(unsigned int, count, SCABUFSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5007) 		desc = &info->tx_buf_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5008) 		desc_ex = &info->tx_buf_list_ex[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5010) 		load_pci_memory(info, desc_ex->virt_addr,buf,copy_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5012) 		desc->length = copy_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5013) 		desc->status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5015) 		buf += copy_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5016) 		count -= copy_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5018) 		if (!count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5019) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5021) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5022) 		if (i >= info->tx_buf_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5023) 			i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5024) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5026) 	info->tx_buf_list[i].status = 0x81;	/* set EOM and EOT status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5027) 	info->last_tx_buf = ++i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5030) static bool register_test(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5031) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5032) 	static unsigned char testval[] = {0x00, 0xff, 0xaa, 0x55, 0x69, 0x96};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5033) 	static unsigned int count = ARRAY_SIZE(testval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5034) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5035) 	bool rc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5036) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5038) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5039) 	reset_port(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5041) 	/* assume failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5042) 	info->init_error = DiagStatus_AddressFailure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5044) 	/* Write bit patterns to various registers but do it out of */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5045) 	/* sync, then read back and verify values. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5047) 	for (i = 0 ; i < count ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5048) 		write_reg(info, TMC, testval[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5049) 		write_reg(info, IDL, testval[(i+1)%count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5050) 		write_reg(info, SA0, testval[(i+2)%count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5051) 		write_reg(info, SA1, testval[(i+3)%count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5053) 		if ( (read_reg(info, TMC) != testval[i]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5054) 			  (read_reg(info, IDL) != testval[(i+1)%count]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5055) 			  (read_reg(info, SA0) != testval[(i+2)%count]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5056) 			  (read_reg(info, SA1) != testval[(i+3)%count]) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5057) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5058) 			rc = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5059) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5060) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5061) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5063) 	reset_port(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5064) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5066) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5069) static bool irq_test(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5071) 	unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5072) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5074) 	unsigned char timer = (info->port_num & 1) ? TIMER2 : TIMER0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5076) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5077) 	reset_port(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5079) 	/* assume failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5080) 	info->init_error = DiagStatus_IrqFailure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5081) 	info->irq_occurred = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5083) 	/* setup timer0 on SCA0 to interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5085) 	/* IER2<7..4> = timer<3..0> interrupt enables (1=enabled) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5086) 	write_reg(info, IER2, (unsigned char)((info->port_num & 1) ? BIT6 : BIT4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5088) 	write_reg(info, (unsigned char)(timer + TEPR), 0);	/* timer expand prescale */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5089) 	write_reg16(info, (unsigned char)(timer + TCONR), 1);	/* timer constant */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5092) 	/* TMCS, Timer Control/Status Register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5093) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5094) 	 * 07      CMF, Compare match flag (read only) 1=match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5095) 	 * 06      ECMI, CMF Interrupt Enable: 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5096) 	 * 05      Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5097) 	 * 04      TME, Timer Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5098) 	 * 03..00  Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5099) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5100) 	 * 0101 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5101) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5102) 	write_reg(info, (unsigned char)(timer + TMCS), 0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5104) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5106) 	timeout=100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5107) 	while( timeout-- && !info->irq_occurred ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5108) 		msleep_interruptible(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5111) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5112) 	reset_port(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5113) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5115) 	return info->irq_occurred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5118) /* initialize individual SCA device (2 ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5119)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5120) static bool sca_init(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5122) 	/* set wait controller to single mem partition (low), no wait states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5123) 	write_reg(info, PABR0, 0);	/* wait controller addr boundary 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5124) 	write_reg(info, PABR1, 0);	/* wait controller addr boundary 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5125) 	write_reg(info, WCRL, 0);	/* wait controller low range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5126) 	write_reg(info, WCRM, 0);	/* wait controller mid range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5127) 	write_reg(info, WCRH, 0);	/* wait controller high range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5129) 	/* DPCR, DMA Priority Control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5130) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5131) 	 * 07..05  Not used, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5132) 	 * 04      BRC, bus release condition: 0=all transfers complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5133) 	 * 03      CCC, channel change condition: 0=every cycle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5134) 	 * 02..00  PR<2..0>, priority 100=round robin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5135) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5136) 	 * 00000100 = 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5137) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5138) 	write_reg(info, DPCR, dma_priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5140) 	/* DMA Master Enable, BIT7: 1=enable all channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5141) 	write_reg(info, DMER, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5143) 	/* enable all interrupt classes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5144) 	write_reg(info, IER0, 0xff);	/* TxRDY,RxRDY,TxINT,RxINT (ports 0-1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5145) 	write_reg(info, IER1, 0xff);	/* DMIB,DMIA (channels 0-3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5146) 	write_reg(info, IER2, 0xf0);	/* TIRQ (timers 0-3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5148) 	/* ITCR, interrupt control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5149) 	 * 07      IPC, interrupt priority, 0=MSCI->DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5150) 	 * 06..05  IAK<1..0>, Acknowledge cycle, 00=non-ack cycle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5151) 	 * 04      VOS, Vector Output, 0=unmodified vector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5152) 	 * 03..00  Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5153) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5154) 	write_reg(info, ITCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5156) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5159) /* initialize adapter hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5160)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5161) static bool init_adapter(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5163) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5165) 	/* Set BIT30 of Local Control Reg 0x50 to reset SCA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5166) 	volatile u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5167) 	u32 readval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5169) 	info->misc_ctrl_value |= BIT30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5170) 	*MiscCtrl = info->misc_ctrl_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5172) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5173) 	 * Force at least 170ns delay before clearing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5174) 	 * reset bit. Each read from LCR takes at least
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5175) 	 * 30ns so 10 times for 300ns to be safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5176) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5177) 	for(i=0;i<10;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5178) 		readval = *MiscCtrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5180) 	info->misc_ctrl_value &= ~BIT30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5181) 	*MiscCtrl = info->misc_ctrl_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5183) 	/* init control reg (all DTRs off, all clksel=input) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5184) 	info->ctrlreg_value = 0xaa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5185) 	write_control_reg(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5187) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5188) 		volatile u32 *LCR1BRDR = (u32 *)(info->lcr_base + 0x2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5189) 		lcr1_brdr_value &= ~(BIT5 + BIT4 + BIT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5191) 		switch(read_ahead_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5192) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5193) 		case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5194) 			lcr1_brdr_value |= BIT5 + BIT4 + BIT3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5195) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5196) 		case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5197) 			lcr1_brdr_value |= BIT5 + BIT4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5198) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5199) 		case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5200) 			lcr1_brdr_value |= BIT5 + BIT3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5201) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5202) 		case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5203) 			lcr1_brdr_value |= BIT5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5204) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5205) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5207) 		*LCR1BRDR = lcr1_brdr_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5208) 		*MiscCtrl = misc_ctrl_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5209) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5211) 	sca_init(info->port_array[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5212) 	sca_init(info->port_array[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5214) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5217) /* Loopback an HDLC frame to test the hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5218)  * interrupt and DMA functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5219)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5220) static bool loopback_test(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5222) #define TESTFRAMESIZE 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5224) 	unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5225) 	u16 count = TESTFRAMESIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5226) 	unsigned char buf[TESTFRAMESIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5227) 	bool rc = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5228) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5230) 	struct tty_struct *oldtty = info->port.tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5231) 	u32 speed = info->params.clock_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5233) 	info->params.clock_speed = 3686400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5234) 	info->port.tty = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5236) 	/* assume failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5237) 	info->init_error = DiagStatus_DmaFailure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5239) 	/* build and send transmit frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5240) 	for (count = 0; count < TESTFRAMESIZE;++count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5241) 		buf[count] = (unsigned char)count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5243) 	memset(info->tmp_rx_buf,0,TESTFRAMESIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5245) 	/* program hardware for HDLC and enabled receiver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5246) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5247) 	hdlc_mode(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5248) 	enable_loopback(info,1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5249)        	rx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5250) 	info->tx_count = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5251) 	tx_load_dma_buffer(info,buf,count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5252) 	tx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5253) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5255) 	/* wait for receive complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5256) 	/* Set a timeout for waiting for interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5257) 	for ( timeout = 100; timeout; --timeout ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5258) 		msleep_interruptible(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5260) 		if (rx_get_frame(info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5261) 			rc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5262) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5263) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5264) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5266) 	/* verify received frame length and contents */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5267) 	if (rc &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5268) 	    ( info->tmp_rx_buf_count != count ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5269) 	      memcmp(buf, info->tmp_rx_buf,count))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5270) 		rc = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5271) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5273) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5274) 	reset_adapter(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5275) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5277) 	info->params.clock_speed = speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5278) 	info->port.tty = oldtty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5280) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5283) /* Perform diagnostics on hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5284)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5285) static int adapter_test( SLMP_INFO *info )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5287) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5288) 	if ( debug_level >= DEBUG_LEVEL_INFO )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5289) 		printk( "%s(%d):Testing device %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5290) 			__FILE__,__LINE__,info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5292) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5293) 	init_adapter(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5294) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5296) 	info->port_array[0]->port_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5298) 	if ( register_test(info->port_array[0]) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5299) 		register_test(info->port_array[1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5301) 		info->port_array[0]->port_count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5303) 		if ( register_test(info->port_array[2]) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5304) 			register_test(info->port_array[3]) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5305) 			info->port_array[0]->port_count += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5306) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5307) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5308) 		printk( "%s(%d):Register test failure for device %s Addr=%08lX\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5309) 			__FILE__,__LINE__,info->device_name, (unsigned long)(info->phys_sca_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5310) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5311) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5313) 	if ( !irq_test(info->port_array[0]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5314) 		!irq_test(info->port_array[1]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5315) 		 (info->port_count == 4 && !irq_test(info->port_array[2])) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5316) 		 (info->port_count == 4 && !irq_test(info->port_array[3]))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5317) 		printk( "%s(%d):Interrupt test failure for device %s IRQ=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5318) 			__FILE__,__LINE__,info->device_name, (unsigned short)(info->irq_level) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5319) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5320) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5322) 	if (!loopback_test(info->port_array[0]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5323) 		!loopback_test(info->port_array[1]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5324) 		 (info->port_count == 4 && !loopback_test(info->port_array[2])) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5325) 		 (info->port_count == 4 && !loopback_test(info->port_array[3]))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5326) 		printk( "%s(%d):DMA test failure for device %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5327) 			__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5328) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5329) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5331) 	if ( debug_level >= DEBUG_LEVEL_INFO )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5332) 		printk( "%s(%d):device %s passed diagnostics\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5333) 			__FILE__,__LINE__,info->device_name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5335) 	info->port_array[0]->init_error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5336) 	info->port_array[1]->init_error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5337) 	if ( info->port_count > 2 ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5338) 		info->port_array[2]->init_error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5339) 		info->port_array[3]->init_error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5342) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5345) /* Test the shared memory on a PCI adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5346)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5347) static bool memory_test(SLMP_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5349) 	static unsigned long testval[] = { 0x0, 0x55555555, 0xaaaaaaaa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5350) 		0x66666666, 0x99999999, 0xffffffff, 0x12345678 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5351) 	unsigned long count = ARRAY_SIZE(testval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5352) 	unsigned long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5353) 	unsigned long limit = SCA_MEM_SIZE/sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5354) 	unsigned long * addr = (unsigned long *)info->memory_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5356) 	/* Test data lines with test pattern at one location. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5358) 	for ( i = 0 ; i < count ; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5359) 		*addr = testval[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5360) 		if ( *addr != testval[i] )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5361) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5362) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5364) 	/* Test address lines with incrementing pattern over */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5365) 	/* entire address range. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5367) 	for ( i = 0 ; i < limit ; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5368) 		*addr = i * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5369) 		addr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5370) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5372) 	addr = (unsigned long *)info->memory_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5374) 	for ( i = 0 ; i < limit ; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5375) 		if ( *addr != i * 4 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5376) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5377) 		addr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5378) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5380) 	memset( info->memory_base, 0, SCA_MEM_SIZE );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5381) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5384) /* Load data into PCI adapter shared memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5385)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5386)  * The PCI9050 releases control of the local bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5387)  * after completing the current read or write operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5388)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5389)  * While the PCI9050 write FIFO not empty, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5390)  * PCI9050 treats all of the writes as a single transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5391)  * and does not release the bus. This causes DMA latency problems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5392)  * at high speeds when copying large data blocks to the shared memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5393)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5394)  * This function breaks a write into multiple transations by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5395)  * interleaving a read which flushes the write FIFO and 'completes'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5396)  * the write transation. This allows any pending DMA request to gain control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5397)  * of the local bus in a timely fasion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5398)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5399) static void load_pci_memory(SLMP_INFO *info, char* dest, const char* src, unsigned short count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5401) 	/* A load interval of 16 allows for 4 32-bit writes at */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5402) 	/* 136ns each for a maximum latency of 542ns on the local bus.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5404) 	unsigned short interval = count / sca_pci_load_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5405) 	unsigned short i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5407) 	for ( i = 0 ; i < interval ; i++ )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5408) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5409) 		memcpy(dest, src, sca_pci_load_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5410) 		read_status_reg(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5411) 		dest += sca_pci_load_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5412) 		src += sca_pci_load_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5413) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5415) 	memcpy(dest, src, count % sca_pci_load_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5418) static void trace_block(SLMP_INFO *info,const char* data, int count, int xmit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5420) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5421) 	int linecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5422) 	if (xmit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5423) 		printk("%s tx data:\n",info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5424) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5425) 		printk("%s rx data:\n",info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5427) 	while(count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5428) 		if (count > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5429) 			linecount = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5430) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5431) 			linecount = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5433) 		for(i=0;i<linecount;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5434) 			printk("%02X ",(unsigned char)data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5435) 		for(;i<17;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5436) 			printk("   ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5437) 		for(i=0;i<linecount;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5438) 			if (data[i]>=040 && data[i]<=0176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5439) 				printk("%c",data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5440) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5441) 				printk(".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5442) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5443) 		printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5445) 		data  += linecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5446) 		count -= linecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5447) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5448) }	/* end of trace_block() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5450) /* called when HDLC frame times out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5451)  * update stats and do tx completion processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5452)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5453) static void tx_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5455) 	SLMP_INFO *info = from_timer(info, t, tx_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5456) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5458) 	if ( debug_level >= DEBUG_LEVEL_INFO )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5459) 		printk( "%s(%d):%s tx_timeout()\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5460) 			__FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5461) 	if(info->tx_active && info->params.mode == MGSL_MODE_HDLC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5462) 		info->icount.txtimeout++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5463) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5464) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5465) 	info->tx_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5466) 	info->tx_count = info->tx_put = info->tx_get = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5468) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5470) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5471) 	if (info->netcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5472) 		hdlcdev_tx_done(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5473) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5474) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5475) 		bh_transmit(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5478) /* called to periodically check the DSR/RI modem signal input status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5479)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5480) static void status_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5482) 	u16 status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5483) 	SLMP_INFO *info = from_timer(info, t, status_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5484) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5485) 	unsigned char delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5488) 	spin_lock_irqsave(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5489) 	get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5490) 	spin_unlock_irqrestore(&info->lock,flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5492) 	/* check for DSR/RI state change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5494) 	delta = info->old_signals ^ info->serial_signals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5495) 	info->old_signals = info->serial_signals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5497) 	if (delta & SerialSignal_DSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5498) 		status |= MISCSTATUS_DSR_LATCHED|(info->serial_signals&SerialSignal_DSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5500) 	if (delta & SerialSignal_RI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5501) 		status |= MISCSTATUS_RI_LATCHED|(info->serial_signals&SerialSignal_RI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5503) 	if (delta & SerialSignal_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5504) 		status |= MISCSTATUS_DCD_LATCHED|(info->serial_signals&SerialSignal_DCD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5506) 	if (delta & SerialSignal_CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5507) 		status |= MISCSTATUS_CTS_LATCHED|(info->serial_signals&SerialSignal_CTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5509) 	if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5510) 		isr_io_pin(info,status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5512) 	mod_timer(&info->status_timer, jiffies + msecs_to_jiffies(10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5516) /* Register Access Routines -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5517)  * All registers are memory mapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5518)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5519) #define CALC_REGADDR() \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5520) 	unsigned char * RegAddr = (unsigned char*)(info->sca_base + Addr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5521) 	if (info->port_num > 1) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5522) 		RegAddr += 256;	    		/* port 0-1 SCA0, 2-3 SCA1 */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5523) 	if ( info->port_num & 1) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5524) 		if (Addr > 0x7f) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5525) 			RegAddr += 0x40;	/* DMA access */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5526) 		else if (Addr > 0x1f && Addr < 0x60) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5527) 			RegAddr += 0x20;	/* MSCI access */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5531) static unsigned char read_reg(SLMP_INFO * info, unsigned char Addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5533) 	CALC_REGADDR();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5534) 	return *RegAddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5536) static void write_reg(SLMP_INFO * info, unsigned char Addr, unsigned char Value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5538) 	CALC_REGADDR();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5539) 	*RegAddr = Value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5542) static u16 read_reg16(SLMP_INFO * info, unsigned char Addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5544) 	CALC_REGADDR();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5545) 	return *((u16 *)RegAddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5548) static void write_reg16(SLMP_INFO * info, unsigned char Addr, u16 Value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5550) 	CALC_REGADDR();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5551) 	*((u16 *)RegAddr) = Value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5554) static unsigned char read_status_reg(SLMP_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5556) 	unsigned char *RegAddr = (unsigned char *)info->statctrl_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5557) 	return *RegAddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5560) static void write_control_reg(SLMP_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5562) 	unsigned char *RegAddr = (unsigned char *)info->statctrl_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5563) 	*RegAddr = info->port_array[0]->ctrlreg_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5567) static int synclinkmp_init_one (struct pci_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5568) 					  const struct pci_device_id *ent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5570) 	if (pci_enable_device(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5571) 		printk("error enabling pci device %p\n", dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5572) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5573) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5574) 	return device_init( ++synclinkmp_adapter_count, dev );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5577) static void synclinkmp_remove_one (struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5579) }