Linux Kernel USB Drivers

The full text of Linux Device Drivers is available online which contains a lot of useful information. In particular, chapter 13 (PDF) contains a fairly complete explanation of writing USB device drivers.

Registration

Drivers identify themselves to the kernel via the usb_register() function. This takes a pointer to a struct usb_driver:

struct usb_driver {
  const char *name;
 
  int (*probe) (struct usb_interface *intf,
                const struct usb_device_id *id);
  void (*disconnect) (struct usb_interface *intf);
  int (*unlocked_ioctl) (struct usb_interface *intf, unsigned int code,
                        void *buf);
  int (*suspend) (struct usb_interface *intf, pm_message_t message);
  int (*resume) (struct usb_interface *intf);
  int (*reset_resume)(struct usb_interface *intf);
  int (*pre_reset)(struct usb_interface *intf);
  int (*post_reset)(struct usb_interface *intf);
 
  const struct usb_device_id *id_table;
  struct usb_dynids dynids;
  struct usbdrv_wrap drvwrap;
 
  unsigned int no_dynamic_id:1;
  unsigned int supports_autosuspend:1;
  unsigned int disable_hub_initiated_lpm:1;
  unsigned int soft_unbind:1;
};

The name field is fairly self-explanatory, and this is followed by pointers to a set of callback functions. These are invoked on the following conditions:

Function Reason
probe() Called by the USB core when a device matching the registered filters is found. Should initialise the device and return 0 to claim the device, or a negative error value otherwise.
disconnect() Called then a device is removed or the driver is unloaded.
unlocked_ioctl() Called to support user-space ioctl() calls into usbfs for this driver — not generally used, sysfs is preferred.
suspend() Called when the device is to be suspended by USB core.
resume() Called when the device is to be resumed after suspension by USB core.
reset_resume() Called when the device has been reset instead of resumed.
pre_reset() Called just prior to a device reset.
post_reset() Called just after a device reset.

More information on these can be found in Documentation/usb/callbacks.txt within the Linux kernel distribution.

The id_table field specifies a filter of which devices the driver potentially supports. Any device which matches these criteria will cause the probe() callback function to be invoked, which is where the driver should check whether it supports this instance of the device and initialise it appropriately. The field is a pointer to struct usb_device_id, which should be an array of structures terminated by one entirely zeroed. Commonly there will be a single, static instance of this structure in the driver which is useful as static variables are always zero-initialised.