Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754651AbbKCM7U (ORCPT ); Tue, 3 Nov 2015 07:59:20 -0500 Received: from mailout4.samsung.com ([203.254.224.34]:45822 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754088AbbKCMy4 (ORCPT ); Tue, 3 Nov 2015 07:54:56 -0500 X-AuditID: cbfee61b-f79d56d0000048c5-8c-5638ae9e3351 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 13/23] usb: gadget: composite: enable eps before calling set_alt() callback Date: Tue, 03 Nov 2015 13:53:52 +0100 Message-id: <1446555242-3733-14-git-send-email-r.baldyga@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1446555242-3733-1-git-send-email-r.baldyga@samsung.com> References: <1446555242-3733-1-git-send-email-r.baldyga@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprCLMWRmVeSWpSXmKPExsVy+t9jQd156yzCDD5v0raY9bKdxWLjjPWs Fgfv11s0L17PZnF51xw2i0XLWpkt1h65y27x4PBOdgcOj/1z17B79G1Zxehx/MZ2Jo/Pm+QC WKK4bFJSczLLUov07RK4Mub+/sBW0KlQ0XTuDUsD4yPJLkZODgkBE4n3/feZIWwxiQv31rN1 MXJxCAnMYpR4+movM4Tzk1Fi2/PTYFVsAjoSW75PYASxRQQEJNa/uMQOUsQscI5R4uGdNqAE B4ewQKzElj4/kBoWAVWJda9nMYHYvAKuEr0HF7FBbJOTOHlsMitIOSdQ/NI7ZRBTSMBF4vh2 ngmMvAsYGVYxSqQWJBcUJ6XnGuWllusVJ+YWl+al6yXn525iBIfVM+kdjId3uR9iFOBgVOLh XbDEPEyINbGsuDL3EKMEB7OSCO/uuRZhQrwpiZVVqUX58UWlOanFhxilOViUxHn1PY3ChATS E0tSs1NTC1KLYLJMHJxSDYybPQ6pHtI+rCex13bdS6unGqLBHwNqEqeket62X7sw2/TW05im L3KLzOv9/jvYhf2yFTu96zDzzUv+Ddvv3bR4e1M38iHzvcXF6dOPPNT4s+JDxd675g9/rjp6 WKtQyPdaodWptqW7s7VPXcxQVUh9a5K5/J957LXI62LmofLFjAn3t1zUa7qvxFKckWioxVxU nAgA0jO1YicCAAA= Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4220 Lines: 135 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 | 80 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index a965fbc..439beca 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -651,6 +651,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 @@ -996,6 +1016,62 @@ 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) + 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; + return ret; +} + static int set_config(struct usb_composite_dev *cdev, const struct usb_ctrlrequest *ctrl, unsigned number) { @@ -1075,7 +1151,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); @@ -1976,7 +2052,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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/