Probe whole process of USB device

Source: Internet
Author: User

This article will explain in detail how a USB device in the 2.6.22 is plugged into our USB device-driven probe function, and we know that one of the parameters in our USB-driven probe function is the interface structure, so generally, Any one of the interfaces in a USB device should have a corresponding driver, with an exception (e.g., CDC-ACM).

We know that USB devices are plugged into the upper hub of a port to connect the system and then discovered by the system, when the USB device into a hub, the hub of the port state will change, so the system will know the change, this time will call Hub_port_connect _change ()/*driver/usb/core/hub.c*/

static void Hub_connect_change (struct usb_hub *hub, int portl, U16 Portstatus, U16 Portchange)

{

....

Usb_new_device (Udev);

...

}

The function creates a Usb_device object Udev, initializes it, and then invokes Usb_new_device () to obtain various descriptors for the USB device and to find the driver for each interface.

int Usb_new_device (struct usb_device *udev)

{

....

Err = Usb_get_configuration (udev);

....

Device_add (&udev->dev);

}

The function first calls Usb_get_configuration () to obtain various descriptors for the device (device descriptor, configuration descriptor, etc.), and then calls Device_add () to add the USB device to the USB system. In this process, the system goes back to find the appropriate driver for this device. In earlier versions of 2.6, when the configuration descriptor was parsed, the interface was interface as a device to invoke Device_add ()

int Device_add (struct device *dev)

{

....

if ((Error = Bus_add_device (dev))

...

Bus_attach_device (Dev);

...

}

This function is a general-purpose device management function that will call Bus_add_device for each device to add the device to the corresponding bus's device list. Bus_attach_device () is then invoked to match the driver, and the parameter dev for the first time the Bus_attach_device () is invoked for the USB device represents the entire USB device ( Later, the interface in the USB device will also call this function as a device.

int Bus_attach_device (struct device *dev)

{

...

ret = Device_attach (dev);

...

}

This function is used to find the appropriate device driver for the device (implemented by calling Device_attach ()).

int Device_attach (struct device *dev)

{

...

ret = Bus_for_each_drv (Dev->bus, NULL, Dev, __device_attach);

...

}

The function calls Bus_for_each_drv () to find the matching driver from all the drivers registered on the bus.

int bus_for_each_drv (struct bus_type *bus,

struct Device_driver *start,

void *data,

Int (*FN) (struct device_driver *, void *))

{

....

while ((DRV = Next_driver (&i)) &&!error)

Error = FN (DRV, data); Returning 0 will continue the search, and returning the error value will stop the search.

...

}

This function traverses all the drivers on the bus and invokes FN () for each driver to see if it matches. The FN here is __device_attach.

static int __device_attach (struct device_driver *drv, void *data)

{

struct device *dev = data;

Return Driver_probe_device (DRV, Dev);

}

int Driver_probe_device (struct device *drv, struct device)

{

...

if (Drv->bus->match &&!drv->bus_match (Dev, DRV))

...

ret = Really_probe (dev, DRV);

}

For USB drives, we register our drivers with Usb_registe () R, which is designated as Usb_bus_type for the bus in our driver object (usb_driver):

Struct Bus_type Usb_bus_type = {

...

. match = Usb_device_match,

....

}

Therefore, for the USB driver, the Usb_device_match () is invoked first.

static int Usb_device_match (struct device *dev, struct device_driver)

{

if (Is_usb_device (dev)) {/*dev represents the entire USB device * *

....

}

else/*dev represents a USB device interface*/

{

...

USB_MATCH_ID ();

...

USB_MATCH_DYNAMIC_ID ();

...

}

}

This function simply makes a rough match, returns 1 if the match succeeds, and then makes a further match by Really_probe, and returns 0 if the match fails, and Really_probe is not executing. The call to this function guarantees dev, DRV either at the device level (i.e. dev represents the USB device, DRV on behalf of the USB device driver), or at the interface level (that is, Dev represents a interface,drv for the USB device that represents the USB interface driver).

static int really_probe (struct device *dev, struct device_driver)

{

...

Dev->driver = DRV; First assign the value, the later probe process will use the

else if (drv->probe)

ret = Drv->probe (dev);

...

Probe_failed:

Dev->drvier = NULL; Probe failed, reset it

...

}

For USB, the call to this function has 2 branches, 1:DEV,DRV represents the device level, and 2 dev,drv represents the interface level. The other combinations were filtered out in the Usb_device_match,

The branch 1:dev,drv represents the device level:

At this time the DRV must be usb_generic_driver. Because in the current USB system only this driver represents the entire device driver, it is registered in the Usb_init, and we usually write the USB drive is representative of a interface.

struct Usb_device_driver usb_generic_driver = {

...

. Probe = Generic_probe,

...

}

Therefore, the drv->probe at this time will invoke Generic_probe ().

static int generic_probe (struct usb_device *udev)

{

...

c = choose_configuration (dev);

if (c >= 0) {

Err = Usb_set_configuration (Udev, C); Set up the configuration and register the interface.

...

}

...

}

This function selects a suitable configuration for this USB device and registers the interface below this configuration.

int usb_set_configuration (struct usb_device *dev, int configuration)

{

...

for (I = 0; I < nintf; i++) {

struct Usb_interface *intf = cp->interface[i];

...

Device_add (&intf->dev);

...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.