⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbtest.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
			retval = -ENOMEM;			break;		}		// FIRMWARE:  bulk source (maybe generates short writes)		retval = simple_io (urb, param->iterations, param->vary,					0, "test4");		simple_free_urb (urb);		break;	/* Queued bulk I/O tests */	case 5:		if (dev->out_pipe == 0 || param->sglen == 0)			break;		dev_dbg (&intf->dev,			"TEST 5:  write %d sglists %d entries of %d bytes\n",				param->iterations,				param->sglen, param->length);		sg = alloc_sglist (param->sglen, param->length, 0);		if (!sg) {			retval = -ENOMEM;			break;		}		// FIRMWARE:  bulk sink (maybe accepts short writes)		retval = perform_sglist (udev, param->iterations, dev->out_pipe,				&req, sg, param->sglen);		free_sglist (sg, param->sglen);		break;	case 6:		if (dev->in_pipe == 0 || param->sglen == 0)			break;		dev_dbg (&intf->dev,			"TEST 6:  read %d sglists %d entries of %d bytes\n",				param->iterations,				param->sglen, param->length);		sg = alloc_sglist (param->sglen, param->length, 0);		if (!sg) {			retval = -ENOMEM;			break;		}		// FIRMWARE:  bulk source (maybe generates short writes)		retval = perform_sglist (udev, param->iterations, dev->in_pipe,				&req, sg, param->sglen);		free_sglist (sg, param->sglen);		break;	case 7:		if (dev->out_pipe == 0 || param->sglen == 0 || param->vary == 0)			break;		dev_dbg (&intf->dev,			"TEST 7:  write/%d %d sglists %d entries 0..%d bytes\n",				param->vary, param->iterations,				param->sglen, param->length);		sg = alloc_sglist (param->sglen, param->length, param->vary);		if (!sg) {			retval = -ENOMEM;			break;		}		// FIRMWARE:  bulk sink (maybe accepts short writes)		retval = perform_sglist (udev, param->iterations, dev->out_pipe,				&req, sg, param->sglen);		free_sglist (sg, param->sglen);		break;	case 8:		if (dev->in_pipe == 0 || param->sglen == 0 || param->vary == 0)			break;		dev_dbg (&intf->dev,			"TEST 8:  read/%d %d sglists %d entries 0..%d bytes\n",				param->vary, param->iterations,				param->sglen, param->length);		sg = alloc_sglist (param->sglen, param->length, param->vary);		if (!sg) {			retval = -ENOMEM;			break;		}		// FIRMWARE:  bulk source (maybe generates short writes)		retval = perform_sglist (udev, param->iterations, dev->in_pipe,				&req, sg, param->sglen);		free_sglist (sg, param->sglen);		break;	/* non-queued sanity tests for control (chapter 9 subset) */	case 9:		retval = 0;		dev_dbg (&intf->dev,			"TEST 9:  ch9 (subset) control tests, %d times\n",				param->iterations);		for (i = param->iterations; retval == 0 && i--; /* NOP */)			retval = ch9_postconfig (dev);		if (retval)			dbg ("ch9 subset failed, iterations left %d", i);		break;	/* queued control messaging */	case 10:		if (param->sglen == 0)			break;		retval = 0;		dev_dbg (&intf->dev,				"TEST 10:  queue %d control calls, %d times\n",				param->sglen,				param->iterations);		retval = test_ctrl_queue (dev, param);		break;	/* simple non-queued unlinks (ring with one urb) */	case 11:		if (dev->in_pipe == 0 || !param->length)			break;		retval = 0;		dev_dbg (&intf->dev, "TEST 11:  unlink %d reads of %d\n",				param->iterations, param->length);		for (i = param->iterations; retval == 0 && i--; /* NOP */)			retval = unlink_simple (dev, dev->in_pipe,						param->length);		if (retval)			dev_dbg (&intf->dev, "unlink reads failed %d, "				"iterations left %d\n", retval, i);		break;	case 12:		if (dev->out_pipe == 0 || !param->length)			break;		retval = 0;		dev_dbg (&intf->dev, "TEST 12:  unlink %d writes of %d\n",				param->iterations, param->length);		for (i = param->iterations; retval == 0 && i--; /* NOP */)			retval = unlink_simple (dev, dev->out_pipe,						param->length);		if (retval)			dev_dbg (&intf->dev, "unlink writes failed %d, "				"iterations left %d\n", retval, i);		break;	/* ep halt tests */	case 13:		if (dev->out_pipe == 0 && dev->in_pipe == 0)			break;		retval = 0;		dev_dbg (&intf->dev, "TEST 13:  set/clear %d halts\n",				param->iterations);		for (i = param->iterations; retval == 0 && i--; /* NOP */)			retval = halt_simple (dev);				if (retval)			DBG (dev, "halts failed, iterations left %d\n", i);		break;	/* control write tests */	case 14:		if (!dev->info->ctrl_out)			break;		dev_dbg (&intf->dev, "TEST 14:  %d ep0out, %d..%d vary %d\n",				param->iterations,				realworld ? 1 : 0, param->length,				param->vary);		retval = ctrl_out (dev, param->iterations, 				param->length, param->vary);		break;	/* iso write tests */	case 15:		if (dev->out_iso_pipe == 0 || param->sglen == 0)			break;		dev_dbg (&intf->dev, 			"TEST 15:  write %d iso, %d entries of %d bytes\n",				param->iterations,				param->sglen, param->length);		// FIRMWARE:  iso sink		retval = test_iso_queue (dev, param,				dev->out_iso_pipe, dev->iso_out);		break;	/* iso read tests */	case 16:		if (dev->in_iso_pipe == 0 || param->sglen == 0)			break;		dev_dbg (&intf->dev,			"TEST 16:  read %d iso, %d entries of %d bytes\n",				param->iterations,				param->sglen, param->length);		// FIRMWARE:  iso source		retval = test_iso_queue (dev, param,				dev->in_iso_pipe, dev->iso_in);		break;	// FIXME unlink from queue (ring with N urbs)	// FIXME scatterlist cancel (needs helper thread)	}	do_gettimeofday (&param->duration);	param->duration.tv_sec -= start.tv_sec;	param->duration.tv_usec -= start.tv_usec;	if (param->duration.tv_usec < 0) {		param->duration.tv_usec += 1000 * 1000;		param->duration.tv_sec -= 1;	}	up (&dev->sem);	return retval;}/*-------------------------------------------------------------------------*/static unsigned force_interrupt = 0;module_param (force_interrupt, uint, 0);MODULE_PARM_DESC (force_interrupt, "0 = test default; else interrupt");#ifdef	GENERICstatic unsigned short vendor;module_param(vendor, ushort, 0);MODULE_PARM_DESC (vendor, "vendor code (from usb-if)");static unsigned short product;module_param(product, ushort, 0);MODULE_PARM_DESC (product, "product code (from vendor)");#endifstatic intusbtest_probe (struct usb_interface *intf, const struct usb_device_id *id){	struct usb_device	*udev;	struct usbtest_dev	*dev;	struct usbtest_info	*info;	char			*rtest, *wtest;	char			*irtest, *iwtest;	udev = interface_to_usbdev (intf);#ifdef	GENERIC	/* specify devices by module parameters? */	if (id->match_flags == 0) {		/* vendor match required, product match optional */		if (!vendor || le16_to_cpu(udev->descriptor.idVendor) != (u16)vendor)			return -ENODEV;		if (product && le16_to_cpu(udev->descriptor.idProduct) != (u16)product)			return -ENODEV;		dbg ("matched module params, vend=0x%04x prod=0x%04x",				le16_to_cpu(udev->descriptor.idVendor),				le16_to_cpu(udev->descriptor.idProduct));	}#endif	dev = kmalloc (sizeof *dev, SLAB_KERNEL);	if (!dev)		return -ENOMEM;	memset (dev, 0, sizeof *dev);	info = (struct usbtest_info *) id->driver_info;	dev->info = info;	init_MUTEX (&dev->sem);	dev->intf = intf;	/* cacheline-aligned scratch for i/o */	if ((dev->buf = kmalloc (TBUF_SIZE, SLAB_KERNEL)) == NULL) {		kfree (dev);		return -ENOMEM;	}	/* NOTE this doesn't yet test the handful of difference that are	 * visible with high speed interrupts:  bigger maxpacket (1K) and	 * "high bandwidth" modes (up to 3 packets/uframe).	 */	rtest = wtest = "";	irtest = iwtest = "";	if (force_interrupt || udev->speed == USB_SPEED_LOW) {		if (info->ep_in) {			dev->in_pipe = usb_rcvintpipe (udev, info->ep_in);			rtest = " intr-in";		}		if (info->ep_out) {			dev->out_pipe = usb_sndintpipe (udev, info->ep_out);			wtest = " intr-out";		}	} else {		if (info->autoconf) {			int status;			status = get_endpoints (dev, intf);			if (status < 0) {				dbg ("couldn't get endpoints, %d\n", status);				return status;			}			/* may find bulk or ISO pipes */		} else {			if (info->ep_in)				dev->in_pipe = usb_rcvbulkpipe (udev,							info->ep_in);			if (info->ep_out)				dev->out_pipe = usb_sndbulkpipe (udev,							info->ep_out);		}		if (dev->in_pipe)			rtest = " bulk-in";		if (dev->out_pipe)			wtest = " bulk-out";		if (dev->in_iso_pipe)			irtest = " iso-in";		if (dev->out_iso_pipe)			iwtest = " iso-out";	}	usb_set_intfdata (intf, dev);	dev_info (&intf->dev, "%s\n", info->name);	dev_info (&intf->dev, "%s speed {control%s%s%s%s%s} tests%s\n",			({ char *tmp;			switch (udev->speed) {			case USB_SPEED_LOW: tmp = "low"; break;			case USB_SPEED_FULL: tmp = "full"; break;			case USB_SPEED_HIGH: tmp = "high"; break;			default: tmp = "unknown"; break;			}; tmp; }),			info->ctrl_out ? " in/out" : "",			rtest, wtest,			irtest, iwtest,			info->alt >= 0 ? " (+alt)" : "");	return 0;}static int usbtest_suspend (struct usb_interface *intf, pm_message_t message){	return 0;}static int usbtest_resume (struct usb_interface *intf){	return 0;}static void usbtest_disconnect (struct usb_interface *intf){	struct usbtest_dev	*dev = usb_get_intfdata (intf);	down (&dev->sem);	usb_set_intfdata (intf, NULL);	dev_dbg (&intf->dev, "disconnect\n");	kfree (dev);}/* 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 = {	.name		= "EZ-USB device",	.ep_in		= 2,	.ep_out		= 2,	.alt		= 1,};/* fx2 version of ez-usb */static struct usbtest_info ez2_info = {	.name		= "FX2 device",	.ep_in		= 6,	.ep_out		= 2,	.alt		= 1,};/* ezusb family device with dedicated usb test firmware, */static struct usbtest_info fw_info = {	.name		= "usb test device",	.ep_in		= 2,	.ep_out		= 2,	.alt		= 1,	.autoconf	= 1,		// iso and ctrl_out need autoconf	.ctrl_out	= 1,	.iso		= 1,		// iso_ep's are #8 in/out};/* 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 = {	.name		= "Linux gadget zero",	.autoconf	= 1,	.ctrl_out	= 1,	.alt		= 0,};static struct usbtest_info um_info = {	.name		= "Linux user mode test driver",	.autoconf	= 1,	.alt		= -1,};static struct usbtest_info um2_info = {	.name		= "Linux user mode ISO test driver",	.autoconf	= 1,	.iso		= 1,	.alt		= -1,};#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 = {	.name		= "Generic USB device",	.alt		= -1,};#endif// FIXME remove this static struct usbtest_info hact_info = {	.name		= "FX2/hact",	//.ep_in		= 6,	.ep_out		= 2,	.alt		= -1,};static struct usb_device_id id_table [] = {	{ USB_DEVICE (0x0547, 0x1002),		.driver_info = (unsigned long) &hact_info,		},	/*-------------------------------------------------------------*/	/* EZ-USB devices which download firmware to replace (or in our	 * case augment) the default device implementation.	 */	/* generic EZ-USB FX controller */	{ USB_DEVICE (0x0547, 0x2235),		.driver_info = (unsigned long) &ez1_info,		},	/* CY3671 development board with EZ-USB FX */	{ USB_DEVICE (0x0547, 0x0080),		.driver_info = (unsigned long) &ez1_info,		},	/* generic EZ-USB FX2 controller (or development board) */	{ USB_DEVICE (0x04b4, 0x8613),		.driver_info = (unsigned long) &ez2_info,		},	/* re-enumerated usb test device firmware */	{ USB_DEVICE (0xfff0, 0xfff0),		.driver_info = (unsigned long) &fw_info,		},	/* "Gadget Zero" firmware runs under Linux */	{ USB_DEVICE (0x0525, 0xa4a0),		.driver_info = (unsigned long) &gz_info,		},	/* so does a user-mode variant */	{ USB_DEVICE (0x0525, 0xa4a4),		.driver_info = (unsigned long) &um_info,		},	/* ... and a user-mode variant that talks iso */	{ USB_DEVICE (0x0525, 0xa4a3),		.driver_info = (unsigned long) &um2_info,		},#ifdef KEYSPAN_19Qi	/* Keyspan 19qi uses an21xx (original EZ-USB) */	// this does not coexist with the real Keyspan 19qi driver!	{ USB_DEVICE (0x06cd, 0x010b),		.driver_info = (unsigned long) &ez1_info,		},#endif	/*-------------------------------------------------------------*/#ifdef IBOT2	/* iBOT2 makes a nice source of high speed bulk-in data */	// this does not coexist with a real iBOT2 driver!	{ USB_DEVICE (0x0b62, 0x0059),		.driver_info = (unsigned long) &ibot2_info,		},#endif	/*-------------------------------------------------------------*/#ifdef GENERIC	/* module params can specify devices to use for control tests */	{ .driver_info = (unsigned long) &generic_info, },#endif	/*-------------------------------------------------------------*/	{ }};MODULE_DEVICE_TABLE (usb, id_table);static struct usb_driver usbtest_driver = {	.owner =	THIS_MODULE,	.name =		"usbtest",	.id_table =	id_table,	.probe =	usbtest_probe,	.ioctl =	usbtest_ioctl,	.disconnect =	usbtest_disconnect,	.suspend =	usbtest_suspend,	.resume =	usbtest_resume,};/*-------------------------------------------------------------------------*/static int __init usbtest_init (void){#ifdef GENERIC	if (vendor)		dbg ("params: vend=0x%04x prod=0x%04x", vendor, product);#endif	return usb_register (&usbtest_driver);}module_init (usbtest_init);static void __exit usbtest_exit (void){	usb_deregister (&usbtest_driver);}module_exit (usbtest_exit);MODULE_DESCRIPTION ("USB Core/HCD Testing Driver");MODULE_LICENSE ("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -