Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On Sun, Dec 06, 2015 at 05:23:22PM +, Stuart Henderson wrote: > The bigger problem is "dual use" devices; e.g. some want UPS to attach > to upd(4), others want ugen(4) for use with NUT/apcupsd. Your code is > partially useful for these, but because it just changes things at attach, > won't survive a reboot - if it could instead force a device to detach > and reattach to ugen it would help a lot more cases. I have a question about usb devices which are not as ugen. If I would like to use usb redirection (libusbredir + libusb + spice-gtk) with remote-viewer, part of virt-viewer package, ie. eg. redirecting usb flash disk from laptop to remote Qemu/KVM VM, would I need such usb flash disk be available as ugen? I think so, am I right? IMO mpi@'s point to always present usb devices as well as ugen make sense. j.
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On 2015/12/08 20:55, Xiaofan Chen wrote: > On Mon, Dec 7, 2015 at 10:43 PM, Stuart Henderson wrote: > > On 2015/12/07 22:11, Xiaofan Chen wrote: > >> Not so sure if there is a port of hidapi under OpenBSD. > >> Ref: http://www.signal11.us/oss/hidapi/ > > > > It isn't ported to OpenBSD, and it's one of those projects where they > > don't provide any infrastructure to build a library and suggest that > > people copy it to their source tree and add to their own Makefiles.. > > > > Maybe you are looking at an old version. Now it is not like that. > https://github.com/signal11/hidapi > > Since it is working under FreeBSD with the libusb backend, it is > probably not so difficult to port to OpenBSD as well. I'm looking at 0.7.0, which is the last actual release on https://github.com/signal11/hidapi/releases. This isn't another of those projects that expects everyone to use some random version of development code is it?
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On Mon, Dec 7, 2015 at 10:43 PM, Stuart Henderson wrote: > On 2015/12/07 22:11, Xiaofan Chen wrote: >> Not so sure if there is a port of hidapi under OpenBSD. >> Ref: http://www.signal11.us/oss/hidapi/ > > It isn't ported to OpenBSD, and it's one of those projects where they > don't provide any infrastructure to build a library and suggest that > people copy it to their source tree and add to their own Makefiles.. > Maybe you are looking at an old version. Now it is not like that. https://github.com/signal11/hidapi Since it is working under FreeBSD with the libusb backend, it is probably not so difficult to port to OpenBSD as well. -- Xiaofan
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On Sun, December 6, 2015 22:10, Ian Darwin wrote: > > > On 2015-12-06 12:23 PM, Stuart Henderson wrote: >> On 2015/12/06 06:02, Mickael Torres wrote: >>> Hello, >>> >>> This is a kernel patch plus a utility called ugenctl I use to allow >>> selected USB devices to attach as ugen(4) instead of their more specific >>> driver. My use case is a Microchip "PICkit 2 Microcontroller Programmer" >>> that attaches as uhid(4), but the command line utility pk2cmd wants a >>> udev(4) device. There maybe are some other use cases. >> If a device is generally pointless with uhid, we can just knock it >> out completely in the kernel, see the UQ_BAD_HID mechanism. I think this >> applies to your device. >> >> The bigger problem is "dual use" devices; e.g. some want UPS to attach >> to upd(4), others want ugen(4) for use with NUT/apcupsd. Your code is >> partially useful for these, but because it just changes things at attach, >> won't survive a reboot - if it could instead force a device to detach >> and reattach to ugen it would help a lot more cases. >> > One fairly common (I believe) use is with USB printers that attach as ulpt > but CUPS wants as ugen - for these, this is useful as it stands - just > run it > from rc. Do people want their UPS to sometimes be upd and other times be > a ugen? I can see there might be "I want to change this now" cases, but I > suspect the majority could be done once at each boot and be quite useful. > > I guess no. I have to configure kernel after every update to make my ups attach as ugen and not upd. So this tool would be useful for me with a config file so I can configure it once and don't bother on every reboot/update.
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On 07/12/15(Mon) 22:18, Xiaofan Chen wrote: > On Mon, Dec 7, 2015 at 7:42 PM, Martin Pieuchot wrote: > > I'd really prefer a solution that doesn't need any button. In other > > words to always be able to use your device from userland if the kernel > > is not using it. > > > > One way would be to always attach a ugen(4) driver to every USB device, > > I think that's what FreeBSD does. The other way would be to use the > > usb(4) bus interface to talk to your device. In both cases some work > > is needed to guarantee that an endpoint is only driven by one driver at > > a time. Right now this is done by attaching only one driver. > > It will be good if this limitation is removed (I know the FreeBSD approach > but FreeBSD libusb is not under libusb project due to license concerns) > and then libusb will be more useful. Or a method like Linux where the > kernel driver can be dynamically detached (so that usbfs generic driver > is attached and libusb uses usbfs under Linux). I agree, but somebody has to do the work 8) Starting with a HID device is the way to go. The first step should be to deprecate the libusbhid(3) and use the libusb instead. Userland should stop using it, then we disable it in the kernel making every HID device attach as ugen(4) and switch the ports currently using libusbhid to libusb. > > To which driver your device currently attaches? What kind of transfers > > to you want to submit from userland? The libusb already allow your to > > submit(some) control transfers. It would be nice if you could improve > > this rather than adding a hack like this one. > > > > As mentioned in another email reply, PICKit 2 is a generic USB device > and it uses control transfer and interrupt transfer. It is a bit unique that > PICkit 2 has two USB configurations, one for HID and one for custom > USB ( a legacy from the PICKit 1 days). Well having two configurations should not be a problem.
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On 2015/12/07 22:11, Xiaofan Chen wrote: > Not so sure if there is a port of hidapi under OpenBSD. > Ref: http://www.signal11.us/oss/hidapi/ It isn't ported to OpenBSD, and it's one of those projects where they don't provide any infrastructure to build a library and suggest that people copy it to their source tree and add to their own Makefiles..
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On Mon, Dec 7, 2015 at 7:42 PM, Martin Pieuchot wrote: > I'd really prefer a solution that doesn't need any button. In other > words to always be able to use your device from userland if the kernel > is not using it. > > One way would be to always attach a ugen(4) driver to every USB device, > I think that's what FreeBSD does. The other way would be to use the > usb(4) bus interface to talk to your device. In both cases some work > is needed to guarantee that an endpoint is only driven by one driver at > a time. Right now this is done by attaching only one driver. It will be good if this limitation is removed (I know the FreeBSD approach but FreeBSD libusb is not under libusb project due to license concerns) and then libusb will be more useful. Or a method like Linux where the kernel driver can be dynamically detached (so that usbfs generic driver is attached and libusb uses usbfs under Linux). > To which driver your device currently attaches? What kind of transfers > to you want to submit from userland? The libusb already allow your to > submit(some) control transfers. It would be nice if you could improve > this rather than adding a hack like this one. > As mentioned in another email reply, PICKit 2 is a generic USB device and it uses control transfer and interrupt transfer. It is a bit unique that PICkit 2 has two USB configurations, one for HID and one for custom USB ( a legacy from the PICKit 1 days). -- Xiaofan
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On Mon, Dec 7, 2015 at 8:19 PM, Mickael Torres wrote: > > Actually the device attaches as uhid. I don't know which kind of transfer > is used, I'll have to look into this, but the soft (pk2cmd) uses libusb > and only works when the device is attached as ugen. pk2cmd is only for PICkit 2 which is an HID device for the default configuration. It actually has two configurations and the alternative configuration is a generic USB device. I have not tried it under OpenBSD and not so sure if it can use the alternative configuration. Not so sure if there is a port of hidapi under OpenBSD. Ref: http://www.signal11.us/oss/hidapi/ We at the libusb project now recommend HIDAPI for generic USB HID device like PICKit 2. https://github.com/libusb/libusb/wiki/FAQ#Does_libusb_support_HID_devices When Jeff Post worked with Microchip developer to get pk2cmd to work under Linux, there was no HIDAPI, only libusb-0.1. I was involved heavily at that time to get pk2cmd to work under Linux and I actually got pk2cmd to work under FreeBSD last time. https://github.com/psmay/pk2cmd/blob/master/pk2cmd/ReadmeMakefile.txt > And another soft (pic32prog) which also uses libusb seems to only detect > the device when it is attached as uhid. > I'll try to take a look into libusb. pic32prog seems to supports different USB interface but many of them uses HID interface. pk2cmd code github mirror (license not considered to be open source). https://github.com/psmay/pk2cmd The Linux backend for pk2cmd is this one. https://github.com/psmay/pk2cmd/blob/master/pk2cmd/pk2usb.cpp I have submitted kernel patch to Linux kernel to blacklist PICkit 2 under Linux so it is not attached to the kernel HID driver. Ref: http://mcuee.blogspot.sg/2008/08/two-trivial-patches-now-in-linux-kernel.html pic32prog seems to be here. https://github.com/sergev/pic32prog -- Xiaofan
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On 07/12/15(Mon) 13:19, Mickael Torres wrote: > [...] > Actually the device attaches as uhid. I don't know which kind of transfer > is used, I'll have to look into this, but the soft (pk2cmd) uses libusb > and only works when the device is attached as ugen. That's easy because the uhid(4) driver does nothing but offers an userland interface. > And another soft (pic32prog) which also uses libusb seems to only detect > the device when it is attached as uhid. This generally means it uses the libusbhid. Could you try to build the port using libusb instead?
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On 2015-12-07 12:42, Martin Pieuchot wrote: On 07/12/15(Mon) 00:36, Mickael Torres wrote: On 2015-12-06 20:10, Ian Darwin wrote: >On 2015-12-06 12:23 PM, Stuart Henderson wrote: >>On 2015/12/06 06:02, Mickael Torres wrote: >>>Hello, >>> >>>This is a kernel patch plus a utility called ugenctl I use to allow >>>selected USB devices to attach as ugen(4) instead of their more >>>specific >>>driver. My use case is a Microchip "PICkit 2 Microcontroller >>>Programmer" >>>that attaches as uhid(4), but the command line utility pk2cmd wants a >>>udev(4) device. There maybe are some other use cases. >>If a device is generally pointless with uhid, we can just knock it >>out completely in the kernel, see the UQ_BAD_HID mechanism. I think this >>applies to your device. >> >>The bigger problem is "dual use" devices; e.g. some want UPS to attach >>to upd(4), others want ugen(4) for use with NUT/apcupsd. Your code is >>partially useful for these, but because it just changes things at >>attach, >>won't survive a reboot - if it could instead force a device to detach >>and reattach to ugen it would help a lot more cases. >> >One fairly common (I believe) use is with USB printers that attach as ulpt >but CUPS wants as ugen - for these, this is useful as it stands - just run >it >from rc. Do people want their UPS to sometimes be upd and other times be >a ugen? I can see there might be "I want to change this now" cases, but I >suspect the majority could be done once at each boot and be quite useful. Hello, Hello Mickael, an updated version that detach/reattach if a device is already connected, when adding and when removing from the ugen list. Seems to work well, but I don't have a lot of hardware to test it. What do you think ? I'd really prefer a solution that doesn't need any button. In other words to always be able to use your device from userland if the kernel is not using it. One way would be to always attach a ugen(4) driver to every USB device, I think that's what FreeBSD does. The other way would be to use the usb(4) bus interface to talk to your device. In both cases some work is needed to guarantee that an endpoint is only driven by one driver at a time. Right now this is done by attaching only one driver. To which driver your device currently attaches? What kind of transfers to you want to submit from userland? The libusb already allow your to submit(some) control transfers. It would be nice if you could improve this rather than adding a hack like this one. Cheers, Martin Hello Martin, Actually the device attaches as uhid. I don't know which kind of transfer is used, I'll have to look into this, but the soft (pk2cmd) uses libusb and only works when the device is attached as ugen. And another soft (pic32prog) which also uses libusb seems to only detect the device when it is attached as uhid. I'll try to take a look into libusb. Cheers, Mike.
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On 07/12/15(Mon) 00:36, Mickael Torres wrote: > On 2015-12-06 20:10, Ian Darwin wrote: > >On 2015-12-06 12:23 PM, Stuart Henderson wrote: > >>On 2015/12/06 06:02, Mickael Torres wrote: > >>>Hello, > >>> > >>>This is a kernel patch plus a utility called ugenctl I use to allow > >>>selected USB devices to attach as ugen(4) instead of their more > >>>specific > >>>driver. My use case is a Microchip "PICkit 2 Microcontroller > >>>Programmer" > >>>that attaches as uhid(4), but the command line utility pk2cmd wants a > >>>udev(4) device. There maybe are some other use cases. > >>If a device is generally pointless with uhid, we can just knock it > >>out completely in the kernel, see the UQ_BAD_HID mechanism. I think this > >>applies to your device. > >> > >>The bigger problem is "dual use" devices; e.g. some want UPS to attach > >>to upd(4), others want ugen(4) for use with NUT/apcupsd. Your code is > >>partially useful for these, but because it just changes things at > >>attach, > >>won't survive a reboot - if it could instead force a device to detach > >>and reattach to ugen it would help a lot more cases. > >> > >One fairly common (I believe) use is with USB printers that attach as ulpt > >but CUPS wants as ugen - for these, this is useful as it stands - just run > >it > >from rc. Do people want their UPS to sometimes be upd and other times be > >a ugen? I can see there might be "I want to change this now" cases, but I > >suspect the majority could be done once at each boot and be quite useful. > > Hello, Hello Mickael, > an updated version that detach/reattach if a device is already connected, > when > adding and when removing from the ugen list. > Seems to work well, but I don't have a lot of hardware to test it. > What do you think ? I'd really prefer a solution that doesn't need any button. In other words to always be able to use your device from userland if the kernel is not using it. One way would be to always attach a ugen(4) driver to every USB device, I think that's what FreeBSD does. The other way would be to use the usb(4) bus interface to talk to your device. In both cases some work is needed to guarantee that an endpoint is only driven by one driver at a time. Right now this is done by attaching only one driver. To which driver your device currently attaches? What kind of transfers to you want to submit from userland? The libusb already allow your to submit(some) control transfers. It would be nice if you could improve this rather than adding a hack like this one. Cheers, Martin
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On 2015-12-06 20:10, Ian Darwin wrote: On 2015-12-06 12:23 PM, Stuart Henderson wrote: On 2015/12/06 06:02, Mickael Torres wrote: Hello, This is a kernel patch plus a utility called ugenctl I use to allow selected USB devices to attach as ugen(4) instead of their more specific driver. My use case is a Microchip "PICkit 2 Microcontroller Programmer" that attaches as uhid(4), but the command line utility pk2cmd wants a udev(4) device. There maybe are some other use cases. If a device is generally pointless with uhid, we can just knock it out completely in the kernel, see the UQ_BAD_HID mechanism. I think this applies to your device. The bigger problem is "dual use" devices; e.g. some want UPS to attach to upd(4), others want ugen(4) for use with NUT/apcupsd. Your code is partially useful for these, but because it just changes things at attach, won't survive a reboot - if it could instead force a device to detach and reattach to ugen it would help a lot more cases. One fairly common (I believe) use is with USB printers that attach as ulpt but CUPS wants as ugen - for these, this is useful as it stands - just run it from rc. Do people want their UPS to sometimes be upd and other times be a ugen? I can see there might be "I want to change this now" cases, but I suspect the majority could be done once at each boot and be quite useful. Hello, an updated version that detach/reattach if a device is already connected, when adding and when removing from the ugen list. Seems to work well, but I don't have a lot of hardware to test it. What do you think ? https://github.com/mickaeltorres/openbsd_ugenctl and inlined. Cheers, Mike. kernel patch below: Index: usb.c === RCS file: /cvs/src/sys/dev/usb/usb.c,v retrieving revision 1.107 diff -u -p -r1.107 usb.c --- usb.c 14 Mar 2015 03:38:50 - 1.107 +++ usb.c 6 Dec 2015 23:19:48 - @@ -137,6 +137,8 @@ const struct cfattach usb_ca = { usb_activate, }; +struct usb_device_ugen_force usb_udf; + int usb_match(struct device *parent, void *match, void *aux) { @@ -156,6 +158,7 @@ usb_attach(struct device *parent, struct TAILQ_INIT(&usb_generic_tasks); usb_run_tasks = usb_run_abort_tasks = 1; kthread_create_deferred(usb_create_task_threads, NULL); + bzero(&usb_udf, sizeof(usb_udf)); } usb_nbuses++; @@ -792,6 +795,37 @@ usbioctl(dev_t devt, u_long cmd, caddr_t return (error); } + case USB_DEVICE_FORCE_UGEN: + { + struct usb_device_ugen_force *udf = + (struct usb_device_ugen_force *)data; + + switch (udf->udf_cmd) { + case USB_DEVICE_UGEN_FORCE_GET: + { + memcpy(udf, &usb_udf, sizeof(usb_udf)); + break; + } + case USB_DEVICE_UGEN_FORCE_SET: + { + memcpy(&usb_udf, udf, sizeof(usb_udf)); + break; + } + case USB_DEVICE_UGEN_FORCE_RESET: + { + struct usbd_device *dev; + + if (udf->udf_addr < 1 || + udf->udf_addr >= USB_MAX_DEVICES) + return (EINVAL); + dev = sc->sc_bus->devices[udf->udf_addr]; + usbd_reset_port(dev->myhub, dev->powersrc->portno); + usb_needs_reattach(dev); + break; + } + default: + return (EINVAL); + } + return (0); + } + default: return (EINVAL); } Index: usb.h === RCS file: /cvs/src/sys/dev/usb/usb.h,v retrieving revision 1.53 diff -u -p -r1.53 usb.h --- usb.h 9 Jul 2015 05:40:44 - 1.53 +++ usb.h 6 Dec 2015 23:19:48 - @@ -749,6 +749,17 @@ struct usb_device_stats { u_long uds_requests[4];/* indexed by transfer type UE_* */ }; +#define USB_DEVICE_UGEN_FORCE_MAX 16 +#define USB_DEVICE_UGEN_FORCE_GET 0 +#define USB_DEVICE_UGEN_FORCE_SET 1 +#define USB_DEVICE_UGEN_FORCE_RESET 2 +struct usb_device_ugen_force { +int udf_cmd; +u_char udf_addr; +u_short udf_ven_id[USB_DEVICE_UGEN_FORCE_MAX]; +u_short udf_dev_id[USB_DEVICE_UGEN_FORCE_MAX]; +}; + /* USB controller */ #define USB_REQUEST_IOWR('U', 1, struct usb_ctl_request) #define USB_SETDEBUG _IOW ('U', 2, unsigned int) @@ -758,6 +769,7 @@ struct usb_device_stats { #define USB_DEVICE_GET_CDESC _IOWR('U', 6, struct usb_device_cdesc) #define USB_DEVICE_GET_FDESC _IOWR('U', 7, struct usb_device_fdesc) #define USB_DEVICE_GET_DDESC _IOW
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On 2015-12-06 20:10, Ian Darwin wrote: On 2015-12-06 12:23 PM, Stuart Henderson wrote: On 2015/12/06 06:02, Mickael Torres wrote: Hello, This is a kernel patch plus a utility called ugenctl I use to allow selected USB devices to attach as ugen(4) instead of their more specific driver. My use case is a Microchip "PICkit 2 Microcontroller Programmer" that attaches as uhid(4), but the command line utility pk2cmd wants a udev(4) device. There maybe are some other use cases. If a device is generally pointless with uhid, we can just knock it out completely in the kernel, see the UQ_BAD_HID mechanism. I think this applies to your device. The bigger problem is "dual use" devices; e.g. some want UPS to attach to upd(4), others want ugen(4) for use with NUT/apcupsd. Your code is partially useful for these, but because it just changes things at attach, won't survive a reboot - if it could instead force a device to detach and reattach to ugen it would help a lot more cases. One fairly common (I believe) use is with USB printers that attach as ulpt but CUPS wants as ugen - for these, this is useful as it stands - just run it from rc. Do people want their UPS to sometimes be upd and other times be a ugen? I can see there might be "I want to change this now" cases, but I suspect the majority could be done once at each boot and be quite useful. Hello, an updated version that detach/reattach if a device is already connected, when adding and when removing from the ugen list. Seems to work well, but I don't have a lot of hardware to test it. What do you think ? https://github.com/mickaeltorres/openbsd_ugenctl and inlined. Cheers, Mike. kernel patch below: Index: usb.c === RCS file: /cvs/src/sys/dev/usb/usb.c,v retrieving revision 1.107 diff -u -p -r1.107 usb.c --- usb.c 14 Mar 2015 03:38:50 - 1.107 +++ usb.c 6 Dec 2015 23:19:48 - @@ -137,6 +137,8 @@ const struct cfattach usb_ca = { usb_activate, }; +struct usb_device_ugen_force usb_udf; + int usb_match(struct device *parent, void *match, void *aux) { @@ -156,6 +158,7 @@ usb_attach(struct device *parent, struct TAILQ_INIT(&usb_generic_tasks); usb_run_tasks = usb_run_abort_tasks = 1; kthread_create_deferred(usb_create_task_threads, NULL); + bzero(&usb_udf, sizeof(usb_udf)); } usb_nbuses++; @@ -792,6 +795,37 @@ usbioctl(dev_t devt, u_long cmd, caddr_t return (error); } + case USB_DEVICE_FORCE_UGEN: + { + struct usb_device_ugen_force *udf = + (struct usb_device_ugen_force *)data; + + switch (udf->udf_cmd) { + case USB_DEVICE_UGEN_FORCE_GET: + { + memcpy(udf, &usb_udf, sizeof(usb_udf)); + break; + } + case USB_DEVICE_UGEN_FORCE_SET: + { + memcpy(&usb_udf, udf, sizeof(usb_udf)); + break; + } + case USB_DEVICE_UGEN_FORCE_RESET: + { + struct usbd_device *dev; + + if (udf->udf_addr < 1 || + udf->udf_addr >= USB_MAX_DEVICES) + return (EINVAL); + dev = sc->sc_bus->devices[udf->udf_addr]; + usbd_reset_port(dev->myhub, dev->powersrc->portno); + usb_needs_reattach(dev); + break; + } + default: + return (EINVAL); + } + return (0); + } + default: return (EINVAL); } Index: usb.h === RCS file: /cvs/src/sys/dev/usb/usb.h,v retrieving revision 1.53 diff -u -p -r1.53 usb.h --- usb.h 9 Jul 2015 05:40:44 - 1.53 +++ usb.h 6 Dec 2015 23:19:48 - @@ -749,6 +749,17 @@ struct usb_device_stats { u_long uds_requests[4];/* indexed by transfer type UE_* */ }; +#define USB_DEVICE_UGEN_FORCE_MAX 16 +#define USB_DEVICE_UGEN_FORCE_GET 0 +#define USB_DEVICE_UGEN_FORCE_SET 1 +#define USB_DEVICE_UGEN_FORCE_RESET 2 +struct usb_device_ugen_force { +int udf_cmd; +u_char udf_addr; +u_short udf_ven_id[USB_DEVICE_UGEN_FORCE_MAX]; +u_short udf_dev_id[USB_DEVICE_UGEN_FORCE_MAX]; +}; + /* USB controller */ #define USB_REQUEST_IOWR('U', 1, struct usb_ctl_request) #define USB_SETDEBUG _IOW ('U', 2, unsigned int) @@ -758,6 +769,7 @@ struct usb_device_stats { #define USB_DEVICE_GET_CDESC _IOWR('U', 6, struct usb_device_cdesc) #define USB_DEVICE_GET_FDESC _IOWR('U', 7, struct usb_device_fdesc) #define USB_DEVICE_GET_DDESC _IOWR('U', 8, struct usb_device_ddesc) +#defi
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
Hello Stuart, On 2015-12-06 18:23, Stuart Henderson wrote: On 2015/12/06 06:02, Mickael Torres wrote: Hello, This is a kernel patch plus a utility called ugenctl I use to allow selected USB devices to attach as ugen(4) instead of their more specific driver. My use case is a Microchip "PICkit 2 Microcontroller Programmer" that attaches as uhid(4), but the command line utility pk2cmd wants a udev(4) device. There maybe are some other use cases. If a device is generally pointless with uhid, we can just knock it out completely in the kernel, see the UQ_BAD_HID mechanism. I think this applies to your device. The bigger problem is "dual use" devices; e.g. some want UPS to attach to upd(4), others want ugen(4) for use with NUT/apcupsd. Your code is partially useful for these, but because it just changes things at attach, won't survive a reboot - if it could instead force a device to detach and reattach to ugen it would help a lot more cases. Actually another utility (pic32prog, but I can't seem to make it work right now) wants a uhid device, so it was easier to have a dynamic way to switch. I'll try to modify this to have the device doing a detach/reattach automatically, thanks for the idea. Cheers, Mike. It is mostly quick and dirty, but does the job. It can be found there: https://github.com/mickaeltorres/openbsd_ugenctl or inlined at the end of this mail. Cheers, Mike. Here is the kernel patch: Index: usb.c === RCS file: /cvs/src/sys/dev/usb/usb.c,v retrieving revision 1.107 diff -u -p -r1.107 usb.c --- usb.c 14 Mar 2015 03:38:50 - 1.107 +++ usb.c 6 Dec 2015 04:29:22 - @@ -137,6 +137,8 @@ const struct cfattach usb_ca = { usb_activate, }; +struct usb_device_ugen_force usb_udf; + int usb_match(struct device *parent, void *match, void *aux) { @@ -156,6 +158,7 @@ usb_attach(struct device *parent, struct TAILQ_INIT(&usb_generic_tasks); usb_run_tasks = usb_run_abort_tasks = 1; kthread_create_deferred(usb_create_task_threads, NULL); + bzero(&usb_udf, sizeof(usb_udf)); } usb_nbuses++; @@ -792,6 +795,23 @@ usbioctl(dev_t devt, u_long cmd, caddr_t return (error); } + case USB_DEVICE_FORCE_UGEN: + { + struct usb_device_ugen_force *udf = + (struct usb_device_ugen_force *)data; + + if (udf->udf_set) // replace our list + { + memcpy(&usb_udf, udf, sizeof(usb_udf)); + return (0); + } + else // return the list + { + memcpy(udf, &usb_udf, sizeof(usb_udf)); + return (0); + } + } + default: return (EINVAL); } Index: usb.h === RCS file: /cvs/src/sys/dev/usb/usb.h,v retrieving revision 1.53 diff -u -p -r1.53 usb.h --- usb.h 9 Jul 2015 05:40:44 - 1.53 +++ usb.h 6 Dec 2015 04:29:23 - @@ -749,6 +749,13 @@ struct usb_device_stats { u_long uds_requests[4];/* indexed by transfer type UE_* */ }; +#define USB_DEVICE_UGEN_FORCE_MAX 16 +struct usb_device_ugen_force { +int udf_set; +u_short udf_ven_id[USB_DEVICE_UGEN_FORCE_MAX]; +u_short udf_dev_id[USB_DEVICE_UGEN_FORCE_MAX]; +}; + /* USB controller */ #define USB_REQUEST_IOWR('U', 1, struct usb_ctl_request) #define USB_SETDEBUG _IOW ('U', 2, unsigned int) @@ -758,6 +765,7 @@ struct usb_device_stats { #define USB_DEVICE_GET_CDESC _IOWR('U', 6, struct usb_device_cdesc) #define USB_DEVICE_GET_FDESC _IOWR('U', 7, struct usb_device_fdesc) #define USB_DEVICE_GET_DDESC _IOWR('U', 8, struct usb_device_ddesc) +#define USB_DEVICE_FORCE_UGEN _IOWR('U', 9, struct usb_device_ugen_force) /* Generic HID device */ #define USB_GET_REPORT_DESC_IOR ('U', 21, struct usb_ctl_report_desc) Index: usb_subr.c === RCS file: /cvs/src/sys/dev/usb/usb_subr.c,v retrieving revision 1.117 diff -u -p -r1.117 usb_subr.c --- usb_subr.c 23 Mar 2015 22:26:01 - 1.117 +++ usb_subr.c 6 Dec 2015 04:29:23 - @@ -840,6 +840,7 @@ usbd_probe_and_attach(struct device *par struct device *dv; struct usbd_interface **ifaces; extern struct rwlock usbpalock; + extern struct usb_device_ugen_force usb_udf; rw_enter_write(&usbpalock); @@ -855,6 +856,14 @@ usbd_probe_and_attach(struct device *par uaa.product = UGETW(dd->idProduct); uaa.release = UGETW(dd->bcdDevice); + /* Check if this device is in the ugen force list */ + for (i = 0; i < USB_DEVICE_UGEN_FORCE_MAX; i++) + if ((usb_udf.udf_ven_id[i] == uaa.vend
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On 2015-12-06 12:23 PM, Stuart Henderson wrote: On 2015/12/06 06:02, Mickael Torres wrote: Hello, This is a kernel patch plus a utility called ugenctl I use to allow selected USB devices to attach as ugen(4) instead of their more specific driver. My use case is a Microchip "PICkit 2 Microcontroller Programmer" that attaches as uhid(4), but the command line utility pk2cmd wants a udev(4) device. There maybe are some other use cases. If a device is generally pointless with uhid, we can just knock it out completely in the kernel, see the UQ_BAD_HID mechanism. I think this applies to your device. The bigger problem is "dual use" devices; e.g. some want UPS to attach to upd(4), others want ugen(4) for use with NUT/apcupsd. Your code is partially useful for these, but because it just changes things at attach, won't survive a reboot - if it could instead force a device to detach and reattach to ugen it would help a lot more cases. One fairly common (I believe) use is with USB printers that attach as ulpt but CUPS wants as ugen - for these, this is useful as it stands - just run it from rc. Do people want their UPS to sometimes be upd and other times be a ugen? I can see there might be "I want to change this now" cases, but I suspect the majority could be done once at each boot and be quite useful.
Re: ugenctl for attaching USB devices to ugen instead of their specific driver
On 2015/12/06 06:02, Mickael Torres wrote: > Hello, > > This is a kernel patch plus a utility called ugenctl I use to allow > selected USB devices to attach as ugen(4) instead of their more specific > driver. My use case is a Microchip "PICkit 2 Microcontroller Programmer" > that attaches as uhid(4), but the command line utility pk2cmd wants a > udev(4) device. There maybe are some other use cases. If a device is generally pointless with uhid, we can just knock it out completely in the kernel, see the UQ_BAD_HID mechanism. I think this applies to your device. The bigger problem is "dual use" devices; e.g. some want UPS to attach to upd(4), others want ugen(4) for use with NUT/apcupsd. Your code is partially useful for these, but because it just changes things at attach, won't survive a reboot - if it could instead force a device to detach and reattach to ugen it would help a lot more cases. > It is mostly quick and dirty, but does the job. > > It can be found there: https://github.com/mickaeltorres/openbsd_ugenctl or > inlined at the end of this mail. > > Cheers, > Mike. > > Here is the kernel patch: > > Index: usb.c > === > RCS file: /cvs/src/sys/dev/usb/usb.c,v > retrieving revision 1.107 > diff -u -p -r1.107 usb.c > --- usb.c 14 Mar 2015 03:38:50 - 1.107 > +++ usb.c 6 Dec 2015 04:29:22 - > @@ -137,6 +137,8 @@ const struct cfattach usb_ca = { > usb_activate, > }; > > +struct usb_device_ugen_force usb_udf; > + > int > usb_match(struct device *parent, void *match, void *aux) > { > @@ -156,6 +158,7 @@ usb_attach(struct device *parent, struct > TAILQ_INIT(&usb_generic_tasks); > usb_run_tasks = usb_run_abort_tasks = 1; > kthread_create_deferred(usb_create_task_threads, NULL); > + bzero(&usb_udf, sizeof(usb_udf)); > } > usb_nbuses++; > > @@ -792,6 +795,23 @@ usbioctl(dev_t devt, u_long cmd, caddr_t > return (error); > } > > + case USB_DEVICE_FORCE_UGEN: > + { > + struct usb_device_ugen_force *udf = > + (struct usb_device_ugen_force *)data; > + > + if (udf->udf_set) // replace our list > + { > + memcpy(&usb_udf, udf, sizeof(usb_udf)); > + return (0); > + } > + else // return the list > + { > + memcpy(udf, &usb_udf, sizeof(usb_udf)); > + return (0); > + } > + } > + > default: > return (EINVAL); > } > Index: usb.h > === > RCS file: /cvs/src/sys/dev/usb/usb.h,v > retrieving revision 1.53 > diff -u -p -r1.53 usb.h > --- usb.h 9 Jul 2015 05:40:44 - 1.53 > +++ usb.h 6 Dec 2015 04:29:23 - > @@ -749,6 +749,13 @@ struct usb_device_stats { > u_long uds_requests[4];/* indexed by transfer type UE_* */ > }; > > +#define USB_DEVICE_UGEN_FORCE_MAX 16 > +struct usb_device_ugen_force { > +int udf_set; > +u_short udf_ven_id[USB_DEVICE_UGEN_FORCE_MAX]; > +u_short udf_dev_id[USB_DEVICE_UGEN_FORCE_MAX]; > +}; > + > /* USB controller */ > #define USB_REQUEST_IOWR('U', 1, struct usb_ctl_request) > #define USB_SETDEBUG _IOW ('U', 2, unsigned int) > @@ -758,6 +765,7 @@ struct usb_device_stats { > #define USB_DEVICE_GET_CDESC _IOWR('U', 6, struct usb_device_cdesc) > #define USB_DEVICE_GET_FDESC _IOWR('U', 7, struct usb_device_fdesc) > #define USB_DEVICE_GET_DDESC _IOWR('U', 8, struct usb_device_ddesc) > +#define USB_DEVICE_FORCE_UGEN _IOWR('U', 9, struct > usb_device_ugen_force) > > /* Generic HID device */ > #define USB_GET_REPORT_DESC_IOR ('U', 21, struct usb_ctl_report_desc) > Index: usb_subr.c > === > RCS file: /cvs/src/sys/dev/usb/usb_subr.c,v > retrieving revision 1.117 > diff -u -p -r1.117 usb_subr.c > --- usb_subr.c 23 Mar 2015 22:26:01 - 1.117 > +++ usb_subr.c 6 Dec 2015 04:29:23 - > @@ -840,6 +840,7 @@ usbd_probe_and_attach(struct device *par > struct device *dv; > struct usbd_interface **ifaces; > extern struct rwlock usbpalock; > + extern struct usb_device_ugen_force usb_udf; > > rw_enter_write(&usbpalock); > > @@ -855,6 +856,14 @@ usbd_probe_and_attach(struct device *par > uaa.product = UGETW(dd->idProduct); > uaa.release = UGETW(dd->bcdDevice); > > + /* Check if this device is in the ugen force list */ > + for (i = 0; i < USB_DEVICE_UGEN_FORCE_MAX; i++) > + if ((usb_udf.udf_ven_id[i] == uaa.vendor) && > + (usb_udf.udf_dev_id[i] == uaa.product)) > + break; > + if (i != US
ugenctl for attaching USB devices to ugen instead of their specific driver
Hello, This is a kernel patch plus a utility called ugenctl I use to allow selected USB devices to attach as ugen(4) instead of their more specific driver. My use case is a Microchip "PICkit 2 Microcontroller Programmer" that attaches as uhid(4), but the command line utility pk2cmd wants a udev(4) device. There maybe are some other use cases. It is mostly quick and dirty, but does the job. It can be found there: https://github.com/mickaeltorres/openbsd_ugenctl or inlined at the end of this mail. Cheers, Mike. Here is the kernel patch: Index: usb.c === RCS file: /cvs/src/sys/dev/usb/usb.c,v retrieving revision 1.107 diff -u -p -r1.107 usb.c --- usb.c 14 Mar 2015 03:38:50 - 1.107 +++ usb.c 6 Dec 2015 04:29:22 - @@ -137,6 +137,8 @@ const struct cfattach usb_ca = { usb_activate, }; +struct usb_device_ugen_force usb_udf; + int usb_match(struct device *parent, void *match, void *aux) { @@ -156,6 +158,7 @@ usb_attach(struct device *parent, struct TAILQ_INIT(&usb_generic_tasks); usb_run_tasks = usb_run_abort_tasks = 1; kthread_create_deferred(usb_create_task_threads, NULL); + bzero(&usb_udf, sizeof(usb_udf)); } usb_nbuses++; @@ -792,6 +795,23 @@ usbioctl(dev_t devt, u_long cmd, caddr_t return (error); } + case USB_DEVICE_FORCE_UGEN: + { + struct usb_device_ugen_force *udf = + (struct usb_device_ugen_force *)data; + + if (udf->udf_set) // replace our list + { + memcpy(&usb_udf, udf, sizeof(usb_udf)); + return (0); + } + else // return the list + { + memcpy(udf, &usb_udf, sizeof(usb_udf)); + return (0); + } + } + default: return (EINVAL); } Index: usb.h === RCS file: /cvs/src/sys/dev/usb/usb.h,v retrieving revision 1.53 diff -u -p -r1.53 usb.h --- usb.h 9 Jul 2015 05:40:44 - 1.53 +++ usb.h 6 Dec 2015 04:29:23 - @@ -749,6 +749,13 @@ struct usb_device_stats { u_long uds_requests[4];/* indexed by transfer type UE_* */ }; +#define USB_DEVICE_UGEN_FORCE_MAX 16 +struct usb_device_ugen_force { +int udf_set; +u_short udf_ven_id[USB_DEVICE_UGEN_FORCE_MAX]; +u_short udf_dev_id[USB_DEVICE_UGEN_FORCE_MAX]; +}; + /* USB controller */ #define USB_REQUEST_IOWR('U', 1, struct usb_ctl_request) #define USB_SETDEBUG _IOW ('U', 2, unsigned int) @@ -758,6 +765,7 @@ struct usb_device_stats { #define USB_DEVICE_GET_CDESC _IOWR('U', 6, struct usb_device_cdesc) #define USB_DEVICE_GET_FDESC _IOWR('U', 7, struct usb_device_fdesc) #define USB_DEVICE_GET_DDESC _IOWR('U', 8, struct usb_device_ddesc) +#define USB_DEVICE_FORCE_UGEN _IOWR('U', 9, struct usb_device_ugen_force) /* Generic HID device */ #define USB_GET_REPORT_DESC_IOR ('U', 21, struct usb_ctl_report_desc) Index: usb_subr.c === RCS file: /cvs/src/sys/dev/usb/usb_subr.c,v retrieving revision 1.117 diff -u -p -r1.117 usb_subr.c --- usb_subr.c 23 Mar 2015 22:26:01 - 1.117 +++ usb_subr.c 6 Dec 2015 04:29:23 - @@ -840,6 +840,7 @@ usbd_probe_and_attach(struct device *par struct device *dv; struct usbd_interface **ifaces; extern struct rwlock usbpalock; + extern struct usb_device_ugen_force usb_udf; rw_enter_write(&usbpalock); @@ -855,6 +856,14 @@ usbd_probe_and_attach(struct device *par uaa.product = UGETW(dd->idProduct); uaa.release = UGETW(dd->bcdDevice); + /* Check if this device is in the ugen force list */ + for (i = 0; i < USB_DEVICE_UGEN_FORCE_MAX; i++) + if ((usb_udf.udf_ven_id[i] == uaa.vendor) && + (usb_udf.udf_dev_id[i] == uaa.product)) + break; + if (i != USB_DEVICE_UGEN_FORCE_MAX) + goto generic; + /* First try with device specific drivers. */ DPRINTF(("usbd_probe_and_attach trying device specific drivers\n")); dv = config_found(parent, &uaa, usbd_print); And here is the ugenctl utility: Makefile: # $OpenBSD: Makefile,v 1.1 2000/02/03 21:52:15 jakob Exp $ # $NetBSD: Makefile,v 1.2 1998/07/12 20:40:45 augustss Exp $ PROG= ugenctl MAN=ugenctl.8 .include ugenctl.c: #include #include #include #include #include #include #include struct usb_change_list { u_short vid[USB_DEVICE_UGEN_FORCE_MAX]; u_short pid[USB_DEVICE_UGEN_FORCE_MAX]; int rem[USB_DEVICE_UGEN_FORCE_MAX]; int end; }; #define USB_PATH "/dev/usb0" exter