drivers/usb/image/mdc800.c

Source file repositories/reference/linux-study-clean/drivers/usb/image/mdc800.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/image/mdc800.c
Extension
.c
Size
24188 bytes
Lines
1079
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 mdc800_device_ops;
static struct usb_class_driver mdc800_class = {
	.name =		"mdc800%d",
	.fops =		&mdc800_device_ops,
	.minor_base =	MDC800_DEVICE_MINOR_BASE,
};


/*
 * Callback to search the Mustek MDC800 on the USB Bus
 */
static int mdc800_usb_probe (struct usb_interface *intf,
			       const struct usb_device_id *id)
{
	int i,j;
	struct usb_host_interface *intf_desc;
	struct usb_device *dev = interface_to_usbdev (intf);
	int irq_interval=0;
	int retval;

	dev_dbg(&intf->dev, "(%s) called.\n", __func__);


	if (mdc800->dev != NULL)
	{
		dev_warn(&intf->dev, "only one Mustek MDC800 is supported.\n");
		return -ENODEV;
	}

	if (dev->descriptor.bNumConfigurations != 1)
	{
		dev_err(&intf->dev,
			"probe fails -> wrong Number of Configuration\n");
		return -ENODEV;
	}
	intf_desc = intf->cur_altsetting;

	if (
			( intf_desc->desc.bInterfaceClass != 0xff )
		||	( intf_desc->desc.bInterfaceSubClass != 0 )
		|| ( intf_desc->desc.bInterfaceProtocol != 0 )
		|| ( intf_desc->desc.bNumEndpoints != 4)
	)
	{
		dev_err(&intf->dev, "probe fails -> wrong Interface\n");
		return -ENODEV;
	}

	/* Check the Endpoints */
	for (i=0; i<4; i++)
	{
		mdc800->endpoint[i]=-1;
		for (j=0; j<4; j++)
		{
			if (mdc800_endpoint_equals (&intf_desc->endpoint [j].desc,&mdc800_ed [i]))
			{
				mdc800->endpoint[i]=intf_desc->endpoint [j].desc.bEndpointAddress ;
				if (i==1)
				{
					irq_interval=intf_desc->endpoint [j].desc.bInterval;
				}
			}
		}
		if (mdc800->endpoint[i] == -1)
		{
			dev_err(&intf->dev, "probe fails -> Wrong Endpoints.\n");
			return -ENODEV;
		}
	}


	dev_info(&intf->dev, "Found Mustek MDC800 on USB.\n");

	mutex_lock(&mdc800->io_lock);

	retval = usb_register_dev(intf, &mdc800_class);
	if (retval) {
		dev_err(&intf->dev, "Not able to get a minor for this device.\n");
		mutex_unlock(&mdc800->io_lock);
		return -ENODEV;
	}

	mdc800->dev=dev;
	mdc800->open=0;

	/* Setup URB Structs */
	usb_fill_int_urb (
		mdc800->irq_urb,
		mdc800->dev,
		usb_rcvintpipe (mdc800->dev,mdc800->endpoint [1]),

Annotation

Implementation Notes