From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757108AbcBCMkz (ORCPT ); Wed, 3 Feb 2016 07:40:55 -0500 Received: from mailout2.samsung.com ([203.254.224.25]:60660 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756990AbcBCMku (ORCPT ); Wed, 3 Feb 2016 07:40:50 -0500 X-AuditID: cbfee61b-f793c6d00000236c-11-56b1f550dcb2 From: Robert Baldyga To: balbi@ti.com Cc: gregkh@linuxfoundation.org, andrzej.p@samsung.com, m.szyprowski@samsung.com, b.zolnierkie@samsung.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, Robert Baldyga Subject: [PATCH v4 13/43] usb: gadget: composite: enable eps before calling set_alt() callback Date: Wed, 03 Feb 2016 13:39:21 +0100 Message-id: <1454503191-11796-14-git-send-email-r.baldyga@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1454503191-11796-1-git-send-email-r.baldyga@samsung.com> References: <1454503191-11796-1-git-send-email-r.baldyga@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprKLMWRmVeSWpSXmKPExsVy+t9jQd2ArxvDDOZPsraY9bKdxWLjjPWs Fgfv11s0L17PZnF51xw2i0XLWpkt1h65y27x4PBOdgcOj/1z17B79G1Zxehx/MZ2Jo/Pm+QC WKK4bFJSczLLUov07RK4Mpad+s1WcFqhYu+tNsYGxqlSXYycHBICJhJrTj9jhrDFJC7cW88G YgsJzGKUOL40t4uRC8j+ySixZP8dsASbgI7Elu8TGEFsEQEBifUvLrGDFDELnGOUeHinDSwh LJAgMbn9BROIzSKgKrGoazI7iM0r4Cbx4eVaRohtchInj01m7WLk4OAEij885gCx2FViV+t3 xgmMvAsYGVYxSqQWJBcUJ6XnGuWllusVJ+YWl+al6yXn525iBAfWM+kdjId3uR9iFOBgVOLh jfi1IUyINbGsuDL3EKMEB7OSCK/R541hQrwpiZVVqUX58UWlOanFhxilOViUxHkf/18XJiSQ nliSmp2aWpBaBJNl4uCUamDcdevLS62ndrxnYt8dmriS6/2BTjven+1Wc38Gywvs+fAm6C3b 04srTuRcWO/DrcN81dJcnfHXXbvpL2aJd1vYqGio3DdPP/I97tFqn4iJAvpd335PrlpU9PTU eiahYttzR7oF263Tc1ZK7JFauKFKbX5pkZPspaMd9d3Cpz5I3trROr2825RZiaU4I9FQi7mo OBEAhsQE2igCAAA= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Change set_alt() behavior for functions using new API. Before we call set_alt() callback, we disable endpoints of previously selected altsetting, and enable endpoints of currently selected altsetting, which reduces amount of boilerplate code in USB functions. We also calculate index of interface in function and pass it to set_alt() callback instead of passing index of interface in configuration which has to be obtained from interface descriptor. This simplifies altsetting changes handling in code of USB functions. Signed-off-by: Robert Baldyga --- drivers/usb/gadget/composite.c | 83 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index f2c08b3..0c962d4 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -650,6 +650,26 @@ static void usb_function_free_vendor_descs(struct usb_function *f) } /** + * usb_interface_id_to_index - if interface with a specified id belongs + * to given USB function, return its index within descriptors array + * of this function + * @f: USB function + * @id: id number of interface + * + * Returns interface index on success, else negative errno. + */ +static int usb_interface_id_to_index(struct usb_function *f, u8 id) +{ + int i; + + for (i = 0; i < f->descs->intfs_num; ++i) + if (f->descs->intfs[i]->id == id) + return i; + + return -EINVAL; +} + +/** * usb_interface_id() - allocate an unused interface ID * @config: configuration associated with the interface * @function: function handling the interface @@ -995,6 +1015,65 @@ static void reset_config(struct usb_composite_dev *cdev) cdev->delayed_status = 0; } +/** + * set_alt() - select specified altsetting in given interface + * @f: USB function + * @i: interface id number + * @a: altsetting number + * + * This function has different behavior depending on which API is used by + * given USB function. For functions using old API behavior stays unchanged, + * while for functions using new API index of interface in function is + * calculated and endpoints are configured and enabled before calling + * set_alt() callback. + */ +static int set_alt(struct usb_function *f, unsigned i, unsigned a) +{ + struct usb_composite_dev *cdev = f->config->cdev; + struct usb_composite_altset *alt; + struct usb_composite_ep *ep; + int e, ret = -EINVAL; + + /* To be removed after switch to new API */ + if (!usb_function_is_new_api(f)) + return f->set_alt(f, i, a); + + i = usb_interface_id_to_index(f, i); + if (i < 0) + return i; + + disable_interface(f, i); + + if (a >= f->descs->intfs[i]->altsets_num) + return -EINVAL; + + alt = f->descs->intfs[i]->altsets[a]; + for (e = 0; e < alt->eps_num; ++e) { + ep = alt->eps[e]; + ret = config_ep_by_speed(cdev->gadget, f, ep->ep); + if (ret) + goto err; + ret = usb_ep_enable(ep->ep); + if (ret) + goto err; + } + + f->descs->intfs[i]->cur_altset = a; + ret = f->set_alt(f, i, a); + if (ret == USB_GADGET_DELAYED_STATUS) + goto out; + if (ret < 0) + goto err; + + return 0; +err: + for (e = 0; e < alt->eps_num; ++e) + usb_ep_disable(alt->eps[e]->ep); + f->descs->intfs[i]->cur_altset = -1; +out: + return ret; +} + static int set_config(struct usb_composite_dev *cdev, const struct usb_ctrlrequest *ctrl, unsigned number) { @@ -1074,7 +1153,7 @@ static int set_config(struct usb_composite_dev *cdev, set_bit(addr, f->endpoints); } - result = f->set_alt(f, tmp, 0); + result = set_alt(f, tmp, 0); if (result < 0) { DBG(cdev, "interface %d (%s/%p) alt 0 --> %d\n", tmp, f->name, f, result); @@ -1975,7 +2054,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) break; if (w_value && !f->set_alt) break; - value = f->set_alt(f, w_index, w_value); + value = set_alt(f, w_index, w_value); if (value == USB_GADGET_DELAYED_STATUS) { DBG(cdev, "%s: interface %d (%s) requested delayed status\n", -- 1.9.1