summaryrefslogtreecommitdiff
path: root/sys/dev/usb/uhid.c
diff options
context:
space:
mode:
authorAaron Campbell <aaron@cvs.openbsd.org>2000-03-26 08:39:47 +0000
committerAaron Campbell <aaron@cvs.openbsd.org>2000-03-26 08:39:47 +0000
commit28320e899fbfbbe660f759f96511b4ed754a9a0b (patch)
tree789ef853a5b4025e2d189b0a56408bd794bdadbc /sys/dev/usb/uhid.c
parentee37c844b6cad757fe1b782a43e759d2e9570934 (diff)
Sync with NetBSD.
Diffstat (limited to 'sys/dev/usb/uhid.c')
-rw-r--r--sys/dev/usb/uhid.c144
1 files changed, 94 insertions, 50 deletions
diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c
index d0bd5efa5ed..0443d21994a 100644
--- a/sys/dev/usb/uhid.c
+++ b/sys/dev/usb/uhid.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uhid.c,v 1.6 1999/11/07 21:30:19 fgsch Exp $ */
-/* $NetBSD: uhid.c,v 1.26 1999/10/13 08:10:56 augustss Exp $ */
+/* $OpenBSD: uhid.c,v 1.7 2000/03/26 08:39:46 aaron Exp $ */
+/* $NetBSD: uhid.c,v 1.35 2000/03/19 22:23:28 augustss Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -83,6 +83,7 @@ int uhiddebug = 0;
struct uhid_softc {
USBBASEDEVICE sc_dev; /* base device */
+ usbd_device_handle sc_udev;
usbd_interface_handle sc_iface; /* interface */
usbd_pipe_handle sc_intrpipe; /* interrupt pipe */
int sc_ep_addr;
@@ -94,8 +95,8 @@ struct uhid_softc {
u_int8_t sc_oid;
u_int8_t sc_fid;
- char *sc_ibuf;
- char *sc_obuf;
+ u_char *sc_ibuf;
+ u_char *sc_obuf;
void *sc_repdesc;
int sc_repdesc_size;
@@ -146,7 +147,7 @@ static struct cdevsw uhid_cdevsw = {
};
#endif
-void uhid_intr __P((usbd_request_handle, usbd_private_handle, usbd_status));
+void uhid_intr __P((usbd_xfer_handle, usbd_private_handle, usbd_status));
int uhid_do_read __P((struct uhid_softc *, struct uio *uio, int));
int uhid_do_write __P((struct uhid_softc *, struct uio *uio, int));
@@ -159,10 +160,10 @@ USB_MATCH(uhid)
USB_MATCH_START(uhid, uaa);
usb_interface_descriptor_t *id;
- if (!uaa->iface)
+ if (uaa->iface == NULL)
return (UMATCH_NONE);
id = usbd_get_interface_descriptor(uaa->iface);
- if (!id || id->bInterfaceClass != UCLASS_HID)
+ if (id == NULL || id->bInterfaceClass != UICLASS_HID)
return (UMATCH_NONE);
return (UMATCH_IFACECLASS_GENERIC);
}
@@ -175,9 +176,10 @@ USB_ATTACH(uhid)
usb_endpoint_descriptor_t *ed;
int size;
void *desc;
- usbd_status r;
+ usbd_status err;
char devinfo[1024];
-
+
+ sc->sc_udev = uaa->device;
sc->sc_iface = iface;
id = usbd_get_interface_descriptor(iface);
usbd_devinfo(uaa->device, 0, devinfo);
@@ -186,7 +188,7 @@ USB_ATTACH(uhid)
devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
ed = usbd_interface2endpoint_descriptor(iface, 0);
- if (!ed) {
+ if (ed == NULL) {
printf("%s: could not read endpoint descriptor\n",
USBDEVNAME(sc->sc_dev));
sc->sc_dying = 1;
@@ -212,12 +214,10 @@ USB_ATTACH(uhid)
sc->sc_ep_addr = ed->bEndpointAddress;
desc = 0;
- r = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_USBDEV);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_USBDEV);
+ if (err) {
printf("%s: no report descriptor\n", USBDEVNAME(sc->sc_dev));
sc->sc_dying = 1;
- if (desc)
- free(desc, M_USBDEV);
USB_ATTACH_ERROR_RETURN;
}
@@ -230,6 +230,20 @@ USB_ATTACH(uhid)
sc->sc_repdesc = desc;
sc->sc_repdesc_size = size;
+#ifdef __FreeBSD__
+ {
+ static int global_init_done = 0;
+
+ if (!global_init_done) {
+ cdevsw_add(&uhid_cdevsw);
+ global_init_done = 1;
+ }
+ }
+#endif
+
+ usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
+ USBDEV(sc->sc_dev));
+
USB_ATTACH_SUCCESS_RETURN;
}
@@ -267,7 +281,7 @@ USB_DETACH(uhid)
#endif
sc->sc_dying = 1;
- if (sc->sc_intrpipe)
+ if (sc->sc_intrpipe != NULL)
usbd_abort_pipe(sc->sc_intrpipe);
if (sc->sc_state & UHID_OPEN) {
@@ -296,20 +310,32 @@ USB_DETACH(uhid)
free(sc->sc_repdesc, M_USBDEV);
+ usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
+ USBDEV(sc->sc_dev));
+
return (0);
}
void
-uhid_intr(reqh, addr, status)
- usbd_request_handle reqh;
+uhid_intr(xfer, addr, status)
+ usbd_xfer_handle xfer;
usbd_private_handle addr;
usbd_status status;
{
struct uhid_softc *sc = addr;
- DPRINTFN(5, ("uhid_intr: status=%d\n", status));
- DPRINTFN(5, ("uhid_intr: data = %02x %02x %02x\n",
- sc->sc_ibuf[0], sc->sc_ibuf[1], sc->sc_ibuf[2]));
+#ifdef UHID_DEBUG
+ if (uhiddebug > 5) {
+ u_int32_t cc, i;
+
+ usbd_get_xfer_status(xfer, NULL, NULL, &cc, NULL);
+ DPRINTF(("uhid_intr: status=%d cc=%d\n", status, cc));
+ DPRINTF(("uhid_intr: data="));
+ for (i = 0; i < cc; i++)
+ DPRINTF((" %02x", sc->sc_ibuf[i]));
+ DPRINTF(("\n"));
+ }
+#endif
if (status == USBD_CANCELLED)
return;
@@ -338,7 +364,7 @@ uhidopen(dev, flag, mode, p)
struct proc *p;
{
struct uhid_softc *sc;
- usbd_status r;
+ usbd_status err;
USB_GET_SC_OPEN(uhid, UHIDUNIT(dev), sc);
@@ -360,13 +386,12 @@ uhidopen(dev, flag, mode, p)
sc->sc_obuf = malloc(sc->sc_osize, M_USBDEV, M_WAITOK);
/* Set up interrupt pipe. */
- r = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
- USBD_SHORT_XFER_OK,
- &sc->sc_intrpipe, sc, sc->sc_ibuf,
- sc->sc_isize, uhid_intr);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
+ USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc, sc->sc_ibuf,
+ sc->sc_isize, uhid_intr, USBD_DEFAULT_INTERVAL);
+ if (err) {
DPRINTF(("uhidopen: usbd_open_pipe_intr failed, "
- "error=%d\n",r));
+ "error=%d\n",err));
free(sc->sc_ibuf, M_USBDEV);
free(sc->sc_obuf, M_USBDEV);
sc->sc_state &= ~UHID_OPEN;
@@ -416,15 +441,15 @@ uhid_do_read(sc, uio, flag)
int error = 0;
size_t length;
u_char buffer[UHID_CHUNK];
- usbd_status r;
+ usbd_status err;
DPRINTFN(1, ("uhidread\n"));
if (sc->sc_state & UHID_IMMED) {
DPRINTFN(1, ("uhidread immed\n"));
- r = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
+ err = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
sc->sc_iid, buffer, sc->sc_isize);
- if (r != USBD_NORMAL_COMPLETION)
+ if (err)
return (EIO);
return (uiomove(buffer, sc->sc_isize, uio));
}
@@ -461,7 +486,7 @@ uhid_do_read(sc, uio, flag)
/* Remove a small chunk from the input queue. */
(void) q_to_b(&sc->sc_q, buffer, length);
- DPRINTFN(5, ("uhidread: got %d chars\n", length));
+ DPRINTFN(5, ("uhidread: got %lu chars\n", (u_long)length));
/* Copy the data to the user process. */
if ((error = uiomove(buffer, length, uio)) != 0)
@@ -497,7 +522,7 @@ uhid_do_write(sc, uio, flag)
{
int error;
int size;
- usbd_status r;
+ usbd_status err;
DPRINTFN(1, ("uhidwrite\n"));
@@ -511,15 +536,13 @@ uhid_do_write(sc, uio, flag)
error = uiomove(sc->sc_obuf, size, uio);
if (!error) {
if (sc->sc_oid)
- r = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
- sc->sc_obuf[0],
- sc->sc_obuf+1, size-1);
+ err = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
+ sc->sc_obuf[0], sc->sc_obuf+1, size-1);
else
- r = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
- 0, sc->sc_obuf, size);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
+ 0, sc->sc_obuf, size);
+ if (err)
error = EIO;
- }
}
return (error);
@@ -554,7 +577,7 @@ uhid_do_ioctl(sc, cmd, addr, flag, p)
struct usb_ctl_report_desc *rd;
struct usb_ctl_report *re;
int size, id;
- usbd_status r;
+ usbd_status err;
DPRINTFN(2, ("uhidioctl: cmd=%lx\n", cmd));
@@ -575,11 +598,10 @@ uhid_do_ioctl(sc, 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)
+ /* XXX should read into ibuf, but does it matter? */
+ err = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
+ sc->sc_iid, sc->sc_ibuf, sc->sc_isize);
+ if (err)
return (EOPNOTSUPP);
sc->sc_state |= UHID_IMMED;
@@ -605,9 +627,32 @@ uhid_do_ioctl(sc, cmd, addr, flag, p)
default:
return (EINVAL);
}
- r = usbd_get_report(sc->sc_iface, re->report, id,
- re->data, size);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_get_report(sc->sc_iface, re->report, id, re->data,
+ size);
+ if (err)
+ return (EIO);
+ break;
+ case USB_SET_REPORT:
+ re = (struct usb_ctl_report *)addr;
+ switch (re->report) {
+ case UHID_INPUT_REPORT:
+ size = sc->sc_isize;
+ id = sc->sc_iid;
+ break;
+ case UHID_OUTPUT_REPORT:
+ size = sc->sc_osize;
+ id = sc->sc_oid;
+ break;
+ case UHID_FEATURE_REPORT:
+ size = sc->sc_fsize;
+ id = sc->sc_fid;
+ break;
+ default:
+ return (EINVAL);
+ }
+ err = usbd_set_report(sc->sc_iface, re->report, id, re->data,
+ size);
+ if (err)
return (EIO);
break;
@@ -667,6 +712,5 @@ uhidpoll(dev, events, p)
}
#if defined(__FreeBSD__)
-DEV_DRIVER_MODULE(uhid, uhub, uhid_driver, uhid_devclass,
- uhid_cdevsw, usbd_driver_load, 0);
+DRIVER_MODULE(uhid, uhub, uhid_driver, uhid_devclass, usbd_driver_load, 0);
#endif