[Midnightbsd-cvs] src: ums.c: merge freebsd 7 changes.
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sat Nov 29 11:21:48 EST 2008
Log Message:
-----------
merge freebsd 7 changes. Keep the apple mighty mouse hack
Modified Files:
--------------
src/sys/dev/usb:
ums.c (r1.3 -> r1.4)
-------------- next part --------------
Index: ums.c
===================================================================
RCS file: /home/cvs/src/sys/dev/usb/ums.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -L sys/dev/usb/ums.c -L sys/dev/usb/ums.c -u -r1.3 -r1.4
--- sys/dev/usb/ums.c
+++ sys/dev/usb/ums.c
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/usb/ums.c,v 1.77.2.2 2006/02/06 20:29:17 netchild Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/usb/ums.c,v 1.96 2007/07/25 06:43:06 imp Exp $");
/*
* HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
@@ -53,11 +53,7 @@
#include <sys/fcntl.h>
#include <sys/tty.h>
#include <sys/file.h>
-#if __FreeBSD_version >= 500014
#include <sys/selinfo.h>
-#else
-#include <sys/select.h>
-#endif
#include <sys/poll.h>
#include <sys/sysctl.h>
#include <sys/uio.h>
@@ -71,15 +67,11 @@
#include <dev/usb/usb_quirks.h>
#include <dev/usb/hid.h>
-#if __FreeBSD_version >= 500000
#include <sys/mouse.h>
-#else
-#include <machine/mouse.h>
-#endif
#ifdef USB_DEBUG
-#define DPRINTF(x) if (umsdebug) logprintf x
-#define DPRINTFN(n,x) if (umsdebug>(n)) logprintf x
+#define DPRINTF(x) if (umsdebug) printf x
+#define DPRINTFN(n,x) if (umsdebug>(n)) printf x
int umsdebug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, ums, CTLFLAG_RW, 0, "USB ums");
SYSCTL_INT(_hw_usb_ums, OID_AUTO, debug, CTLFLAG_RW,
@@ -107,7 +99,7 @@
struct hid_location sc_loc_x, sc_loc_y, sc_loc_z, sc_loc_t;
struct hid_location *sc_loc_btn;
- usb_callout_t callout_handle; /* for spurious button ups */
+ struct callout callout_handle; /* for spurious button ups */
int sc_enabled;
int sc_disconnected; /* device is gone */
@@ -137,24 +129,24 @@
#define MOUSE_FLAGS_MASK (HIO_CONST|HIO_RELATIVE)
#define MOUSE_FLAGS (HIO_RELATIVE)
-Static void ums_intr(usbd_xfer_handle xfer,
+static void ums_intr(usbd_xfer_handle xfer,
usbd_private_handle priv, usbd_status status);
-Static void ums_add_to_queue(struct ums_softc *sc,
+static void ums_add_to_queue(struct ums_softc *sc,
int dx, int dy, int dz, int dt, int buttons);
-Static void ums_add_to_queue_timeout(void *priv);
+static void ums_add_to_queue_timeout(void *priv);
-Static int ums_enable(void *);
-Static void ums_disable(void *);
+static int ums_enable(void *);
+static void ums_disable(void *);
-Static d_open_t ums_open;
-Static d_close_t ums_close;
-Static d_read_t ums_read;
-Static d_ioctl_t ums_ioctl;
-Static d_poll_t ums_poll;
+static d_open_t ums_open;
+static d_close_t ums_close;
+static d_read_t ums_read;
+static d_ioctl_t ums_ioctl;
+static d_poll_t ums_poll;
-Static struct cdevsw ums_cdevsw = {
+static struct cdevsw ums_cdevsw = {
.d_version = D_VERSION,
.d_flags = D_NEEDGIANT,
.d_open = ums_open,
@@ -163,16 +155,33 @@
.d_ioctl = ums_ioctl,
.d_poll = ums_poll,
.d_name = "ums",
-#if __FreeBSD_version < 500014
- .d_bmaj -1
-#endif
};
-USB_DECLARE_DRIVER(ums);
+static device_probe_t ums_match;
+static device_attach_t ums_attach;
+static device_detach_t ums_detach;
+
+static device_method_t ums_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ums_match),
+ DEVMETHOD(device_attach, ums_attach),
+ DEVMETHOD(device_detach, ums_detach),
+
+ { 0, 0 }
+};
-USB_MATCH(ums)
+static driver_t ums_driver = {
+ "ums",
+ ums_methods,
+ sizeof(struct ums_softc)
+};
+
+static devclass_t ums_devclass;
+
+static int
+ums_match(device_t self)
{
- USB_MATCH_START(ums, uaa);
+ struct usb_attach_arg *uaa = device_get_ivars(self);
usb_interface_descriptor_t *id;
int size, ret;
void *desc;
@@ -188,8 +197,9 @@
if (err)
return (UMATCH_NONE);
- if (hid_is_collection(desc, size,
- HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE)))
+ if (id->bInterfaceClass == UICLASS_HID &&
+ id->bInterfaceSubClass == UISUBCLASS_BOOT &&
+ id->bInterfaceProtocol == UIPROTO_MOUSE)
ret = UMATCH_IFACECLASS;
else
ret = UMATCH_NONE;
@@ -198,16 +208,17 @@
return (ret);
}
-USB_ATTACH(ums)
+static int
+ums_attach(device_t self)
{
- USB_ATTACH_START(ums, sc, uaa);
+ struct ums_softc *sc = device_get_softc(self);
+ struct usb_attach_arg *uaa = device_get_ivars(self);
usbd_interface_handle iface = uaa->iface;
usb_interface_descriptor_t *id;
usb_endpoint_descriptor_t *ed;
int size;
void *desc;
usbd_status err;
- char devinfo[1024];
u_int32_t flags;
int i;
struct hid_location loc_btn;
@@ -215,13 +226,12 @@
sc->sc_disconnected = 1;
sc->sc_iface = iface;
id = usbd_get_interface_descriptor(iface);
- usbd_devinfo(uaa->device, USBD_SHOW_INTERFACE_CLASS, devinfo);
- USB_ATTACH_SETUP;
+ sc->sc_dev = self;
ed = usbd_interface2endpoint_descriptor(iface, 0);
if (!ed) {
printf("%s: could not read endpoint descriptor\n",
- USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
+ device_get_nameunit(sc->sc_dev));
+ return ENXIO;
}
DPRINTFN(10,("ums_attach: bLength=%d bDescriptorType=%d "
@@ -236,34 +246,34 @@
if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN ||
UE_GET_XFERTYPE(ed->bmAttributes) != UE_INTERRUPT) {
printf("%s: unexpected endpoint\n",
- USBDEVNAME(sc->sc_dev));
- USB_ATTACH_ERROR_RETURN;
+ device_get_nameunit(sc->sc_dev));
+ return ENXIO;
}
err = usbd_read_report_desc(uaa->iface, &desc, &size, M_TEMP);
if (err)
- USB_ATTACH_ERROR_RETURN;
+ return ENXIO;
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));
- USB_ATTACH_ERROR_RETURN;
+ printf("%s: mouse has no X report\n", device_get_nameunit(sc->sc_dev));
+ return ENXIO;
}
if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
printf("%s: X report 0x%04x not supported\n",
- USBDEVNAME(sc->sc_dev), flags);
- USB_ATTACH_ERROR_RETURN;
+ device_get_nameunit(sc->sc_dev), flags);
+ return ENXIO;
}
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));
- USB_ATTACH_ERROR_RETURN;
+ printf("%s: mouse has no Y report\n", device_get_nameunit(sc->sc_dev));
+ return ENXIO;
}
if ((flags & MOUSE_FLAGS_MASK) != MOUSE_FLAGS) {
printf("%s: Y report 0x%04x not supported\n",
- USBDEVNAME(sc->sc_dev), flags);
- USB_ATTACH_ERROR_RETURN;
+ device_get_nameunit(sc->sc_dev), flags);
+ return ENXIO;
}
/* Apple's Mighty Mouse reports HUG_Z as horizontal scrolling and
@@ -288,11 +298,13 @@
}
}
- /* The Microsoft Wireless Intellimouse 2.0 reports it's wheel
+ /*
+ * The Microsoft Wireless Intellimouse 2.0 reports it's wheel
* using 0x0048 (i've called it HUG_TWHEEL) and seems to expect
* you to know that the byte after the wheel is the tilt axis.
* There are no other HID axis descriptors other than X,Y and
- * TWHEEL */
+ * TWHEEL
+ */
if (hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_TWHEEL),
hid_input, &sc->sc_loc_t, &flags)) {
sc->sc_loc_t.pos = sc->sc_loc_t.pos + 8;
@@ -308,11 +320,11 @@
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: no memory\n", device_get_nameunit(sc->sc_dev));
+ return ENXIO;
}
- printf("%s: %d buttons%s%s.\n", USBDEVNAME(sc->sc_dev),
+ printf("%s: %d buttons%s%s.\n", device_get_nameunit(sc->sc_dev),
sc->nbuttons, sc->flags & UMS_Z? " and Z dir" : "",
sc->flags & UMS_T?" and a TILT dir": "");
@@ -323,9 +335,30 @@
sc->sc_isize = hid_report_size(desc, size, hid_input, &sc->sc_iid);
sc->sc_ibuf = malloc(sc->sc_isize, M_USB, M_NOWAIT);
if (!sc->sc_ibuf) {
- printf("%s: no memory\n", USBDEVNAME(sc->sc_dev));
+ printf("%s: no memory\n", device_get_nameunit(sc->sc_dev));
free(sc->sc_loc_btn, M_USB);
- USB_ATTACH_ERROR_RETURN;
+ return ENXIO;
+ }
+
+ /*
+ * The Microsoft Wireless Notebook Optical Mouse seems to be in worse
+ * shape than the Wireless Intellimouse 2.0, as its X, Y, wheel, and
+ * all of its other button positions are all off. It also reports that
+ * it has two addional buttons and a tilt wheel.
+ */
+ if (usbd_get_quirks(uaa->device)->uq_flags & UQ_MS_BAD_CLASS) {
+ sc->flags = UMS_Z;
+ sc->flags |= UMS_SPUR_BUT_UP;
+ sc->nbuttons = 3;
+ sc->sc_isize = 5;
+ sc->sc_iid = 0;
+ /* 1st byte of descriptor report contains garbage */
+ sc->sc_loc_x.pos = 16;
+ sc->sc_loc_y.pos = 24;
+ sc->sc_loc_z.pos = 32;
+ sc->sc_loc_btn[0].pos = 8;
+ sc->sc_loc_btn[1].pos = 9;
+ sc->sc_loc_btn[2].pos = 10;
}
sc->sc_ep_addr = ed->bEndpointAddress;
@@ -369,27 +402,22 @@
sc->status.button = sc->status.obutton = 0;
sc->status.dx = sc->status.dy = sc->status.dz = 0;
-#ifndef __FreeBSD__
- sc->rsel.si_flags = 0;
- sc->rsel.si_pid = 0;
-#endif
-
sc->dev = make_dev(&ums_cdevsw, device_get_unit(self),
UID_ROOT, GID_OPERATOR,
0644, "ums%d", device_get_unit(self));
- usb_callout_init(sc->callout_handle);
+ callout_init(&sc->callout_handle, 0);
if (usbd_get_quirks(uaa->device)->uq_flags & UQ_SPUR_BUT_UP) {
DPRINTF(("%s: Spurious button up events\n",
- USBDEVNAME(sc->sc_dev)));
+ device_get_nameunit(sc->sc_dev)));
sc->flags |= UMS_SPUR_BUT_UP;
}
- USB_ATTACH_SUCCESS_RETURN;
+ return 0;
}
-Static int
+static int
ums_detach(device_t self)
{
struct ums_softc *sc = device_get_softc(self);
@@ -397,7 +425,7 @@
if (sc->sc_enabled)
ums_disable(sc);
- DPRINTF(("%s: disconnected\n", USBDEVNAME(self)));
+ DPRINTF(("%s: disconnected\n", device_get_nameunit(self)));
free(sc->sc_loc_btn, M_USB);
free(sc->sc_ibuf, M_USB);
@@ -425,10 +453,7 @@
}
void
-ums_intr(xfer, addr, status)
- usbd_xfer_handle xfer;
- usbd_private_handle addr;
- usbd_status status;
+ums_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
{
struct ums_softc *sc = addr;
u_char *ibuf;
@@ -466,12 +491,20 @@
* This should sort that.
* Currently it's the only user of UMS_T so use it as an identifier.
* We probably should switch to some more official quirk.
+ *
+ * UPDATE: This problem affects the M$ Wireless Notebook Optical Mouse,
+ * too. However, the leading byte for this mouse is normally 0x11,
+ * and the phantom mouse click occurs when its 0x14.
*/
if (sc->flags & UMS_T) {
if (sc->sc_iid) {
if (*ibuf++ == 0x02)
return;
}
+ } else if (sc->flags & UMS_SPUR_BUT_UP) {
+ DPRINTFN(5, ("ums_intr: #### ibuf[0] =3D %d ####\n", *ibuf));
+ if (*ibuf == 0x14 || *ibuf == 0x15)
+ return;
} else {
if (sc->sc_iid) {
if (*ibuf++ != sc->sc_iid)
@@ -517,17 +550,16 @@
*/
if (sc->flags & UMS_SPUR_BUT_UP &&
dx == 0 && dy == 0 && dz == 0 && dt == 0 && buttons == 0) {
- usb_callout(sc->callout_handle, MS_TO_TICKS(50 /*msecs*/),
- ums_add_to_queue_timeout, (void *) sc);
+ callout_reset(&sc->callout_handle, MS_TO_TICKS(50),
+ ums_add_to_queue_timeout, (void *) sc);
} else {
- usb_uncallout(sc->callout_handle,
- ums_add_to_queue_timeout, (void *) sc);
+ callout_stop(&sc->callout_handle);
ums_add_to_queue(sc, dx, dy, dz, dt, buttons);
}
}
}
-Static void
+static void
ums_add_to_queue_timeout(void *priv)
{
struct ums_softc *sc = priv;
@@ -538,7 +570,7 @@
splx(s);
}
-Static void
+static void
ums_add_to_queue(struct ums_softc *sc, int dx, int dy, int dz, int dt, int buttons)
{
/* Discard data in case of full buffer */
@@ -586,7 +618,7 @@
selwakeuppri(&sc->rsel, PZERO);
}
}
-Static int
+static int
ums_enable(v)
void *v;
{
@@ -606,6 +638,14 @@
callout_handle_init((struct callout_handle *)&sc->callout_handle);
+ /*
+ * Force the report (non-boot) protocol.
+ *
+ * Mice without boot protocol support may choose not to implement
+ * Set_Protocol at all; do not check for error.
+ */
+ usbd_set_protocol(sc->sc_iface, 1);
+
/* Set up interrupt pipe. */
err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc,
@@ -620,13 +660,13 @@
return (0);
}
-Static void
+static void
ums_disable(priv)
void *priv;
{
struct ums_softc *sc = priv;
- usb_uncallout(sc->callout_handle, ums_add_to_queue_timeout, sc);
+ callout_stop(&sc->callout_handle);
/* Disable interrupts. */
usbd_abort_pipe(sc->sc_intrpipe);
@@ -638,23 +678,24 @@
DPRINTF(("Discarded %d bytes in queue\n", sc->qcount));
}
-Static int
-ums_open(struct cdev *dev, int flag, int fmt, usb_proc_ptr p)
+static int
+ums_open(struct cdev *dev, int flag, int fmt, struct thread *p)
{
struct ums_softc *sc;
- USB_GET_SC_OPEN(ums, UMSUNIT(dev), sc);
+ sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
+ if (sc == NULL)
+ return (ENXIO);
return ums_enable(sc);
}
-Static int
-ums_close(struct cdev *dev, int flag, int fmt, usb_proc_ptr p)
+static int
+ums_close(struct cdev *dev, int flag, int fmt, struct thread *p)
{
struct ums_softc *sc;
- USB_GET_SC(ums, UMSUNIT(dev), sc);
-
+ sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
if (!sc)
return 0;
@@ -664,7 +705,7 @@
return 0;
}
-Static int
+static int
ums_read(struct cdev *dev, struct uio *uio, int flag)
{
struct ums_softc *sc;
@@ -673,8 +714,7 @@
int l = 0;
int error;
- USB_GET_SC(ums, UMSUNIT(dev), sc);
-
+ sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
s = splusb();
if (!sc) {
splx(s);
@@ -734,15 +774,14 @@
return 0;
}
-Static int
-ums_poll(struct cdev *dev, int events, usb_proc_ptr p)
+static int
+ums_poll(struct cdev *dev, int events, struct thread *p)
{
struct ums_softc *sc;
int revents = 0;
int s;
- USB_GET_SC(ums, UMSUNIT(dev), sc);
-
+ sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
if (!sc)
return 0;
@@ -761,15 +800,14 @@
}
int
-ums_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, usb_proc_ptr p)
+ums_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *p)
{
struct ums_softc *sc;
int error = 0;
int s;
mousemode_t mode;
- USB_GET_SC(ums, UMSUNIT(dev), sc);
-
+ sc = devclass_get_softc(ums_devclass, UMSUNIT(dev));
if (!sc)
return EIO;
@@ -876,4 +914,5 @@
return error;
}
+MODULE_DEPEND(ums, usb, 1, 1, 1);
DRIVER_MODULE(ums, uhub, ums_driver, ums_devclass, usbd_driver_load, 0);
More information about the Midnightbsd-cvs
mailing list