Re: ugenctl for attaching USB devices to ugen instead of their specific driver

2016-01-09 Thread Jiri B
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

2015-12-08 Thread Stuart Henderson
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

2015-12-08 Thread Xiaofan Chen
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

2015-12-07 Thread Kirill Bychkov
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

2015-12-07 Thread Martin Pieuchot
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

2015-12-07 Thread Stuart Henderson
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

2015-12-07 Thread Xiaofan Chen
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

2015-12-07 Thread Xiaofan Chen
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

2015-12-07 Thread Martin Pieuchot
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

2015-12-07 Thread Mickael Torres

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

2015-12-07 Thread Martin Pieuchot
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

2015-12-06 Thread Mickael Torres

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

2015-12-06 Thread Mike

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

2015-12-06 Thread Mickael Torres

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

2015-12-06 Thread Ian Darwin



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

2015-12-06 Thread Stuart Henderson
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

2015-12-06 Thread Mickael Torres

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