⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbs.h

📁 eCos操作系统源码
💻 H
📖 第 1 页 / 共 2 页
字号:
    // functions. However in simple devices those device-specific    // state change functions could be invoked directly.    void                (*state_change_fn)(struct usbs_control_endpoint*, void*, usbs_state_change, int /* old state */);    void*               state_change_data;    // When a standard control message arrives, the device driver will    // detect some requests such as SET_ADDRESS and handle it    // internally. Otherwise if higher-level code has installed a    // callback then that will be invoked. If the callback returns    // UNKNOWN then the default handler usbs_handle_standard_control()    // is used to process the request.     usbs_control_return (*standard_control_fn)(struct usbs_control_endpoint*, void*);    void*               standard_control_data;        // These three callbacks are used for other types of control    // messages. The generic USB code has no way of knowing what    // such control messages are about.    usbs_control_return (*class_control_fn)(struct usbs_control_endpoint*, void*);    void*               class_control_data;    usbs_control_return (*vendor_control_fn)(struct usbs_control_endpoint*, void*);    void*               vendor_control_data;    usbs_control_return (*reserved_control_fn)(struct usbs_control_endpoint*, void*);    void*               reserved_control_data;    // If a control operation involves transferring more data than    // just the initial eight-byte packet, the following fields are    // used to keep track of the current operation. The original    // control request indicates the direction of the transfer (IN or    // OUT) and a length field. For OUT this length is exact, for IN    // it is an upper bound. The transfer operates mostly as per the    // bulk protocol, but if the length requested is an exact multiple    // of the control fifo size (typically eight bytes) then there    // is no need for an empty packet at the end.    //    // For an OUT operation the control message handler should supply    // a suitable buffer via the "buffer" field below. The only other    // field of interest is the complete_fn which must be provided and    // will be invoked once all the data has arrived. Alternatively    // the OUT operation may get aborted if a new control message    // arrives. The second argument is an error code -EPIPE or -EIO,    // or zero to indicate success. The return code is used by the    // device driver during the status phase.    //    // IN is more complicated and the defined interface makes it    // possible to gather data from multiple locations, eliminating    // the need for copying into large buffers in some circumstances.    // Basically when an IN request arrives the device driver will    // look at the buffer and buffer_size fields, extracting data from    // there if possible. If the current buffer has been exhausted    // then the the refill function will be invoked, and this can    // reset the buffer and size fields to point somewhere else.     // This continues until such time that there is no longer    // a refill function and the current buffer is empty. The    // refill function can use the refill_data and refill_index    // to keep track of the current state. The control_buffer    // fields are available as well. At the end of the transfer,    // if a completion function has been supplied then it will    // be invoked. The return code will be ignored.    unsigned char*      buffer;    int                 buffer_size;    void                (*fill_buffer_fn)(struct usbs_control_endpoint*);    void*               fill_data;    int                 fill_index;    usbs_control_return (*complete_fn)(struct usbs_control_endpoint*, int);} usbs_control_endpoint;// Data endpoints are a little bit simpler, but not much. From the// perspective of a device driver things a single buffer is most// convenient, but that is quite likely to require a max-size buffer// at a higher level and an additional copy operation. Supplying// a vector of buffers is a bit more general, but in a layered// system it may be desirable to prepend to this vector...// A combination of a current buffer and a refill/empty function// offers flexibility, at the cost of additional function calls// from inside the device driver.//// FIXME: implement support for fill/empty functions.//// Some USB devices may prefer buffers of particular alignment,// e.g. for DMA purposes. This is hard to reconcile with the// current interface. However pushing such alignment restrictions// etc. up into the higher levels is difficult, e.g. it does// not map at all onto a conventional read/write interface.// The device driver will just have to do the best it can.//// The completion function will be invoked at the end of the transfer.// The second argument indicates per-transfer completion data. The// third argument indicates the total amount received, or an error// code: typically -EPIPE to indicate a broken conenction; -EAGAIN to// indicate a stall condition; -EMSGSIZE if the host is sending more// data than the target is expecting; or -EIO to indicate some other// error. Individual device drivers should avoid generating other// errors.typedef struct usbs_rx_endpoint {    void                (*start_rx_fn)(struct usbs_rx_endpoint*);    void                (*set_halted_fn)(struct usbs_rx_endpoint*, cyg_bool);    void                (*complete_fn)(void*, int);    void*               complete_data;    unsigned char*      buffer;    int                 buffer_size;    cyg_bool            halted;} usbs_rx_endpoint;typedef struct usbs_tx_endpoint {    void                (*start_tx_fn)(struct usbs_tx_endpoint*);    void                (*set_halted_fn)(struct usbs_tx_endpoint*, cyg_bool);    void                (*complete_fn)(void*, int);    void*               complete_data;    const unsigned char*buffer;    int                 buffer_size;    cyg_bool            halted;} usbs_tx_endpoint;// Functions called by device drivers.extern usbs_control_return usbs_handle_standard_control(struct usbs_control_endpoint*);    // Utility functions. These just invoke the corresponding function// pointers in the endpoint structures. It is assumed that the// necessary fields in the endpoint structures will have been// filled in already.extern void     usbs_start(usbs_control_endpoint*);extern void     usbs_start_rx(usbs_rx_endpoint*);extern void     usbs_start_tx(usbs_tx_endpoint*);extern void     usbs_start_rx_buffer(usbs_rx_endpoint*, unsigned char*, int, void (*)(void*, int), void*);extern void     usbs_start_tx_buffer(usbs_tx_endpoint*, const unsigned char*, int, void (*)(void*, int), void*);extern cyg_bool usbs_rx_endpoint_halted(usbs_rx_endpoint*);extern cyg_bool usbs_tx_endpoint_halted(usbs_tx_endpoint*);extern void     usbs_set_rx_endpoint_halted(usbs_rx_endpoint*, cyg_bool);extern void     usbs_set_tx_endpoint_halted(usbs_tx_endpoint*, cyg_bool);extern void     usbs_start_rx_endpoint_wait(usbs_rx_endpoint*, void (*)(void*, int), void*);extern void     usbs_start_tx_endpoint_wait(usbs_tx_endpoint*, void (*)(void*, int), void*);    // Functions that can go into devtab entries. These should not be// called directly, they are intended only for use by USB device// drivers.#if defined(CYGPKG_IO) && defined(CYGPKG_ERROR)#include <cyg/io/io.h>extern Cyg_ErrNo usbs_devtab_cwrite(cyg_io_handle_t, const void*, cyg_uint32*);extern Cyg_ErrNo usbs_devtab_cread(cyg_io_handle_t, void*, cyg_uint32*);extern Cyg_ErrNo usbs_devtab_get_config(cyg_io_handle_t, cyg_uint32, void*, cyg_uint32*);extern Cyg_ErrNo usbs_devtab_set_config(cyg_io_handle_t, cyg_uint32, const void*, cyg_uint32*);#endif// Additional support for testing.// Test cases need to have some way of finding out about what support is// actually provided by the USB device driver, for example what endpoints// are available. There is no perfect way of achieving this. One approach// would be to scan through the devtab table looking for devices of the// form /dev/usbs1r. That is not reliable: the devtab entries may have been// configured out if higher-level code uses the usb-specific API; or the// devtab entries may have been renamed. Also having a devtab entry does not// really give the kind of information a general-purpose testcase needs,// for example upper bounds on transfer size.    // // An alternative approach is to have a data structure that somehow// defines the USB hardware, and the USB device driver then creates an// instance of this. This is the approach actually taken. The problem// now is how the test code can access this instance. Accessing by// unique name is simple, as long as there is only one USB device in// the system (which of course will usually be the case on the USB// slave side). Alternative approaches such as creating a table at// link time or a list during static construction time are vulnerable// either to selective linking or to having these structures present// in applications other than the test cases. In future it might be// possible to address the latter issue by extending the build system// support, e.g. a new library libtesting.a and a new object file// testing.o.//// Note that a given endpoint could be used for bulk transfers some// of the time, then for isochronous transfers, etc. It is the// responsibility of the host to only perform one type of IN operation// for a given endpoint number, and ditto for OUT.    typedef struct usbs_testing_endpoint {    int         endpoint_type;          // One of ATTR_CONTROL, ATTR_BULK, ...    int         endpoint_number;        // Between 0 and 15    int         endpoint_direction;     // ENDPOINT_IN or ENDPOINT_OUT    void*       endpoint;               // pointer to the usbs_control_endpoint, usbs_rx_endpoint, ...    const char* devtab_entry;           // e.g. "/dev/usbs1r", or 0 if inaccessible via devtab    int         min_size;               // Minimum transfer size    int         max_size;               // -1 indicates no specific upper bound    int         max_in_padding;         // extra bytes that the target may send, usually 0.                                        // Primarily for SA11x0 hardware. It is assumed                                        // for now that no other hardware will exhibit                                        // comparable problems.    int         alignment;              // Buffer should be aligned to a suitable boundary} usbs_testing_endpoint;// A specific instance provided by the device driver. The end of// the table is indicated by a NULL endpoint field.    extern usbs_testing_endpoint usbs_testing_endpoints[];    #define USBS_TESTING_ENDPOINTS_TERMINATOR                           \    {                                                               \        endpoint_type       : USB_ENDPOINT_DESCRIPTOR_ATTR_CONTROL, \        endpoint_number     : 0,                                    \        endpoint_direction  : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,  \        endpoint            : (void*) 0,                            \        devtab_entry        : (const char*) 0,                      \        min_size            : 0,                                    \        max_size            : 0,                                    \        max_in_padding      : 0,                                    \        alignment           : 0                                     \    }#define USBS_TESTING_ENDPOINTS_IS_TERMINATOR(_endpoint_) ((void*)0 == (_endpoint_).endpoint)    #ifdef __cplusplus} // extern "C" {#endif#endif // CYGONCE_USBS_H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -