On Tue, Jan 04, 2011 at 02:13:05PM +0900, Yojiro UO wrote:
> as the ugen(4) is too flexible (and unsafe) than other usb device drivers, 
> i don't like this work to extend ugen(4)'s area. 
> 
> I know many userland applications which supports multiple platform using
> ugen type interface (because they usually use libusb or ugen apis), but 
> it is no reason to support them without considerations.
> 
> .....
> 
> >From usb developer's view (include me), this work is seems to the so 
> useful to use "unsupported" / "partially supported" device. hmm...
> 
> -- Yojiro UO

well, when ugen(4) is attached as a secondary device, it is not
allowed to change the configuration, and is only allowed access to
the unclaimed interfaces.  this is essentially the same as other
class/interface drivers.  normal ugen(4) attachments and drivers
that attach by matching vendor/pid are given full access to the
device.

there is no defined class for scanners.  so, I don't see how usb
scanners will be supported without a generic usb device driver,
except maybe something like uscanner ...

this saves me from having to disable ulpt, so that I can use my
mfp as a ugen, which then forces me to use CUPS for printing.
now I don't have to fiddle in ukc or use CUPS.

I don't disagree that the wrong device attaching as ugen could have
unforseen negative consequences.  you wouldn't want to allow
unrestricted use of a ugen attached to a umass interface that is
controlling a filesystem, for example.  but we attach umass there,
so that shouldn't happen.



> 
> 
> On 2011/01/04, at 8:18, Jacob Meuser wrote:
> 
> > when a USB device is inserted, usbd_probe_and_attach() first tries to
> > find a driver that claims to support the device by matching the
> > vendor/product IDs.  if no such driver is found, usbd_probe_and_attach()
> > loops through each interface of each of the devices configurations,
> > trying to match "interface" (aka class) drivers to an interface.  if
> > the device has more than one interface *in a single configuration*
> > that matches drivers, then drivers are allowed to attach to each
> > interface.  for example:
> > 
> > uvideo0 at uhub5 port 1 configuration 1 interface 0 "Logitech product 
> > 0x09a2" rev 2.00/0.08 addr 4
> > video0 at uvideo0
> > uaudio0 at uhub5 port 1 configuration 1 interface 2 "Logitech product 
> > 0x09a2" rev 2.00/0.08 addr 4
> > uaudio0: audio rev 1.00, 2 mixer controls
> > audio1 at uaudio0
> > 
> > note how they are both attached "at uhub5 port 1 configuration 1".
> > 
> > and:
> > 
> > uhidev0 at uhub1 port 2 configuration 1 interface 0 "Logitech USB Receiver" 
> > rev 2.00/16.00 addr 2
> > uhidev0: iclass 3/1
> > ums0 at uhidev0: 16 buttons, Z dir
> > wsmouse1 at ums0 mux 0
> > uhidev1 at uhub1 port 2 configuration 1 interface 1 "Logitech USB Receiver" 
> > rev 2.00/16.00 addr 2
> > uhidev1: iclass 3/0, 17 report ids
> > uhid0 at uhidev1 reportid 3: input=4, output=0, feature=0
> > uhid1 at uhidev1 reportid 16: input=6, output=6, feature=0
> > uhid2 at uhidev1 reportid 17: input=19, output=19, feature=0
> > 
> > note how both uhidev(4)s are attached "at uhub1 port 2 configuration 1".
> > 
> > currently, usbd_probe_and_attach() makes a copy of the array of pointers
> > to the interface descriptors and passes these to the match/attach functions
> > in struct usb_attach_args (uaa).  when an interface is matched, the pointer
> > to the interface descriptor in uaa is set to NULL.  and, if a driver uses
> > other interfaces, the driver sets the pointer to those interface
> > descriptors in the uaa to NULL.  this way, what interfaces are available
> > is known, but this only really works at attach time.
> > 
> > currently, ugen(4) assumes it can use any interface in any configuration.
> > for this reason, ugen(4) is only attached if no interfaces have drivers
> > attached.
> > 
> > the following allows ugen(4) to be safely attached when there are unused
> > interfaces.  this is accomplished by:
> > 
> > * instead of NULLing pointers to interface descriptors in the uaa, mark
> >  interfaces as being claimed in the usbd_device's copy of the interface
> >  descriptors
> > * allow ugen(4) to be attached if there are unused interfaces in a
> >  configuration that has had drivers attached
> > * make ugen(4) aware that it may be sharing a device with (an)other
> >  driver(s), and if so:
> >  * do not let ugen(4) change the configuration
> >  * do not let ugen(4) access the already claimed interfaces
> > 
> > this allows, for example:
> > 
> > ulpt0 at uhub0 port 1 configuration 1 interface 1 "HP Officejet 4500 
> > G510g-m" rev 2.00/1.00 addr 2
> > ulpt0: using bi-directional mode
> > ugen0 at uhub0 port 1 configuration 1 "HP Officejet 4500 G510g-m" rev 
> > 2.00/1.00 addr 2
> > 
> > which means this MFP can be used by both lpd and sane, simultaneously.
> > this also requires a patch to libusb, to let it know that ugen(4) might
> > not be the first driver attached to the device.  that patch is at
> > http://jakemsr.trancell.org/libusb.diff
> > 
> > thoughts?  oks?
> > 
> > -- 
> > jake...@sdf.lonestar.org
> > SDF Public Access UNIX System - http://sdf.lonestar.org
> > 
> > Index: if_cdce.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/usb/if_cdce.c,v
> > retrieving revision 1.47
> > diff -u -p if_cdce.c
> > --- if_cdce.c       27 Oct 2010 17:51:11 -0000      1.47
> > +++ if_cdce.c       3 Jan 2011 21:52:27 -0000
> > @@ -224,12 +224,12 @@ cdce_attach(struct device *parent, struct device *self
> >             DPRINTF(("cdce_attach: union interface: ctl=%d, data=%d\n",
> >                 ctl_ifcno, data_ifcno));
> >             for (i = 0; i < uaa->nifaces; i++) {
> > -                   if (uaa->ifaces[i] == NULL)
> > +                   if (usbd_iface_claimed(sc->cdce_udev, i))
> >                             continue;
> >                     id = usbd_get_interface_descriptor(uaa->ifaces[i]);
> >                     if (id != NULL && id->bInterfaceNumber == data_ifcno) {
> >                             sc->cdce_data_iface = uaa->ifaces[i];
> > -                           uaa->ifaces[i] = NULL;
> > +                           usbd_claim_iface(sc->cdce_udev, i);
> >                     }
> >             }
> >     }
> > Index: if_urndis.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/usb/if_urndis.c,v
> > retrieving revision 1.27
> > diff -u -p if_urndis.c
> > --- if_urndis.c     27 Oct 2010 17:51:11 -0000      1.27
> > +++ if_urndis.c     3 Jan 2011 21:52:27 -0000
> > @@ -1389,12 +1389,12 @@ urndis_attach(struct device *parent, struct device 
> > *se
> >             DPRINTF(("urndis_attach: union interface: ctl %u, data %u\n",
> >                 if_ctl, if_data));
> >             for (i = 0; i < uaa->nifaces; i++) {
> > -                   if (uaa->ifaces[i] == NULL)
> > +                   if (usbd_iface_claimed(sc->sc_udev, i))
> >                             continue;
> >                     id = usbd_get_interface_descriptor(uaa->ifaces[i]);
> >                     if (id && id->bInterfaceNumber == if_data) {
> >                             sc->sc_iface_data = uaa->ifaces[i];
> > -                           uaa->ifaces[i] = NULL;
> > +                           usbd_claim_iface(sc->sc_udev, i);
> >                     }
> >             }
> >     }
> > Index: uaudio.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/usb/uaudio.c,v
> > retrieving revision 1.89
> > diff -u -p uaudio.c
> > --- uaudio.c        18 Aug 2010 22:54:58 -0000      1.89
> > +++ uaudio.c        3 Jan 2011 21:52:27 -0000
> > @@ -210,7 +210,6 @@ struct uaudio_softc {
> >     struct device    sc_dev;        /* base device */
> >     usbd_device_handle sc_udev;     /* USB device */
> >     int              sc_ac_iface;   /* Audio Control interface */
> > -   usbd_interface_handle   sc_ac_ifaceh;
> >     struct chan      sc_playchan;   /* play channel */
> >     struct chan      sc_recchan;    /* record channel */
> >     int              sc_nullalt;
> > @@ -520,10 +519,9 @@ uaudio_attach(struct device *parent, struct device *se
> >             return;
> >     }
> > 
> > -   sc->sc_ac_ifaceh = uaa->iface;
> >     /* Pick up the AS interface. */
> >     for (i = 0; i < uaa->nifaces; i++) {
> > -           if (uaa->ifaces[i] == NULL)
> > +           if (usbd_iface_claimed(sc->sc_udev, i))
> >                     continue;
> >             id = usbd_get_interface_descriptor(uaa->ifaces[i]);
> >             if (id == NULL)
> > @@ -537,7 +535,7 @@ uaudio_attach(struct device *parent, struct device *se
> >                     }
> >             }
> >             if (found)
> > -                   uaa->ifaces[i] = NULL;
> > +                   usbd_claim_iface(sc->sc_udev, i);
> >     }
> > 
> >     for (j = 0; j < sc->sc_nalts; j++) {
> > Index: ugen.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/usb/ugen.c,v
> > retrieving revision 1.62
> > diff -u -p ugen.c
> > --- ugen.c  24 Sep 2010 08:33:59 -0000      1.62
> > +++ ugen.c  3 Jan 2011 21:52:28 -0000
> > @@ -103,6 +103,7 @@ struct ugen_softc {
> > 
> >     int sc_refcnt;
> >     u_char sc_dying;
> > +   u_char sc_secondary;
> > };
> > 
> > void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr,
> > @@ -166,13 +167,18 @@ ugen_attach(struct device *parent, struct device *self
> > 
> >     sc->sc_udev = udev = uaa->device;
> > 
> > -   /* First set configuration index 0, the default one for ugen. */
> > -   err = usbd_set_config_index(udev, 0, 0);
> > -   if (err) {
> > -           printf("%s: setting configuration index 0 failed\n",
> > -                  sc->sc_dev.dv_xname);
> > -           sc->sc_dying = 1;
> > -           return;
> > +   if (usbd_get_devcnt(udev) > 0)
> > +           sc->sc_secondary = 1;
> > +
> > +   if (!sc->sc_secondary) {
> > +           /* First set configuration index 0, the default one for ugen. */
> > +           err = usbd_set_config_index(udev, 0, 0);
> > +           if (err) {
> > +                   printf("%s: setting configuration index 0 failed\n",
> > +                          sc->sc_dev.dv_xname);
> > +                   sc->sc_dying = 1;
> > +                   return;
> > +           }
> >     }
> >     conf = usbd_get_config_descriptor(udev)->bConfigurationValue;
> > 
> > @@ -220,9 +226,15 @@ ugen_set_config(struct ugen_softc *sc, int configno)
> >     /* Avoid setting the current value. */
> >     cdesc = usbd_get_config_descriptor(dev);
> >     if (!cdesc || cdesc->bConfigurationValue != configno) {
> > -           err = usbd_set_config_no(dev, configno, 1);
> > -           if (err)
> > -                   return (err);
> > +           if (sc->sc_secondary) {
> > +                   printf("%s: secondary, not changing config to %d\n",
> > +                       __func__, configno);
> > +                   return (USBD_IN_USE);
> > +           } else {
> > +                   err = usbd_set_config_no(dev, configno, 1);
> > +                   if (err)
> > +                           return (err);
> > +           }
> >     }
> > 
> >     err = usbd_interface_count(dev, &niface);
> > @@ -231,6 +243,10 @@ ugen_set_config(struct ugen_softc *sc, int configno)
> >     memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
> >     for (ifaceno = 0; ifaceno < niface; ifaceno++) {
> >             DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
> > +           if (usbd_iface_claimed(dev, ifaceno)) {
> > +                   DPRINTF(("%s: iface %d claimed\n", __func__, ifaceno));
> > +                   continue;
> > +           }
> >             err = usbd_device2interface_handle(dev, ifaceno, &iface);
> >             if (err)
> >                     return (err);
> > Index: umodem.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/usb/umodem.c,v
> > retrieving revision 1.39
> > diff -u -p umodem.c
> > --- umodem.c        2 Dec 2010 01:37:45 -0000       1.39
> > +++ umodem.c        3 Jan 2011 21:52:28 -0000
> > @@ -280,12 +280,12 @@ umodem_attach(struct device *parent, struct device *se
> > 
> >     /* Get the data interface too. */
> >     for (i = 0; i < uaa->nifaces; i++) {
> > -           if (uaa->ifaces[i] != NULL) {
> > +           if (!usbd_iface_claimed(sc->sc_udev, i)) {
> >                     id = usbd_get_interface_descriptor(uaa->ifaces[i]);
> >                     if (id != NULL &&
> >                             id->bInterfaceNumber == data_iface_no) {
> >                             sc->sc_data_iface = uaa->ifaces[i];
> > -                           uaa->ifaces[i] = NULL;
> > +                           usbd_claim_iface(sc->sc_udev, i);
> >                     }
> >             }
> >     }
> > ? usb-n.diff
> > Index: usb_subr.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/usb/usb_subr.c,v
> > retrieving revision 1.77
> > diff -u -p usb_subr.c
> > --- usb_subr.c      17 Dec 2010 22:38:54 -0000      1.77
> > +++ usb_subr.c      3 Jan 2011 21:52:28 -0000
> > @@ -777,7 +777,7 @@ usbd_set_config_index(usbd_device_handle dev, int inde
> >     /* Allocate and fill interface data. */
> >     nifc = cdp->bNumInterface;
> >     dev->ifaces = malloc(nifc * sizeof(struct usbd_interface),
> > -       M_USB, M_NOWAIT);
> > +       M_USB, M_NOWAIT | M_ZERO);
> >     if (dev->ifaces == NULL) {
> >             err = USBD_NOMEM;
> >             goto bad;
> > @@ -859,14 +859,13 @@ usbd_getnewaddr(usbd_bus_handle bus)
> >     return (-1);
> > }
> > 
> > -
> > usbd_status
> > usbd_probe_and_attach(struct device *parent, usbd_device_handle dev, int 
> > port,
> >     int addr)
> > {
> >     struct usb_attach_arg uaa;
> >     usb_device_descriptor_t *dd = &dev->ddesc;
> > -   int found, i, confi, nifaces, len;
> > +   int i, confi, nifaces, len;
> >     usbd_status err;
> >     struct device *dv;
> >     usbd_interface_handle *ifaces;
> > @@ -895,8 +894,8 @@ usbd_probe_and_attach(struct device *parent, usbd_devi
> >                     err = USBD_NOMEM;
> >                     goto fail;
> >             }
> > -           dev->subdevs[0] = dv;
> > -           dev->subdevs[1] = 0;
> > +           dev->subdevs[dev->ndevs++] = dv;
> > +           dev->subdevs[dev->ndevs] = 0;
> >             err = USBD_NORMAL_COMPLETION;
> >             goto fail;
> >     }
> > @@ -934,7 +933,9 @@ usbd_probe_and_attach(struct device *parent, usbd_devi
> >                     ifaces[i] = &dev->ifaces[i];
> >             uaa.ifaces = ifaces;
> >             uaa.nifaces = nifaces;
> > -           len = (nifaces+1) * sizeof dv;
> > +
> > +           /* add 1 for possible ugen and 1 for NULL terminator */
> > +           len = (nifaces + 2) * sizeof dv;
> >             dev->subdevs = malloc(len, M_USB, M_NOWAIT | M_ZERO);
> >             if (dev->subdevs == NULL) {
> >                     free(ifaces, M_USB);
> > @@ -942,25 +943,31 @@ usbd_probe_and_attach(struct device *parent, usbd_devi
> >                     goto fail;
> >             }
> > 
> > -           found = 0;
> >             for (i = 0; i < nifaces; i++) {
> > -                   if (ifaces[i] == NULL)
> > -                           continue; /* interface already claimed */
> > +                   if (usbd_iface_claimed(dev, i))
> > +                           continue;
> >                     uaa.iface = ifaces[i];
> >                     uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber;
> >                     dv = config_found_sm(parent, &uaa, usbd_print,
> >                                        usbd_submatch);
> > -
> >                     if (dv != NULL) {
> > -                           dev->subdevs[found++] = dv;
> > -                           ifaces[i] = NULL; /* consumed */
> > +                           dev->subdevs[dev->ndevs++] = dv;
> > +                           usbd_claim_iface(dev, i);
> >                     }
> >             }
> >             free(ifaces, M_USB);
> > -           if (found != 0) {
> > -                   err = USBD_NORMAL_COMPLETION;
> > -                   goto fail;
> > +
> > +           if (dev->ndevs > 0) {
> > +                   for (i = 0; i < nifaces; i++) {
> > +                           if (!usbd_iface_claimed(dev, i))
> > +                                   break;
> > +                   }
> > +                   if (i < nifaces)
> > +                           goto generic;
> > +                    else
> > +                           goto fail;
> >             }
> > +
> >             free(dev->subdevs, M_USB);
> >             dev->subdevs = 0;
> >     }
> > @@ -971,20 +978,24 @@ usbd_probe_and_attach(struct device *parent, usbd_devi
> > 
> >     DPRINTF(("usbd_probe_and_attach: no interface drivers found\n"));
> > 
> > +generic:
> >     /* Finally try the generic driver. */
> >     uaa.iface = NULL;
> >     uaa.usegeneric = 1;
> > -   uaa.configno = UHUB_UNK_CONFIGURATION;
> > +   uaa.configno = dev->ndevs == 0 ? UHUB_UNK_CONFIGURATION :
> > +       dev->cdesc->bConfigurationValue;
> >     uaa.ifaceno = UHUB_UNK_INTERFACE;
> >     dv = config_found_sm(parent, &uaa, usbd_print, usbd_submatch);
> >     if (dv != NULL) {
> > -           dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
> > -           if (dev->subdevs == 0) {
> > -                   err = USBD_NOMEM;
> > -                   goto fail;
> > +           if (dev->ndevs == 0) {
> > +                   dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
> > +                   if (dev->subdevs == NULL) {
> > +                           err = USBD_NOMEM;
> > +                           goto fail;
> > +                   }
> >             }
> > -           dev->subdevs[0] = dv;
> > -           dev->subdevs[1] = 0;
> > +           dev->subdevs[dev->ndevs++] = dv;
> > +           dev->subdevs[dev->ndevs] = 0;
> >             err = USBD_NORMAL_COMPLETION;
> >             goto fail;
> >     }
> > Index: usbdi.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/usb/usbdi.c,v
> > retrieving revision 1.42
> > diff -u -p usbdi.c
> > --- usbdi.c 30 Dec 2010 05:10:35 -0000      1.42
> > +++ usbdi.c 3 Jan 2011 21:52:28 -0000
> > @@ -117,6 +117,24 @@ usbd_ref_wait(usbd_device_handle dev)
> >             tsleep(&dev->ref_cnt, PWAIT, "usbref", hz * 60);
> > }
> > 
> > +int
> > +usbd_get_devcnt(usbd_device_handle dev)
> > +{
> > +   return (dev->ndevs);
> > +}
> > +
> > +void
> > +usbd_claim_iface(usbd_device_handle dev, int ifaceidx)
> > +{
> > +   dev->ifaces[ifaceidx].claimed = 1;
> > +}
> > +
> > +int
> > +usbd_iface_claimed(usbd_device_handle dev, int ifaceidx)
> > +{
> > +   return (dev->ifaces[ifaceidx].claimed);
> > +}
> > +
> > static __inline int
> > usbd_xfer_isread(usbd_xfer_handle xfer)
> > {
> > Index: usbdi.h
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/usb/usbdi.h,v
> > retrieving revision 1.37
> > diff -u -p usbdi.h
> > --- usbdi.h 30 Dec 2010 05:10:35 -0000      1.37
> > +++ usbdi.h 3 Jan 2011 21:52:28 -0000
> > @@ -165,6 +165,10 @@ usbd_status usbd_reload_device_desc(usbd_device_handle
> > 
> > int usbd_ratecheck(struct timeval *last);
> > 
> > +int usbd_get_devcnt(usbd_device_handle);
> > +void usbd_claim_iface(usbd_device_handle, int);
> > +int usbd_iface_claimed(usbd_device_handle, int);
> > +
> > int usbd_is_dying(usbd_device_handle);
> > void usbd_deactivate(usbd_device_handle);
> > 
> > Index: usbdivar.h
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/usb/usbdivar.h,v
> > retrieving revision 1.41
> > diff -u -p usbdivar.h
> > --- usbdivar.h      30 Dec 2010 05:10:35 -0000      1.41
> > +++ usbdivar.h      3 Jan 2011 21:52:28 -0000
> > @@ -147,6 +147,7 @@ struct usbd_device {
> >     const struct usbd_quirks     *quirks;  /* device quirks, always set */
> >     struct usbd_hub        *hub;           /* only if this is a hub */
> >     struct device         **subdevs;       /* sub-devices, 0 terminated */
> > +   int                     ndevs;         /* # of subdevs */
> > };
> > 
> > struct usbd_interface {
> > @@ -157,6 +158,7 @@ struct usbd_interface {
> >     struct usbd_endpoint   *endpoints;
> >     void                   *priv;
> >     LIST_HEAD(, usbd_pipe)  pipes;
> > +   u_int8_t                claimed;
> > };
> > 
> > struct usbd_pipe {
> > Index: uvideo.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/usb/uvideo.c,v
> > retrieving revision 1.147
> > diff -u -p uvideo.c
> > --- uvideo.c        24 Nov 2010 19:53:07 -0000      1.147
> > +++ uvideo.c        3 Jan 2011 21:52:28 -0000
> > @@ -468,13 +468,24 @@ uvideo_attach(struct device *parent, struct device *se
> > {
> >     struct uvideo_softc *sc = (struct uvideo_softc *)self;
> >     struct usb_attach_arg *uaa = aux;
> > +   usb_interface_descriptor_t *id;
> > +   int i;
> > 
> >     sc->sc_udev = uaa->device;
> >     sc->sc_nifaces = uaa->nifaces;
> > -   sc->sc_ifaces = malloc(uaa->nifaces * sizeof(usbd_interface_handle),
> > -       M_USB, M_WAITOK);
> > -   bcopy(uaa->ifaces, sc->sc_ifaces,
> > -       uaa->nifaces * sizeof(usbd_interface_handle));
> > +   /*
> > +    * Claim all video interfaces.  Interfaces must be claimed during
> > +    * attach, during attach hooks is too late.
> > +    */
> > +   for (i = 0; i < sc->sc_nifaces; i++) {
> > +           if (usbd_iface_claimed(sc->sc_udev, i))
> > +                   continue;
> > +           id = usbd_get_interface_descriptor(&sc->sc_udev->ifaces[i]);
> > +           if (id == NULL)
> > +                   continue;
> > +           if (id->bInterfaceClass == UICLASS_VIDEO)
> > +                   usbd_claim_iface(sc->sc_udev, i);
> > +   }
> > 
> >     /* maybe the device has quirks */
> >     sc->sc_quirk = uvideo_lookup(uaa->vendor, uaa->product);
> > @@ -557,8 +568,6 @@ uvideo_detach(struct device *self, int flags)
> >     struct uvideo_softc *sc = (struct uvideo_softc *)self;
> >     int rv = 0;
> > 
> > -   free(sc->sc_ifaces, M_USB);
> > -
> >     /* Wait for outstanding requests to complete */
> >     usbd_delay_ms(sc->sc_udev, UVIDEO_NFRAMES_MAX);
> > 
> > @@ -837,12 +846,13 @@ uvideo_vs_parse_desc(struct uvideo_softc *sc, usb_conf
> >     for (i = 0; i < sc->sc_desc_vc_header.fix->bInCollection; i++) {
> >             iface = sc->sc_desc_vc_header.baInterfaceNr[i];
> > 
> > -           id = usbd_get_interface_descriptor(sc->sc_ifaces[iface]);
> > +           id = usbd_get_interface_descriptor(&sc->sc_udev->ifaces[iface]);
> >             if (id == NULL) {
> >                     printf("%s: can't get VS interface %d!\n",
> >                         DEVNAME(sc), iface);
> >                     return (USBD_INVAL);
> >             }
> > +           usbd_claim_iface(sc->sc_udev, iface);
> > 
> >             numalts = usbd_get_no_alts(cdesc, id->bInterfaceNumber);
> > 
> > @@ -1197,7 +1207,7 @@ uvideo_vs_parse_desc_alt(struct uvideo_softc *sc, int 
> > 
> >             /* save endpoint with largest bandwidth */
> >             if (UGETW(ed->wMaxPacketSize) > vs->psize) {
> > -                   vs->ifaceh = sc->sc_ifaces[iface];
> > +                   vs->ifaceh = &sc->sc_udev->ifaces[iface];
> >                     vs->endpoint = ed->bEndpointAddress;
> >                     vs->numalts = numalts;
> >                     vs->curalt = id->bAlternateSetting;
> > 
> 

-- 
jake...@sdf.lonestar.org
SDF Public Access UNIX System - http://sdf.lonestar.org

Reply via email to