^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * linux/drivers/char/pcmcia/synclink_cs.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * $Id: synclink_cs.c,v 4.34 2005/09/08 13:20:54 paulkf Exp $
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Device driver for Microgate SyncLink PC Card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * multiprotocol serial adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * written by Paul Fulghum for Microgate Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * paulkf@microgate.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Microgate and SyncLink are trademarks of Microgate Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * This code is released under the GNU General Public License (GPL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define VERSION(ver,rel,seq) (((ver)<<16) | ((rel)<<8) | (seq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #if defined(__i386__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) # define BREAKPOINT() asm(" int $3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) # define BREAKPOINT() { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define MAX_DEVICE_COUNT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/major.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include <linux/ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include <linux/synclink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #include <asm/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #include <linux/termios.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #include <linux/hdlc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #include <pcmcia/cistpl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #include <pcmcia/cisreg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #include <pcmcia/ds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_CS_MODULE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SYNCLINK_GENERIC_HDLC 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define SYNCLINK_GENERIC_HDLC 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define GET_USER(error,value,addr) error = get_user(value,addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #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 84) #define PUT_USER(error,value,addr) error = put_user(value,addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #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 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static MGSL_PARAMS default_params = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) MGSL_MODE_HDLC, /* unsigned long mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) 0, /* unsigned char loopback; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) HDLC_FLAG_UNDERRUN_ABORT15, /* unsigned short flags; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) HDLC_ENCODING_NRZI_SPACE, /* unsigned char encoding; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) 0, /* unsigned long clock_speed; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) 0xff, /* unsigned char addr_filter; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) HDLC_CRC_16_CCITT, /* unsigned short crc_type; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) HDLC_PREAMBLE_LENGTH_8BITS, /* unsigned char preamble_length; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) HDLC_PREAMBLE_PATTERN_NONE, /* unsigned char preamble; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) 9600, /* unsigned long data_rate; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 8, /* unsigned char data_bits; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 1, /* unsigned char stop_bits; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ASYNC_PARITY_NONE /* unsigned char parity; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) unsigned char status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) char data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) } RXBUF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* The queue of BH actions to be performed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define BH_RECEIVE 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define BH_TRANSMIT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define BH_STATUS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define IO_PIN_SHUTDOWN_LIMIT 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct _input_signal_events {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int ri_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int ri_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int dsr_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int dsr_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int dcd_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int dcd_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int cts_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int cts_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * Device instance data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) typedef struct _mgslpc_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct tty_port port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) void *if_ptr; /* General purpose pointer (used by SPPP) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct mgsl_icount icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int x_char; /* xon/xoff character */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) unsigned char read_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unsigned char ignore_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) unsigned char *tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) int tx_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int tx_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) int tx_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* circular list of fixed length rx buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) unsigned char *rx_buf; /* memory allocated for all rx buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int rx_buf_total_size; /* size of memory allocated for rx buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int rx_put; /* index of next empty rx buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int rx_get; /* index of next full rx buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int rx_buf_size; /* size in bytes of single rx buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) int rx_buf_count; /* total number of rx buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int rx_frame_count; /* number of full rx buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) wait_queue_head_t status_event_wait_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) wait_queue_head_t event_wait_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct timer_list tx_timer; /* HDLC transmit timeout timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct _mgslpc_info *next_device; /* device list link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) unsigned short imra_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) unsigned short imrb_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) unsigned char pim_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct work_struct task; /* task structure for scheduling bh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u32 max_frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u32 pending_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) bool bh_running;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) bool bh_requested;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int dcd_chkcount; /* check counts to prevent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) int cts_chkcount; /* too many IRQs if a signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int dsr_chkcount; /* is floating */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int ri_chkcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) bool rx_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) bool rx_overflow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) bool tx_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) bool tx_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) bool tx_aborting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u32 idle_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int if_mode; /* serial interface selection (RS-232, v.35 etc) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) char device_name[25]; /* device instance name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) unsigned int io_base; /* base I/O address of adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) unsigned int irq_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) MGSL_PARAMS params; /* communications parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) unsigned char serial_signals; /* current serial signal states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) bool irq_occurred; /* for diagnostics use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) char testing_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) unsigned int init_error; /* startup error (DIAGS) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) char *flag_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) bool drop_rts_on_tx_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct _input_signal_events input_signal_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* PCMCIA support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct pcmcia_device *p_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) int stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /* SPPP/Cisco HDLC device parts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) int netcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) spinlock_t netlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct net_device *netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) } MGSLPC_INFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #define MGSLPC_MAGIC 0x5402
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * The size of the serial xmit buffer is 1 page, or 4096 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) #define TXBUFSIZE 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #define CHA 0x00 /* channel A offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #define CHB 0x40 /* channel B offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * FIXME: PPC has PVR defined in asm/reg.h. For now we just undef it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #undef PVR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #define RXFIFO 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #define TXFIFO 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define STAR 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) #define CMDR 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) #define RSTA 0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) #define PRE 0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #define MODE 0x22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #define TIMR 0x23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) #define XAD1 0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) #define XAD2 0x25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) #define RAH1 0x26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #define RAH2 0x27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) #define DAFO 0x27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) #define RAL1 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) #define RFC 0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) #define RHCR 0x29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #define RAL2 0x29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #define RBCL 0x2a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) #define XBCL 0x2a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) #define RBCH 0x2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) #define XBCH 0x2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #define CCR0 0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) #define CCR1 0x2d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #define CCR2 0x2e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) #define CCR3 0x2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) #define VSTR 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #define BGR 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #define RLCR 0x35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) #define AML 0x36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #define AMH 0x37
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) #define GIS 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #define IVA 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #define IPC 0x39
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) #define ISR 0x3a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) #define IMR 0x3a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) #define PVR 0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) #define PIS 0x3d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #define PIM 0x3d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #define PCR 0x3e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) #define CCR4 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) // IMR/ISR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #define IRQ_BREAK_ON BIT15 // rx break detected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) #define IRQ_DATAOVERRUN BIT14 // receive data overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) #define IRQ_ALLSENT BIT13 // all sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) #define IRQ_UNDERRUN BIT12 // transmit data underrun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) #define IRQ_TIMER BIT11 // timer interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) #define IRQ_CTS BIT10 // CTS status change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) #define IRQ_TXREPEAT BIT9 // tx message repeat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) #define IRQ_TXFIFO BIT8 // transmit pool ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) #define IRQ_RXEOM BIT7 // receive message end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) #define IRQ_EXITHUNT BIT6 // receive frame start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) #define IRQ_RXTIME BIT6 // rx char timeout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) #define IRQ_DCD BIT2 // carrier detect status change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) #define IRQ_OVERRUN BIT1 // receive frame overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) #define IRQ_RXFIFO BIT0 // receive pool full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) // STAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) #define XFW BIT6 // transmit FIFO write enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) #define CEC BIT2 // command executing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) #define CTS BIT1 // CTS state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) #define PVR_DTR BIT0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) #define PVR_DSR BIT1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) #define PVR_RI BIT2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) #define PVR_AUTOCTS BIT3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) #define PVR_RS232 0x20 /* 0010b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) #define PVR_V35 0xe0 /* 1110b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) #define PVR_RS422 0x40 /* 0100b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* Register access functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) #define write_reg(info, reg, val) outb((val),(info)->io_base + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) #define read_reg(info, reg) inb((info)->io_base + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) #define read_reg16(info, reg) inw((info)->io_base + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) #define write_reg16(info, reg, val) outw((val), (info)->io_base + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) #define set_reg_bits(info, reg, mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) write_reg(info, (reg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) (unsigned char) (read_reg(info, (reg)) | (mask)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) #define clear_reg_bits(info, reg, mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) write_reg(info, (reg), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) (unsigned char) (read_reg(info, (reg)) & ~(mask)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * interrupt enable/disable routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static void irq_disable(MGSLPC_INFO *info, unsigned char channel, unsigned short mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (channel == CHA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) info->imra_value |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) write_reg16(info, CHA + IMR, info->imra_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) info->imrb_value |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) write_reg16(info, CHB + IMR, info->imrb_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static void irq_enable(MGSLPC_INFO *info, unsigned char channel, unsigned short mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (channel == CHA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) info->imra_value &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) write_reg16(info, CHA + IMR, info->imra_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) info->imrb_value &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) write_reg16(info, CHB + IMR, info->imrb_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) #define port_irq_disable(info, mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) { info->pim_value |= (mask); write_reg(info, PIM, info->pim_value); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) #define port_irq_enable(info, mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) { info->pim_value &= ~(mask); write_reg(info, PIM, info->pim_value); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static void rx_start(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static void rx_stop(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static void tx_start(MGSLPC_INFO *info, struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static void tx_stop(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static void tx_set_idle(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static void get_signals(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static void set_signals(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static void reset_device(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static void hdlc_mode(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) static void async_mode(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static void tx_timeout(struct timer_list *t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static int carrier_raised(struct tty_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static void dtr_rts(struct tty_port *port, int onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) #define dev_to_port(D) (dev_to_hdlc(D)->priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static void hdlcdev_tx_done(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static int hdlcdev_init(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static void hdlcdev_exit(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static void trace_block(MGSLPC_INFO *info,const char* data, int count, int xmit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static bool register_test(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static bool irq_test(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static int adapter_test(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) static int claim_resources(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static void release_resources(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static int mgslpc_add_device(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static void mgslpc_remove_device(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static bool rx_get_frame(MGSLPC_INFO *info, struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static void rx_reset_buffers(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static int rx_alloc_buffers(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static void rx_free_buffers(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static irqreturn_t mgslpc_isr(int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * Bottom half interrupt handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static void bh_handler(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static void bh_transmit(MGSLPC_INFO *info, struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static void bh_status(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * ioctl handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static int tiocmget(struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static int tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) unsigned int set, unsigned int clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static int get_stats(MGSLPC_INFO *info, struct mgsl_icount __user *user_icount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static int get_params(MGSLPC_INFO *info, MGSL_PARAMS __user *user_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static int set_params(MGSLPC_INFO *info, MGSL_PARAMS __user *new_params, struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static int get_txidle(MGSLPC_INFO *info, int __user *idle_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static int set_txidle(MGSLPC_INFO *info, int idle_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static int set_txenable(MGSLPC_INFO *info, int enable, struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static int tx_abort(MGSLPC_INFO *info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) static int set_rxenable(MGSLPC_INFO *info, int enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static int wait_events(MGSLPC_INFO *info, int __user *mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static MGSLPC_INFO *mgslpc_device_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static int mgslpc_device_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * Set this param to non-zero to load eax with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * .text section address and breakpoint on module load.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * This is useful for use with gdb and add-symbol-file command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static bool break_on_load;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * Driver major number, defaults to zero to get auto
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * assigned major number. May be forced as module parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static int ttymajor=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static int debug_level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static int maxframe[MAX_DEVICE_COUNT] = {0,};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) module_param(break_on_load, bool, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) module_param(ttymajor, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) module_param(debug_level, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) module_param_array(maxframe, int, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) static char *driver_name = "SyncLink PC Card driver";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static char *driver_version = "$Revision: 4.34 $";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) static struct tty_driver *serial_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* number of characters left in xmit buffer before we ask for more */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) #define WAKEUP_CHARS 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static void mgslpc_change_params(MGSLPC_INFO *info, struct tty_struct *tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) /* PCMCIA prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static int mgslpc_config(struct pcmcia_device *link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) static void mgslpc_release(u_long arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static void mgslpc_detach(struct pcmcia_device *p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * 1st function defined in .text section. Calling this function in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * init_module() followed by a breakpoint allows a remote debugger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * (gdb) to get the .text address for the add-symbol-file command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * This allows remote debugging of dynamically loadable modules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static void* mgslpc_get_text_ptr(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return mgslpc_get_text_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * line discipline callback wrappers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * The wrappers maintain line discipline references
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * while calling into the line discipline.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * ldisc_receive_buf - pass receive data to line discipline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static void ldisc_receive_buf(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) const __u8 *data, char *flags, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) struct tty_ldisc *ld;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (!tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ld = tty_ldisc_ref(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (ld) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (ld->ops->receive_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ld->ops->receive_buf(tty, data, flags, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) tty_ldisc_deref(ld);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static const struct tty_port_operations mgslpc_port_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) .carrier_raised = carrier_raised,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) .dtr_rts = dtr_rts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static int mgslpc_probe(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) MGSLPC_INFO *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) printk("mgslpc_attach\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) info = kzalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (!info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) printk("Error can't allocate device instance data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) info->magic = MGSLPC_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) tty_port_init(&info->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) info->port.ops = &mgslpc_port_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) INIT_WORK(&info->task, bh_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) info->max_frame_size = 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) info->port.close_delay = 5*HZ/10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) info->port.closing_wait = 30*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) init_waitqueue_head(&info->status_event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) init_waitqueue_head(&info->event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) spin_lock_init(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) spin_lock_init(&info->netlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) info->idle_mode = HDLC_TXIDLE_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) info->imra_value = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) info->imrb_value = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) info->pim_value = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) info->p_dev = link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) link->priv = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* Initialize the struct pcmcia_device structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ret = mgslpc_config(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ret = mgslpc_add_device(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) goto failed_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) failed_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) mgslpc_release((u_long)link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) tty_port_destroy(&info->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) kfree(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) /* Card has been inserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static int mgslpc_ioprobe(struct pcmcia_device *p_dev, void *priv_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return pcmcia_request_io(p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static int mgslpc_config(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) MGSLPC_INFO *info = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) printk("mgslpc_config(0x%p)\n", link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) link->config_index = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) link->config_regs = PRESENT_OPTION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ret = pcmcia_request_irq(link, mgslpc_isr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) ret = pcmcia_enable_device(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) info->io_base = link->resource[0]->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) info->irq_level = link->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) mgslpc_release((u_long)link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /* Card has been removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * Unregister device and release PCMCIA configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * If device is open, postpone until it is closed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static void mgslpc_release(u_long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct pcmcia_device *link = (struct pcmcia_device *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) printk("mgslpc_release(0x%p)\n", link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) pcmcia_disable_device(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static void mgslpc_detach(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) printk("mgslpc_detach(0x%p)\n", link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) ((MGSLPC_INFO *)link->priv)->stop = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) mgslpc_release((u_long)link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) mgslpc_remove_device((MGSLPC_INFO *)link->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static int mgslpc_suspend(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) MGSLPC_INFO *info = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) info->stop = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static int mgslpc_resume(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) MGSLPC_INFO *info = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) info->stop = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static inline bool mgslpc_paranoia_check(MGSLPC_INFO *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) char *name, const char *routine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) #ifdef MGSLPC_PARANOIA_CHECK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static const char *badmagic =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) "Warning: bad magic number for mgsl struct (%s) in %s\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) static const char *badinfo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) "Warning: null mgslpc_info for (%s) in %s\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (!info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) printk(badinfo, name, routine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (info->magic != MGSLPC_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) printk(badmagic, name, routine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) #define CMD_RXFIFO BIT7 // release current rx FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) #define CMD_RXRESET BIT6 // receiver reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) #define CMD_RXFIFO_READ BIT5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) #define CMD_START_TIMER BIT4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) #define CMD_TXFIFO BIT3 // release current tx FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) #define CMD_TXEOM BIT1 // transmit end message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) #define CMD_TXRESET BIT0 // transmit reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static bool wait_command_complete(MGSLPC_INFO *info, unsigned char channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) /* wait for command completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) while (read_reg(info, (unsigned char)(channel+STAR)) & BIT2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (i++ == 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static void issue_command(MGSLPC_INFO *info, unsigned char channel, unsigned char cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) wait_command_complete(info, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) write_reg(info, (unsigned char) (channel + CMDR), cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static void tx_pause(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (mgslpc_paranoia_check(info, tty->name, "tx_pause"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) printk("tx_pause(%s)\n", info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (info->tx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) static void tx_release(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (mgslpc_paranoia_check(info, tty->name, "tx_release"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) printk("tx_release(%s)\n", info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (!info->tx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) tx_start(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) spin_unlock_irqrestore(&info->lock, flags);
^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) /* Return next bottom half action to perform.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) * or 0 if nothing to do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) static int bh_action(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (info->pending_bh & BH_RECEIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) info->pending_bh &= ~BH_RECEIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) rc = BH_RECEIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) } else if (info->pending_bh & BH_TRANSMIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) info->pending_bh &= ~BH_TRANSMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) rc = BH_TRANSMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) } else if (info->pending_bh & BH_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) info->pending_bh &= ~BH_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) rc = BH_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) /* Mark BH routine as complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) info->bh_running = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) info->bh_requested = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) static void bh_handler(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) MGSLPC_INFO *info = container_of(work, MGSLPC_INFO, task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) int action;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (debug_level >= DEBUG_LEVEL_BH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) printk("%s(%d):bh_handler(%s) entry\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) __FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) info->bh_running = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) tty = tty_port_tty_get(&info->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) while((action = bh_action(info)) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /* Process work item */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (debug_level >= DEBUG_LEVEL_BH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) printk("%s(%d):bh_handler() work item action=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) __FILE__,__LINE__,action);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) switch (action) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) case BH_RECEIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) while(rx_get_frame(info, tty));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) case BH_TRANSMIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) bh_transmit(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) case BH_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) bh_status(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) /* unknown work item ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) printk("Unknown work item ID=%08X!\n", action);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (debug_level >= DEBUG_LEVEL_BH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) printk("%s(%d):bh_handler(%s) exit\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) __FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static void bh_transmit(MGSLPC_INFO *info, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (debug_level >= DEBUG_LEVEL_BH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) printk("bh_transmit() entry on %s\n", info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) tty_wakeup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) static void bh_status(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) info->ri_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) info->dsr_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) info->dcd_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) info->cts_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /* eom: non-zero = end of frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) static void rx_ready_hdlc(MGSLPC_INFO *info, int eom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) unsigned char data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) unsigned char fifo_count, read_count, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) RXBUF *buf = (RXBUF*)(info->rx_buf + (info->rx_put * info->rx_buf_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) printk("%s(%d):rx_ready_hdlc(eom=%d)\n", __FILE__, __LINE__, eom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (!info->rx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (info->rx_frame_count >= info->rx_buf_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) /* no more free buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) issue_command(info, CHA, CMD_RXRESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) info->pending_bh |= BH_RECEIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) info->rx_overflow = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) info->icount.buf_overrun++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (eom) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /* end of frame, get FIFO count from RBCL register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) fifo_count = (unsigned char)(read_reg(info, CHA+RBCL) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (fifo_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) fifo_count = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) fifo_count = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (fifo_count == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) read_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) data[0] = read_reg(info, CHA + RXFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) read_count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) *((unsigned short *) data) = read_reg16(info, CHA + RXFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) fifo_count -= read_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (!fifo_count && eom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) buf->status = data[--read_count];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) for (i = 0; i < read_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (buf->count >= info->max_frame_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /* frame too large, reset receiver and reset current buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) issue_command(info, CHA, CMD_RXRESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) buf->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) *(buf->data + buf->count) = data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) buf->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) } while (fifo_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (eom) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) info->pending_bh |= BH_RECEIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) info->rx_frame_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) info->rx_put++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (info->rx_put >= info->rx_buf_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) info->rx_put = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) issue_command(info, CHA, CMD_RXFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) static void rx_ready_async(MGSLPC_INFO *info, int tcd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) struct tty_port *port = &info->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) unsigned char data, status, flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) int fifo_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) int work = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) struct mgsl_icount *icount = &info->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (tcd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) /* early termination, get FIFO count from RBCL register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) fifo_count = (unsigned char)(read_reg(info, CHA+RBCL) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /* Zero fifo count could mean 0 or 32 bytes available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * If BIT5 of STAR is set then at least 1 byte is available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (!fifo_count && (read_reg(info,CHA+STAR) & BIT5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) fifo_count = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) fifo_count = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) tty_buffer_request_room(port, fifo_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) /* Flush received async data to receive data buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) while (fifo_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) data = read_reg(info, CHA + RXFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) status = read_reg(info, CHA + RXFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) fifo_count -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) icount->rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) flag = TTY_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) // if no frameing/crc error then save data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) // BIT7:parity error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) // BIT6:framing error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (status & (BIT7 + BIT6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (status & BIT7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) icount->parity++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) icount->frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /* discard char if tty control flags say so */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (status & info->ignore_status_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) status &= info->read_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (status & BIT7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) flag = TTY_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) else if (status & BIT6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) flag = TTY_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) work += tty_insert_flip_char(port, data, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) issue_command(info, CHA, CMD_RXFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (debug_level >= DEBUG_LEVEL_ISR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) printk("%s(%d):rx_ready_async",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) __FILE__,__LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) __FILE__,__LINE__,icount->rx,icount->brk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) icount->parity,icount->frame,icount->overrun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) tty_flip_buffer_push(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) static void tx_done(MGSLPC_INFO *info, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (!info->tx_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) info->tx_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) info->tx_aborting = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (info->params.mode == MGSL_MODE_ASYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) info->tx_count = info->tx_put = info->tx_get = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) del_timer(&info->tx_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (info->drop_rts_on_tx_done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (info->serial_signals & SerialSignal_RTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) info->serial_signals &= ~SerialSignal_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) info->drop_rts_on_tx_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (info->netcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) hdlcdev_tx_done(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (tty && (tty->stopped || tty->hw_stopped)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) info->pending_bh |= BH_TRANSMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static void tx_ready(MGSLPC_INFO *info, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) unsigned char fifo_count = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) printk("%s(%d):tx_ready(%s)\n", __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (info->params.mode == MGSL_MODE_HDLC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (!info->tx_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (tty && (tty->stopped || tty->hw_stopped)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (!info->tx_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) info->tx_active = false;
^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) if (!info->tx_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) while (info->tx_count && fifo_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) c = min(2, min_t(int, fifo_count, min(info->tx_count, TXBUFSIZE - info->tx_get)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (c == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) write_reg(info, CHA + TXFIFO, *(info->tx_buf + info->tx_get));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) write_reg16(info, CHA + TXFIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) *((unsigned short*)(info->tx_buf + info->tx_get)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) info->tx_count -= c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) info->tx_get = (info->tx_get + c) & (TXBUFSIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) fifo_count -= c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (info->params.mode == MGSL_MODE_ASYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (info->tx_count < WAKEUP_CHARS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) info->pending_bh |= BH_TRANSMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) issue_command(info, CHA, CMD_TXFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (info->tx_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) issue_command(info, CHA, CMD_TXFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) issue_command(info, CHA, CMD_TXFIFO + CMD_TXEOM);
^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) static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if ((info->cts_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) irq_disable(info, CHB, IRQ_CTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) info->icount.cts++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (info->serial_signals & SerialSignal_CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) info->input_signal_events.cts_up++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) info->input_signal_events.cts_down++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) wake_up_interruptible(&info->status_event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) wake_up_interruptible(&info->event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (tty && tty_port_cts_enabled(&info->port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (tty->hw_stopped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) if (info->serial_signals & SerialSignal_CTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) printk("CTS tx start...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) tty->hw_stopped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) tx_start(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) info->pending_bh |= BH_TRANSMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (!(info->serial_signals & SerialSignal_CTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) printk("CTS tx stop...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) tty->hw_stopped = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) info->pending_bh |= BH_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) static void dcd_change(MGSLPC_INFO *info, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if ((info->dcd_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) irq_disable(info, CHB, IRQ_DCD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) info->icount.dcd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (info->serial_signals & SerialSignal_DCD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) info->input_signal_events.dcd_up++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) info->input_signal_events.dcd_down++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (info->netcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (info->serial_signals & SerialSignal_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) netif_carrier_on(info->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) netif_carrier_off(info->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) wake_up_interruptible(&info->status_event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) wake_up_interruptible(&info->event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (tty_port_check_carrier(&info->port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) printk("%s CD now %s...", info->device_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) (info->serial_signals & SerialSignal_DCD) ? "on" : "off");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (info->serial_signals & SerialSignal_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) wake_up_interruptible(&info->port.open_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) printk("doing serial hangup...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) tty_hangup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) info->pending_bh |= BH_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) static void dsr_change(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if ((info->dsr_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) port_irq_disable(info, PVR_DSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) info->icount.dsr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (info->serial_signals & SerialSignal_DSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) info->input_signal_events.dsr_up++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) info->input_signal_events.dsr_down++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) wake_up_interruptible(&info->status_event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) wake_up_interruptible(&info->event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) info->pending_bh |= BH_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static void ri_change(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if ((info->ri_chkcount)++ >= IO_PIN_SHUTDOWN_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) port_irq_disable(info, PVR_RI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) info->icount.rng++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (info->serial_signals & SerialSignal_RI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) info->input_signal_events.ri_up++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) info->input_signal_events.ri_down++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) wake_up_interruptible(&info->status_event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) wake_up_interruptible(&info->event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) info->pending_bh |= BH_STATUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) /* Interrupt service routine entry point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) * Arguments:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) * irq interrupt number that caused interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) * dev_id device ID supplied during interrupt registration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) static irqreturn_t mgslpc_isr(int dummy, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) MGSLPC_INFO *info = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) unsigned short isr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) unsigned char gis, pis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) int count=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) printk("mgslpc_isr(%d) entry.\n", info->irq_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (!(info->p_dev->_locked))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) tty = tty_port_tty_get(&info->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) spin_lock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) while ((gis = read_reg(info, CHA + GIS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) printk("mgslpc_isr %s gis=%04X\n", info->device_name,gis);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if ((gis & 0x70) || count > 1000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) printk("synclink_cs:hardware failed or ejected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (gis & (BIT1 | BIT0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) isr = read_reg16(info, CHB + ISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) if (isr & IRQ_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) dcd_change(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (isr & IRQ_CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) cts_change(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (gis & (BIT3 | BIT2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) isr = read_reg16(info, CHA + ISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) if (isr & IRQ_TIMER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) info->irq_occurred = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) irq_disable(info, CHA, IRQ_TIMER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) /* receive IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (isr & IRQ_EXITHUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) info->icount.exithunt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) wake_up_interruptible(&info->event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (isr & IRQ_BREAK_ON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) info->icount.brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) if (info->port.flags & ASYNC_SAK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) do_SAK(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) if (isr & IRQ_RXTIME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) issue_command(info, CHA, CMD_RXFIFO_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (isr & (IRQ_RXEOM | IRQ_RXFIFO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) if (info->params.mode == MGSL_MODE_HDLC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) rx_ready_hdlc(info, isr & IRQ_RXEOM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) rx_ready_async(info, isr & IRQ_RXEOM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) /* transmit IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) if (isr & IRQ_UNDERRUN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) if (info->tx_aborting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) info->icount.txabort++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) info->icount.txunder++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) tx_done(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) else if (isr & IRQ_ALLSENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) info->icount.txok++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) tx_done(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) else if (isr & IRQ_TXFIFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) tx_ready(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (gis & BIT7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) pis = read_reg(info, CHA + PIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) if (pis & BIT1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) dsr_change(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (pis & BIT2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) ri_change(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) /* Request bottom half processing if there's something
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) * for it to do and the bh is not already running
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (info->pending_bh && !info->bh_running && !info->bh_requested) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) printk("%s(%d):%s queueing bh task.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) __FILE__,__LINE__,info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) schedule_work(&info->task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) info->bh_requested = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) spin_unlock(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) printk("%s(%d):mgslpc_isr(%d)exit.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) __FILE__, __LINE__, info->irq_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) /* Initialize and start device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) static int startup(MGSLPC_INFO * info, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) int retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) printk("%s(%d):startup(%s)\n", __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (tty_port_initialized(&info->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (!info->tx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) /* allocate a page of memory for a transmit buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) info->tx_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) if (!info->tx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) printk(KERN_ERR"%s(%d):%s can't allocate transmit buffer\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) info->pending_bh = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) memset(&info->icount, 0, sizeof(info->icount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) timer_setup(&info->tx_timer, tx_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) /* Allocate and claim adapter resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) retval = claim_resources(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) /* perform existence check and diagnostics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if (!retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) retval = adapter_test(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) if (capable(CAP_SYS_ADMIN) && tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) set_bit(TTY_IO_ERROR, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) release_resources(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) /* program hardware for current parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) mgslpc_change_params(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) clear_bit(TTY_IO_ERROR, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) tty_port_set_initialized(&info->port, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) /* Called by mgslpc_close() and mgslpc_hangup() to shutdown hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (!tty_port_initialized(&info->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) printk("%s(%d):mgslpc_shutdown(%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) /* clear status wait queue because status changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) /* can't happen after shutting down the hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) wake_up_interruptible(&info->status_event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) wake_up_interruptible(&info->event_wait_q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) del_timer_sync(&info->tx_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) if (info->tx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) free_page((unsigned long) info->tx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) info->tx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) rx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) /* TODO:disable interrupts instead of reset to preserve signal states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) reset_device(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) if (!tty || C_HUPCL(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) release_resources(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) set_bit(TTY_IO_ERROR, &tty->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) tty_port_set_initialized(&info->port, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) static void mgslpc_program_hw(MGSLPC_INFO *info, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) rx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) info->tx_count = info->tx_put = info->tx_get = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) if (info->params.mode == MGSL_MODE_HDLC || info->netcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) hdlc_mode(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) async_mode(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) info->dcd_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) info->cts_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) info->ri_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) info->dsr_chkcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) irq_enable(info, CHB, IRQ_DCD | IRQ_CTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) port_irq_enable(info, (unsigned char) PVR_DSR | PVR_RI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) if (info->netcount || (tty && C_CREAD(tty)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) rx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) spin_unlock_irqrestore(&info->lock, flags);
^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) /* Reconfigure adapter based on new parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) static void mgslpc_change_params(MGSLPC_INFO *info, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) unsigned cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) int bits_per_char;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) if (!tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) printk("%s(%d):mgslpc_change_params(%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) cflag = tty->termios.c_cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) /* if B0 rate (hangup) specified then negate RTS and DTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) /* otherwise assert RTS and DTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) if (cflag & CBAUD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) /* byte size and parity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) switch (cflag & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) case CS5: info->params.data_bits = 5; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) case CS6: info->params.data_bits = 6; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) case CS7: info->params.data_bits = 7; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) case CS8: info->params.data_bits = 8; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) default: info->params.data_bits = 7; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) if (cflag & CSTOPB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) info->params.stop_bits = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) info->params.stop_bits = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) info->params.parity = ASYNC_PARITY_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) if (cflag & PARENB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if (cflag & PARODD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) info->params.parity = ASYNC_PARITY_ODD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) info->params.parity = ASYNC_PARITY_EVEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) #ifdef CMSPAR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (cflag & CMSPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) info->params.parity = ASYNC_PARITY_SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) /* calculate number of jiffies to transmit a full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) * FIFO (32 bytes) at specified data rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) bits_per_char = info->params.data_bits +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) info->params.stop_bits + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) /* if port data rate is set to 460800 or less then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) * allow tty settings to override, otherwise keep the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) * current data rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (info->params.data_rate <= 460800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) info->params.data_rate = tty_get_baud_rate(tty);
^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) if (info->params.data_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) info->timeout = (32*HZ*bits_per_char) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) info->params.data_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) info->timeout += HZ/50; /* Add .02 seconds of slop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) tty_port_set_cts_flow(&info->port, cflag & CRTSCTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) tty_port_set_check_carrier(&info->port, ~cflag & CLOCAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) /* process tty input control flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) info->read_status_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) if (I_INPCK(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) info->read_status_mask |= BIT7 | BIT6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if (I_IGNPAR(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) info->ignore_status_mask |= BIT7 | BIT6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) mgslpc_program_hw(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) /* Add a character to the transmit buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) static int mgslpc_put_char(struct tty_struct *tty, unsigned char ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) if (debug_level >= DEBUG_LEVEL_INFO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) printk("%s(%d):mgslpc_put_char(%d) on %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) __FILE__, __LINE__, ch, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_put_char"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) if (!info->tx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) if (info->params.mode == MGSL_MODE_ASYNC || !info->tx_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) if (info->tx_count < TXBUFSIZE - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) info->tx_buf[info->tx_put++] = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) info->tx_put &= TXBUFSIZE-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) info->tx_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) /* Enable transmitter so remaining characters in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) * transmit buffer are sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) static void mgslpc_flush_chars(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) printk("%s(%d):mgslpc_flush_chars() entry on %s tx_count=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) __FILE__, __LINE__, info->device_name, info->tx_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_flush_chars"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) if (info->tx_count <= 0 || tty->stopped ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) tty->hw_stopped || !info->tx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) printk("%s(%d):mgslpc_flush_chars() entry on %s starting transmitter\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) if (!info->tx_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) tx_start(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) /* Send a block of data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) * Arguments:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) * tty pointer to tty information structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) * buf pointer to buffer containing send data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) * count size of send data in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) * Returns: number of characters written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) static int mgslpc_write(struct tty_struct * tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) const unsigned char *buf, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) int c, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) printk("%s(%d):mgslpc_write(%s) count=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) __FILE__, __LINE__, info->device_name, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_write") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) !info->tx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) if (info->params.mode == MGSL_MODE_HDLC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if (count > TXBUFSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) if (info->tx_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) else if (info->tx_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) goto start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) c = min(count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) min(TXBUFSIZE - info->tx_count - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) TXBUFSIZE - info->tx_put));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) if (c <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) memcpy(info->tx_buf + info->tx_put, buf, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) info->tx_put = (info->tx_put + c) & (TXBUFSIZE-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) info->tx_count += c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) buf += c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) count -= c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) ret += c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) start:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if (info->tx_count && !tty->stopped && !tty->hw_stopped) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) if (!info->tx_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) tx_start(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) printk("%s(%d):mgslpc_write(%s) returning=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) __FILE__, __LINE__, info->device_name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) return ret;
^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) /* Return the count of free bytes in transmit buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) static int mgslpc_write_room(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_write_room"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) if (info->params.mode == MGSL_MODE_HDLC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) /* HDLC (frame oriented) mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) if (info->tx_active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) return HDLC_MAX_FRAME_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) ret = TXBUFSIZE - info->tx_count - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) printk("%s(%d):mgslpc_write_room(%s)=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) __FILE__, __LINE__, info->device_name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) /* Return the count of bytes in transmit buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) static int mgslpc_chars_in_buffer(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) printk("%s(%d):mgslpc_chars_in_buffer(%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_chars_in_buffer"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) if (info->params.mode == MGSL_MODE_HDLC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) rc = info->tx_active ? info->max_frame_size : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) rc = info->tx_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) printk("%s(%d):mgslpc_chars_in_buffer(%s)=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) __FILE__, __LINE__, info->device_name, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) /* Discard all data in the send buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) static void mgslpc_flush_buffer(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) printk("%s(%d):mgslpc_flush_buffer(%s) entry\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_flush_buffer"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) info->tx_count = info->tx_put = info->tx_get = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) del_timer(&info->tx_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) wake_up_interruptible(&tty->write_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) tty_wakeup(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) /* Send a high-priority XON/XOFF character
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) static void mgslpc_send_xchar(struct tty_struct *tty, char ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) printk("%s(%d):mgslpc_send_xchar(%s,%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) __FILE__, __LINE__, info->device_name, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_send_xchar"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) info->x_char = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) if (ch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) if (!info->tx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) tx_start(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) /* Signal remote device to throttle send data (our receive data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) static void mgslpc_throttle(struct tty_struct * tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) printk("%s(%d):mgslpc_throttle(%s) entry\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_throttle"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) if (I_IXOFF(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) mgslpc_send_xchar(tty, STOP_CHAR(tty));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) if (C_CRTSCTS(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) info->serial_signals &= ~SerialSignal_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) /* Signal remote device to stop throttling send data (our receive data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) static void mgslpc_unthrottle(struct tty_struct * tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) printk("%s(%d):mgslpc_unthrottle(%s) entry\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_unthrottle"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) if (I_IXOFF(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) if (info->x_char)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) info->x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) mgslpc_send_xchar(tty, START_CHAR(tty));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) if (C_CRTSCTS(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) info->serial_signals |= SerialSignal_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) /* get the current serial statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) static int get_stats(MGSLPC_INFO * info, struct mgsl_icount __user *user_icount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) printk("get_params(%s)\n", info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) if (!user_icount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) memset(&info->icount, 0, sizeof(info->icount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) COPY_TO_USER(err, user_icount, &info->icount, sizeof(struct mgsl_icount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) /* get the current serial parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) static int get_params(MGSLPC_INFO * info, MGSL_PARAMS __user *user_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) printk("get_params(%s)\n", info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) COPY_TO_USER(err,user_params, &info->params, sizeof(MGSL_PARAMS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) /* set the serial parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) * Arguments:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) * info pointer to device instance data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) * new_params user buffer containing new serial params
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) * Returns: 0 if success, otherwise error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) static int set_params(MGSLPC_INFO * info, MGSL_PARAMS __user *new_params, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) MGSL_PARAMS tmp_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) printk("%s(%d):set_params %s\n", __FILE__,__LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) COPY_FROM_USER(err,&tmp_params, new_params, sizeof(MGSL_PARAMS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) printk("%s(%d):set_params(%s) user buffer copy failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) memcpy(&info->params,&tmp_params,sizeof(MGSL_PARAMS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) mgslpc_change_params(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) static int get_txidle(MGSLPC_INFO * info, int __user *idle_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) printk("get_txidle(%s)=%d\n", info->device_name, info->idle_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) COPY_TO_USER(err,idle_mode, &info->idle_mode, sizeof(int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) static int set_txidle(MGSLPC_INFO * info, int idle_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) printk("set_txidle(%s,%d)\n", info->device_name, idle_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) info->idle_mode = idle_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) tx_set_idle(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) static int get_interface(MGSLPC_INFO * info, int __user *if_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) printk("get_interface(%s)=%d\n", info->device_name, info->if_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) COPY_TO_USER(err,if_mode, &info->if_mode, sizeof(int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) static int set_interface(MGSLPC_INFO * info, int if_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) unsigned char val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) printk("set_interface(%s,%d)\n", info->device_name, if_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) info->if_mode = if_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) val = read_reg(info, PVR) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) switch (info->if_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) case MGSL_INTERFACE_RS232: val |= PVR_RS232; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) case MGSL_INTERFACE_V35: val |= PVR_V35; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) case MGSL_INTERFACE_RS422: val |= PVR_RS422; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) write_reg(info, PVR, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) static int set_txenable(MGSLPC_INFO * info, int enable, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) printk("set_txenable(%s,%d)\n", info->device_name, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) if (!info->tx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) tx_start(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) if (info->tx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) static int tx_abort(MGSLPC_INFO * info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) printk("tx_abort(%s)\n", info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) if (info->tx_active && info->tx_count &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) info->params.mode == MGSL_MODE_HDLC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) /* clear data count so FIFO is not filled on next IRQ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) * This results in underrun and abort transmission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) info->tx_count = info->tx_put = info->tx_get = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) info->tx_aborting = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) static int set_rxenable(MGSLPC_INFO * info, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) printk("set_rxenable(%s,%d)\n", info->device_name, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) if (!info->rx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) rx_start(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) if (info->rx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) rx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) /* wait for specified event to occur
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) * Arguments: info pointer to device instance data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) * mask pointer to bitmask of events to wait for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) * Return Value: 0 if successful and bit mask updated with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) * of events triggerred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) * otherwise error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) static int wait_events(MGSLPC_INFO * info, int __user *mask_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) int s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) int rc=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) struct mgsl_icount cprev, cnow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) int events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) struct _input_signal_events oldsigs, newsigs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) DECLARE_WAITQUEUE(wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) COPY_FROM_USER(rc,&mask, mask_ptr, sizeof(int));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) printk("wait_events(%s,%d)\n", info->device_name, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) /* return immediately if state matches requested events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) s = info->serial_signals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) events = mask &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) ((s & SerialSignal_DCD) ? MgslEvent_DcdActive:MgslEvent_DcdInactive) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) ((s & SerialSignal_CTS) ? MgslEvent_CtsActive:MgslEvent_CtsInactive) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) ((s & SerialSignal_RI) ? MgslEvent_RiActive :MgslEvent_RiInactive) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) if (events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) /* save current irq counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) cprev = info->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) oldsigs = info->input_signal_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) if ((info->params.mode == MGSL_MODE_HDLC) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) (mask & MgslEvent_ExitHuntMode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) irq_enable(info, CHA, IRQ_EXITHUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) add_wait_queue(&info->event_wait_q, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) for(;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) rc = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) /* get current irq counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) cnow = info->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) newsigs = info->input_signal_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) /* if no change, wait aborted for some reason */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) if (newsigs.dsr_up == oldsigs.dsr_up &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) newsigs.dsr_down == oldsigs.dsr_down &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) newsigs.dcd_up == oldsigs.dcd_up &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) newsigs.dcd_down == oldsigs.dcd_down &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) newsigs.cts_up == oldsigs.cts_up &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) newsigs.cts_down == oldsigs.cts_down &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) newsigs.ri_up == oldsigs.ri_up &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) newsigs.ri_down == oldsigs.ri_down &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) cnow.exithunt == cprev.exithunt &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) cnow.rxidle == cprev.rxidle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) events = mask &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) ( (newsigs.dsr_up != oldsigs.dsr_up ? MgslEvent_DsrActive:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) (newsigs.dsr_down != oldsigs.dsr_down ? MgslEvent_DsrInactive:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) (newsigs.dcd_up != oldsigs.dcd_up ? MgslEvent_DcdActive:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) (newsigs.dcd_down != oldsigs.dcd_down ? MgslEvent_DcdInactive:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) (newsigs.cts_up != oldsigs.cts_up ? MgslEvent_CtsActive:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) (newsigs.cts_down != oldsigs.cts_down ? MgslEvent_CtsInactive:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) (newsigs.ri_up != oldsigs.ri_up ? MgslEvent_RiActive:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) (newsigs.ri_down != oldsigs.ri_down ? MgslEvent_RiInactive:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) (cnow.exithunt != cprev.exithunt ? MgslEvent_ExitHuntMode:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) (cnow.rxidle != cprev.rxidle ? MgslEvent_IdleReceived:0) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) if (events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) cprev = cnow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) oldsigs = newsigs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) remove_wait_queue(&info->event_wait_q, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) if (mask & MgslEvent_ExitHuntMode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) if (!waitqueue_active(&info->event_wait_q))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) irq_disable(info, CHA, IRQ_EXITHUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) PUT_USER(rc, events, mask_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) static int modem_input_wait(MGSLPC_INFO *info,int arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) struct mgsl_icount cprev, cnow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) DECLARE_WAITQUEUE(wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) /* save current irq counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) cprev = info->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) add_wait_queue(&info->status_event_wait_q, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) for(;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) rc = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) /* get new irq counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) cnow = info->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) /* if no change, wait aborted for some reason */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) /* check for change in caller specified modem input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) if ((arg & TIOCM_RNG && cnow.rng != cprev.rng) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) (arg & TIOCM_DSR && cnow.dsr != cprev.dsr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) (arg & TIOCM_CD && cnow.dcd != cprev.dcd) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) (arg & TIOCM_CTS && cnow.cts != cprev.cts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) cprev = cnow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) remove_wait_queue(&info->status_event_wait_q, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) return rc;
^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) /* return the state of the serial control and status signals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) static int tiocmget(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) unsigned int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) result = ((info->serial_signals & SerialSignal_RTS) ? TIOCM_RTS:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) ((info->serial_signals & SerialSignal_DTR) ? TIOCM_DTR:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) ((info->serial_signals & SerialSignal_DCD) ? TIOCM_CAR:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) ((info->serial_signals & SerialSignal_RI) ? TIOCM_RNG:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) ((info->serial_signals & SerialSignal_DSR) ? TIOCM_DSR:0) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) ((info->serial_signals & SerialSignal_CTS) ? TIOCM_CTS:0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) printk("%s(%d):%s tiocmget() value=%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) __FILE__, __LINE__, info->device_name, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) /* set modem control signals (DTR/RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) static int tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) unsigned int set, unsigned int clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) printk("%s(%d):%s tiocmset(%x,%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) __FILE__, __LINE__, info->device_name, set, clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) if (set & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) info->serial_signals |= SerialSignal_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) if (set & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) info->serial_signals |= SerialSignal_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) if (clear & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) info->serial_signals &= ~SerialSignal_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) if (clear & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) info->serial_signals &= ~SerialSignal_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) /* Set or clear transmit break condition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) * Arguments: tty pointer to tty instance data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) * break_state -1=set break condition, 0=clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) static int mgslpc_break(struct tty_struct *tty, int break_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) printk("%s(%d):mgslpc_break(%s,%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) __FILE__, __LINE__, info->device_name, break_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_break"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) if (break_state == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) set_reg_bits(info, CHA+DAFO, BIT6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) clear_reg_bits(info, CHA+DAFO, BIT6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) static int mgslpc_get_icount(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) struct serial_icounter_struct *icount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) struct mgsl_icount cnow; /* kernel counter temps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) cnow = info->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) icount->cts = cnow.cts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) icount->dsr = cnow.dsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) icount->rng = cnow.rng;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) icount->dcd = cnow.dcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) icount->rx = cnow.rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) icount->tx = cnow.tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) icount->frame = cnow.frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) icount->overrun = cnow.overrun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) icount->parity = cnow.parity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) icount->brk = cnow.brk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) icount->buf_overrun = cnow.buf_overrun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) /* Service an IOCTL request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) * Arguments:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) * tty pointer to tty instance data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) * cmd IOCTL command code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) * arg command argument/context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) * Return Value: 0 if success, otherwise error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) static int mgslpc_ioctl(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) void __user *argp = (void __user *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) printk("%s(%d):mgslpc_ioctl %s cmd=%08X\n", __FILE__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) info->device_name, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_ioctl"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) if (cmd != TIOCMIWAIT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) if (tty_io_error(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) case MGSL_IOCGPARAMS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) return get_params(info, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) case MGSL_IOCSPARAMS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) return set_params(info, argp, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) case MGSL_IOCGTXIDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) return get_txidle(info, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) case MGSL_IOCSTXIDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) return set_txidle(info, (int)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) case MGSL_IOCGIF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) return get_interface(info, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) case MGSL_IOCSIF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) return set_interface(info,(int)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) case MGSL_IOCTXENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) return set_txenable(info,(int)arg, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) case MGSL_IOCRXENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) return set_rxenable(info,(int)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) case MGSL_IOCTXABORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) return tx_abort(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) case MGSL_IOCGSTATS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) return get_stats(info, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) case MGSL_IOCWAITEVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) return wait_events(info, argp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) case TIOCMIWAIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) return modem_input_wait(info,(int)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) /* Set new termios settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) * Arguments:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) * tty pointer to tty structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) * termios pointer to buffer to hold returned old termios
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) printk("%s(%d):mgslpc_set_termios %s\n", __FILE__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) tty->driver->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) /* just return if nothing has changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) if ((tty->termios.c_cflag == old_termios->c_cflag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) && (RELEVANT_IFLAG(tty->termios.c_iflag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) == RELEVANT_IFLAG(old_termios->c_iflag)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) mgslpc_change_params(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) /* Handle transition to B0 status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) if ((old_termios->c_cflag & CBAUD) && !C_BAUD(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) /* Handle transition away from B0 status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) if (!(old_termios->c_cflag & CBAUD) && C_BAUD(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) info->serial_signals |= SerialSignal_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) if (!C_CRTSCTS(tty) || !tty_throttled(tty))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) info->serial_signals |= SerialSignal_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) spin_unlock_irqrestore(&info->lock, flags);
^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) /* Handle turning off CRTSCTS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) if (old_termios->c_cflag & CRTSCTS && !C_CRTSCTS(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) tty->hw_stopped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) tx_release(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) static void mgslpc_close(struct tty_struct *tty, struct file * filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) struct tty_port *port = &info->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_close"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) printk("%s(%d):mgslpc_close(%s) entry, count=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) __FILE__, __LINE__, info->device_name, port->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) if (tty_port_close_start(port, tty, filp) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) if (tty_port_initialized(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) mgslpc_wait_until_sent(tty, info->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) mgslpc_flush_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) tty_ldisc_flush(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) shutdown(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) tty_port_close_end(port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) tty_port_tty_set(port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) printk("%s(%d):mgslpc_close(%s) exit, count=%d\n", __FILE__, __LINE__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) tty->driver->name, port->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) /* Wait until the transmitter is empty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) unsigned long orig_jiffies, char_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) printk("%s(%d):mgslpc_wait_until_sent(%s) entry\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_wait_until_sent"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) if (!tty_port_initialized(&info->port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) orig_jiffies = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) /* Set check interval to 1/5 of estimated time to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) * send a character, and make it at least 1. The check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) * interval should also be less than the timeout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) * Note: use tight timings here to satisfy the NIST-PCTS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) if (info->params.data_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) char_time = info->timeout/(32 * 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) if (!char_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) char_time++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) char_time = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) if (timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) char_time = min_t(unsigned long, char_time, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) if (info->params.mode == MGSL_MODE_HDLC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) while (info->tx_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) msleep_interruptible(jiffies_to_msecs(char_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) if (timeout && time_after(jiffies, orig_jiffies + timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) while ((info->tx_count || info->tx_active) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) info->tx_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) msleep_interruptible(jiffies_to_msecs(char_time));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) if (signal_pending(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) if (timeout && time_after(jiffies, orig_jiffies + timeout))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) printk("%s(%d):mgslpc_wait_until_sent(%s) exit\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) /* Called by tty_hangup() when a hangup is signaled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) * This is the same as closing all open files for the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) static void mgslpc_hangup(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) MGSLPC_INFO * info = (MGSLPC_INFO *)tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) printk("%s(%d):mgslpc_hangup(%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_hangup"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) mgslpc_flush_buffer(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) shutdown(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) tty_port_hangup(&info->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) static int carrier_raised(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) MGSLPC_INFO *info = container_of(port, MGSLPC_INFO, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) if (info->serial_signals & SerialSignal_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) static void dtr_rts(struct tty_port *port, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) MGSLPC_INFO *info = container_of(port, MGSLPC_INFO, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) if (onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) static int mgslpc_open(struct tty_struct *tty, struct file * filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) MGSLPC_INFO *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) struct tty_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) int retval, line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) /* verify range of specified line number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) line = tty->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) if (line >= mgslpc_device_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) printk("%s(%d):mgslpc_open with invalid line #%d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) __FILE__, __LINE__, line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) /* find the info structure for the specified line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) info = mgslpc_device_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) while(info && info->line != line)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) info = info->next_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) if (mgslpc_paranoia_check(info, tty->name, "mgslpc_open"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) port = &info->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) tty->driver_data = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) tty_port_tty_set(port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) printk("%s(%d):mgslpc_open(%s), old ref count = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) __FILE__, __LINE__, tty->driver->name, port->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) spin_lock_irqsave(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) if (info->netcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) retval = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) spin_unlock_irqrestore(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) spin_lock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) port->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) spin_unlock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) spin_unlock_irqrestore(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) if (port->count == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) /* 1st open on this device, init hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) retval = startup(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) if (retval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) retval = tty_port_block_til_ready(&info->port, tty, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) printk("%s(%d):block_til_ready(%s) returned %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) __FILE__, __LINE__, info->device_name, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) printk("%s(%d):mgslpc_open(%s) success\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) retval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) * /proc fs routines....
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) static inline void line_info(struct seq_file *m, MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) char stat_buf[30];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) seq_printf(m, "%s:io:%04X irq:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) info->device_name, info->io_base, info->irq_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) /* output current serial signal states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) stat_buf[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) stat_buf[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) if (info->serial_signals & SerialSignal_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) strcat(stat_buf, "|RTS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) if (info->serial_signals & SerialSignal_CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) strcat(stat_buf, "|CTS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) if (info->serial_signals & SerialSignal_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) strcat(stat_buf, "|DTR");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) if (info->serial_signals & SerialSignal_DSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) strcat(stat_buf, "|DSR");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) if (info->serial_signals & SerialSignal_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) strcat(stat_buf, "|CD");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) if (info->serial_signals & SerialSignal_RI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) strcat(stat_buf, "|RI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) if (info->params.mode == MGSL_MODE_HDLC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) seq_printf(m, " HDLC txok:%d rxok:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) info->icount.txok, info->icount.rxok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) if (info->icount.txunder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) seq_printf(m, " txunder:%d", info->icount.txunder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) if (info->icount.txabort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) seq_printf(m, " txabort:%d", info->icount.txabort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) if (info->icount.rxshort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) seq_printf(m, " rxshort:%d", info->icount.rxshort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) if (info->icount.rxlong)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) seq_printf(m, " rxlong:%d", info->icount.rxlong);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) if (info->icount.rxover)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) seq_printf(m, " rxover:%d", info->icount.rxover);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) if (info->icount.rxcrc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) seq_printf(m, " ASYNC tx:%d rx:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) info->icount.tx, info->icount.rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) if (info->icount.frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) seq_printf(m, " fe:%d", info->icount.frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) if (info->icount.parity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) seq_printf(m, " pe:%d", info->icount.parity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) if (info->icount.brk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) seq_printf(m, " brk:%d", info->icount.brk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) if (info->icount.overrun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) seq_printf(m, " oe:%d", info->icount.overrun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) /* Append serial signal status to end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) seq_printf(m, " %s\n", stat_buf+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) info->tx_active,info->bh_requested,info->bh_running,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) info->pending_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) /* Called to print information about devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) static int mgslpc_proc_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) MGSLPC_INFO *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) seq_printf(m, "synclink driver:%s\n", driver_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) info = mgslpc_device_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) while (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) line_info(m, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) info = info->next_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) static int rx_alloc_buffers(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) /* each buffer has header and data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) info->rx_buf_size = sizeof(RXBUF) + info->max_frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) /* calculate total allocation size for 8 buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) info->rx_buf_total_size = info->rx_buf_size * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) /* limit total allocated memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) if (info->rx_buf_total_size > 0x10000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) info->rx_buf_total_size = 0x10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) /* calculate number of buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) info->rx_buf_count = info->rx_buf_total_size / info->rx_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) info->rx_buf = kmalloc(info->rx_buf_total_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) if (info->rx_buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) /* unused flag buffer to satisfy receive_buf calling interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) info->flag_buf = kzalloc(info->max_frame_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) if (!info->flag_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) kfree(info->rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) info->rx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) rx_reset_buffers(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) static void rx_free_buffers(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) kfree(info->rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) info->rx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) kfree(info->flag_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) info->flag_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) static int claim_resources(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) if (rx_alloc_buffers(info) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) printk("Can't allocate rx buffer %s\n", info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) release_resources(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) static void release_resources(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) printk("release_resources(%s)\n", info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) rx_free_buffers(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) /* Add the specified device instance data structure to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) * global linked list of devices and increment the device count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) * Arguments: info pointer to device instance data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) static int mgslpc_add_device(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) MGSLPC_INFO *current_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) struct device *tty_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) info->next_device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) info->line = mgslpc_device_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) sprintf(info->device_name,"ttySLP%d",info->line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) if (info->line < MAX_DEVICE_COUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) if (maxframe[info->line])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) info->max_frame_size = maxframe[info->line];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) mgslpc_device_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) if (!mgslpc_device_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) mgslpc_device_list = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) current_dev = mgslpc_device_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) while (current_dev->next_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) current_dev = current_dev->next_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) current_dev->next_device = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) if (info->max_frame_size < 4096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) info->max_frame_size = 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) else if (info->max_frame_size > 65535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) info->max_frame_size = 65535;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) printk("SyncLink PC Card %s:IO=%04X IRQ=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) info->device_name, info->io_base, info->irq_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) ret = hdlcdev_init(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) tty_dev = tty_port_register_device(&info->port, serial_driver, info->line,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) &info->p_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) if (IS_ERR(tty_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) ret = PTR_ERR(tty_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) hdlcdev_exit(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) if (current_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) current_dev->next_device = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) mgslpc_device_list = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) mgslpc_device_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) static void mgslpc_remove_device(MGSLPC_INFO *remove_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) MGSLPC_INFO *info = mgslpc_device_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) MGSLPC_INFO *last = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) while(info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) if (info == remove_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) if (last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) last->next_device = info->next_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) mgslpc_device_list = info->next_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) tty_unregister_device(serial_driver, info->line);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) hdlcdev_exit(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) release_resources(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) tty_port_destroy(&info->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) kfree(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) mgslpc_device_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) last = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) info = info->next_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) static const struct pcmcia_device_id mgslpc_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) PCMCIA_DEVICE_MANF_CARD(0x02c5, 0x0050),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) PCMCIA_DEVICE_NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) MODULE_DEVICE_TABLE(pcmcia, mgslpc_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) static struct pcmcia_driver mgslpc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) .name = "synclink_cs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) .probe = mgslpc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) .remove = mgslpc_detach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) .id_table = mgslpc_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) .suspend = mgslpc_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) .resume = mgslpc_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) static const struct tty_operations mgslpc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) .open = mgslpc_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) .close = mgslpc_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) .write = mgslpc_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) .put_char = mgslpc_put_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) .flush_chars = mgslpc_flush_chars,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) .write_room = mgslpc_write_room,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) .chars_in_buffer = mgslpc_chars_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) .flush_buffer = mgslpc_flush_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) .ioctl = mgslpc_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) .throttle = mgslpc_throttle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) .unthrottle = mgslpc_unthrottle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) .send_xchar = mgslpc_send_xchar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) .break_ctl = mgslpc_break,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) .wait_until_sent = mgslpc_wait_until_sent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) .set_termios = mgslpc_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) .stop = tx_pause,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) .start = tx_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) .hangup = mgslpc_hangup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) .tiocmget = tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) .tiocmset = tiocmset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) .get_icount = mgslpc_get_icount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) .proc_show = mgslpc_proc_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) static int __init synclink_cs_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) if (break_on_load) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) mgslpc_get_text_ptr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) BREAKPOINT();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) serial_driver = tty_alloc_driver(MAX_DEVICE_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) TTY_DRIVER_REAL_RAW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) TTY_DRIVER_DYNAMIC_DEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) if (IS_ERR(serial_driver)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) rc = PTR_ERR(serial_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) /* Initialize the tty_driver structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) serial_driver->driver_name = "synclink_cs";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) serial_driver->name = "ttySLP";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) serial_driver->major = ttymajor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) serial_driver->minor_start = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) serial_driver->subtype = SERIAL_TYPE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) serial_driver->init_termios = tty_std_termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) serial_driver->init_termios.c_cflag =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) B9600 | CS8 | CREAD | HUPCL | CLOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) tty_set_operations(serial_driver, &mgslpc_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) rc = tty_register_driver(serial_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) printk(KERN_ERR "%s(%d):Couldn't register serial driver\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) __FILE__, __LINE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) goto err_put_tty;
^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) rc = pcmcia_register_driver(&mgslpc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) goto err_unreg_tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) printk(KERN_INFO "%s %s, tty major#%d\n", driver_name, driver_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) serial_driver->major);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) err_unreg_tty:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) tty_unregister_driver(serial_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) err_put_tty:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) put_tty_driver(serial_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) static void __exit synclink_cs_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) pcmcia_unregister_driver(&mgslpc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) tty_unregister_driver(serial_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) put_tty_driver(serial_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) module_init(synclink_cs_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) module_exit(synclink_cs_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) static void mgslpc_set_rate(MGSLPC_INFO *info, unsigned char channel, unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) unsigned int M, N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) unsigned char val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) /* note:standard BRG mode is broken in V3.2 chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) * so enhanced mode is always used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) if (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) N = 3686400 / rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) if (!N)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) N = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) N >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) for (M = 1; N > 64 && M < 16; M++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) N >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) N--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) /* BGR[5..0] = N
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) * BGR[9..6] = M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) * BGR[7..0] contained in BGR register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) * BGR[9..8] contained in CCR2[7..6]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) * divisor = (N+1)*2^M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) * Note: M *must* not be zero (causes asymetric duty cycle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) write_reg(info, (unsigned char) (channel + BGR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) (unsigned char) ((M << 6) + N));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) val = read_reg(info, (unsigned char) (channel + CCR2)) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) val |= ((M << 4) & 0xc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) write_reg(info, (unsigned char) (channel + CCR2), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) /* Enabled the AUX clock output at the specified frequency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) static void enable_auxclk(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) unsigned char val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) /* MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) * 07..06 MDS[1..0] 10 = transparent HDLC mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) * 05 ADM Address Mode, 0 = no addr recognition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) * 04 TMD Timer Mode, 0 = external
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) * 03 RAC Receiver Active, 0 = inactive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) * 02 RTS 0=RTS active during xmit, 1=RTS always active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) * 01 TRS Timer Resolution, 1=512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) * 00 TLP Test Loop, 0 = no loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) * 1000 0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) val = 0x82;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) /* channel B RTS is used to enable AUXCLK driver on SP505 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) if (info->params.mode == MGSL_MODE_HDLC && info->params.clock_speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) val |= BIT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) write_reg(info, CHB + MODE, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) /* CCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) * 07 PU Power Up, 1=active, 0=power down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) * 06 MCE Master Clock Enable, 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) * 05 Reserved, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) * 04..02 SC[2..0] Encoding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) * 01..00 SM[1..0] Serial Mode, 00=HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) * 11000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) write_reg(info, CHB + CCR0, 0xc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) /* CCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) * 07 SFLG Shared Flag, 0 = disable shared flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) * 06 GALP Go Active On Loop, 0 = not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) * 05 GLP Go On Loop, 0 = not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) * 04 ODS Output Driver Select, 1=TxD is push-pull output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) * 03 ITF Interframe Time Fill, 0=mark, 1=flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) * 02..00 CM[2..0] Clock Mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) * 0001 0111
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) write_reg(info, CHB + CCR1, 0x17);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) /* CCR2 (Channel B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) * 07..06 BGR[9..8] Baud rate bits 9..8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) * 05 BDF Baud rate divisor factor, 0=1, 1=BGR value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) * 04 SSEL Clock source select, 1=submode b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) * 03 TOE 0=TxCLK is input, 1=TxCLK is output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) * 02 RWX Read/Write Exchange 0=disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) * 01 C32, CRC select, 0=CRC-16, 1=CRC-32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) * 00 DIV, data inversion 0=disabled, 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) * 0011 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) if (info->params.mode == MGSL_MODE_HDLC && info->params.clock_speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) write_reg(info, CHB + CCR2, 0x38);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) write_reg(info, CHB + CCR2, 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) /* CCR4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) * 07 MCK4 Master Clock Divide by 4, 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) * 06 EBRG Enhanced Baud Rate Generator Mode, 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) * 05 TST1 Test Pin, 0=normal operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) * 04 ICD Ivert Carrier Detect, 1=enabled (active low)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) * 03..02 Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) * 01..00 RFT[1..0] RxFIFO Threshold 00=32 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) * 0101 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) write_reg(info, CHB + CCR4, 0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) /* if auxclk not enabled, set internal BRG so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) * CTS transitions can be detected (requires TxC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) if (info->params.mode == MGSL_MODE_HDLC && info->params.clock_speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) mgslpc_set_rate(info, CHB, info->params.clock_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) mgslpc_set_rate(info, CHB, 921600);
^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) static void loopback_enable(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) unsigned char val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) /* CCR1:02..00 CM[2..0] Clock Mode = 111 (clock mode 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) val = read_reg(info, CHA + CCR1) | (BIT2 | BIT1 | BIT0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) write_reg(info, CHA + CCR1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) /* CCR2:04 SSEL Clock source select, 1=submode b */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) val = read_reg(info, CHA + CCR2) | (BIT4 | BIT5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) write_reg(info, CHA + CCR2, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) /* set LinkSpeed if available, otherwise default to 2Mbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) if (info->params.clock_speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) mgslpc_set_rate(info, CHA, info->params.clock_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) mgslpc_set_rate(info, CHA, 1843200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) /* MODE:00 TLP Test Loop, 1=loopback enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) val = read_reg(info, CHA + MODE) | BIT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) write_reg(info, CHA + MODE, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) static void hdlc_mode(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) unsigned char val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) unsigned char clkmode, clksubmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) /* disable all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) irq_disable(info, CHA, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) irq_disable(info, CHB, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) port_irq_disable(info, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) /* assume clock mode 0a, rcv=RxC xmt=TxC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) clkmode = clksubmode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) if (info->params.flags & HDLC_FLAG_RXC_DPLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) && info->params.flags & HDLC_FLAG_TXC_DPLL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) /* clock mode 7a, rcv = DPLL, xmt = DPLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) clkmode = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) } else if (info->params.flags & HDLC_FLAG_RXC_BRG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) && info->params.flags & HDLC_FLAG_TXC_BRG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) /* clock mode 7b, rcv = BRG, xmt = BRG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) clkmode = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) clksubmode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) } else if (info->params.flags & HDLC_FLAG_RXC_DPLL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) if (info->params.flags & HDLC_FLAG_TXC_BRG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) /* clock mode 6b, rcv = DPLL, xmt = BRG/16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) clkmode = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) clksubmode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) /* clock mode 6a, rcv = DPLL, xmt = TxC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) clkmode = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) } else if (info->params.flags & HDLC_FLAG_TXC_BRG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) /* clock mode 0b, rcv = RxC, xmt = BRG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) clksubmode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) /* MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) * 07..06 MDS[1..0] 10 = transparent HDLC mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) * 05 ADM Address Mode, 0 = no addr recognition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) * 04 TMD Timer Mode, 0 = external
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) * 03 RAC Receiver Active, 0 = inactive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) * 02 RTS 0=RTS active during xmit, 1=RTS always active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) * 01 TRS Timer Resolution, 1=512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) * 00 TLP Test Loop, 0 = no loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) * 1000 0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) val = 0x82;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) if (info->params.loopback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) val |= BIT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) /* preserve RTS state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) if (info->serial_signals & SerialSignal_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) val |= BIT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) write_reg(info, CHA + MODE, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) /* CCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) * 07 PU Power Up, 1=active, 0=power down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) * 06 MCE Master Clock Enable, 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) * 05 Reserved, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) * 04..02 SC[2..0] Encoding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) * 01..00 SM[1..0] Serial Mode, 00=HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) * 11000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) val = 0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) switch (info->params.encoding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) case HDLC_ENCODING_NRZI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) val |= BIT3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) case HDLC_ENCODING_BIPHASE_SPACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) val |= BIT4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) break; // FM0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) case HDLC_ENCODING_BIPHASE_MARK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) val |= BIT4 | BIT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) break; // FM1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) case HDLC_ENCODING_BIPHASE_LEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) val |= BIT4 | BIT3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) break; // Manchester
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) write_reg(info, CHA + CCR0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) /* CCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) * 07 SFLG Shared Flag, 0 = disable shared flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) * 06 GALP Go Active On Loop, 0 = not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) * 05 GLP Go On Loop, 0 = not used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) * 04 ODS Output Driver Select, 1=TxD is push-pull output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) * 03 ITF Interframe Time Fill, 0=mark, 1=flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) * 02..00 CM[2..0] Clock Mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) * 0001 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) val = 0x10 + clkmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) write_reg(info, CHA + CCR1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) /* CCR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) * 07..06 BGR[9..8] Baud rate bits 9..8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) * 05 BDF Baud rate divisor factor, 0=1, 1=BGR value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) * 04 SSEL Clock source select, 1=submode b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) * 03 TOE 0=TxCLK is input, 0=TxCLK is input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) * 02 RWX Read/Write Exchange 0=disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) * 01 C32, CRC select, 0=CRC-16, 1=CRC-32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) * 00 DIV, data inversion 0=disabled, 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) * 0000 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) val = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) if (clkmode == 2 || clkmode == 3 || clkmode == 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) || clkmode == 7 || (clkmode == 0 && clksubmode == 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) val |= BIT5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) if (clksubmode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) val |= BIT4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) if (info->params.crc_type == HDLC_CRC_32_CCITT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) val |= BIT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) if (info->params.encoding == HDLC_ENCODING_NRZB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) val |= BIT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) write_reg(info, CHA + CCR2, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) /* CCR3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) * 07..06 PRE[1..0] Preamble count 00=1, 01=2, 10=4, 11=8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) * 05 EPT Enable preamble transmission, 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) * 04 RADD Receive address pushed to FIFO, 0=disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) * 03 CRL CRC Reset Level, 0=FFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) * 02 RCRC Rx CRC 0=On 1=Off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) * 01 TCRC Tx CRC 0=On 1=Off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) * 00 PSD DPLL Phase Shift Disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) * 0000 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) val = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) if (info->params.crc_type == HDLC_CRC_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) val |= BIT2 | BIT1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) if (info->params.preamble != HDLC_PREAMBLE_PATTERN_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) val |= BIT5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) switch (info->params.preamble_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) case HDLC_PREAMBLE_LENGTH_16BITS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) val |= BIT6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) case HDLC_PREAMBLE_LENGTH_32BITS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) val |= BIT6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) case HDLC_PREAMBLE_LENGTH_64BITS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) val |= BIT7 | BIT6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) write_reg(info, CHA + CCR3, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) /* PRE - Preamble pattern */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) switch (info->params.preamble)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) case HDLC_PREAMBLE_PATTERN_FLAGS: val = 0x7e; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) case HDLC_PREAMBLE_PATTERN_10: val = 0xaa; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) case HDLC_PREAMBLE_PATTERN_01: val = 0x55; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) case HDLC_PREAMBLE_PATTERN_ONES: val = 0xff; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) write_reg(info, CHA + PRE, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) /* CCR4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) * 07 MCK4 Master Clock Divide by 4, 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) * 06 EBRG Enhanced Baud Rate Generator Mode, 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) * 05 TST1 Test Pin, 0=normal operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) * 04 ICD Ivert Carrier Detect, 1=enabled (active low)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) * 03..02 Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) * 01..00 RFT[1..0] RxFIFO Threshold 00=32 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) * 0101 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) val = 0x50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) write_reg(info, CHA + CCR4, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) if (info->params.flags & HDLC_FLAG_RXC_DPLL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) mgslpc_set_rate(info, CHA, info->params.clock_speed * 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) mgslpc_set_rate(info, CHA, info->params.clock_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) /* RLCR Receive length check register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) * 7 1=enable receive length check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) * 6..0 Max frame length = (RL + 1) * 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) write_reg(info, CHA + RLCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) /* XBCH Transmit Byte Count High
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) * 07 DMA mode, 0 = interrupt driven
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) * 06 NRM, 0=ABM (ignored)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) * 05 CAS Carrier Auto Start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) * 04 XC Transmit Continuously (ignored)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) * 03..00 XBC[10..8] Transmit byte count bits 10..8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) * 0000 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) val = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) if (info->params.flags & HDLC_FLAG_AUTO_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) val |= BIT5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) write_reg(info, CHA + XBCH, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) enable_auxclk(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) if (info->params.loopback || info->testing_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) loopback_enable(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) if (info->params.flags & HDLC_FLAG_AUTO_CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) irq_enable(info, CHB, IRQ_CTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) /* PVR[3] 1=AUTO CTS active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) set_reg_bits(info, CHA + PVR, BIT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) clear_reg_bits(info, CHA + PVR, BIT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) irq_enable(info, CHA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) IRQ_RXEOM | IRQ_RXFIFO | IRQ_ALLSENT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) IRQ_UNDERRUN | IRQ_TXFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) issue_command(info, CHA, CMD_TXRESET + CMD_RXRESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) wait_command_complete(info, CHA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) read_reg16(info, CHA + ISR); /* clear pending IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) /* Master clock mode enabled above to allow reset commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) * to complete even if no data clocks are present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) * Disable master clock mode for normal communications because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) * V3.2 of the ESCC2 has a bug that prevents the transmit all sent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) * IRQ when in master clock mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) * Leave master clock mode enabled for IRQ test because the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) * timer IRQ used by the test can only happen in master clock mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) if (!info->testing_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) clear_reg_bits(info, CHA + CCR0, BIT6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) tx_set_idle(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) rx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) static void rx_stop(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) printk("%s(%d):rx_stop(%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) /* MODE:03 RAC Receiver Active, 0=inactive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) clear_reg_bits(info, CHA + MODE, BIT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) info->rx_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) info->rx_overflow = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) static void rx_start(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) printk("%s(%d):rx_start(%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) rx_reset_buffers(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) info->rx_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) info->rx_overflow = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) /* MODE:03 RAC Receiver Active, 1=active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) set_reg_bits(info, CHA + MODE, BIT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) info->rx_enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) static void tx_start(MGSLPC_INFO *info, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) printk("%s(%d):tx_start(%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) if (info->tx_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) /* If auto RTS enabled and RTS is inactive, then assert */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) /* RTS and set a flag indicating that the driver should */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) /* negate RTS when the transmission completes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) info->drop_rts_on_tx_done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) if (info->params.flags & HDLC_FLAG_AUTO_RTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) if (!(info->serial_signals & SerialSignal_RTS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) info->serial_signals |= SerialSignal_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) set_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) info->drop_rts_on_tx_done = true;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) if (info->params.mode == MGSL_MODE_ASYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) if (!info->tx_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) info->tx_active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) tx_ready(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) info->tx_active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) tx_ready(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) mod_timer(&info->tx_timer, jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) msecs_to_jiffies(5000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) if (!info->tx_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) info->tx_enabled = true;
^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) static void tx_stop(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) if (debug_level >= DEBUG_LEVEL_ISR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) printk("%s(%d):tx_stop(%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) del_timer(&info->tx_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) info->tx_enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) info->tx_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) /* Reset the adapter to a known state and prepare it for further use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) static void reset_device(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) /* power up both channels (set BIT7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) write_reg(info, CHA + CCR0, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) write_reg(info, CHB + CCR0, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) write_reg(info, CHA + MODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) write_reg(info, CHB + MODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) /* disable all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) irq_disable(info, CHA, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) irq_disable(info, CHB, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) port_irq_disable(info, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) /* PCR Port Configuration Register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) * 07..04 DEC[3..0] Serial I/F select outputs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) * 03 output, 1=AUTO CTS control enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) * 02 RI Ring Indicator input 0=active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) * 01 DSR input 0=active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) * 00 DTR output 0=active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) * 0000 0110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) write_reg(info, PCR, 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) /* PVR Port Value Register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) * 07..04 DEC[3..0] Serial I/F select (0000=disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) * 03 AUTO CTS output 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) * 02 RI Ring Indicator input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) * 01 DSR input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) * 00 DTR output (1=inactive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) * 0000 0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) // write_reg(info, PVR, PVR_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) /* IPC Interrupt Port Configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) * 07 VIS 1=Masked interrupts visible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) * 06..05 Reserved, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) * 04..03 SLA Slave address, 00 ignored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) * 02 CASM Cascading Mode, 1=daisy chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) * 01..00 IC[1..0] Interrupt Config, 01=push-pull output, active low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) * 0000 0101
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) write_reg(info, IPC, 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) static void async_mode(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) unsigned char val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) /* disable all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) irq_disable(info, CHA, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) irq_disable(info, CHB, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) port_irq_disable(info, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) /* MODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) * 07 Reserved, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) * 06 FRTS RTS State, 0=active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) * 05 FCTS Flow Control on CTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) * 04 FLON Flow Control Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) * 03 RAC Receiver Active, 0 = inactive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) * 02 RTS 0=Auto RTS, 1=manual RTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) * 01 TRS Timer Resolution, 1=512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) * 00 TLP Test Loop, 0 = no loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) * 0000 0110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) val = 0x06;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) if (info->params.loopback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) val |= BIT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) /* preserve RTS state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) if (!(info->serial_signals & SerialSignal_RTS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) val |= BIT6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) write_reg(info, CHA + MODE, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) /* CCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) * 07 PU Power Up, 1=active, 0=power down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) * 06 MCE Master Clock Enable, 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) * 05 Reserved, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) * 04..02 SC[2..0] Encoding, 000=NRZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) * 01..00 SM[1..0] Serial Mode, 11=Async
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) * 1000 0011
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) write_reg(info, CHA + CCR0, 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) /* CCR1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) * 07..05 Reserved, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) * 04 ODS Output Driver Select, 1=TxD is push-pull output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) * 03 BCR Bit Clock Rate, 1=16x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) * 02..00 CM[2..0] Clock Mode, 111=BRG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) * 0001 1111
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) write_reg(info, CHA + CCR1, 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) /* CCR2 (channel A)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) * 07..06 BGR[9..8] Baud rate bits 9..8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) * 05 BDF Baud rate divisor factor, 0=1, 1=BGR value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) * 04 SSEL Clock source select, 1=submode b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) * 03 TOE 0=TxCLK is input, 0=TxCLK is input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) * 02 RWX Read/Write Exchange 0=disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) * 01 Reserved, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) * 00 DIV, data inversion 0=disabled, 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) * 0001 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) write_reg(info, CHA + CCR2, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) /* CCR3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) * 07..01 Reserved, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) * 00 PSD DPLL Phase Shift Disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) * 0000 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) write_reg(info, CHA + CCR3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) /* CCR4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) * 07 MCK4 Master Clock Divide by 4, 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) * 06 EBRG Enhanced Baud Rate Generator Mode, 1=enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) * 05 TST1 Test Pin, 0=normal operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) * 04 ICD Ivert Carrier Detect, 1=enabled (active low)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) * 03..00 Reserved, must be 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) * 0101 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) write_reg(info, CHA + CCR4, 0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) mgslpc_set_rate(info, CHA, info->params.data_rate * 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) /* DAFO Data Format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) * 07 Reserved, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) * 06 XBRK transmit break, 0=normal operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) * 05 Stop bits (0=1, 1=2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) * 04..03 PAR[1..0] Parity (01=odd, 10=even)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) * 02 PAREN Parity Enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) * 01..00 CHL[1..0] Character Length (00=8, 01=7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) val = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) if (info->params.data_bits != 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) val |= BIT0; /* 7 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) if (info->params.stop_bits != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) val |= BIT5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) if (info->params.parity != ASYNC_PARITY_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) val |= BIT2; /* Parity enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) if (info->params.parity == ASYNC_PARITY_ODD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) val |= BIT3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) val |= BIT4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) write_reg(info, CHA + DAFO, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) /* RFC Rx FIFO Control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) * 07 Reserved, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) * 06 DPS, 1=parity bit not stored in data byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) * 05 DXS, 0=all data stored in FIFO (including XON/XOFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) * 04 RFDF Rx FIFO Data Format, 1=status byte stored in FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) * 03..02 RFTH[1..0], rx threshold, 11=16 status + 16 data byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) * 01 Reserved, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) * 00 TCDE Terminate Char Detect Enable, 0=disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) * 0101 1100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) write_reg(info, CHA + RFC, 0x5c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) /* RLCR Receive length check register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) * Max frame length = (RL + 1) * 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) write_reg(info, CHA + RLCR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) /* XBCH Transmit Byte Count High
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) * 07 DMA mode, 0 = interrupt driven
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) * 06 NRM, 0=ABM (ignored)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) * 05 CAS Carrier Auto Start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) * 04 XC Transmit Continuously (ignored)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) * 03..00 XBC[10..8] Transmit byte count bits 10..8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) * 0000 0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) val = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) if (info->params.flags & HDLC_FLAG_AUTO_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) val |= BIT5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) write_reg(info, CHA + XBCH, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) if (info->params.flags & HDLC_FLAG_AUTO_CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) irq_enable(info, CHA, IRQ_CTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) /* MODE:03 RAC Receiver Active, 1=active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) set_reg_bits(info, CHA + MODE, BIT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) enable_auxclk(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) if (info->params.flags & HDLC_FLAG_AUTO_CTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) irq_enable(info, CHB, IRQ_CTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) /* PVR[3] 1=AUTO CTS active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) set_reg_bits(info, CHA + PVR, BIT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) clear_reg_bits(info, CHA + PVR, BIT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) irq_enable(info, CHA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) IRQ_RXEOM | IRQ_RXFIFO | IRQ_BREAK_ON | IRQ_RXTIME |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) IRQ_ALLSENT | IRQ_TXFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) issue_command(info, CHA, CMD_TXRESET + CMD_RXRESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) wait_command_complete(info, CHA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) read_reg16(info, CHA + ISR); /* clear pending IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) /* Set the HDLC idle mode for the transmitter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) static void tx_set_idle(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) /* Note: ESCC2 only supports flags and one idle modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) if (info->idle_mode == HDLC_TXIDLE_FLAGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) set_reg_bits(info, CHA + CCR1, BIT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) clear_reg_bits(info, CHA + CCR1, BIT3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) /* get state of the V24 status (input) signals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) static void get_signals(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) unsigned char status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) /* preserve RTS and DTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) info->serial_signals &= SerialSignal_RTS | SerialSignal_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) if (read_reg(info, CHB + VSTR) & BIT7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) info->serial_signals |= SerialSignal_DCD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) if (read_reg(info, CHB + STAR) & BIT1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) info->serial_signals |= SerialSignal_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) status = read_reg(info, CHA + PVR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) if (!(status & PVR_RI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) info->serial_signals |= SerialSignal_RI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) if (!(status & PVR_DSR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) info->serial_signals |= SerialSignal_DSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) /* Set the state of RTS and DTR based on contents of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) * serial_signals member of device extension.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) static void set_signals(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) unsigned char val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) val = read_reg(info, CHA + MODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) if (info->params.mode == MGSL_MODE_ASYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) if (info->serial_signals & SerialSignal_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) val &= ~BIT6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) val |= BIT6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) if (info->serial_signals & SerialSignal_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) val |= BIT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) val &= ~BIT2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) write_reg(info, CHA + MODE, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) if (info->serial_signals & SerialSignal_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) clear_reg_bits(info, CHA + PVR, PVR_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) set_reg_bits(info, CHA + PVR, PVR_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) static void rx_reset_buffers(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) RXBUF *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) info->rx_put = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) info->rx_get = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) info->rx_frame_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) for (i=0 ; i < info->rx_buf_count ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) buf = (RXBUF*)(info->rx_buf + (i * info->rx_buf_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) buf->status = buf->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) /* Attempt to return a received HDLC frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) * Only frames received without errors are returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) * Returns true if frame returned, otherwise false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) static bool rx_get_frame(MGSLPC_INFO *info, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) unsigned short status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) RXBUF *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) unsigned int framesize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) bool return_frame = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) if (info->rx_frame_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) buf = (RXBUF*)(info->rx_buf + (info->rx_get * info->rx_buf_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) status = buf->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) /* 07 VFR 1=valid frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) * 06 RDO 1=data overrun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) * 05 CRC 1=OK, 0=error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) * 04 RAB 1=frame aborted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) if ((status & 0xf0) != 0xA0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) if (!(status & BIT7) || (status & BIT4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) info->icount.rxabort++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) else if (status & BIT6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) info->icount.rxover++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) else if (!(status & BIT5)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) info->icount.rxcrc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) if (info->params.crc_type & HDLC_CRC_RETURN_EX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) return_frame = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) framesize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) info->netdev->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) info->netdev->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) return_frame = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) if (return_frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) framesize = buf->count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) if (debug_level >= DEBUG_LEVEL_BH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) printk("%s(%d):rx_get_frame(%s) status=%04X size=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) __FILE__, __LINE__, info->device_name, status, framesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) if (debug_level >= DEBUG_LEVEL_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) trace_block(info, buf->data, framesize, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) if (framesize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) if ((info->params.crc_type & HDLC_CRC_RETURN_EX &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) framesize+1 > info->max_frame_size) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) framesize > info->max_frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) info->icount.rxlong++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) if (status & BIT5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) info->icount.rxok++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) if (info->params.crc_type & HDLC_CRC_RETURN_EX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) *(buf->data + framesize) = status & BIT5 ? RX_OK:RX_CRC_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) ++framesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) if (info->netcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) hdlcdev_rx(info, buf->data, framesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) ldisc_receive_buf(tty, buf->data, info->flag_buf, framesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) buf->status = buf->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) info->rx_frame_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) info->rx_get++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) if (info->rx_get >= info->rx_buf_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) info->rx_get = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) static bool register_test(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) static unsigned char patterns[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) { 0x00, 0xff, 0xaa, 0x55, 0x69, 0x96, 0x0f };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) static unsigned int count = ARRAY_SIZE(patterns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) bool rc = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) reset_device(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) for (i = 0; i < count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) write_reg(info, XAD1, patterns[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) write_reg(info, XAD2, patterns[(i + 1) % count]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) if ((read_reg(info, XAD1) != patterns[i]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) (read_reg(info, XAD2) != patterns[(i + 1) % count])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) rc = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) static bool irq_test(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) unsigned long end_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) reset_device(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) info->testing_irq = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) hdlc_mode(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) info->irq_occurred = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) /* init hdlc mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) irq_enable(info, CHA, IRQ_TIMER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) write_reg(info, CHA + TIMR, 0); /* 512 cycles */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) issue_command(info, CHA, CMD_START_TIMER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) end_time=100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) while(end_time-- && !info->irq_occurred) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) msleep_interruptible(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) info->testing_irq = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) reset_device(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) return info->irq_occurred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) static int adapter_test(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) if (!register_test(info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) info->init_error = DiagStatus_AddressFailure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) printk("%s(%d):Register test failure for device %s Addr=%04X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) __FILE__, __LINE__, info->device_name, (unsigned short)(info->io_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) if (!irq_test(info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) info->init_error = DiagStatus_IrqFailure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) printk("%s(%d):Interrupt test failure for device %s IRQ=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) __FILE__, __LINE__, info->device_name, (unsigned short)(info->irq_level));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) return -ENODEV;
^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) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) printk("%s(%d):device %s passed diagnostics\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) static void trace_block(MGSLPC_INFO *info,const char* data, int count, int xmit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) int linecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) if (xmit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) printk("%s tx data:\n", info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) printk("%s rx data:\n", info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) while(count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) if (count > 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) linecount = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) linecount = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) for(i=0;i<linecount;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) printk("%02X ", (unsigned char)data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) for(;i<17;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) printk(" ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) for(i=0;i<linecount;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) if (data[i]>=040 && data[i]<=0176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) printk("%c", data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) printk(".");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) data += linecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) count -= linecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) /* HDLC frame time out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) * update stats and do tx completion processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) static void tx_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) MGSLPC_INFO *info = from_timer(info, t, tx_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) printk("%s(%d):tx_timeout(%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) __FILE__, __LINE__, info->device_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) if (info->tx_active &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) info->params.mode == MGSL_MODE_HDLC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) info->icount.txtimeout++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) info->tx_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) info->tx_count = info->tx_put = info->tx_get = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) if (info->netcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) hdlcdev_tx_done(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) struct tty_struct *tty = tty_port_tty_get(&info->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) bh_transmit(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) #if SYNCLINK_GENERIC_HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) * set encoding and frame check sequence (FCS) options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) * dev pointer to network device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) * encoding serial encoding setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) * parity FCS setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) * returns 0 if success, otherwise error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) unsigned short parity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) MGSLPC_INFO *info = dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) unsigned char new_encoding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) unsigned short new_crctype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) /* return error if TTY interface open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) if (info->port.count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) switch (encoding)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) case ENCODING_NRZ: new_encoding = HDLC_ENCODING_NRZ; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) case ENCODING_NRZI: new_encoding = HDLC_ENCODING_NRZI_SPACE; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) case ENCODING_FM_MARK: new_encoding = HDLC_ENCODING_BIPHASE_MARK; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) case ENCODING_FM_SPACE: new_encoding = HDLC_ENCODING_BIPHASE_SPACE; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) case ENCODING_MANCHESTER: new_encoding = HDLC_ENCODING_BIPHASE_LEVEL; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) default: return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) switch (parity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) case PARITY_NONE: new_crctype = HDLC_CRC_NONE; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) case PARITY_CRC16_PR1_CCITT: new_crctype = HDLC_CRC_16_CCITT; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) case PARITY_CRC32_PR1_CCITT: new_crctype = HDLC_CRC_32_CCITT; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) default: return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) info->params.encoding = new_encoding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) info->params.crc_type = new_crctype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) /* if network interface up, reprogram hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) if (info->netcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) tty = tty_port_tty_get(&info->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) mgslpc_program_hw(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) * called by generic HDLC layer to send frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) * skb socket buffer containing HDLC frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) * dev pointer to network device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) static netdev_tx_t hdlcdev_xmit(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) MGSLPC_INFO *info = dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) printk(KERN_INFO "%s:hdlc_xmit(%s)\n", __FILE__, dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) /* stop sending until this frame completes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) /* copy data to device buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) skb_copy_from_linear_data(skb, info->tx_buf, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) info->tx_get = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) info->tx_put = info->tx_count = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) /* update network statistics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) dev->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) dev->stats.tx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) /* done with socket buffer, so free it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) /* save start time for transmit timeout detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) netif_trans_update(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) /* start hardware transmitter if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) if (!info->tx_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) struct tty_struct *tty = tty_port_tty_get(&info->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) tx_start(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) * called by network layer when interface enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) * claim resources and initialize hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) * dev pointer to network device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) * returns 0 if success, otherwise error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) static int hdlcdev_open(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) MGSLPC_INFO *info = dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) printk("%s:hdlcdev_open(%s)\n", __FILE__, dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) /* generic HDLC layer open processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) rc = hdlc_open(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) if (rc != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) /* arbitrate between network and tty opens */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) spin_lock_irqsave(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) if (info->port.count != 0 || info->netcount != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) printk(KERN_WARNING "%s: hdlc_open returning busy\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) spin_unlock_irqrestore(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) info->netcount=1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) spin_unlock_irqrestore(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) tty = tty_port_tty_get(&info->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) /* claim resources and init adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) rc = startup(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) if (rc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) spin_lock_irqsave(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) info->netcount=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) spin_unlock_irqrestore(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) /* assert RTS and DTR, apply hardware settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) mgslpc_program_hw(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) /* enable network layer transmit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) netif_trans_update(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) netif_start_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) /* inform generic HDLC layer of current DCD status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) get_signals(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) if (info->serial_signals & SerialSignal_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) netif_carrier_on(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) netif_carrier_off(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) * called by network layer when interface is disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) * shutdown hardware and release resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) * dev pointer to network device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) * returns 0 if success, otherwise error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) static int hdlcdev_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) MGSLPC_INFO *info = dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) struct tty_struct *tty = tty_port_tty_get(&info->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) printk("%s:hdlcdev_close(%s)\n", __FILE__, dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) /* shutdown adapter and release resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) shutdown(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) hdlc_close(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) spin_lock_irqsave(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) info->netcount=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) spin_unlock_irqrestore(&info->netlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) * called by network layer to process IOCTL call to network device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) * dev pointer to network device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) * ifr pointer to network interface request structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) * cmd IOCTL command code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) * returns 0 if success, otherwise error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) const size_t size = sizeof(sync_serial_settings);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) sync_serial_settings new_line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) MGSLPC_INFO *info = dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) unsigned int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) printk("%s:hdlcdev_ioctl(%s)\n", __FILE__, dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) /* return error if TTY interface open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) if (info->port.count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) if (cmd != SIOCWANDEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) return hdlc_ioctl(dev, ifr, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) memset(&new_line, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) switch(ifr->ifr_settings.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) case IF_GET_IFACE: /* return current sync_serial_settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) if (ifr->ifr_settings.size < size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) ifr->ifr_settings.size = size; /* data size wanted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) flags = info->params.flags & (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) switch (flags){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) 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 4104) 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 4105) 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 4106) 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 4107) default: new_line.clock_type = CLOCK_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) new_line.clock_rate = info->params.clock_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) new_line.loopback = info->params.loopback ? 1:0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) if (copy_to_user(line, &new_line, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) case IF_IFACE_SYNC_SERIAL: /* set sync_serial_settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) if(!capable(CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) if (copy_from_user(&new_line, line, size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) switch (new_line.clock_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) case CLOCK_EXT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) case CLOCK_TXFROMRX: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) case CLOCK_INT: flags = HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) case CLOCK_TXINT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) case CLOCK_DEFAULT: flags = info->params.flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) default: return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) if (new_line.loopback != 0 && new_line.loopback != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) info->params.flags &= ~(HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142) HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143) HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144) HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145) info->params.flags |= flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) info->params.loopback = new_line.loopback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) if (flags & (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) info->params.clock_speed = new_line.clock_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) info->params.clock_speed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) /* if network interface up, reprogram hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) if (info->netcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) struct tty_struct *tty = tty_port_tty_get(&info->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) mgslpc_program_hw(info, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) return hdlc_ioctl(dev, ifr, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) }
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) * called by network layer when transmit timeout is detected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) * dev pointer to network device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) static void hdlcdev_tx_timeout(struct net_device *dev, unsigned int txqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) MGSLPC_INFO *info = dev_to_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) printk("hdlcdev_tx_timeout(%s)\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) dev->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) dev->stats.tx_aborted_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) spin_lock_irqsave(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) tx_stop(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) spin_unlock_irqrestore(&info->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) * called by device driver when transmit completes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) * reenable network layer transmit if stopped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) * info pointer to device instance information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) static void hdlcdev_tx_done(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198) if (netif_queue_stopped(info->netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199) netif_wake_queue(info->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) * called by device driver when frame received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) * pass frame to network layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) * info pointer to device instance information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) * buf pointer to buffer contianing frame data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) * size count of data bytes in buf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) struct sk_buff *skb = dev_alloc_skb(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) struct net_device *dev = info->netdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) if (debug_level >= DEBUG_LEVEL_INFO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) printk("hdlcdev_rx(%s)\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) if (skb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) dev->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) skb_put_data(skb, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) skb->protocol = hdlc_type_trans(skb, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) dev->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) dev->stats.rx_bytes += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) static const struct net_device_ops hdlcdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) .ndo_open = hdlcdev_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) .ndo_stop = hdlcdev_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) .ndo_start_xmit = hdlc_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) .ndo_do_ioctl = hdlcdev_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) .ndo_tx_timeout = hdlcdev_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) };
^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) * called by device driver when adding device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) * do generic HDLC initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) * info pointer to device instance information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) * returns 0 if success, otherwise error code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) static int hdlcdev_init(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) hdlc_device *hdlc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) /* allocate and initialize network and HDLC layer objects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) dev = alloc_hdlcdev(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) if (dev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) printk(KERN_ERR "%s:hdlc device allocation failure\n", __FILE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) /* for network layer reporting purposes only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) dev->base_addr = info->io_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) dev->irq = info->irq_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) /* network layer callbacks and settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) dev->netdev_ops = &hdlcdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) dev->watchdog_timeo = 10 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) dev->tx_queue_len = 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) /* generic HDLC layer callbacks and settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) hdlc->attach = hdlcdev_attach;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) hdlc->xmit = hdlcdev_xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) /* register objects with HDLC layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) rc = register_hdlc_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) printk(KERN_WARNING "%s:unable to register hdlc device\n", __FILE__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) info->netdev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) * called by device driver when removing device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) * do generic HDLC cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) * info pointer to device instance information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) static void hdlcdev_exit(MGSLPC_INFO *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) unregister_hdlc_device(info->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) free_netdev(info->netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) info->netdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) #endif /* CONFIG_HDLC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304)