A question below..

On Wed, Feb 03, 2021 at 11:22:16AM +0000, Mikolaj Kucharski wrote:
> On Wed, Feb 03, 2021 at 11:10:45AM +0000, Edd Barrett wrote:
> > Hi,
> > 
> > CCing ratchov@ and kettenis@ with some context.
> > 
> > In short: my change broke ugen, which expects to scan up the interface
> > range until an interface doesn't exist.
> > 
> > On Wed, Feb 03, 2021 at 06:25:48AM +0100, Marcus Glocker wrote:
> > > 
> > > Index: dev/usb/usbdi.c
> > > ===================================================================
> > > RCS file: /cvs/src/sys/dev/usb/usbdi.c,v
> > > retrieving revision 1.109
> > > diff -u -p -u -p -r1.109 usbdi.c
> > > --- dev/usb/usbdi.c     1 Feb 2021 09:21:51 -0000       1.109
> > > +++ dev/usb/usbdi.c     2 Feb 2021 06:07:41 -0000
> > > @@ -642,6 +642,10 @@ usbd_device2interface_handle(struct usbd
> > > 
> > >         if (dev->cdesc == NULL)
> > >                 return (USBD_NOT_CONFIGURED);
> > > +       if (ifaceno < dev->cdesc->bNumInterfaces) {
> > > +               *iface = &dev->ifaces[ifaceno];
> > > +               return (USBD_NORMAL_COMPLETION);
> > > +       }
> > >         /*
> > >          * The correct interface should be at dev->ifaces[ifaceno], but 
> > > we've
> > >          * seen non-compliant devices in the wild which present 
> > > non-contiguous
> > >
> > > So OK if I commit this fix Edd, Stuart?
> > 
> > I'm OK with it as a quick-fix. At least it will make both of the devices
> > in question work.
> > 
> > But in the long run, it's not hard to imagine other non-compliant
> > devices which would still be defeated by this code.
> > 
> > Suppose a device presents its contiguous interfaces in reverse order, e.g.:
> > [2, 1, 0]. Now suppose a device driver asks for interface 2. We will
> > find interface 0, as we never check if it's the right interface and we
> > never reach the part of the code that scans the array.
> > 
> > In other words, just because an index exists, doesn't mean it's the right
> > interface.
> > 
> > I think (and I'm not much of a kernel hacker, so I reserve the right be 
> > wrong)
> > the correct solution is to:
> > 
> >  * always loop over the array looking for the right interface.
> >  * change ugen, so that it's scanning resilient to gaps in interface range.
> > 

I would probably ask, what is the meaning of ifaceno?

Is that variable an index in the array or is it bInterfaceNumber?

>From my understanding, with -r1.110 of usbdi.c it's both. From this
email thread, in various devices array index and bInterfaceNumber
don't always have the same value. They don't always match.

What users of usbd_device2interface_handle() function assume,
an array index or bInterfaceNumber for ifaceno argument?

> Not sure is your above proposition enough. Here is part of dmesg with
> some debugging statments for 2 devices which trigger 
> usbd_device2interface_handle()
> 
> See MMM markers.
> 
> ...
> ulpt0 at uhub0 port 3 configuration 1 interface 1 "Samsung Electronics Co., 
> Ltd. M2070 Series" rev 2.00/1.00 addr 2
> ulpt0: using bi-directional mode
> ugen0 at uhub0 port 3 configuration 1 "Samsung Electronics Co., Ltd. M2070 
> Series" rev 2.00/1.00 addr 2
> MMM: USBD_NORMAL_COMPLETION v1 ifaceno=0 bNumInterfaces=2 
> [usbd_device2interface_handle()|usbdi.c|649]
> uhub2 at uhub1 port 1 configuration 1 interface 0 "Advanced Micro Devices 
> Hub" rev 2.00/0.18 addr 2
> umb0 at uhub2 port 3 configuration 1 interface 12 "Sierra Wireless, 
> Incorporated Sierra Wireless MC7455 Qualcomm\M-. Snapdragon? X7 LTE-A" rev 
> 2.00/0.06 addr 3
> ugen1 at uhub2 port 3 configuration 1 "Sierra Wireless, Incorporated Sierra 
> Wireless MC7455 Qualcomm\M-. Snapdragon? X7 LTE-A" rev 2.00/0.06 addr 3
> MMM: USBD_NORMAL_COMPLETION v1 ifaceno=0 bNumInterfaces=5 
> [usbd_device2interface_handle()|usbdi.c|649]
> MMM: USBD_NORMAL_COMPLETION v1 ifaceno=1 bNumInterfaces=5 
> [usbd_device2interface_handle()|usbdi.c|649]
> MMM: USBD_NORMAL_COMPLETION v1 ifaceno=2 bNumInterfaces=5 
> [usbd_device2interface_handle()|usbdi.c|649]
> vscsi0 at root
> scsibus2 at vscsi0: 256 targets
> ...
> 
> For ugen1 (belongs to physical device, whih also attaches a umb(4)) we
> can see that ifaceno has value of 0, 1, 2, but from lsusb we see that:
> 
> (from earliers Marcus Glocker's email)
> 
> Index   Interface Number
> -----   ---------------
> 0       0
> 1       2
> 2       3
> 3       12
> 4       13
> 
> for ifaceno 1 and 2 it will not equal to bInterfaceNumber if we iterate
> the for (idx = 0; idx < dev->cdesc->bNumInterfaces; idx++) loop.
> 
> I don't have good picture for how all the functions work with each
> other, but it does feel like substantial work is needed here, to piece
> everything together.
> 

-- 
Regards,
 Mikolaj

Reply via email to