Some not-so-well-behaving USB hosts with a popular proprietary operating
system sometimes issue per-device requests even though they mean requests
for a particular function, e.g. for ptp (picture transfer protocol).

This patch adds optional "for_device" function in usb_configuration so that
it can be used as the last fallback when handling unknown requests. If it
is not set then the composite_setup() behaviour remains unchanged.

Signed-off-by: Andrzej Pietrasiewicz <andrze...@samsung.com>
---
 drivers/usb/gadget/composite.c | 16 ++++++++++------
 include/linux/usb/composite.h  |  1 +
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 6178353..32b0104 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1785,12 +1785,16 @@ unknown:
                        }
 
                        /* try the only function in the current config */
-                       if (!list_is_singular(&c->functions))
-                               goto done;
-                       f = list_first_entry(&c->functions, struct usb_function,
-                                            list);
-                       if (f->setup)
-                               value = f->setup(f, ctrl);
+                       if (list_is_singular(&c->functions)) {
+                               f = list_first_entry(&c->functions,
+                                                    struct usb_function, list);
+                               if (f->setup)
+                                       value = f->setup(f, ctrl);
+                       } else {
+                               f = c->for_device;
+                               if (f && f->setup)
+                                       value = f->setup(f, ctrl);
+                       }
                }
 
                goto done;
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 3d87def..080aaa2 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -313,6 +313,7 @@ struct usb_configuration {
        unsigned                highspeed:1;
        unsigned                fullspeed:1;
        struct usb_function     *interface[MAX_CONFIG_INTERFACES];
+       struct usb_function     *for_device;
 };
 
 int usb_add_config(struct usb_composite_dev *,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to