| File: | dev/usb/uts.c |
| Warning: | line 403, column 6 Branch condition evaluates to a garbage value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: uts.c,v 1.43 2020/07/31 10:49:33 mglocker Exp $ */ | |||
| 2 | ||||
| 3 | /* | |||
| 4 | * Copyright (c) 2007 Robert Nagy <robert@openbsd.org> | |||
| 5 | * | |||
| 6 | * Permission to use, copy, modify, and distribute this software for any | |||
| 7 | * purpose with or without fee is hereby granted, provided that the above | |||
| 8 | * copyright notice and this permission notice appear in all copies. | |||
| 9 | * | |||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |||
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
| 17 | */ | |||
| 18 | ||||
| 19 | #include <sys/param.h> | |||
| 20 | #include <sys/sockio.h> | |||
| 21 | #include <sys/mbuf.h> | |||
| 22 | #include <sys/kernel.h> | |||
| 23 | #include <sys/socket.h> | |||
| 24 | #include <sys/systm.h> | |||
| 25 | #include <sys/malloc.h> | |||
| 26 | #include <sys/timeout.h> | |||
| 27 | #include <sys/conf.h> | |||
| 28 | #include <sys/device.h> | |||
| 29 | #include <sys/endian.h> | |||
| 30 | ||||
| 31 | #include <machine/intr.h> | |||
| 32 | ||||
| 33 | #include <dev/usb/usb.h> | |||
| 34 | #include <dev/usb/usbdi.h> | |||
| 35 | #include <dev/usb/usbdi_util.h> | |||
| 36 | #include <dev/usb/usbdevs.h> | |||
| 37 | ||||
| 38 | #include <dev/wscons/wsconsio.h> | |||
| 39 | #include <dev/wscons/wsmousevar.h> | |||
| 40 | ||||
| 41 | #ifdef UTS_DEBUG | |||
| 42 | #define DPRINTF(x) do { printf x; } while (0) | |||
| 43 | #else | |||
| 44 | #define DPRINTF(x) | |||
| 45 | #endif | |||
| 46 | ||||
| 47 | struct tsscale { | |||
| 48 | int minx, maxx; | |||
| 49 | int miny, maxy; | |||
| 50 | int swapxy; | |||
| 51 | int resx, resy; | |||
| 52 | } def_scale = { | |||
| 53 | 67, 1931, 102, 1937, 0, 1024, 768 | |||
| 54 | }; | |||
| 55 | ||||
| 56 | struct uts_softc { | |||
| 57 | struct device sc_dev; | |||
| 58 | struct usbd_device *sc_udev; | |||
| 59 | struct usbd_interface *sc_iface; | |||
| 60 | int sc_product; | |||
| 61 | int sc_vendor; | |||
| 62 | ||||
| 63 | int sc_intr_number; | |||
| 64 | struct usbd_pipe *sc_intr_pipe; | |||
| 65 | u_char *sc_ibuf; | |||
| 66 | int sc_isize; | |||
| 67 | u_int8_t sc_pkts; | |||
| 68 | ||||
| 69 | struct device *sc_wsmousedev; | |||
| 70 | ||||
| 71 | int sc_enabled; | |||
| 72 | int sc_buttons; | |||
| 73 | int sc_oldx; | |||
| 74 | int sc_oldy; | |||
| 75 | int sc_rawmode; | |||
| 76 | ||||
| 77 | struct tsscale sc_tsscale; | |||
| 78 | }; | |||
| 79 | ||||
| 80 | struct uts_pos { | |||
| 81 | int down; | |||
| 82 | int x; | |||
| 83 | int y; | |||
| 84 | int z; /* touch pressure */ | |||
| 85 | }; | |||
| 86 | ||||
| 87 | const struct usb_devno uts_devs[] = { | |||
| 88 | { USB_VENDOR_FTDI0x0403, USB_PRODUCT_FTDI_ITM_TOUCH0xf9e9 }, | |||
| 89 | { USB_VENDOR_EGALAX0x0eef, USB_PRODUCT_EGALAX_TPANEL0x0001 }, | |||
| 90 | { USB_VENDOR_EGALAX0x0eef, USB_PRODUCT_EGALAX_TPANEL20x0002 }, | |||
| 91 | { USB_VENDOR_GUNZE0x0637, USB_PRODUCT_GUNZE_TOUCHPANEL0x0001 } | |||
| 92 | }; | |||
| 93 | ||||
| 94 | void uts_intr(struct usbd_xfer *, void *, usbd_status); | |||
| 95 | void uts_get_pos(void *addr, struct uts_pos *tp); | |||
| 96 | ||||
| 97 | int uts_enable(void *); | |||
| 98 | void uts_disable(void *); | |||
| 99 | int uts_ioctl(void *, u_long, caddr_t, int, struct proc *); | |||
| 100 | ||||
| 101 | const struct wsmouse_accessops uts_accessops = { | |||
| 102 | uts_enable, | |||
| 103 | uts_ioctl, | |||
| 104 | uts_disable, | |||
| 105 | }; | |||
| 106 | ||||
| 107 | int uts_match(struct device *, void *, void *); | |||
| 108 | void uts_attach(struct device *, struct device *, void *); | |||
| 109 | int uts_detach(struct device *, int); | |||
| 110 | int uts_activate(struct device *, int); | |||
| 111 | ||||
| 112 | struct cfdriver uts_cd = { | |||
| 113 | NULL((void *)0), "uts", DV_DULL | |||
| 114 | }; | |||
| 115 | ||||
| 116 | const struct cfattach uts_ca = { | |||
| 117 | sizeof(struct uts_softc), | |||
| 118 | uts_match, | |||
| 119 | uts_attach, | |||
| 120 | uts_detach, | |||
| 121 | uts_activate, | |||
| 122 | }; | |||
| 123 | ||||
| 124 | int | |||
| 125 | uts_match(struct device *parent, void *match, void *aux) | |||
| 126 | { | |||
| 127 | struct usb_attach_arg *uaa = aux; | |||
| 128 | usb_interface_descriptor_t *id; | |||
| 129 | ||||
| 130 | if (uaa->iface == NULL((void *)0)) | |||
| 131 | return (UMATCH_NONE0); | |||
| 132 | ||||
| 133 | /* Some eGalax touch screens are HID devices. ignore them */ | |||
| 134 | id = usbd_get_interface_descriptor(uaa->iface); | |||
| 135 | if (id != NULL((void *)0) && id->bInterfaceClass == UICLASS_HID0x03) | |||
| 136 | return (UMATCH_NONE0); | |||
| 137 | ||||
| 138 | return (usb_lookup(uts_devs, uaa->vendor, uaa->product)usbd_match_device((const struct usb_devno *)(uts_devs), sizeof (uts_devs) / sizeof ((uts_devs)[0]), sizeof ((uts_devs)[0]), (uaa->vendor), (uaa->product)) != NULL((void *)0)) ? | |||
| 139 | UMATCH_VENDOR_PRODUCT13 : UMATCH_NONE0; | |||
| 140 | } | |||
| 141 | ||||
| 142 | void | |||
| 143 | uts_attach(struct device *parent, struct device *self, void *aux) | |||
| 144 | { | |||
| 145 | struct uts_softc *sc = (struct uts_softc *)self; | |||
| 146 | struct usb_attach_arg *uaa = aux; | |||
| 147 | usb_config_descriptor_t *cdesc; | |||
| 148 | usb_interface_descriptor_t *id; | |||
| 149 | usb_endpoint_descriptor_t *ed; | |||
| 150 | struct wsmousedev_attach_args a; | |||
| 151 | int i; | |||
| 152 | ||||
| 153 | sc->sc_udev = uaa->device; | |||
| 154 | sc->sc_product = uaa->product; | |||
| 155 | sc->sc_vendor = uaa->vendor; | |||
| 156 | sc->sc_intr_number = -1; | |||
| 157 | sc->sc_intr_pipe = NULL((void *)0); | |||
| 158 | sc->sc_enabled = sc->sc_isize = 0; | |||
| 159 | ||||
| 160 | /* Copy the default scalue values to each softc */ | |||
| 161 | bcopy(&def_scale, &sc->sc_tsscale, sizeof(sc->sc_tsscale)); | |||
| 162 | ||||
| 163 | /* get the config descriptor */ | |||
| 164 | cdesc = usbd_get_config_descriptor(sc->sc_udev); | |||
| 165 | if (cdesc == NULL((void *)0)) { | |||
| 166 | printf("%s: failed to get configuration descriptor\n", | |||
| 167 | sc->sc_dev.dv_xname); | |||
| 168 | usbd_deactivate(sc->sc_udev); | |||
| 169 | return; | |||
| 170 | } | |||
| 171 | ||||
| 172 | /* get the interface */ | |||
| 173 | if (usbd_device2interface_handle(uaa->device, 0, &sc->sc_iface) != 0) { | |||
| 174 | printf("%s: failed to get interface\n", | |||
| 175 | sc->sc_dev.dv_xname); | |||
| 176 | usbd_deactivate(sc->sc_udev); | |||
| 177 | return; | |||
| 178 | } | |||
| 179 | ||||
| 180 | /* Find the interrupt endpoint */ | |||
| 181 | id = usbd_get_interface_descriptor(sc->sc_iface); | |||
| 182 | ||||
| 183 | for (i = 0; i < id->bNumEndpoints; i++) { | |||
| 184 | ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); | |||
| 185 | if (ed == NULL((void *)0)) { | |||
| 186 | printf("%s: no endpoint descriptor for %d\n", | |||
| 187 | sc->sc_dev.dv_xname, i); | |||
| 188 | usbd_deactivate(sc->sc_udev); | |||
| 189 | return; | |||
| 190 | } | |||
| 191 | ||||
| 192 | if (UE_GET_DIR(ed->bEndpointAddress)((ed->bEndpointAddress) & 0x80) == UE_DIR_IN0x80 && | |||
| 193 | UE_GET_XFERTYPE(ed->bmAttributes)((ed->bmAttributes) & 0x03) == UE_INTERRUPT0x03) { | |||
| 194 | sc->sc_intr_number = ed->bEndpointAddress; | |||
| 195 | sc->sc_isize = UGETW(ed->wMaxPacketSize)(*(u_int16_t *)(ed->wMaxPacketSize)); | |||
| 196 | } | |||
| 197 | } | |||
| 198 | ||||
| 199 | if (sc->sc_intr_number== -1) { | |||
| 200 | printf("%s: Could not find interrupt in\n", | |||
| 201 | sc->sc_dev.dv_xname); | |||
| 202 | usbd_deactivate(sc->sc_udev); | |||
| 203 | return; | |||
| 204 | } | |||
| 205 | ||||
| 206 | a.accessops = &uts_accessops; | |||
| 207 | a.accesscookie = sc; | |||
| 208 | ||||
| 209 | sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint)config_found_sm((self), (&a), (wsmousedevprint), ((void * )0)); | |||
| 210 | } | |||
| 211 | ||||
| 212 | int | |||
| 213 | uts_detach(struct device *self, int flags) | |||
| 214 | { | |||
| 215 | struct uts_softc *sc = (struct uts_softc *)self; | |||
| 216 | int rv = 0; | |||
| 217 | ||||
| 218 | if (sc->sc_intr_pipe != NULL((void *)0)) { | |||
| 219 | usbd_close_pipe(sc->sc_intr_pipe); | |||
| 220 | sc->sc_intr_pipe = NULL((void *)0); | |||
| 221 | } | |||
| 222 | ||||
| 223 | if (sc->sc_wsmousedev != NULL((void *)0)) { | |||
| 224 | rv = config_detach(sc->sc_wsmousedev, flags); | |||
| 225 | sc->sc_wsmousedev = NULL((void *)0); | |||
| 226 | } | |||
| 227 | ||||
| 228 | return (rv); | |||
| 229 | } | |||
| 230 | ||||
| 231 | int | |||
| 232 | uts_activate(struct device *self, int act) | |||
| 233 | { | |||
| 234 | struct uts_softc *sc = (struct uts_softc *)self; | |||
| 235 | int rv = 0; | |||
| 236 | ||||
| 237 | switch (act) { | |||
| 238 | case DVACT_DEACTIVATE1: | |||
| 239 | if (sc->sc_wsmousedev != NULL((void *)0)) | |||
| 240 | rv = config_deactivate(sc->sc_wsmousedev); | |||
| 241 | usbd_deactivate(sc->sc_udev); | |||
| 242 | break; | |||
| 243 | } | |||
| 244 | ||||
| 245 | return (rv); | |||
| 246 | } | |||
| 247 | ||||
| 248 | int | |||
| 249 | uts_enable(void *v) | |||
| 250 | { | |||
| 251 | struct uts_softc *sc = v; | |||
| 252 | int err; | |||
| 253 | ||||
| 254 | if (usbd_is_dying(sc->sc_udev)) | |||
| 255 | return (EIO5); | |||
| 256 | ||||
| 257 | if (sc->sc_enabled) | |||
| 258 | return (EBUSY16); | |||
| 259 | ||||
| 260 | if (sc->sc_isize == 0) | |||
| 261 | return (0); | |||
| 262 | sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV102, M_WAITOK0x0001); | |||
| 263 | err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_intr_number, | |||
| 264 | USBD_SHORT_XFER_OK0x04, &sc->sc_intr_pipe, sc, sc->sc_ibuf, | |||
| 265 | sc->sc_isize, uts_intr, USBD_DEFAULT_INTERVAL(-1)); | |||
| 266 | if (err) { | |||
| 267 | free(sc->sc_ibuf, M_USBDEV102, sc->sc_isize); | |||
| 268 | sc->sc_intr_pipe = NULL((void *)0); | |||
| 269 | return (EIO5); | |||
| 270 | } | |||
| 271 | ||||
| 272 | sc->sc_enabled = 1; | |||
| 273 | sc->sc_buttons = 0; | |||
| 274 | ||||
| 275 | return (0); | |||
| 276 | } | |||
| 277 | ||||
| 278 | void | |||
| 279 | uts_disable(void *v) | |||
| 280 | { | |||
| 281 | struct uts_softc *sc = v; | |||
| 282 | ||||
| 283 | if (!sc->sc_enabled) { | |||
| 284 | printf("uts_disable: already disabled!\n"); | |||
| 285 | return; | |||
| 286 | } | |||
| 287 | ||||
| 288 | /* Disable interrupts. */ | |||
| 289 | if (sc->sc_intr_pipe != NULL((void *)0)) { | |||
| 290 | usbd_close_pipe(sc->sc_intr_pipe); | |||
| 291 | sc->sc_intr_pipe = NULL((void *)0); | |||
| 292 | } | |||
| 293 | ||||
| 294 | if (sc->sc_ibuf != NULL((void *)0)) { | |||
| 295 | free(sc->sc_ibuf, M_USBDEV102, sc->sc_isize); | |||
| 296 | sc->sc_ibuf = NULL((void *)0); | |||
| 297 | } | |||
| 298 | ||||
| 299 | sc->sc_enabled = 0; | |||
| 300 | } | |||
| 301 | ||||
| 302 | int | |||
| 303 | uts_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *l) | |||
| 304 | { | |||
| 305 | int error = 0; | |||
| 306 | struct uts_softc *sc = v; | |||
| 307 | struct wsmouse_calibcoords *wsmc = (struct wsmouse_calibcoords *)data; | |||
| 308 | ||||
| 309 | DPRINTF(("uts_ioctl(%zu, '%c', %zu)\n", | |||
| 310 | IOCPARM_LEN(cmd), (int) IOCGROUP(cmd), cmd & 0xff)); | |||
| 311 | ||||
| 312 | switch (cmd) { | |||
| 313 | case WSMOUSEIO_SCALIBCOORDS((unsigned long)0x80000000 | ((sizeof(struct wsmouse_calibcoords ) & 0x1fff) << 16) | ((('W')) << 8) | ((36))): | |||
| 314 | if (!(wsmc->minx >= -32768 && wsmc->maxx >= 0 && | |||
| 315 | wsmc->miny >= -32768 && wsmc->maxy >= 0 && | |||
| 316 | wsmc->resx >= 0 && wsmc->resy >= 0 && | |||
| 317 | wsmc->minx < 32768 && wsmc->maxx < 32768 && | |||
| 318 | wsmc->miny < 32768 && wsmc->maxy < 32768 && | |||
| 319 | (wsmc->maxx - wsmc->minx) != 0 && | |||
| 320 | (wsmc->maxy - wsmc->miny) != 0 && | |||
| 321 | wsmc->resx < 32768 && wsmc->resy < 32768 && | |||
| 322 | wsmc->swapxy >= 0 && wsmc->swapxy <= 1 && | |||
| 323 | wsmc->samplelen >= 0 && wsmc->samplelen <= 1)) | |||
| 324 | return (EINVAL22); | |||
| 325 | ||||
| 326 | sc->sc_tsscale.minx = wsmc->minx; | |||
| 327 | sc->sc_tsscale.maxx = wsmc->maxx; | |||
| 328 | sc->sc_tsscale.miny = wsmc->miny; | |||
| 329 | sc->sc_tsscale.maxy = wsmc->maxy; | |||
| 330 | sc->sc_tsscale.swapxy = wsmc->swapxy; | |||
| 331 | sc->sc_tsscale.resx = wsmc->resx; | |||
| 332 | sc->sc_tsscale.resy = wsmc->resy; | |||
| 333 | sc->sc_rawmode = wsmc->samplelen; | |||
| 334 | break; | |||
| 335 | case WSMOUSEIO_GCALIBCOORDS((unsigned long)0x40000000 | ((sizeof(struct wsmouse_calibcoords ) & 0x1fff) << 16) | ((('W')) << 8) | ((37))): | |||
| 336 | wsmc->minx = sc->sc_tsscale.minx; | |||
| 337 | wsmc->maxx = sc->sc_tsscale.maxx; | |||
| 338 | wsmc->miny = sc->sc_tsscale.miny; | |||
| 339 | wsmc->maxy = sc->sc_tsscale.maxy; | |||
| 340 | wsmc->swapxy = sc->sc_tsscale.swapxy; | |||
| 341 | wsmc->resx = sc->sc_tsscale.resx; | |||
| 342 | wsmc->resy = sc->sc_tsscale.resy; | |||
| 343 | wsmc->samplelen = sc->sc_rawmode; | |||
| 344 | break; | |||
| 345 | case WSMOUSEIO_GTYPE((unsigned long)0x40000000 | ((sizeof(u_int) & 0x1fff) << 16) | ((('W')) << 8) | ((32))): | |||
| 346 | *(u_int *)data = WSMOUSE_TYPE_TPANEL6; | |||
| 347 | break; | |||
| 348 | default: | |||
| 349 | error = ENOTTY25; | |||
| 350 | break; | |||
| 351 | } | |||
| 352 | ||||
| 353 | return (error); | |||
| 354 | } | |||
| 355 | ||||
| 356 | void | |||
| 357 | uts_get_pos(void *addr, struct uts_pos *tp) | |||
| 358 | { | |||
| 359 | struct uts_softc *sc = addr; | |||
| 360 | u_char *p = sc->sc_ibuf; | |||
| 361 | int down, x, y, z; | |||
| 362 | ||||
| 363 | switch (sc->sc_product) { | |||
| 364 | case USB_PRODUCT_FTDI_ITM_TOUCH0xf9e9: | |||
| 365 | down = (~p[7] & 0x20); | |||
| 366 | x = ((p[0] & 0x1f) << 7) | (p[3] & 0x7f); | |||
| 367 | /* Invert the Y coordinate */ | |||
| 368 | y = 0x0fff - abs(((p[1] & 0x1f) << 7) | (p[4] & 0x7f)); | |||
| 369 | z = ((p[2] & 0x1) << 7) | (p[5] & 0x7f); | |||
| 370 | sc->sc_pkts = 0x8; | |||
| 371 | break; | |||
| 372 | case USB_PRODUCT_EGALAX_TPANEL0x0001: | |||
| 373 | case USB_PRODUCT_EGALAX_TPANEL20x0002: | |||
| 374 | /* | |||
| 375 | * eGalax and Gunze USB touch panels have the same device ID, | |||
| 376 | * so decide upon the vendor ID. | |||
| 377 | */ | |||
| 378 | switch (sc->sc_vendor) { | |||
| 379 | case USB_VENDOR_EGALAX0x0eef: | |||
| 380 | down = (p[0] & 0x01); | |||
| 381 | /* Invert the X coordinate */ | |||
| 382 | x = 0x07ff - abs(((p[3] & 0x0f) << 7) | (p[4] & 0x7f)); | |||
| 383 | y = ((p[1] & 0x0f) << 7) | (p[2] & 0x7f); | |||
| 384 | z = down; | |||
| 385 | sc->sc_pkts = 0x5; | |||
| 386 | break; | |||
| 387 | case USB_VENDOR_GUNZE0x0637: | |||
| 388 | down = (~p[7] & 0x20); | |||
| 389 | /* Invert the X coordinate */ | |||
| 390 | x = 0x0fff - abs(((p[0] & 0x1f) << 7) | (p[2] & 0x7f)); | |||
| 391 | y = ((p[1] & 0x1f) << 7) | (p[3] & 0x7f); | |||
| 392 | z = (down != 0); | |||
| 393 | sc->sc_pkts = 0x4; | |||
| 394 | break; | |||
| 395 | } | |||
| 396 | break; | |||
| 397 | } | |||
| 398 | ||||
| 399 | DPRINTF(("%s: down = 0x%x, sc->sc_pkts = 0x%x\n", | |||
| 400 | sc->sc_dev.dv_xname, down, sc->sc_pkts)); | |||
| 401 | ||||
| 402 | /* x/y values are not reliable if there is no pressure */ | |||
| 403 | if (down) { | |||
| ||||
| 404 | if (sc->sc_tsscale.swapxy && !sc->sc_rawmode) { | |||
| 405 | /* Swap X/Y-Axis */ | |||
| 406 | tp->y = x; | |||
| 407 | tp->x = y; | |||
| 408 | } else { | |||
| 409 | tp->x = x; | |||
| 410 | tp->y = y; | |||
| 411 | } | |||
| 412 | if (!sc->sc_rawmode && | |||
| 413 | (sc->sc_tsscale.maxx - sc->sc_tsscale.minx) != 0 && | |||
| 414 | (sc->sc_tsscale.maxy - sc->sc_tsscale.miny) != 0) { | |||
| 415 | /* Scale down to the screen resolution. */ | |||
| 416 | tp->x = ((tp->x - sc->sc_tsscale.minx) * | |||
| 417 | sc->sc_tsscale.resx) / | |||
| 418 | (sc->sc_tsscale.maxx - sc->sc_tsscale.minx); | |||
| 419 | tp->y = ((tp->y - sc->sc_tsscale.miny) * | |||
| 420 | sc->sc_tsscale.resy) / | |||
| 421 | (sc->sc_tsscale.maxy - sc->sc_tsscale.miny); | |||
| 422 | } | |||
| 423 | } else { | |||
| 424 | tp->x = sc->sc_oldx; | |||
| 425 | tp->y = sc->sc_oldy; | |||
| 426 | } | |||
| 427 | tp->z = z; | |||
| 428 | tp->down = down; | |||
| 429 | } | |||
| 430 | ||||
| 431 | void | |||
| 432 | uts_intr(struct usbd_xfer *xfer, void *addr, usbd_status status) | |||
| 433 | { | |||
| 434 | struct uts_softc *sc = addr; | |||
| 435 | u_int32_t len; | |||
| 436 | int s; | |||
| 437 | struct uts_pos tp; | |||
| 438 | ||||
| 439 | if (status == USBD_CANCELLED) | |||
| ||||
| 440 | return; | |||
| 441 | ||||
| 442 | if (status != USBD_NORMAL_COMPLETION) { | |||
| 443 | printf("%s: status %d\n", sc->sc_dev.dv_xname, status); | |||
| 444 | if (status == USBD_STALLED) | |||
| 445 | usbd_clear_endpoint_stall_async(sc->sc_intr_pipe); | |||
| 446 | return; | |||
| 447 | } | |||
| 448 | ||||
| 449 | usbd_get_xfer_status(xfer, NULL((void *)0), NULL((void *)0), &len, NULL((void *)0)); | |||
| 450 | ||||
| 451 | s = spltty()splraise(0x9); | |||
| 452 | ||||
| 453 | uts_get_pos(sc, &tp); | |||
| 454 | ||||
| 455 | if (len != sc->sc_pkts) { | |||
| 456 | DPRINTF(("%s: bad input length %d != %d\n", | |||
| 457 | sc->sc_dev.dv_xname, len, sc->sc_isize)); | |||
| 458 | splx(s)spllower(s); | |||
| 459 | return; | |||
| 460 | } | |||
| 461 | ||||
| 462 | DPRINTF(("%s: tp.down = %d, tp.z = %d, tp.x = %d, tp.y = %d\n", | |||
| 463 | sc->sc_dev.dv_xname, tp.down, tp.z, tp.x, tp.y)); | |||
| 464 | ||||
| 465 | WSMOUSE_TOUCH(sc->sc_wsmousedev, tp.down, tp.x, tp.y, tp.z, 0)do { wsmouse_buttons((sc->sc_wsmousedev), (tp.down)); wsmouse_position ((sc->sc_wsmousedev), (tp.x), (tp.y)); wsmouse_touch((sc-> sc_wsmousedev), (tp.z), (0)); wsmouse_input_sync(sc->sc_wsmousedev ); } while (0); | |||
| 466 | sc->sc_oldy = tp.y; | |||
| 467 | sc->sc_oldx = tp.x; | |||
| 468 | ||||
| 469 | splx(s)spllower(s); | |||
| 470 | } |