From 0cd049e906326c52b7a03249bf968dc7b42870f5 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 23 Dec 2012 21:09:57 +0100 Subject: [PATCH] --- yaml --- r: 354637 b: refs/heads/master c: 544aca39e670421c2daae4b6706f1e405b19ba72 h: refs/heads/master i: 354635: 468d180da79b399199559d8fdf5c2425463db7ab v: v3 --- [refs] | 2 +- trunk/drivers/usb/gadget/f_sourcesink.c | 70 ++++++++++++++++--------- 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/[refs] b/[refs] index c2ab87a6929b..4039691d0508 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 32b8666589d5c274cea0ea4b07e202422bf975b1 +refs/heads/master: 544aca39e670421c2daae4b6706f1e405b19ba72 diff --git a/trunk/drivers/usb/gadget/f_sourcesink.c b/trunk/drivers/usb/gadget/f_sourcesink.c index de608864c6db..bac04b0c628e 100644 --- a/trunk/drivers/usb/gadget/f_sourcesink.c +++ b/trunk/drivers/usb/gadget/f_sourcesink.c @@ -449,11 +449,14 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f) return 0; } +static struct usb_function *global_ss_func; + static void sourcesink_unbind(struct usb_configuration *c, struct usb_function *f) { usb_free_all_descriptors(f); kfree(func_to_ss(f)); + global_ss_func = NULL; } /* optionally require specific source/sink data patterns */ @@ -756,32 +759,10 @@ static void sourcesink_disable(struct usb_function *f) } /*-------------------------------------------------------------------------*/ - -static int __init sourcesink_bind_config(struct usb_configuration *c) -{ - struct f_sourcesink *ss; - int status; - - ss = kzalloc(sizeof *ss, GFP_KERNEL); - if (!ss) - return -ENOMEM; - - ss->function.name = "source/sink"; - ss->function.bind = sourcesink_bind; - ss->function.unbind = sourcesink_unbind; - ss->function.set_alt = sourcesink_set_alt; - ss->function.get_alt = sourcesink_get_alt; - ss->function.disable = sourcesink_disable; - - status = usb_add_function(c, &ss->function); - if (status) - kfree(ss); - return status; -} - -static int sourcesink_setup(struct usb_configuration *c, +static int sourcesink_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) { + struct usb_configuration *c = f->config; struct usb_request *req = c->cdev->req; int value = -EOPNOTSUPP; u16 w_index = le16_to_cpu(ctrl->wIndex); @@ -850,10 +831,49 @@ static int sourcesink_setup(struct usb_configuration *c, return value; } +static int __init sourcesink_bind_config(struct usb_configuration *c) +{ + struct f_sourcesink *ss; + int status; + + ss = kzalloc(sizeof(*ss), GFP_KERNEL); + if (!ss) + return -ENOMEM; + + global_ss_func = &ss->function; + + ss->function.name = "source/sink"; + ss->function.bind = sourcesink_bind; + ss->function.unbind = sourcesink_unbind; + ss->function.set_alt = sourcesink_set_alt; + ss->function.get_alt = sourcesink_get_alt; + ss->function.disable = sourcesink_disable; + ss->function.setup = sourcesink_setup; + + status = usb_add_function(c, &ss->function); + if (status) + kfree(ss); + return status; +} + +static int ss_config_setup(struct usb_configuration *c, + const struct usb_ctrlrequest *ctrl) +{ + if (!global_ss_func) + return -EOPNOTSUPP; + switch (ctrl->bRequest) { + case 0x5b: + case 0x5c: + return global_ss_func->setup(global_ss_func, ctrl); + default: + return -EOPNOTSUPP; + } +} + static struct usb_configuration sourcesink_driver = { .label = "source/sink", .strings = sourcesink_strings, - .setup = sourcesink_setup, + .setup = ss_config_setup, .bConfigurationValue = 3, .bmAttributes = USB_CONFIG_ATT_SELFPOWER, /* .iConfiguration = DYNAMIC */