linux/drivers/usb/misc/ldusb.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * Generic USB driver for report based interrupt in/out devices
 * like LD Didactic's USB devices. LD Didactic's USB devices are
 * HID devices which do not use HID report definitons (they use
 * raw interrupt in and our reports only for communication).
 *
 * This driver uses a ring buffer for time critical reading of
 * interrupt in reports and provides read and write methods for
 * raw interrupt reports (similar to the Windows HID driver).
 * Devices based on the book USB COMPLETE by Jan Axelson may need
 * such a compatibility to the Windows HID driver.
 *
 * Copyright (C) 2005 Michael Hund <[email protected]>
 *
 * Derived from Lego USB Tower driver
 * Copyright (C) 2003 David Glance <[email protected]>
 *		 2001-2004 Juergen Stuber <[email protected]>
 */

#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mutex.h>

#include <linux/uaccess.h>
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/poll.h>

/* Define these values to match your devices */
#define USB_VENDOR_ID_LD
#define USB_DEVICE_ID_LD_CASSY
#define USB_DEVICE_ID_LD_CASSY2
#define USB_DEVICE_ID_LD_POCKETCASSY
#define USB_DEVICE_ID_LD_POCKETCASSY2
#define USB_DEVICE_ID_LD_MOBILECASSY
#define USB_DEVICE_ID_LD_MOBILECASSY2
#define USB_DEVICE_ID_LD_MICROCASSYVOLTAGE
#define USB_DEVICE_ID_LD_MICROCASSYCURRENT
#define USB_DEVICE_ID_LD_MICROCASSYTIME
#define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE
#define USB_DEVICE_ID_LD_MICROCASSYPH
#define USB_DEVICE_ID_LD_POWERANALYSERCASSY
#define USB_DEVICE_ID_LD_CONVERTERCONTROLLERCASSY
#define USB_DEVICE_ID_LD_MACHINETESTCASSY
#define USB_DEVICE_ID_LD_JWM
#define USB_DEVICE_ID_LD_DMMP
#define USB_DEVICE_ID_LD_UMIP
#define USB_DEVICE_ID_LD_UMIC
#define USB_DEVICE_ID_LD_UMIB
#define USB_DEVICE_ID_LD_XRAY
#define USB_DEVICE_ID_LD_XRAY2
#define USB_DEVICE_ID_LD_XRAYCT
#define USB_DEVICE_ID_LD_VIDEOCOM
#define USB_DEVICE_ID_LD_MOTOR
#define USB_DEVICE_ID_LD_COM3LAB
#define USB_DEVICE_ID_LD_TELEPORT
#define USB_DEVICE_ID_LD_NETWORKANALYSER
#define USB_DEVICE_ID_LD_POWERCONTROL
#define USB_DEVICE_ID_LD_MACHINETEST
#define USB_DEVICE_ID_LD_MOSTANALYSER
#define USB_DEVICE_ID_LD_MOSTANALYSER2
#define USB_DEVICE_ID_LD_ABSESP
#define USB_DEVICE_ID_LD_AUTODATABUS
#define USB_DEVICE_ID_LD_MCT
#define USB_DEVICE_ID_LD_HYBRID
#define USB_DEVICE_ID_LD_HEATCONTROL

#ifdef CONFIG_USB_DYNAMIC_MINORS
#define USB_LD_MINOR_BASE
#else
#define USB_LD_MINOR_BASE
#endif

/* table of devices that work with this driver */
static const struct usb_device_id ld_usb_table[] =;
MODULE_DEVICE_TABLE(usb, ld_usb_table);
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();

/* All interrupt in transfers are collected in a ring buffer to
 * avoid racing conditions and get better performance of the driver.
 */
static int ring_buffer_size =;
module_param(ring_buffer_size, int, 0000);
MODULE_PARM_DESC();

/* The write_buffer can contain more than one interrupt out transfer.
 */
static int write_buffer_size =;
module_param(write_buffer_size, int, 0000);
MODULE_PARM_DESC();

/* As of kernel version 2.6.4 ehci-hcd uses an
 * "only one interrupt transfer per frame" shortcut
 * to simplify the scheduling of periodic transfers.
 * This conflicts with our standard 1ms intervals for in and out URBs.
 * We use default intervals of 2ms for in and 2ms for out transfers,
 * which should be fast enough.
 * Increase the interval to allow more devices that do interrupt transfers,
 * or set to 1 to use the standard interval from the endpoint descriptors.
 */
static int min_interrupt_in_interval =;
module_param(min_interrupt_in_interval, int, 0000);
MODULE_PARM_DESC();

static int min_interrupt_out_interval =;
module_param(min_interrupt_out_interval, int, 0000);
MODULE_PARM_DESC();

/* Structure to hold all of our device specific stuff */
struct ld_usb {};

static struct usb_driver ld_usb_driver;

/*
 *	ld_usb_abort_transfers
 *      aborts transfers and frees associated data structures
 */
static void ld_usb_abort_transfers(struct ld_usb *dev)
{}

/*
 *	ld_usb_delete
 */
static void ld_usb_delete(struct ld_usb *dev)
{}

/*
 *	ld_usb_interrupt_in_callback
 */
static void ld_usb_interrupt_in_callback(struct urb *urb)
{}

/*
 *	ld_usb_interrupt_out_callback
 */
static void ld_usb_interrupt_out_callback(struct urb *urb)
{}

/*
 *	ld_usb_open
 */
static int ld_usb_open(struct inode *inode, struct file *file)
{}

/*
 *	ld_usb_release
 */
static int ld_usb_release(struct inode *inode, struct file *file)
{}

/*
 *	ld_usb_poll
 */
static __poll_t ld_usb_poll(struct file *file, poll_table *wait)
{}

/*
 *	ld_usb_read
 */
static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,
			   loff_t *ppos)
{}

/*
 *	ld_usb_write
 */
static ssize_t ld_usb_write(struct file *file, const char __user *buffer,
			    size_t count, loff_t *ppos)
{}

/* file operations needed when we register this driver */
static const struct file_operations ld_usb_fops =;

/*
 * usb class driver info in order to get a minor number from the usb core,
 * and to have the device registered with the driver core
 */
static struct usb_class_driver ld_usb_class =;

/*
 *	ld_usb_probe
 *
 *	Called by the usb core when a new device is connected that it thinks
 *	this driver might be interested in.
 */
static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{}

/*
 *	ld_usb_disconnect
 *
 *	Called by the usb core when the device is removed from the system.
 */
static void ld_usb_disconnect(struct usb_interface *intf)
{}

/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver ld_usb_driver =;

module_usb_driver();