Re: allow ugen(4) to attach to unused interfaces
On 01/04/11 00:13, 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. Here is one very strong consideration: Inasmuch as this change makes at least some MFC devices just work with CUPS and xsane, for normal users, without having to e.g., build a custom kernel, I am in favor of it, unless there is a *specific* risk to other drivers.
Re: allow ugen(4) to attach to unused interfaces
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://
Re: allow ugen(4) to attach to unused interfaces
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 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 - 1.47 > +++ if_cdce.c 3 Jan 2011 21:52:27 - > @@ -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); > } > } > }
allow ugen(4) to attach to unused interfaces
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 - 1.47 +++ if_cdce.c 3 Jan 2011 21:52:27 - @@ -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 - 1.27 +++ if_urndis.c 3 Jan 2011 21:52:27 - @@ -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))