^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Driver for Option High Speed Mobile Devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2008 Option International
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Filip Aben <f.aben@option.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Denis Joseph Barrow <d.barow@option.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Jan Dumon <j.dumon@option.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2007 Andrew Bird (Sphere Systems Ltd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * <ajb@spheresystems.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Copyright (C) 2008 Novell, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Description of the device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Interface 0: Contains the IP network interface on the bulk end points.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * The multiplexed serial ports are using the interrupt and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * control endpoints.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Interrupt contains a bitmap telling which multiplexed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * serialport needs servicing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Interface 1: Diagnostics port, uses bulk only, do not submit urbs until the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * port is opened, as this have a huge impact on the network port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * throughput.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * Interface 2: Standard modem interface - circuit switched interface, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * can be used to make a standard ppp connection however it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * should not be used in conjunction with the IP network interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * enabled for USB performance reasons i.e. if using this set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * ideally disable_net=1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/tty_driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/kmod.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <linux/rfkill.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/usb/cdc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <net/arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define MOD_AUTHOR "Option Wireless"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define MOD_DESCRIPTION "USB High Speed Option driver"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define HSO_MAX_NET_DEVICES 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define HSO__MAX_MTU 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define DEFAULT_MTU 1500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define DEFAULT_MRU 1500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define CTRL_URB_RX_SIZE 1024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define CTRL_URB_TX_SIZE 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define BULK_URB_RX_SIZE 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define BULK_URB_TX_SIZE 8192
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define MUX_BULK_RX_BUF_SIZE HSO__MAX_MTU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define MUX_BULK_TX_BUF_SIZE HSO__MAX_MTU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define MUX_BULK_RX_BUF_COUNT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define USB_TYPE_OPTION_VENDOR 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* These definitions are used with the struct hso_net flags element */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* - use *_bit operations on it. (bit indices not values.) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define HSO_NET_RUNNING 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define HSO_NET_TX_TIMEOUT (HZ*10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define HSO_SERIAL_MAGIC 0x48534f31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* Number of ttys to handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define HSO_SERIAL_TTY_MINORS 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define MAX_RX_URBS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* Debugging functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define hso_dbg(lvl, fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if ((lvl) & debug) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) pr_info("[%d:%s] " fmt, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) __LINE__, __func__, ##__VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Enumerators */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) enum pkt_parse_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) WAIT_IP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) WAIT_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) WAIT_SYNC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* Structs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct hso_shared_int {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct usb_endpoint_descriptor *intr_endp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) void *shared_intr_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct urb *shared_intr_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct usb_device *usb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int use_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int ref_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct mutex shared_int_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct hso_net {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct hso_device *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct net_device *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct rfkill *rfkill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) char name[24];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct usb_endpoint_descriptor *in_endp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct usb_endpoint_descriptor *out_endp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct urb *mux_bulk_rx_urb_pool[MUX_BULK_RX_BUF_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct urb *mux_bulk_tx_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) void *mux_bulk_rx_buf_pool[MUX_BULK_RX_BUF_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) void *mux_bulk_tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct sk_buff *skb_rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct sk_buff *skb_tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) enum pkt_parse_state rx_parse_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) spinlock_t net_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unsigned short rx_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) unsigned short rx_buf_missing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct iphdr rx_ip_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) enum rx_ctrl_state{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) RX_IDLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) RX_SENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) RX_PENDING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define BM_REQUEST_TYPE (0xa1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define B_NOTIFICATION (0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define W_VALUE (0x0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define W_LENGTH (0x2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define B_OVERRUN (0x1<<6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define B_PARITY (0x1<<5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define B_FRAMING (0x1<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define B_RING_SIGNAL (0x1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define B_BREAK (0x1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define B_TX_CARRIER (0x1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define B_RX_CARRIER (0x1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct hso_serial_state_notification {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u8 bmRequestType;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u8 bNotification;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) u16 wValue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u16 wIndex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) u16 wLength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) u16 UART_state_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct hso_tiocmget {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) wait_queue_head_t waitq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int intr_completed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct usb_endpoint_descriptor *endp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct hso_serial_state_notification *serial_state_notification;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) u16 prev_UART_state_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct uart_icount icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct hso_serial {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct hso_device *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) u8 minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct hso_shared_int *shared_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* rx/tx urb could be either a bulk urb or a control urb depending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) on which serial port it is used on. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct urb *rx_urb[MAX_RX_URBS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u8 num_rx_urbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) u8 *rx_data[MAX_RX_URBS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) u16 rx_data_length; /* should contain allocated length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct urb *tx_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) u8 *tx_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) u8 *tx_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u16 tx_data_length; /* should contain allocated length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u16 tx_data_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) u16 tx_buffer_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct usb_ctrlrequest ctrl_req_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct usb_ctrlrequest ctrl_req_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct usb_endpoint_descriptor *in_endp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct usb_endpoint_descriptor *out_endp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) enum rx_ctrl_state rx_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) u8 rts_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) u8 dtr_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) unsigned tx_urb_used:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct tty_port port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /* from usb_serial_port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) spinlock_t serial_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) int (*write_data) (struct hso_serial *serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct hso_tiocmget *tiocmget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /* Hacks required to get flow control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * working on the serial receive buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * so as not to drop characters on the floor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) int curr_rx_urb_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u8 rx_urb_filled[MAX_RX_URBS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct tasklet_struct unthrottle_tasklet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct hso_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct hso_serial *dev_serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct hso_net *dev_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) } port_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) u32 port_spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) u8 is_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) u8 usb_gone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct work_struct async_get_intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct work_struct async_put_intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct usb_device *usb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct usb_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct kref ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* Type of interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #define HSO_INTF_MASK 0xFF00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #define HSO_INTF_MUX 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) #define HSO_INTF_BULK 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /* Type of port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #define HSO_PORT_MASK 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) #define HSO_PORT_NO_PORT 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #define HSO_PORT_CONTROL 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) #define HSO_PORT_APP 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) #define HSO_PORT_GPS 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #define HSO_PORT_PCSC 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #define HSO_PORT_APP2 0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) #define HSO_PORT_GPS_CONTROL 0x6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #define HSO_PORT_MSD 0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) #define HSO_PORT_VOICE 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #define HSO_PORT_DIAG2 0x9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #define HSO_PORT_DIAG 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) #define HSO_PORT_MODEM 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) #define HSO_PORT_NETWORK 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /* Additional device info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #define HSO_INFO_MASK 0xFF000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #define HSO_INFO_CRC_BUG 0x01000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /* Prototypes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* Serial driver functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int hso_serial_tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) unsigned int set, unsigned int clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static void ctrl_callback(struct urb *urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static void hso_kick_transmit(struct hso_serial *serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* Helper functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct usb_device *usb, gfp_t gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static void handle_usb_error(int status, const char *function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct hso_device *hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) int type, int dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static void hso_free_interface(struct usb_interface *intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static int hso_stop_serial_device(struct hso_device *hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static int hso_start_net_device(struct hso_device *hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static void hso_free_shared_int(struct hso_shared_int *shared_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static int hso_stop_net_device(struct hso_device *hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static void hso_serial_ref_free(struct kref *ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static void hso_std_serial_read_bulk_callback(struct urb *urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static int hso_mux_serial_read(struct hso_serial *serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static void async_get_intf(struct work_struct *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static void async_put_intf(struct work_struct *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static int hso_put_activity(struct hso_device *hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static int hso_get_activity(struct hso_device *hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static void tiocmget_intr_callback(struct urb *urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* Helping functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /*****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* #define DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static inline struct hso_net *dev2net(struct hso_device *hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return hso_dev->port_data.dev_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static inline struct hso_serial *dev2ser(struct hso_device *hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return hso_dev->port_data.dev_serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* Debugging functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static void dbg_dump(int line_count, const char *func_name, unsigned char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static char name[255];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) sprintf(name, "hso[%d:%s]", line_count, func_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) print_hex_dump_bytes(name, DUMP_PREFIX_NONE, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) #define DUMP(buf_, len_) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) dbg_dump(__LINE__, __func__, (unsigned char *)buf_, len_)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) #define DUMP1(buf_, len_) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (0x01 & debug) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) DUMP(buf_, len_); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) #define DUMP(buf_, len_)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) #define DUMP1(buf_, len_)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* module parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static int tty_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static int disable_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* driver info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static const char driver_name[] = "hso";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static const char tty_filename[] = "ttyHS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static const char *version = __FILE__ ": " MOD_AUTHOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* the usb driver itself (registered in hso_init) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static struct usb_driver hso_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* serial structures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static struct tty_driver *tty_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static struct hso_device *serial_table[HSO_SERIAL_TTY_MINORS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static struct hso_device *network_table[HSO_MAX_NET_DEVICES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static spinlock_t serial_table_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static const s32 default_port_spec[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) HSO_INTF_MUX | HSO_PORT_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) HSO_INTF_BULK | HSO_PORT_DIAG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) HSO_INTF_BULK | HSO_PORT_MODEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static const s32 icon321_port_spec[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) HSO_INTF_MUX | HSO_PORT_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) HSO_INTF_BULK | HSO_PORT_DIAG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) HSO_INTF_BULK | HSO_PORT_MODEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) HSO_INTF_BULK | HSO_PORT_DIAG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) #define default_port_device(vendor, product) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) USB_DEVICE(vendor, product), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .driver_info = (kernel_ulong_t)default_port_spec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) #define icon321_port_device(vendor, product) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) USB_DEVICE(vendor, product), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) .driver_info = (kernel_ulong_t)icon321_port_spec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* list of devices we support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static const struct usb_device_id hso_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {default_port_device(0x0af0, 0x6711)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {default_port_device(0x0af0, 0x6731)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {default_port_device(0x0af0, 0x6751)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {default_port_device(0x0af0, 0x6771)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {default_port_device(0x0af0, 0x6791)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {default_port_device(0x0af0, 0x6811)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {default_port_device(0x0af0, 0x6911)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {default_port_device(0x0af0, 0x6951)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) {default_port_device(0x0af0, 0x6971)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {default_port_device(0x0af0, 0x7011)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {default_port_device(0x0af0, 0x7031)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {default_port_device(0x0af0, 0x7051)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {default_port_device(0x0af0, 0x7071)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {default_port_device(0x0af0, 0x7111)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {default_port_device(0x0af0, 0x7211)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {default_port_device(0x0af0, 0x7251)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {default_port_device(0x0af0, 0x7271)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {default_port_device(0x0af0, 0x7311)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {default_port_device(0x0af0, 0xc031)}, /* Icon-Edge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {icon321_port_device(0x0af0, 0xd013)}, /* Module HSxPA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {icon321_port_device(0x0af0, 0xd031)}, /* Icon-321 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {icon321_port_device(0x0af0, 0xd033)}, /* Icon-322 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {USB_DEVICE(0x0af0, 0x7301)}, /* GE40x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {USB_DEVICE(0x0af0, 0x7361)}, /* GE40x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {USB_DEVICE(0x0af0, 0x7381)}, /* GE40x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {USB_DEVICE(0x0af0, 0x7401)}, /* GI 0401 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {USB_DEVICE(0x0af0, 0x7701)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {USB_DEVICE(0x0af0, 0x7706)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {USB_DEVICE(0x0af0, 0x7801)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {USB_DEVICE(0x0af0, 0x7901)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {USB_DEVICE(0x0af0, 0x7A01)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {USB_DEVICE(0x0af0, 0x7A05)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {USB_DEVICE(0x0af0, 0x8200)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {USB_DEVICE(0x0af0, 0x8201)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {USB_DEVICE(0x0af0, 0x8300)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {USB_DEVICE(0x0af0, 0x8302)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {USB_DEVICE(0x0af0, 0x8304)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {USB_DEVICE(0x0af0, 0x8400)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {USB_DEVICE(0x0af0, 0x8600)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {USB_DEVICE(0x0af0, 0x8800)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {USB_DEVICE(0x0af0, 0x8900)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {USB_DEVICE(0x0af0, 0x9000)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {USB_DEVICE(0x0af0, 0x9200)}, /* Option GTM671WFS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {USB_DEVICE(0x0af0, 0xd035)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {USB_DEVICE(0x0af0, 0xd055)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {USB_DEVICE(0x0af0, 0xd155)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {USB_DEVICE(0x0af0, 0xd255)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {USB_DEVICE(0x0af0, 0xd057)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {USB_DEVICE(0x0af0, 0xd157)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {USB_DEVICE(0x0af0, 0xd257)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {USB_DEVICE(0x0af0, 0xd357)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {USB_DEVICE(0x0af0, 0xd058)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {USB_DEVICE(0x0af0, 0xc100)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) MODULE_DEVICE_TABLE(usb, hso_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* Sysfs attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static ssize_t hso_sysfs_show_porttype(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct hso_device *hso_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) char *port_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (!hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) switch (hso_dev->port_spec & HSO_PORT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) case HSO_PORT_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) port_name = "Control";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) case HSO_PORT_APP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) port_name = "Application";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) case HSO_PORT_APP2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) port_name = "Application2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) case HSO_PORT_GPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) port_name = "GPS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) case HSO_PORT_GPS_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) port_name = "GPS Control";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) case HSO_PORT_PCSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) port_name = "PCSC";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) case HSO_PORT_DIAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) port_name = "Diagnostic";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) case HSO_PORT_DIAG2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) port_name = "Diagnostic2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) case HSO_PORT_MODEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) port_name = "Modem";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) case HSO_PORT_NETWORK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) port_name = "Network";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) port_name = "Unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return sprintf(buf, "%s\n", port_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static DEVICE_ATTR(hsotype, 0444, hso_sysfs_show_porttype, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static struct attribute *hso_serial_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) &dev_attr_hsotype.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ATTRIBUTE_GROUPS(hso_serial_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static int hso_urb_to_index(struct hso_serial *serial, struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) for (idx = 0; idx < serial->num_rx_urbs; idx++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (serial->rx_urb[idx] == urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) dev_err(serial->parent->dev, "hso_urb_to_index failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return -1;
^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) /* converts mux value to a port spec value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) static u32 hso_mux_to_port(int mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) u32 result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) switch (mux) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) case 0x1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) result = HSO_PORT_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) case 0x2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) result = HSO_PORT_APP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) case 0x4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) result = HSO_PORT_PCSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) case 0x8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) result = HSO_PORT_GPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) case 0x10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) result = HSO_PORT_APP2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) result = HSO_PORT_NO_PORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /* converts port spec value to a mux value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) static u32 hso_port_to_mux(int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) u32 result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) switch (port & HSO_PORT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) case HSO_PORT_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) result = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) case HSO_PORT_APP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) result = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) case HSO_PORT_PCSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) result = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) case HSO_PORT_GPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) result = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) case HSO_PORT_APP2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) result = 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) result = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static struct hso_serial *get_serial_by_shared_int_and_type(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct hso_shared_int *shared_int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) int mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) int i, port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) port = hso_mux_to_port(mux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (serial_table[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) (dev2ser(serial_table[i])->shared_int == shared_int) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ((serial_table[i]->port_spec & HSO_PORT_MASK) == port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return dev2ser(serial_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static struct hso_serial *get_serial_by_index(unsigned index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct hso_serial *serial = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) spin_lock_irqsave(&serial_table_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (serial_table[index])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) serial = dev2ser(serial_table[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) spin_unlock_irqrestore(&serial_table_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static int obtain_minor(struct hso_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) spin_lock_irqsave(&serial_table_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) for (index = 0; index < HSO_SERIAL_TTY_MINORS; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (serial_table[index] == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) serial_table[index] = serial->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) serial->minor = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) spin_unlock_irqrestore(&serial_table_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) spin_unlock_irqrestore(&serial_table_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) pr_err("%s: no free serial devices in table\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return -1;
^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 void release_minor(struct hso_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) spin_lock_irqsave(&serial_table_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) serial_table[serial->minor] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) spin_unlock_irqrestore(&serial_table_lock, flags);
^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 void handle_usb_error(int status, const char *function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) struct hso_device *hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) char *explanation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) case -ENODEV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) explanation = "no device";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) explanation = "endpoint not enabled";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) case -EPIPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) explanation = "endpoint stalled";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) case -ENOSPC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) explanation = "not enough bandwidth";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) explanation = "device disabled";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) case -EHOSTUNREACH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) explanation = "device suspended";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) case -EINVAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) case -EAGAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) case -EFBIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) case -EMSGSIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) explanation = "internal error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) case -EILSEQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) case -EPROTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) case -ETIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) case -ETIMEDOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) explanation = "protocol error";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) usb_queue_reset_device(hso_dev->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) explanation = "unknown status";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /* log a meaningful explanation of an USB status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) hso_dbg(0x1, "%s: received USB status - %s (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) function, explanation, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /* Network interface functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /* called when net interface is brought up by ifconfig */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) static int hso_net_open(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct hso_net *odev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (!odev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) dev_err(&net->dev, "No net device !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return -ENODEV;
^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) odev->skb_tx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /* setup environment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) spin_lock_irqsave(&odev->net_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) odev->rx_parse_state = WAIT_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) odev->rx_buf_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) odev->rx_buf_missing = sizeof(struct iphdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) spin_unlock_irqrestore(&odev->net_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /* We are up and running. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) set_bit(HSO_NET_RUNNING, &odev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) hso_start_net_device(odev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /* Tell the kernel we are ready to start receiving from it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) netif_start_queue(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) /* called when interface is brought down by ifconfig */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static int hso_net_close(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) struct hso_net *odev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /* we don't need the queue anymore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) netif_stop_queue(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) /* no longer running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) clear_bit(HSO_NET_RUNNING, &odev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) hso_stop_net_device(odev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /* done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) /* USB tells is xmit done, we should start the netqueue again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static void write_bulk_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) struct hso_net *odev = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /* Sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (!odev || !test_bit(HSO_NET_RUNNING, &odev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) dev_err(&urb->dev->dev, "%s: device not running\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) /* Do we still have a valid kernel network device? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (!netif_device_present(odev->net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) dev_err(&urb->dev->dev, "%s: net device not present\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) /* log status, but don't act on it, we don't need to resubmit anything
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * anyhow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) handle_usb_error(status, __func__, odev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) hso_put_activity(odev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) /* Tell the network interface we are ready for another frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) netif_wake_queue(odev->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /* called by kernel when we need to transmit a packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct hso_net *odev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) /* Tell the kernel, "No more frames 'til we are done with this one." */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) netif_stop_queue(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (hso_get_activity(odev->parent) == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) odev->skb_tx_buf = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /* log if asked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) DUMP1(skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) /* Copy it from kernel memory to OUR memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) memcpy(odev->mux_bulk_tx_buf, skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) hso_dbg(0x1, "len: %d/%d\n", skb->len, MUX_BULK_TX_BUF_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) /* Fill in the URB for shipping it out. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) usb_fill_bulk_urb(odev->mux_bulk_tx_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) odev->parent->usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) usb_sndbulkpipe(odev->parent->usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) odev->out_endp->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) bEndpointAddress & 0x7F),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) odev->mux_bulk_tx_buf, skb->len, write_bulk_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) odev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) /* Deal with the Zero Length packet problem, I hope */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) odev->mux_bulk_tx_urb->transfer_flags |= URB_ZERO_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) /* Send the URB on its merry way. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) dev_warn(&odev->parent->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) "failed mux_bulk_tx_urb %d\n", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) net->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) netif_start_queue(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) net->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) net->stats.tx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) /* we're done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static const struct ethtool_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) .get_link = ethtool_op_get_link
^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) /* called when a packet did not ack after watchdogtimeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static void hso_net_tx_timeout(struct net_device *net, unsigned int txqueue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) struct hso_net *odev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (!odev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /* Tell syslog we are hosed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) dev_warn(&net->dev, "Tx timed out.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) /* Tear the waiting frame off the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (odev->mux_bulk_tx_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) usb_unlink_urb(odev->mux_bulk_tx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) /* Update statistics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) net->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) /* make a real packet from the received USB buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) unsigned int count, unsigned char is_eop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) unsigned short temp_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) unsigned short buffer_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) unsigned short frame_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) /* log if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) hso_dbg(0x1, "Rx %d bytes\n", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) DUMP(ip_pkt, min(128, (int)count));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) while (count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) switch (odev->rx_parse_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) case WAIT_IP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) /* waiting for IP header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) /* wanted bytes - size of ip header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) temp_bytes =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) (count <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) odev->rx_buf_missing) ? count : odev->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) rx_buf_missing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) memcpy(((unsigned char *)(&odev->rx_ip_hdr)) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) odev->rx_buf_size, ip_pkt + buffer_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) temp_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) odev->rx_buf_size += temp_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) buffer_offset += temp_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) odev->rx_buf_missing -= temp_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) count -= temp_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (!odev->rx_buf_missing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) /* header is complete allocate an sk_buffer and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) * continue to WAIT_DATA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) frame_len = ntohs(odev->rx_ip_hdr.tot_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if ((frame_len > DEFAULT_MRU) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) (frame_len < sizeof(struct iphdr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) dev_err(&odev->net->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) "Invalid frame (%d) length\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) frame_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) odev->rx_parse_state = WAIT_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) /* Allocate an sk_buff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) odev->skb_rx_buf = netdev_alloc_skb(odev->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) frame_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (!odev->skb_rx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /* We got no receive buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) hso_dbg(0x1, "could not allocate memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) odev->rx_parse_state = WAIT_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) /* Copy what we got so far. make room for iphdr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * after tail. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) skb_put_data(odev->skb_rx_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) (char *)&(odev->rx_ip_hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) sizeof(struct iphdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) /* ETH_HLEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) odev->rx_buf_size = sizeof(struct iphdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) /* Filip actually use .tot_len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) odev->rx_buf_missing =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) frame_len - sizeof(struct iphdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) odev->rx_parse_state = WAIT_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) case WAIT_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) temp_bytes = (count < odev->rx_buf_missing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) ? count : odev->rx_buf_missing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) /* Copy the rest of the bytes that are left in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * buffer into the waiting sk_buf. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) /* Make room for temp_bytes after tail. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) skb_put_data(odev->skb_rx_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) ip_pkt + buffer_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) temp_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) odev->rx_buf_missing -= temp_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) count -= temp_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) buffer_offset += temp_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) odev->rx_buf_size += temp_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) if (!odev->rx_buf_missing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /* Packet is complete. Inject into stack. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) /* We have IP packet here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) skb_reset_mac_header(odev->skb_rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) /* Ship it off to the kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) netif_rx(odev->skb_rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /* No longer our buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) odev->skb_rx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) /* update out statistics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) odev->net->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) odev->net->stats.rx_bytes += odev->rx_buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) odev->rx_buf_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) odev->rx_buf_missing = sizeof(struct iphdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) odev->rx_parse_state = WAIT_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) case WAIT_SYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) hso_dbg(0x1, " W_S\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) hso_dbg(0x1, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) /* Recovery mechanism for WAIT_SYNC state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (is_eop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (odev->rx_parse_state == WAIT_SYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) odev->rx_parse_state = WAIT_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) odev->rx_buf_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) odev->rx_buf_missing = sizeof(struct iphdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) static void fix_crc_bug(struct urb *urb, __le16 max_packet_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) static const u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) u32 rest = urb->actual_length % le16_to_cpu(max_packet_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (((rest == 5) || (rest == 6)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) !memcmp(((u8 *)urb->transfer_buffer) + urb->actual_length - 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) crc_check, 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) urb->actual_length -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) /* Moving data from usb to kernel (in interrupt state) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) static void read_bulk_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) struct hso_net *odev = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) struct net_device *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) /* is al ok? (Filip: Who's Al ?) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) handle_usb_error(status, __func__, odev->parent);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) /* Sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (!odev || !test_bit(HSO_NET_RUNNING, &odev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) hso_dbg(0x1, "BULK IN callback but driver is not active!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) usb_mark_last_busy(urb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) net = odev->net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (!netif_device_present(net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) /* Somebody killed our network interface... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (odev->parent->port_spec & HSO_INFO_CRC_BUG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) fix_crc_bug(urb, odev->in_endp->wMaxPacketSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* do we even have a packet? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (urb->actual_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) /* Handle the IP stream, add header and push it onto network
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) * stack if the packet is complete. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) spin_lock_irqsave(&odev->net_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) packetizeRx(odev, urb->transfer_buffer, urb->actual_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) (urb->transfer_buffer_length >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) urb->actual_length) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) spin_unlock_irqrestore(&odev->net_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) /* We are done with this URB, resubmit it. Prep the USB to wait for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) * another frame. Reuse same as received. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) usb_fill_bulk_urb(urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) odev->parent->usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) usb_rcvbulkpipe(odev->parent->usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) odev->in_endp->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) bEndpointAddress & 0x7F),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) urb->transfer_buffer, MUX_BULK_RX_BUF_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) read_bulk_callback, odev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) /* Give this to the USB subsystem so it can tell us when more data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) * arrives. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) result = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) dev_warn(&odev->parent->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) "%s failed submit mux_bulk_rx_urb %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) /* Serial driver functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) static void hso_init_termios(struct ktermios *termios)
^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) * The default requirements for this device are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) termios->c_iflag &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) ~(IGNBRK /* disable ignore break */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) | BRKINT /* disable break causes interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) | PARMRK /* disable mark parity errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) | ISTRIP /* disable clear high bit of input characters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) | INLCR /* disable translate NL to CR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) | IGNCR /* disable ignore CR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) | ICRNL /* disable translate CR to NL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) | IXON); /* disable enable XON/XOFF flow control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) /* disable postprocess output characters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) termios->c_oflag &= ~OPOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) termios->c_lflag &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) ~(ECHO /* disable echo input characters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) | ECHONL /* disable echo new line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) | ICANON /* disable erase, kill, werase, and rprnt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) special characters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) | ISIG /* disable interrupt, quit, and suspend special
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) characters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) | IEXTEN); /* disable non-POSIX special characters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) termios->c_cflag &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) ~(CSIZE /* no size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) | PARENB /* disable parity bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) | CBAUD /* clear current baud rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) | CBAUDEX); /* clear current buad rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) termios->c_cflag |= CS8; /* character size 8 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /* baud rate 115200 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) tty_termios_encode_baud_rate(termios, 115200, 115200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) static void _hso_serial_set_termios(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) struct hso_serial *serial = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (!serial) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) pr_err("%s: no tty structures", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) hso_dbg(0x8, "port %d\n", serial->minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) * Fix up unsupported bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) tty->termios.c_iflag &= ~IXON; /* disable enable XON/XOFF flow control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) tty->termios.c_cflag &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) ~(CSIZE /* no size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) | PARENB /* disable parity bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) | CBAUD /* clear current baud rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) | CBAUDEX); /* clear current buad rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) tty->termios.c_cflag |= CS8; /* character size 8 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) /* baud rate 115200 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) tty_encode_baud_rate(tty, 115200, 115200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) /* We are done with this URB, resubmit it. Prep the USB to wait for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) * another frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) usb_fill_bulk_urb(urb, serial->parent->usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) usb_rcvbulkpipe(serial->parent->usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) serial->in_endp->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) bEndpointAddress & 0x7F),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) urb->transfer_buffer, serial->rx_data_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) hso_std_serial_read_bulk_callback, serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /* Give this to the USB subsystem so it can tell us when more data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) * arrives. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) result = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) dev_err(&urb->dev->dev, "%s failed submit serial rx_urb %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^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 put_rxbuf_data_and_resubmit_bulk_urb(struct hso_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) struct urb *curr_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) while (serial->rx_urb_filled[serial->curr_rx_urb_idx]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) curr_urb = serial->rx_urb[serial->curr_rx_urb_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) count = put_rxbuf_data(curr_urb, serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if (count == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) serial->curr_rx_urb_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (serial->curr_rx_urb_idx >= serial->num_rx_urbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) serial->curr_rx_urb_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) hso_resubmit_rx_bulk_urb(serial, curr_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) static void put_rxbuf_data_and_resubmit_ctrl_urb(struct hso_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) urb = serial->rx_urb[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) if (serial->port.count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) count = put_rxbuf_data(urb, serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (count == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) /* Re issue a read as long as we receive data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (count == 0 && ((urb->actual_length != 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) (serial->rx_state == RX_PENDING))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) serial->rx_state = RX_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) hso_mux_serial_read(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) serial->rx_state = RX_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) /* read callback for Diag and CS port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) static void hso_std_serial_read_bulk_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) struct hso_serial *serial = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) hso_dbg(0x8, "--- Got serial_read_bulk callback %02x ---\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /* sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) if (!serial) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) hso_dbg(0x1, "serial == NULL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) handle_usb_error(status, __func__, serial->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) hso_dbg(0x1, "Actual length = %d\n", urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) DUMP1(urb->transfer_buffer, urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) /* Anyone listening? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) if (serial->port.count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (serial->parent->port_spec & HSO_INFO_CRC_BUG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) fix_crc_bug(urb, serial->in_endp->wMaxPacketSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) /* Valid data, handle RX data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) spin_lock_irqsave(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) put_rxbuf_data_and_resubmit_bulk_urb(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) spin_unlock_irqrestore(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) * This needs to be a tasklet otherwise we will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) * end up recursively calling this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) static void hso_unthrottle_tasklet(unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) struct hso_serial *serial = (struct hso_serial *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) spin_lock_irqsave(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) if ((serial->parent->port_spec & HSO_INTF_MUX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) put_rxbuf_data_and_resubmit_ctrl_urb(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) put_rxbuf_data_and_resubmit_bulk_urb(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) spin_unlock_irqrestore(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) static void hso_unthrottle(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) struct hso_serial *serial = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) tasklet_hi_schedule(&serial->unthrottle_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) /* open the requested serial port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) static int hso_serial_open(struct tty_struct *tty, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) struct hso_serial *serial = get_serial_by_index(tty->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) /* sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (serial == NULL || serial->magic != HSO_SERIAL_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) tty->driver_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) hso_dbg(0x1, "Failed to open port\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) mutex_lock(&serial->parent->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) result = usb_autopm_get_interface(serial->parent->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) if (result < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) goto err_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) hso_dbg(0x1, "Opening %d\n", serial->minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) /* setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) tty->driver_data = serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) tty_port_tty_set(&serial->port, tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) /* check for port already opened, if not set the termios */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) serial->port.count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (serial->port.count == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) serial->rx_state = RX_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) /* Force default termio settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) _hso_serial_set_termios(tty, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) tasklet_init(&serial->unthrottle_tasklet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) hso_unthrottle_tasklet,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) (unsigned long)serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) result = hso_start_serial_device(serial->parent, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) hso_stop_serial_device(serial->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) serial->port.count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) kref_get(&serial->parent->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) hso_dbg(0x1, "Port was already open\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) usb_autopm_put_interface(serial->parent->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) /* done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) hso_serial_tiocmset(tty, TIOCM_RTS | TIOCM_DTR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) err_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) mutex_unlock(&serial->parent->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) /* close the requested serial port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) static void hso_serial_close(struct tty_struct *tty, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) struct hso_serial *serial = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) u8 usb_gone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) hso_dbg(0x1, "Closing serial port\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) /* Open failed, no close cleanup required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) if (serial == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) mutex_lock(&serial->parent->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) usb_gone = serial->parent->usb_gone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) if (!usb_gone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) usb_autopm_get_interface(serial->parent->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) /* reset the rts and dtr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) /* do the actual close */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) serial->port.count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) if (serial->port.count <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) serial->port.count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) tty_port_tty_set(&serial->port, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (!usb_gone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) hso_stop_serial_device(serial->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) tasklet_kill(&serial->unthrottle_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (!usb_gone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) usb_autopm_put_interface(serial->parent->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) mutex_unlock(&serial->parent->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) /* close the requested serial port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) static int hso_serial_write(struct tty_struct *tty, const unsigned char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct hso_serial *serial = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) int space, tx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) /* sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) if (serial == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) pr_err("%s: serial is NULL\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) spin_lock_irqsave(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) space = serial->tx_data_length - serial->tx_buffer_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) tx_bytes = (count < space) ? count : space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (!tx_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) memcpy(serial->tx_buffer + serial->tx_buffer_count, buf, tx_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) serial->tx_buffer_count += tx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) spin_unlock_irqrestore(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) hso_kick_transmit(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) /* done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) return tx_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) /* how much room is there for writing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) static int hso_serial_write_room(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) struct hso_serial *serial = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) int room;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) spin_lock_irqsave(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) room = serial->tx_data_length - serial->tx_buffer_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) spin_unlock_irqrestore(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) /* return free room */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) return room;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) static void hso_serial_cleanup(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) struct hso_serial *serial = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) if (!serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) kref_put(&serial->parent->ref, hso_serial_ref_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) /* setup the term */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) struct hso_serial *serial = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) if (old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) hso_dbg(0x16, "Termios called with: cflags new[%u] - old[%u]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) (unsigned int)tty->termios.c_cflag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) (unsigned int)old->c_cflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) /* the actual setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) spin_lock_irqsave(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (serial->port.count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) _hso_serial_set_termios(tty, old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) tty->termios = *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) spin_unlock_irqrestore(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) /* done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) /* how many characters in the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) static int hso_serial_chars_in_buffer(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) struct hso_serial *serial = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) int chars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) /* sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) if (serial == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) spin_lock_irqsave(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) chars = serial->tx_buffer_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) spin_unlock_irqrestore(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) return chars;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) static int tiocmget_submit_urb(struct hso_serial *serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) struct hso_tiocmget *tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) struct usb_device *usb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) if (serial->parent->usb_gone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) usb_fill_int_urb(tiocmget->urb, usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) usb_rcvintpipe(usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) tiocmget->endp->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) bEndpointAddress & 0x7F),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) tiocmget->serial_state_notification,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) sizeof(struct hso_serial_state_notification),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) tiocmget_intr_callback, serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) tiocmget->endp->bInterval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) result = usb_submit_urb(tiocmget->urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) dev_warn(&usb->dev, "%s usb_submit_urb failed %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) static void tiocmget_intr_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) struct hso_serial *serial = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) struct hso_tiocmget *tiocmget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) u16 UART_state_bitmap, prev_UART_state_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) struct uart_icount *icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) struct hso_serial_state_notification *serial_state_notification;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) struct usb_device *usb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) struct usb_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) int if_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) /* Sanity checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) if (!serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) handle_usb_error(status, __func__, serial->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) /* tiocmget is only supported on HSO_PORT_MODEM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) tiocmget = serial->tiocmget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) if (!tiocmget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) BUG_ON((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) usb = serial->parent->usb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) interface = serial->parent->interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if_num = interface->cur_altsetting->desc.bInterfaceNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) /* wIndex should be the USB interface number of the port to which the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) * notification applies, which should always be the Modem port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) serial_state_notification = tiocmget->serial_state_notification;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) if (serial_state_notification->bmRequestType != BM_REQUEST_TYPE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) serial_state_notification->bNotification != B_NOTIFICATION ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) le16_to_cpu(serial_state_notification->wValue) != W_VALUE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) le16_to_cpu(serial_state_notification->wIndex) != if_num ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) le16_to_cpu(serial_state_notification->wLength) != W_LENGTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) dev_warn(&usb->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) "hso received invalid serial state notification\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) DUMP(serial_state_notification,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) sizeof(struct hso_serial_state_notification));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) UART_state_bitmap = le16_to_cpu(serial_state_notification->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) UART_state_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) prev_UART_state_bitmap = tiocmget->prev_UART_state_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) icount = &tiocmget->icount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) spin_lock_irqsave(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) if ((UART_state_bitmap & B_OVERRUN) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) (prev_UART_state_bitmap & B_OVERRUN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) icount->parity++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) if ((UART_state_bitmap & B_PARITY) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) (prev_UART_state_bitmap & B_PARITY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) icount->parity++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) if ((UART_state_bitmap & B_FRAMING) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) (prev_UART_state_bitmap & B_FRAMING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) icount->frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) if ((UART_state_bitmap & B_RING_SIGNAL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) !(prev_UART_state_bitmap & B_RING_SIGNAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) icount->rng++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) if ((UART_state_bitmap & B_BREAK) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) (prev_UART_state_bitmap & B_BREAK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) icount->brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) if ((UART_state_bitmap & B_TX_CARRIER) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) (prev_UART_state_bitmap & B_TX_CARRIER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) icount->dsr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if ((UART_state_bitmap & B_RX_CARRIER) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) (prev_UART_state_bitmap & B_RX_CARRIER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) icount->dcd++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) tiocmget->prev_UART_state_bitmap = UART_state_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) spin_unlock_irqrestore(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) tiocmget->intr_completed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) wake_up_interruptible(&tiocmget->waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) memset(serial_state_notification, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) sizeof(struct hso_serial_state_notification));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) tiocmget_submit_urb(serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) serial->parent->usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) * next few functions largely stolen from drivers/serial/serial_core.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) /* Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) * - mask passed in arg for lines of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) * Caller should use TIOCGICOUNT to see which one it was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) hso_wait_modem_status(struct hso_serial *serial, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) DECLARE_WAITQUEUE(wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) struct uart_icount cprev, cnow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) struct hso_tiocmget *tiocmget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) tiocmget = serial->tiocmget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) if (!tiocmget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) * note the counters on entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) spin_lock_irq(&serial->serial_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) memcpy(&cprev, &tiocmget->icount, sizeof(struct uart_icount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) spin_unlock_irq(&serial->serial_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) add_wait_queue(&tiocmget->waitq, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) spin_lock_irq(&serial->serial_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) spin_unlock_irq(&serial->serial_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) /* see if a signal did it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) ret = -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) cprev = cnow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) __set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) remove_wait_queue(&tiocmget->waitq, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) * Return: write counters to the user passed counter struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) * NB: both 1->0 and 0->1 transitions are counted except for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) * RI where only 0->1 is counted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) static int hso_get_count(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) struct serial_icounter_struct *icount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) struct uart_icount cnow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) struct hso_serial *serial = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) struct hso_tiocmget *tiocmget = serial->tiocmget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) memset(icount, 0, sizeof(struct serial_icounter_struct));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if (!tiocmget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) spin_lock_irq(&serial->serial_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) spin_unlock_irq(&serial->serial_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) icount->cts = cnow.cts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) icount->dsr = cnow.dsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) icount->rng = cnow.rng;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) icount->dcd = cnow.dcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) icount->rx = cnow.rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) icount->tx = cnow.tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) icount->frame = cnow.frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) icount->overrun = cnow.overrun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) icount->parity = cnow.parity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) icount->brk = cnow.brk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) icount->buf_overrun = cnow.buf_overrun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) static int hso_serial_tiocmget(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) struct hso_serial *serial = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) struct hso_tiocmget *tiocmget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) u16 UART_state_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) /* sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) if (!serial) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) hso_dbg(0x1, "no tty structures\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) spin_lock_irq(&serial->serial_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) retval = ((serial->rts_state) ? TIOCM_RTS : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) ((serial->dtr_state) ? TIOCM_DTR : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) tiocmget = serial->tiocmget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) if (tiocmget) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) UART_state_bitmap = le16_to_cpu(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) tiocmget->prev_UART_state_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) if (UART_state_bitmap & B_RING_SIGNAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) retval |= TIOCM_RNG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (UART_state_bitmap & B_RX_CARRIER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) retval |= TIOCM_CD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (UART_state_bitmap & B_TX_CARRIER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) retval |= TIOCM_DSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) spin_unlock_irq(&serial->serial_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) static int hso_serial_tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) unsigned int set, unsigned int clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) int if_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) struct hso_serial *serial = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) struct usb_interface *interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) /* sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) if (!serial) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) hso_dbg(0x1, "no tty structures\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) if ((serial->parent->port_spec & HSO_PORT_MASK) != HSO_PORT_MODEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) interface = serial->parent->interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) if_num = interface->cur_altsetting->desc.bInterfaceNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) spin_lock_irqsave(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) if (set & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) serial->rts_state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) if (set & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) serial->dtr_state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) if (clear & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) serial->rts_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) if (clear & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) serial->dtr_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) if (serial->dtr_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) val |= 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) if (serial->rts_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) val |= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) spin_unlock_irqrestore(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) return usb_control_msg(serial->parent->usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) usb_sndctrlpipe(serial->parent->usb, 0), 0x22,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 0x21, val, if_num, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) USB_CTRL_SET_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) static int hso_serial_ioctl(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) unsigned int cmd, unsigned long arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) struct hso_serial *serial = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) hso_dbg(0x8, "IOCTL cmd: %d, arg: %ld\n", cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) if (!serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) case TIOCMIWAIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) ret = hso_wait_modem_status(serial, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) ret = -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) /* starts a transmit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) static void hso_kick_transmit(struct hso_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) spin_lock_irqsave(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) if (!serial->tx_buffer_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) if (serial->tx_urb_used)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) /* Wakeup USB interface if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) if (hso_get_activity(serial->parent) == -EAGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) /* Switch pointers around to avoid memcpy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) swap(serial->tx_buffer, serial->tx_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) serial->tx_data_count = serial->tx_buffer_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) serial->tx_buffer_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) /* If serial->tx_data is set, it means we switched buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) if (serial->tx_data && serial->write_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) res = serial->write_data(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) if (res >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) serial->tx_urb_used = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) spin_unlock_irqrestore(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) /* make a request (for reading and writing data to muxed serial port) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) static int mux_device_request(struct hso_serial *serial, u8 type, u16 port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) struct urb *ctrl_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) struct usb_ctrlrequest *ctrl_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) u8 *ctrl_urb_data, u32 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) int pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) /* Sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) if (!serial || !ctrl_urb || !ctrl_req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) pr_err("%s: Wrong arguments\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) return -EINVAL;
^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) /* initialize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) ctrl_req->wValue = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) ctrl_req->wIndex = cpu_to_le16(hso_port_to_mux(port));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) ctrl_req->wLength = cpu_to_le16(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) if (type == USB_CDC_GET_ENCAPSULATED_RESPONSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) /* Reading command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) ctrl_req->bRequestType = USB_DIR_IN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) USB_TYPE_OPTION_VENDOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) USB_RECIP_INTERFACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) ctrl_req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) pipe = usb_rcvctrlpipe(serial->parent->usb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) /* Writing command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) ctrl_req->bRequestType = USB_DIR_OUT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) USB_TYPE_OPTION_VENDOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) USB_RECIP_INTERFACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) ctrl_req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) pipe = usb_sndctrlpipe(serial->parent->usb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) /* syslog */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) hso_dbg(0x2, "%s command (%02x) len: %d, port: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) type == USB_CDC_GET_ENCAPSULATED_RESPONSE ? "Read" : "Write",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) ctrl_req->bRequestType, ctrl_req->wLength, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) /* Load ctrl urb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) ctrl_urb->transfer_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) usb_fill_control_urb(ctrl_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) serial->parent->usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) (u8 *) ctrl_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) ctrl_urb_data, size, ctrl_callback, serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) /* Send it on merry way */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) result = usb_submit_urb(ctrl_urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) dev_err(&ctrl_urb->dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) "%s failed submit ctrl_urb %d type %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) result, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) /* done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) /* called by intr_callback when read occurs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) static int hso_mux_serial_read(struct hso_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) if (!serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) /* clean data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) memset(serial->rx_data[0], 0, CTRL_URB_RX_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) /* make the request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) if (serial->num_rx_urbs != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) dev_err(&serial->parent->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) "ERROR: mux'd reads with multiple buffers "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) "not possible\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) return mux_device_request(serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) USB_CDC_GET_ENCAPSULATED_RESPONSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) serial->parent->port_spec & HSO_PORT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) serial->rx_urb[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) &serial->ctrl_req_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) serial->rx_data[0], serial->rx_data_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) /* used for muxed serial port callback (muxed serial read) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) static void intr_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) struct hso_shared_int *shared_int = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) struct hso_serial *serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) unsigned char *port_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) usb_mark_last_busy(urb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) /* sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) if (!shared_int)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) /* status check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) handle_usb_error(status, __func__, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) hso_dbg(0x8, "--- Got intr callback 0x%02X ---\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) /* what request? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) port_req = urb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) hso_dbg(0x8, "port_req = 0x%.2X\n", *port_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) /* loop over all muxed ports to find the one sending this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) /* max 8 channels on MUX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if (*port_req & (1 << i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) serial = get_serial_by_shared_int_and_type(shared_int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) (1 << i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) if (serial != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) hso_dbg(0x1, "Pending read interrupt on port %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) spin_lock_irqsave(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) if (serial->rx_state == RX_IDLE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) serial->port.count > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) /* Setup and send a ctrl req read on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) * port i */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) if (!serial->rx_urb_filled[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) serial->rx_state = RX_SENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) hso_mux_serial_read(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) serial->rx_state = RX_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) hso_dbg(0x1, "Already a read pending on port %d or port not open\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) spin_unlock_irqrestore(&serial->serial_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) flags);
^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) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) /* Resubmit interrupt urb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) hso_mux_submit_intr_urb(shared_int, urb->dev, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) /* called for writing to muxed serial port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) static int hso_mux_serial_write_data(struct hso_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) if (NULL == serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) return mux_device_request(serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) USB_CDC_SEND_ENCAPSULATED_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) serial->parent->port_spec & HSO_PORT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) serial->tx_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) &serial->ctrl_req_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) serial->tx_data, serial->tx_data_count);
^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) /* write callback for Diag and CS port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) static void hso_std_serial_write_bulk_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) struct hso_serial *serial = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) /* sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) if (!serial) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) hso_dbg(0x1, "serial == NULL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) spin_lock_irqsave(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) serial->tx_urb_used = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) spin_unlock_irqrestore(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) handle_usb_error(status, __func__, serial->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) hso_put_activity(serial->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) tty_port_tty_wakeup(&serial->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) hso_kick_transmit(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) hso_dbg(0x1, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) /* called for writing diag or CS serial port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) static int hso_std_serial_write_data(struct hso_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) int count = serial->tx_data_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) usb_fill_bulk_urb(serial->tx_urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) serial->parent->usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) usb_sndbulkpipe(serial->parent->usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) serial->out_endp->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) bEndpointAddress & 0x7F),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) serial->tx_data, serial->tx_data_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) hso_std_serial_write_bulk_callback, serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) result = usb_submit_urb(serial->tx_urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) dev_warn(&serial->parent->usb->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) "Failed to submit urb - res %d\n", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) /* callback after read or write on muxed serial port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) static void ctrl_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) struct hso_serial *serial = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) struct usb_ctrlrequest *req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) int status = urb->status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) /* sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) if (!serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) spin_lock_irqsave(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) serial->tx_urb_used = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) spin_unlock_irqrestore(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) handle_usb_error(status, __func__, serial->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) /* what request? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) req = (struct usb_ctrlrequest *)(urb->setup_packet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) hso_dbg(0x8, "--- Got muxed ctrl callback 0x%02X ---\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) hso_dbg(0x8, "Actual length of urb = %d\n", urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) DUMP1(urb->transfer_buffer, urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) if (req->bRequestType ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) (USB_DIR_IN | USB_TYPE_OPTION_VENDOR | USB_RECIP_INTERFACE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) /* response to a read command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) serial->rx_urb_filled[0] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) spin_lock_irqsave(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) put_rxbuf_data_and_resubmit_ctrl_urb(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) spin_unlock_irqrestore(&serial->serial_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) hso_put_activity(serial->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) tty_port_tty_wakeup(&serial->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) /* response to a write command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) hso_kick_transmit(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) /* handle RX data for serial port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) /* Sanity check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) if (urb == NULL || serial == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) hso_dbg(0x1, "serial = NULL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) return -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) tty = tty_port_tty_get(&serial->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) if (tty && tty_throttled(tty)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) /* Push data to tty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) hso_dbg(0x1, "data to push to tty\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) count = tty_buffer_request_room(&serial->port, urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) if (count >= urb->actual_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) tty_insert_flip_string(&serial->port, urb->transfer_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) tty_flip_buffer_push(&serial->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) dev_warn(&serial->parent->usb->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) "dropping data, %d bytes lost\n", urb->actual_length);
^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) tty_kref_put(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) /* Base driver functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) static void hso_log_port(struct hso_device *hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) char *port_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) char port_dev[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) switch (hso_dev->port_spec & HSO_PORT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) case HSO_PORT_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) port_type = "Control";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) case HSO_PORT_APP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) port_type = "Application";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) case HSO_PORT_GPS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) port_type = "GPS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) case HSO_PORT_GPS_CONTROL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) port_type = "GPS control";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) case HSO_PORT_APP2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) port_type = "Application2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) case HSO_PORT_PCSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) port_type = "PCSC";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) case HSO_PORT_DIAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) port_type = "Diagnostic";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) case HSO_PORT_DIAG2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) port_type = "Diagnostic2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) case HSO_PORT_MODEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) port_type = "Modem";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) case HSO_PORT_NETWORK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) port_type = "Network";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) port_type = "Unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) if ((hso_dev->port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) sprintf(port_dev, "%s", dev2net(hso_dev)->net->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) sprintf(port_dev, "/dev/%s%d", tty_filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) dev2ser(hso_dev)->minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) dev_dbg(&hso_dev->interface->dev, "HSO: Found %s port %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) port_type, port_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) static int hso_start_net_device(struct hso_device *hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) int i, result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) struct hso_net *hso_net = dev2net(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) if (!hso_net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) /* send URBs for all read buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) /* Prep a receive URB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) usb_fill_bulk_urb(hso_net->mux_bulk_rx_urb_pool[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) hso_dev->usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) usb_rcvbulkpipe(hso_dev->usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) hso_net->in_endp->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) bEndpointAddress & 0x7F),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) hso_net->mux_bulk_rx_buf_pool[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) MUX_BULK_RX_BUF_SIZE, read_bulk_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) hso_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) /* Put it out there so the device can send us stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) result = usb_submit_urb(hso_net->mux_bulk_rx_urb_pool[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) dev_warn(&hso_dev->usb->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) "%s failed mux_bulk_rx_urb[%d] %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) i, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) static int hso_stop_net_device(struct hso_device *hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) struct hso_net *hso_net = dev2net(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) if (!hso_net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) if (hso_net->mux_bulk_rx_urb_pool[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) usb_kill_urb(hso_net->mux_bulk_rx_urb_pool[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) if (hso_net->mux_bulk_tx_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) usb_kill_urb(hso_net->mux_bulk_tx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) int i, result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) struct hso_serial *serial = dev2ser(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) if (!serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) /* If it is not the MUX port fill in and submit a bulk urb (already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) * allocated in hso_serial_start) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) if (!(serial->parent->port_spec & HSO_INTF_MUX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) for (i = 0; i < serial->num_rx_urbs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) usb_fill_bulk_urb(serial->rx_urb[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) serial->parent->usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) usb_rcvbulkpipe(serial->parent->usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) serial->in_endp->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) bEndpointAddress &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 0x7F),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) serial->rx_data[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) serial->rx_data_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) hso_std_serial_read_bulk_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) result = usb_submit_urb(serial->rx_urb[i], flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) dev_warn(&serial->parent->usb->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) "Failed to submit urb - res %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) mutex_lock(&serial->shared_int->shared_int_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) if (!serial->shared_int->use_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) result =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) hso_mux_submit_intr_urb(serial->shared_int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) hso_dev->usb, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) serial->shared_int->use_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) mutex_unlock(&serial->shared_int->shared_int_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) if (serial->tiocmget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) tiocmget_submit_urb(serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) serial->tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) serial->parent->usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) static int hso_stop_serial_device(struct hso_device *hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) struct hso_serial *serial = dev2ser(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) struct hso_tiocmget *tiocmget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) if (!serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) for (i = 0; i < serial->num_rx_urbs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) if (serial->rx_urb[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) usb_kill_urb(serial->rx_urb[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) serial->rx_urb_filled[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) serial->curr_rx_urb_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) if (serial->tx_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) usb_kill_urb(serial->tx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if (serial->shared_int) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) mutex_lock(&serial->shared_int->shared_int_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) if (serial->shared_int->use_count &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) (--serial->shared_int->use_count == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) urb = serial->shared_int->shared_intr_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) if (urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) usb_kill_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) mutex_unlock(&serial->shared_int->shared_int_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) tiocmget = serial->tiocmget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) if (tiocmget) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) wake_up_interruptible(&tiocmget->waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) usb_kill_urb(tiocmget->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) static void hso_serial_tty_unregister(struct hso_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) tty_unregister_device(tty_drv, serial->minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) release_minor(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) static void hso_serial_common_free(struct hso_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) for (i = 0; i < serial->num_rx_urbs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) /* unlink and free RX URB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) usb_free_urb(serial->rx_urb[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) /* free the RX buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) kfree(serial->rx_data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) /* unlink and free TX URB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) usb_free_urb(serial->tx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) kfree(serial->tx_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) kfree(serial->tx_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) tty_port_destroy(&serial->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) int rx_size, int tx_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) tty_port_init(&serial->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) if (obtain_minor(serial))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) goto exit2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) /* register our minor number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) serial->parent->dev = tty_port_register_device_attr(&serial->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) tty_drv, serial->minor, &serial->parent->interface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) serial->parent, hso_serial_dev_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) if (IS_ERR(serial->parent->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) release_minor(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) goto exit2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) serial->magic = HSO_SERIAL_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) spin_lock_init(&serial->serial_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) serial->num_rx_urbs = num_urbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) /* RX, allocate urb and initialize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) /* prepare our RX buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) serial->rx_data_length = rx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) for (i = 0; i < serial->num_rx_urbs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) serial->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) if (!serial->rx_urb[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) serial->rx_urb[i]->transfer_buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) serial->rx_urb[i]->transfer_buffer_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) serial->rx_data[i] = kzalloc(serial->rx_data_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) if (!serial->rx_data[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) /* TX, allocate urb and initialize */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) serial->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) if (!serial->tx_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) serial->tx_urb->transfer_buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) serial->tx_urb->transfer_buffer_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) /* prepare our TX buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) serial->tx_data_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) serial->tx_buffer_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) serial->tx_data_length = tx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) if (!serial->tx_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) if (!serial->tx_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) hso_serial_tty_unregister(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) exit2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) hso_serial_common_free(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) return -1;
^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) /* Creates a general hso device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) static struct hso_device *hso_create_device(struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) int port_spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) struct hso_device *hso_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) hso_dev = kzalloc(sizeof(*hso_dev), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) if (!hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) hso_dev->port_spec = port_spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) hso_dev->usb = interface_to_usbdev(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) hso_dev->interface = intf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) kref_init(&hso_dev->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) mutex_init(&hso_dev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) INIT_WORK(&hso_dev->async_get_intf, async_get_intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) INIT_WORK(&hso_dev->async_put_intf, async_put_intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) return hso_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) /* Removes a network device in the network device table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) static int remove_net_device(struct hso_device *hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) if (network_table[i] == hso_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) network_table[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) if (i == HSO_MAX_NET_DEVICES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) return 0;
^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) /* Frees our network device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) static void hso_free_net_device(struct hso_device *hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) struct hso_net *hso_net = dev2net(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) if (!hso_net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) remove_net_device(hso_net->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) if (hso_net->net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) unregister_netdev(hso_net->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) /* start freeing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) usb_free_urb(hso_net->mux_bulk_rx_urb_pool[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) kfree(hso_net->mux_bulk_rx_buf_pool[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) hso_net->mux_bulk_rx_buf_pool[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) usb_free_urb(hso_net->mux_bulk_tx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) kfree(hso_net->mux_bulk_tx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) hso_net->mux_bulk_tx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) if (hso_net->net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) free_netdev(hso_net->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) kfree(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) static const struct net_device_ops hso_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) .ndo_open = hso_net_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) .ndo_stop = hso_net_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) .ndo_start_xmit = hso_net_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) .ndo_tx_timeout = hso_net_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) /* initialize the network interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) static void hso_net_init(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) struct hso_net *hso_net = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) hso_dbg(0x1, "sizeof hso_net is %zu\n", sizeof(*hso_net));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) /* fill in the other fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) net->netdev_ops = &hso_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) net->watchdog_timeo = HSO_NET_TX_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) net->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) net->type = ARPHRD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) net->mtu = DEFAULT_MTU - 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) net->tx_queue_len = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) net->ethtool_ops = &ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) /* and initialize the semaphore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) spin_lock_init(&hso_net->net_lock);
^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) /* Adds a network device in the network device table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) static int add_net_device(struct hso_device *hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) if (network_table[i] == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) network_table[i] = hso_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) if (i == HSO_MAX_NET_DEVICES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) static int hso_rfkill_set_block(void *data, bool blocked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) struct hso_device *hso_dev = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) int enabled = !blocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) mutex_lock(&hso_dev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) if (hso_dev->usb_gone)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) rv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) rv = usb_control_msg(hso_dev->usb, usb_sndctrlpipe(hso_dev->usb, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) enabled ? 0x82 : 0x81, 0x40, 0, 0, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) USB_CTRL_SET_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) mutex_unlock(&hso_dev->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) static const struct rfkill_ops hso_rfkill_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) .set_block = hso_rfkill_set_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) /* Creates and sets up everything for rfkill */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) static void hso_create_rfkill(struct hso_device *hso_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) struct hso_net *hso_net = dev2net(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) struct device *dev = &hso_net->net->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) static u32 rfkill_counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) snprintf(hso_net->name, sizeof(hso_net->name), "hso-%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) rfkill_counter++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) hso_net->rfkill = rfkill_alloc(hso_net->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) &interface_to_usbdev(interface)->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) RFKILL_TYPE_WWAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) &hso_rfkill_ops, hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) if (!hso_net->rfkill)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) if (rfkill_register(hso_net->rfkill) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) rfkill_destroy(hso_net->rfkill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) hso_net->rfkill = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) dev_err(dev, "%s - Failed to register rfkill\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) static struct device_type hso_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) .name = "wwan",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) /* Creates our network device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) static struct hso_device *hso_create_net_device(struct usb_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) int port_spec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) int result, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) struct net_device *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) struct hso_net *hso_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) struct hso_device *hso_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) hso_dev = hso_create_device(interface, port_spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) if (!hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) /* allocate our network device, then we can put in our private data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) /* call hso_net_init to do the basic initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) net = alloc_netdev(sizeof(struct hso_net), "hso%d", NET_NAME_UNKNOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) hso_net_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) if (!net) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) dev_err(&interface->dev, "Unable to create ethernet device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) goto err_hso_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) hso_net = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) hso_dev->port_data.dev_net = hso_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) hso_net->net = net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) hso_net->parent = hso_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) hso_net->in_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) USB_DIR_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) if (!hso_net->in_endp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) dev_err(&interface->dev, "Can't find BULK IN endpoint\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) goto err_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) hso_net->out_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) USB_DIR_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) if (!hso_net->out_endp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) dev_err(&interface->dev, "Can't find BULK OUT endpoint\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) goto err_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) SET_NETDEV_DEV(net, &interface->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) SET_NETDEV_DEVTYPE(net, &hso_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) /* start allocating */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) hso_net->mux_bulk_rx_urb_pool[i] = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) if (!hso_net->mux_bulk_rx_urb_pool[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) goto err_mux_bulk_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) hso_net->mux_bulk_rx_buf_pool[i] = kzalloc(MUX_BULK_RX_BUF_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) if (!hso_net->mux_bulk_rx_buf_pool[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) goto err_mux_bulk_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) hso_net->mux_bulk_tx_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) if (!hso_net->mux_bulk_tx_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) goto err_mux_bulk_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) hso_net->mux_bulk_tx_buf = kzalloc(MUX_BULK_TX_BUF_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) if (!hso_net->mux_bulk_tx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) goto err_free_tx_urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) result = add_net_device(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) dev_err(&interface->dev, "Failed to add net device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) goto err_free_tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) /* registering our net device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) result = register_netdev(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) dev_err(&interface->dev, "Failed to register device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) goto err_rmv_ndev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) hso_log_port(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) hso_create_rfkill(hso_dev, interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) return hso_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) err_rmv_ndev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) remove_net_device(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) err_free_tx_buf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) kfree(hso_net->mux_bulk_tx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) err_free_tx_urb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) usb_free_urb(hso_net->mux_bulk_tx_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) err_mux_bulk_rx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) usb_free_urb(hso_net->mux_bulk_rx_urb_pool[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) kfree(hso_net->mux_bulk_rx_buf_pool[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) err_net:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) free_netdev(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) err_hso_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) kfree(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) static void hso_free_tiomget(struct hso_serial *serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) struct hso_tiocmget *tiocmget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) if (!serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) tiocmget = serial->tiocmget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) if (tiocmget) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) usb_free_urb(tiocmget->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) tiocmget->urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) serial->tiocmget = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) kfree(tiocmget->serial_state_notification);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) tiocmget->serial_state_notification = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) kfree(tiocmget);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) /* Frees an AT channel ( goes for both mux and non-mux ) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) static void hso_free_serial_device(struct hso_device *hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) struct hso_serial *serial = dev2ser(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) if (!serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) hso_serial_common_free(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) if (serial->shared_int) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) mutex_lock(&serial->shared_int->shared_int_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) if (--serial->shared_int->ref_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) hso_free_shared_int(serial->shared_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) mutex_unlock(&serial->shared_int->shared_int_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) hso_free_tiomget(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) kfree(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) kfree(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) /* Creates a bulk AT channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) static struct hso_device *hso_create_bulk_serial_device(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) struct usb_interface *interface, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) struct hso_device *hso_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) struct hso_serial *serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) int num_urbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) struct hso_tiocmget *tiocmget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) hso_dev = hso_create_device(interface, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) if (!hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) serial = kzalloc(sizeof(*serial), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) if (!serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) serial->parent = hso_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) hso_dev->port_data.dev_serial = serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) if ((port & HSO_PORT_MASK) == HSO_PORT_MODEM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) num_urbs = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) serial->tiocmget = kzalloc(sizeof(struct hso_tiocmget),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) if (!serial->tiocmget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) serial->tiocmget->serial_state_notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) = kzalloc(sizeof(struct hso_serial_state_notification),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) if (!serial->tiocmget->serial_state_notification)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) tiocmget = serial->tiocmget;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) tiocmget->endp = hso_get_ep(interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) USB_ENDPOINT_XFER_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) USB_DIR_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) if (!tiocmget->endp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) dev_err(&interface->dev, "Failed to find INT IN ep\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) tiocmget->urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) if (!tiocmget->urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) mutex_init(&tiocmget->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) init_waitqueue_head(&tiocmget->waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) num_urbs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) if (hso_serial_common_create(serial, num_urbs, BULK_URB_RX_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) BULK_URB_TX_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) serial->in_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) USB_DIR_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) if (!serial->in_endp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) dev_err(&interface->dev, "Failed to find BULK IN ep\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) goto exit2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) if (!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) (serial->out_endp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) dev_err(&interface->dev, "Failed to find BULK OUT ep\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) goto exit2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) serial->write_data = hso_std_serial_write_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) /* setup the proc dirs and files if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) hso_log_port(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) /* done, return it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) return hso_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) exit2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) hso_serial_tty_unregister(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) hso_serial_common_free(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) hso_free_tiomget(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) kfree(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) kfree(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) /* Creates a multiplexed AT channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) struct hso_device *hso_create_mux_serial_device(struct usb_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) int port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) struct hso_shared_int *mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) struct hso_device *hso_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) struct hso_serial *serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) int port_spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) port_spec = HSO_INTF_MUX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) port_spec &= ~HSO_PORT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) port_spec |= hso_mux_to_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NO_PORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) hso_dev = hso_create_device(interface, port_spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) if (!hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) serial = kzalloc(sizeof(*serial), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) if (!serial)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) goto err_free_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) hso_dev->port_data.dev_serial = serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) serial->parent = hso_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) if (hso_serial_common_create
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) (serial, 1, CTRL_URB_RX_SIZE, CTRL_URB_TX_SIZE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) goto err_free_serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) serial->tx_data_length--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) serial->write_data = hso_mux_serial_write_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) serial->shared_int = mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) mutex_lock(&serial->shared_int->shared_int_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) serial->shared_int->ref_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) mutex_unlock(&serial->shared_int->shared_int_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) /* setup the proc dirs and files if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) hso_log_port(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) /* done, return it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) return hso_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) err_free_serial:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) kfree(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) err_free_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) kfree(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) static void hso_free_shared_int(struct hso_shared_int *mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) usb_free_urb(mux->shared_intr_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) kfree(mux->shared_intr_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) mutex_unlock(&mux->shared_int_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) kfree(mux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) struct hso_shared_int *mux = kzalloc(sizeof(*mux), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) if (!mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) mux->intr_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_INT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) USB_DIR_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) if (!mux->intr_endp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) dev_err(&interface->dev, "Can't find INT IN endpoint\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) if (!mux->shared_intr_urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) mux->shared_intr_buf =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) kzalloc(le16_to_cpu(mux->intr_endp->wMaxPacketSize),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) if (!mux->shared_intr_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) mutex_init(&mux->shared_int_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) return mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) kfree(mux->shared_intr_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) usb_free_urb(mux->shared_intr_urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) kfree(mux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) /* Gets the port spec for a certain interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) static int hso_get_config_data(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) struct usb_device *usbdev = interface_to_usbdev(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) u8 *config_data = kmalloc(17, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) u32 if_num = interface->cur_altsetting->desc.bInterfaceNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) s32 result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) if (!config_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) if (usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 0x86, 0xC0, 0, 0, config_data, 17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) USB_CTRL_SET_TIMEOUT) != 0x11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) kfree(config_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) /* check if we have a valid interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) if (if_num > 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) kfree(config_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) switch (config_data[if_num]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) case 0x0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) case 0x1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) result = HSO_PORT_DIAG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) case 0x2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) result = HSO_PORT_GPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) case 0x3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) result = HSO_PORT_GPS_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) case 0x4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) result = HSO_PORT_APP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) case 0x5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) result = HSO_PORT_APP2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) case 0x6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) result = HSO_PORT_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) case 0x7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) result = HSO_PORT_NETWORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) case 0x8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) result = HSO_PORT_MODEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) case 0x9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) result = HSO_PORT_MSD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) case 0xa:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) result = HSO_PORT_PCSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) case 0xb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) result = HSO_PORT_VOICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) result |= HSO_INTF_BULK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) if (config_data[16] & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) result |= HSO_INFO_CRC_BUG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) kfree(config_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) /* called once for each interface upon device insertion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) static int hso_probe(struct usb_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) int mux, i, if_num, port_spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) unsigned char port_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) struct hso_device *hso_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) struct hso_shared_int *shared_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) struct hso_device *tmp_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) if (interface->cur_altsetting->desc.bInterfaceClass != 0xFF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) dev_err(&interface->dev, "Not our interface\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) if_num = interface->cur_altsetting->desc.bInterfaceNumber;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) /* Get the interface/port specification from either driver_info or from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) * the device itself */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) if (id->driver_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) /* if_num is controlled by the device, driver_info is a 0 terminated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) * array. Make sure, the access is in bounds! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) for (i = 0; i <= if_num; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) if (((u32 *)(id->driver_info))[i] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) port_spec = ((u32 *)(id->driver_info))[if_num];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) port_spec = hso_get_config_data(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) if (port_spec < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) /* Check if we need to switch to alt interfaces prior to port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) * configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) if (interface->num_altsetting > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) usb_set_interface(interface_to_usbdev(interface), if_num, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) interface->needs_remote_wakeup = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) /* Allocate new hso device(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) switch (port_spec & HSO_INTF_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) case HSO_INTF_MUX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) /* Create the network device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) if (!disable_net) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) hso_dev = hso_create_net_device(interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) port_spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) if (!hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) tmp_dev = hso_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) if (hso_get_mux_ports(interface, &port_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) /* TODO: de-allocate everything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) shared_int = hso_create_shared_int(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) if (!shared_int)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) for (i = 1, mux = 0; i < 0x100; i = i << 1, mux++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) if (port_mask & i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) hso_dev = hso_create_mux_serial_device(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) interface, i, shared_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) if (!hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) if (tmp_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) hso_dev = tmp_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) case HSO_INTF_BULK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) /* It's a regular bulk interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) if (!disable_net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) hso_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) hso_create_net_device(interface, port_spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) hso_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) hso_create_bulk_serial_device(interface, port_spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) if (!hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) /* save our data pointer in this device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) usb_set_intfdata(interface, hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) /* done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) hso_free_interface(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) /* device removed, cleaning up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) static void hso_disconnect(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) hso_free_interface(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) /* remove reference of our private data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) usb_set_intfdata(interface, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) static void async_get_intf(struct work_struct *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) struct hso_device *hso_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) container_of(data, struct hso_device, async_get_intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) usb_autopm_get_interface(hso_dev->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) static void async_put_intf(struct work_struct *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) struct hso_device *hso_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) container_of(data, struct hso_device, async_put_intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) usb_autopm_put_interface(hso_dev->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) static int hso_get_activity(struct hso_device *hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) if (hso_dev->usb->state == USB_STATE_SUSPENDED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) if (!hso_dev->is_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) hso_dev->is_active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) schedule_work(&hso_dev->async_get_intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) if (hso_dev->usb->state != USB_STATE_CONFIGURED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) usb_mark_last_busy(hso_dev->usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) static int hso_put_activity(struct hso_device *hso_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) if (hso_dev->usb->state != USB_STATE_SUSPENDED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) if (hso_dev->is_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) hso_dev->is_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) schedule_work(&hso_dev->async_put_intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) hso_dev->is_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) /* called by kernel when we need to suspend device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) static int hso_suspend(struct usb_interface *iface, pm_message_t message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) int i, result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) /* Stop all serial ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) if (serial_table[i] && (serial_table[i]->interface == iface)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) result = hso_stop_serial_device(serial_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) /* Stop all network ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) if (network_table[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) (network_table[i]->interface == iface)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) result = hso_stop_net_device(network_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) /* called by kernel when we need to resume device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) static int hso_resume(struct usb_interface *iface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) int i, result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) struct hso_net *hso_net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) /* Start all serial ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) if (serial_table[i] && (serial_table[i]->interface == iface)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) if (dev2ser(serial_table[i])->port.count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) result =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) hso_start_serial_device(serial_table[i], GFP_NOIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) hso_kick_transmit(dev2ser(serial_table[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) /* Start all network ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) if (network_table[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) (network_table[i]->interface == iface)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) hso_net = dev2net(network_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) if (hso_net->flags & IFF_UP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) /* First transmit any lingering data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) then restart the device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) if (hso_net->skb_tx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) dev_dbg(&iface->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) "Transmitting"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) " lingering data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) hso_net_start_xmit(hso_net->skb_tx_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) hso_net->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) hso_net->skb_tx_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) result = hso_start_net_device(network_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) static void hso_serial_ref_free(struct kref *ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) struct hso_device *hso_dev = container_of(ref, struct hso_device, ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) hso_free_serial_device(hso_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) static void hso_free_interface(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) struct hso_serial *serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) if (serial_table[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) (serial_table[i]->interface == interface)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) serial = dev2ser(serial_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) tty_port_tty_hangup(&serial->port, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) mutex_lock(&serial->parent->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) serial->parent->usb_gone = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) mutex_unlock(&serial->parent->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) cancel_work_sync(&serial_table[i]->async_put_intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) cancel_work_sync(&serial_table[i]->async_get_intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) hso_serial_tty_unregister(serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) kref_put(&serial->parent->ref, hso_serial_ref_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) for (i = 0; i < HSO_MAX_NET_DEVICES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) if (network_table[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) (network_table[i]->interface == interface)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) struct rfkill *rfk = dev2net(network_table[i])->rfkill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) /* hso_stop_net_device doesn't stop the net queue since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) * traffic needs to start it again when suspended */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) netif_stop_queue(dev2net(network_table[i])->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) hso_stop_net_device(network_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) cancel_work_sync(&network_table[i]->async_put_intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) cancel_work_sync(&network_table[i]->async_get_intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) if (rfk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) rfkill_unregister(rfk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) rfkill_destroy(rfk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) hso_free_net_device(network_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) /* Helper functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) /* Get the endpoint ! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) int type, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) struct usb_host_interface *iface = intf->cur_altsetting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) struct usb_endpoint_descriptor *endp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) for (i = 0; i < iface->desc.bNumEndpoints; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) endp = &iface->endpoint[i].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) if (((endp->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == dir) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) (usb_endpoint_type(endp) == type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) return endp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) /* Get the byte that describes which ports are enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) struct usb_host_interface *iface = intf->cur_altsetting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) if (iface->extralen == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) *ports = iface->extra[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) for (i = 0; i < iface->desc.bNumEndpoints; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) if (iface->endpoint[i].extralen == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) *ports = iface->endpoint[i].extra[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) /* interrupt urb needs to be submitted, used for serial read of muxed port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) struct usb_device *usb, gfp_t gfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) usb_fill_int_urb(shared_int->shared_intr_urb, usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) usb_rcvintpipe(usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) shared_int->intr_endp->bEndpointAddress & 0x7F),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) shared_int->shared_intr_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) intr_callback, shared_int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) shared_int->intr_endp->bInterval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) result = usb_submit_urb(shared_int->shared_intr_urb, gfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) dev_warn(&usb->dev, "%s failed mux_intr_urb %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) /* operations setup of the serial interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) static const struct tty_operations hso_serial_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) .open = hso_serial_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) .close = hso_serial_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) .write = hso_serial_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) .write_room = hso_serial_write_room,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) .cleanup = hso_serial_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) .ioctl = hso_serial_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) .set_termios = hso_serial_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) .chars_in_buffer = hso_serial_chars_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) .tiocmget = hso_serial_tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) .tiocmset = hso_serial_tiocmset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) .get_icount = hso_get_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) .unthrottle = hso_unthrottle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) static struct usb_driver hso_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) .name = driver_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) .probe = hso_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) .disconnect = hso_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) .id_table = hso_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) .suspend = hso_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) .resume = hso_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) .reset_resume = hso_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) .supports_autosuspend = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) .disable_hub_initiated_lpm = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) static int __init hso_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) /* put it in the log */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) pr_info("%s\n", version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) /* Initialise the serial table semaphore and table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) spin_lock_init(&serial_table_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) serial_table[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) /* allocate our driver using the proper amount of supported minors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) tty_drv = alloc_tty_driver(HSO_SERIAL_TTY_MINORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) if (!tty_drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) /* fill in all needed values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) tty_drv->driver_name = driver_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) tty_drv->name = tty_filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) /* if major number is provided as parameter, use that one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) if (tty_major)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) tty_drv->major = tty_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) tty_drv->minor_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) tty_drv->type = TTY_DRIVER_TYPE_SERIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) tty_drv->subtype = SERIAL_TYPE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) tty_drv->init_termios = tty_std_termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) hso_init_termios(&tty_drv->init_termios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) tty_set_operations(tty_drv, &hso_serial_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) /* register the tty driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) result = tty_register_driver(tty_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) pr_err("%s - tty_register_driver failed(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) goto err_free_tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) /* register this module as an usb driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) result = usb_register(&hso_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) pr_err("Could not register hso driver - error: %d\n", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) goto err_unreg_tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) /* done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) err_unreg_tty:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) tty_unregister_driver(tty_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) err_free_tty:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) put_tty_driver(tty_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) static void __exit hso_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) pr_info("unloaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) tty_unregister_driver(tty_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) /* deregister the usb driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) usb_deregister(&hso_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) put_tty_driver(tty_drv);
^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) /* Module definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) module_init(hso_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) module_exit(hso_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) MODULE_AUTHOR(MOD_AUTHOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) MODULE_DESCRIPTION(MOD_DESCRIPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) /* change the debug level (eg: insmod hso.ko debug=0x04) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) MODULE_PARM_DESC(debug, "debug level mask [0x01 | 0x02 | 0x04 | 0x08 | 0x10]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) module_param(debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) /* set the major tty number (eg: insmod hso.ko tty_major=245) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) MODULE_PARM_DESC(tty_major, "Set the major tty number");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) module_param(tty_major, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) /* disable network interface (eg: insmod hso.ko disable_net=1) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) MODULE_PARM_DESC(disable_net, "Disable the network interface");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) module_param(disable_net, int, 0644);