On Fri, Jan 22, 2021 at 07:00:57PM +0100, Marcus Glocker wrote:
> On Fri, 15 Jan 2021 22:41:13 +0100
> Marcus Glocker <mar...@nazgul.ch> wrote:
> 
> > On Fri, 15 Jan 2021 11:37:47 -0500
> > Bryan Steele <bry...@gmail.com> wrote:
> > 
> > > On Fri, Jan 15, 2021 at 06:23:01AM -0700, Thomas Frohwein wrote:  
> > > > On Sat, Jan 09, 2021 at 10:16:16AM +0100, Marcus Glocker wrote:
> > > >  
> > > > > On Thu, Jan 07, 2021 at 08:20:35PM +0100, Marcus Glocker wrote:
> > > > >     
> > > > > > > I have heard from others who tried the diff that the PS4
> > > > > > > controller is causing problems with the way it attaches. I
> > > > > > > ordered one to trial-and- error this myself at home. Could
> > > > > > > you share output of lsusb -vv? Thanks for giving it a try!
> > > > > > >   
> > > > > > 
> > > > > > Sure, here we go.
> > > > > > If I can find anything myself in the meantime I let you know.
> > > > > >    
> > > > > 
> > > > > So the problem doesn't seem to be in your new ujoy(4) code, but
> > > > > how the dev/hid/hid.c:hid_is_collection() function tries to cope
> > > > > with the PS4 controller.    
> > > > 
> > > > So with the hid_is_collection() problem not easy to mitigate [1],
> > > > should we table the ujoy(4) proposal for now pending a fix for the
> > > > problems with the PS4 controller? Or is this interesting enough
> > > > for some to work on moving forward despite this issue and finding
> > > > a solution for this specific (and in some ways unusual) device
> > > > later? 
> > > 
> > > Considering the hid_is_collection() fix from NetBSD proposed by
> > > Marcus fixes the issue with ujoy(4) but breaks some other drivers
> > > (imt(4) and ims(4)), could we not inline it into ujoy(4) for now?
> > > It's fairly small helper function. Like hid_is_joy_collection()?  
> > 
> > I think that could be an XXX workaround until somebody finds a proper,
> > generic fix for hid_is_collection() ...
> 
> That's what you meant, yes?

Yep, this is what I meant. Hopefully it won't have to stay for long, but
t would be nice to get ujoy(4) working as many controllers as possible
so that it can go in.

Can you send a new full diff thfr@? I still need to test with my USB
SNES controller, but tentatively this is still ok brynet@

-Bryan.

> Can this been updated in the overall diff and re-verified if it still
> works fine with the other controllers?  It (obviously) works with my
> PS4 controller.
> 
> 
> Index: sys/dev/usb/ujoy.c
> ===================================================================
> RCS file: sys/dev/usb/ujoy.c
> diff -N sys/dev/usb/ujoy.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ sys/dev/usb/ujoy.c        22 Jan 2021 17:54:46 -0000
> @@ -0,0 +1,149 @@
> +/*   $OpenBSD$ */
> +
> +/*
> + * Copyright (c) 2020 Thomas Frohwein        <t...@openbsd.org>
> + * Copyright (c) 2020 Bryan Steele   <bry...@openbsd.org>
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#include <sys/param.h>
> +#include <sys/systm.h>
> +#include <sys/kernel.h>
> +#include <sys/malloc.h>
> +#include <sys/signalvar.h>
> +#include <sys/device.h>
> +#include <sys/ioctl.h>
> +#include <sys/conf.h>
> +#include <sys/tty.h>
> +#include <sys/selinfo.h>
> +#include <sys/proc.h>
> +#include <sys/vnode.h>
> +#include <sys/poll.h>
> +#include <sys/fcntl.h>
> +
> +#include <dev/usb/usb.h>
> +#include <dev/usb/usbhid.h>
> +
> +#include <dev/usb/usbdevs.h>
> +#include <dev/usb/usbdi.h>
> +#include <dev/usb/usbdi_util.h>
> +
> +#include <dev/usb/uhidev.h>
> +#include <dev/usb/uhid.h>
> +
> +int ujoy_match(struct device *, void *, void *);
> +
> +struct cfdriver ujoy_cd = {
> +     NULL, "ujoy", DV_DULL
> +};
> +
> +const struct cfattach ujoy_ca = {
> +     sizeof(struct uhid_softc),
> +     ujoy_match,
> +     uhid_attach,
> +     uhid_detach,
> +};
> +
> +/*
> + * XXX workaround:
> + *
> + * This is a copy of sys/dev/hid/hid.c:hid_is_collection(), synced up to the
> + * NetBSD version.  Our current hid_is_collection() is not playing nice with
> + * all HID devices like the PS4 controller.  But applying this version
> + * globally breaks other HID devices like ims(4) and imt(4).  Until our 
> global
> + * hid_is_collection() can't be fixed to play nice with all HID devices, we
> + * go for this dedicated ujoy(4) version.
> + */
> +int
> +ujoy_hid_is_collection(const void *desc, int size, uint8_t id, int32_t usage)
> +{
> +     struct hid_data *hd;
> +     struct hid_item hi;
> +     uint32_t coll_usage = ~0;
> +
> +     hd = hid_start_parse(desc, size, hid_input);
> +     if (hd == NULL)
> +             return (0);
> +
> +     while (hid_get_item(hd, &hi)) {
> +             if (hi.kind == hid_collection &&
> +                 hi.collection == HCOLL_APPLICATION)
> +                     coll_usage = hi.usage;
> +
> +             if (hi.kind == hid_endcollection)
> +                     coll_usage = ~0;
> +
> +             if (hi.kind == hid_input &&
> +                 coll_usage == usage &&
> +                 hi.report_ID == id) {
> +                     hid_end_parse(hd);
> +                     return (1);
> +             }
> +     }
> +     hid_end_parse(hd);
> +
> +     return (0);
> +}
> +
> +int
> +ujoy_match(struct device *parent, void *match, void *aux)
> +{
> +     struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
> +     int                       size;
> +     void                     *desc;
> +     int                       ret = UMATCH_NONE;
> +
> +     if (uha->reportid == UHIDEV_CLAIM_ALLREPORTID)
> +             return (ret);
> +
> +     /* Find the general usage page and gamecontroller collections */
> +     uhidev_get_report_desc(uha->parent, &desc, &size);
> +
> +     if (ujoy_hid_is_collection(desc, size, uha->reportid,
> +         HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_JOYSTICK)))
> +             ret = UMATCH_IFACECLASS;
> +
> +     if (ujoy_hid_is_collection(desc, size, uha->reportid,
> +         HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_GAME_PAD)))
> +             ret = UMATCH_IFACECLASS;
> +
> +     return (ret);
> +}
> +
> +int
> +ujoyopen(dev_t dev, int flag, int mode, struct proc *p)
> +{
> +     /* Restrict ujoy devices to read operations */
> +     if ((flag & FWRITE))
> +             return (EPERM);
> +     return (uhid_do_open(dev, flag, mode, p));
> +}
> +
> +int
> +ujoyioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
> +{
> +     switch (cmd) {
> +     case FIONBIO:
> +     case FIOASYNC:
> +     case USB_GET_DEVICEINFO:
> +     case USB_GET_REPORT:
> +     case USB_GET_REPORT_DESC:
> +     case USB_GET_REPORT_ID:
> +             break;
> +     default:
> +             return (EPERM);
> +     }
> +
> +     return (uhidioctl(dev, cmd, addr, flag, p));
> +}
> 

Reply via email to