LCOV - code coverage report
Current view: top level - dev/usb - ums.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 94 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: ums.c,v 1.43 2016/01/12 19:16:21 jcs Exp $ */
       2             : /*      $NetBSD: ums.c,v 1.60 2003/03/11 16:44:00 augustss Exp $        */
       3             : 
       4             : /*
       5             :  * Copyright (c) 1998 The NetBSD Foundation, Inc.
       6             :  * All rights reserved.
       7             :  *
       8             :  * This code is derived from software contributed to The NetBSD Foundation
       9             :  * by Lennart Augustsson (lennart@augustsson.net) at
      10             :  * Carlstedt Research & Technology.
      11             :  *
      12             :  * Redistribution and use in source and binary forms, with or without
      13             :  * modification, are permitted provided that the following conditions
      14             :  * are met:
      15             :  * 1. Redistributions of source code must retain the above copyright
      16             :  *    notice, this list of conditions and the following disclaimer.
      17             :  * 2. Redistributions in binary form must reproduce the above copyright
      18             :  *    notice, this list of conditions and the following disclaimer in the
      19             :  *    documentation and/or other materials provided with the distribution.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
      22             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      23             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      24             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
      25             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      26             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      27             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      28             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      29             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      30             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      31             :  * POSSIBILITY OF SUCH DAMAGE.
      32             :  */
      33             : 
      34             : /*
      35             :  * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
      36             :  */
      37             : 
      38             : #include <sys/param.h>
      39             : #include <sys/systm.h>
      40             : #include <sys/kernel.h>
      41             : #include <sys/device.h>
      42             : #include <sys/ioctl.h>
      43             : 
      44             : #include <dev/usb/usb.h>
      45             : #include <dev/usb/usbhid.h>
      46             : 
      47             : #include <dev/usb/usbdi.h>
      48             : #include <dev/usb/usbdi_util.h>
      49             : #include <dev/usb/usbdevs.h>
      50             : #include <dev/usb/usb_quirks.h>
      51             : #include <dev/usb/uhidev.h>
      52             : 
      53             : #include <dev/wscons/wsconsio.h>
      54             : #include <dev/wscons/wsmousevar.h>
      55             : 
      56             : #include <dev/hid/hidmsvar.h>
      57             : 
      58             : struct ums_softc {
      59             :         struct uhidev   sc_hdev;
      60             :         struct hidms    sc_ms;
      61             : };
      62             : 
      63             : void ums_intr(struct uhidev *addr, void *ibuf, u_int len);
      64             : 
      65             : int     ums_enable(void *);
      66             : void    ums_disable(void *);
      67             : int     ums_ioctl(void *, u_long, caddr_t, int, struct proc *);
      68             : 
      69             : const struct wsmouse_accessops ums_accessops = {
      70             :         ums_enable,
      71             :         ums_ioctl,
      72             :         ums_disable,
      73             : };
      74             : 
      75             : int ums_match(struct device *, void *, void *);
      76             : void ums_attach(struct device *, struct device *, void *);
      77             : int ums_detach(struct device *, int);
      78             : 
      79             : struct cfdriver ums_cd = {
      80             :         NULL, "ums", DV_DULL
      81             : };
      82             : 
      83             : const struct cfattach ums_ca = {
      84             :         sizeof(struct ums_softc), ums_match, ums_attach, ums_detach
      85             : };
      86             : 
      87             : int
      88           0 : ums_match(struct device *parent, void *match, void *aux)
      89             : {
      90           0 :         struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
      91           0 :         int size;
      92           0 :         void *desc;
      93             : 
      94           0 :         uhidev_get_report_desc(uha->parent, &desc, &size);
      95             : 
      96           0 :         if (hid_is_collection(desc, size, uha->reportid,
      97             :             HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_POINTER)))
      98           0 :                 return (UMATCH_IFACECLASS);
      99             : 
     100           0 :         if (hid_is_collection(desc, size, uha->reportid,
     101             :             HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)))
     102           0 :                 return (UMATCH_IFACECLASS);
     103             : 
     104           0 :         if (hid_is_collection(desc, size, uha->reportid,
     105             :             HID_USAGE2(HUP_DIGITIZERS, HUD_TOUCHSCREEN)))
     106           0 :                 return (UMATCH_IFACECLASS);
     107             : 
     108           0 :         if (hid_is_collection(desc, size, uha->reportid,
     109             :             HID_USAGE2(HUP_DIGITIZERS, HUD_PEN)))
     110           0 :                 return (UMATCH_IFACECLASS);
     111             : 
     112           0 :         return (UMATCH_NONE);
     113           0 : }
     114             : 
     115             : void
     116           0 : ums_attach(struct device *parent, struct device *self, void *aux)
     117             : {
     118           0 :         struct ums_softc *sc = (struct ums_softc *)self;
     119           0 :         struct hidms *ms = &sc->sc_ms;
     120           0 :         struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
     121           0 :         struct usb_attach_arg *uaa = uha->uaa;
     122           0 :         int size, repid;
     123           0 :         void *desc;
     124             :         u_int32_t quirks, qflags = 0;
     125             : 
     126           0 :         sc->sc_hdev.sc_intr = ums_intr;
     127           0 :         sc->sc_hdev.sc_parent = uha->parent;
     128           0 :         sc->sc_hdev.sc_udev = uaa->device;
     129           0 :         sc->sc_hdev.sc_report_id = uha->reportid;
     130             : 
     131           0 :         quirks = usbd_get_quirks(sc->sc_hdev.sc_udev)->uq_flags;
     132           0 :         uhidev_get_report_desc(uha->parent, &desc, &size);
     133           0 :         repid = uha->reportid;
     134           0 :         sc->sc_hdev.sc_isize = hid_report_size(desc, size, hid_input, repid);
     135           0 :         sc->sc_hdev.sc_osize = hid_report_size(desc, size, hid_output, repid);
     136           0 :         sc->sc_hdev.sc_fsize = hid_report_size(desc, size, hid_feature, repid);
     137             : 
     138           0 :         if (quirks & UQ_MS_REVZ)
     139           0 :                 qflags |= HIDMS_REVZ;
     140           0 :         if (quirks & UQ_SPUR_BUT_UP)
     141           0 :                 qflags |= HIDMS_SPUR_BUT_UP;
     142           0 :         if (quirks & UQ_MS_BAD_CLASS)
     143           0 :                 qflags |= HIDMS_MS_BAD_CLASS;
     144           0 :         if (quirks & UQ_MS_LEADING_BYTE)
     145           0 :                 qflags |= HIDMS_LEADINGBYTE;
     146             : 
     147           0 :         if (hidms_setup(self, ms, qflags, uha->reportid, desc, size) != 0)
     148           0 :                 return;
     149             : 
     150             :         /*
     151             :          * The Microsoft Wireless Notebook Optical Mouse 3000 Model 1049 has
     152             :          * five Report IDs: 19, 23, 24, 17, 18 (in the order they appear in
     153             :          * report descriptor), it seems that report 17 contains the necessary
     154             :          * mouse information (3-buttons, X, Y, wheel) so we specify it
     155             :          * manually.
     156             :          */
     157           0 :         if (uaa->vendor == USB_VENDOR_MICROSOFT &&
     158           0 :             uaa->product == USB_PRODUCT_MICROSOFT_WLNOTEBOOK3) {
     159           0 :                 ms->sc_flags = HIDMS_Z;
     160           0 :                 ms->sc_num_buttons = 3;
     161             :                 /* XXX change sc_hdev isize to 5? */
     162           0 :                 ms->sc_loc_x.pos = 8;
     163           0 :                 ms->sc_loc_y.pos = 16;
     164           0 :                 ms->sc_loc_z.pos = 24;
     165           0 :                 ms->sc_loc_btn[0].pos = 0;
     166           0 :                 ms->sc_loc_btn[1].pos = 1;
     167           0 :                 ms->sc_loc_btn[2].pos = 2;
     168           0 :         }
     169             : 
     170           0 :         hidms_attach(ms, &ums_accessops);
     171           0 : }
     172             : 
     173             : int
     174           0 : ums_detach(struct device *self, int flags)
     175             : {
     176           0 :         struct ums_softc *sc = (struct ums_softc *)self;
     177           0 :         struct hidms *ms = &sc->sc_ms;
     178             : 
     179           0 :         return hidms_detach(ms, flags);
     180             : }
     181             : 
     182             : void
     183           0 : ums_intr(struct uhidev *addr, void *buf, u_int len)
     184             : {
     185           0 :         struct ums_softc *sc = (struct ums_softc *)addr;
     186           0 :         struct hidms *ms = &sc->sc_ms;
     187             : 
     188           0 :         if (ms->sc_enabled != 0)
     189           0 :                 hidms_input(ms, (uint8_t *)buf, len);
     190           0 : }
     191             : 
     192             : int
     193           0 : ums_enable(void *v)
     194             : {
     195           0 :         struct ums_softc *sc = v;
     196           0 :         struct hidms *ms = &sc->sc_ms;
     197             :         int rv;
     198             : 
     199           0 :         if (usbd_is_dying(sc->sc_hdev.sc_udev))
     200           0 :                 return EIO;
     201             : 
     202           0 :         if ((rv = hidms_enable(ms)) != 0)
     203           0 :                 return rv;
     204             : 
     205           0 :         return uhidev_open(&sc->sc_hdev);
     206           0 : }
     207             : 
     208             : void
     209           0 : ums_disable(void *v)
     210             : {
     211           0 :         struct ums_softc *sc = v;
     212           0 :         struct hidms *ms = &sc->sc_ms;
     213             : 
     214           0 :         hidms_disable(ms);
     215           0 :         uhidev_close(&sc->sc_hdev);
     216           0 : }
     217             : 
     218             : int
     219           0 : ums_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
     220             : {
     221           0 :         struct ums_softc *sc = v;
     222           0 :         struct hidms *ms = &sc->sc_ms;
     223             :         int rc;
     224             : 
     225           0 :         rc = uhidev_ioctl(&sc->sc_hdev, cmd, data, flag, p);
     226           0 :         if (rc != -1)
     227           0 :                 return rc;
     228           0 :         rc = hidms_ioctl(ms, cmd, data, flag, p);
     229           0 :         if (rc != -1)
     230           0 :                 return rc;
     231             : 
     232           0 :         switch (cmd) {
     233             :         case WSMOUSEIO_GTYPE:
     234           0 :                 *(u_int *)data = WSMOUSE_TYPE_USB;
     235           0 :                 return 0;
     236             :         default:
     237           0 :                 return -1;
     238             :         }
     239           0 : }

Generated by: LCOV version 1.13