#define pr_fmt(fmt) …
#include <linux/sched/signal.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/module.h>
#include <linux/ethtool.h>
#include <linux/usb.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/kmod.h>
#include <linux/rfkill.h>
#include <linux/ip.h>
#include <linux/uaccess.h>
#include <linux/usb/cdc.h>
#include <net/arp.h>
#include <asm/byteorder.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#define MOD_AUTHOR …
#define MOD_DESCRIPTION …
#define HSO_MAX_NET_DEVICES …
#define HSO__MAX_MTU …
#define DEFAULT_MTU …
#define DEFAULT_MRU …
#define CTRL_URB_RX_SIZE …
#define CTRL_URB_TX_SIZE …
#define BULK_URB_RX_SIZE …
#define BULK_URB_TX_SIZE …
#define MUX_BULK_RX_BUF_SIZE …
#define MUX_BULK_TX_BUF_SIZE …
#define MUX_BULK_RX_BUF_COUNT …
#define USB_TYPE_OPTION_VENDOR …
#define HSO_NET_RUNNING …
#define HSO_NET_TX_TIMEOUT …
#define HSO_SERIAL_MAGIC …
#define HSO_SERIAL_TTY_MINORS …
#define MAX_RX_URBS …
#define hso_dbg(lvl, fmt, ...) …
enum pkt_parse_state { … };
struct hso_shared_int { … };
struct hso_net { … };
enum rx_ctrl_state{ … };
#define BM_REQUEST_TYPE …
#define B_NOTIFICATION …
#define W_VALUE …
#define W_LENGTH …
#define B_OVERRUN …
#define B_PARITY …
#define B_FRAMING …
#define B_RING_SIGNAL …
#define B_BREAK …
#define B_TX_CARRIER …
#define B_RX_CARRIER …
struct hso_serial_state_notification { … } __packed;
struct hso_tiocmget { … };
struct hso_serial { … };
struct hso_device { … };
#define HSO_INTF_MASK …
#define HSO_INTF_MUX …
#define HSO_INTF_BULK …
#define HSO_PORT_MASK …
#define HSO_PORT_NO_PORT …
#define HSO_PORT_CONTROL …
#define HSO_PORT_APP …
#define HSO_PORT_GPS …
#define HSO_PORT_PCSC …
#define HSO_PORT_APP2 …
#define HSO_PORT_GPS_CONTROL …
#define HSO_PORT_MSD …
#define HSO_PORT_VOICE …
#define HSO_PORT_DIAG2 …
#define HSO_PORT_DIAG …
#define HSO_PORT_MODEM …
#define HSO_PORT_NETWORK …
#define HSO_INFO_MASK …
#define HSO_INFO_CRC_BUG …
static int hso_serial_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear);
static void ctrl_callback(struct urb *urb);
static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial);
static void hso_kick_transmit(struct hso_serial *serial);
static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int,
struct usb_device *usb, gfp_t gfp);
static void handle_usb_error(int status, const char *function,
struct hso_device *hso_dev);
static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf,
int type, int dir);
static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports);
static void hso_free_interface(struct usb_interface *intf);
static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags);
static int hso_stop_serial_device(struct hso_device *hso_dev);
static int hso_start_net_device(struct hso_device *hso_dev);
static void hso_free_shared_int(struct hso_shared_int *shared_int);
static int hso_stop_net_device(struct hso_device *hso_dev);
static void hso_serial_ref_free(struct kref *ref);
static void hso_std_serial_read_bulk_callback(struct urb *urb);
static int hso_mux_serial_read(struct hso_serial *serial);
static void async_get_intf(struct work_struct *data);
static void async_put_intf(struct work_struct *data);
static int hso_put_activity(struct hso_device *hso_dev);
static int hso_get_activity(struct hso_device *hso_dev);
static void tiocmget_intr_callback(struct urb *urb);
static inline struct hso_net *dev2net(struct hso_device *hso_dev)
{ … }
static inline struct hso_serial *dev2ser(struct hso_device *hso_dev)
{ … }
#ifdef DEBUG
static void dbg_dump(int line_count, const char *func_name, unsigned char *buf,
unsigned int len)
{
static char name[255];
sprintf(name, "hso[%d:%s]", line_count, func_name);
print_hex_dump_bytes(name, DUMP_PREFIX_NONE, buf, len);
}
#define DUMP …
#define DUMP1 …
#else
#define DUMP(buf_, len_) …
#define DUMP1(buf_, len_) …
#endif
static int debug;
static int tty_major;
static int disable_net;
static const char driver_name[] = …;
static const char tty_filename[] = …;
static struct usb_driver hso_driver;
static struct tty_driver *tty_drv;
static struct hso_device *serial_table[HSO_SERIAL_TTY_MINORS];
static struct hso_device *network_table[HSO_MAX_NET_DEVICES];
static DEFINE_SPINLOCK(serial_table_lock);
static const s32 default_port_spec[] = …;
static const s32 icon321_port_spec[] = …;
#define default_port_device(vendor, product) …
#define icon321_port_device(vendor, product) …
static const struct usb_device_id hso_ids[] = …;
MODULE_DEVICE_TABLE(usb, hso_ids);
static ssize_t hsotype_show(struct device *dev,
struct device_attribute *attr, char *buf)
{ … }
static DEVICE_ATTR_RO(hsotype);
static struct attribute *hso_serial_dev_attrs[] = …;
ATTRIBUTE_GROUPS(…);
static int hso_urb_to_index(struct hso_serial *serial, struct urb *urb)
{ … }
static u32 hso_mux_to_port(int mux)
{ … }
static u32 hso_port_to_mux(int port)
{ … }
static struct hso_serial *get_serial_by_shared_int_and_type(
struct hso_shared_int *shared_int,
int mux)
{ … }
static struct hso_serial *get_serial_by_index(unsigned index)
{ … }
static int obtain_minor(struct hso_serial *serial)
{ … }
static void release_minor(struct hso_serial *serial)
{ … }
static void handle_usb_error(int status, const char *function,
struct hso_device *hso_dev)
{ … }
static int hso_net_open(struct net_device *net)
{ … }
static int hso_net_close(struct net_device *net)
{ … }
static void write_bulk_callback(struct urb *urb)
{ … }
static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb,
struct net_device *net)
{ … }
static const struct ethtool_ops ops = …;
static void hso_net_tx_timeout(struct net_device *net, unsigned int txqueue)
{ … }
static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
unsigned int count, unsigned char is_eop)
{ … }
static void fix_crc_bug(struct urb *urb, __le16 max_packet_size)
{ … }
static void read_bulk_callback(struct urb *urb)
{ … }
static void hso_init_termios(struct ktermios *termios)
{ … }
static void _hso_serial_set_termios(struct tty_struct *tty)
{ … }
static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb)
{ … }
static void put_rxbuf_data_and_resubmit_bulk_urb(struct hso_serial *serial)
{ … }
static void put_rxbuf_data_and_resubmit_ctrl_urb(struct hso_serial *serial)
{ … }
static void hso_std_serial_read_bulk_callback(struct urb *urb)
{ … }
static void hso_unthrottle_tasklet(struct tasklet_struct *t)
{ … }
static void hso_unthrottle(struct tty_struct *tty)
{ … }
static int hso_serial_open(struct tty_struct *tty, struct file *filp)
{ … }
static void hso_serial_close(struct tty_struct *tty, struct file *filp)
{ … }
static ssize_t hso_serial_write(struct tty_struct *tty, const u8 *buf,
size_t count)
{ … }
static unsigned int hso_serial_write_room(struct tty_struct *tty)
{ … }
static void hso_serial_cleanup(struct tty_struct *tty)
{ … }
static void hso_serial_set_termios(struct tty_struct *tty,
const struct ktermios *old)
{ … }
static unsigned int hso_serial_chars_in_buffer(struct tty_struct *tty)
{ … }
static int tiocmget_submit_urb(struct hso_serial *serial,
struct hso_tiocmget *tiocmget,
struct usb_device *usb)
{ … }
static void tiocmget_intr_callback(struct urb *urb)
{ … }
static int
hso_wait_modem_status(struct hso_serial *serial, unsigned long arg)
{ … }
static int hso_get_count(struct tty_struct *tty,
struct serial_icounter_struct *icount)
{ … }
static int hso_serial_tiocmget(struct tty_struct *tty)
{ … }
static int hso_serial_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear)
{ … }
static int hso_serial_ioctl(struct tty_struct *tty,
unsigned int cmd, unsigned long arg)
{ … }
static void hso_kick_transmit(struct hso_serial *serial)
{ … }
static int mux_device_request(struct hso_serial *serial, u8 type, u16 port,
struct urb *ctrl_urb,
struct usb_ctrlrequest *ctrl_req,
u8 *ctrl_urb_data, u32 size)
{ … }
static int hso_mux_serial_read(struct hso_serial *serial)
{ … }
static void intr_callback(struct urb *urb)
{ … }
static int hso_mux_serial_write_data(struct hso_serial *serial)
{ … }
static void hso_std_serial_write_bulk_callback(struct urb *urb)
{ … }
static int hso_std_serial_write_data(struct hso_serial *serial)
{ … }
static void ctrl_callback(struct urb *urb)
{ … }
static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
{ … }
static void hso_log_port(struct hso_device *hso_dev)
{ … }
static int hso_start_net_device(struct hso_device *hso_dev)
{ … }
static int hso_stop_net_device(struct hso_device *hso_dev)
{ … }
static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags)
{ … }
static int hso_stop_serial_device(struct hso_device *hso_dev)
{ … }
static void hso_serial_tty_unregister(struct hso_serial *serial)
{ … }
static void hso_serial_common_free(struct hso_serial *serial)
{ … }
static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
int rx_size, int tx_size)
{ … }
static struct hso_device *hso_create_device(struct usb_interface *intf,
int port_spec)
{ … }
static int remove_net_device(struct hso_device *hso_dev)
{ … }
static void hso_free_net_device(struct hso_device *hso_dev)
{ … }
static const struct net_device_ops hso_netdev_ops = …;
static void hso_net_init(struct net_device *net)
{ … }
static int add_net_device(struct hso_device *hso_dev)
{ … }
static int hso_rfkill_set_block(void *data, bool blocked)
{ … }
static const struct rfkill_ops hso_rfkill_ops = …;
static void hso_create_rfkill(struct hso_device *hso_dev,
struct usb_interface *interface)
{ … }
static const struct device_type hso_type = …;
static struct hso_device *hso_create_net_device(struct usb_interface *interface,
int port_spec)
{ … }
static void hso_free_tiomget(struct hso_serial *serial)
{ … }
static void hso_free_serial_device(struct hso_device *hso_dev)
{ … }
static struct hso_device *hso_create_bulk_serial_device(
struct usb_interface *interface, int port)
{ … }
static
struct hso_device *hso_create_mux_serial_device(struct usb_interface *interface,
int port,
struct hso_shared_int *mux)
{ … }
static void hso_free_shared_int(struct hso_shared_int *mux)
{ … }
static
struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface)
{ … }
static int hso_get_config_data(struct usb_interface *interface)
{ … }
static int hso_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{ … }
static void hso_disconnect(struct usb_interface *interface)
{ … }
static void async_get_intf(struct work_struct *data)
{ … }
static void async_put_intf(struct work_struct *data)
{ … }
static int hso_get_activity(struct hso_device *hso_dev)
{ … }
static int hso_put_activity(struct hso_device *hso_dev)
{ … }
static int hso_suspend(struct usb_interface *iface, pm_message_t message)
{ … }
static int hso_resume(struct usb_interface *iface)
{ … }
static void hso_serial_ref_free(struct kref *ref)
{ … }
static void hso_free_interface(struct usb_interface *interface)
{ … }
static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf,
int type, int dir)
{ … }
static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports)
{ … }
static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int,
struct usb_device *usb, gfp_t gfp)
{ … }
static const struct tty_operations hso_serial_ops = …;
static struct usb_driver hso_driver = …;
static int __init hso_init(void)
{ … }
static void __exit hso_exit(void)
{ … }
module_init(…) …;
module_exit(hso_exit);
MODULE_AUTHOR(…);
MODULE_DESCRIPTION(…);
MODULE_LICENSE(…) …;
MODULE_PARM_DESC(…) …;
module_param(debug, int, 0644);
MODULE_PARM_DESC(…) …;
module_param(tty_major, int, 0644);
MODULE_PARM_DESC(…) …;
module_param(disable_net, int, 0644);