博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
USB子系统gadget analyse
阅读量:6676 次
发布时间:2019-06-25

本文共 10648 字,大约阅读时间需要 35 分钟。

struct usb_gadget_driver {        char                    *function;        enum usb_device_speed   speed;        void                    (*unbind)(struct usb_gadget *);        int                     (*setup)(struct usb_gadget *,                                        const struct usb_ctrlrequest *);        void                    (*disconnect)(struct usb_gadget *);        void                    (*suspend)(struct usb_gadget *);        void                    (*resume)(struct usb_gadget *);        /* FIXME support safe rmmod */        struct device_driver    driver;};struct s3c2410_udc {spinlock_t lock;struct s3c2410_ep ep[S3C2410_ENDPOINTS];int address;struct usb_gadget gadget;struct usb_gadget_driver *driver;struct s3c2410_request fifo_req;u8 fifo_buf[EP_FIFO_SIZE];u16 devstatus;u32 port_status;int ep0state;unsigned got_irq : 1;unsigned req_std : 1;unsigned req_config : 1;unsigned req_pending : 1;u8 vbus;struct dentry *regs_info;};USB从设备测分析. 首先我们要知道把usb 运行于client角色时, 它的USB控制器是运行在otg模式,  USB OTG标准在完全兼容USB2.0标准的基础之上, 它允许设备既可以做为主机, 也可作为外设操作,而此时控制USB设备控制器的驱动称之为UDC驱动, 我们记得HOST模式下控制USB设备控制器的是:USB主机控制器驱动.这些概念比较多.只要我们理清楚就容易理解了.UDC之上就是Gadget api .再之上就是gadeget  驱动. USB OTG的设备控制器被抽象为:"struct s3c2410_udc {        spinlock_t                      lock;        struct s3c2410_ep               ep[S3C2410_ENDPOINTS];        int                             address;        struct usb_gadget               gadget;        struct usb_gadget_driver        *driver;        struct s3c2410_request          fifo_req;        u8                              fifo_buf[EP_FIFO_SIZE];        u16                             devstatus;        u32                             port_status;        int                             ep0state;        unsigned                        got_irq : 1;        unsigned                        req_std : 1;        unsigned                        req_config : 1;        unsigned                        req_pending : 1;        u8                              vbus;        struct dentry                   *regs_info;};/*---------------------------------------------------------------------------*/static struct s3c2410_udc memory = {   .gadget = {          .ops             = &s3c2410_ops,          .ep0             = &memory.ep[0].ep,              .name            = gadget_name,               .dev = {                     .init_name       = "gadget",          },   },   /* control endpoint */       .ep[0] = {           .num             = 0,         .ep = {                      .name            = ep0name,                   .ops             = &s3c2410_ep_ops,                       .maxpacket       = EP0_FIFO_SIZE,             },           .dev             = &memory,       },   /* first group of endpoints */       .ep[1] = {           .num             = 1,         .ep = {                      .name            = "ep1-bulk",                        .ops             = &s3c2410_ep_ops,                       .maxpacket       = EP_FIFO_SIZE,              },           .dev             = &memory,               .fifo_size       = EP_FIFO_SIZE,              .bEndpointAddress = 1,               .bmAttributes    = USB_ENDPOINT_XFER_BULK,    },   .ep[2] = {           .num             = 2,         .ep = {                      .name            = "ep2-bulk",                        .ops             = &s3c2410_ep_ops,                       .maxpacket       = EP_FIFO_SIZE,              },           .dev             = &memory,               .fifo_size       = EP_FIFO_SIZE,              .bEndpointAddress = 2,               .bmAttributes    = USB_ENDPOINT_XFER_BULK,    },   .ep[3] = {           .num             = 3,         .ep = {                      .name            = "ep3-bulk",                        .ops             = &s3c2410_ep_ops,                       .maxpacket       = EP_FIFO_SIZE,              },           .dev             = &memory,               .fifo_size       = EP_FIFO_SIZE,              .bEndpointAddress = 3,               .bmAttributes    = USB_ENDPOINT_XFER_BULK,    },   .ep[4] = {           .num             = 4,         .ep = {                      .name            = "ep4-bulk",                        .ops             = &s3c2410_ep_ops,                       .maxpacket       = EP_FIFO_SIZE,              },           .dev             = &memory,               .fifo_size       = EP_FIFO_SIZE,              .bEndpointAddress = 4,               .bmAttributes    = USB_ENDPOINT_XFER_BULK,    }};

usb_add_function .

为configuration 添加一个或一个以上的functions,   添加过程条用@bind 函数.

比如下面添加下面的adb

static int adb_bind_config(struct usb_configuration *c){	struct adb_dev *dev = _adb_dev;	printk(KERN_INFO "adb_bind_config\n");	dev->cdev = c->cdev;	dev->function.name = "adb";	dev->function.descriptors = fs_adb_descs;	dev->function.hs_descriptors = hs_adb_descs;	dev->function.bind = adb_function_bind;	dev->function.unbind = adb_function_unbind;	dev->function.set_alt = adb_function_set_alt;	dev->function.disable = adb_function_disable;	return usb_add_function(c, &dev->function);}

这里dev->function.bind = adb_function_bind;    把bind函数的进行了赋值

下面在调用

usb_add_function

这个函数时会调用这个bind函数 ,不信往下看

/** * usb_add_function() - add a function to a configuration * @config: the configuration * @function: the function being added * Context: single threaded during gadget setup * * After initialization, each configuration must have one or more * functions added to it.  Adding a function involves calling its @bind() * method to allocate resources such as interface and string identifiers * and endpoints. * * This function returns the value of the function's bind(), which is * zero for success else a negative errno value. */int usb_add_function(struct usb_configuration *config,		struct usb_function *function){	int	value = -EINVAL;	DBG(config->cdev, "adding '%s'/%p to config '%s'/%p\n",			function->name, function,			config->label, config);	if (!function->set_alt || !function->disable)		goto done;	function->config = config;	list_add_tail(&function->list, &config->functions);	/* REVISIT *require* function->bind? */
/*这里就在调用bind  函数就行configuration和  usb_function的绑定*/
if (function->bind) {		value = function->bind(config, function);  //调用开始		if (value < 0) {			list_del(&function->list);			function->config = NULL;		}	} else		value = 0;	/* We allow configurations that don't work at both speeds.	 * If we run into a lowspeed Linux system, treat it the same	 * as full speed ... it's the function drivers that will need	 * to avoid bulk and ISO transfers.	 */	if (!config->fullspeed && function->descriptors)		config->fullspeed = true;	if (!config->highspeed && function->hs_descriptors)		config->highspeed = true;	if (!config->superspeed && function->ss_descriptors)		config->superspeed = true;done:	if (value)		DBG(config->cdev, "adding '%s'/%p --> %d\n",				function->name, function, value);	return value;}

看上面的这部分代码,.  就是调用了dev->function.bind = adb_function_bind; 这个函数进行functions 和configuration的绑定.

 

 

再看下 usb_function . 

 

那这个 usb_function   是什么作用呢?

看下面的介绍

/**

 * struct usb_function - describes one function of a configuration
 * @name: For diagnostics, identifies the function.
 * @strings: tables of strings, keyed by identifiers assigned during bind()
 * and by language IDs provided in control requests
 * @descriptors: Table of full (or low) speed descriptors, using interface and
 * string identifiers assigned during @bind().  If this pointer is null,
 * the function will not be available at full speed (or at low speed).
 * @hs_descriptors: Table of high speed descriptors, using interface and
 * string identifiers assigned during @bind().  If this pointer is null,
 * the function will not be available at high speed.
 * @ss_descriptors: Table of super speed descriptors, using interface and
 * string identifiers assigned during @bind(). If this
 * pointer is null after initiation, the function will not
 * be available at super speed.
 * @config: assigned when @usb_add_function() is called; this is the
 * configuration with which this function is associated.
 * @bind: Before the gadget can register, all of its functions bind() to the
 * available resources including string and interface identifiers used
 * in interface or class descriptors; endpoints; I/O buffers; and so on.
 * @unbind: Reverses @bind; called as a side effect of unregistering the
 * driver which added this function.
 * @set_alt: (REQUIRED) Reconfigures altsettings; function drivers may
 * initialize usb_ep.driver data at this time (when it is used).
 * Note that setting an interface to its current altsetting resets
 * interface state, and that all interfaces have a disabled state.
 * @get_alt: Returns the active altsetting.  If this is not provided,
 * then only altsetting zero is supported.
 * @disable: (REQUIRED) Indicates the function should be disabled.  Reasons
 * include host resetting or reconfiguring the gadget, and disconnection.
 * @setup: Used for interface-specific control requests.
 * @suspend: Notifies functions when the host stops sending USB traffic.
 * @resume: Notifies functions when the host restarts USB traffic.
 * @get_status: Returns function status as a reply to
 * GetStatus() request when the recepient is Interface.
 * @func_suspend: callback to be called when
 * SetFeature(FUNCTION_SUSPEND) is reseived
 *
 * A single USB function uses one or more interfaces, and should in most
 * cases support operation at both full and high speeds.  Each function is
 * associated by @usb_add_function() with a one configuration; that function
 * causes @bind() to be called so resources can be allocated as part of
 * setting up a gadget driver.  Those resources include endpoints, which
 * should be allocated using @usb_ep_autoconfig().
 *
 * To support dual speed operation, a function driver provides descriptors
 * for both high and full speed operation.  Except in rare cases that don't
 * involve bulk endpoints, each speed needs different endpoint descriptors.
 *
 * Function drivers choose their own strategies for managing instance data.
 * The simplest strategy just declares it "static', which means the function
 * can only be activated once.  If the function needs to be exposed in more
 * than one configuration at a given speed, it needs to support multiple
 * usb_function structures (one for each configuration).
 *
 * A more complex strategy might encapsulate a @usb_function structure inside
 * a driver-specific instance structure to allows multiple activations.  An
 * example of multiple activations might be a CDC ACM function that supports
 * two or more distinct instances within the same configuration, providing
 * several independent logical data links to a USB host.
 */

转载于:https://www.cnblogs.com/yuzaipiaofei/archive/2013/01/21/4124135.html

你可能感兴趣的文章
面试题解 | 创建最大数
查看>>
蚂蚁金服SOFAMesh在多语言上的实践 | CNUTCon 实录
查看>>
读Zepto源码之Fx模块
查看>>
蚂蚁双11的这群筑梦师
查看>>
彻底搞懂HTTPS的加密机制
查看>>
使用jstack确认saiku报表刷新缓存无法访问问题
查看>>
2018,一个转行程序员的成长 | 掘金年度征文
查看>>
[Android]后端之路--整合SSM(Spring+SpringMVC+MyBatis)框架(2)
查看>>
深入理解虚拟机之类文件结构
查看>>
深入Spring Boot--使用Arthas排查应用404/401问题
查看>>
从路由原理出发,深入阅读理解react-router 4.0的源码
查看>>
0707 - iTips v0.0.1
查看>>
ConstraintLayout 属性详解 和Chain的使用
查看>>
java基础(三) 加强型for循环与Iterator
查看>>
ReactNaive之CSS和Flex布局
查看>>
ES6-import 和 export
查看>>
[Day 2] 听说你没来 JSConf 2017?
查看>>
JavaScript实现背景颜色随时间变化
查看>>
Spring第四篇【Intellij idea环境下、Struts2和Spring整合】
查看>>
前端面试 | 掘金技术征文
查看>>