Transferred from: http://blog.csdn.net/zkami/article/details/2496770
Usb_hcd_omap_probe (const struct hc_driver *driver) (DEV/OHCI/OHCI-OMAP.C)
Called by Platform_driver_register () during module initialization to initialize and Ohci_hcd_omap_driver
Match the USB host controller.
->USB_CREATE_HCD (driver); Create a data structure representing Host-controller (struct USB_HCD) and initialize the Core/hcd.h
->HCD = Kzalloc (sizeof (*HCD) + driver->hcd_priv_size, Gfp_kernel); Allocating a piece of memory to a struct USB_HCD
->usb_bus_init (struct Usb_bus *bus); (HCD.C) Initializes the data structure representing the USB bus (struct Usb_bus)
Initialization of the struct USB_HCD timer, Work queue
Rsrc_start field of the fill struct USB_HCD: The starting physical address of the Host-controller Memory/io
Rsrc_len field: Length of Host-controller Memory/io
regs field: Host-controller Memory/io the kernel virtual address of the map.
->ohci_hcd_init (struct OHCI_HCD *ohci); (DEV/OHCI/OHCI-MEM.C)
->USB_ADD_HCD (struct USB_HCD *hcd,unsigned int irqnum, unsigned long irqflags) (/core/hcd.h)
Complete the remaining initialization of the struct USB_HCD
->hcd_buffer_create (HCD): Create Dmapool
->usb_register_bus (usb_bus): Register USB Bus
->usb_alloc_dev (NULL, &hcd->self, 0): (CORE/USB.C)
Dealing with the root hub (Hcd->self.root_hub) on the host controller HCD, what is done here is to request a struct usb_device struct for root hub and initialize it to assign the return value to the pointer Rhdev. The parent pointer of the Root hub points to the controller itself.
->ohci_omap_init: Complete init work for OMAP hardware
->otg_get_transceiver ();
->otg_set_host (Ohci->transceiver, &OHCI_TO_HCD (OHCI)->self);
Initialization for OTG features, followed by analysis
->ohci_init (struct OHCI_HCD *ohci); (HOST/OHCI-HCD.C)
--Allocate space for Ohci->hcca
->ohci_mem_init () Create dma_pool for Ohci->td_cache and Ohci->ed_cache
->REQUEST_IRQ (Irqnum, &USB_HCD_IRQ, IRQFLAGS,HCD->IRQ_DESCR, HCD)
Registers the interrupt handler function. Where the interrupt number is irqnum, the interrupt service is USB_HCD_IRQ (struct USB_HCD *hcd) (OHCI-HCD.C).
The interrupt types defined by the USB2.0 spec are: USB_HCD_IRQ () performs the corresponding operation according to the specific type, which is analyzed later.
#define OHCI_INTR_SO (1 << 0)/* Scheduling overrun */
#define OHCI_INTR_WDH (1 << 1)/* Writeback of Done_head */
#define OHCI_INTR_SF (1 << 2)/* Start Frame */
#define OHCI_INTR_RD (1 << 3)/* Resume Detect */
#define OHCI_INTR_UE (1 << 4)/* Unrecoverable error */
#define OHCI_INTR_FNO (1 << 5)/* Frame number Overflow */
#define OHCI_INTR_RHSC (1 << 6)/* Root Hub status change */
#define OHCI_INTR_OC (1 <<)/* Ownership change */
#define OHCI_INTR_MIE (1 <<)/* Master Interrupt Enable */
->ohci_omap_start (struct USB_HCD *hcd): Start OHCI
->ohci_run (struct OHCI_HCD *ohci) (OHCI-HCD.C)
Start an OHCI controller, set the BUS operational resets USB and controller
Enable interrupts to start OHCI HC according to spec write corresponding register
->ohci_stop (struct USB_HCD *hcd)
If the Ohci_run fails, release some resources and the requested interrupts, releasing the OHCI ed/td cache and Ohci-hcca
->register_root_hub (struct USB_HCD) (CORE/HCD.C)
->usb_set_device_state (Usb_device, Usb_device_state)
is Roothub words will only assign new_state to udev->state, otherwise according to Usb_device_state for different treatment
->usb_get_device_descriptor (Usb_dev, usb_dt_device_size) Gets the device descriptor for Roothub
->usb_get_descriptor (Dev, usb_dt_device, 0, desc, size); Returns the device descriptor, followed by analysis
->usb_new_device (Usb_dev) configuring and registering USB devices (HUB.C)
->usb_configure_device (Udev); (HUB.C) Read device configuration information
->usb_get_configuration (Udev);
->usb_cache_string () Read the device below three messages (character descriptor):p roduct, manufacturer, serial
->USB_CONFIGURE_DEVICE_OTG (Udev);
->usb_autoresume_device (udev->parent); Establishing a parent-child relationship for a USB device
->device_add (&udev->dev);
Registering a USB device: loading the device onto the bus (added to the bus's device queue) and searching for the matching driver for the device
->usb_set_device_state (Udev, usb_state_notattached);
->usb_hc_died (HCD);
->usb_hcd_poll_rh_status (USB_HCD) hcd.c
Get specific information on "root hub status changes" and submit this information to Usb_hcd->status_urb
->ohci_hub_status_data (USB_HCD, BUF)
First: Read the root hub "status change information" and store it in buffer
->ohci_root_hub_state_changes (OHCI, changed, any_connected);
Depending on the state of the host controller prior to the device access (such as suspend), the host controller state is set to the next state (such as operation) after the interrupt occurs, and whether the root hub needs to continue polling (Poll_rh equals indicating the need to continue polling)
->ohci_rh_suspend (OHCI, 1); PM Aspect later analysis
->ohci_rh_resume (OHCI); PM Aspect later analysis
->usb_hcd_resume_root_hub (OHCI_TO_HCD (OHCI)); PM Aspect later analysis
Then: Pass the root hub "state change information" saved in buffer to usb_hcd->status_urb and submit the URB to the root hub driver layer
Usb_hcd_unlink_urb_from_ep ()
Usb_hcd_giveback_urb ()
-Mod_timer () adjust the Roothub timer to enter the timer queue again
Linux USB Host-controller Initialization code Framework Analysis "Go"