^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) }