// SPDX-License-Identifier: GPL-2.0+ /* * u_serial.c - utilities for USB gadget "serial port"/TTY support * * Copyright (C) 2003 Al Borchers ([email protected]) * Copyright (C) 2008 David Brownell * Copyright (C) 2008 by Nokia Corporation * * This code also borrows from usbserial.c, which is * Copyright (C) 1999 - 2002 Greg Kroah-Hartman ([email protected]) * Copyright (C) 2000 Peter Berger ([email protected]) * Copyright (C) 2000 Al Borchers ([email protected]) */ /* #define VERBOSE_DEBUG */ #include <linux/kernel.h> #include <linux/sched.h> #include <linux/device.h> #include <linux/delay.h> #include <linux/tty.h> #include <linux/tty_flip.h> #include <linux/slab.h> #include <linux/export.h> #include <linux/module.h> #include <linux/console.h> #include <linux/kstrtox.h> #include <linux/kthread.h> #include <linux/workqueue.h> #include <linux/kfifo.h> #include <linux/serial.h> #include "u_serial.h" /* * This component encapsulates the TTY layer glue needed to provide basic * "serial port" functionality through the USB gadget stack. Each such * port is exposed through a /dev/ttyGS* node. * * After this module has been loaded, the individual TTY port can be requested * (gserial_alloc_line()) and it will stay available until they are removed * (gserial_free_line()). Each one may be connected to a USB function * (gserial_connect), or disconnected (with gserial_disconnect) when the USB * host issues a config change event. Data can only flow when the port is * connected to the host. * * A given TTY port can be made available in multiple configurations. * For example, each one might expose a ttyGS0 node which provides a * login application. In one case that might use CDC ACM interface 0, * while another configuration might use interface 3 for that. The * work to handle that (including descriptor management) is not part * of this component. * * Configurations may expose more than one TTY port. For example, if * ttyGS0 provides login service, then ttyGS1 might provide dialer access * for a telephone or fax link. And ttyGS2 might be something that just * needs a simple byte stream interface for some messaging protocol that * is managed in userspace ... OBEX, PTP, and MTP have been mentioned. * * * gserial is the lifecycle interface, used by USB functions * gs_port is the I/O nexus, used by the tty driver * tty_struct links to the tty/filesystem framework * * gserial <---> gs_port ... links will be null when the USB link is * inactive; managed by gserial_{connect,disconnect}(). each gserial * instance can wrap its own USB control protocol. * gserial->ioport == usb_ep->driver_data ... gs_port * gs_port->port_usb ... gserial * * gs_port <---> tty_struct ... links will be null when the TTY file * isn't opened; managed by gs_open()/gs_close() * gserial->port_tty ... tty_struct * tty_struct->driver_data ... gserial */ /* RX and TX queues can buffer QUEUE_SIZE packets before they hit the * next layer of buffering. For TX that's a circular buffer; for RX * consider it a NOP. A third layer is provided by the TTY code. */ #define QUEUE_SIZE … #define WRITE_BUF_SIZE … #define GS_CONSOLE_BUF_SIZE … /* Prevents race conditions while accessing gser->ioport */ static DEFINE_SPINLOCK(serial_port_lock); /* console info */ struct gs_console { … }; /* * The port structure holds info for each port, one for each minor number * (and thus for each /dev/ node). */ struct gs_port { … }; static struct portmaster { … } ports[MAX_U_SERIAL_PORTS]; #define GS_CLOSE_TIMEOUT … #ifdef VERBOSE_DEBUG #ifndef pr_vdebug #define pr_vdebug(fmt, arg...) … #endif /* pr_vdebug */ #else #ifndef pr_vdebug #define pr_vdebug … #endif /* pr_vdebug */ #endif /*-------------------------------------------------------------------------*/ /* I/O glue between TTY (upper) and USB function (lower) driver layers */ /* * gs_alloc_req * * Allocate a usb_request and its buffer. Returns a pointer to the * usb_request or NULL if there is an error. */ struct usb_request * gs_alloc_req(struct usb_ep *ep, unsigned len, gfp_t kmalloc_flags) { … } EXPORT_SYMBOL_GPL(…); /* * gs_free_req * * Free a usb_request and its buffer. */ void gs_free_req(struct usb_ep *ep, struct usb_request *req) { … } EXPORT_SYMBOL_GPL(…); /* * gs_send_packet * * If there is data to send, a packet is built in the given * buffer and the size is returned. If there is no data to * send, 0 is returned. * * Called with port_lock held. */ static unsigned gs_send_packet(struct gs_port *port, char *packet, unsigned size) { … } /* * gs_start_tx * * This function finds available write requests, calls * gs_send_packet to fill these packets with data, and * continues until either there are no more write requests * available or no more data to send. This function is * run whenever data arrives or write requests are available. * * Context: caller owns port_lock; port_usb is non-null. */ static int gs_start_tx(struct gs_port *port) /* __releases(&port->port_lock) __acquires(&port->port_lock) */ { … } /* * Context: caller owns port_lock, and port_usb is set */ static unsigned gs_start_rx(struct gs_port *port) /* __releases(&port->port_lock) __acquires(&port->port_lock) */ { … } /* * RX work takes data out of the RX queue and hands it up to the TTY * layer until it refuses to take any more data (or is throttled back). * Then it issues reads for any further data. * * If the RX queue becomes full enough that no usb_request is queued, * the OUT endpoint may begin NAKing as soon as its FIFO fills up. * So QUEUE_SIZE packets plus however many the FIFO holds (usually two) * can be buffered before the TTY layer's buffers (currently 64 KB). */ static void gs_rx_push(struct work_struct *work) { … } static void gs_read_complete(struct usb_ep *ep, struct usb_request *req) { … } static void gs_write_complete(struct usb_ep *ep, struct usb_request *req) { … } static void gs_free_requests(struct usb_ep *ep, struct list_head *head, int *allocated) { … } static int gs_alloc_requests(struct usb_ep *ep, struct list_head *head, void (*fn)(struct usb_ep *, struct usb_request *), int *allocated) { … } /** * gs_start_io - start USB I/O streams * @port: port to use * Context: holding port_lock; port_tty and port_usb are non-null * * We only start I/O when something is connected to both sides of * this port. If nothing is listening on the host side, we may * be pointlessly filling up our TX buffers and FIFO. */ static int gs_start_io(struct gs_port *port) { … } /*-------------------------------------------------------------------------*/ /* TTY Driver */ /* * gs_open sets up the link between a gs_port and its associated TTY. * That link is broken *only* by TTY close(), and all driver methods * know that. */ static int gs_open(struct tty_struct *tty, struct file *file) { … } static int gs_close_flush_done(struct gs_port *p) { … } static void gs_close(struct tty_struct *tty, struct file *file) { … } static ssize_t gs_write(struct tty_struct *tty, const u8 *buf, size_t count) { … } static int gs_put_char(struct tty_struct *tty, u8 ch) { … } static void gs_flush_chars(struct tty_struct *tty) { … } static unsigned int gs_write_room(struct tty_struct *tty) { … } static unsigned int gs_chars_in_buffer(struct tty_struct *tty) { … } /* undo side effects of setting TTY_THROTTLED */ static void gs_unthrottle(struct tty_struct *tty) { … } static int gs_break_ctl(struct tty_struct *tty, int duration) { … } static int gs_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount) { … } static const struct tty_operations gs_tty_ops = …; /*-------------------------------------------------------------------------*/ static struct tty_driver *gs_tty_driver; #ifdef CONFIG_U_SERIAL_CONSOLE static void gs_console_complete_out(struct usb_ep *ep, struct usb_request *req) { … } static void __gs_console_push(struct gs_console *cons) { … } static void gs_console_work(struct work_struct *work) { … } static void gs_console_write(struct console *co, const char *buf, unsigned count) { … } static struct tty_driver *gs_console_device(struct console *co, int *index) { … } static int gs_console_connect(struct gs_port *port) { … } static void gs_console_disconnect(struct gs_port *port) { … } static int gs_console_init(struct gs_port *port) { … } static void gs_console_exit(struct gs_port *port) { … } ssize_t gserial_set_console(unsigned char port_num, const char *page, size_t count) { … } EXPORT_SYMBOL_GPL(…); ssize_t gserial_get_console(unsigned char port_num, char *page) { … } EXPORT_SYMBOL_GPL(…); #else static int gs_console_connect(struct gs_port *port) { return 0; } static void gs_console_disconnect(struct gs_port *port) { } static int gs_console_init(struct gs_port *port) { return -ENOSYS; } static void gs_console_exit(struct gs_port *port) { } #endif static int gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) { … } static int gs_closed(struct gs_port *port) { … } static void gserial_free_port(struct gs_port *port) { … } void gserial_free_line(unsigned char port_num) { … } EXPORT_SYMBOL_GPL(…); int gserial_alloc_line_no_console(unsigned char *line_num) { … } EXPORT_SYMBOL_GPL(…); int gserial_alloc_line(unsigned char *line_num) { … } EXPORT_SYMBOL_GPL(…); /** * gserial_connect - notify TTY I/O glue that USB link is active * @gser: the function, set up with endpoints and descriptors * @port_num: which port is active * Context: any (usually from irq) * * This is called activate endpoints and let the TTY layer know that * the connection is active ... not unlike "carrier detect". It won't * necessarily start I/O queues; unless the TTY is held open by any * task, there would be no point. However, the endpoints will be * activated so the USB host can perform I/O, subject to basic USB * hardware flow control. * * Caller needs to have set up the endpoints and USB function in @dev * before calling this, as well as the appropriate (speed-specific) * endpoint descriptors, and also have allocate @port_num by calling * @gserial_alloc_line(). * * Returns negative errno or zero. * On success, ep->driver_data will be overwritten. */ int gserial_connect(struct gserial *gser, u8 port_num) { … } EXPORT_SYMBOL_GPL(…); /** * gserial_disconnect - notify TTY I/O glue that USB link is inactive * @gser: the function, on which gserial_connect() was called * Context: any (usually from irq) * * This is called to deactivate endpoints and let the TTY layer know * that the connection went inactive ... not unlike "hangup". * * On return, the state is as if gserial_connect() had never been called; * there is no active USB I/O on these endpoints. */ void gserial_disconnect(struct gserial *gser) { … } EXPORT_SYMBOL_GPL(…); void gserial_suspend(struct gserial *gser) { … } EXPORT_SYMBOL_GPL(…); void gserial_resume(struct gserial *gser) { … } EXPORT_SYMBOL_GPL(…); static int __init userial_init(void) { … } module_init(…) …; static void __exit userial_cleanup(void) { … } module_exit(userial_cleanup); MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;