summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/uhid.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/uhid.c')
-rw-r--r--sys/dev/usb/uhid.c229
1 files changed, 68 insertions, 161 deletions
diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c
index a74f124..06d1c75 100644
--- a/sys/dev/usb/uhid.c
+++ b/sys/dev/usb/uhid.c
@@ -1,12 +1,13 @@
-/* $NetBSD: uhid.c,v 1.3 1998/08/01 20:52:45 augustss Exp $ */
+/* $NetBSD: uhid.c,v 1.12 1998/12/26 12:53:02 augustss Exp $ */
/* FreeBSD $Id$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
- * Author: Lennart Augustsson <augustss@carlstedt.se>
- * Carlstedt Research & Technology
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (augustss@carlstedt.se) at
+ * Carlstedt Research & Technology.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,7 +38,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <dev/usb/usb_port.h>
#include <sys/param.h>
#include <sys/systm.h>
@@ -51,6 +51,7 @@
#include <sys/filio.h>
#include <sys/module.h>
#include <sys/bus.h>
+#include <sys/ioccom.h>
#endif
#include <sys/tty.h>
#include <sys/file.h>
@@ -64,7 +65,6 @@
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbdivar.h>
#include <dev/usb/hid.h>
#include <dev/usb/usb_quirks.h>
@@ -78,7 +78,7 @@ int uhiddebug = 0;
#endif
struct uhid_softc {
- bdevice sc_dev; /* base device */
+ bdevice sc_dev; /* base device */
usbd_interface_handle sc_iface; /* interface */
usbd_pipe_handle sc_intrpipe; /* interrupt pipe */
int sc_ep_addr;
@@ -100,7 +100,7 @@ struct uhid_softc {
struct selinfo sc_rsel;
u_char sc_state; /* driver state */
#define UHID_OPEN 0x01 /* device is open */
-#define UHID_ASLP 0x02 /* waiting for mouse data */
+#define UHID_ASLP 0x02 /* waiting for device data */
#define UHID_NEEDCLEAR 0x04 /* needs clearing endpoint stall */
#define UHID_IMMED 0x08 /* return read data immediately */
int sc_disconnected; /* device is gone */
@@ -110,14 +110,6 @@ struct uhid_softc {
#define UHID_CHUNK 128 /* chunk size for read */
#define UHID_BSIZE 1020 /* buffer size */
-#if defined(__NetBSD__)
-int uhid_match __P((struct device *, struct cfdata *, void *));
-void uhid_attach __P((struct device *, struct device *, void *));
-#elif defined(__FreeBSD__)
-static device_probe_t uhid_match;
-static device_attach_t uhid_attach;
-#endif
-
int uhidopen __P((dev_t, int, int, struct proc *));
int uhidclose __P((dev_t, int, int, struct proc *p));
int uhidread __P((dev_t, struct uio *uio, int));
@@ -127,45 +119,11 @@ int uhidpoll __P((dev_t, int, struct proc *));
void uhid_intr __P((usbd_request_handle, usbd_private_handle, usbd_status));
void uhid_disco __P((void *));
-#if defined(__NetBSD__)
-extern struct cfdriver uhid_cd;
-
-struct cfattach uhid_ca = {
- sizeof(struct uhid_softc), uhid_match, uhid_attach
-};
-#elif defined(__FreeBSD__)
+USB_DECLARE_DRIVER(uhid);
-static devclass_t uhid_devclass;
-
-static device_method_t uhid_methods[] = {
- DEVMETHOD(device_probe, uhid_match),
- DEVMETHOD(device_attach, uhid_attach),
- {0,0}
-};
-
-static driver_t uhid_driver = {
- "uhid",
- uhid_methods,
- DRIVER_TYPE_MISC,
- sizeof(struct uhid_softc)
-};
-#endif
-
-
-#if defined(__NetBSD__)
-int
-uhid_match(parent, match, aux)
- struct device *parent;
- struct cfdata *match;
- void *aux;
+USB_MATCH(uhid)
{
- struct usb_attach_arg *uaa = aux;
-#elif defined(__FreeBSD__)
-static int
-uhid_match(device_t device)
-{
- struct usb_attach_arg *uaa = device_get_ivars(device);
-#endif
+ USB_MATCH_START(uhid, uaa);
usb_interface_descriptor_t *id;
if (!uaa->iface)
@@ -176,22 +134,9 @@ uhid_match(device_t device)
return (UMATCH_IFACECLASS_GENERIC);
}
-#if defined(__NetBSD__)
-void
-uhid_attach(parent, self, aux)
- struct device *parent;
- struct device *self;
- void *aux;
+USB_ATTACH(uhid)
{
- struct uhid_softc *sc = (struct uhid_softc *)self;
- struct usb_attach_arg *uaa = aux;
-#elif defined(__FreeBSD__)
-static int
-uhid_attach(device_t self)
-{
- struct uhid_softc *sc = device_get_softc(self);
- struct usb_attach_arg *uaa = device_get_ivars(self);
-#endif
+ USB_ATTACH_START(uhid, sc, uaa);
usbd_interface_handle iface = uaa->iface;
usb_interface_descriptor_t *id;
usb_endpoint_descriptor_t *ed;
@@ -204,31 +149,30 @@ uhid_attach(device_t self)
sc->sc_iface = iface;
id = usbd_get_interface_descriptor(iface);
usbd_devinfo(uaa->device, 0, devinfo);
-#if defined(__FreeBSD__)
- usb_device_set_desc(self, devinfo);
- printf("%s%d", device_get_name(self), device_get_unit(self));
-#endif
- printf(": %s (interface class %d/%d)\n", devinfo,
- id->bInterfaceClass, id->bInterfaceSubClass);
- sc->sc_dev = self;
+ USB_ATTACH_SETUP;
+ printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev),
+ devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
ed = usbd_interface2endpoint_descriptor(iface, 0);
if (!ed) {
- DEVICE_ERROR(sc->sc_dev, ("could not read endpoint descriptor\n"));
- ATTACH_ERROR_RETURN;
+ printf("%s: could not read endpoint descriptor\n",
+ USBDEVNAME(sc->sc_dev));
+ USB_ATTACH_ERROR_RETURN;
}
- DPRINTFN(10,("uhid_attach: \
-bLength=%d bDescriptorType=%d bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d bInterval=%d\n",
- ed->bLength, ed->bDescriptorType, ed->bEndpointAddress & UE_ADDR,
- ed->bEndpointAddress & UE_IN ? "in" : "out",
- ed->bmAttributes & UE_XFERTYPE,
- UGETW(ed->wMaxPacketSize), ed->bInterval));
+ DPRINTFN(10,("uhid_attach: bLength=%d bDescriptorType=%d "
+ "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d"
+ " bInterval=%d\n",
+ ed->bLength, ed->bDescriptorType,
+ ed->bEndpointAddress & UE_ADDR,
+ ed->bEndpointAddress & UE_IN ? "in" : "out",
+ ed->bmAttributes & UE_XFERTYPE,
+ UGETW(ed->wMaxPacketSize), ed->bInterval));
if ((ed->bEndpointAddress & UE_IN) != UE_IN ||
(ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
- DEVICE_ERROR(sc->sc_dev, ("unexpected endpoint\n"));
- ATTACH_ERROR_RETURN;
+ printf("%s: unexpected endpoint\n", USBDEVNAME(sc->sc_dev));
+ USB_ATTACH_ERROR_RETURN;
}
sc->sc_ep_addr = ed->bEndpointAddress;
@@ -236,8 +180,8 @@ bLength=%d bDescriptorType=%d bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketS
r = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_USB);
if (r != USBD_NORMAL_COMPLETION) {
- DEVICE_ERROR(sc->sc_dev, ("no report descriptor\n"));
- ATTACH_ERROR_RETURN;
+ printf("%s: no report descriptor\n", USBDEVNAME(sc->sc_dev));
+ USB_ATTACH_ERROR_RETURN;
}
(void)usbd_set_idle(iface, 0, 0);
@@ -249,9 +193,24 @@ bLength=%d bDescriptorType=%d bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketS
sc->sc_repdesc = desc;
sc->sc_repdesc_size = size;
- ATTACH_SUCCESS_RETURN;
+ USB_ATTACH_SUCCESS_RETURN;
}
+#if defined(__FreeBSD__)
+static int
+uhid_detach(device_t self)
+{
+ struct uhid_softc *sc = device_get_softc(self);
+ char *devinfo = (char *) device_get_desc(self);
+
+ if (devinfo) {
+ device_set_desc(self, NULL);
+ free(devinfo, M_USB);
+ }
+ return 0;
+}
+#endif
+
void
uhid_disco(p)
void *p;
@@ -302,18 +261,10 @@ uhidopen(dev, flag, mode, p)
struct proc *p;
{
usbd_status r;
-#if defined(__NetBSD__)
- struct uhid_softc *sc;
- int unit = UHIDUNIT(dev);
+ USB_GET_SC_OPEN(uhid, UHIDUNIT(dev), sc);
- if (unit >= uhid_cd.cd_ndevs)
- return ENXIO;
- sc = uhid_cd.cd_devs[unit];
-#elif defined(__FreeBSD__)
- struct uhid_softc *sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
-#endif
if (!sc)
- return ENXIO;
+ return (ENXIO);
DPRINTF(("uhidopen: sc=%p, disco=%d\n", sc, sc->sc_disconnected));
@@ -321,11 +272,11 @@ uhidopen(dev, flag, mode, p)
return (EIO);
if (sc->sc_state & UHID_OPEN)
- return EBUSY;
+ return (EBUSY);
#if defined(__NetBSD__)
if (clalloc(&sc->sc_q, UHID_BSIZE, 0) == -1)
- return ENOMEM;
+ return (ENOMEM);
#elif defined(__FreeBSD__)
clist_alloc_cblocks(&sc->sc_q, UHID_BSIZE, 0);
#endif
@@ -342,13 +293,14 @@ uhidopen(dev, flag, mode, p)
&sc->sc_intrpipe, sc, sc->sc_ibuf,
sc->sc_isize, uhid_intr);
if (r != USBD_NORMAL_COMPLETION) {
- DPRINTF(("uhidopen: usbd_open_pipe_intr failed, error=%d\n",r));
+ DPRINTF(("uhidopen: usbd_open_pipe_intr failed, "
+ "error=%d\n",r));
sc->sc_state &= ~UHID_OPEN;
return (EIO);
}
usbd_set_disco(sc->sc_intrpipe, uhid_disco, sc);
- return 0;
+ return (0);
}
int
@@ -358,16 +310,7 @@ uhidclose(dev, flag, mode, p)
int mode;
struct proc *p;
{
-#if defined(__NetBSD__)
- struct uhid_softc *sc;
- int unit = UHIDUNIT(dev);
-
- if (unit >= uhid_cd.cd_ndevs)
- return ENXIO;
- sc = uhid_cd.cd_devs[unit];
-#elif defined(__FreeBSD__)
- struct uhid_softc *sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
-#endif
+ USB_GET_SC(uhid, UHIDUNIT(dev), sc);
if (sc->sc_disconnected)
return (EIO);
@@ -389,7 +332,7 @@ uhidclose(dev, flag, mode, p)
free(sc->sc_ibuf, M_USB);
free(sc->sc_obuf, M_USB);
- return 0;
+ return (0);
}
int
@@ -403,16 +346,7 @@ uhidread(dev, uio, flag)
size_t length;
u_char buffer[UHID_CHUNK];
usbd_status r;
-#if defined(__NetBSD__)
- struct uhid_softc *sc;
- int unit = UHIDUNIT(dev);
-
- if (unit >= uhid_cd.cd_ndevs)
- return ENXIO;
- sc = uhid_cd.cd_devs[unit];
-#elif defined(__FreeBSD__)
- struct uhid_softc *sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
-#endif
+ USB_GET_SC(uhid, UHIDUNIT(dev), sc);
if (sc->sc_disconnected)
return (EIO);
@@ -428,7 +362,7 @@ uhidread(dev, uio, flag)
return (uiomove(buffer, sc->sc_isize, uio));
}
- s = spltty();
+ s = splusb();
while (sc->sc_q.c_cc == 0) {
if (flag & IO_NDELAY) {
splx(s);
@@ -478,16 +412,7 @@ uhidwrite(dev, uio, flag)
int error;
int size;
usbd_status r;
-#if defined(__NetBSD__)
- struct uhid_softc *sc;
- int unit = UHIDUNIT(dev);
-
- if (unit >= uhid_cd.cd_ndevs)
- return ENXIO;
- sc = uhid_cd.cd_devs[unit];
-#elif defined(__FreeBSD__)
- struct uhid_softc *sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
-#endif
+ USB_GET_SC(uhid, UHIDUNIT(dev), sc);
if (sc->sc_disconnected)
return (EIO);
@@ -528,16 +453,7 @@ uhidioctl(dev, cmd, addr, flag, p)
struct usb_ctl_report *re;
int size, id;
usbd_status r;
-#if defined(__NetBSD__)
- struct uhid_softc *sc;
- int unit = UHIDUNIT(dev);
-
- if (unit >= uhid_cd.cd_ndevs)
- return ENXIO;
- sc = uhid_cd.cd_devs[unit];
-#elif defined(__FreeBSD__)
- struct uhid_softc *sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
-#endif
+ USB_GET_SC(uhid, UHIDUNIT(dev), sc);
if (sc->sc_disconnected)
return (EIO);
@@ -557,12 +473,12 @@ uhidioctl(dev, cmd, addr, flag, p)
case USB_SET_IMMED:
if (*(int *)addr) {
- /* XXX should read into ibuf, but does it matter */
- r = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
- sc->sc_iid, sc->sc_ibuf,
- sc->sc_isize);
- if (r != USBD_NORMAL_COMPLETION)
- return (EOPNOTSUPP);
+ /* XXX should read into ibuf, but does it matter */
+ r = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
+ sc->sc_iid, sc->sc_ibuf,
+ sc->sc_isize);
+ if (r != USBD_NORMAL_COMPLETION)
+ return (EOPNOTSUPP);
sc->sc_state |= UHID_IMMED;
} else
@@ -607,21 +523,12 @@ uhidpoll(dev, events, p)
{
int revents = 0;
int s;
-#if defined(__NetBSD__)
- struct uhid_softc *sc;
- int unit = UHIDUNIT(dev);
-
- if (unit >= uhid_cd.cd_ndevs)
- return ENXIO;
- sc = uhid_cd.cd_devs[unit];
-#elif defined(__FreeBSD__)
- struct uhid_softc *sc = devclass_get_softc(uhid_devclass, UHIDUNIT(dev));
-#endif
+ USB_GET_SC(uhid, UHIDUNIT(dev), sc);
if (sc->sc_disconnected)
return (EIO);
- s = spltty();
+ s = splusb();
if (events & (POLLOUT | POLLWRNORM))
revents |= events & (POLLOUT | POLLWRNORM);
if (events & (POLLIN | POLLRDNORM)) {
@@ -636,5 +543,5 @@ uhidpoll(dev, events, p)
}
#if defined(__FreeBSD__)
-DRIVER_MODULE(uhid, usb, uhid_driver, uhid_devclass, usb_driver_load, 0);
+DRIVER_MODULE(uhid, usb, uhid_driver, uhid_devclass, usbd_driver_load, 0);
#endif
OpenPOWER on IntegriCloud