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

hid-gembird.c (3318B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  HID driver for Gembird Joypad, "PC Game Controller"
      4 *
      5 *  Copyright (c) 2015 Red Hat, Inc
      6 *  Copyright (c) 2015 Benjamin Tissoires
      7 */
      8
      9/*
     10 */
     11
     12#include <linux/device.h>
     13#include <linux/hid.h>
     14#include <linux/module.h>
     15
     16#include "hid-ids.h"
     17
     18#define GEMBIRD_START_FAULTY_RDESC	8
     19
     20static const __u8 gembird_jpd_faulty_rdesc[] = {
     21	0x75, 0x08,			/*   Report Size (8)		*/
     22	0x95, 0x05,			/*   Report Count (5)		*/
     23	0x15, 0x00,			/*   Logical Minimum (0)	*/
     24	0x26, 0xff, 0x00,		/*   Logical Maximum (255)	*/
     25	0x35, 0x00,			/*   Physical Minimum (0)	*/
     26	0x46, 0xff, 0x00,		/*   Physical Maximum (255)	*/
     27	0x09, 0x30,			/*   Usage (X)			*/
     28	0x09, 0x31,			/*   Usage (Y)			*/
     29	0x09, 0x32,			/*   Usage (Z)			*/
     30	0x09, 0x32,			/*   Usage (Z)			*/
     31	0x09, 0x35,			/*   Usage (Rz)			*/
     32	0x81, 0x02,			/*   Input (Data,Var,Abs)	*/
     33};
     34
     35/*
     36 * we fix the report descriptor by:
     37 * - marking the first Z axis as constant (so it is ignored by HID)
     38 * - assign the original second Z to Rx
     39 * - assign the original Rz to Ry
     40 */
     41static const __u8 gembird_jpd_fixed_rdesc[] = {
     42	0x75, 0x08,			/*   Report Size (8)		*/
     43	0x95, 0x02,			/*   Report Count (2)		*/
     44	0x15, 0x00,			/*   Logical Minimum (0)	*/
     45	0x26, 0xff, 0x00,		/*   Logical Maximum (255)	*/
     46	0x35, 0x00,			/*   Physical Minimum (0)	*/
     47	0x46, 0xff, 0x00,		/*   Physical Maximum (255)	*/
     48	0x09, 0x30,			/*   Usage (X)			*/
     49	0x09, 0x31,			/*   Usage (Y)			*/
     50	0x81, 0x02,			/*   Input (Data,Var,Abs)	*/
     51	0x95, 0x01,			/*   Report Count (1)		*/
     52	0x09, 0x32,			/*   Usage (Z)			*/
     53	0x81, 0x01,			/*   Input (Cnst,Arr,Abs)	*/
     54	0x95, 0x02,			/*   Report Count (2)		*/
     55	0x09, 0x33,			/*   Usage (Rx)			*/
     56	0x09, 0x34,			/*   Usage (Ry)			*/
     57	0x81, 0x02,			/*   Input (Data,Var,Abs)	*/
     58};
     59
     60static __u8 *gembird_report_fixup(struct hid_device *hdev, __u8 *rdesc,
     61		unsigned int *rsize)
     62{
     63	__u8 *new_rdesc;
     64	/* delta_size is > 0 */
     65	size_t delta_size = sizeof(gembird_jpd_fixed_rdesc) -
     66			    sizeof(gembird_jpd_faulty_rdesc);
     67	size_t new_size = *rsize + delta_size;
     68
     69	if (*rsize >= 31 && !memcmp(&rdesc[GEMBIRD_START_FAULTY_RDESC],
     70				    gembird_jpd_faulty_rdesc,
     71				    sizeof(gembird_jpd_faulty_rdesc))) {
     72		new_rdesc = devm_kzalloc(&hdev->dev, new_size, GFP_KERNEL);
     73		if (new_rdesc == NULL)
     74			return rdesc;
     75
     76		dev_info(&hdev->dev,
     77			 "fixing Gembird JPD-DualForce 2 report descriptor.\n");
     78
     79		/* start by copying the end of the rdesc */
     80		memcpy(new_rdesc + delta_size, rdesc, *rsize);
     81
     82		/* add the correct beginning */
     83		memcpy(new_rdesc, rdesc, GEMBIRD_START_FAULTY_RDESC);
     84
     85		/* replace the faulty part with the fixed one */
     86		memcpy(new_rdesc + GEMBIRD_START_FAULTY_RDESC,
     87		       gembird_jpd_fixed_rdesc,
     88		       sizeof(gembird_jpd_fixed_rdesc));
     89
     90		*rsize = new_size;
     91		rdesc = new_rdesc;
     92	}
     93
     94	return rdesc;
     95}
     96
     97static const struct hid_device_id gembird_devices[] = {
     98	{ HID_USB_DEVICE(USB_VENDOR_ID_GEMBIRD,
     99			 USB_DEVICE_ID_GEMBIRD_JPD_DUALFORCE2) },
    100	{ }
    101};
    102MODULE_DEVICE_TABLE(hid, gembird_devices);
    103
    104static struct hid_driver gembird_driver = {
    105	.name = "gembird",
    106	.id_table = gembird_devices,
    107	.report_fixup = gembird_report_fixup,
    108};
    109module_hid_driver(gembird_driver);
    110
    111MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
    112MODULE_DESCRIPTION("HID Gembird joypad driver");
    113MODULE_LICENSE("GPL");