当前位置: 代码迷 >> 综合 >> OHCI and usb-core and related
  详细解决方案

OHCI and usb-core and related

热度:95   发布时间:2024-01-12 19:59:57.0

OHCI规范
    OHCI规范定义了两种主机控制器(HC)和主机控制器驱动(HCD)的通信通道,第一个为主机控制器操作寄存器,第二个为主机控制器通信域(HCCA)。在HCCA中定义了四种链表,周期性数据链表,控制传输数据链表,批量传输数据链表和完成数据链表。由数据结构TD和ED组成,每个ED描述USB设备一个端点的所有数据传输,所有ED链接在一起,TD描述在USB总线上传输的数据包。属于同一USB设备端点的TD被链接在一起,并挂在相应的ED上。

USB主机驱动结构

linuxUSB主机驱动由三部分组成:USB主机控制器驱动(HCD),USB驱动(USBD,应该就是USB-core),usb设备类驱动。
HCD主要功能:1,主机控制器硬件初始化2,为USBD层提供相应的接口函数3,提供根HUB设备配置控制功能()4,提供4种类型的设备传输。

USB驱动(USBD):整个USB主机驱动的核心,主要功能:1,USB总线管理,2,USB总线设备,3,USB总线带宽管理 4,USB的4种数据传输5,USB HUB驱动 6,为USB设备驱动提供接口,7,提供USB文件系统接口

USB设备驱动:访问特定的USB设备,为应用程序提供访问接口。

其中linux定义了URB用来在设备驱动和USBD,USBD和HCD间进行数据传输。

USBD提供了文件系统接口。应用程序可以通过文件系统访问USBD层,以获得USB驱动程序的管理信息,如USB总线状态,拓扑结构,连接在总线上的USB设备状态属性等。

主要数据结构及接口函数

管道(PIPE)是USB规范中定义的数据传输通道,USB设备的每个端点都对应唯一的数据传输通道。在LINUX中PIPE用32位的整型变量表示,描述了最大包长度,数据传输方向,设备地址,端点号,DATA0/DATA1标志,传输速度描述,数据传输类型。

USBD通过usb_driver,usb_operation,usb_bus,usb_device分别实现对USB设备驱动程序,USB主机控制器,USB总线和所有USB设备的管理。

usb_operations
在HCD层,每个USB主机控制器驱动都需要提供一个usb_operations结构,USBD将通过该结构中的接口函数访问相应的主机控制器。包括两部分,资源管理接口和数据传输接口。
struct usb_operations {
    int (*get_frame_number) (struct usb_device *usb_dev);
    int (*submit_urb) (struct urb *urb, unsigned mem_flags);
    int (*unlink_urb) (struct urb *urb, int status);

    /* allocate dma-consistent buffer for URB_DMA_NOMAPPING */
    void *(*buffer_alloc)(struct usb_bus *bus, size_t size,
            unsigned mem_flags,
            dma_addr_t *dma);
    void (*buffer_free)(struct usb_bus *bus, size_t size,
            void *addr, dma_addr_t dma);

    void (*disable)(struct usb_device *udev,
            struct usb_host_endpoint *ep);

    /* global suspend/resume of bus */
    int (*hub_suspend)(struct usb_bus *);
    int (*hub_resume)(struct usb_bus *);
};


struct usb_bus
每一个主机控制器和一套USB总线对应,所以usb-core要支持多套usb总线,用bus_list来管理这些usb_bus
*
 * Allocated per bus (tree of devices) we have:
 */
struct usb_bus {
    struct device *controller;    /* host/master side hardware */
    int busnum;            /* Bus number (in order of reg) */
    char *bus_name;            /* stable id (PCI slot_name etc) */
    u8 otg_port;            /* 0, or number of OTG/HNP port */
    unsigned is_b_host:1;        /* true during some HNP roleswitches */
    unsigned b_hnp_enable:1;    /* OTG: did A-Host enable HNP? */

    int devnum_next;        /* Next open device number in round-robin allocation */

    struct usb_devmap devmap;    /* device address allocation map */
    struct usb_operations *op;    /* Operations (specific to the HC) */
    struct usb_device *root_hub;    /* Root hub */
    struct list_head bus_list;    /* list of busses */
    void *hcpriv;                   /* Host Controller private data */

    int bandwidth_allocated;    /* on this bus: how much of the time
                     * reserved for periodic (intr/iso)
                     * requests is used, on average?
                     * Units: microseconds/frame.
                     * Limits: Full/low speed reserve 90%,
                     * while high speed reserves 80%.
                     */
    int bandwidth_int_reqs;        /* number of Interrupt requests */
    int bandwidth_isoc_reqs;    /* number of Isoc. requests */

    struct dentry *usbfs_dentry;    /* usbfs dentry entry for the bus */

    struct class_device *class_dev;    /* class device for this bus */
    struct kref kref;        /* handles reference counting this bus */
    void (*release)(struct usb_bus *bus);    /* function to destroy this bus's memory */
#if defined(CONFIG_USB_MON)
    struct mon_bus *mon_bus;    /* non-null when associated */
    int monitored;            /* non-zero when monitored */
#endif
};
其中usb_operations被挂在这儿。
相关函数:
usb_alloc_bus,初始化配置一个新的USB主机控制器时,HCD驱动程序调用此函数在USBD层为相关主机控制器分配相应的USB总线资源
usb_register_bus,当驱动程序完成对USB主机控制器的初始化后,需要通过调用usb_register_bus实现usb总线系统在USBD层的注册,以实现USBD层对总线的访问。

usb_device  USBD需要对连接到总线上的所有USB设备进行管理和资源分配。
/*
 * struct usb_device - kernel's representation of a USB device
 *
 * FIXME: Write the kerneldoc!
 *
 * Usbcore drivers should not set usbdev->state directly.  Instead use
 * usb_set_device_state().
 */
struct usb_device {
    int        devnum;        /* Address on USB bus */
    char        devpath [16];    /* Use in messages: /port/port/... */
    enum usb_device_state    state;    /* configured, not attached, etc */
    enum usb_device_speed    speed;    /* high/full/low (or error) */

    struct usb_tt    *tt;         /* low/full speed dev, highspeed hub */
    int        ttport;        /* device port on that tt hub */

    struct semaphore serialize;

    unsigned int toggle[2];        /* one bit for each endpoint ([0] = IN, [1] = OUT) */

    struct usb_device *parent;    /* our hub, unless we're the root */
    struct usb_bus *bus;        /* Bus we're part of */
    struct usb_host_endpoint ep0;

    struct device dev;        /* Generic device interface */

    struct usb_device_descriptor descriptor;/* Descriptor */
    struct usb_host_config *config;    /* All of the configs */

    struct usb_host_config *actconfig;/* the active configuration */
    struct usb_host_endpoint *ep_in[16];
    struct usb_host_endpoint *ep_out[16];

    char **rawdescriptors;        /* Raw descriptors for each config */

    int have_langid;        /* whether string_langid is valid yet */
    int string_langid;        /* language ID for strings */

    char *product;
    char *manufacturer;
    char *serial;            /* static strings from the device */
    struct list_head filelist;
    struct dentry *usbfs_dentry;    /* usbfs dentry entry for the device */

    /*
     * Child devices - these can be either new devices
     * (if this is a hub device), or different instances
     * of this same device.
     *
     * Each instance needs its own set of data structures.
     */

    int maxchild;            /* Number of ports if hub */
    struct usb_device *children[USB_MAXCHILDREN];
};
注意一下这几个字段
        struct usb_device_descriptor descriptor;/* Descriptor */
        struct usb_host_config *config; /* All of the configs */
       
        struct usb_host_config *actconfig;/* the active configuration */
        struct usb_host_endpoint *ep_in[16];
        struct usb_host_endpoint *ep_out[16];
描述的设备的端点和配置。

usb_driver:这个结构把USB设备挂在USB系统上。相当于USB设备和USB系统的接口
struct usb_driver {
    struct module *owner;

    const char *name;

    int (*probe) (struct usb_interface *intf,
              const struct usb_device_id *id);

    void (*disconnect) (struct usb_interface *intf);

    int (*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);

    const struct usb_device_id *id_table;

    struct device_driver driver;
};

usb_register:
USB设备类驱动可以将其注册到USBD层,同时USBD层会遍历当前总线上的所有设备判断是否有该驱动支持的USB设备
关于urb的就省略了,吃饭去。

  相关解决方案