Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755381AbbLKLgB (ORCPT ); Fri, 11 Dec 2015 06:36:01 -0500 Received: from mailout2.samsung.com ([203.254.224.25]:46046 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755192AbbLKL0J (ORCPT ); Fri, 11 Dec 2015 06:26:09 -0500 X-AuditID: cbfee61b-f793c6d00000236c-ab-566ab2d00f2c 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 v3 13/36] usb: gadget: composite: enable eps before calling set_alt() callback Date: Fri, 11 Dec 2015 12:24:52 +0100 Message-id: <1449833115-24065-14-git-send-email-r.baldyga@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1449833115-24065-1-git-send-email-r.baldyga@samsung.com> References: <1449833115-24065-1-git-send-email-r.baldyga@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprOLMWRmVeSWpSXmKPExsVy+t9jQd0Lm7LCDFb8MbKY9bKdxWLjjPWs Fgfv11s0L17PZnF51xw2i0XLWpkt1h65y27x4PBOdgcOj/1z17B79G1Zxehx/MZ2Jo/Pm+QC WKK4bFJSczLLUov07RK4Mhoe/Gcr6FSouP37BXsD4yPJLkZODgkBE4murWvZIWwxiQv31rN1 MXJxCAnMYpT4/beXBcL5ySixZvFzVpAqNgEdiS3fJzCC2CICAhLrX1xiByliFjjHKPHwThtY QlggQeLw8fVMIDaLgKrE60uvwGxeATeJJwfWMEOsk5M4eWwy2FBOoPjkk5fA4kICrhJvXq9j nMDIu4CRYRWjRGpBckFxUnquUV5quV5xYm5xaV66XnJ+7iZGcHA9k97BeHiX+yFGAQ5GJR7e BRxZYUKsiWXFlbmHGCU4mJVEeH9tAArxpiRWVqUW5ccXleakFh9ilOZgURLn3XcpMkxIID2x JDU7NbUgtQgmy8TBKdXA2MOw1+LpvGVeifL/fJPrNk/X5siP6xdS4w4Udd+9ckmVlsFTOdFI O/V/vxqmh6l3/fjauM/yPntC3LzCvM1h2wN+vL+/eEcF63a7Nz51eTKB1U7m2ROnbvn8a4rf DCsrr+XtXz2akhUn/ju2bsLZI/szft05nfkhbmX/Sfnn7jyXyp2lYk8yKrEUZyQaajEXFScC AJ4sDnMqAgAA 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 3695b75..34721ef 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -654,6 +654,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 @@ -999,6 +1019,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) { @@ -1078,7 +1154,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); @@ -1979,7 +2055,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/