linux/drivers/usb/misc/usbtest.c

// SPDX-License-Identifier: GPL-2.0
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/scatterlist.h>
#include <linux/mutex.h>
#include <linux/timer.h>
#include <linux/usb.h>

#define SIMPLE_IO_TIMEOUT

/*-------------------------------------------------------------------------*/

static int override_alt =;
module_param_named(alt, override_alt, int, 0644);
MODULE_PARM_DESC();
static void complicated_callback(struct urb *urb);

/*-------------------------------------------------------------------------*/

/* FIXME make these public somewhere; usbdevfs.h? */

/* Parameter for usbtest driver. */
struct usbtest_param_32 {};

/*
 * Compat parameter to the usbtest driver.
 * This supports older user space binaries compiled with 64 bit compiler.
 */
struct usbtest_param_64 {};

/* IOCTL interface to the driver. */
#define USBTEST_REQUEST_32
/* COMPAT IOCTL interface to the driver. */
#define USBTEST_REQUEST_64

/*-------------------------------------------------------------------------*/

#define GENERIC

/* Some devices that can be used for testing will have "real" drivers.
 * Entries for those need to be enabled here by hand, after disabling
 * that "real" driver.
 */
//#define	IBOT2		/* grab iBOT2 webcams */
//#define	KEYSPAN_19Qi	/* grab un-renumerated serial adapter */

/*-------------------------------------------------------------------------*/

struct usbtest_info {};

/* this is accessed only through usbfs ioctl calls.
 * one ioctl to issue a test ... one lock per device.
 * tests create other threads if they need them.
 * urbs and buffers are allocated dynamically,
 * and data generated deterministically.
 */
struct usbtest_dev {};

static struct usb_device *testdev_to_usbdev(struct usbtest_dev *test)
{}

/* set up all urbs so they can be used with either bulk or interrupt */
#define INTERRUPT_RATE

#define ERROR(tdev, fmt, args...)
#define WARNING(tdev, fmt, args...)

#define GUARD_BYTE
#define MAX_SGLEN

/*-------------------------------------------------------------------------*/

static inline void endpoint_update(int edi,
				   struct usb_host_endpoint **in,
				   struct usb_host_endpoint **out,
				   struct usb_host_endpoint *e)
{}

static int
get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf)
{}

/*-------------------------------------------------------------------------*/

/* Support for testing basic non-queued I/O streams.
 *
 * These just package urbs as requests that can be easily canceled.
 * Each urb's data buffer is dynamically allocated; callers can fill
 * them with non-zero test data (or test for it) when appropriate.
 */

static void simple_callback(struct urb *urb)
{}

static struct urb *usbtest_alloc_urb(
	struct usb_device	*udev,
	int			pipe,
	unsigned long		bytes,
	unsigned		transfer_flags,
	unsigned		offset,
	u8			bInterval,
	usb_complete_t		complete_fn)
{}

static struct urb *simple_alloc_urb(
	struct usb_device	*udev,
	int			pipe,
	unsigned long		bytes,
	u8			bInterval)
{}

static struct urb *complicated_alloc_urb(
	struct usb_device	*udev,
	int			pipe,
	unsigned long		bytes,
	u8			bInterval)
{}

static unsigned pattern;
static unsigned mod_pattern;
module_param_named(pattern, mod_pattern, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC();

static unsigned get_maxpacket(struct usb_device *udev, int pipe)
{}

static int ss_isoc_get_packet_num(struct usb_device *udev, int pipe)
{}

static void simple_fill_buf(struct urb *urb)
{}

static inline unsigned long buffer_offset(void *buf)
{}

static int check_guard_bytes(struct usbtest_dev *tdev, struct urb *urb)
{}

static int simple_check_buf(struct usbtest_dev *tdev, struct urb *urb)
{}

static void simple_free_urb(struct urb *urb)
{}

static int simple_io(
	struct usbtest_dev	*tdev,
	struct urb		*urb,
	int			iterations,
	int			vary,
	int			expected,
	const char		*label
)
{}


/*-------------------------------------------------------------------------*/

/* We use scatterlist primitives to test queued I/O.
 * Yes, this also tests the scatterlist primitives.
 */

static void free_sglist(struct scatterlist *sg, int nents)
{}

static struct scatterlist *
alloc_sglist(int nents, int max, int vary, struct usbtest_dev *dev, int pipe)
{}

struct sg_timeout {};

static void sg_timeout(struct timer_list *t)
{}

static int perform_sglist(
	struct usbtest_dev	*tdev,
	unsigned		iterations,
	int			pipe,
	struct usb_sg_request	*req,
	struct scatterlist	*sg,
	int			nents
)
{}


/*-------------------------------------------------------------------------*/

/* unqueued control message testing
 *
 * there's a nice set of device functional requirements in chapter 9 of the
 * usb 2.0 spec, which we can apply to ANY device, even ones that don't use
 * special test firmware.
 *
 * we know the device is configured (or suspended) by the time it's visible
 * through usbfs.  we can't change that, so we won't test enumeration (which
 * worked 'well enough' to get here, this time), power management (ditto),
 * or remote wakeup (which needs human interaction).
 */

static unsigned realworld =;
module_param(realworld, uint, 0);
MODULE_PARM_DESC();

static int get_altsetting(struct usbtest_dev *dev)
{}

static int set_altsetting(struct usbtest_dev *dev, int alternate)
{}

static int is_good_config(struct usbtest_dev *tdev, int len)
{}

static int is_good_ext(struct usbtest_dev *tdev, u8 *buf)
{}

static int is_good_ss_cap(struct usbtest_dev *tdev, u8 *buf)
{}

static int is_good_con_id(struct usbtest_dev *tdev, u8 *buf)
{}

/* sanity test for standard requests working with usb_control_mesg() and some
 * of the utility functions which use it.
 *
 * this doesn't test how endpoint halts behave or data toggles get set, since
 * we won't do I/O to bulk/interrupt endpoints here (which is how to change
 * halt or toggle).  toggle testing is impractical without support from hcds.
 *
 * this avoids failing devices linux would normally work with, by not testing
 * config/altsetting operations for devices that only support their defaults.
 * such devices rarely support those needless operations.
 *
 * NOTE that since this is a sanity test, it's not examining boundary cases
 * to see if usbcore, hcd, and device all behave right.  such testing would
 * involve varied read sizes and other operation sequences.
 */
static int ch9_postconfig(struct usbtest_dev *dev)
{}

/*-------------------------------------------------------------------------*/

/* use ch9 requests to test whether:
 *   (a) queues work for control, keeping N subtests queued and
 *       active (auto-resubmit) for M loops through the queue.
 *   (b) protocol stalls (control-only) will autorecover.
 *       it's not like bulk/intr; no halt clearing.
 *   (c) short control reads are reported and handled.
 *   (d) queues are always processed in-order
 */

struct ctrl_ctx {};

#define NUM_SUBCASES

struct subcase {};

static void ctrl_complete(struct urb *urb)
{}

static int
test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param)
{}
#undef NUM_SUBCASES


/*-------------------------------------------------------------------------*/

static void unlink1_callback(struct urb *urb)
{}

static int unlink1(struct usbtest_dev *dev, int pipe, int size, int async)
{}

static int unlink_simple(struct usbtest_dev *dev, int pipe, int len)
{}

/*-------------------------------------------------------------------------*/

struct queued_ctx {};

static void unlink_queued_callback(struct urb *urb)
{}

static int unlink_queued(struct usbtest_dev *dev, int pipe, unsigned num,
		unsigned size)
{}

/*-------------------------------------------------------------------------*/

static int verify_not_halted(struct usbtest_dev *tdev, int ep, struct urb *urb)
{}

static int verify_halted(struct usbtest_dev *tdev, int ep, struct urb *urb)
{}

static int test_halt(struct usbtest_dev *tdev, int ep, struct urb *urb)
{}

static int test_toggle_sync(struct usbtest_dev *tdev, int ep, struct urb *urb)
{}

static int halt_simple(struct usbtest_dev *dev)
{}

static int toggle_sync_simple(struct usbtest_dev *dev)
{}

/*-------------------------------------------------------------------------*/

/* Control OUT tests use the vendor control requests from Intel's
 * USB 2.0 compliance test device:  write a buffer, read it back.
 *
 * Intel's spec only _requires_ that it work for one packet, which
 * is pretty weak.   Some HCDs place limits here; most devices will
 * need to be able to handle more than one OUT data packet.  We'll
 * try whatever we're told to try.
 */
static int ctrl_out(struct usbtest_dev *dev,
		unsigned count, unsigned length, unsigned vary, unsigned offset)
{}

/*-------------------------------------------------------------------------*/

/* ISO/BULK tests ... mimics common usage
 *  - buffer length is split into N packets (mostly maxpacket sized)
 *  - multi-buffers according to sglen
 */

struct transfer_context {};

static void complicated_callback(struct urb *urb)
{}

static struct urb *iso_alloc_urb(
	struct usb_device	*udev,
	int			pipe,
	struct usb_endpoint_descriptor	*desc,
	long			bytes,
	unsigned offset
)
{}

static int
test_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param,
		int pipe, struct usb_endpoint_descriptor *desc, unsigned offset)
{}

static int test_unaligned_bulk(
	struct usbtest_dev *tdev,
	int pipe,
	unsigned length,
	int iterations,
	unsigned transfer_flags,
	const char *label)
{}

/* Run tests. */
static int
usbtest_do_ioctl(struct usb_interface *intf, struct usbtest_param_32 *param)
{}

/*-------------------------------------------------------------------------*/

/* We only have this one interface to user space, through usbfs.
 * User mode code can scan usbfs to find N different devices (maybe on
 * different busses) to use when testing, and allocate one thread per
 * test.  So discovery is simplified, and we have no device naming issues.
 *
 * Don't use these only as stress/load tests.  Use them along with
 * other USB bus activity:  plugging, unplugging, mousing, mp3 playback,
 * video capture, and so on.  Run different tests at different times, in
 * different sequences.  Nothing here should interact with other devices,
 * except indirectly by consuming USB bandwidth and CPU resources for test
 * threads and request completion.  But the only way to know that for sure
 * is to test when HC queues are in use by many devices.
 *
 * WARNING:  Because usbfs grabs udev->dev.sem before calling this ioctl(),
 * it locks out usbcore in certain code paths.  Notably, if you disconnect
 * the device-under-test, hub_wq will wait block forever waiting for the
 * ioctl to complete ... so that usb_disconnect() can abort the pending
 * urbs and then call usbtest_disconnect().  To abort a test, you're best
 * off just killing the userspace task and waiting for it to exit.
 */

static int
usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
{}

/*-------------------------------------------------------------------------*/

static unsigned force_interrupt;
module_param(force_interrupt, uint, 0);
MODULE_PARM_DESC();

#ifdef	GENERIC
static unsigned short vendor;
module_param(vendor, ushort, 0);
MODULE_PARM_DESC();

static unsigned short product;
module_param(product, ushort, 0);
MODULE_PARM_DESC();
#endif

static int
usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id)
{}

static int usbtest_suspend(struct usb_interface *intf, pm_message_t message)
{}

static int usbtest_resume(struct usb_interface *intf)
{}


static void usbtest_disconnect(struct usb_interface *intf)
{}

/* Basic testing only needs a device that can source or sink bulk traffic.
 * Any device can test control transfers (default with GENERIC binding).
 *
 * Several entries work with the default EP0 implementation that's built
 * into EZ-USB chips.  There's a default vendor ID which can be overridden
 * by (very) small config EEPROMS, but otherwise all these devices act
 * identically until firmware is loaded:  only EP0 works.  It turns out
 * to be easy to make other endpoints work, without modifying that EP0
 * behavior.  For now, we expect that kind of firmware.
 */

/* an21xx or fx versions of ez-usb */
static struct usbtest_info ez1_info =;

/* fx2 version of ez-usb */
static struct usbtest_info ez2_info =;

/* ezusb family device with dedicated usb test firmware,
 */
static struct usbtest_info fw_info =;

/* peripheral running Linux and 'zero.c' test firmware, or
 * its user-mode cousin. different versions of this use
 * different hardware with the same vendor/product codes.
 * host side MUST rely on the endpoint descriptors.
 */
static struct usbtest_info gz_info =;

static struct usbtest_info um_info =;

static struct usbtest_info um2_info =;

#ifdef IBOT2
/* this is a nice source of high speed bulk data;
 * uses an FX2, with firmware provided in the device
 */
static struct usbtest_info ibot2_info = {
	.name		= "iBOT2 webcam",
	.ep_in		= 2,
	.alt		= -1,
};
#endif

#ifdef GENERIC
/* we can use any device to test control traffic */
static struct usbtest_info generic_info =;
#endif


static const struct usb_device_id id_table[] =;
MODULE_DEVICE_TABLE(usb, id_table);

static struct usb_driver usbtest_driver =;

/*-------------------------------------------------------------------------*/

static int __init usbtest_init(void)
{}
module_init();

static void __exit usbtest_exit(void)
{}
module_exit(usbtest_exit);

MODULE_DESCRIPTION();
MODULE_LICENSE();