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

trancevibrator.c (2963B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * PlayStation 2 Trance Vibrator driver
      4 *
      5 * Copyright (C) 2006 Sam Hocevar <sam@zoy.org>
      6 */
      7
      8/* Standard include files */
      9#include <linux/kernel.h>
     10#include <linux/errno.h>
     11#include <linux/slab.h>
     12#include <linux/module.h>
     13#include <linux/usb.h>
     14
     15#define DRIVER_AUTHOR "Sam Hocevar, sam@zoy.org"
     16#define DRIVER_DESC "PlayStation 2 Trance Vibrator driver"
     17
     18#define TRANCEVIBRATOR_VENDOR_ID	0x0b49	/* ASCII Corporation */
     19#define TRANCEVIBRATOR_PRODUCT_ID	0x064f	/* Trance Vibrator */
     20
     21static const struct usb_device_id id_table[] = {
     22	{ USB_DEVICE(TRANCEVIBRATOR_VENDOR_ID, TRANCEVIBRATOR_PRODUCT_ID) },
     23	{ },
     24};
     25MODULE_DEVICE_TABLE (usb, id_table);
     26
     27/* Driver-local specific stuff */
     28struct trancevibrator {
     29	struct usb_device *udev;
     30	unsigned int speed;
     31};
     32
     33static ssize_t speed_show(struct device *dev, struct device_attribute *attr,
     34			  char *buf)
     35{
     36	struct usb_interface *intf = to_usb_interface(dev);
     37	struct trancevibrator *tv = usb_get_intfdata(intf);
     38
     39	return sprintf(buf, "%d\n", tv->speed);
     40}
     41
     42static ssize_t speed_store(struct device *dev, struct device_attribute *attr,
     43			 const char *buf, size_t count)
     44{
     45	struct usb_interface *intf = to_usb_interface(dev);
     46	struct trancevibrator *tv = usb_get_intfdata(intf);
     47	int temp, retval, old;
     48
     49	retval = kstrtoint(buf, 10, &temp);
     50	if (retval)
     51		return retval;
     52	if (temp > 255)
     53		temp = 255;
     54	else if (temp < 0)
     55		temp = 0;
     56	old = tv->speed;
     57	tv->speed = temp;
     58
     59	dev_dbg(&tv->udev->dev, "speed = %d\n", tv->speed);
     60
     61	/* Set speed */
     62	retval = usb_control_msg(tv->udev, usb_sndctrlpipe(tv->udev, 0),
     63				 0x01, /* vendor request: set speed */
     64				 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
     65				 tv->speed, /* speed value */
     66				 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
     67	if (retval) {
     68		tv->speed = old;
     69		dev_dbg(&tv->udev->dev, "retval = %d\n", retval);
     70		return retval;
     71	}
     72	return count;
     73}
     74static DEVICE_ATTR_RW(speed);
     75
     76static struct attribute *tv_attrs[] = {
     77	&dev_attr_speed.attr,
     78	NULL,
     79};
     80ATTRIBUTE_GROUPS(tv);
     81
     82static int tv_probe(struct usb_interface *interface,
     83		    const struct usb_device_id *id)
     84{
     85	struct usb_device *udev = interface_to_usbdev(interface);
     86	struct trancevibrator *dev;
     87	int retval;
     88
     89	dev = kzalloc(sizeof(struct trancevibrator), GFP_KERNEL);
     90	if (!dev) {
     91		retval = -ENOMEM;
     92		goto error;
     93	}
     94
     95	dev->udev = usb_get_dev(udev);
     96	usb_set_intfdata(interface, dev);
     97
     98	return 0;
     99
    100error:
    101	kfree(dev);
    102	return retval;
    103}
    104
    105static void tv_disconnect(struct usb_interface *interface)
    106{
    107	struct trancevibrator *dev;
    108
    109	dev = usb_get_intfdata (interface);
    110	usb_set_intfdata(interface, NULL);
    111	usb_put_dev(dev->udev);
    112	kfree(dev);
    113}
    114
    115/* USB subsystem object */
    116static struct usb_driver tv_driver = {
    117	.name =		"trancevibrator",
    118	.probe =	tv_probe,
    119	.disconnect =	tv_disconnect,
    120	.id_table =	id_table,
    121	.dev_groups =	tv_groups,
    122};
    123
    124module_usb_driver(tv_driver);
    125
    126MODULE_AUTHOR(DRIVER_AUTHOR);
    127MODULE_DESCRIPTION(DRIVER_DESC);
    128MODULE_LICENSE("GPL");