Re: [PATCH 20/29] usb: gadget: composite: add req_match method to usb_function

2015-03-02 Thread Bin Liu
Hi,

On Mon, Feb 23, 2015 at 9:02 AM, Andrzej Pietrasiewicz
andrze...@samsung.com wrote:
 Non-standard requests can encode the actual interface number in a
 non-standard way. For example composite_setup() assumes
 that it is w_index  0xFF, but the printer function encodes the interface
 number in a context-dependet way (either w_index or w_index  8).
 This can lead to such requests being directed to wrong functions.

 This patch adds req_match() method to usb_function. Its purpose is to
 verify that a given request can be handled by a given function.
 If any function within a configuration provides the method and it returns
 true, then it is assumed that the right function is found.

 If a function uses req_match(), it should try as hard as possible to
 determine if the request is meant for it.

 If no functions in a configuration provide req_match or none of them
 returns true, then fall back to the usual approach.

 Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com
 ---
  drivers/usb/gadget/composite.c | 7 ++-
  include/linux/usb/composite.h  | 3 +++
  2 files changed, 9 insertions(+), 1 deletion(-)

 diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
 index 9fb9231..07cee80 100644
 --- a/drivers/usb/gadget/composite.c
 +++ b/drivers/usb/gadget/composite.c
 @@ -1758,6 +1758,11 @@ unknown:
  * take such requests too, if that's ever needed:  to work
  * in config 0, etc.
  */
 +   list_for_each_entry(f, cdev-config-functions, list)
 +   if (f-req_match  f-req_match(f, ctrl))
 +   break;

In this loop, if f-req_match is NULL, or f-req_match() returns
false, f becomes non-NULL at the end of the loop, which causes kernel
panic later.

 +   if (f-list != cdev-config-functions)
 +   goto try_fun_setup;

The following change fixes it.

+   list_for_each_entry(f, cdev-config-functions, list)
+   if (f-req_match  f-req_match(f, ctrl))
+   goto try_fun_setup;
+
+   f = NULL;
+

Regards,
-Bin.

 switch (ctrl-bRequestType  USB_RECIP_MASK) {
 case USB_RECIP_INTERFACE:
 if (!cdev-config || intf = MAX_CONFIG_INTERFACES)
 @@ -1775,7 +1780,7 @@ unknown:
 f = NULL;
 break;
 }
 -
 +try_fun_setup:
 if (f  f-setup)
 value = f-setup(f, ctrl);
 else {
 diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
 index 3d87def..51f477a 100644
 --- a/include/linux/usb/composite.h
 +++ b/include/linux/usb/composite.h
 @@ -147,6 +147,7 @@ struct usb_os_desc_table {
   * then only altsetting zero is supported.
   * @disable: (REQUIRED) Indicates the function should be disabled.  Reasons
   * include host resetting or reconfiguring the gadget, and disconnection.
 + * @req_match: Tests if a given class request can be handled by this 
 function.
   * @setup: Used for interface-specific control requests.
   * @suspend: Notifies functions when the host stops sending USB traffic.
   * @resume: Notifies functions when the host restarts USB traffic.
 @@ -211,6 +212,8 @@ struct usb_function {
 int (*get_alt)(struct usb_function *,
 unsigned interface);
 void(*disable)(struct usb_function *);
 +   bool(*req_match)(struct usb_function *,
 +   const struct usb_ctrlrequest *);
 int (*setup)(struct usb_function *,
 const struct usb_ctrlrequest *);
 void(*suspend)(struct usb_function *);
 --
 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
--
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


Re: [PATCH 20/29] usb: gadget: composite: add req_match method to usb_function

2015-03-02 Thread Andrzej Pietrasiewicz

W dniu 02.03.2015 o 23:03, Bin Liu pisze:

Hi,

On Mon, Feb 23, 2015 at 9:02 AM, Andrzej Pietrasiewicz
andrze...@samsung.com wrote:

Non-standard requests can encode the actual interface number in a
non-standard way. For example composite_setup() assumes
that it is w_index  0xFF, but the printer function encodes the interface
number in a context-dependet way (either w_index or w_index  8).
This can lead to such requests being directed to wrong functions.

This patch adds req_match() method to usb_function. Its purpose is to
verify that a given request can be handled by a given function.
If any function within a configuration provides the method and it returns
true, then it is assumed that the right function is found.

If a function uses req_match(), it should try as hard as possible to
determine if the request is meant for it.

If no functions in a configuration provide req_match or none of them
returns true, then fall back to the usual approach.

Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com
---
  drivers/usb/gadget/composite.c | 7 ++-
  include/linux/usb/composite.h  | 3 +++
  2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 9fb9231..07cee80 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1758,6 +1758,11 @@ unknown:
  * take such requests too, if that's ever needed:  to work
  * in config 0, etc.
  */
+   list_for_each_entry(f, cdev-config-functions, list)
+   if (f-req_match  f-req_match(f, ctrl))
+   break;


In this loop, if f-req_match is NULL, or f-req_match() returns
false, f becomes non-NULL at the end of the loop, which causes kernel
panic later.


+   if (f-list != cdev-config-functions)
+   goto try_fun_setup;


The following change fixes it.

+   list_for_each_entry(f, cdev-config-functions, list)
+   if (f-req_match  f-req_match(f, ctrl))
+   goto try_fun_setup;
+
+   f = NULL;
+


Right. Thanks!

AP

--
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


Re: [PATCH 20/29] usb: gadget: composite: add req_match method to usb_function

2015-03-02 Thread Andrzej Pietrasiewicz

W dniu 27.02.2015 o 21:58, Felipe Balbi pisze:

Hi,

On Fri, Feb 27, 2015 at 02:55:25PM -0600, Felipe Balbi wrote:

On Mon, Feb 23, 2015 at 04:02:09PM +0100, Andrzej Pietrasiewicz wrote:

Non-standard requests can encode the actual interface number in a
non-standard way. For example composite_setup() assumes
that it is w_index  0xFF, but the printer function encodes the interface
number in a context-dependet way (either w_index or w_index  8).
This can lead to such requests being directed to wrong functions.

This patch adds req_match() method to usb_function. Its purpose is to
verify that a given request can be handled by a given function.
If any function within a configuration provides the method and it returns
true, then it is assumed that the right function is found.

If a function uses req_match(), it should try as hard as possible to
determine if the request is meant for it.

If no functions in a configuration provide req_match or none of them
returns true, then fall back to the usual approach.

Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com


this regresses testusb at least on am335x:



I don't have this particular hardware but will try looking into the issue.
As soon as I have some results I will let you know.

AP

--
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


Re: [PATCH 20/29] usb: gadget: composite: add req_match method to usb_function

2015-03-02 Thread Andrzej Pietrasiewicz

W dniu 27.02.2015 o 21:55, Felipe Balbi pisze:

On Mon, Feb 23, 2015 at 04:02:09PM +0100, Andrzej Pietrasiewicz wrote:

Non-standard requests can encode the actual interface number in a
non-standard way. For example composite_setup() assumes
that it is w_index  0xFF, but the printer function encodes the interface
number in a context-dependet way (either w_index or w_index  8).
This can lead to such requests being directed to wrong functions.

This patch adds req_match() method to usb_function. Its purpose is to
verify that a given request can be handled by a given function.
If any function within a configuration provides the method and it returns
true, then it is assumed that the right function is found.

If a function uses req_match(), it should try as hard as possible to
determine if the request is meant for it.

If no functions in a configuration provide req_match or none of them
returns true, then fall back to the usual approach.

Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com


this regresses testusb at least on am335x:

test 14: control writes


When I tried it on odroid u3 (with dwc2) at the host side it says:

/dev/bus/usb/002/009 test 14 -- 22 (Invalid argument)

(run as root at host)

but there is no problem at the device side.

On the same board with dummy hcd the result for test 14 is:

/dev/bus/usb/002/002 test 14 -- 25 (Inappropriate ioctl for device)

(run as root at host)

but no problem with the device.

I'm running tools/usb/testusb with -a option. Do I need some
more preparation to actually run the tests? Perhaps I don't
experience the problem because there is no attempt to
actually trigger composite_setup() call?

On the other hand I'm thinking what could be wrong with the patch
adding req_match? With the patch applied usb_function structure
has one more member, which is (1) checked for not being NULL and,
if non-NULL it is (2) dereferenced in composite_setup(). The problem
you experience might be that (1) succeeds (req_match != NULL) and
then (2) explodes, because the pointer is actually either garbage or
some other data mis-interpreted. The struct usb_function in question
is allocated with kzalloc() in both f_loopback.c:loopback_alloc()
and f_sourcesink.c:source_sink_alloc_func() so there is no way
the pointer is not initialized to NULL, so (1) should fail
in the first place. But if (1) does not fail the member in question
is non-NULL, but how could it become non-NULL if properly initialized?
The only possibilities are: explicit assignment, unintentional memory
overwrite or mismatch between headers with which your modules/and or your
kernel have been built. If you did not add explicit assignment, and
indeed you didn't, explicit assignment is out of the question. Unintentional
memory overwrite might happen with e.g. memcpy() or variants of strcpy(),
but both f_sourcesink.c and f_loopback.c do not contain any  cpy string.
However silly this might sound, would you be able to double check
that you used consistent headers+kernel binary+module binaries?

AP
--
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


Re: [PATCH 20/29] usb: gadget: composite: add req_match method to usb_function

2015-03-02 Thread Bin Liu
Hi,

On Mon, Mar 2, 2015 at 2:38 AM, Andrzej Pietrasiewicz
andrze...@samsung.com wrote:
 W dniu 27.02.2015 o 21:58, Felipe Balbi pisze:

 Hi,

 On Fri, Feb 27, 2015 at 02:55:25PM -0600, Felipe Balbi wrote:

 On Mon, Feb 23, 2015 at 04:02:09PM +0100, Andrzej Pietrasiewicz wrote:

 Non-standard requests can encode the actual interface number in a
 non-standard way. For example composite_setup() assumes
 that it is w_index  0xFF, but the printer function encodes the
 interface
 number in a context-dependet way (either w_index or w_index  8).
 This can lead to such requests being directed to wrong functions.

 This patch adds req_match() method to usb_function. Its purpose is to
 verify that a given request can be handled by a given function.
 If any function within a configuration provides the method and it
 returns
 true, then it is assumed that the right function is found.

 If a function uses req_match(), it should try as hard as possible to
 determine if the request is meant for it.

 If no functions in a configuration provide req_match or none of them
 returns true, then fall back to the usual approach.

 Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com


 this regresses testusb at least on am335x:


 I don't have this particular hardware but will try looking into the issue.
 As soon as I have some results I will let you know.

I am unable to explain what I found below. Toolchain related?

I added the following change to the driver.

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 07cee80..3b0e5da 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1781,6 +1781,7 @@ unknown:
break;
}
 try_fun_setup:
+   dev_err(NULL, f %p, -setup %p\n, f, f-setup);
if (f  f-setup)
value = f-setup(f, ctrl);
else {

Then, got the following kernel crash log.

[   59.365832] (NULL device *): f bf0116ac, -setup 00400403
[   59.371515] Unable to handle kernel paging request at virtual
address 00400402

So the problem is f-setup pointer is not word aligned.

The following patch seems make the issue disappeared.

diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 51f477a..dde3184 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -212,10 +212,10 @@ struct usb_function {
int (*get_alt)(struct usb_function *,
unsigned interface);
void(*disable)(struct usb_function *);
-   bool(*req_match)(struct usb_function *,
-   const struct usb_ctrlrequest *);
int (*setup)(struct usb_function *,
const struct usb_ctrlrequest *);
+   bool(*req_match)(struct usb_function *,
+   const struct usb_ctrlrequest *);
void(*suspend)(struct usb_function *);
void(*resume)(struct usb_function *);

Regards,
-Bin.


 AP


 --
 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
--
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


Re: [PATCH 20/29] usb: gadget: composite: add req_match method to usb_function

2015-02-27 Thread Felipe Balbi
Hi,

On Fri, Feb 27, 2015 at 02:55:25PM -0600, Felipe Balbi wrote:
 On Mon, Feb 23, 2015 at 04:02:09PM +0100, Andrzej Pietrasiewicz wrote:
  Non-standard requests can encode the actual interface number in a
  non-standard way. For example composite_setup() assumes
  that it is w_index  0xFF, but the printer function encodes the interface
  number in a context-dependet way (either w_index or w_index  8).
  This can lead to such requests being directed to wrong functions.
  
  This patch adds req_match() method to usb_function. Its purpose is to
  verify that a given request can be handled by a given function.
  If any function within a configuration provides the method and it returns
  true, then it is assumed that the right function is found.
  
  If a function uses req_match(), it should try as hard as possible to
  determine if the request is meant for it.
  
  If no functions in a configuration provide req_match or none of them
  returns true, then fall back to the usual approach.
  
  Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com
 
 this regresses testusb at least on am335x:
 
 test 14: control writes
 [   32.968145] usbtest 2-1:3.0: TEST 14:  15000 ep0out, 1..256 vary 1
 [   32.974659] Unable to handle kernel paging request at virtual address 
 00400402
 [   32.982199] pgd = dd3fc000
 [   32.985021] [00400402] *pgd=
 [   32.988765] Internal error: Oops: 8005 [#1] SMP ARM
 [   32.994217] Modules linked in: usbtest usb_f_ss_lb g_zero libcomposite 
 configfs musb_dsps musb_hdrc udc_core usbcore usb_common omap_rng rng_core 
 musb_am335x rtc_omap omap_wdt leds_gpio led_class ipv6 autofs4
 [   33.013652] CPU: 0 PID: 219 Comm: testusb Tainted: GW   
 4.0.0-rc1-00069-g00b54e1bab53 #350
 [   33.023364] Hardware name: Generic AM33XX (Flattened Device Tree)
 [   33.029722] task: dd27c680 ti: dd2c2000 task.ti: dd2c2000
 [   33.035358] PC is at 0x400402
 [   33.038499] LR is at composite_setup+0x29c/0x16f0 [libcomposite]
 [   33.044767] pc : [00400402]lr : [bf166f34]psr: 200301b3
 [   33.044767] sp : dd2c3ad8  ip : bf179668  fp : 0040
 [   33.056747] r10:   r9 : dd2c3b48  r8 : 
 [   33.062197] r7 :   r6 : bf179690  r5 : bf17963c  r4 : dd26f280
 [   33.069008] r3 : 00400403  r2 : bf179690  r1 : dd2c3b48  r0 : bf17963c
 [   33.075821] Flags: nzCv  IRQs off  FIQs on  Mode SVC_32  ISA Thumb  
 Segment user
 [   33.083538] Control: 10c5387d  Table: 9d3fc019  DAC: 0015
 [   33.089533] Process testusb (pid: 219, stack limit = 0xdd2c2218)
 [   33.095800] Stack: (0xdd2c3ad8 to 0xdd2c4000)
 [   33.100346] 3ac0:   
  1f205000
 [   33.108883] 3ae0: c083c880 dfa41880  0100 dd2c3d6c  
  0003
 [   33.117419] 3b00: 0001 0001 c0064714 c08c3afb dd2c3b4e e1a26410 
 dd237010 bf12b014
 [   33.125956] 3b20: e1a26400 bf12b010 dd236304 dd236010 0001 bf125244 
 e1a26410 
 [   33.134492] 3b40:   5b40 0100 39363831 dd2362f0 
 dd236010 bf12b008
 [   33.143029] 3b60: dd237010  dd2362ec 0099  bf120908 
 dd26eb80 de524010
 [   33.151565] 3b80: 0001 bf122dc8 0001 dd26eb80 0841 c08c3afb 
 c070b44e dd236010
 [   33.160102] 3ba0:  bf14f148 dd287650 dd2362f0 60030193 e1a28000 
 c08bd83c bf14e6bc
 [   33.168639] 3bc0: bf14e5dc dd3e8600 dd284b20 00af   
  c08bd828
 [   33.177175] 3be0: c08bd83c c0084c1c de111610 0004  dd284ac0 
 0010 dd284ac0
 [   33.185712] 3c00: dd284b20 c0841594  0001 de013000 01f4 
  c0084df8
 [   33.194248] 3c20: dd284ac0 00af c0841594 c0087a30 00af c0084304 
 c083ad30 c00845ac
 [   33.202785] 3c40: dd2c3c78 c088db80 dd2c3c78 c08fffc0 0012 c0840100 
  c0008690
 [   33.211322] 3c60: c0574a80 c0308db8 40030013  dd2c3cac c0575cc0 
 dd2c3cf8 ffd0
 [   33.219858] 3c80:   99a4 c0572e28 dd2c3cc4 0002 
 c0840100 
 [   33.228395] 3ca0: 01f4   dd2c3cc0 c0574a80 c0308db8 
 40030013 
 [   33.236931] 3cc0:   c073fa98 dd2c3dc4 c08d4c40 000e 
 dd2c3d08 
 [   33.245468] 3ce0:       
 dd2c3d54 dd2c2000
 [   33.254004] 3d00: dd2c3d58 0002  c0572e28 73753d4d 0001 
 dd27c680 c0064714
 [   33.262541] 3d20: dd2c3d5c dd2c3d5c dd270030 dd26eb80 dd2c3d54  
 dd2c3d8c 1388
 [   33.271077] 3d40:  005b 0040 bf0a218c   
 00010001 dd2c3d20
 [   33.279614] 3d60: dd2c3d20 de497000 dd37c9c0 0100   
 de497000 bf0a22a0
 [   33.288150] 3d80:  8200 dd3811b0 dd2c3df0 0006 dd26e680 
 0100 de453800
 [   33.296687] 3da0:  0100 de497068 de497000  bf189434 
  
 [   33.305223] 3dc0: de453800 0100 1388 dd2c3df0 0100 3a98 
 0001 dd26e680
 [  

Re: [PATCH 20/29] usb: gadget: composite: add req_match method to usb_function

2015-02-27 Thread Felipe Balbi
On Mon, Feb 23, 2015 at 04:02:09PM +0100, Andrzej Pietrasiewicz wrote:
 Non-standard requests can encode the actual interface number in a
 non-standard way. For example composite_setup() assumes
 that it is w_index  0xFF, but the printer function encodes the interface
 number in a context-dependet way (either w_index or w_index  8).
 This can lead to such requests being directed to wrong functions.
 
 This patch adds req_match() method to usb_function. Its purpose is to
 verify that a given request can be handled by a given function.
 If any function within a configuration provides the method and it returns
 true, then it is assumed that the right function is found.
 
 If a function uses req_match(), it should try as hard as possible to
 determine if the request is meant for it.
 
 If no functions in a configuration provide req_match or none of them
 returns true, then fall back to the usual approach.
 
 Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com

this regresses testusb at least on am335x:

test 14: control writes
[   32.968145] usbtest 2-1:3.0: TEST 14:  15000 ep0out, 1..256 vary 1
[   32.974659] Unable to handle kernel paging request at virtual address 
00400402
[   32.982199] pgd = dd3fc000
[   32.985021] [00400402] *pgd=
[   32.988765] Internal error: Oops: 8005 [#1] SMP ARM
[   32.994217] Modules linked in: usbtest usb_f_ss_lb g_zero libcomposite 
configfs musb_dsps musb_hdrc udc_core usbcore usb_common omap_rng rng_core 
musb_am335x rtc_omap omap_wdt leds_gpio led_class ipv6 autofs4
[   33.013652] CPU: 0 PID: 219 Comm: testusb Tainted: GW   
4.0.0-rc1-00069-g00b54e1bab53 #350
[   33.023364] Hardware name: Generic AM33XX (Flattened Device Tree)
[   33.029722] task: dd27c680 ti: dd2c2000 task.ti: dd2c2000
[   33.035358] PC is at 0x400402
[   33.038499] LR is at composite_setup+0x29c/0x16f0 [libcomposite]
[   33.044767] pc : [00400402]lr : [bf166f34]psr: 200301b3
[   33.044767] sp : dd2c3ad8  ip : bf179668  fp : 0040
[   33.056747] r10:   r9 : dd2c3b48  r8 : 
[   33.062197] r7 :   r6 : bf179690  r5 : bf17963c  r4 : dd26f280
[   33.069008] r3 : 00400403  r2 : bf179690  r1 : dd2c3b48  r0 : bf17963c
[   33.075821] Flags: nzCv  IRQs off  FIQs on  Mode SVC_32  ISA Thumb  Segment 
user
[   33.083538] Control: 10c5387d  Table: 9d3fc019  DAC: 0015
[   33.089533] Process testusb (pid: 219, stack limit = 0xdd2c2218)
[   33.095800] Stack: (0xdd2c3ad8 to 0xdd2c4000)
[   33.100346] 3ac0:   
 1f205000
[   33.108883] 3ae0: c083c880 dfa41880  0100 dd2c3d6c  
 0003
[   33.117419] 3b00: 0001 0001 c0064714 c08c3afb dd2c3b4e e1a26410 
dd237010 bf12b014
[   33.125956] 3b20: e1a26400 bf12b010 dd236304 dd236010 0001 bf125244 
e1a26410 
[   33.134492] 3b40:   5b40 0100 39363831 dd2362f0 
dd236010 bf12b008
[   33.143029] 3b60: dd237010  dd2362ec 0099  bf120908 
dd26eb80 de524010
[   33.151565] 3b80: 0001 bf122dc8 0001 dd26eb80 0841 c08c3afb 
c070b44e dd236010
[   33.160102] 3ba0:  bf14f148 dd287650 dd2362f0 60030193 e1a28000 
c08bd83c bf14e6bc
[   33.168639] 3bc0: bf14e5dc dd3e8600 dd284b20 00af   
 c08bd828
[   33.177175] 3be0: c08bd83c c0084c1c de111610 0004  dd284ac0 
0010 dd284ac0
[   33.185712] 3c00: dd284b20 c0841594  0001 de013000 01f4 
 c0084df8
[   33.194248] 3c20: dd284ac0 00af c0841594 c0087a30 00af c0084304 
c083ad30 c00845ac
[   33.202785] 3c40: dd2c3c78 c088db80 dd2c3c78 c08fffc0 0012 c0840100 
 c0008690
[   33.211322] 3c60: c0574a80 c0308db8 40030013  dd2c3cac c0575cc0 
dd2c3cf8 ffd0
[   33.219858] 3c80:   99a4 c0572e28 dd2c3cc4 0002 
c0840100 
[   33.228395] 3ca0: 01f4   dd2c3cc0 c0574a80 c0308db8 
40030013 
[   33.236931] 3cc0:   c073fa98 dd2c3dc4 c08d4c40 000e 
dd2c3d08 
[   33.245468] 3ce0:       
dd2c3d54 dd2c2000
[   33.254004] 3d00: dd2c3d58 0002  c0572e28 73753d4d 0001 
dd27c680 c0064714
[   33.262541] 3d20: dd2c3d5c dd2c3d5c dd270030 dd26eb80 dd2c3d54  
dd2c3d8c 1388
[   33.271077] 3d40:  005b 0040 bf0a218c   
00010001 dd2c3d20
[   33.279614] 3d60: dd2c3d20 de497000 dd37c9c0 0100   
de497000 bf0a22a0
[   33.288150] 3d80:  8200 dd3811b0 dd2c3df0 0006 dd26e680 
0100 de453800
[   33.296687] 3da0:  0100 de497068 de497000  bf189434 
 
[   33.305223] 3dc0: de453800 0100 1388 dd2c3df0 0100 3a98 
0001 dd26e680
[   33.313760] 3de0: dd26e680  dd26e680 de497000 dd31d200 dd37c940 
dd37c940 bf18e4b0
[   33.322296] 3e00: de497068 bf18bde0  0001 de445ad0 ddb7bd48 

[PATCH 20/29] usb: gadget: composite: add req_match method to usb_function

2015-02-23 Thread Andrzej Pietrasiewicz
Non-standard requests can encode the actual interface number in a
non-standard way. For example composite_setup() assumes
that it is w_index  0xFF, but the printer function encodes the interface
number in a context-dependet way (either w_index or w_index  8).
This can lead to such requests being directed to wrong functions.

This patch adds req_match() method to usb_function. Its purpose is to
verify that a given request can be handled by a given function.
If any function within a configuration provides the method and it returns
true, then it is assumed that the right function is found.

If a function uses req_match(), it should try as hard as possible to
determine if the request is meant for it.

If no functions in a configuration provide req_match or none of them
returns true, then fall back to the usual approach.

Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com
---
 drivers/usb/gadget/composite.c | 7 ++-
 include/linux/usb/composite.h  | 3 +++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 9fb9231..07cee80 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1758,6 +1758,11 @@ unknown:
 * take such requests too, if that's ever needed:  to work
 * in config 0, etc.
 */
+   list_for_each_entry(f, cdev-config-functions, list)
+   if (f-req_match  f-req_match(f, ctrl))
+   break;
+   if (f-list != cdev-config-functions)
+   goto try_fun_setup;
switch (ctrl-bRequestType  USB_RECIP_MASK) {
case USB_RECIP_INTERFACE:
if (!cdev-config || intf = MAX_CONFIG_INTERFACES)
@@ -1775,7 +1780,7 @@ unknown:
f = NULL;
break;
}
-
+try_fun_setup:
if (f  f-setup)
value = f-setup(f, ctrl);
else {
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index 3d87def..51f477a 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -147,6 +147,7 @@ struct usb_os_desc_table {
  * then only altsetting zero is supported.
  * @disable: (REQUIRED) Indicates the function should be disabled.  Reasons
  * include host resetting or reconfiguring the gadget, and disconnection.
+ * @req_match: Tests if a given class request can be handled by this function.
  * @setup: Used for interface-specific control requests.
  * @suspend: Notifies functions when the host stops sending USB traffic.
  * @resume: Notifies functions when the host restarts USB traffic.
@@ -211,6 +212,8 @@ struct usb_function {
int (*get_alt)(struct usb_function *,
unsigned interface);
void(*disable)(struct usb_function *);
+   bool(*req_match)(struct usb_function *,
+   const struct usb_ctrlrequest *);
int (*setup)(struct usb_function *,
const struct usb_ctrlrequest *);
void(*suspend)(struct usb_function *);
-- 
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