linux/drivers/usb/gadget/function/f_acm.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * f_acm.c -- USB CDC serial (ACM) function driver
 *
 * Copyright (C) 2003 Al Borchers ([email protected])
 * Copyright (C) 2008 by David Brownell
 * Copyright (C) 2008 by Nokia Corporation
 * Copyright (C) 2009 by Samsung Electronics
 * Author: Michal Nazarewicz ([email protected])
 */

/* #define VERBOSE_DEBUG */

#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/err.h>

#include "u_serial.h"


/*
 * This CDC ACM function support just wraps control functions and
 * notifications around the generic serial-over-usb code.
 *
 * Because CDC ACM is standardized by the USB-IF, many host operating
 * systems have drivers for it.  Accordingly, ACM is the preferred
 * interop solution for serial-port type connections.  The control
 * models are often not necessary, and in any case don't do much in
 * this bare-bones implementation.
 *
 * Note that even MS-Windows has some support for ACM.  However, that
 * support is somewhat broken because when you use ACM in a composite
 * device, having multiple interfaces confuses the poor OS.  It doesn't
 * seem to understand CDC Union descriptors.  The new "association"
 * descriptors (roughly equivalent to CDC Unions) may sometimes help.
 */

struct f_acm {};

static inline struct f_acm *func_to_acm(struct usb_function *f)
{}

static inline struct f_acm *port_to_acm(struct gserial *p)
{}

/*-------------------------------------------------------------------------*/

/* notification endpoint uses smallish and infrequent fixed-size messages */

#define GS_NOTIFY_INTERVAL_MS
#define GS_NOTIFY_MAXPACKET

/* interface and class descriptors: */

static struct usb_interface_assoc_descriptor
acm_iad_descriptor =;


static struct usb_interface_descriptor acm_control_interface_desc =;

static struct usb_interface_descriptor acm_data_interface_desc =;

static struct usb_cdc_header_desc acm_header_desc =;

static struct usb_cdc_call_mgmt_descriptor
acm_call_mgmt_descriptor =;

static struct usb_cdc_acm_descriptor acm_descriptor =;

static struct usb_cdc_union_desc acm_union_desc =;

/* full speed support: */

static struct usb_endpoint_descriptor acm_fs_notify_desc =;

static struct usb_endpoint_descriptor acm_fs_in_desc =;

static struct usb_endpoint_descriptor acm_fs_out_desc =;

static struct usb_descriptor_header *acm_fs_function[] =;

/* high speed support: */
static struct usb_endpoint_descriptor acm_hs_notify_desc =;

static struct usb_endpoint_descriptor acm_hs_in_desc =;

static struct usb_endpoint_descriptor acm_hs_out_desc =;

static struct usb_descriptor_header *acm_hs_function[] =;

static struct usb_endpoint_descriptor acm_ss_in_desc =;

static struct usb_endpoint_descriptor acm_ss_out_desc =;

static struct usb_ss_ep_comp_descriptor acm_ss_bulk_comp_desc =;

static struct usb_descriptor_header *acm_ss_function[] =;

/* string descriptors: */

#define ACM_CTRL_IDX
#define ACM_DATA_IDX
#define ACM_IAD_IDX

/* static strings, in UTF-8 */
static struct usb_string acm_string_defs[] =;

static struct usb_gadget_strings acm_string_table =;

static struct usb_gadget_strings *acm_strings[] =;

/*-------------------------------------------------------------------------*/

/* ACM control ... data handling is delegated to tty library code.
 * The main task of this function is to activate and deactivate
 * that code based on device state; track parameters like line
 * speed, handshake state, and so on; and issue notifications.
 */

static void acm_complete_set_line_coding(struct usb_ep *ep,
		struct usb_request *req)
{}

static int acm_send_break(struct gserial *port, int duration);

static int acm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
{}

static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
{}

static void acm_disable(struct usb_function *f)
{}

/*-------------------------------------------------------------------------*/

/**
 * acm_cdc_notify - issue CDC notification to host
 * @acm: wraps host to be notified
 * @type: notification type
 * @value: Refer to cdc specs, wValue field.
 * @data: data to be sent
 * @length: size of data
 * Context: irqs blocked, acm->lock held, acm_notify_req non-null
 *
 * Returns zero on success or a negative errno.
 *
 * See section 6.3.5 of the CDC 1.1 specification for information
 * about the only notification we issue:  SerialState change.
 */
static int acm_cdc_notify(struct f_acm *acm, u8 type, u16 value,
		void *data, unsigned length)
{}

static int acm_notify_serial_state(struct f_acm *acm)
{}

static void acm_cdc_notify_complete(struct usb_ep *ep, struct usb_request *req)
{}

/* connect == the TTY link is open */

static void acm_connect(struct gserial *port)
{}

static void acm_disconnect(struct gserial *port)
{}

static int acm_send_break(struct gserial *port, int duration)
{}

/*-------------------------------------------------------------------------*/

/* ACM function driver setup/binding */
static int
acm_bind(struct usb_configuration *c, struct usb_function *f)
{}

static void acm_unbind(struct usb_configuration *c, struct usb_function *f)
{}

static void acm_free_func(struct usb_function *f)
{}

static void acm_resume(struct usb_function *f)
{}

static void acm_suspend(struct usb_function *f)
{}

static struct usb_function *acm_alloc_func(struct usb_function_instance *fi)
{}

static inline struct f_serial_opts *to_f_serial_opts(struct config_item *item)
{}

static void acm_attr_release(struct config_item *item)
{}

static struct configfs_item_operations acm_item_ops =;

#ifdef CONFIG_U_SERIAL_CONSOLE

static ssize_t f_acm_console_store(struct config_item *item,
		const char *page, size_t count)
{}

static ssize_t f_acm_console_show(struct config_item *item, char *page)
{}

CONFIGFS_ATTR();

#endif /* CONFIG_U_SERIAL_CONSOLE */

static ssize_t f_acm_port_num_show(struct config_item *item, char *page)
{}

CONFIGFS_ATTR_RO();

static ssize_t f_acm_protocol_show(struct config_item *item, char *page)
{}

static ssize_t f_acm_protocol_store(struct config_item *item,
		const char *page, size_t count)
{}

CONFIGFS_ATTR();

static struct configfs_attribute *acm_attrs[] =;

static const struct config_item_type acm_func_type =;

static void acm_free_instance(struct usb_function_instance *fi)
{}

static struct usb_function_instance *acm_alloc_instance(void)
{}
DECLARE_USB_FUNCTION_INIT(acm, acm_alloc_instance, acm_alloc_func);
MODULE_DESCRIPTION();
MODULE_LICENSE();