123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- /* ==========================================================================
- * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
- * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
- * otherwise expressly agreed to in writing between Synopsys and you.
- *
- * The Software IS NOT an item of Licensed Software or Licensed Product under
- * any End User Software License Agreement or Agreement for Licensed Product
- * with Synopsys or any supplement thereto. You are permitted to use and
- * redistribute this Software in source and binary forms, with or without
- * modification, provided that redistributions of source code must retain this
- * notice. You may not view, use, disclose, copy or distribute this file or
- * any information contained herein except pursuant to this license grant from
- * Synopsys. If you do not agree with this notice, including the disclaimer
- * below, then you are not authorized to use the Software.
- *
- * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- * ========================================================================== */
- #if !defined(__DWC_OTG_CFI_H__)
- #define __DWC_OTG_CFI_H__
- #include "dwc_otg_pcd.h"
- #include "dwc_cfi_common.h"
- /**
- * @file
- * This file contains the CFI related OTG PCD specific common constants,
- * interfaces(functions and macros) and data structures.The CFI Protocol is an
- * optional interface for internal testing purposes that a DUT may implement to
- * support testing of configurable features.
- *
- */
- struct dwc_otg_pcd;
- struct dwc_otg_pcd_ep;
- /** OTG CFI Features (properties) ID constants */
- /** This is a request for all Core Features */
- #define FT_ID_DMA_MODE 0x0001
- #define FT_ID_DMA_BUFFER_SETUP 0x0002
- #define FT_ID_DMA_BUFF_ALIGN 0x0003
- #define FT_ID_DMA_CONCAT_SETUP 0x0004
- #define FT_ID_DMA_CIRCULAR 0x0005
- #define FT_ID_THRESHOLD_SETUP 0x0006
- #define FT_ID_DFIFO_DEPTH 0x0007
- #define FT_ID_TX_FIFO_DEPTH 0x0008
- #define FT_ID_RX_FIFO_DEPTH 0x0009
- /**********************************************************/
- #define CFI_INFO_DEF
- #ifdef CFI_INFO_DEF
- #define CFI_INFO(fmt...) DWC_PRINTF("CFI: " fmt);
- #else
- #define CFI_INFO(fmt...)
- #endif
- #define min(x,y) ({ \
- x < y ? x : y; })
- #define max(x,y) ({ \
- x > y ? x : y; })
- /**
- * Descriptor DMA SG Buffer setup structure (SG buffer). This structure is
- * also used for setting up a buffer for Circular DDMA.
- */
- struct _ddma_sg_buffer_setup {
- #define BS_SG_VAL_DESC_LEN 6
- /* The OUT EP address */
- uint8_t bOutEndpointAddress;
- /* The IN EP address */
- uint8_t bInEndpointAddress;
- /* Number of bytes to put between transfer segments (must be DWORD boundaries) */
- uint8_t bOffset;
- /* The number of transfer segments (a DMA descriptors per each segment) */
- uint8_t bCount;
- /* Size (in byte) of each transfer segment */
- uint16_t wSize;
- } __attribute__ ((packed));
- typedef struct _ddma_sg_buffer_setup ddma_sg_buffer_setup_t;
- /** Descriptor DMA Concatenation Buffer setup structure */
- struct _ddma_concat_buffer_setup_hdr {
- #define BS_CONCAT_VAL_HDR_LEN 4
- /* The endpoint for which the buffer is to be set up */
- uint8_t bEndpointAddress;
- /* The count of descriptors to be used */
- uint8_t bDescCount;
- /* The total size of the transfer */
- uint16_t wSize;
- } __attribute__ ((packed));
- typedef struct _ddma_concat_buffer_setup_hdr ddma_concat_buffer_setup_hdr_t;
- /** Descriptor DMA Concatenation Buffer setup structure */
- struct _ddma_concat_buffer_setup {
- /* The SG header */
- ddma_concat_buffer_setup_hdr_t hdr;
- /* The XFER sizes pointer (allocated dynamically) */
- uint16_t *wTxBytes;
- } __attribute__ ((packed));
- typedef struct _ddma_concat_buffer_setup ddma_concat_buffer_setup_t;
- /** Descriptor DMA Alignment Buffer setup structure */
- struct _ddma_align_buffer_setup {
- #define BS_ALIGN_VAL_HDR_LEN 2
- uint8_t bEndpointAddress;
- uint8_t bAlign;
- } __attribute__ ((packed));
- typedef struct _ddma_align_buffer_setup ddma_align_buffer_setup_t;
- /** Transmit FIFO Size setup structure */
- struct _tx_fifo_size_setup {
- uint8_t bEndpointAddress;
- uint16_t wDepth;
- } __attribute__ ((packed));
- typedef struct _tx_fifo_size_setup tx_fifo_size_setup_t;
- /** Transmit FIFO Size setup structure */
- struct _rx_fifo_size_setup {
- uint16_t wDepth;
- } __attribute__ ((packed));
- typedef struct _rx_fifo_size_setup rx_fifo_size_setup_t;
- /**
- * struct cfi_usb_ctrlrequest - the CFI implementation of the struct usb_ctrlrequest
- * This structure encapsulates the standard usb_ctrlrequest and adds a pointer
- * to the data returned in the data stage of a 3-stage Control Write requests.
- */
- struct cfi_usb_ctrlrequest {
- uint8_t bRequestType;
- uint8_t bRequest;
- uint16_t wValue;
- uint16_t wIndex;
- uint16_t wLength;
- uint8_t *data;
- } UPACKED;
- /*---------------------------------------------------------------------------*/
- /**
- * The CFI wrapper of the enabled and activated dwc_otg_pcd_ep structures.
- * This structure is used to store the buffer setup data for any
- * enabled endpoint in the PCD.
- */
- struct cfi_ep {
- /* Entry for the list container */
- dwc_list_link_t lh;
- /* Pointer to the active PCD endpoint structure */
- struct dwc_otg_pcd_ep *ep;
- /* The last descriptor in the chain of DMA descriptors of the endpoint */
- struct dwc_otg_dma_desc *dma_desc_last;
- /* The SG feature value */
- ddma_sg_buffer_setup_t *bm_sg;
- /* The Circular feature value */
- ddma_sg_buffer_setup_t *bm_circ;
- /* The Concatenation feature value */
- ddma_concat_buffer_setup_t *bm_concat;
- /* The Alignment feature value */
- ddma_align_buffer_setup_t *bm_align;
- /* XFER length */
- uint32_t xfer_len;
- /*
- * Count of DMA descriptors currently used.
- * The total should not exceed the MAX_DMA_DESCS_PER_EP value
- * defined in the dwc_otg_cil.h
- */
- uint32_t desc_count;
- };
- typedef struct cfi_ep cfi_ep_t;
- typedef struct cfi_dma_buff {
- #define CFI_IN_BUF_LEN 1024
- #define CFI_OUT_BUF_LEN 1024
- dma_addr_t addr;
- uint8_t *buf;
- } cfi_dma_buff_t;
- struct cfiobject;
- /**
- * This is the interface for the CFI operations.
- *
- * @param ep_enable Called when any endpoint is enabled and activated.
- * @param release Called when the CFI object is released and it needs to correctly
- * deallocate the dynamic memory
- * @param ctrl_write_complete Called when the data stage of the request is complete
- */
- typedef struct cfi_ops {
- int (*ep_enable) (struct cfiobject * cfi, struct dwc_otg_pcd * pcd,
- struct dwc_otg_pcd_ep * ep);
- void *(*ep_alloc_buf) (struct cfiobject * cfi, struct dwc_otg_pcd * pcd,
- struct dwc_otg_pcd_ep * ep, dma_addr_t * dma,
- unsigned size, gfp_t flags);
- void (*release) (struct cfiobject * cfi);
- int (*ctrl_write_complete) (struct cfiobject * cfi,
- struct dwc_otg_pcd * pcd);
- void (*build_descriptors) (struct cfiobject * cfi,
- struct dwc_otg_pcd * pcd,
- struct dwc_otg_pcd_ep * ep,
- dwc_otg_pcd_request_t * req);
- } cfi_ops_t;
- struct cfiobject {
- cfi_ops_t ops;
- struct dwc_otg_pcd *pcd;
- struct usb_gadget *gadget;
- /* Buffers used to send/receive CFI-related request data */
- cfi_dma_buff_t buf_in;
- cfi_dma_buff_t buf_out;
- /* CFI specific Control request wrapper */
- struct cfi_usb_ctrlrequest ctrl_req;
- /* The list of active EP's in the PCD of type cfi_ep_t */
- dwc_list_link_t active_eps;
- /* This flag shall control the propagation of a specific request
- * to the gadget's processing routines.
- * 0 - no gadget handling
- * 1 - the gadget needs to know about this request (w/o completing a status
- * phase - just return a 0 to the _setup callback)
- */
- uint8_t need_gadget_att;
- /* Flag indicating whether the status IN phase needs to be
- * completed by the PCD
- */
- uint8_t need_status_in_complete;
- };
- typedef struct cfiobject cfiobject_t;
- #define DUMP_MSG
- #if defined(DUMP_MSG)
- static inline void dump_msg(const u8 * buf, unsigned int length)
- {
- unsigned int start, num, i;
- char line[52], *p;
- if (length >= 512)
- return;
- start = 0;
- while (length > 0) {
- num = min(length, 16u);
- p = line;
- for (i = 0; i < num; ++i) {
- if (i == 8)
- *p++ = ' ';
- DWC_SPRINTF(p, " %02x", buf[i]);
- p += 3;
- }
- *p = 0;
- DWC_DEBUG("%6x: %s\n", start, line);
- buf += num;
- start += num;
- length -= num;
- }
- }
- #else
- static inline void dump_msg(const u8 * buf, unsigned int length)
- {
- }
- #endif
- /**
- * This function returns a pointer to cfi_ep_t object with the addr address.
- */
- static inline struct cfi_ep *get_cfi_ep_by_addr(struct cfiobject *cfi,
- uint8_t addr)
- {
- struct cfi_ep *pcfiep;
- dwc_list_link_t *tmp;
- DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
- pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
- if (pcfiep->ep->desc->bEndpointAddress == addr) {
- return pcfiep;
- }
- }
- return NULL;
- }
- /**
- * This function returns a pointer to cfi_ep_t object that matches
- * the dwc_otg_pcd_ep object.
- */
- static inline struct cfi_ep *get_cfi_ep_by_pcd_ep(struct cfiobject *cfi,
- struct dwc_otg_pcd_ep *ep)
- {
- struct cfi_ep *pcfiep = NULL;
- dwc_list_link_t *tmp;
- DWC_LIST_FOREACH(tmp, &cfi->active_eps) {
- pcfiep = DWC_LIST_ENTRY(tmp, struct cfi_ep, lh);
- if (pcfiep->ep == ep) {
- return pcfiep;
- }
- }
- return NULL;
- }
- int cfi_setup(struct dwc_otg_pcd *pcd, struct cfi_usb_ctrlrequest *ctrl);
- #endif /* (__DWC_OTG_CFI_H__) */
|