Linux under the USB drive call flow __linux

Source: Internet
Author: User

Driver/usb/core/hub.c:usb->hun_thread ()->hub->events ()->hub_port_connect_change () driver/usb/core/ HUB.C Hub_port_connect_change ()//detection of new device Connections Usb_new_device (UDEV)//Registration of new equipment usb_get_configuration (UDEV)//acquisition of equipment various descriptors Devic E_add (&udev->dev)//register this device in the USB system Bus_attach_device (DEV)///Take this device to the unit list of the corresponding bus Device_attach ()// Find the appropriate device driver for the device bus_for_each_drv (Dev->bus,null,dev,__device_attach)//Find a matching driver from all registered drivers on the bus (drv=next_ Driver (&i)) &&!error) ERROR=FN (drv,data);//return 0 mechanical search, return error will stop search next_driver (&i)//Traverse all driver fn on bus ( Drv,data)//See if the driver matches Driver_probe_device (Drv,dev)//Check device Usb_register_device_driver ()//Register our driver//bus_register (& Amp;usb_bus_type) DRIVERS/USB/CORE/USB.C//usb_bus_type drivers/usb/core/driver.c usb/core/driver.c for USB drivers will first call USB _device_match () is_usb_device (Dev)//dev represents the entire USB device usb_match_id () usb_math_dynamic_id ()//dev represents the USB device interface Really_ Probe ()//further matching USB devices two branches: device-level, interface-level. The rest of the usb_device_match was filtered out. Device Level DrV must be usb_generic_driver in the USB system only driver is the driver of the entire device, it is registered in Usb_init, and the USB drive we usually write is representative of a interface Choose_	Configuration () usb_set_configuration ();

Set the configuration, and register interface Device_add ()//here for the corresponding interface analysis, will enter what we call Branch 2, interface.		Usb_probe_interface () driver->probe (); Here is the code to call your own. This function is the probe function we write ourselves.




The above content is I reproduced below the simple shorthand, may provide some reference.

2.6.22 a USB device plugged into the Linux system after the PC is how to step into our USB device-driven probe function, we know that our USB-driven probe function of a parameter is a interface structure, so generally speaking, Any one of the interfaces in a USB device should have a corresponding driver, with an exception (e.g., CDC-ACM).

/*driver/usb/core/hub.c*/:usb_hub_init ()-->hub_thread ()-->hub_events ()-->hub_port_connect_change ()

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 driver via Usb_registe_device_driver (), which specifies the bus as Usb_bus_type for our driver object (usb_driver):
Bus_register (&usb_bus_type)---DRIVERS/USB/CORE/USB.C
Usb_bus_type----DRIVERS/USB/CORE/DRIVER.C

Struct Bus_type Usb_bus_type = {

...

. match = Usb_device_match,

....

}
Usb/core/driver.c
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);

...

}

...

}

This function is more important, but we only care about the probe process so it saves a lot of things. It calls the Device_add () function for each interface under the current configuration, which, according to the previous analysis, will go to the next branch of 2 that we are going to analyze.

The branch 2:dev,drv represents the interface level:

At this point dev represents a interface, and DRV represents our own USB drive. But we should see that DRV is a device_driver type, and the type of USB drive we write is generally usb_driver, so the probe here and the probe we write ourselves are obviously not the same. In fact, the DRV here is a child object embedded in our drive object (because the driver of Linux must be represented by Device_driver). Where is the probe function of this child object assigned? It depends on the Usb_register function,

Tracking This function we can see that the probe function here is actually usb_probe_interface/*usb/core/driver.c*/(all USB interface drives are the same).
static int usb_probe_interface (struct device *dev)

{

struct Driver = To_usb_driver (dev->driver); Dev->driver is set in Really_probe.
...

Error = Driver->probe (intf, id); This is the probe function we wrote ourselves.
...

}

Driver->probe (intf, id); This is called into the code we wrote ourselves,

Article from http://www.cublog.cn/u3/117158/showart_2278763.html

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.