From d54f41468d1ba13735bf69a0e7655c5c7557776d Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Fri, 4 Dec 2020 15:09:30 +0900 Subject: [PATCH] WORKAROUND: usb: gadget: f_acm: Add dummy mode With amlogic dwc2, only fixed bytes for fifo can be used because it is set as 2848 bytes in sram. But Tizen default usb gadget mode enables mtp, acm, and sdb, and for those interfaces, 3104 bytes are required. Disabling acm gadget causes usb mode setting fail in Tizen deviced, so add acm gadget dummy mode which enables acm gadget in configuration, but not really using any endpoint fifo. Note: once gadget mode is properly fixed, this change will not be necessary, so it will be reverted after gadget mode modification is done in deviced. Change-Id: I6148a714520642050133b6c32bce666971869826 Signed-off-by: Seung-Woo Kim --- drivers/usb/gadget/Kconfig | 8 ++++++++ drivers/usb/gadget/function/f_acm.c | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index f6cce5a..45e3cc3 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -149,6 +149,14 @@ config USB_LIBCOMPOSITE config USB_F_ACM tristate +config USB_F_ACM_DUMMY + bool "ACM gadget dummy mode" + default n + depends on USB_F_ACM + help + to disable acm as dummy even with acm config, enable this option. + If unsure, say N. + config USB_F_SS_LB tristate diff --git a/drivers/usb/gadget/function/f_acm.c b/drivers/usb/gadget/function/f_acm.c index 5e3828d..b923d71 100644 --- a/drivers/usb/gadget/function/f_acm.c +++ b/drivers/usb/gadget/function/f_acm.c @@ -346,6 +346,10 @@ static int acm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) u16 w_value = le16_to_cpu(ctrl->wValue); u16 w_length = le16_to_cpu(ctrl->wLength); +#ifdef CONFIG_USB_F_ACM_DUMMY + return 0; +#endif + /* composite driver infrastructure handles everything except * CDC class messages; interface activation uses set_alt(). * @@ -425,6 +429,9 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) struct f_acm *acm = func_to_acm(f); struct usb_composite_dev *cdev = f->config->cdev; +#ifdef CONFIG_USB_F_ACM_DUMMY + return 0; +#endif /* we know alt == 0, so this is an activation or a reset */ if (intf == acm->ctrl_id) { @@ -469,6 +476,10 @@ static void acm_disable(struct usb_function *f) struct f_acm *acm = func_to_acm(f); struct usb_composite_dev *cdev = f->config->cdev; +#ifdef CONFIG_USB_F_ACM_DUMMY + return; +#endif + dev_dbg(&cdev->gadget->dev, "acm ttyGS%d deactivated\n", acm->port_num); gserial_disconnect(&acm->port); usb_ep_disable(acm->notify); @@ -576,6 +587,10 @@ static void acm_connect(struct gserial *port) { struct f_acm *acm = port_to_acm(port); +#ifdef CONFIG_USB_F_ACM_DUMMY + return; +#endif + acm->serial_state |= ACM_CTRL_DSR | ACM_CTRL_DCD; acm_notify_serial_state(acm); } @@ -584,6 +599,9 @@ static void acm_disconnect(struct gserial *port) { struct f_acm *acm = port_to_acm(port); +#ifdef CONFIG_USB_F_ACM_DUMMY + return; +#endif acm->serial_state &= ~(ACM_CTRL_DSR | ACM_CTRL_DCD); acm_notify_serial_state(acm); } @@ -593,6 +611,9 @@ static int acm_send_break(struct gserial *port, int duration) struct f_acm *acm = port_to_acm(port); u16 state; +#ifdef CONFIG_USB_F_ACM_DUMMY + return 0; +#endif state = acm->serial_state; state &= ~ACM_CTRL_BRK; if (duration) @@ -614,6 +635,9 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) int status; struct usb_ep *ep; +#ifdef CONFIG_USB_F_ACM_DUMMY + return 0; +#endif /* REVISIT might want instance-specific strings to help * distinguish instances ... */ @@ -713,6 +737,10 @@ static void acm_unbind(struct usb_configuration *c, struct usb_function *f) { struct f_acm *acm = func_to_acm(f); +#ifdef CONFIG_USB_F_ACM_DUMMY + return; +#endif + acm_string_defs[0].id = 0; usb_free_all_descriptors(f); if (acm->notify_req) @@ -786,7 +814,7 @@ static struct configfs_attribute *acm_attrs[] = { NULL, }; -static struct config_item_type acm_func_type = { +static __maybe_unused struct config_item_type acm_func_type = { .ct_item_ops = &acm_item_ops, .ct_attrs = acm_attrs, .ct_owner = THIS_MODULE, @@ -797,24 +825,28 @@ static void acm_free_instance(struct usb_function_instance *fi) struct f_serial_opts *opts; opts = container_of(fi, struct f_serial_opts, func_inst); +#ifndef CONFIG_USB_F_ACM_DUMMY gserial_free_line(opts->port_num); +#endif kfree(opts); } static struct usb_function_instance *acm_alloc_instance(void) { struct f_serial_opts *opts; - int ret; + __maybe_unused int ret; opts = kzalloc(sizeof(*opts), GFP_KERNEL); if (!opts) return ERR_PTR(-ENOMEM); opts->func_inst.free_func_inst = acm_free_instance; +#ifndef CONFIG_USB_F_ACM_DUMMY ret = gserial_alloc_line(&opts->port_num); if (ret) { kfree(opts); return ERR_PTR(ret); } +#endif config_group_init_type_name(&opts->func_inst.group, "", &acm_func_type); return &opts->func_inst; -- 2.7.4