drivers/usb/misc/idmouse.c

Source file repositories/reference/linux-study-clean/drivers/usb/misc/idmouse.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/misc/idmouse.c
Extension
.c
Size
10821 bytes
Lines
408
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations idmouse_fops = {
	.owner = THIS_MODULE,
	.read = idmouse_read,
	.open = idmouse_open,
	.release = idmouse_release,
	.llseek = default_llseek,
};

/* class driver information */
static struct usb_class_driver idmouse_class = {
	.name = "idmouse%d",
	.fops = &idmouse_fops,
	.minor_base = USB_IDMOUSE_MINOR_BASE,
};

/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver idmouse_driver = {
	.name = DRIVER_SHORT,
	.probe = idmouse_probe,
	.disconnect = idmouse_disconnect,
	.suspend = idmouse_suspend,
	.resume = idmouse_resume,
	.reset_resume = idmouse_resume,
	.id_table = idmouse_table,
	.supports_autosuspend = 1,
};

static int idmouse_create_image(struct usb_idmouse *dev)
{
	int bytes_read;
	int bulk_read;
	int result;

	memcpy(dev->bulk_in_buffer, HEADER, sizeof(HEADER)-1);
	bytes_read = sizeof(HEADER)-1;

	/* reset the device and set a fast blink rate */
	result = ftip_command(dev, FTIP_RELEASE, 0, 0);
	if (result < 0)
		goto reset;
	result = ftip_command(dev, FTIP_BLINK,   1, 0);
	if (result < 0)
		goto reset;

	/* initialize the sensor - sending this command twice */
	/* significantly reduces the rate of failed reads     */
	result = ftip_command(dev, FTIP_ACQUIRE, 0, 0);
	if (result < 0)
		goto reset;
	result = ftip_command(dev, FTIP_ACQUIRE, 0, 0);
	if (result < 0)
		goto reset;

	/* start the readout - sending this command twice */
	/* presumably enables the high dynamic range mode */
	result = ftip_command(dev, FTIP_RESET,   0, 0);
	if (result < 0)
		goto reset;
	result = ftip_command(dev, FTIP_RESET,   0, 0);
	if (result < 0)
		goto reset;

	/* loop over a blocking bulk read to get data from the device */
	while (bytes_read < IMGSIZE) {
		result = usb_bulk_msg(dev->udev,
				usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
				dev->bulk_in_buffer + bytes_read,
				dev->bulk_in_size, &bulk_read, 5000);
		if (result < 0) {
			/* Maybe this error was caused by the increased packet size? */
			/* Reset to the original value and tell userspace to retry.  */
			if (dev->bulk_in_size != dev->orig_bi_size) {
				dev->bulk_in_size = dev->orig_bi_size;
				result = -EAGAIN;
			}
			break;
		}
		if (signal_pending(current)) {
			result = -EINTR;
			break;
		}
		bytes_read += bulk_read;
	}

	/* check for valid image */
	/* right border should be black (0x00) */
	for (bytes_read = sizeof(HEADER)-1 + WIDTH-1; bytes_read < IMGSIZE; bytes_read += WIDTH)
		if (dev->bulk_in_buffer[bytes_read] != 0x00)
			return -EAGAIN;

Annotation

Implementation Notes