Chinaunix首页 | 论坛 | 博客
  • 博客访问: 561051
  • 博文数量: 105
  • 博客积分: 3274
  • 博客等级: 中校
  • 技术积分: 1161
  • 用 户 组: 普通用户
  • 注册时间: 2010-02-21 12:14
文章分类

全部博文(105)

文章存档

2011年(1)

2010年(104)

分类: LINUX

2010-09-06 21:16:42

/**

 * struct usb_request - describes one i/o request

 * @buf: Buffer used for data.  Always provide this; some controllers

 *    only use PIO, or don't use DMA for some endpoints.数据缓存区

 * @dma: DMA address corresponding to 'buf'.  If you don't set this

 *    field, and the usb controller needs one, it is responsible

 *    for mapping and unmapping the buffer.缓存区的DMA地址,如果不设置这个字段,USB控制器又需要,它就负责映射和去掉映射缓存

 * @length: Length of that data数据长度

 * @no_interrupt: If true, hints that no completion irq is needed.

 *    Helpful sometimes with deep request queues that are handled

 *    directly by DMA controllers.如果设置为true,就不需要完成后的中断提示。

 * @zero: If true, when writing data, makes the last packet be "short"

 *     by adding a zero length packet as needed;如果为true,当写数据时,如果需要,则通过增加一个0长度的包使最后一包数据为“短”包

 * @short_not_ok: When reading data, makes short packets be

 *     treated as errors (queue stops advancing till cleanup).读数据时,使短包被认为是错误的

 * @complete: Function called when request completes, so this request and

 *    its buffer may be re-used.  The function will always be called with

 *    interrupts disabled, and it must not sleep.

 *    Reads terminate with a short packet, or when the buffer fills,

 *    whichever comes first.  When writes terminate, some data bytes

 *    will usually still be in flight (often in a hardware fifo).

 *    Errors (for reads or writes) stop the queue from advancing

 *    until the completion function returns, so that any transfers

 *    invalidated by the error may first be dequeued.当请求完成后调用的函数。因此这个请求和它的buffer可能会被重复使用。这个函数会在中断被关闭时调用,因此它不能睡眠。读终止时是一个短包或者当buffer被填充,将会首先调用它。当写终止,一些数据字节通常仍然没固定下来(比如在硬件缓存区)。错误(读或写时)会停止队列的遍历前行直到完成函数返回后,因此读写错误产生的无效传输将会首先被清除出队列

 * @context: For use by the completion callback完成函数回调时会使用到

 * @list: For use by the gadget driver.gadget驱动使用

 * @status: Reports completion code, zero or a negative errno.报告完成函数的返回状态

 *    Normally, faults block the transfer queue from advancing until正常情况下,错误会阻塞传输队列遍历前行直到完成函数返回

 *    the completion callback returns.

 *    Code indicates completion caused by device disconnect,代码"-ESHUTDOWN"标志着完成函数是被设备断开或者驱动停止了端点

 *    or when the driver disabled the endpoint.

 * @actual: Reports bytes transferred to/from the buffer.  For reads (OUT

 *    transfers) this may be less than the requested length.  If the

 *    short_not_ok flag is set, short reads are treated as errors

 *    even when status otherwise indicates successful completion.

 *    Note that for writes (IN transfers) some data bytes may still

 *    reside in a device-side FIFO when the request is reported as

 *    complete. 报告buffer读写字节数。读(OUT 传输)的时候这个数可能会小于请求的长度。如果设置了short_not_ok标记,短包的读就被认为是错误,即使完成函数返回成功。注意写(IN 传输)一些数据字节时,即使请求被报告为完成,数据仍可能还在从机设备端的fifo里。

 *

 * These are allocated/freed through the endpoint they're used with.  The

 * hardware's driver can add extra per-request data to the memory it returns,

 * which often avoids separate memory allocations (potential failures),

 * later when the request is queued.

 *

 * Request flags affect request handling, such as whether a zero length

 * packet is written (the "zero" flag), whether a short read should be

 * treated as an error (blocking request queue advance, the "short_not_ok"

 * flag), or hinting that an interrupt is not required (the "no_interrupt"

 * flag, for use with deep request queues).

 *

 * Bulk endpoints can use any size buffers, and can also be used for interrupt

 * transfers. interrupt-only endpoints can be much less functional.

 *

 * NOTE:  this is analagous to 'struct urb' on the host side, except that

 * it's thinner and promotes more pre-allocation.

 */

 

struct usb_request {

       void               *buf;

       unsigned         length;

       dma_addr_t           dma;

 

       unsigned         no_interrupt:1;

       unsigned         zero:1;

       unsigned         short_not_ok:1;

 

       void               (*complete)(struct usb_ep *ep,

                                   struct usb_request *req);

       void               *context;

       struct list_head       list;

 

       int                 status;

       unsigned         actual;

};

 

/*-------------------------------------------------------------------------*/

 

/* endpoint-specific parts of the api to the usb controller hardware.

 * unlike the urb model, (de)multiplexing layers are not required.

 * (so this api could slash overhead if used on the host side...)

 *

 * note that device side usb controllers commonly differ in how many

 * endpoints they support, as well as their capabilities.

 */

USB控制器打交道的具体端点部分的API。与urb模型不一样的是,复合层是不需要的(因此,如果在主机端使用,这个API能够降低开销。)

注意设备端usb控制器支持的端点数通常不一样,以及它们的容积能力。

struct usb_ep_ops {

       int (*enable) (struct usb_ep *ep,

              const struct usb_endpoint_descriptor *desc);

       int (*disable) (struct usb_ep *ep);

 

       struct usb_request *(*alloc_request) (struct usb_ep *ep,

              gfp_t gfp_flags);

       void (*free_request) (struct usb_ep *ep, struct usb_request *req);

 

       int (*queue) (struct usb_ep *ep, struct usb_request *req,

              gfp_t gfp_flags);

       int (*dequeue) (struct usb_ep *ep, struct usb_request *req);

 

       int (*set_halt) (struct usb_ep *ep, int value);

       int (*set_wedge) (struct usb_ep *ep);

 

       int (*fifo_status) (struct usb_ep *ep);

       void (*fifo_flush) (struct usb_ep *ep);

};

 

/**

 * struct usb_ep - device side representation of USB endpoint设备端的USB端点

 * @name:identifier for the endpoint, such as "ep-a" or "ep9in-bulk"端点标志

 * @ops: Function pointers used to access hardware-specific operations.端点文件操作结构体

 * @ep_list:the gadget's ep_list holds all of its endpoints gadget端驱动端点链表

 * @maxpacket:The maximum packet size used on this endpoint.  The initial

 *    value can sometimes be reduced (hardware allowing), according to

 *      the endpoint descriptor used to configure the endpoint. 该端点的最大包大小。初始值有时可以被减少(硬件允许的情况下),通过配置端点的端点描述符。

 * @driver_data:for use by the gadget driver.  all other fields are

 *    read-only to gadget drivers.gadget驱动使用,所有其他的字段对gadget drivers都是只读的。

 *

 * the bus controller driver lists all the general purpose endpoints in

 * gadget->ep_list.  the control endpoint (gadget->ep0) is not in that list,

 * and is accessed only in response to a driver setup() callback.

 */总线控制器驱动在gadget->ep_list列出了所有的通用端点,控制端点(gadget->ep0)不在列表中,它仅在setup回调函数中反馈使用。

struct usb_ep {

       void               *driver_data;

 

       const char              *name;

       const struct usb_ep_ops  *ops;

       struct list_head       ep_list;

       unsigned         maxpacket:16;

};

 

/*-------------------------------------------------------------------------*/

 

/**

 * usb_ep_enable - configure endpoint, making it usable配置端点,使之可以使用

 * @ep:the endpoint being configured.  may not be the endpoint named .

 *    drivers discover endpoints through the ep_list of a usb_gadget.配置端点。不一定就是名字叫做"ep0"的端点。驱动通过usb_gadgetep_list来发现端点

 * @desc:descriptor for desired behavior.  caller guarantees this pointer

 *    remains valid until the endpoint is disabled; the data byte order

 *    is little-endian (usb-standard).端点描述符。调用者保证这个指针是有效的直到端点被禁止

 *

 * when configurations are set, or when interface settings change, the driver

 * will enable or disable the relevant endpoints.  while it is enabled, an

 * endpoint may be used for i/o until the driver receives a disconnect() from

 * the host or until the endpoint is disabled.当配置被设置,或者接口设置改变,驱动都需要使能或停止相关端点。当它使能时,一个端点也许会仍然被IO使用直到驱动从host接收到disconnect()或者端点被禁止

 *

 * the ep0 implementation (which calls this routine) must ensure that the

 * hardware capabilities of each endpoint match the descriptor provided

 * for it.  for example, an endpoint named2in-bulk" would be usable

 * for interrupt transfers as well as bulk, but it likely couldn't be used

 * for iso transfers or for endpoint 14.  some endpoints are fully

 * configurable, with more generic names like.  (remember that for

 * USB, "in" means "towards the USB master".)

 *ep0执行(谁调用这个例程)必须保证硬件每个端点的能力与描述符提供的匹配。举例来说,一个叫做"ep2in-bulk"的端点会在中断传输以及批量传输时很有用,但是它很可能不能被用到iso传输或者端点14.有些端点是全配置的,会有一些诸如"ep-a"通用的名字

 * returns zero, or a negative error code.

 */

static inline int usb_ep_enable(struct usb_ep *ep,

                            const struct usb_endpoint_descriptor *desc)

{

       return ep->ops->enable(ep, desc);

}

/**

 * usb_ep_disable - endpoint is no longer usable端点不能再被使用

 * @ep:the endpoint being unconfigured.  may not be the endpoint named "ep0".

 *端点配置取消,该端点不一定叫做"ep0"

 * no other task may be using this endpoint when this is called.

 * any pending and uncompleted requests will complete with status

 * indicating disconnect (-ESHUTDOWN) before this call returns.

 * gadget drivers must call usb_ep_enable() again before queueing

 * requests to the endpoint.

 *当调用这个函数后,别的任务就不能再使用这个端点了。任何其他刮起或未完成的请求结束时都会返回未连接(-ESHUTDOWN).gadget驱动要想再把这个端点加入请求队列必须调用usb_ep_enable()

 * returns zero, or a negative error code.

 */

static inline int usb_ep_disable(struct usb_ep *ep)

{

       return ep->ops->disable(ep);

}

/**

 * usb_ep_alloc_request - allocate a request object to use with this endpoint请求用于该端点的对象分配

 * @ep:the endpoint to be used with with the request用于该请求的端点

 * @gfp_flags:GFP_* flags to use内存申请标记

 *

 * Request objects must be allocated with this call, since they normally

 * need controller-specific setup and may even need endpoint-specific

 * resources such as allocation of DMA descriptors.请求对象必须调用这个函数来被分配资源,它们通常需要控制器setup时的具体信息,甚至于端点的具体资源,比如DMA描述符的分配等。

 * Requests may be submitted with , and receive a single

 * completion callback.  Free requests with , when

 * they are no longer needed.请求可能会通过usb_ep_queue()被提交,并接收到一个完成函数的回调。当不再需要使用这些资源是,可以通过usb_ep_free_request()释放请求。

 *

 * Returns the request, or null if one could not be allocated.

 */

static inline struct usb_request *usb_ep_alloc_request(struct usb_ep *ep,

                                                 gfp_t gfp_flags)

{

       return ep->ops->alloc_request(ep, gfp_flags);

}

 

/**

 * usb_ep_free_request - frees a request object释放请求对象

 * @ep:the endpoint associated with the request

 * @req:the request being freed需要释放的请求

 *

 * Reverses the effect of .usb_ep_alloc_request()的影响相反

 * Caller guarantees the request is not queued, and that it will

 * no longer be requeued (or otherwise used).调用这个函数保证请求不在队列中,并且它不会再被使用。

 */

static inline void usb_ep_free_request(struct usb_ep *ep,

                                   struct usb_request *req)

{

       ep->ops->free_request(ep, req);

}

 

/**

 * usb_ep_queue - queues (submits) an I/O request to an endpoint.向端点提交一个IO请求

 * @ep:the endpoint associated with the request用于分配该请求的端点

 * @req:the request being submitted提交的请求

 * @gfp_flags: GFP_* flags to use in case the lower level driver couldn't

 *    pre-allocate all necessary memory with the request.

 *

 * This tells the device controller to perform the specified request through

 * that endpoint (reading or writing a buffer).  When the request completes,

 * including being canceled by the request's completion

 * routine is called to return the request to the driver.  Any endpoint

 * (except control endpoints like ep0) may have more than one transfer

 * request queued; they complete in FIFO order.  Once a gadget driver

 * submits a request, that request may not be examined or modified until it

 * is given back to that driver through the completion callback.这告诉设备控制器来通过端点执行指定的请求(读或者写缓存)。当请求完成后,包括调用usb_ep_dequeue()的请求退出,请求完成函数会被调用并返回这个请求给驱动。任何端点(控制端点例如ep0除外)可能会不止一个传输请求;这些请求会按照FIFO的顺序完成。一旦一个gadget驱动提交了一个请求,这个请求不一定会被检查或修改直到它通过完成函数回调被返回给驱动。

 *

 * Each request is turned into one or more packets.  The controller driver

 * never merges adjacent requests into the same packet.  OUT transfers

 * will sometimes use data that's already buffered in the hardware.

 * Drivers can rely on the fact that the first byte of the request's buffer

 * always corresponds to the first byte of some USB packet, for both

 * IN and OUT transfers.每个请求会被放入一个或多个包中。控制器驱动从来不会把邻近的请求合并到相同的包中。OUT传输有时会使用硬件中已经存在的缓存。驱动可以依赖的一个事实是,对于INOUT传输而言,请求的缓存的第一个字节总是对应于一些USB包的第一个字节。

 *

 * Bulk endpoints can queue any amount of data; the transfer is packetized

 * automatically.  The last packet will be short if the request doesn't fill it

 * out completely.  Zero length packets (ZLPs) should be avoided in portable

 * protocols since not all usb hardware can successfully handle zero length

 * packets.  (ZLPs may be explicitly written, and may be implicitly written if

 * the request 'zero' flag is set.)  Bulk endpoints may also be used

 * for interrupt transfers; but the reverse is not true, and some endpoints

 * won't support every interrupt transfer.  (Such as 768 byte packets.)

 *批量端点可以传输任意数量的队列,传输的数据被自动打包。如果请求没有填充完全,最后一包的数据会被截短。零长度包应该在协议中被避免,因为不是所有的USB硬件都能处理零长度的包。(如果请求zero标记flag被设置,ZLIPS可以被直接或间接的发送)。批量端点也可用于中断传输中,但是反过来就不行,并且一些端点并不支持每一个中断传输。(比如768字节的包)

 * Interrupt-only endpoints are less functional than bulk endpoints, for

 * example by not supporting queueing or not handling buffers that are

 * larger than the endpoint's maxpacket size.  They may also treat data

 * toggle differently.只能中断的端点的功能就没有批量传输端点的多了。比如不支持队列以及不能处理比端点最大包长度大的缓存。它们也可以切换不同的数据。

 *

 * Control endpoints ... after getting a setup() callback, the driver queues

 * one response (even if it would be zero length).  That enables the

 * status ack, after transfering data as specified in the response.  Setup

 * functions may return negative error codes to generate protocol stalls.

 * (Note that some USB device controllers disallow protocol stall responses

 * in some cases.)  When control responses are deferred (the response is

 * written after the setup callback returns), then usb_ep_set_halt() may be

 * used on ep0 to trigger protocol stalls.  Depending on the controller,

 * it may not be possible to trigger a status-stage protocol stall when the

 * data stage is over, that is, from within the response's completion

 * routine.控制端点,当得到setup()的回调后,驱动往队列里添加一个反馈(甚至于它是0长度)。传输了指定的反馈数据后,状态就使能了。Setup函数也会反馈负的错误代码来停止协议协议。(注意有些USB设备控制器在某些情况下不允许反馈STALL。)当控制反馈延迟时(反馈在setup回调返回后才发送),usb_ep_set_halt()可能会使用在ep0上来触发协议停止。受制于控制器,当反馈的完成函数回调的数据阶段完成后,它可能不会触发一个协议停止的状态。

 *

 * For periodic endpoints, like interrupt or isochronous ones, the usb host

 * arranges to poll once per interval, and the gadget driver usually will

 * have queued some data to transfer at that time.

 *对于周期性的端点来说,如中断和等时传输,USB主机会每隔一定周期就轮询一次,gadget驱动就在这个时候把相关的数据传输加入到队列。

 * Returns zero, or a negative error code.  Endpoints that are not enabled

 * report errors; errors will also be

 * reported when the usb peripheral is disconnected.

 */

static inline int usb_ep_queue(struct usb_ep *ep,

                            struct usb_request *req, gfp_t gfp_flags)

{

       return ep->ops->queue(ep, req, gfp_flags);

}

 

/**

 * usb_ep_dequeue - dequeues (cancels, unlinks) an I/O request from an endpoint

 * @ep:the endpoint associated with the request

 * @req:the request being canceled

 *

 * if the request is still active on the endpoint, it is dequeued and its

 * completion routine is called (with status -ECONNRESET); else a negative

 * error code is returned.如果请求的端点仍然有效,它就会把端点从队列中除去,并且它的完成函数会被调用,否则一个负的错误代码会被返回。

 *

 * note that some hardware can't clear out write fifos (to unlink the request

 * at the head of the queue) except as part of disconnecting from usb.  such

 * restrictions prevent drivers from supporting configuration changes,

 * even to configuration zero (a "chapter 9" requirement).

 */注意一些硬件不能清除掉写fifos除非直接从usb断开。这些限制会阻止驱动支持多配置,甚至于配置为0.

static inline int usb_ep_dequeue(struct usb_ep *ep, struct usb_request *req)

{

       return ep->ops->dequeue(ep, req);

}

/**

 * usb_ep_set_halt - sets the endpoint halt feature. 设置端点为停止状态

 * @ep: the non-isochronous endpoint being stalled需要被停止的非等时传输的端点

 *

 * Use this to stall an endpoint, perhaps as an error report.

 * Except for control endpoints,

 * the endpoint stays halted (will not stream any data) until the host

 * clears this feature; drivers may need to empty the endpoint's request

 * queue first, to make sure no inappropriate transfers happen.使用它来停止一个端点,或许被认为是一个错误报告,除了控制端点之外,端点会保持在停止状态(无任何数据流)直到主机清除这个状态。驱动可能首先需要清空这个端点的请求队列,来保证没有不合适的传输发生。

 *

 * Note that while an endpoint CLEAR_FEATURE will be invisible to the

 * gadget driver, a SET_INTERFACE will not be.  To reset endpoints for the

 * current altsetting, see usb_ep_clear_halt().  When switching altsettings,

 * it's simplest to use usb_ep_enable() or usb_ep_disable() for the endpoints.

 *注意一个端点CLEAR_FEATURE对于gadget驱动来说是不可见的,但是SET_INTERFACE不一样。为了使用当前的设置来复位端点,需要使用usb_ep_clear_halt()。对于端点来说,当切换不同的设置时,最简单的方法是使用use usb_ep_enable()usb_ep_disable()

 * Returns zero, or a negative error code.  On success, this call sets

 * underlying hardware state that blocks data transfers.

 * Attempts to halt IN endpoints will fail (returning -EAGAIN) if any

 * transfer requests are still queued, or if the controller hardware

 * (usually a FIFO) still holds bytes that the host hasn't collected.

 */返回0或者负的错误代码值。一旦成功,这个函数会调用底层的硬件状态来阻止数据传输。如果有任何传输请求仍在队列中,或者控制器硬件(通常是fifo)仍然保留着主机还没有收集好的数据,那么尝试停止IN端点就会失败。

static inline int usb_ep_set_halt(struct usb_ep *ep)

{

       return ep->ops->set_halt(ep, 1);

}

 

/**

 * usb_ep_clear_halt - clears endpoint halt, and resets toggle清除端点停止状态,并复位触发

 * @ep:the bulk or interrupt endpoint being reset要复位的批量或中断端点

 *

 * Use this when responding to the standard usb "set interface" request,

 * for endpoints that aren't reconfigured, after clearing any other state

 * in the endpoint's i/o queue.当反馈标准的usb "set interface"请求是需要用到这个函数。对于端点来说,在清除掉端点IO队列的其他状态之后,它们不需要重新配置。

 *

 * Returns zero, or a negative error code.  On success, this call clears

 * the underlying hardware state reflecting endpoint halt and data toggle.

 * Note that some hardware can't support this request (like pxa2xx_udc),

 * and accordingly can't correctly implement interface altsettings.

 */返回0或者负的错去代码。一旦成功,就会清除掉底层硬件反映的端点停止和数据触发的状态。注意有些 不支持这种请求(pxa2xx_udc),并因此不能正确的使接口配置生效

static inline int usb_ep_clear_halt(struct usb_ep *ep)

{

       return ep->ops->set_halt(ep, 0);

}

 

/**

 * usb_ep_set_wedge - sets the halt feature and ignores clear requests设置为停止特征并且忽略清除的请求

 * @ep: the endpoint being wedged 被设置为wedged的端点

 *

 * Use this to stall an endpoint and ignore CLEAR_FEATURE(HALT_ENDPOINT)

 * requests. If the gadget driver clears the halt status, it will

 * automatically unwedge the endpoint.使用这个函数可以停止一个端点并且忽略掉CLEAR_FEATURE(HALT_ENDPOINT)请求。如果一个gadget驱动清除这个停止状态,它会自动 unwedge该端点。

 *

 * Returns zero on success, else negative errno.

 */

static inline int

usb_ep_set_wedge(struct usb_ep *ep)

{

       if (ep->ops->set_wedge)

              return ep->ops->set_wedge(ep);

       else

              return ep->ops->set_halt(ep, 1);

}

 

/**

 * usb_ep_fifo_status - returns number of bytes in fifo, or error返回fifo的字节数或者错误

 * @ep: the endpoint whose fifo status is being checked.正在被检查fifo状态的端点

 *

 * FIFO endpoints may have "unclaimed data" in them in certain cases,

 * such as after aborted transfers.  Hosts may not have collected all

 * the IN data written by the gadget driver (and reported by a request

 * completion).  The gadget driver may not have collected all the data

 * written OUT to it by the host.  Drivers that need precise handling for

 * fault reporting or recovery may need to use this call.fifo端点在某些情况下可能会存在一些"未知数据",比如当丢弃了传输之后。主机不会去收集所有gadget驱动(通过一个请求完成来报告)发送的IN数据,Gadget驱动也不会去收集所有从主机发送的OUT数据。驱动需要为这些错误报告做准确的处理或恢复。

 *

 * This returns the number of such bytes in the fifo, or a negative

 * errno if the endpoint doesn't use a FIFO or doesn't support such

 * precise handling.

 */

static inline int usb_ep_fifo_status(struct usb_ep *ep)

{

       if (ep->ops->fifo_status)

              return ep->ops->fifo_status(ep);

       else

              return -EOPNOTSUPP;

}

 

/**

 * usb_ep_fifo_flush - flushes contents of a fifo更新fifo的内容

 * @ep: the endpoint whose fifo is being flushed.需要更新fifo的端点

 *

 * This call may be used to flush the "unclaimed data" that may exist in

 * an endpoint fifo after abnormal transaction terminations.  The call

 * must never be used except when endpoint is not being used for any

 * protocol translation.这个函数可以被用来更新放弃传输后,存在在端点fifo的未知数据。必须在端点没有任何协议传输时才能调用这个函数。

 */

static inline void usb_ep_fifo_flush(struct usb_ep *ep)

{

       if (ep->ops->fifo_flush)

              ep->ops->fifo_flush(ep);

}

 

 

阅读(2567) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-09-08 10:01:19

Download More than 1000 free IT eBooks: http://free-ebooks.appspot.com