summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/alpha/conf/GENERIC13
-rw-r--r--sys/arch/i386/conf/GENERIC11
-rw-r--r--sys/arch/macppc/conf/GENERIC9
-rw-r--r--sys/arch/sparc64/conf/GENERIC13
-rw-r--r--sys/dev/usb/files.usb43
-rw-r--r--sys/dev/usb/hid.c143
-rw-r--r--sys/dev/usb/hid.h21
-rw-r--r--sys/dev/usb/uhid.c349
-rw-r--r--sys/dev/usb/uhidev.c513
-rw-r--r--sys/dev/usb/uhidev.h91
-rw-r--r--sys/dev/usb/ukbd.c492
-rw-r--r--sys/dev/usb/ums.c197
-rw-r--r--sys/dev/usb/usb.h3
-rw-r--r--sys/dev/usb/usb_port.h5
-rw-r--r--sys/dev/usb/usbhid.h19
15 files changed, 1146 insertions, 776 deletions
diff --git a/sys/arch/alpha/conf/GENERIC b/sys/arch/alpha/conf/GENERIC
index 0554e38ec4d..dbb5409547f 100644
--- a/sys/arch/alpha/conf/GENERIC
+++ b/sys/arch/alpha/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.106 2002/05/02 22:56:06 miod Exp $
+# $OpenBSD: GENERIC,v 1.107 2002/05/09 15:06:29 nate Exp $
# $NetBSD: GENERIC,v 1.31 1996/12/03 17:25:29 cgd Exp $
machine alpha
@@ -53,7 +53,12 @@ usb* at ohci?
uhub* at usb? # USB Hubs
uhub* at uhub? port ? configuration ? # USB Hubs
-uhid* at uhub? port ? configuration ? # USB Generic HID devices
+uhidev* at uhub? port ? configuration ? interface ?
+ums* at uhidev? reportid ? # USB Mice
+wsmouse* at ums? mux 0
+ukbd* at uhidev? reportid ? # USB Keyboards
+wskbd* at ukbd? console ? mux 1
+uhid* at uhidev? reportid ? # USB Generic HID devices
umodem* at uhub? port ? configuration ? # USB Modems/Serial
ucom* at umodem?
uvisor* at uhub? port ? configuration ? # Handspring Visor
@@ -62,12 +67,8 @@ uftdi* at uhub? port ?
ucom* at uftdi? portno ?
uaudio* at uhub? port ? configuration ? # USB Audio
ulpt* at uhub? port ? configuration ? # USB Printers
-ukbd* at uhub? port ? configuration ? # USB Keyboards
-wskbd* at ukbd? console ?
umass* at uhub? port ? configuration ? # USB Mass Storage devices
scsibus* at umass?
-ums* at uhub? port ? configuration ? # USB Mice
-wsmouse* at ums?
aue* at uhub? port ? # ADMtek AN986 Pegasus Ethernet
cue* at uhub? port ? # CATC USB-EL1201A based Ethernet
kue* at uhub? port ? # Kawasaki KL5KUSB101B based Ethernet
diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC
index a4c67416c0f..7fd663c9d9e 100644
--- a/sys/arch/i386/conf/GENERIC
+++ b/sys/arch/i386/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.297 2002/05/07 19:42:34 nate Exp $
+# $OpenBSD: GENERIC,v 1.298 2002/05/09 15:06:29 nate Exp $
# $NetBSD: GENERIC,v 1.48 1996/05/20 18:17:23 mrg Exp $
#
# GENERIC -- everything that's currently supported
@@ -91,7 +91,6 @@ usb* at ohci?
uhub* at usb? # USB Hubs
uhub* at uhub? port ? configuration ? # USB Hubs
-uhid* at uhub? port ? configuration ? # USB Generic HID devices
umodem* at uhub? port ? configuration ? # USB Modems/Serial
ucom* at umodem?
uvisor* at uhub? port ? configuration ? # Handspring Visor
@@ -103,12 +102,14 @@ ucom* at uplcom? portno ?
uaudio* at uhub? port ? configuration ? # USB Audio
ulpt* at uhub? port ? configuration ? # USB Printers
-ukbd* at uhub? port ? configuration ? # USB Keyboards
-wskbd* at ukbd? console ? mux 1
umass* at uhub? port ? configuration ? # USB Mass Storage devices
scsibus* at umass?
-ums* at uhub? port ? configuration ? # USB Mice
+uhidev* at uhub? port ? configuration ? interface ?
+ums* at uhidev? reportid ?
wsmouse* at ums? mux 0
+ukbd* at uhidev? reportid ?
+wskbd* at ukbd? console ? mux 1
+uhid* at uhidev? reportid ?
aue* at uhub? port ? # ADMtek AN986 Pegasus Ethernet
cue* at uhub? port ? # CATC USB-EL1201A based Ethernet
kue* at uhub? port ? # Kawasaki KL5KUSB101B based Ethernet
diff --git a/sys/arch/macppc/conf/GENERIC b/sys/arch/macppc/conf/GENERIC
index 7febcd75f87..13c4cce8b0b 100644
--- a/sys/arch/macppc/conf/GENERIC
+++ b/sys/arch/macppc/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.22 2002/04/08 17:02:44 drahn Exp $g
+# $OpenBSD: GENERIC,v 1.23 2002/05/09 15:06:29 nate Exp $g
#
# PPC GENERIC config file
#
@@ -143,9 +143,10 @@ usb* at ohci? flags 0x1
uhub* at usb?
uhub* at uhub? port ? configuration ? interface ?
-uhid* at uhub? port ? configuration ? # USB Generic HID devices
-ukbd* at uhub? port ? configuration ? # USB HID Keyboard devices
-ums* at uhub? port ? configuration ? # USB Mice
+uhidev* at uhub? port ? configuration ? interface ?
+uhid* at uhidev? reportid ? # USB Generic HID devices
+ukbd* at uhidev? reportid ? # USB HID Keyboard devices
+ums* at uhidev? reportid ? # USB Mice
wsmouse* at ums? mux 0
uaudio* at uhub? port ? configuration ? # USB Audio
ulpt* at uhub? port ? configuration ? # USB Printer
diff --git a/sys/arch/sparc64/conf/GENERIC b/sys/arch/sparc64/conf/GENERIC
index 8ace8ace53d..253578f0bcf 100644
--- a/sys/arch/sparc64/conf/GENERIC
+++ b/sys/arch/sparc64/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.58 2002/04/18 14:15:11 jason Exp $
+# $OpenBSD: GENERIC,v 1.59 2002/05/09 15:06:29 nate Exp $
# $NetBSD: GENERIC32,v 1.18 2001/07/20 00:07:12 eeh Exp $
machine sparc64
@@ -60,11 +60,12 @@ usb* at ohci? flags 0x1
# USB devices
uhub* at usb?
uhub* at uhub? port ? configuration ?
-ukbd* at uhub? # USB keyboard
-wskbd* at ukbd? console ?
-ums* at uhub? port ? configuration ? # USB mouse
-wsmouse* at ums?
-uhid* at uhub? port ? configuration ? # USB generic human interface
+uhidev* at uhub? port ? configuration ? interface ?
+ukbd* at uhidev? reportid ?
+wskbd* at ukbd? console ? mux 1
+ums* at uhidev? reportid ?
+wsmouse* at ums? mux 0
+uhid* at uhidev? reportid ?
ugen* at uhub? port ? configuration ? # USB generic device
#### Standard system devices -- all required for a given architecture
diff --git a/sys/dev/usb/files.usb b/sys/dev/usb/files.usb
index 5936f8fc971..f5fd7406e34 100644
--- a/sys/dev/usb/files.usb
+++ b/sys/dev/usb/files.usb
@@ -1,4 +1,4 @@
-# $OpenBSD: files.usb,v 1.24 2002/05/07 19:32:49 nate Exp $
+# $OpenBSD: files.usb,v 1.25 2002/05/09 15:06:29 nate Exp $
# $NetBSD: files.usb,v 1.16 2000/02/14 20:29:54 augustss Exp $
#
# Config file and device description for machine-independent USB code.
@@ -7,7 +7,6 @@
device usb { }
attach usb at usbus
-file dev/usb/hid.c usb
file dev/usb/usb.c usb needs-flag
file dev/usb/usbdi.c usb
file dev/usb/usbdi_util.c usb
@@ -45,16 +44,35 @@ device ugen
attach ugen at uhub
file dev/usb/ugen.c ugen needs-flag
-# Generic HID devices
-device uhid
-attach uhid at uhub
-file dev/usb/uhid.c uhid needs-flag
+# HID
+# HID "bus"
+define uhidbus {[ reportid = -1 ]}
+
+# HID processing
+define hid
+file dev/usb/hid.c hid
+# HID root device for multiple report IDs
+device uhidev: hid, uhidbus
+attach uhidev at uhub
+file dev/usb/uhidev.c uhidev
+
+# Generic HID devices
+device uhid: hid
+attach uhid at uhidbus
+file dev/usb/uhid.c uhid needs-flag
+
# Keyboards
-device ukbd: wskbddev
-attach ukbd at uhub
-file dev/usb/ukbd.c ukbd needs-flag
-file dev/usb/ukbdmap.c ukbd
+device ukbd: hid, wskbddev
+attach ukbd at uhidbus
+file dev/usb/ukbd.c ukbd needs-flag
+file dev/usb/ukbdmap.c ukbd
+
+# Mice
+device ums: hid, wsmousedev
+attach ums at uhidbus
+file dev/usb/ums.c ums
+
# Printers
device ulpt
@@ -71,11 +89,6 @@ device umodem: ucombus
attach umodem at uhub
file dev/usb/umodem.c umodem
-# Mice
-device ums: wsmousedev
-attach ums at uhub
-file dev/usb/ums.c ums
-
# Diamond Multimedia Rio 500
device urio
attach urio at uhub
diff --git a/sys/dev/usb/hid.c b/sys/dev/usb/hid.c
index d14721fe107..81deacbd866 100644
--- a/sys/dev/usb/hid.c
+++ b/sys/dev/usb/hid.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: hid.c,v 1.11 2002/05/07 18:29:18 nate Exp $ */
-/* $NetBSD: hid.c,v 1.16 2000/06/01 14:28:57 augustss Exp $ */
+/* $OpenBSD: hid.c,v 1.12 2002/05/09 15:06:29 nate Exp $ */
+/* $NetBSD: hid.c,v 1.22 2002/01/12 17:11:03 tsutsui Exp $ */
/* $FreeBSD: src/sys/dev/usb/hid.c,v 1.11 1999/11/17 22:33:39 n_hibma Exp $ */
/*
@@ -51,10 +51,10 @@
#include <dev/usb/hid.h>
-#ifdef UHID_DEBUG
-#define DPRINTF(x) if (usbdebug) logprintf x
-#define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x
-extern int usbdebug;
+#ifdef UHIDEV_DEBUG
+#define DPRINTF(x) if (uhidevdebug) logprintf x
+#define DPRINTFN(n,x) if (uhidevdebug>(n)) logprintf x
+extern int uhidevdebug;
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
@@ -62,7 +62,7 @@ extern int usbdebug;
Static void hid_clear_local(struct hid_item *);
-#define MAXUSAGE 100
+#define MAXUSAGE 256
struct hid_data {
u_char *start;
u_char *end;
@@ -73,13 +73,14 @@ struct hid_data {
int minset;
int multi;
int multimax;
- int kindset;
+ enum hid_kind kind;
};
Static void
hid_clear_local(struct hid_item *c)
{
+ DPRINTFN(5,("hid_clear_local\n"));
c->usage = 0;
c->usage_minimum = 0;
c->usage_maximum = 0;
@@ -93,15 +94,18 @@ hid_clear_local(struct hid_item *c)
}
struct hid_data *
-hid_start_parse(void *d, int len, int kindset)
+hid_start_parse(void *d, int len, enum hid_kind kind)
{
struct hid_data *s;
s = malloc(sizeof *s, M_TEMP, M_WAITOK);
+ if (s == NULL)
+ panic("hid_start_parse");
memset(s, 0, sizeof *s);
+
s->start = s->p = d;
s->end = (char *)d + len;
- s->kindset = kindset;
+ s->kind = kind;
return (s);
}
@@ -128,15 +132,19 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
u_char *p;
struct hid_item *hi;
int i;
+ enum hid_kind retkind;
top:
+ DPRINTFN(5,("hid_get_item: multi=%d multimax=%d\n",
+ s->multi, s->multimax));
if (s->multimax != 0) {
if (s->multi < s->multimax) {
c->usage = s->usages[min(s->multi, s->nu-1)];
s->multi++;
*h = *c;
c->loc.pos += c->loc.size;
- h->next = 0;
+ h->next = NULL;
+ DPRINTFN(5,("return multi\n"));
return (1);
} else {
c->loc.count = s->multimax;
@@ -174,12 +182,12 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
dval = 0;
break;
case 1:
- dval = (int8_t)*data++;
+ dval = /*(int8_t)*/ *data++;
break;
case 2:
dval = *data++;
dval |= *data++ << 8;
- dval = (int16_t)dval;
+ dval = /*(int16_t)*/ dval;
break;
case 4:
dval = *data++;
@@ -192,15 +200,22 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
continue;
}
+ DPRINTFN(5,("hid_get_item: bType=%d bTag=%d dval=%d\n",
+ bType, bTag, dval));
switch (bType) {
case 0: /* Main */
switch (bTag) {
case 8: /* Input */
- if (!(s->kindset & (1 << hid_input)))
+ retkind = hid_input;
+ ret:
+ if (s->kind != retkind) {
+ s->minset = 0;
+ s->nu = 0;
+ hid_clear_local(c);
continue;
- c->kind = hid_input;
+ }
+ c->kind = retkind;
c->flags = dval;
- ret:
if (c->flags & HIO_VARIABLE) {
s->multimax = c->loc.count;
s->multi = 0;
@@ -217,19 +232,18 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
}
goto top;
} else {
+ c->usage = c->_usage_page; /* XXX */
*h = *c;
- h->next = 0;
+ h->next = NULL;
c->loc.pos +=
- c->loc.size * c->loc.count;
- hid_clear_local(c);
+ c->loc.size * c->loc.count;
s->minset = 0;
+ s->nu = 0;
+ hid_clear_local(c);
return (1);
}
case 9: /* Output */
- if (!(s->kindset & (1 << hid_output)))
- continue;
- c->kind = hid_output;
- c->flags = dval;
+ retkind = hid_output;
goto ret;
case 10: /* Collection */
c->kind = hid_collection;
@@ -240,16 +254,12 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
s->nu = 0;
return (1);
case 11: /* Feature */
- if (!(s->kindset & (1 << hid_feature)))
- continue;
- c->kind = hid_feature;
- c->flags = dval;
+ retkind = hid_feature;
goto ret;
case 12: /* End collection */
c->kind = hid_endcollection;
c->collevel--;
*h = *c;
- hid_clear_local(c);
s->nu = 0;
return (1);
default:
@@ -285,6 +295,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
break;
case 8:
c->report_ID = dval;
+ c->loc.pos = 0;
break;
case 9:
c->loc.count = dval;
@@ -367,35 +378,51 @@ hid_get_item(struct hid_data *s, struct hid_item *h)
}
int
-hid_report_size(void *buf, int len, enum hid_kind k, u_int8_t *idp)
+hid_report_size(void *buf, int len, enum hid_kind k, u_int8_t id)
{
struct hid_data *d;
struct hid_item h;
- int size, id;
+ int lo, hi;
- id = 0;
- for (d = hid_start_parse(buf, len, 1<<k); hid_get_item(d, &h); )
- if (h.report_ID != 0)
- id = h.report_ID;
+ h.report_ID = 0;
+ lo = hi = -1;
+ DPRINTFN(2,("hid_report_size: kind=%d id=%d\n", k, id));
+ for (d = hid_start_parse(buf, len, k); hid_get_item(d, &h); ) {
+ DPRINTFN(2,("hid_report_size: item kind=%d id=%d pos=%d "
+ "size=%d count=%d\n",
+ h.kind, h.report_ID, h.loc.pos, h.loc.size,
+ h.loc.count));
+ if (h.report_ID == id && h.kind == k) {
+ if (lo < 0) {
+ lo = h.loc.pos;
+#ifdef DIAGNOSTIC
+ if (lo != 0) {
+ printf("hid_report_size: lo != 0\n");
+ }
+#endif
+ }
+ hi = h.loc.pos + h.loc.size * h.loc.count;
+ DPRINTFN(2,("hid_report_size: lo=%d hi=%d\n", lo, hi));
+ }
+ }
hid_end_parse(d);
- size = h.loc.pos;
- if (id != 0) {
- size += 8;
- *idp = id; /* XXX wrong */
- } else
- *idp = 0;
- return ((size + 7) / 8);
+ return ((hi - lo + 7) / 8);
}
int
-hid_locate(void *desc, int size, u_int32_t u, enum hid_kind k,
+hid_locate(void *desc, int size, u_int32_t u, u_int8_t id, enum hid_kind k,
struct hid_location *loc, u_int32_t *flags)
{
struct hid_data *d;
struct hid_item h;
- for (d = hid_start_parse(desc, size, 1<<k); hid_get_item(d, &h); ) {
- if (h.kind == k && !(h.flags & HIO_CONST) && h.usage == u) {
+ h.report_ID = 0;
+ DPRINTFN(5,("hid_locate: enter usage=0x%x kind=%d id=%d\n", u, k, id));
+ for (d = hid_start_parse(desc, size, k); hid_get_item(d, &h); ) {
+ DPRINTFN(5,("hid_locate: usage=0x%x kind=%d id=%d flags=0x%x\n",
+ h.usage, h.kind, h.report_ID, h.flags));
+ if (h.kind == k && !(h.flags & HIO_CONST) &&
+ h.usage == u && h.report_ID == id) {
if (loc != NULL)
*loc = h.loc;
if (flags != NULL)
@@ -437,19 +464,33 @@ hid_get_data(u_char *buf, struct hid_location *loc)
}
int
-hid_is_collection(void *desc, int size, u_int32_t usage)
+hid_is_collection(void *desc, int size, u_int8_t id, u_int32_t usage)
{
struct hid_data *hd;
struct hid_item hi;
- int err;
+ u_int32_t coll_usage = ~0;
- hd = hid_start_parse(desc, size, hid_input);
+ hd = hid_start_parse(desc, size, hid_none);
if (hd == NULL)
return (0);
- err = hid_get_item(hd, &hi) &&
- hi.kind == hid_collection &&
- hi.usage == usage;
+ DPRINTFN(2,("hid_is_collection: id=%d usage=0x%x\n", id, usage));
+ while (hid_get_item(hd, &hi)) {
+ DPRINTFN(2,("hid_is_collection: kind=%d id=%d usage=0x%x"
+ "(0x%x)\n",
+ hi.kind, hi.report_ID, hi.usage, coll_usage));
+ if (hi.kind == hid_collection &&
+ hi.collection == HCOLL_APPLICATION)
+ coll_usage = hi.usage;
+ if (hi.kind == hid_endcollection &&
+ coll_usage == usage &&
+ hi.report_ID == id) {
+ DPRINTFN(2,("hid_is_collection: found\n"));
+ hid_end_parse(hd);
+ return (1);
+ }
+ }
+ DPRINTFN(2,("hid_is_collection: not found\n"));
hid_end_parse(hd);
- return (err);
+ return (0);
}
diff --git a/sys/dev/usb/hid.h b/sys/dev/usb/hid.h
index 096a34e270f..18dac5988e5 100644
--- a/sys/dev/usb/hid.h
+++ b/sys/dev/usb/hid.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: hid.h,v 1.6 2002/05/07 18:29:18 nate Exp $ */
-/* $NetBSD: hid.h,v 1.6 2000/06/01 14:28:57 augustss Exp $ */
+/* $OpenBSD: hid.h,v 1.7 2002/05/09 15:06:29 nate Exp $ */
+/* $NetBSD: hid.h,v 1.7 2001/12/28 17:32:36 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/hid.h,v 1.7 1999/11/17 22:33:40 n_hibma Exp $ */
/*
@@ -40,7 +40,12 @@
*/
enum hid_kind {
- hid_input, hid_output, hid_feature, hid_collection, hid_endcollection
+ hid_input,
+ hid_output,
+ hid_feature,
+ hid_collection,
+ hid_endcollection,
+ hid_none
};
struct hid_location {
@@ -81,11 +86,11 @@ struct hid_item {
struct hid_item *next;
};
-struct hid_data *hid_start_parse(void *d, int len, int kindset);
+struct hid_data *hid_start_parse(void *d, int len, enum hid_kind kind);
void hid_end_parse(struct hid_data *s);
int hid_get_item(struct hid_data *s, struct hid_item *h);
-int hid_report_size(void *buf, int len, enum hid_kind k, u_int8_t *id);
-int hid_locate(void *desc, int size, u_int32_t usage, enum hid_kind kind,
- struct hid_location *loc, u_int32_t *flags);
+int hid_report_size(void *buf, int len, enum hid_kind k, u_int8_t id);
+int hid_locate(void *desc, int size, u_int32_t usage, u_int8_t id,
+ enum hid_kind kind, struct hid_location *loc, u_int32_t *flags);
u_long hid_get_data(u_char *buf, struct hid_location *loc);
-int hid_is_collection(void *desc, int size, u_int32_t usage);
+int hid_is_collection(void *desc, int size, u_int8_t id, u_int32_t usage);
diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c
index 968af28c593..146a6ad44c7 100644
--- a/sys/dev/usb/uhid.c
+++ b/sys/dev/usb/uhid.c
@@ -1,6 +1,5 @@
-/* $OpenBSD: uhid.c,v 1.18 2002/05/07 18:29:18 nate Exp $ */
-/* $NetBSD: uhid.c,v 1.45 2001/10/26 17:58:21 augustss Exp $ */
-/* $FreeBSD: src/sys/dev/usb/uhid.c,v 1.22 1999/11/17 22:33:43 n_hibma Exp $ */
+/* $OpenBSD: uhid.c,v 1.19 2002/05/09 15:06:29 nate Exp $ */
+/* $NetBSD: uhid.c,v 1.51 2002/03/17 18:02:53 augustss Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -48,16 +47,8 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/signalvar.h>
-#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/device.h>
#include <sys/ioctl.h>
-#elif defined(__FreeBSD__)
-#include <sys/ioccom.h>
-#include <sys/filio.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <sys/ioccom.h>
-#endif
#include <sys/conf.h>
#include <sys/tty.h>
#include <sys/file.h>
@@ -75,8 +66,7 @@
#include <dev/usb/hid.h>
#include <dev/usb/usb_quirks.h>
-/* Report descriptor for broken Wacom Graphire */
-#include <dev/usb/ugraphire_rdesc.h>
+#include <dev/usb/uhidev.h>
#ifdef UHID_DEBUG
#define DPRINTF(x) if (uhiddebug) logprintf x
@@ -88,33 +78,20 @@ int uhiddebug = 0;
#endif
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;
+ struct uhidev sc_hdev;
int sc_isize;
int sc_osize;
int sc_fsize;
- u_int8_t sc_iid;
- u_int8_t sc_oid;
- u_int8_t sc_fid;
- u_char *sc_ibuf;
u_char *sc_obuf;
- void *sc_repdesc;
- int sc_repdesc_size;
-
struct clist sc_q;
struct selinfo sc_rsel;
- struct proc *sc_async; /* process that wants SIGIO */
+ usb_proc_ptr sc_async; /* process that wants SIGIO */
u_char sc_state; /* driver state */
-#define UHID_OPEN 0x01 /* device is open */
-#define UHID_ASLP 0x02 /* waiting for device data */
-#define UHID_NEEDCLEAR 0x04 /* needs clearing endpoint stall */
-#define UHID_IMMED 0x08 /* return read data immediately */
+#define UHID_ASLP 0x01 /* waiting for device data */
+#define UHID_IMMED 0x02 /* return read data immediately */
int sc_refcnt;
u_char sc_dying;
@@ -124,153 +101,52 @@ struct uhid_softc {
#define UHID_CHUNK 128 /* chunk size for read */
#define UHID_BSIZE 1020 /* buffer size */
-#if defined(__NetBSD__) || defined(__OpenBSD__)
cdev_decl(uhid);
-#elif defined(__FreeBSD__)
-d_open_t uhidopen;
-d_close_t uhidclose;
-d_read_t uhidread;
-d_write_t uhidwrite;
-d_ioctl_t uhidioctl;
-d_poll_t uhidpoll;
-
-#define UHID_CDEV_MAJOR 122
-
-Static struct cdevsw uhid_cdevsw = {
- /* open */ uhidopen,
- /* close */ uhidclose,
- /* read */ uhidread,
- /* write */ uhidwrite,
- /* ioctl */ uhidioctl,
- /* poll */ uhidpoll,
- /* mmap */ nommap,
- /* strategy */ nostrategy,
- /* name */ "uhid",
- /* maj */ UHID_CDEV_MAJOR,
- /* dump */ nodump,
- /* psize */ nopsize,
- /* flags */ 0,
- /* bmaj */ -1
-};
-#endif
-Static void uhid_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
+Static void uhid_intr(struct uhidev *, void *, u_int len);
Static int uhid_do_read(struct uhid_softc *, struct uio *uio, int);
Static int uhid_do_write(struct uhid_softc *, struct uio *uio, int);
-Static int uhid_do_ioctl(struct uhid_softc*, u_long, caddr_t, int,struct proc*);
+Static int uhid_do_ioctl(struct uhid_softc*, u_long, caddr_t, int,
+ usb_proc_ptr);
USB_DECLARE_DRIVER(uhid);
USB_MATCH(uhid)
{
USB_MATCH_START(uhid, uaa);
- usb_interface_descriptor_t *id;
-
- if (uaa->iface == NULL)
- return (UMATCH_NONE);
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id == NULL || id->bInterfaceClass != UICLASS_HID)
- return (UMATCH_NONE);
- if (uaa->matchlvl)
- return (uaa->matchlvl);
+ struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
+
+ DPRINTF(("uhid_match: report=%d\n", uha->reportid));
+
+ if (uha->matchlvl)
+ return (uha->matchlvl);
return (UMATCH_IFACECLASS_GENERIC);
}
USB_ATTACH(uhid)
{
USB_ATTACH_START(uhid, sc, uaa);
- usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- int size;
+ struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
+ int size, repid;
void *desc;
- 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);
- 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 == NULL) {
- printf("%s: could not read endpoint descriptor\n",
- USBDEVNAME(sc->sc_dev));
- sc->sc_dying = 1;
- 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,
- UE_GET_DIR(ed->bEndpointAddress)==UE_DIR_IN? "in" : "out",
- ed->bmAttributes & UE_XFERTYPE,
- UGETW(ed->wMaxPacketSize), ed->bInterval));
-
- if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN ||
- (ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
- printf("%s: unexpected endpoint\n", USBDEVNAME(sc->sc_dev));
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
- }
-
- sc->sc_ep_addr = ed->bEndpointAddress;
-
- if (uaa->vendor == USB_VENDOR_WACOM &&
- uaa->product == USB_PRODUCT_WACOM_GRAPHIRE /* &&
- uaa->revision == 0x???? */) { /* XXX should use revision */
- /* The report descriptor for the Wacom Graphire is broken. */
- size = sizeof uhid_graphire_report_descr;
- desc = malloc(size, M_USBDEV, M_NOWAIT);
- if (desc == NULL)
- err = USBD_NOMEM;
- else {
- err = USBD_NORMAL_COMPLETION;
- memcpy(desc, uhid_graphire_report_descr, size);
- }
- } else {
- desc = NULL;
- err = usbd_read_report_desc(uaa->iface, &desc, &size,M_USBDEV);
- }
- if (err) {
- printf("%s: no report descriptor\n", USBDEVNAME(sc->sc_dev));
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
- }
- (void)usbd_set_idle(iface, 0, 0);
-
- sc->sc_isize = hid_report_size(desc, size, hid_input, &sc->sc_iid);
- sc->sc_osize = hid_report_size(desc, size, hid_output, &sc->sc_oid);
- sc->sc_fsize = hid_report_size(desc, size, hid_feature, &sc->sc_fid);
+ sc->sc_hdev.sc_intr = uhid_intr;
+ sc->sc_hdev.sc_parent = uha->parent;
+ sc->sc_hdev.sc_report_id = uha->reportid;
- sc->sc_repdesc = desc;
- sc->sc_repdesc_size = size;
+ uhidev_get_report_desc(uha->parent, &desc, &size);
+ repid = uha->reportid;
+ sc->sc_isize = hid_report_size(desc, size, hid_input, repid);
+ sc->sc_osize = hid_report_size(desc, size, hid_output, repid);
+ sc->sc_fsize = hid_report_size(desc, size, hid_feature, repid);
-#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));
+ printf(": input=%d, output=%d, feature=%d\n",
+ sc->sc_isize, sc->sc_osize, sc->sc_fsize);
USB_ATTACH_SUCCESS_RETURN;
}
-#if defined(__NetBSD__) || defined(__OpenBSD__)
int
uhid_activate(device_ptr_t self, enum devact act)
{
@@ -287,36 +163,28 @@ uhid_activate(device_ptr_t self, enum devact act)
}
return (0);
}
-#endif
USB_DETACH(uhid)
{
USB_DETACH_START(uhid, sc);
int s;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
int maj, mn;
DPRINTF(("uhid_detach: sc=%p flags=%d\n", sc, flags));
-#else
- DPRINTF(("uhid_detach: sc=%p\n", sc));
-#endif
sc->sc_dying = 1;
- if (sc->sc_intrpipe != NULL)
- usbd_abort_pipe(sc->sc_intrpipe);
- if (sc->sc_state & UHID_OPEN) {
+ if (sc->sc_hdev.sc_state & UHIDEV_OPEN) {
s = splusb();
if (--sc->sc_refcnt >= 0) {
/* Wake everyone */
wakeup(&sc->sc_q);
/* Wait for processes to go away. */
- usb_detach_wait(USBDEV(sc->sc_dev));
+ usb_detach_wait(USBDEV(sc->sc_hdev.sc_dev));
}
splx(s);
}
-#if defined(__NetBSD__) || defined(__OpenBSD__)
/* locate the major number */
for (maj = 0; maj < nchrdev; maj++)
if (cdevsw[maj].d_open == uhidopen)
@@ -325,47 +193,33 @@ USB_DETACH(uhid)
/* Nuke the vnodes for any open instances (calls close). */
mn = self->dv_unit;
vdevgone(maj, mn, mn, VCHR);
-#elif defined(__FreeBSD__)
- /* XXX not implemented yet */
-#endif
- if (sc->sc_repdesc)
- free(sc->sc_repdesc, M_USBDEV);
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
+#if 0
+ usbd_add_drv_event(USB_EVENT_DRIVER_DETACH,
+ sc->sc_hdev.sc_parent->sc_udev,
+ USBDEV(sc->sc_hdev.sc_dev));
+#endif
return (0);
}
void
-uhid_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
+uhid_intr(struct uhidev *addr, void *data, u_int len)
{
- struct uhid_softc *sc = addr;
+ struct uhid_softc *sc = (struct uhid_softc *)addr;
#ifdef UHID_DEBUG
if (uhiddebug > 5) {
- u_int32_t cc, i;
+ u_int32_t 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]));
+ for (i = 0; i < len; i++)
+ DPRINTF((" %02x", ((u_char *)data)[i]));
DPRINTF(("\n"));
}
#endif
- if (status == USBD_CANCELLED)
- return;
-
- if (status != USBD_NORMAL_COMPLETION) {
- DPRINTF(("uhid_intr: status=%d\n", status));
- sc->sc_state |= UHID_NEEDCLEAR;
- return;
- }
-
- (void) b_to_q(sc->sc_ibuf, sc->sc_isize, &sc->sc_q);
+ (void)b_to_q(data, len, &sc->sc_q);
if (sc->sc_state & UHID_ASLP) {
sc->sc_state &= ~UHID_ASLP;
@@ -380,10 +234,10 @@ uhid_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
}
int
-uhidopen(dev_t dev, int flag, int mode, struct proc *p)
+uhidopen(dev_t dev, int flag, int mode, usb_proc_ptr p)
{
struct uhid_softc *sc;
- usbd_status err;
+ int error;
USB_GET_SC_OPEN(uhid, UHIDUNIT(dev), sc);
@@ -392,40 +246,23 @@ uhidopen(dev_t dev, int flag, int mode, struct proc *p)
if (sc->sc_dying)
return (ENXIO);
- if (sc->sc_state & UHID_OPEN)
- return (EBUSY);
- sc->sc_state |= UHID_OPEN;
+ error = uhidev_open(&sc->sc_hdev);
+ if (error)
+ return (error);
if (clalloc(&sc->sc_q, UHID_BSIZE, 0) == -1) {
- sc->sc_state &= ~UHID_OPEN;
+ uhidev_close(&sc->sc_hdev);
return (ENOMEM);
}
-
- sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
sc->sc_obuf = malloc(sc->sc_osize, M_USBDEV, M_WAITOK);
-
- /* Set up interrupt pipe. */
- 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",err));
- free(sc->sc_ibuf, M_USBDEV);
- free(sc->sc_obuf, M_USBDEV);
- sc->sc_state &= ~UHID_OPEN;
- return (EIO);
- }
-
sc->sc_state &= ~UHID_IMMED;
-
- sc->sc_async = 0;
+ sc->sc_async = NULL;
return (0);
}
int
-uhidclose(dev_t dev, int flag, int mode, struct proc *p)
+uhidclose(dev_t dev, int flag, int mode, usb_proc_ptr p)
{
struct uhid_softc *sc;
@@ -433,19 +270,10 @@ uhidclose(dev_t dev, int flag, int mode, struct proc *p)
DPRINTF(("uhidclose: sc=%p\n", sc));
- /* Disable interrupts. */
- usbd_abort_pipe(sc->sc_intrpipe);
- usbd_close_pipe(sc->sc_intrpipe);
- sc->sc_intrpipe = 0;
-
clfree(&sc->sc_q);
-
- free(sc->sc_ibuf, M_USBDEV);
free(sc->sc_obuf, M_USBDEV);
-
- sc->sc_state &= ~UHID_OPEN;
-
- sc->sc_async = 0;
+ sc->sc_async = NULL;
+ uhidev_close(&sc->sc_hdev);
return (0);
}
@@ -455,6 +283,7 @@ uhid_do_read(struct uhid_softc *sc, struct uio *uio, int flag)
{
int s;
int error = 0;
+ int extra;
size_t length;
u_char buffer[UHID_CHUNK];
usbd_status err;
@@ -462,12 +291,12 @@ uhid_do_read(struct uhid_softc *sc, struct uio *uio, int flag)
DPRINTFN(1, ("uhidread\n"));
if (sc->sc_state & UHID_IMMED) {
DPRINTFN(1, ("uhidread immed\n"));
-
- err = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
- sc->sc_iid, buffer, sc->sc_isize);
+ extra = sc->sc_hdev.sc_report_id != 0;
+ err = uhidev_get_report(&sc->sc_hdev, UHID_INPUT_REPORT,
+ buffer, sc->sc_isize + extra);
if (err)
return (EIO);
- return (uiomove(buffer, sc->sc_isize, uio));
+ return (uiomove(buffer+extra, sc->sc_isize, uio));
}
s = splusb();
@@ -486,11 +315,6 @@ uhid_do_read(struct uhid_softc *sc, struct uio *uio, int flag)
sc->sc_state &= ~UHID_ASLP;
break;
}
- if (sc->sc_state & UHID_NEEDCLEAR) {
- DPRINTFN(-1,("uhidread: clearing stall\n"));
- sc->sc_state &= ~UHID_NEEDCLEAR;
- usbd_clear_endpoint_stall(sc->sc_intrpipe);
- }
}
splx(s);
@@ -523,7 +347,7 @@ uhidread(dev_t dev, struct uio *uio, int flag)
sc->sc_refcnt++;
error = uhid_do_read(sc, uio, flag);
if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(USBDEV(sc->sc_dev));
+ usb_detach_wakeup(USBDEV(sc->sc_hdev.sc_dev));
return (error);
}
@@ -545,12 +369,8 @@ uhid_do_write(struct uhid_softc *sc, struct uio *uio, int flag)
return (EINVAL);
error = uiomove(sc->sc_obuf, size, uio);
if (!error) {
- if (sc->sc_oid)
- err = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
- sc->sc_obuf[0], sc->sc_obuf+1, size-1);
- else
- err = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
- 0, sc->sc_obuf, size);
+ err = uhidev_set_report(&sc->sc_hdev, UHID_OUTPUT_REPORT,
+ sc->sc_obuf, size);
if (err)
error = EIO;
}
@@ -569,18 +389,20 @@ uhidwrite(dev_t dev, struct uio *uio, int flag)
sc->sc_refcnt++;
error = uhid_do_write(sc, uio, flag);
if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(USBDEV(sc->sc_dev));
+ usb_detach_wakeup(USBDEV(sc->sc_hdev.sc_dev));
return (error);
}
int
uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t addr,
- int flag, struct proc *p)
+ int flag, usb_proc_ptr p)
{
struct usb_ctl_report_desc *rd;
struct usb_ctl_report *re;
- int size, id;
+ u_char buffer[UHID_CHUNK];
+ int size, extra;
usbd_status err;
+ void *desc;
DPRINTFN(2, ("uhidioctl: cmd=%lx\n", cmd));
@@ -611,17 +433,18 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t addr,
break;
case USB_GET_REPORT_DESC:
+ uhidev_get_report_desc(sc->sc_hdev.sc_parent, &desc, &size);
rd = (struct usb_ctl_report_desc *)addr;
- size = min(sc->sc_repdesc_size, sizeof rd->ucrd_data);
+ size = min(size, sizeof rd->ucrd_data);
rd->ucrd_size = size;
- memcpy(rd->ucrd_data, sc->sc_repdesc, size);
+ memcpy(rd->ucrd_data, desc, size);
break;
case USB_SET_IMMED:
if (*(int *)addr) {
- /* 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);
+ extra = sc->sc_hdev.sc_report_id != 0;
+ err = uhidev_get_report(&sc->sc_hdev, UHID_INPUT_REPORT,
+ buffer, sc->sc_isize + extra);
if (err)
return (EOPNOTSUPP);
@@ -635,21 +458,21 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t addr,
switch (re->ucr_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_get_report(sc->sc_iface, re->ucr_report, id,
- re->ucr_data, size);
+ extra = sc->sc_hdev.sc_report_id != 0;
+ err = uhidev_get_report(&sc->sc_hdev, re->ucr_report,
+ re->ucr_data, size + extra);
+ if (extra)
+ memcpy(re->ucr_data, re->ucr_data+1, size);
if (err)
return (EIO);
break;
@@ -659,26 +482,26 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t addr,
switch (re->ucr_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->ucr_report, id,
- re->ucr_data,
- size);
+ err = uhidev_set_report(&sc->sc_hdev, re->ucr_report,
+ re->ucr_data, size);
if (err)
return (EIO);
break;
+ case USB_GET_REPORT_ID:
+ *(int *)addr = sc->sc_hdev.sc_report_id;
+ break;
+
default:
return (EINVAL);
}
@@ -686,7 +509,7 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, caddr_t addr,
}
int
-uhidioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
+uhidioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p)
{
struct uhid_softc *sc;
int error;
@@ -696,12 +519,12 @@ uhidioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
sc->sc_refcnt++;
error = uhid_do_ioctl(sc, cmd, addr, flag, p);
if (--sc->sc_refcnt < 0)
- usb_detach_wakeup(USBDEV(sc->sc_dev));
+ usb_detach_wakeup(USBDEV(sc->sc_hdev.sc_dev));
return (error);
}
int
-uhidpoll(dev_t dev, int events, struct proc *p)
+uhidpoll(dev_t dev, int events, usb_proc_ptr p)
{
struct uhid_softc *sc;
int revents = 0;
@@ -725,7 +548,3 @@ uhidpoll(dev_t dev, int events, struct proc *p)
splx(s);
return (revents);
}
-
-#if defined(__FreeBSD__)
-DRIVER_MODULE(uhid, uhub, uhid_driver, uhid_devclass, usbd_driver_load, 0);
-#endif
diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c
new file mode 100644
index 00000000000..c7af847f017
--- /dev/null
+++ b/sys/dev/usb/uhidev.c
@@ -0,0 +1,513 @@
+/* $OpenBSD: uhidev.c,v 1.3 2002/05/09 15:06:29 nate Exp $ */
+/* $NetBSD: uhidev.c,v 1.5 2002/02/27 01:30:50 augustss Exp $ */
+
+/*
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lennart@augustsson.net) at
+ * Carlstedt Research & Technology.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * HID spec: http://www.usb.org/developers/data/devclass/hid1_1.pdf
+ */
+
+#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 <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/hid.h>
+#include <dev/usb/usb_quirks.h>
+
+#include <dev/usb/uhidev.h>
+
+/* Report descriptor for broken Wacom Graphire */
+#include <dev/usb/ugraphire_rdesc.h>
+
+#ifdef UHIDEV_DEBUG
+#define DPRINTF(x) if (uhidevdebug) logprintf x
+#define DPRINTFN(n,x) if (uhidevdebug>(n)) logprintf x
+int uhidevdebug = 0;
+#else
+#define DPRINTF(x)
+#define DPRINTFN(n,x)
+#endif
+
+Static void uhidev_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
+
+Static int uhidev_maxrepid(void *buf, int len);
+Static int uhidevprint(void *aux, const char *pnp);
+#if defined(__NetBSD__)
+Static int uhidevsubmatch(struct device *parent, struct cfdata *cf, void *aux);
+#else
+Static int uhidevsubmatch(struct device *parent, void *cf, void *aux);
+#endif
+
+USB_DECLARE_DRIVER(uhidev);
+
+USB_MATCH(uhidev)
+{
+ USB_MATCH_START(uhidev, uaa);
+ usb_interface_descriptor_t *id;
+
+ if (uaa->iface == NULL)
+ return (UMATCH_NONE);
+ id = usbd_get_interface_descriptor(uaa->iface);
+ if (id == NULL || id->bInterfaceClass != UICLASS_HID)
+ return (UMATCH_NONE);
+ if (uaa->matchlvl)
+ return (uaa->matchlvl);
+ return (UMATCH_IFACECLASS_GENERIC);
+}
+
+int repproto = 1;
+
+USB_ATTACH(uhidev)
+{
+ USB_ATTACH_START(uhidev, sc, uaa);
+ usbd_interface_handle iface = uaa->iface;
+ usb_interface_descriptor_t *id;
+ usb_endpoint_descriptor_t *ed;
+ struct uhidev_attach_arg uha;
+ struct uhidev *dev;
+ int size, nrepid, repid, repsz;
+ int repsizes[256];
+ void *desc;
+ 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);
+ USB_ATTACH_SETUP;
+ printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev),
+ devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
+
+ (void)usbd_set_idle(iface, 0, 0);
+#if 0
+
+ qflags = usbd_get_quirks(sc->sc_udev)->uq_flags;
+ if ((qflags & UQ_NO_SET_PROTO) == 0 &&
+ id->bInterfaceSubClass != UISUBCLASS_BOOT)
+ (void)usbd_set_protocol(iface, 1);
+#endif
+
+ ed = usbd_interface2endpoint_descriptor(iface, 0);
+ if (ed == NULL) {
+ printf("%s: could not read endpoint descriptor\n",
+ USBDEVNAME(sc->sc_dev));
+ sc->sc_dying = 1;
+ USB_ATTACH_ERROR_RETURN;
+ }
+
+ DPRINTFN(10,("uhidev_attach: bLength=%d bDescriptorType=%d "
+ "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d"
+ " bInterval=%d\n",
+ ed->bLength, ed->bDescriptorType,
+ ed->bEndpointAddress & UE_ADDR,
+ UE_GET_DIR(ed->bEndpointAddress)==UE_DIR_IN? "in" : "out",
+ ed->bmAttributes & UE_XFERTYPE,
+ UGETW(ed->wMaxPacketSize), ed->bInterval));
+
+ if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN ||
+ (ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
+ printf("%s: unexpected endpoint\n", USBDEVNAME(sc->sc_dev));
+ sc->sc_dying = 1;
+ USB_ATTACH_ERROR_RETURN;
+ }
+
+ sc->sc_ep_addr = ed->bEndpointAddress;
+
+ /* XXX need to extend this */
+ if (uaa->vendor == USB_VENDOR_WACOM &&
+ uaa->product == USB_PRODUCT_WACOM_GRAPHIRE /* &&
+ uaa->revision == 0x???? */) { /* XXX should use revision */
+ /* The report descriptor for the Wacom Graphire is broken. */
+ size = sizeof uhid_graphire_report_descr;
+ desc = malloc(size, M_USBDEV, M_NOWAIT);
+ if (desc == NULL)
+ err = USBD_NOMEM;
+ else {
+ err = USBD_NORMAL_COMPLETION;
+ memcpy(desc, uhid_graphire_report_descr, size);
+ }
+ } else {
+ desc = NULL;
+ err = usbd_read_report_desc(uaa->iface, &desc, &size, M_USBDEV);
+ }
+ if (err) {
+ printf("%s: no report descriptor\n", USBDEVNAME(sc->sc_dev));
+ sc->sc_dying = 1;
+ USB_ATTACH_ERROR_RETURN;
+ }
+
+ sc->sc_repdesc = desc;
+ sc->sc_repdesc_size = size;
+
+ uha.uaa = uaa;
+ nrepid = uhidev_maxrepid(desc, size);
+ if (nrepid < 0)
+ USB_ATTACH_SUCCESS_RETURN;
+ if (nrepid > 0)
+ printf("%s: %d report ids\n", USBDEVNAME(sc->sc_dev), nrepid);
+ nrepid++;
+ sc->sc_subdevs = malloc(nrepid * sizeof(device_ptr_t),
+ M_USBDEV, M_NOWAIT);
+ bzero(sc->sc_subdevs, nrepid * sizeof(device_ptr_t));
+ if (sc->sc_subdevs == NULL) {
+ printf("%s: no memory\n", USBDEVNAME(sc->sc_dev));
+ USB_ATTACH_ERROR_RETURN;
+ }
+ sc->sc_nrepid = nrepid;
+ sc->sc_isize = 0;
+
+ usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
+ USBDEV(sc->sc_dev));
+
+ for (repid = 0; repid < nrepid; repid++) {
+ repsz = hid_report_size(desc, size, hid_input, repid);
+ DPRINTF(("uhidev_match: repid=%d, repsz=%d\n", repid, repsz));
+ repsizes[repid] = repsz;
+ if (repsz > 0) {
+ if (repsz > sc->sc_isize)
+ sc->sc_isize = repsz;
+ }
+ }
+ sc->sc_isize += nrepid != 1; /* space for report ID */
+ DPRINTF(("uhidev_attach: isize=%d\n", sc->sc_isize));
+
+ uha.parent = sc;
+ for (repid = 0; repid < nrepid; repid++) {
+ DPRINTF(("uhidev_match: try repid=%d\n", repid));
+ if (hid_report_size(desc, size, hid_input, repid) == 0 &&
+ hid_report_size(desc, size, hid_output, repid) == 0 &&
+ hid_report_size(desc, size, hid_feature, repid) == 0) {
+ ; /* already NULL in sc->sc_subdevs[repid] */
+ } else {
+ uha.reportid = repid;
+ dev = (struct uhidev *)config_found_sm(self, &uha,
+ uhidevprint, uhidevsubmatch);
+ sc->sc_subdevs[repid] = dev;
+ if (dev != NULL) {
+ dev->sc_in_rep_size = repsizes[repid];
+#ifdef DIAGNOSTIC
+ DPRINTF(("uhidev_match: repid=%d dev=%p\n",
+ repid, dev));
+ if (dev->sc_intr == NULL) {
+ printf("%s: sc_intr == NULL\n",
+ USBDEVNAME(sc->sc_dev));
+ USB_ATTACH_ERROR_RETURN;
+ }
+#endif
+ }
+ }
+ }
+
+ USB_ATTACH_SUCCESS_RETURN;
+}
+
+int
+uhidev_maxrepid(void *buf, int len)
+{
+ struct hid_data *d;
+ struct hid_item h;
+ int maxid;
+
+ maxid = -1;
+ h.report_ID = 0;
+ for (d = hid_start_parse(buf, len, hid_none); hid_get_item(d, &h); )
+ if (h.report_ID > maxid)
+ maxid = h.report_ID;
+ hid_end_parse(d);
+ return (maxid);
+}
+
+int
+uhidevprint(void *aux, const char *pnp)
+{
+ struct uhidev_attach_arg *uha = aux;
+
+ if (pnp)
+ printf("uhid at %s", pnp);
+ if (uha->reportid != 0)
+ printf(" reportid %d", uha->reportid);
+ return (UNCONF);
+}
+
+#if defined(__NetBSD__)
+Static int uhidevsubmatch(struct device *parent, struct cfdata *cf, void *aux)
+#else
+Static int uhidevsubmatch(struct device *parent, void *match, void *aux)
+#endif
+{
+ struct uhidev_attach_arg *uha = aux;
+#if defined(__OpenBSD__)
+ struct cfdata *cf = match;
+#endif
+
+ if (cf->uhidevcf_reportid != UHIDEV_UNK_REPORTID &&
+ cf->uhidevcf_reportid != uha->reportid)
+ return (0);
+ if (cf->uhidevcf_reportid == uha->reportid)
+ uha->matchlvl = UMATCH_VENDOR_PRODUCT;
+ else
+ uha->matchlvl = 0;
+ return ((*cf->cf_attach->ca_match)(parent, cf, aux));
+}
+
+int
+uhidev_activate(device_ptr_t self, enum devact act)
+{
+ struct uhidev_softc *sc = (struct uhidev_softc *)self;
+ int i, rv;
+
+ switch (act) {
+ case DVACT_ACTIVATE:
+ return (EOPNOTSUPP);
+ break;
+
+ case DVACT_DEACTIVATE:
+ rv = 0;
+ for (i = 0; i < sc->sc_nrepid; i++)
+ if (sc->sc_subdevs[i] != NULL)
+ rv |= config_deactivate(
+ &sc->sc_subdevs[i]->sc_dev);
+ sc->sc_dying = 1;
+ break;
+ }
+ return (rv);
+}
+
+USB_DETACH(uhidev)
+{
+ USB_DETACH_START(uhidev, sc);
+ int i, rv;
+
+ DPRINTF(("uhidev_detach: sc=%p flags=%d\n", sc, flags));
+
+ sc->sc_dying = 1;
+ if (sc->sc_intrpipe != NULL)
+ usbd_abort_pipe(sc->sc_intrpipe);
+
+ if (sc->sc_repdesc != NULL)
+ free(sc->sc_repdesc, M_USBDEV);
+
+ rv = 0;
+ for (i = 0; i < sc->sc_nrepid; i++) {
+ if (sc->sc_subdevs[i] != NULL) {
+ rv |= config_detach(&sc->sc_subdevs[i]->sc_dev, flags);
+ sc->sc_subdevs[i] = NULL;
+ }
+ }
+
+ usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
+ USBDEV(sc->sc_dev));
+
+ return (rv);
+}
+
+void
+uhidev_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
+{
+ struct uhidev_softc *sc = addr;
+ struct uhidev *scd;
+ u_char *p;
+ u_int rep;
+ u_int32_t cc;
+
+ usbd_get_xfer_status(xfer, NULL, NULL, &cc, NULL);
+
+#ifdef UHIDEV_DEBUG
+ if (uhidevdebug > 5) {
+ u_int32_t i;
+
+ DPRINTF(("uhidev_intr: status=%d cc=%d\n", status, cc));
+ DPRINTF(("uhidev_intr: data ="));
+ for (i = 0; i < cc; i++)
+ DPRINTF((" %02x", sc->sc_ibuf[i]));
+ DPRINTF(("\n"));
+ }
+#endif
+
+ if (status == USBD_CANCELLED)
+ return;
+
+ if (status != USBD_NORMAL_COMPLETION) {
+ DPRINTF(("%s: interrupt status=%d\n", USBDEVNAME(sc->sc_dev),
+ status));
+ usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
+ return;
+ }
+
+ p = sc->sc_ibuf;
+ if (sc->sc_nrepid != 1)
+ rep = *p++, cc--;
+ else
+ rep = 0;
+ if (rep >= sc->sc_nrepid) {
+ printf("uhidev_intr: bad repid %d\n", rep);
+ return;
+ }
+ scd = sc->sc_subdevs[rep];
+ DPRINTFN(5,("uhidev_intr: rep=%d, scd=%p state=0x%x\n",
+ rep, scd, scd ? scd->sc_state : 0));
+ if (scd == NULL || !(scd->sc_state & UHIDEV_OPEN))
+ return;
+#ifdef DIAGNOSTIC
+ if (scd->sc_in_rep_size != cc)
+ printf("%s: bad input length %d != %d\n",USBDEVNAME(sc->sc_dev),
+ scd->sc_in_rep_size, cc);
+#endif
+ scd->sc_intr(scd, p, cc);
+}
+
+void
+uhidev_get_report_desc(struct uhidev_softc *sc, void **desc, int *size)
+{
+ *desc = sc->sc_repdesc;
+ *size = sc->sc_repdesc_size;
+}
+
+int
+uhidev_open(struct uhidev *scd)
+{
+ struct uhidev_softc *sc = scd->sc_parent;
+ usbd_status err;
+
+ DPRINTF(("uhidev_open: open pipe, state=%d refcnt=%d\n",
+ scd->sc_state, sc->sc_refcnt));
+
+ if (scd->sc_state & UHIDEV_OPEN)
+ return (EBUSY);
+ scd->sc_state |= UHIDEV_OPEN;
+ if (sc->sc_refcnt++)
+ return (0);
+
+ if (sc->sc_isize == 0)
+ return (0);
+
+ sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
+
+ /* Set up interrupt pipe. */
+ DPRINTF(("uhidev_open: isize=%d, ep=0x%02x\n", sc->sc_isize,
+ sc->sc_ep_addr));
+ 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, uhidev_intr, USBD_DEFAULT_INTERVAL);
+ if (err) {
+ DPRINTF(("uhidopen: usbd_open_pipe_intr failed, "
+ "error=%d\n",err));
+ free(sc->sc_ibuf, M_USBDEV);
+ scd->sc_state &= ~UHIDEV_OPEN;
+ sc->sc_refcnt = 0;
+ sc->sc_intrpipe = NULL;
+ return (EIO);
+ }
+ return (0);
+}
+
+void
+uhidev_close(struct uhidev *scd)
+{
+ struct uhidev_softc *sc = scd->sc_parent;
+
+ if (!(scd->sc_state & UHIDEV_OPEN))
+ return;
+ scd->sc_state &= ~UHIDEV_OPEN;
+ if (--sc->sc_refcnt)
+ return;
+ DPRINTF(("uhidev_close: close pipe\n"));
+
+ /* Disable interrupts. */
+ if (sc->sc_intrpipe != NULL) {
+ usbd_abort_pipe(sc->sc_intrpipe);
+ usbd_close_pipe(sc->sc_intrpipe);
+ sc->sc_intrpipe = NULL;
+ }
+
+ if (sc->sc_ibuf != NULL) {
+ free(sc->sc_ibuf, M_USBDEV);
+ sc->sc_ibuf = NULL;
+ }
+}
+
+usbd_status
+uhidev_set_report(struct uhidev *scd, int type, void *data, int len)
+{
+ /* XXX */
+ char buf[100];
+ if (scd->sc_report_id) {
+ buf[0] = scd->sc_report_id;
+ memcpy(buf+1, data, len);
+ len++;
+ data = buf;
+ }
+
+ return usbd_set_report(scd->sc_parent->sc_iface, type,
+ scd->sc_report_id, data, len);
+}
+
+void
+uhidev_set_report_async(struct uhidev *scd, int type, void *data, int len)
+{
+ /* XXX */
+ char buf[100];
+ if (scd->sc_report_id) {
+ buf[0] = scd->sc_report_id;
+ memcpy(buf+1, data, len);
+ len++;
+ data = buf;
+ }
+
+ usbd_set_report_async(scd->sc_parent->sc_iface, type,
+ scd->sc_report_id, data, len);
+}
+
+usbd_status
+uhidev_get_report(struct uhidev *scd, int type, void *data, int len)
+{
+ return usbd_get_report(scd->sc_parent->sc_iface, type,
+ scd->sc_report_id, data, len);
+}
diff --git a/sys/dev/usb/uhidev.h b/sys/dev/usb/uhidev.h
new file mode 100644
index 00000000000..360eae75784
--- /dev/null
+++ b/sys/dev/usb/uhidev.h
@@ -0,0 +1,91 @@
+/* $OpenBSD: uhidev.h,v 1.3 2002/05/09 15:06:29 nate Exp $ */
+/* $NetBSD: uhidev.h,v 1.2 2001/12/29 18:56:52 augustss Exp $ */
+
+/*
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Lennart Augustsson (lennart@augustsson.net) at
+ * Carlstedt Research & Technology.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(__NetBSD__)
+#include "locators.h"
+#endif
+
+#define uhidevcf_reportid cf_loc[UHIDBUSCF_REPORTID]
+#define UHIDEV_UNK_REPORTID UHIDBUSCF_REPORTID_DEFAULT
+
+struct uhidev_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;
+
+ u_char *sc_ibuf;
+ u_int sc_isize;
+
+ void *sc_repdesc;
+ int sc_repdesc_size;
+
+ u_int sc_nrepid;
+ struct uhidev **sc_subdevs;
+
+ int sc_refcnt;
+ u_char sc_dying;
+};
+
+struct uhidev {
+ USBBASEDEVICE sc_dev; /* base device */
+ struct uhidev_softc *sc_parent;
+ uByte sc_report_id;
+ u_int8_t sc_state;
+ int sc_in_rep_size;
+#define UHIDEV_OPEN 0x01 /* device is open */
+ void (*sc_intr)(struct uhidev *, void *, u_int);
+};
+
+struct uhidev_attach_arg {
+ struct usb_attach_arg *uaa;
+ struct uhidev_softc *parent;
+ int reportid;
+ int reportsize;
+ int matchlvl;
+};
+
+void uhidev_get_report_desc(struct uhidev_softc *, void **, int *);
+int uhidev_open(struct uhidev *);
+void uhidev_close(struct uhidev *);
+usbd_status uhidev_set_report(struct uhidev *scd, int type, void *data,int len);
+void uhidev_set_report_async(struct uhidev *scd, int type, void *data, int len);
+usbd_status uhidev_get_report(struct uhidev *scd, int type, void *data,int len);
diff --git a/sys/dev/usb/ukbd.c b/sys/dev/usb/ukbd.c
index 0843bd9392d..3c8c6ca9dec 100644
--- a/sys/dev/usb/ukbd.c
+++ b/sys/dev/usb/ukbd.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ukbd.c,v 1.13 2002/05/07 18:29:18 nate Exp $ */
-/* $NetBSD: ukbd.c,v 1.69 2001/10/24 21:02:18 augustss Exp $ */
+/* $OpenBSD: ukbd.c,v 1.14 2002/05/09 15:06:29 nate Exp $ */
+/* $NetBSD: ukbd.c,v 1.79 2001/12/30 19:37:43 augustss Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -66,6 +66,7 @@
#include <dev/usb/usbdi_util.h>
#include <dev/usb/usbdevs.h>
#include <dev/usb/usb_quirks.h>
+#include <dev/usb/uhidev.h>
#include <dev/usb/hid.h>
#include <dev/usb/ukbdvar.h>
@@ -88,119 +89,96 @@ int ukbddebug = 0;
#define DPRINTFN(n,x)
#endif
-#define NKEYCODE 6
-
-#define NUM_LOCK 0x01
-#define CAPS_LOCK 0x02
-#define SCROLL_LOCK 0x04
+#define MAXKEYCODE 6
+#define MAXMOD 8 /* max 32 */
struct ukbd_data {
- u_int8_t modifiers;
-#define MOD_CONTROL_L 0x01
-#define MOD_CONTROL_R 0x10
-#define MOD_SHIFT_L 0x02
-#define MOD_SHIFT_R 0x20
-#define MOD_ALT_L 0x04
-#define MOD_ALT_R 0x40
-#define MOD_WIN_L 0x08
-#define MOD_WIN_R 0x80
- u_int8_t reserved;
- u_int8_t keycode[NKEYCODE];
+ u_int32_t modifiers;
+ u_int8_t keycode[MAXKEYCODE];
};
#define PRESS 0x000
#define RELEASE 0x100
#define CODEMASK 0x0ff
-/* Translate USB bitmap to USB keycode. */
-#define NMOD 8
-Static const struct {
- int mask, key;
-} ukbd_mods[NMOD] = {
- { MOD_CONTROL_L, 224 },
- { MOD_CONTROL_R, 228 },
- { MOD_SHIFT_L, 225 },
- { MOD_SHIFT_R, 229 },
- { MOD_ALT_L, 226 },
- { MOD_ALT_R, 230 },
- { MOD_WIN_L, 227 },
- { MOD_WIN_R, 231 },
-};
-
#if defined(WSDISPLAY_COMPAT_RAWKBD)
#define NN 0 /* no translation */
/*
* Translate USB keycodes to US keyboard XT scancodes.
- * Scancodes >= 128 represent EXTENDED keycodes.
+ * Scancodes >= 0x80 represent EXTENDED keycodes.
+ *
+ * See http://www.microsoft.com/HWDEV/TECH/input/Scancode.asp
*/
Static const u_int8_t ukbd_trtab[256] = {
- NN, NN, NN, NN, 30, 48, 46, 32, /* 00 - 07 */
- 18, 33, 34, 35, 23, 36, 37, 38, /* 08 - 0F */
- 50, 49, 24, 25, 16, 19, 31, 20, /* 10 - 17 */
- 22, 47, 17, 45, 21, 44, 2, 3, /* 18 - 1F */
- 4, 5, 6, 7, 8, 9, 10, 11, /* 20 - 27 */
- 28, 1, 14, 15, 57, 12, 13, 26, /* 28 - 2F */
- 27, 43, 43, 39, 40, 41, 51, 52, /* 30 - 37 */
- 53, 58, 59, 60, 61, 62, 63, 64, /* 38 - 3F */
- 65, 66, 67, 68, 87, 88, 170, 70, /* 40 - 47 */
- 127, 210, 199, 201, 211, 207, 209, 205, /* 48 - 4F */
- 203, 208, 200, 69, 181, 55, 74, 78, /* 50 - 57 */
- 156, 79, 80, 81, 75, 76, 77, 71, /* 58 - 5F */
- 72, 73, 82, 83, 86, 221, NN, NN, /* 60 - 67 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 68 - 6F */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 70 - 77 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 78 - 7F */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 80 - 87 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 88 - 8F */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 90 - 97 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* 98 - 9F */
- NN, NN, NN, NN, NN, NN, NN, NN, /* A0 - A7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* A8 - AF */
- NN, NN, NN, NN, NN, NN, NN, NN, /* B0 - B7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* B8 - BF */
- NN, NN, NN, NN, NN, NN, NN, NN, /* C0 - C7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* C8 - CF */
- NN, NN, NN, NN, NN, NN, NN, NN, /* D0 - D7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* D8 - DF */
- 29, 42, 56, 219, 157, 54, 184,220, /* E0 - E7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* E8 - EF */
- NN, NN, NN, NN, NN, NN, NN, NN, /* F0 - F7 */
- NN, NN, NN, NN, NN, NN, NN, NN, /* F8 - FF */
+ NN, NN, NN, NN, 0x1e, 0x30, 0x2e, 0x20, /* 00 - 07 */
+ 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26, /* 08 - 0f */
+ 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1f, 0x14, /* 10 - 17 */
+ 0x16, 0x2f, 0x11, 0x2d, 0x15, 0x2c, 0x02, 0x03, /* 18 - 1f */
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, /* 20 - 27 */
+ 0x1c, 0x01, 0x0e, 0x0f, 0x39, 0x0c, 0x0d, 0x1a, /* 28 - 2f */
+ 0x1b, 0x2b, 0x2b, 0x27, 0x28, 0x29, 0x33, 0x34, /* 30 - 37 */
+ 0x35, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, /* 38 - 3f */
+ 0x41, 0x42, 0x43, 0x44, 0x57, 0x58, 0xaa, 0x46, /* 40 - 47 */
+ 0x7f, 0xd2, 0xc7, 0xc9, 0xd3, 0xcf, 0xd1, 0xcd, /* 48 - 4f */
+ 0xcb, 0xd0, 0xc8, 0x45, 0xb5, 0x37, 0x4a, 0x4e, /* 50 - 57 */
+ 0x9c, 0x4f, 0x50, 0x51, 0x4b, 0x4c, 0x4d, 0x47, /* 58 - 5f */
+ 0x48, 0x49, 0x52, 0x53, 0x56, 0xdd, NN, 0x59, /* 60 - 67 */
+ 0x5d, 0x5e, 0x5f, NN, NN, NN, NN, NN, /* 68 - 6f */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* 70 - 77 */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* 78 - 7f */
+ NN, NN, NN, NN, NN, 0x7e, NN, 0x73, /* 80 - 87 */
+ 0x70, 0x7d, 0x79, 0x7b, 0x5c, NN, NN, NN, /* 88 - 8f */
+ NN, NN, 0x78, 0x77, 0x76, NN, NN, NN, /* 90 - 97 */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* 98 - 9f */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* a0 - a7 */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* a8 - af */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* b0 - b7 */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* b8 - bf */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* c0 - c7 */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* c8 - cf */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* d0 - d7 */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* d8 - df */
+ 0x1d, 0x2a, 0x38, 0xdb, 0x9d, 0x36, 0xb8, 0xdc, /* e0 - e7 */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* e8 - ef */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* f0 - f7 */
+ NN, NN, NN, NN, NN, NN, NN, NN, /* f8 - ff */
};
#endif /* defined(WSDISPLAY_COMPAT_RAWKBD) */
#define KEY_ERROR 0x01
-#define MAXKEYS (NMOD+2*NKEYCODE)
+#define MAXKEYS (MAXMOD+2*MAXKEYCODE)
struct ukbd_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;
+ struct uhidev sc_hdev;
struct ukbd_data sc_ndata;
struct ukbd_data sc_odata;
+ struct hid_location sc_modloc[MAXMOD];
+ u_int sc_nmod;
+ struct {
+ u_int32_t mask;
+ u_int8_t key;
+ } sc_mods[MAXMOD];
+
+ struct hid_location sc_keycodeloc;
+ u_int sc_nkeycode;
char sc_enabled;
int sc_console_keyboard; /* we are the console keyboard */
char sc_debounce; /* for quirk handling */
+ usb_callout_t sc_delay; /* for quirk handling */
struct ukbd_data sc_data; /* for quirk handling */
+ struct hid_location sc_numloc;
+ struct hid_location sc_capsloc;
+ struct hid_location sc_scroloc;
int sc_leds;
-#if defined(__OpenBSD__)
- struct timeout sc_delay; /* for quirk handling */
- struct timeout sc_rawrepeat_ch;
-#else
- struct callout sc_delay; /* for quirk handling */
- struct callout sc_rawrepeat_ch;
-#endif
+ usb_callout_t sc_rawrepeat_ch;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
struct device *sc_wskbddev;
#if defined(WSDISPLAY_COMPAT_RAWKBD)
#define REP_DELAY1 400
@@ -213,7 +191,6 @@ struct ukbd_softc {
int sc_polling;
int sc_npollchar;
u_int16_t sc_pollchars[MAXKEYS];
-#endif
u_char sc_dying;
};
@@ -254,22 +231,21 @@ Static int ukbd_is_console;
Static void ukbd_cngetc(void *, u_int *, int *);
Static void ukbd_cnpollc(void *, int);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
const struct wskbd_consops ukbd_consops = {
ukbd_cngetc,
ukbd_cnpollc,
};
-#endif
-Static void ukbd_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
+Static const char *ukbd_parse_desc(struct ukbd_softc *sc);
+
+Static void ukbd_intr(struct uhidev *addr, void *ibuf, u_int len);
Static void ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud);
Static void ukbd_delayed_decode(void *addr);
Static int ukbd_enable(void *, int);
Static void ukbd_set_leds(void *, int);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-Static int ukbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
+Static int ukbd_ioctl(void *, u_long, caddr_t, int, usb_proc_ptr );
#ifdef WSDISPLAY_COMPAT_RAWKBD
Static void ukbd_rawrepeat(void *v);
#endif
@@ -290,90 +266,53 @@ const struct wskbd_mapdata ukbd_keymapdata = {
KB_US,
#endif
};
-#endif
USB_DECLARE_DRIVER(ukbd);
USB_MATCH(ukbd)
{
USB_MATCH_START(ukbd, uaa);
- usb_interface_descriptor_t *id;
+ struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
+ int size;
+ void *desc;
- /* Check that this is a keyboard that speaks the boot protocol. */
- if (uaa->iface == NULL)
- return (UMATCH_NONE);
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id == NULL ||
- id->bInterfaceClass != UICLASS_HID ||
- id->bInterfaceSubClass != UISUBCLASS_BOOT ||
- id->bInterfaceProtocol != UIPROTO_BOOT_KEYBOARD)
+ uhidev_get_report_desc(uha->parent, &desc, &size);
+ if (!hid_is_collection(desc, size, uha->reportid,
+ HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD)))
return (UMATCH_NONE);
- return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
+
+ return (UMATCH_IFACECLASS);
}
USB_ATTACH(ukbd)
{
USB_ATTACH_START(ukbd, sc, uaa);
- usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
- usbd_status err;
+ struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
u_int32_t qflags;
- char devinfo[1024];
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+ const char *parseerr;
struct wskbddev_attach_args a;
-#else
- int i;
-#endif
- sc->sc_udev = uaa->device;
- sc->sc_iface = iface;
- id = usbd_get_interface_descriptor(iface);
- usbd_devinfo(uaa->device, 0, devinfo);
- 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 == NULL) {
- printf("%s: could not read endpoint descriptor\n",
- USBDEVNAME(sc->sc_dev));
+ sc->sc_hdev.sc_intr = ukbd_intr;
+ sc->sc_hdev.sc_parent = uha->parent;
+ sc->sc_hdev.sc_report_id = uha->reportid;
+
+ parseerr = ukbd_parse_desc(sc);
+ if (parseerr != NULL) {
+ printf("\n%s: attach failed, %s\n",
+ sc->sc_hdev.sc_dev.dv_xname, parseerr);
USB_ATTACH_ERROR_RETURN;
}
+
+#ifdef DIAGNOSTIC
+ printf(": %d modifier keys, %d key codes", sc->sc_nmod,
+ sc->sc_nkeycode);
+#endif
+ printf("\n");
- DPRINTFN(10,("ukbd_attach: bLength=%d bDescriptorType=%d "
- "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d"
- " bInterval=%d\n",
- ed->bLength, ed->bDescriptorType,
- ed->bEndpointAddress & UE_ADDR,
- UE_GET_DIR(ed->bEndpointAddress)==UE_DIR_IN? "in" : "out",
- ed->bmAttributes & UE_XFERTYPE,
- UGETW(ed->wMaxPacketSize), ed->bInterval));
-
- if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN ||
- (ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
- printf("%s: unexpected endpoint\n",
- USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
- }
- qflags = usbd_get_quirks(uaa->device)->uq_flags;
- if ((qflags & UQ_NO_SET_PROTO) == 0) {
- err = usbd_set_protocol(iface, 0);
- DPRINTFN(5, ("ukbd_attach: protocol set\n"));
- if (err) {
- printf("%s: set protocol failed\n",
- USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
- }
- }
+ qflags = usbd_get_quirks(uha->parent->sc_udev)->uq_flags;
sc->sc_debounce = (qflags & UQ_SPUR_BUT_UP) != 0;
- /* Ignore if SETIDLE fails since it is not crucial. */
- (void)usbd_set_idle(iface, 0, 0);
-
- sc->sc_ep_addr = ed->bEndpointAddress;
-
/*
* Remember if we're the console keyboard.
*
@@ -398,26 +337,14 @@ USB_ATTACH(ukbd)
a.accessops = &ukbd_accessops;
a.accesscookie = sc;
-#if defined(__OpenBSD__)
-#ifdef WSDISPLAY_COMPAT_RAWKBD
- timeout_set(&sc->sc_rawrepeat_ch, ukbd_rawrepeat, sc);
-#endif
- timeout_set(&sc->sc_delay, ukbd_delayed_decode, sc);
-#endif
-
-#if defined(__NetBSD__)
- callout_init(&sc->sc_rawrepeat_ch);
- callout_init(&sc->sc_delay);
-#endif
+ usb_callout_init(sc->sc_rawrepeat_ch);
+ usb_callout_init(sc->sc_delay);
/* Flash the leds; no real purpose, just shows we're alive. */
ukbd_set_leds(sc, WSKBD_LED_SCROLL | WSKBD_LED_NUM | WSKBD_LED_CAPS);
- usbd_delay_ms(uaa->device, 400);
+ usbd_delay_ms(uha->parent->sc_udev, 400);
ukbd_set_leds(sc, 0);
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
-
sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
USB_ATTACH_SUCCESS_RETURN;
@@ -427,38 +354,27 @@ int
ukbd_enable(void *v, int on)
{
struct ukbd_softc *sc = v;
- usbd_status err;
if (on && sc->sc_dying)
return (EIO);
/* Should only be called to change state */
if (sc->sc_enabled == on) {
-#ifdef UKBD_DEBUG
+#ifdef DIAGNOSTIC
printf("ukbd_enable: %s: bad call on=%d\n",
- USBDEVNAME(sc->sc_dev), on);
+ USBDEVNAME(sc->sc_hdev.sc_dev), on);
#endif
return (EBUSY);
}
DPRINTF(("ukbd_enable: sc=%p on=%d\n", sc, on));
+ sc->sc_enabled = on;
if (on) {
- /* Set up interrupt pipe. */
- err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
- USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc,
- &sc->sc_ndata, sizeof(sc->sc_ndata), ukbd_intr,
- USBD_DEFAULT_INTERVAL);
- if (err)
- return (EIO);
+ return (uhidev_open(&sc->sc_hdev));
} else {
- /* Disable interrupts. */
- usbd_abort_pipe(sc->sc_intrpipe);
- usbd_close_pipe(sc->sc_intrpipe);
- sc->sc_intrpipe = NULL;
+ uhidev_close(&sc->sc_hdev);
+ return (0);
}
- sc->sc_enabled = on;
-
- return (0);
}
int
@@ -507,7 +423,8 @@ USB_DETACH(ukbd)
* XXX Should notify some other keyboard that it can be
* XXX console, if there are any other keyboards.
*/
- printf("%s: was console keyboard\n", USBDEVNAME(sc->sc_dev));
+ printf("%s: was console keyboard\n",
+ USBDEVNAME(sc->sc_hdev.sc_dev));
wskbd_cndetach();
ukbd_is_console = 1;
#endif
@@ -517,37 +434,34 @@ USB_DETACH(ukbd)
rv = config_detach(sc->sc_wskbddev, flags);
/* The console keyboard does not get a disable call, so check pipe. */
- if (sc->sc_intrpipe != NULL) {
- usbd_abort_pipe(sc->sc_intrpipe);
- usbd_close_pipe(sc->sc_intrpipe);
- sc->sc_intrpipe = NULL;
- }
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
+ if (sc->sc_hdev.sc_state & UHIDEV_OPEN)
+ uhidev_close(&sc->sc_hdev);
return (rv);
}
void
-ukbd_intr(xfer, addr, status)
- usbd_xfer_handle xfer;
- usbd_private_handle addr;
- usbd_status status;
+ukbd_intr(struct uhidev *addr, void *ibuf, u_int len)
{
- struct ukbd_softc *sc = addr;
+ struct ukbd_softc *sc = (struct ukbd_softc *)addr;
struct ukbd_data *ud = &sc->sc_ndata;
+ int i;
- DPRINTFN(5, ("ukbd_intr: status=%d\n", status));
- if (status == USBD_CANCELLED)
- return;
-
- if (status) {
- DPRINTF(("ukbd_intr: status=%d\n", status));
- if (status == USBD_STALLED)
- usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
- return;
+#ifdef UKBD_DEBUG
+ if (ukbddebug > 5) {
+ printf("ukbd_intr: data");
+ for (i = 0; i < len; i++)
+ printf(" 0x%02x", ((u_char *)ibuf)[i]);
+ printf("\n");
}
+#endif
+
+ ud->modifiers = 0;
+ for (i = 0; i < sc->sc_nmod; i++)
+ if (hid_get_data(ibuf, &sc->sc_modloc[i]))
+ ud->modifiers |= sc->sc_mods[i].mask;
+ memcpy(ud->keycode, (char *)ibuf + sc->sc_keycodeloc.pos / 8,
+ sc->sc_nkeycode);
if (sc->sc_debounce && !sc->sc_polling) {
/*
@@ -557,12 +471,8 @@ ukbd_intr(xfer, addr, status)
* We avoid this bug by holding off decoding for 20 ms.
*/
sc->sc_data = *ud;
-#if defined(__OpenBSD__)
- timeout_add(&sc->sc_delay, hz / 50);
-#else
- callout_reset(&sc->sc_delay, hz / 50, ukbd_delayed_decode, sc);
-#endif
-#if DDB
+ usb_callout(sc->sc_delay, hz / 50, ukbd_delayed_decode, sc);
+#ifdef DDB
} else if (sc->sc_console_keyboard && !sc->sc_polling) {
/*
* For the console keyboard we can't deliver CTL-ALT-ESC
@@ -571,11 +481,7 @@ ukbd_intr(xfer, addr, status)
* loses bigtime.
*/
sc->sc_data = *ud;
-#if defined(__OpenBSD__)
- timeout_add(&sc->sc_delay, 1); /* NOT an immediate timeout */
-#else
- callout_reset(&sc->sc_delay, 0, ukbd_delayed_decode, sc);
-#endif
+ usb_callout(sc->sc_delay, 1, ukbd_delayed_decode, sc);
#endif
} else {
ukbd_decode(sc, ud);
@@ -607,7 +513,7 @@ ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud)
*/
if (ukbdtrace) {
struct ukbdtraceinfo *p = &ukbdtracedata[ukbdtraceindex];
- p->unit = sc->sc_dev.dv_unit;
+ p->unit = sc->sc_hdev.sc_dev.dv_unit;
microtime(&p->tv);
p->ud = *ud;
if (++ukbdtraceindex >= UKBDTRACESIZE)
@@ -632,19 +538,19 @@ ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud)
mod = ud->modifiers;
omod = sc->sc_odata.modifiers;
if (mod != omod)
- for (i = 0; i < NMOD; i++)
- if (( mod & ukbd_mods[i].mask) !=
- (omod & ukbd_mods[i].mask))
- ADDKEY(ukbd_mods[i].key |
- (mod & ukbd_mods[i].mask
+ for (i = 0; i < sc->sc_nmod; i++)
+ if (( mod & sc->sc_mods[i].mask) !=
+ (omod & sc->sc_mods[i].mask))
+ ADDKEY(sc->sc_mods[i].key |
+ (mod & sc->sc_mods[i].mask
? PRESS : RELEASE));
- if (memcmp(ud->keycode, sc->sc_odata.keycode, NKEYCODE) != 0) {
+ if (memcmp(ud->keycode, sc->sc_odata.keycode, sc->sc_nkeycode) != 0) {
/* Check for released keys. */
- for (i = 0; i < NKEYCODE; i++) {
+ for (i = 0; i < sc->sc_nkeycode; i++) {
key = sc->sc_odata.keycode[i];
if (key == 0)
continue;
- for (j = 0; j < NKEYCODE; j++)
+ for (j = 0; j < sc->sc_nkeycode; j++)
if (key == ud->keycode[j])
goto rfound;
DPRINTFN(3,("ukbd_intr: relse key=0x%02x\n", key));
@@ -654,11 +560,11 @@ ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud)
}
/* Check for pressed keys. */
- for (i = 0; i < NKEYCODE; i++) {
+ for (i = 0; i < sc->sc_nkeycode; i++) {
key = ud->keycode[i];
if (key == 0)
continue;
- for (j = 0; j < NKEYCODE; j++)
+ for (j = 0; j < sc->sc_nkeycode; j++)
if (key == sc->sc_odata.keycode[j])
goto pfound;
DPRINTFN(2,("ukbd_intr: press key=0x%02x\n", key));
@@ -680,7 +586,7 @@ ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud)
}
#ifdef WSDISPLAY_COMPAT_RAWKBD
if (sc->sc_rawkbd) {
- char cbuf[MAXKEYS * 2];
+ u_char cbuf[MAXKEYS * 2];
int c;
int npress;
@@ -708,19 +614,11 @@ ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud)
s = spltty();
wskbd_rawinput(sc->sc_wskbddev, cbuf, j);
splx(s);
-#if defined(__OpenBSD__)
- timeout_del(&sc->sc_rawrepeat_ch);
-#else
- callout_stop(&sc->sc_rawrepeat_ch);
-#endif
+ usb_uncallout(sc->sc_rawrepeat_ch, ukbd_rawrepeat, sc);
if (npress != 0) {
sc->sc_nrep = npress;
-#if defined(__OpenBSD__)
- timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAY1/1000);
-#else
- callout_reset(&sc->sc_rawrepeat_ch,
+ usb_callout(sc->sc_rawrepeat_ch,
hz * REP_DELAY1 / 1000, ukbd_rawrepeat, sc);
-#endif
}
return;
}
@@ -742,21 +640,24 @@ ukbd_set_leds(void *v, int leds)
struct ukbd_softc *sc = v;
u_int8_t res;
- DPRINTF(("ukbd_set_leds: sc=%p leds=%d\n", sc, leds));
+ DPRINTF(("ukbd_set_leds: sc=%p leds=%d, sc_leds=%d\n",
+ sc, leds, sc->sc_leds));
if (sc->sc_dying)
return;
+ if (sc->sc_leds == leds)
+ return;
sc->sc_leds = leds;
res = 0;
- if (leds & WSKBD_LED_SCROLL)
- res |= SCROLL_LOCK;
- if (leds & WSKBD_LED_NUM)
- res |= NUM_LOCK;
- if (leds & WSKBD_LED_CAPS)
- res |= CAPS_LOCK;
- res |= leds & 0xf8;
- usbd_set_report_async(sc->sc_iface, UHID_OUTPUT_REPORT, 0, &res, 1);
+ /* XXX not really right */
+ if ((leds & WSKBD_LED_SCROLL) && sc->sc_scroloc.size == 1)
+ res |= 1 << sc->sc_scroloc.pos;
+ if ((leds & WSKBD_LED_NUM) && sc->sc_numloc.size == 1)
+ res |= 1 << sc->sc_numloc.pos;
+ if ((leds & WSKBD_LED_CAPS) && sc->sc_capsloc.size == 1)
+ res |= 1 << sc->sc_capsloc.pos;
+ uhidev_set_report_async(&sc->sc_hdev, UHID_OUTPUT_REPORT, &res, 1);
}
#ifdef WSDISPLAY_COMPAT_RAWKBD
@@ -769,17 +670,13 @@ ukbd_rawrepeat(void *v)
s = spltty();
wskbd_rawinput(sc->sc_wskbddev, sc->sc_rep, sc->sc_nrep);
splx(s);
-#if defined(__OpenBSD__)
- timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000);
-#else
- callout_reset(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000,
+ usb_callout(sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000,
ukbd_rawrepeat, sc);
-#endif
}
#endif
int
-ukbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
+ukbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
{
struct ukbd_softc *sc = v;
@@ -797,17 +694,19 @@ ukbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
case WSKBDIO_SETMODE:
DPRINTF(("ukbd_ioctl: set raw = %d\n", *(int *)data));
sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
-#if defined(__OpenBSD__)
- timeout_del(&sc->sc_rawrepeat_ch);
-#else
- callout_stop(&sc->sc_rawrepeat_ch);
-#endif
+ usb_uncallout(sc->sc_rawrepeat_ch, ukbd_rawrepeat, sc);
return (0);
#endif
}
return (-1);
}
+/*
+ * This is a hack to work around some broken ports that don't call
+ * cnpollc() before cngetc().
+ */
+static int pollenter, warned;
+
/* Console interface. */
void
ukbd_cngetc(void *v, u_int *type, int *data)
@@ -815,12 +714,25 @@ ukbd_cngetc(void *v, u_int *type, int *data)
struct ukbd_softc *sc = v;
int s;
int c;
+ int broken;
+
+ if (pollenter == 0) {
+ if (!warned) {
+ printf("\n"
+"This port is broken, it does not call cnpollc() before calling cngetc().\n"
+"This should be fixed, but it will work anyway (for now).\n");
+ warned = 1;
+ }
+ broken = 1;
+ ukbd_cnpollc(v, 1);
+ } else
+ broken = 0;
DPRINTFN(0,("ukbd_cngetc: enter\n"));
s = splusb();
sc->sc_polling = 1;
while(sc->sc_npollchar <= 0)
- usbd_dopoll(sc->sc_iface);
+ usbd_dopoll(sc->sc_hdev.sc_parent->sc_iface);
sc->sc_polling = 0;
c = sc->sc_pollchars[0];
sc->sc_npollchar--;
@@ -830,6 +742,8 @@ ukbd_cngetc(void *v, u_int *type, int *data)
*data = c & CODEMASK;
splx(s);
DPRINTFN(0,("ukbd_cngetc: return 0x%02x\n", c));
+ if (broken)
+ ukbd_cnpollc(v, 0);
}
void
@@ -840,7 +754,8 @@ ukbd_cnpollc(void *v, int on)
DPRINTFN(2,("ukbd_cnpollc: sc=%p on=%d\n", v, on));
- (void)usbd_interface2device_handle(sc->sc_iface,&dev);
+ usbd_interface2device_handle(sc->sc_hdev.sc_parent->sc_iface, &dev);
+ if (on) pollenter++; else pollenter--;
usbd_set_polling(dev, on);
}
@@ -856,3 +771,64 @@ ukbd_cnattach(void)
ukbd_is_console = 1;
return (0);
}
+
+const char *
+ukbd_parse_desc(struct ukbd_softc *sc)
+{
+ struct hid_data *d;
+ struct hid_item h;
+ int size;
+ void *desc;
+ int imod;
+
+ uhidev_get_report_desc(sc->sc_hdev.sc_parent, &desc, &size);
+ imod = 0;
+ sc->sc_nkeycode = 0;
+ d = hid_start_parse(desc, size, hid_input);
+ while (hid_get_item(d, &h)) {
+ /*printf("ukbd: id=%d kind=%d usage=0x%x flags=0x%x pos=%d size=%d cnt=%d\n",
+ h.report_ID, h.kind, h.usage, h.flags, h.loc.pos, h.loc.size, h.loc.count);*/
+ if (h.kind != hid_input || (h.flags & HIO_CONST) ||
+ HID_GET_USAGE_PAGE(h.usage) != HUP_KEYBOARD ||
+ h.report_ID != sc->sc_hdev.sc_report_id)
+ continue;
+ DPRINTF(("ukbd: imod=%d usage=0x%x flags=0x%x pos=%d size=%d "
+ "cnt=%d\n", imod,
+ h.usage, h.flags, h.loc.pos, h.loc.size, h.loc.count));
+ if (h.flags & HIO_VARIABLE) {
+ if (h.loc.size != 1)
+ return ("bad modifier size");
+ /* Single item */
+ if (imod < MAXMOD) {
+ sc->sc_modloc[imod] = h.loc;
+ sc->sc_mods[imod].mask = 1 << imod;
+ sc->sc_mods[imod].key = HID_GET_USAGE(h.usage);
+ imod++;
+ } else
+ return ("too many modifier keys");
+ } else {
+ /* Array */
+ if (h.loc.size != 8)
+ return ("key code size != 8");
+ if (h.loc.count > MAXKEYCODE)
+ return ("too many key codes");
+ if (h.loc.pos % 8 != 0)
+ return ("key codes not on byte boundary");
+ if (sc->sc_nkeycode != 0)
+ return ("multiple key code arrays\n");
+ sc->sc_keycodeloc = h.loc;
+ sc->sc_nkeycode = h.loc.count;
+ }
+ }
+ sc->sc_nmod = imod;
+ hid_end_parse(d);
+
+ hid_locate(desc, size, HID_USAGE2(HUP_LEDS, HUD_LED_NUM_LOCK),
+ sc->sc_hdev.sc_report_id, hid_output, &sc->sc_numloc, NULL);
+ hid_locate(desc, size, HID_USAGE2(HUP_LEDS, HUD_LED_CAPS_LOCK),
+ sc->sc_hdev.sc_report_id, hid_output, &sc->sc_capsloc, NULL);
+ hid_locate(desc, size, HID_USAGE2(HUP_LEDS, HUD_LED_SCROLL_LOCK),
+ sc->sc_hdev.sc_report_id, hid_output, &sc->sc_scroloc, NULL);
+
+ return (NULL);
+}
diff --git a/sys/dev/usb/ums.c b/sys/dev/usb/ums.c
index 8bd88b43c81..324e5119a2c 100644
--- a/sys/dev/usb/ums.c
+++ b/sys/dev/usb/ums.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ums.c,v 1.8 2002/05/07 18:29:18 nate Exp $ */
-/* $NetBSD: ums.c,v 1.49 2001/10/26 17:58:21 augustss Exp $ */
+/* $OpenBSD: ums.c,v 1.9 2002/05/09 15:06:29 nate Exp $ */
+/* $NetBSD: ums.c,v 1.55 2001/12/31 12:15:22 augustss Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -42,8 +42,6 @@
* HID spec: http://www.usb.org/developers/data/devclass/hid1_1.pdf
*/
-/* XXX complete SPUR_UP change */
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -64,6 +62,7 @@
#include <dev/usb/usbdi_util.h>
#include <dev/usb/usbdevs.h>
#include <dev/usb/usb_quirks.h>
+#include <dev/usb/uhidev.h>
#include <dev/usb/hid.h>
#include <dev/wscons/wsconsio.h>
@@ -87,18 +86,13 @@ int umsdebug = 0;
#define PS2MBUTMASK x04
#define PS2BUTMASK 0x0f
+#define MAX_BUTTONS 7 /* must not exceed size of sc_buttons */
+
struct ums_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;
-
- u_char *sc_ibuf;
- u_int8_t sc_iid;
- int sc_isize;
+ struct uhidev sc_hdev;
+
struct hid_location sc_loc_x, sc_loc_y, sc_loc_z;
- struct hid_location *sc_loc_btn;
+ struct hid_location sc_loc_btn[MAX_BUTTONS];
int sc_enabled;
@@ -108,7 +102,6 @@ struct ums_softc {
#define UMS_REVZ 0x04 /* Z-axis is reversed */
int nbuttons;
-#define MAX_BUTTONS 31 /* chosen because sc_buttons is u_int32_t */
u_int32_t sc_buttons; /* mouse button status */
struct device *sc_wsmousedev;
@@ -119,11 +112,11 @@ struct ums_softc {
#define MOUSE_FLAGS_MASK (HIO_CONST|HIO_RELATIVE)
#define MOUSE_FLAGS (HIO_RELATIVE)
-Static void ums_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
+Static void ums_intr(struct uhidev *addr, void *ibuf, u_int len);
Static int ums_enable(void *);
Static void ums_disable(void *);
-Static int ums_ioctl(void *, u_long, caddr_t, int, struct proc *);
+Static int ums_ioctl(void *, u_long, caddr_t, int, usb_proc_ptr);
const struct wsmouse_accessops ums_accessops = {
ums_enable,
@@ -136,115 +129,72 @@ USB_DECLARE_DRIVER(ums);
USB_MATCH(ums)
{
USB_MATCH_START(ums, uaa);
- usb_interface_descriptor_t *id;
- int size, ret;
+ struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
+ int size;
void *desc;
- usbd_status err;
- if (uaa->iface == NULL)
- return (UMATCH_NONE);
- id = usbd_get_interface_descriptor(uaa->iface);
- if (id == NULL || id->bInterfaceClass != UICLASS_HID)
+ uhidev_get_report_desc(uha->parent, &desc, &size);
+ if (!hid_is_collection(desc, size, uha->reportid,
+ HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)))
return (UMATCH_NONE);
- err = usbd_read_report_desc(uaa->iface, &desc, &size, M_TEMP);
- if (err)
- return (UMATCH_NONE);
-
- if (hid_is_collection(desc, size,
- HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)))
- ret = UMATCH_IFACECLASS;
- else
- ret = UMATCH_NONE;
-
- free(desc, M_TEMP);
- return (ret);
+ return (UMATCH_IFACECLASS);
}
USB_ATTACH(ums)
{
USB_ATTACH_START(ums, sc, uaa);
- usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *id;
- usb_endpoint_descriptor_t *ed;
+ struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
struct wsmousedev_attach_args a;
int size;
void *desc;
- usbd_status err;
- char devinfo[1024];
u_int32_t flags, quirks;
int i, wheel;
struct hid_location loc_btn;
-
- sc->sc_udev = uaa->device;
- sc->sc_iface = iface;
- id = usbd_get_interface_descriptor(iface);
- usbd_devinfo(uaa->device, 0, devinfo);
- 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 == NULL) {
- printf("%s: could not read endpoint descriptor\n",
- USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
- }
- DPRINTFN(10,("ums_attach: bLength=%d bDescriptorType=%d "
- "bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketSize=%d"
- " bInterval=%d\n",
- ed->bLength, ed->bDescriptorType,
- ed->bEndpointAddress & UE_ADDR,
- UE_GET_DIR(ed->bEndpointAddress)==UE_DIR_IN? "in" : "out",
- ed->bmAttributes & UE_XFERTYPE,
- UGETW(ed->wMaxPacketSize), ed->bInterval));
-
- if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN ||
- (ed->bmAttributes & UE_XFERTYPE) != UE_INTERRUPT) {
- printf("%s: unexpected endpoint\n",
- USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
- }
+ sc->sc_hdev.sc_intr = ums_intr;
+ sc->sc_hdev.sc_parent = uha->parent;
+ sc->sc_hdev.sc_report_id = uha->reportid;
- quirks = usbd_get_quirks(uaa->device)->uq_flags;
+ quirks = usbd_get_quirks(uha->parent->sc_udev)->uq_flags;
if (quirks & UQ_MS_REVZ)
sc->flags |= UMS_REVZ;
if (quirks & UQ_SPUR_BUT_UP)
sc->flags |= UMS_SPUR_BUT_UP;
- err = usbd_read_report_desc(uaa->iface, &desc, &size, M_TEMP);
- if (err)
- USB_ATTACH_ERROR_RETURN;
+ uhidev_get_report_desc(uha->parent, &desc, &size);
if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
- hid_input, &sc->sc_loc_x, &flags)) {
- printf("%s: mouse has no X report\n", USBDEVNAME(sc->sc_dev));
+ uha->reportid, hid_input, &sc->sc_loc_x, &flags)) {
+ printf("\n%s: mouse has no X report\n",
+ USBDEVNAME(sc->sc_hdev.sc_dev));
USB_ATTACH_ERROR_RETURN;
}
if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
- printf("%s: X report 0x%04x not supported\n",
- USBDEVNAME(sc->sc_dev), flags);
+ printf("\n%s: X report 0x%04x not supported\n",
+ USBDEVNAME(sc->sc_hdev.sc_dev), flags);
USB_ATTACH_ERROR_RETURN;
}
if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y),
- hid_input, &sc->sc_loc_y, &flags)) {
- printf("%s: mouse has no Y report\n", USBDEVNAME(sc->sc_dev));
+ uha->reportid, hid_input, &sc->sc_loc_y, &flags)) {
+ printf("\n%s: mouse has no Y report\n",
+ USBDEVNAME(sc->sc_hdev.sc_dev));
USB_ATTACH_ERROR_RETURN;
}
if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
- printf("%s: Y report 0x%04x not supported\n",
- USBDEVNAME(sc->sc_dev), flags);
+ printf("\n%s: Y report 0x%04x not supported\n",
+ USBDEVNAME(sc->sc_hdev.sc_dev), flags);
USB_ATTACH_ERROR_RETURN;
}
/* Try to guess the Z activator: first check Z, then WHEEL. */
wheel = 0;
if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Z),
- hid_input, &sc->sc_loc_z, &flags) ||
+ uha->reportid, hid_input, &sc->sc_loc_z, &flags) ||
(wheel = hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP,
HUG_WHEEL),
- hid_input, &sc->sc_loc_z, &flags))) {
+ uha->reportid, hid_input, &sc->sc_loc_z, &flags))) {
if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
sc->sc_loc_z.size = 0; /* Bad Z coord, ignore it */
} else {
@@ -258,34 +208,18 @@ USB_ATTACH(ums)
/* figure out the number of buttons */
for (i = 1; i <= MAX_BUTTONS; i++)
if (!hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
- hid_input, &loc_btn, 0))
+ uha->reportid, hid_input, &loc_btn, 0))
break;
sc->nbuttons = i - 1;
- sc->sc_loc_btn = malloc(sizeof(struct hid_location) * sc->nbuttons,
- M_USBDEV, M_NOWAIT);
- if (!sc->sc_loc_btn) {
- printf("%s: no memory\n", USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
- }
- printf("%s: %d button%s%s\n", USBDEVNAME(sc->sc_dev),
+ printf(": %d button%s%s\n",
sc->nbuttons, sc->nbuttons == 1 ? "" : "s",
sc->flags & UMS_Z ? " and Z dir." : "");
for (i = 1; i <= sc->nbuttons; i++)
hid_locate(desc, size, HID_USAGE2(HUP_BUTTON, i),
- hid_input, &sc->sc_loc_btn[i-1], 0);
-
- sc->sc_isize = hid_report_size(desc, size, hid_input, &sc->sc_iid);
- sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_NOWAIT);
- if (sc->sc_ibuf == NULL) {
- printf("%s: no memory\n", USBDEVNAME(sc->sc_dev));
- free(sc->sc_loc_btn, M_USBDEV);
- USB_ATTACH_ERROR_RETURN;
- }
-
- sc->sc_ep_addr = ed->bEndpointAddress;
- free(desc, M_TEMP);
+ uha->reportid, hid_input,
+ &sc->sc_loc_btn[i-1], 0);
#ifdef USB_DEBUG
DPRINTF(("ums_attach: sc=%p\n", sc));
@@ -300,15 +234,11 @@ USB_ATTACH(ums)
DPRINTF(("ums_attach: B%d\t%d/%d\n",
i, sc->sc_loc_btn[i-1].pos,sc->sc_loc_btn[i-1].size));
}
- DPRINTF(("ums_attach: size=%d, id=%d\n", sc->sc_isize, sc->sc_iid));
#endif
a.accessops = &ums_accessops;
a.accesscookie = sc;
- usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
-
sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
USB_ATTACH_SUCCESS_RETURN;
@@ -344,45 +274,21 @@ USB_DETACH(ums)
/* No need to do reference counting of ums, wsmouse has all the goo. */
if (sc->sc_wsmousedev != NULL)
rv = config_detach(sc->sc_wsmousedev, flags);
- if (rv == 0) {
- free(sc->sc_loc_btn, M_USBDEV);
- free(sc->sc_ibuf, M_USBDEV);
- }
-
- usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
- USBDEV(sc->sc_dev));
return (rv);
}
void
-ums_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
+ums_intr(struct uhidev *addr, void *ibuf, u_int len)
{
- struct ums_softc *sc = addr;
- u_char *ibuf;
+ struct ums_softc *sc = (struct ums_softc *)addr;
int dx, dy, dz;
u_int32_t buttons = 0;
int i;
int s;
- DPRINTFN(5, ("ums_intr: sc=%p status=%d\n", sc, status));
- DPRINTFN(5, ("ums_intr: data = %02x %02x %02x\n",
- sc->sc_ibuf[0], sc->sc_ibuf[1], sc->sc_ibuf[2]));
-
- if (status == USBD_CANCELLED)
- return;
-
- if (status) {
- DPRINTF(("ums_intr: status=%d\n", status));
- usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
- return;
- }
+ DPRINTFN(5,("ums_intr: len=%d\n", len));
- ibuf = sc->sc_ibuf;
- if (sc->sc_iid != 0) {
- if (*ibuf++ != sc->sc_iid)
- return;
- }
dx = hid_get_data(ibuf, &sc->sc_loc_x);
dy = -hid_get_data(ibuf, &sc->sc_loc_y);
dz = hid_get_data(ibuf, &sc->sc_loc_z);
@@ -410,8 +316,6 @@ ums_enable(void *v)
{
struct ums_softc *sc = v;
- usbd_status err;
-
DPRINTFN(1,("ums_enable: sc=%p\n", sc));
if (sc->sc_dying)
@@ -423,17 +327,7 @@ ums_enable(void *v)
sc->sc_enabled = 1;
sc->sc_buttons = 0;
- /* Set up interrupt pipe. */
- 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, ums_intr, USBD_DEFAULT_INTERVAL);
- if (err) {
- DPRINTF(("ums_enable: usbd_open_pipe_intr failed, error=%d\n",
- err));
- sc->sc_enabled = 0;
- return (EIO);
- }
- return (0);
+ return (uhidev_open(&sc->sc_hdev));
}
Static void
@@ -449,15 +343,12 @@ ums_disable(void *v)
}
#endif
- /* Disable interrupts. */
- usbd_abort_pipe(sc->sc_intrpipe);
- usbd_close_pipe(sc->sc_intrpipe);
-
sc->sc_enabled = 0;
+ return (uhidev_close(&sc->sc_hdev));
}
Static int
-ums_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
+ums_ioctl(void *v, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
{
switch (cmd) {
diff --git a/sys/dev/usb/usb.h b/sys/dev/usb/usb.h
index 89121f65dec..8defac116a4 100644
--- a/sys/dev/usb/usb.h
+++ b/sys/dev/usb/usb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: usb.h,v 1.17 2002/05/07 18:29:18 nate Exp $ */
+/* $OpenBSD: usb.h,v 1.18 2002/05/09 15:06:29 nate Exp $ */
/* $NetBSD: usb.h,v 1.52 2001/07/23 15:17:50 nathanw Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb.h,v 1.14 1999/11/17 22:33:46 n_hibma Exp $ */
@@ -588,6 +588,7 @@ struct usb_event {
#define USB_SET_IMMED _IOW ('U', 22, int)
#define USB_GET_REPORT _IOWR('U', 23, struct usb_ctl_report)
#define USB_SET_REPORT _IOW ('U', 24, struct usb_ctl_report)
+#define USB_GET_REPORT_ID _IOR ('U', 25, int)
/* Generic USB device */
#define USB_GET_CONFIG _IOR ('U', 100, int)
diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h
index bb15013ec29..1031618e4ab 100644
--- a/sys/dev/usb/usb_port.h
+++ b/sys/dev/usb/usb_port.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: usb_port.h,v 1.37 2002/05/07 18:29:18 nate Exp $ */
+/* $OpenBSD: usb_port.h,v 1.38 2002/05/09 15:06:29 nate Exp $ */
/* $NetBSD: usb_port.h,v 1.44 2001/05/14 20:35:29 bouyer Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_port.h,v 1.21 1999/11/17 22:33:47 n_hibma Exp $ */
@@ -190,6 +190,7 @@ __CONCAT(dname,_detach)(self, flags) \
*/
#ifdef USB_DEBUG
#define UKBD_DEBUG 1
+#define UHIDEV_DEBUG 1
#define UHID_DEBUG 1
#define OHCI_DEBUG 1
#define UGEN_DEBUG 1
@@ -235,6 +236,8 @@ __CONCAT(dname,_detach)(self, flags) \
#define show_scsipi_cmd show_scsi_cmd
#define xs_control flags
#define xs_status status
+#define UHIDBUSCF_REPORTID -1
+#define UHIDBUSCF_REPORTID_DEFAULT -1
#define bswap32(x) swap32(x)
#define bswap16(x) swap16(x)
diff --git a/sys/dev/usb/usbhid.h b/sys/dev/usb/usbhid.h
index 695c1cdb925..d88c6d375ee 100644
--- a/sys/dev/usb/usbhid.h
+++ b/sys/dev/usb/usbhid.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: usbhid.h,v 1.6 2002/05/07 18:29:19 nate Exp $ */
-/* $NetBSD: usbhid.h,v 1.9 2000/09/03 19:09:14 augustss Exp $ */
+/* $OpenBSD: usbhid.h,v 1.7 2002/05/09 15:06:29 nate Exp $ */
+/* $NetBSD: usbhid.h,v 1.11 2001/12/28 00:20:24 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbhid.h,v 1.7 1999/11/17 22:33:51 n_hibma Exp $ */
/*
@@ -165,12 +165,25 @@ typedef struct usb_hid_descriptor {
#define HUD_ERASER 0x0045
#define HUD_TABLET_PICK 0x0046
-#define HID_USAGE2(p,u) (((p) << 16) | u)
+/* Usages LEDs */
+#define HUD_LED_NUM_LOCK 0x0001
+#define HUD_LED_CAPS_LOCK 0x0002
+#define HUD_LED_SCROLL_LOCK 0x0003
+#define HUD_LED_COMPOSE 0x0004
+#define HUD_LED_KANA 0x0005
+
+#define HID_USAGE2(p, u) (((p) << 16) | u)
+#define HID_GET_USAGE(u) ((u) & 0xffff)
+#define HID_GET_USAGE_PAGE(u) (((u) >> 16) & 0xffff)
#define UHID_INPUT_REPORT 0x01
#define UHID_OUTPUT_REPORT 0x02
#define UHID_FEATURE_REPORT 0x03
+#define HCOLL_PHYSICAL 0
+#define HCOLL_APPLICATION 1
+#define HCOLL_LOGICAL 2
+
/* Bits in the input/output/feature items */
#define HIO_CONST 0x001
#define HIO_VARIABLE 0x002