Changes to the USB driver API for the 2.5 series kernel
[This article was contributed by Greg Kroah-Hartman]
Over the 2.5 kernel development series, the USB driver api has changed a lot. As LWN has graciously allowed me to write a kernel article this week, and I know a bit about the USB kernel code, I thought I would discuss a short summary of the major changes that have happened with it for anyone wanting to port a 2.4 USB driver to 2.5.
The main struct usb_driver structure has shrunk. The fops and minor variables have been removed, as the majority of USB drivers do not need to use the USB major number. If a USB driver needs to use the USB major, then the usb_register_dev() function should be called when a USB device has been found, and a minor number needs to be assigned to it. This function needs to have a struct usb_interface that the minor number should be assigned to, and a pointer to a struct usb_class_driver structure. This usb_class_driver structure is defined as:
struct usb_class_driver {
char *name;
struct file_operations *fops;
mode_t mode;
int minor_base;
};
The name variable is the devfs name for this driver. The fops variable is a pointer to the struct file_operations that should be called when this device is accessed. The mode variable defines the file permissions that devfs will use when creating the device node. Finally, the minor_base variable is the start of the minor range that this driver has assigned to it.
When usb_register_dev() is called, the devfs node will be created if devfs is enabled, and a usb class device is created in sysfs at /sys/class/usb/. After the device is removed from the system, the usb_unregister_dev() function should be called. This function will return the minor number to the USB core (to be used again later for a new device), the devfs node will be deleted if devfs is enabled in the kernel, and the usb class device will be removed from sysfs.
Because of these two functions, USB drivers no longer need to worry about managing the devfs entries on their own, like is necessary in the 2.4 kernel.
Also, USB drivers can use the usb_set_intfdata() function to save a pointer to a USB driver specific structure. This can be used instead of having to keep a static array of device pointers for every driver. usb_set_intfdata() should be called at the end of the USB driver probe function. Then in the open() function, usb_get_intfdata() should be called to retrieve the stored pointer.
For a good example of how to make these changes, look at how the usb-skeleton.c driver has changed between the 2.4 and 2.5 kernels. This driver is a framework driver that can be used to base any new USB drivers on.
There are also a number of USB api functions that have had their parameters modified from 2.4 to 2.5. Two of the most visible examples of this is the usb_submit_urb() function, and the USB probe() callback function.
In the usb_submit_urb() function, the USB core and host controller drivers can need to allocate memory from the kernel to complete the USB transfer. In 2.4, the core and host controller drivers guess that it is safe to sleep when requesting memory, and would call kmalloc with the GFP_KERNEL flag. The USB developers quickly realized that this is not always the best thing. So the usb_submit_urb() function now requires that the memory flags be passed to it:
int usb_submit_urb(struct urb *urb, int mem_flags);
In the 2.5 kernel the probe callback is now:
int (*probe) (struct usb_interface *intf,
const struct usb_device_id *id);
This was done to emphasize that USB drivers bind to a USB interface, and
not to an entire USB device. If the struct usb_device structure is
needed to be found, the interface_to_usbdev() macro should be used.
The biggest change in the USB api between the 2.4 and 2.5 kernels is much improved documentation. To build the kernel USB documentation, run:
make psdocs
By doing this, the Documentation/DocBook/usb.ps file will have
been created. This contains a lot of details about how the USB
subsystem works, and what all of the options to the USB functions are.
The primary author of all of this documentation is David Brownell, who
also wrote the USB gadget and USB 2.0 EHCI host controller driver.
