Re: autodetect USB MTP device characteristics without libusb_open()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Linus Walleij <linus.walleij@xxxxxxxxxx> writes:
> On Wed, Nov 7, 2012 at 12:28 AM, Bjørn Mork <bjorn@xxxxxxx> wrote:
>> Linus Walleij <linus.walleij@xxxxxxxxxx> writes:
>
>>> So all MTP devices manufactured before that spec, and numerous produced
>>> after that spec came out, and several still being produced don't use the
>>> class code, i.e. they violate the spec. But we still have to detect them
>>> somehow.
>>
>> Yes, I feared so.  But it still seemed likely that the non conforming
>> ones could be managed as a whitelist, if only most of the new ones were
>> using the standard class codes.
>
> I don't know if most of them do actually. Here is another device I
> bought just the other day, Philips GoGear Vibe:
>
> Bus 002 Device 008: ID 0471:20e5 Philips (or NXP)
> Device Descriptor:
>   bLength                18
>   bDescriptorType         1
>   bcdUSB               2.00
>   bDeviceClass            0 (Defined at Interface level)
>   bDeviceSubClass         0
>   bDeviceProtocol         0
>   bMaxPacketSize0        64
>   idVendor           0x0471 Philips (or NXP)
>   idProduct          0x20e5
>   bcdDevice            0.01
>   iManufacturer           1 Philips
>   iProduct                2 GoGear ViBE
>   iSerial                 5 400400009D0CDC190002DCE4AF289C19
>   bNumConfigurations      2
>   Configuration Descriptor:
>     bLength                 9
>     bDescriptorType         2
>     wTotalLength           39
>     bNumInterfaces          1
>     bConfigurationValue     1
>     iConfiguration          3 USB/MSC LCD Player
>     bmAttributes         0x80
>       (Bus Powered)
>     MaxPower              500mA
>     Interface Descriptor:
>       bLength                 9
>       bDescriptorType         4
>       bInterfaceNumber        0
>       bAlternateSetting       0
>       bNumEndpoints           3
>       bInterfaceClass         8 Mass Storage
>       bInterfaceSubClass      6 SCSI
>       bInterfaceProtocol     80 Bulk (Zip)
>       iInterface              4 USB/MSC LCD Player
>       Endpoint Descriptor:
>         bLength                 7
>         bDescriptorType         5
>         bEndpointAddress     0x81  EP 1 IN
>         bmAttributes            2
>           Transfer Type            Bulk
>           Synch Type               None
>           Usage Type               Data
>         wMaxPacketSize     0x0200  1x 512 bytes
>         bInterval               0
>       Endpoint Descriptor:
>         bLength                 7
>         bDescriptorType         5
>         bEndpointAddress     0x02  EP 2 OUT
>         bmAttributes            2
>           Transfer Type            Bulk
>           Synch Type               None
>           Usage Type               Data
>         wMaxPacketSize     0x0200  1x 512 bytes
>         bInterval               0
>       Endpoint Descriptor:
>         bLength                 7
>         bDescriptorType         5
>         bEndpointAddress     0x83  EP 3 IN
>         bmAttributes            3
>           Transfer Type            Interrupt
>           Synch Type               None
>           Usage Type               Data
>         wMaxPacketSize     0x0040  1x 64 bytes
>         bInterval              16
>   Configuration Descriptor:
>     bLength                 9
>     bDescriptorType         2
>     wTotalLength           39
>     bNumInterfaces          1
>     bConfigurationValue     2
>     iConfiguration          3 USB/MSC LCD Player
>     bmAttributes         0x80
>       (Bus Powered)
>     MaxPower              100mA
>     Interface Descriptor:
>       bLength                 9
>       bDescriptorType         4
>       bInterfaceNumber        0
>       bAlternateSetting       0
>       bNumEndpoints           3
>       bInterfaceClass         8 Mass Storage
>       bInterfaceSubClass      6 SCSI
>       bInterfaceProtocol     80 Bulk (Zip)
>       iInterface              4 USB/MSC LCD Player
>       Endpoint Descriptor:
>         bLength                 7
>         bDescriptorType         5
>         bEndpointAddress     0x81  EP 1 IN
>         bmAttributes            2
>           Transfer Type            Bulk
>           Synch Type               None
>           Usage Type               Data
>         wMaxPacketSize     0x0200  1x 512 bytes
>         bInterval               0
>       Endpoint Descriptor:
>         bLength                 7
>         bDescriptorType         5
>         bEndpointAddress     0x02  EP 2 OUT
>         bmAttributes            2
>           Transfer Type            Bulk
>           Synch Type               None
>           Usage Type               Data
>         wMaxPacketSize     0x0200  1x 512 bytes
>         bInterval               0
>       Endpoint Descriptor:
>         bLength                 7
>         bDescriptorType         5
>         bEndpointAddress     0x83  EP 3 IN
>         bmAttributes            3
>           Transfer Type            Interrupt
>           Synch Type               None
>           Usage Type               Data
>         wMaxPacketSize     0x0040  1x 64 bytes
>         bInterval              16
> Device Qualifier (for other device speed):
>   bLength                10
>   bDescriptorType         6
>   bcdUSB               2.00
>   bDeviceClass            0 (Defined at Interface level)
>   bDeviceSubClass         0
>   bDeviceProtocol         0
>   bMaxPacketSize0        64
>   bNumConfigurations      2
> Device Status:     0x0000
>   (Bus Powered)
>
> So two configurations, each with a USB mass storage
> interface right?
>
> Wrong!
>
> One of them is an MTP interface, and will respond to MTP traffic.
> I think the magic OS handshake make that come into play...
> So Linux erroneously tries to use MSC on it, and we have to
> use libusb_detach_kernel_driver() and then use the interface.
>
> And then it works.
>
> This type of misbehaviour is not uncommon, I just took some
> device at random, there are literally millions of these.

That may be.  But I absolutely refuse thinking about the possibility of
some udev rule probing all mass storage devices just because of
completely broken devices like this one...

OK, filtering on 3 endpoint mass storage devices will eliminate most of
the false positives, but still.  Ugly.


> (...)
> # Autoprobe vendor-specific, communication and PTP devices
> ENV{ID_MTP_DEVICE}!="1", ENV{MTP_NO_PROBE}!="1",
> ENV{COLOR_MEASUREMENT_DEVICE}!="1", ENV{libsane_matched}!="yes",
> ATTR{bDeviceClass}=="00|02|06|ef|ff", PROGRAM="mtp-probe
> /sys$env{DEVPATH} $attr{busnum} $attr{devnum}", RESULT=="1",
> SYMLINK+="libmtp-%k", ENV{ID_MTP_DEVICE}="1", ENV{ID_MEDIA_PLAYER}="1"

I believe this rule is dangerously broad. It probes so many non MTP
devices that I honestly do not understand why you need to except any
device at all.  Your config avoids probing a few whitelisted MTP devices
but ends up probing evey other type of USB device instead.  That does
not make sense.

> So that rather horrible rule avoids probing:
>
> - Devices we just detected in the whitelist
> - Color measurement or scanner devices (these have been
>   prone to errors...)
> - Then check only the classes we mentioned

Yes, but "only the classes we mentioned" includes *all* composite
devices out there. To me that seems completely unacceptable, but others
may disagree.

> So I guess you're suggesting another step, checking the interfaces?

IMHO, you should limit the probing to the devices which you have reason
to believe may support MTP.  That is
 - devices with one or more PTP interfaces
 - possibly devices with 3 endpoint Mass Storage interfaces, like the
   one you showed above

The rest will have to be witelisted based on pid:vid.

But this is my opinion, only..

>> Do you know if these early devices support the typical Microsoft
>> descriptors? I.e. the 0xee string descriptor with "MSFT100<code>"
>> and its friends?
>
> Almost all devices support this. (There are exceptions even to this.)
> So this is what we do as a last resort, if we can't figure it out
> some other way.

I do not understand why that has to be the last resort.  I would expect
this method to be very reliable since Microsoft has been heavily
involved all the way here.  It's an ugly non-standard method of course,
but being pragmatic we do have to use whatever method the vendors have
implemented and *tested*.  Which most likely is what they have observed
som random Windows version doing.

> The problem appear when you ask a device which is not MTP
> for that descriptor, some of them just die, so I cannot do
> that.

Really?  You ask for a string descriptor and the device dies?  Won't
those devices also die if they are connected to a Windows system?



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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux