cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

usbmouse.c (5858B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Copyright (c) 1999-2001 Vojtech Pavlik
      4 *
      5 *  USB HIDBP Mouse support
      6 */
      7
      8/*
      9 *
     10 * Should you need to contact me, the author, you can do so either by
     11 * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
     12 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
     13 */
     14
     15#include <linux/kernel.h>
     16#include <linux/slab.h>
     17#include <linux/module.h>
     18#include <linux/init.h>
     19#include <linux/usb/input.h>
     20#include <linux/hid.h>
     21
     22/* for apple IDs */
     23#ifdef CONFIG_USB_HID_MODULE
     24#include "../hid-ids.h"
     25#endif
     26
     27/*
     28 * Version Information
     29 */
     30#define DRIVER_VERSION "v1.6"
     31#define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
     32#define DRIVER_DESC "USB HID Boot Protocol mouse driver"
     33
     34MODULE_AUTHOR(DRIVER_AUTHOR);
     35MODULE_DESCRIPTION(DRIVER_DESC);
     36MODULE_LICENSE("GPL");
     37
     38struct usb_mouse {
     39	char name[128];
     40	char phys[64];
     41	struct usb_device *usbdev;
     42	struct input_dev *dev;
     43	struct urb *irq;
     44
     45	signed char *data;
     46	dma_addr_t data_dma;
     47};
     48
     49static void usb_mouse_irq(struct urb *urb)
     50{
     51	struct usb_mouse *mouse = urb->context;
     52	signed char *data = mouse->data;
     53	struct input_dev *dev = mouse->dev;
     54	int status;
     55
     56	switch (urb->status) {
     57	case 0:			/* success */
     58		break;
     59	case -ECONNRESET:	/* unlink */
     60	case -ENOENT:
     61	case -ESHUTDOWN:
     62		return;
     63	/* -EPIPE:  should clear the halt */
     64	default:		/* error */
     65		goto resubmit;
     66	}
     67
     68	input_report_key(dev, BTN_LEFT,   data[0] & 0x01);
     69	input_report_key(dev, BTN_RIGHT,  data[0] & 0x02);
     70	input_report_key(dev, BTN_MIDDLE, data[0] & 0x04);
     71	input_report_key(dev, BTN_SIDE,   data[0] & 0x08);
     72	input_report_key(dev, BTN_EXTRA,  data[0] & 0x10);
     73
     74	input_report_rel(dev, REL_X,     data[1]);
     75	input_report_rel(dev, REL_Y,     data[2]);
     76	input_report_rel(dev, REL_WHEEL, data[3]);
     77
     78	input_sync(dev);
     79resubmit:
     80	status = usb_submit_urb (urb, GFP_ATOMIC);
     81	if (status)
     82		dev_err(&mouse->usbdev->dev,
     83			"can't resubmit intr, %s-%s/input0, status %d\n",
     84			mouse->usbdev->bus->bus_name,
     85			mouse->usbdev->devpath, status);
     86}
     87
     88static int usb_mouse_open(struct input_dev *dev)
     89{
     90	struct usb_mouse *mouse = input_get_drvdata(dev);
     91
     92	mouse->irq->dev = mouse->usbdev;
     93	if (usb_submit_urb(mouse->irq, GFP_KERNEL))
     94		return -EIO;
     95
     96	return 0;
     97}
     98
     99static void usb_mouse_close(struct input_dev *dev)
    100{
    101	struct usb_mouse *mouse = input_get_drvdata(dev);
    102
    103	usb_kill_urb(mouse->irq);
    104}
    105
    106static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)
    107{
    108	struct usb_device *dev = interface_to_usbdev(intf);
    109	struct usb_host_interface *interface;
    110	struct usb_endpoint_descriptor *endpoint;
    111	struct usb_mouse *mouse;
    112	struct input_dev *input_dev;
    113	int pipe, maxp;
    114	int error = -ENOMEM;
    115
    116	interface = intf->cur_altsetting;
    117
    118	if (interface->desc.bNumEndpoints != 1)
    119		return -ENODEV;
    120
    121	endpoint = &interface->endpoint[0].desc;
    122	if (!usb_endpoint_is_int_in(endpoint))
    123		return -ENODEV;
    124
    125	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
    126	maxp = usb_maxpacket(dev, pipe);
    127
    128	mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);
    129	input_dev = input_allocate_device();
    130	if (!mouse || !input_dev)
    131		goto fail1;
    132
    133	mouse->data = usb_alloc_coherent(dev, 8, GFP_KERNEL, &mouse->data_dma);
    134	if (!mouse->data)
    135		goto fail1;
    136
    137	mouse->irq = usb_alloc_urb(0, GFP_KERNEL);
    138	if (!mouse->irq)
    139		goto fail2;
    140
    141	mouse->usbdev = dev;
    142	mouse->dev = input_dev;
    143
    144	if (dev->manufacturer)
    145		strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));
    146
    147	if (dev->product) {
    148		if (dev->manufacturer)
    149			strlcat(mouse->name, " ", sizeof(mouse->name));
    150		strlcat(mouse->name, dev->product, sizeof(mouse->name));
    151	}
    152
    153	if (!strlen(mouse->name))
    154		snprintf(mouse->name, sizeof(mouse->name),
    155			 "USB HIDBP Mouse %04x:%04x",
    156			 le16_to_cpu(dev->descriptor.idVendor),
    157			 le16_to_cpu(dev->descriptor.idProduct));
    158
    159	usb_make_path(dev, mouse->phys, sizeof(mouse->phys));
    160	strlcat(mouse->phys, "/input0", sizeof(mouse->phys));
    161
    162	input_dev->name = mouse->name;
    163	input_dev->phys = mouse->phys;
    164	usb_to_input_id(dev, &input_dev->id);
    165	input_dev->dev.parent = &intf->dev;
    166
    167	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
    168	input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
    169		BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
    170	input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
    171	input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |
    172		BIT_MASK(BTN_EXTRA);
    173	input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
    174
    175	input_set_drvdata(input_dev, mouse);
    176
    177	input_dev->open = usb_mouse_open;
    178	input_dev->close = usb_mouse_close;
    179
    180	usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,
    181			 (maxp > 8 ? 8 : maxp),
    182			 usb_mouse_irq, mouse, endpoint->bInterval);
    183	mouse->irq->transfer_dma = mouse->data_dma;
    184	mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
    185
    186	error = input_register_device(mouse->dev);
    187	if (error)
    188		goto fail3;
    189
    190	usb_set_intfdata(intf, mouse);
    191	return 0;
    192
    193fail3:	
    194	usb_free_urb(mouse->irq);
    195fail2:	
    196	usb_free_coherent(dev, 8, mouse->data, mouse->data_dma);
    197fail1:	
    198	input_free_device(input_dev);
    199	kfree(mouse);
    200	return error;
    201}
    202
    203static void usb_mouse_disconnect(struct usb_interface *intf)
    204{
    205	struct usb_mouse *mouse = usb_get_intfdata (intf);
    206
    207	usb_set_intfdata(intf, NULL);
    208	if (mouse) {
    209		usb_kill_urb(mouse->irq);
    210		input_unregister_device(mouse->dev);
    211		usb_free_urb(mouse->irq);
    212		usb_free_coherent(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
    213		kfree(mouse);
    214	}
    215}
    216
    217static const struct usb_device_id usb_mouse_id_table[] = {
    218	{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
    219		USB_INTERFACE_PROTOCOL_MOUSE) },
    220	{ }	/* Terminating entry */
    221};
    222
    223MODULE_DEVICE_TABLE (usb, usb_mouse_id_table);
    224
    225static struct usb_driver usb_mouse_driver = {
    226	.name		= "usbmouse",
    227	.probe		= usb_mouse_probe,
    228	.disconnect	= usb_mouse_disconnect,
    229	.id_table	= usb_mouse_id_table,
    230};
    231
    232module_usb_driver(usb_mouse_driver);