Fork me on GitHub

usb请求块以及提交方式

URB结构体

struct urb {
    /* private: usb core and host controller only fields in the urb */
    struct kref kref;        /* reference count of the URB */
    void *hcpriv;            /* private data for host controller */
    atomic_t use_count;        /* concurrent submissions counter */
    atomic_t reject;        /* submissions will fail */
    int unlinked;            /* unlink error code */

    /* public: documented fields in the urb that can be used by drivers */
    struct list_head urb_list;    /* list head for use by the urb's
                     * current owner */
    struct list_head anchor_list;    /* the URB may be anchored */
    struct usb_anchor *anchor;
    struct usb_device *dev;        /* (in) pointer to associated device */
    struct usb_host_endpoint *ep;    /* (internal) pointer to endpoint */
    unsigned int pipe;        /* (in) pipe information */
    unsigned int stream_id;        /* (in) stream ID */
    int status;            /* (return) non-ISO status */
    unsigned int transfer_flags;    /* (in) URB_SHORT_NOT_OK | ...*/
    void *transfer_buffer;        /* (in) associated data buffer */
    dma_addr_t transfer_dma;    /* (in) dma addr for transfer_buffer */
    struct scatterlist *sg;        /* (in) scatter gather buffer list */
    int num_mapped_sgs;        /* (internal) mapped sg entries */
    int num_sgs;            /* (in) number of entries in the sg list */
    u32 transfer_buffer_length;    /* (in) data buffer length */
    u32 actual_length;        /* (return) actual transfer length */
    unsigned char *setup_packet;    /* (in) setup packet (control only) */
    dma_addr_t setup_dma;        /* (in) dma addr for setup_packet */
    int start_frame;        /* (modify) start frame (ISO) */
    int number_of_packets;        /* (in) number of ISO packets */
    int interval;            /* (modify) transfer interval
                     * (INT/ISO) */
    int error_count;        /* (return) number of ISO errors */
    void *context;            /* (in) context for completion */
    usb_(1)异步提交urb,提交完成后通过usb_fill[control] [int] [bulk]_urb传入的回调函数
_t complete;    /* (in) completion routine */
    struct usb_iso_packet_descriptor iso_frame_desc[0];
                    /* (in) ISO ONLY */
};
  • pipe:端点需要和主机控制器需要通过pipe进行通信;
unsigned int pipe;        /* (in) pipe information */
  • urb是主机控制器发给设备的,因此需要将设备的pipe告诉主机控制器。

  • transfer_buffer:in端点时,存放设备发给主机控制器的数据;out端点时,存放主机控制器发给设备的数据。

void *transfer_buffer;        /* (in) associated data buffer */
  • buffder长度;
u32 transfer_buffer_length;    /* (in) data buffer length */
  • complete:complete是一个回调函数,当通讯接收后,会调用。
usb_complete_t complete;    /* (in) completion routine */

每一个urb都是由usb主机控制器发送给usb设备的。

urb使用方式

1.分配urb

struct urb *usb_alloc_urb(int iso_packets,gfp_t mem_flags);

2.初始化urb

usb控制传输:void usb_fill_control_urb();
usb中断传输:void usb_fill_int_urb();
usb批量传输:void usb_fill_bulk();

以上函数不适用于等时传输:

3.提交urb(提交给主控制器,由主控制器发送给usb设备)

(1)异步提交urb,提交完成后通过usb_fill[control] [int] [bulk]_urb传入的回调函数

int usb_submit_urb(struct urb *urb,gfp_t mem_flags);

该函数只管发出去,不管是否发送成功。

(2)同步提交urb

int usb_fill[control] [int] [bulk]_msg(
struct usb_device *usb_dev,
unsigned int pipe,
void *data,
int len,
int *actual_length,
int timeout);

同步提交会一直等待urb提交成功;

usb 驱动数据结构

struct usb_device {
    int        devnum;
    char        devpath[16];
    u32        route;
    enum usb_device_state    state;
    enum usb_device_speed    speed;
    unsigned int        rx_lanes;
    unsigned int        tx_lanes;

    struct usb_tt    *tt;
    int        ttport;

    unsigned int toggle[2];

    struct usb_device *parent;
    struct usb_bus *bus;
    struct usb_host_endpoint ep0;

    struct device dev;

    struct usb_device_descriptor descriptor;
    struct usb_host_bos *bos;
    struct usb_host_config *config;

    struct usb_host_config *actconfig;
    struct usb_host_endpoint *ep_in[16];
    struct usb_host_endpoint *ep_out[16];

    char **rawdescriptors;

    unsigned short bus_mA;
    u8 portnum;
    u8 level;

    unsigned can_submit:1;
    unsigned persist_enabled:1;
    unsigned have_langid:1;
    unsigned authorized:1;
    unsigned authenticated:1;
    unsigned wusb:1;
    unsigned lpm_capable:1;
    unsigned usb2_hw_lpm_capable:1;
    unsigned usb2_hw_lpm_besl_capable:1;
    unsigned usb2_hw_lpm_enabled:1;
    unsigned usb2_hw_lpm_allowed:1;
    unsigned usb3_lpm_u1_enabled:1;
    unsigned usb3_lpm_u2_enabled:1;
    int string_langid;

    /* static strings from the device */
    char *product;
    char *manufacturer;
    char *serial;

    struct list_head filelist;

    int maxchild;

    u32 quirks;
    atomic_t urbnum;

    unsigned long active_duration;

#ifdef CONFIG_PM
    unsigned long connect_time;

    unsigned do_remote_wakeup:1;
    unsigned reset_resume:1;
    unsigned port_is_suspended:1;
#endif
    struct wusb_dev *wusb_dev;
    int slot_id;
    enum usb_device_removable removable;
    struct usb2_lpm_parameters l1_params;
    struct usb3_lpm_parameters u1_params;
    struct usb3_lpm_parameters u2_params;
    unsigned lpm_disable_count;

    u16 hub_delay;
};

struct usb_device描述一个usb设备
管道
每个断点通过管道和usb主控制器连接,管道包括以下几个部分:
1.端点地址
2.数据传输方向(IN或OUT)
3.数据传输模式

usb_[rcv][snd][ctrl][int][bulk][isoc]pipe(struct usb_device *usb_dev,_u8 endpointAddress);

分别表示接收,发送,控制,中断,批量,等时管道;
得到一个pipe,主机得到这个pipe,就知道跟谁去通讯了;

posted @ 2024-08-23 17:14  yooooooo  阅读(11)  评论(0编辑  收藏  举报