1 /* =========================================================================
2 * $File: //dwh/usb_iip/dev/software/dwc_common_port_2/dwc_os.h $
7 * Synopsys Portability Library Software and documentation
8 * (hereinafter, "Software") is an Unsupported proprietary work of
9 * Synopsys, Inc. unless otherwise expressly agreed to in writing
10 * between Synopsys and you.
12 * The Software IS NOT an item of Licensed Software or Licensed Product
13 * under any End User Software License Agreement or Agreement for
14 * Licensed Product with Synopsys or any supplement thereto. You are
15 * permitted to use and redistribute this Software in source and binary
16 * forms, with or without modification, provided that redistributions
17 * of source code must retain this notice. You may not view, use,
18 * disclose, copy or distribute this file or any information contained
19 * herein except pursuant to this license grant from Synopsys. If you
20 * do not agree with this notice, including the disclaimer below, then
21 * you are not authorized to use the Software.
23 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
24 * BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL
27 * SYNOPSYS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
31 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
33 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
35 * ========================================================================= */
45 * DWC portability library, low level os-wrapper functions
49 /* These basic types need to be defined by some OS header file or custom header
50 * file for your specific target architecture.
52 * uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t
54 * Any custom or alternate header file must be added and enabled here.
58 # include <linux/types.h>
59 # ifdef CONFIG_DEBUG_MUTEXES
60 # include <linux/mutex.h>
62 # include <linux/errno.h>
66 #if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
71 /** @name Primitive Types and Values */
73 /** We define a boolean type for consistency. Can be either YES or NO */
74 typedef uint8_t dwc_bool_t;
80 /** @name Error Codes */
81 #define DWC_E_INVALID EINVAL
82 #define DWC_E_NO_MEMORY ENOMEM
83 #define DWC_E_NO_DEVICE ENODEV
84 #define DWC_E_NOT_SUPPORTED EOPNOTSUPP
85 #define DWC_E_TIMEOUT ETIMEDOUT
86 #define DWC_E_BUSY EBUSY
87 #define DWC_E_AGAIN EAGAIN
88 #define DWC_E_RESTART ERESTART
89 #define DWC_E_ABORT ECONNABORTED
90 #define DWC_E_SHUTDOWN ESHUTDOWN
91 #define DWC_E_NO_DATA ENODATA
92 #define DWC_E_DISCONNECT ECONNRESET
93 #define DWC_E_UNKNOWN EINVAL
94 #define DWC_E_NO_STREAM_RES ENOSR
95 #define DWC_E_COMMUNICATION ECOMM
96 #define DWC_E_OVERFLOW EOVERFLOW
97 #define DWC_E_PROTOCOL EPROTO
98 #define DWC_E_IN_PROGRESS EINPROGRESS
99 #define DWC_E_PIPE EPIPE
101 #define DWC_E_NO_SPACE ENOSPC
105 /** @name Error Codes */
106 #define DWC_E_INVALID 1001
107 #define DWC_E_NO_MEMORY 1002
108 #define DWC_E_NO_DEVICE 1003
109 #define DWC_E_NOT_SUPPORTED 1004
110 #define DWC_E_TIMEOUT 1005
111 #define DWC_E_BUSY 1006
112 #define DWC_E_AGAIN 1007
113 #define DWC_E_RESTART 1008
114 #define DWC_E_ABORT 1009
115 #define DWC_E_SHUTDOWN 1010
116 #define DWC_E_NO_DATA 1011
117 #define DWC_E_DISCONNECT 2000
118 #define DWC_E_UNKNOWN 3000
119 #define DWC_E_NO_STREAM_RES 4001
120 #define DWC_E_COMMUNICATION 4002
121 #define DWC_E_OVERFLOW 4003
122 #define DWC_E_PROTOCOL 4004
123 #define DWC_E_IN_PROGRESS 4005
124 #define DWC_E_PIPE 4006
125 #define DWC_E_IO 4007
126 #define DWC_E_NO_SPACE 4008
131 /** @name Tracing/Logging Functions
133 * These function provide the capability to add tracing, debugging, and error
134 * messages, as well exceptions as assertions. The WUDEV uses these
135 * extensively. These could be logged to the main console, the serial port, an
136 * internal buffer, etc. These functions could also be no-op if they are too
137 * expensive on your system. By default undefining the DEBUG macro already
138 * no-ops some of these functions. */
140 /** Returns non-zero if in interrupt context. */
141 extern dwc_bool_t DWC_IN_IRQ(void);
142 #define dwc_in_irq DWC_IN_IRQ
144 /** Returns "IRQ" if DWC_IN_IRQ is true. */
145 static inline char *dwc_irq(void) {
146 return DWC_IN_IRQ() ? "IRQ" : "";
149 /** Returns non-zero if in bottom-half context. */
150 extern dwc_bool_t DWC_IN_BH(void);
151 #define dwc_in_bh DWC_IN_BH
153 /** Returns "BH" if DWC_IN_BH is true. */
154 static inline char *dwc_bh(void) {
155 return DWC_IN_BH() ? "BH" : "";
159 * A vprintf() clone. Just call vprintf if you've got it.
161 extern void DWC_VPRINTF(char *format, va_list args);
162 #define dwc_vprintf DWC_VPRINTF
165 * A vsnprintf() clone. Just call vprintf if you've got it.
167 extern int DWC_VSNPRINTF(char *str, int size, char *format, va_list args);
168 #define dwc_vsnprintf DWC_VSNPRINTF
171 * printf() clone. Just call printf if you've go it.
173 extern void DWC_PRINTF(char *format, ...)
174 /* This provides compiler level static checking of the parameters if you're
177 __attribute__ ((format(printf, 1, 2)));
181 #define dwc_printf DWC_PRINTF
184 * sprintf() clone. Just call sprintf if you've got it.
186 extern int DWC_SPRINTF(char *string, char *format, ...)
188 __attribute__ ((format(printf, 2, 3)));
192 #define dwc_sprintf DWC_SPRINTF
195 * snprintf() clone. Just call snprintf if you've got it.
197 extern int DWC_SNPRINTF(char *string, int size, char *format, ...)
199 __attribute__ ((format(printf, 3, 4)));
203 #define dwc_snprintf DWC_SNPRINTF
206 * Prints a WARNING message. On systems that don't differentiate between
207 * warnings and regular log messages, just print it. Indicates that something
208 * may be wrong with the driver. Works like printf().
210 * Use the DWC_WARN macro to call this function.
212 extern void __DWC_WARN(char *format, ...)
214 __attribute__ ((format(printf, 1, 2)));
220 * Prints an error message. On systems that don't differentiate between errors
221 * and regular log messages, just print it. Indicates that something went wrong
222 * with the driver. Works like printf().
224 * Use the DWC_ERROR macro to call this function.
226 extern void __DWC_ERROR(char *format, ...)
228 __attribute__ ((format(printf, 1, 2)));
234 * Prints an exception error message and takes some user-defined action such as
235 * print out a backtrace or trigger a breakpoint. Indicates that something went
236 * abnormally wrong with the driver such as programmer error, or other
237 * exceptional condition. It should not be ignored so even on systems without
238 * printing capability, some action should be taken to notify the developer of
239 * it. Works like printf().
241 extern void DWC_EXCEPTION(char *format, ...)
243 __attribute__ ((format(printf, 1, 2)));
247 #define dwc_exception DWC_EXCEPTION
251 * Prints out a debug message. Used for logging/trace messages.
253 * Use the DWC_DEBUG macro to call this function
255 extern void __DWC_DEBUG(char *format, ...)
257 __attribute__ ((format(printf, 1, 2)));
262 #define __DWC_DEBUG(...)
266 * Prints out a Debug message.
268 #define DWC_DEBUG(_format, _args...) __DWC_DEBUG("DEBUG:%s:%s: " _format "\n", \
269 __func__, dwc_irq(), ## _args)
270 #define dwc_debug DWC_DEBUG
272 * Prints out an informative message.
274 #define DWC_INFO(_format, _args...) DWC_PRINTF("INFO:%s: " _format "\n", \
276 #define dwc_info DWC_INFO
278 * Prints out a warning message.
280 #define DWC_WARN(_format, _args...) __DWC_WARN("WARN:%s:%s:%d: " _format "\n", \
281 dwc_irq(), __func__, __LINE__, ## _args)
282 #define dwc_warn DWC_WARN
284 * Prints out an error message.
286 #define DWC_ERROR(_format, _args...) __DWC_ERROR("ERROR:%s:%s:%d: " _format "\n", \
287 dwc_irq(), __func__, __LINE__, ## _args)
288 #define dwc_error DWC_ERROR
290 #define DWC_PROTO_ERROR(_format, _args...) __DWC_WARN("ERROR:%s:%s:%d: " _format "\n", \
291 dwc_irq(), __func__, __LINE__, ## _args)
292 #define dwc_proto_error DWC_PROTO_ERROR
295 /** Prints out a exception error message if the _expr expression fails. Disabled
296 * if DEBUG is not enabled. */
297 #define DWC_ASSERT(_expr, _format, _args...) do { \
298 if (!(_expr)) { DWC_EXCEPTION("%s:%s:%d: " _format "\n", dwc_irq(), \
299 __FILE__, __LINE__, ## _args); } \
302 #define DWC_ASSERT(_x...)
304 #define dwc_assert DWC_ASSERT
307 /** @name Byte Ordering
308 * The following functions are for conversions between processor's byte ordering
309 * and specific ordering you want.
312 /** Converts 32 bit data in CPU byte ordering to little endian. */
313 extern uint32_t DWC_CPU_TO_LE32(uint32_t *p);
314 #define dwc_cpu_to_le32 DWC_CPU_TO_LE32
316 /** Converts 32 bit data in CPU byte orderint to big endian. */
317 extern uint32_t DWC_CPU_TO_BE32(uint32_t *p);
318 #define dwc_cpu_to_be32 DWC_CPU_TO_BE32
320 /** Converts 32 bit little endian data to CPU byte ordering. */
321 extern uint32_t DWC_LE32_TO_CPU(uint32_t *p);
322 #define dwc_le32_to_cpu DWC_LE32_TO_CPU
324 /** Converts 32 bit big endian data to CPU byte ordering. */
325 extern uint32_t DWC_BE32_TO_CPU(uint32_t *p);
326 #define dwc_be32_to_cpu DWC_BE32_TO_CPU
328 /** Converts 16 bit data in CPU byte ordering to little endian. */
329 extern uint16_t DWC_CPU_TO_LE16(uint16_t *p);
330 #define dwc_cpu_to_le16 DWC_CPU_TO_LE16
332 /** Converts 16 bit data in CPU byte orderint to big endian. */
333 extern uint16_t DWC_CPU_TO_BE16(uint16_t *p);
334 #define dwc_cpu_to_be16 DWC_CPU_TO_BE16
336 /** Converts 16 bit little endian data to CPU byte ordering. */
337 extern uint16_t DWC_LE16_TO_CPU(uint16_t *p);
338 #define dwc_le16_to_cpu DWC_LE16_TO_CPU
340 /** Converts 16 bit bi endian data to CPU byte ordering. */
341 extern uint16_t DWC_BE16_TO_CPU(uint16_t *p);
342 #define dwc_be16_to_cpu DWC_BE16_TO_CPU
345 /** @name Register Read/Write
347 * The following six functions should be implemented to read/write registers of
348 * 32-bit and 64-bit sizes. All modules use this to read/write register values.
349 * The reg value is a pointer to the register calculated from the void *base
350 * variable passed into the driver when it is started. */
353 /* Linux doesn't need any extra parameters for register read/write, so we
354 * just throw away the IO context parameter.
356 /** Reads the content of a 32-bit register. */
357 extern uint32_t DWC_READ_REG32(uint32_t volatile *reg);
358 #define dwc_read_reg32(_reg_) DWC_READ_REG32(_reg_)
360 /** Reads the content of a 64-bit register. */
361 extern uint64_t DWC_READ_REG64(uint64_t volatile *reg);
362 #define dwc_read_reg64(_reg_) DWC_READ_REG64(_reg_)
364 /** Writes to a 32-bit register. */
365 extern void DWC_WRITE_REG32(uint32_t volatile *reg, uint32_t value);
366 #define dwc_write_reg32(_reg_,_val_) DWC_WRITE_REG32(_reg_, _val_)
368 /** Writes to a 64-bit register. */
369 extern void DWC_WRITE_REG64(uint64_t volatile *reg, uint64_t value);
370 #define dwc_write_reg64(_reg_,_val_) DWC_WRITE_REG64(_reg_, _val_)
373 * Modify bit values in a register. Using the
374 * algorithm: (reg_contents & ~clear_mask) | set_mask.
376 extern void DWC_MODIFY_REG32(uint32_t volatile *reg, uint32_t clear_mask, uint32_t set_mask);
377 #define dwc_modify_reg32(_reg_,_cmsk_,_smsk_) DWC_MODIFY_REG32(_reg_,_cmsk_,_smsk_)
378 extern void DWC_MODIFY_REG64(uint64_t volatile *reg, uint64_t clear_mask, uint64_t set_mask);
379 #define dwc_modify_reg64(_reg_,_cmsk_,_smsk_) DWC_MODIFY_REG64(_reg_,_cmsk_,_smsk_)
381 #endif /* DWC_LINUX */
383 #if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
384 typedef struct dwc_ioctx {
387 bus_space_handle_t ioh;
390 /** BSD needs two extra parameters for register read/write, so we pass
391 * them in using the IO context parameter.
393 /** Reads the content of a 32-bit register. */
394 extern uint32_t DWC_READ_REG32(void *io_ctx, uint32_t volatile *reg);
395 #define dwc_read_reg32 DWC_READ_REG32
397 /** Reads the content of a 64-bit register. */
398 extern uint64_t DWC_READ_REG64(void *io_ctx, uint64_t volatile *reg);
399 #define dwc_read_reg64 DWC_READ_REG64
401 /** Writes to a 32-bit register. */
402 extern void DWC_WRITE_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t value);
403 #define dwc_write_reg32 DWC_WRITE_REG32
405 /** Writes to a 64-bit register. */
406 extern void DWC_WRITE_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t value);
407 #define dwc_write_reg64 DWC_WRITE_REG64
410 * Modify bit values in a register. Using the
411 * algorithm: (reg_contents & ~clear_mask) | set_mask.
413 extern void DWC_MODIFY_REG32(void *io_ctx, uint32_t volatile *reg, uint32_t clear_mask, uint32_t set_mask);
414 #define dwc_modify_reg32 DWC_MODIFY_REG32
415 extern void DWC_MODIFY_REG64(void *io_ctx, uint64_t volatile *reg, uint64_t clear_mask, uint64_t set_mask);
416 #define dwc_modify_reg64 DWC_MODIFY_REG64
418 #endif /* DWC_FREEBSD || DWC_NETBSD */
422 /** @name Some convenience MACROS used internally. Define DWC_DEBUG_REGS to log the
423 * register writes. */
427 # ifdef DWC_DEBUG_REGS
429 #define dwc_define_read_write_reg_n(_reg,_container_type) \
430 static inline uint32_t dwc_read_##_reg##_n(_container_type *container, int num) { \
431 return DWC_READ_REG32(&container->regs->_reg[num]); \
433 static inline void dwc_write_##_reg##_n(_container_type *container, int num, uint32_t data) { \
434 DWC_DEBUG("WRITING %8s[%d]: %p: %08x", #_reg, num, \
435 &(((uint32_t*)container->regs->_reg)[num]), data); \
436 DWC_WRITE_REG32(&(((uint32_t*)container->regs->_reg)[num]), data); \
439 #define dwc_define_read_write_reg(_reg,_container_type) \
440 static inline uint32_t dwc_read_##_reg(_container_type *container) { \
441 return DWC_READ_REG32(&container->regs->_reg); \
443 static inline void dwc_write_##_reg(_container_type *container, uint32_t data) { \
444 DWC_DEBUG("WRITING %11s: %p: %08x", #_reg, &container->regs->_reg, data); \
445 DWC_WRITE_REG32(&container->regs->_reg, data); \
448 # else /* DWC_DEBUG_REGS */
450 #define dwc_define_read_write_reg_n(_reg,_container_type) \
451 static inline uint32_t dwc_read_##_reg##_n(_container_type *container, int num) { \
452 return DWC_READ_REG32(&container->regs->_reg[num]); \
454 static inline void dwc_write_##_reg##_n(_container_type *container, int num, uint32_t data) { \
455 DWC_WRITE_REG32(&(((uint32_t*)container->regs->_reg)[num]), data); \
458 #define dwc_define_read_write_reg(_reg,_container_type) \
459 static inline uint32_t dwc_read_##_reg(_container_type *container) { \
460 return DWC_READ_REG32(&container->regs->_reg); \
462 static inline void dwc_write_##_reg(_container_type *container, uint32_t data) { \
463 DWC_WRITE_REG32(&container->regs->_reg, data); \
466 # endif /* DWC_DEBUG_REGS */
468 #endif /* DWC_LINUX */
470 #if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
472 # ifdef DWC_DEBUG_REGS
474 #define dwc_define_read_write_reg_n(_reg,_container_type) \
475 static inline uint32_t dwc_read_##_reg##_n(void *io_ctx, _container_type *container, int num) { \
476 return DWC_READ_REG32(io_ctx, &container->regs->_reg[num]); \
478 static inline void dwc_write_##_reg##_n(void *io_ctx, _container_type *container, int num, uint32_t data) { \
479 DWC_DEBUG("WRITING %8s[%d]: %p: %08x", #_reg, num, \
480 &(((uint32_t*)container->regs->_reg)[num]), data); \
481 DWC_WRITE_REG32(io_ctx, &(((uint32_t*)container->regs->_reg)[num]), data); \
484 #define dwc_define_read_write_reg(_reg,_container_type) \
485 static inline uint32_t dwc_read_##_reg(void *io_ctx, _container_type *container) { \
486 return DWC_READ_REG32(io_ctx, &container->regs->_reg); \
488 static inline void dwc_write_##_reg(void *io_ctx, _container_type *container, uint32_t data) { \
489 DWC_DEBUG("WRITING %11s: %p: %08x", #_reg, &container->regs->_reg, data); \
490 DWC_WRITE_REG32(io_ctx, &container->regs->_reg, data); \
493 # else /* DWC_DEBUG_REGS */
495 #define dwc_define_read_write_reg_n(_reg,_container_type) \
496 static inline uint32_t dwc_read_##_reg##_n(void *io_ctx, _container_type *container, int num) { \
497 return DWC_READ_REG32(io_ctx, &container->regs->_reg[num]); \
499 static inline void dwc_write_##_reg##_n(void *io_ctx, _container_type *container, int num, uint32_t data) { \
500 DWC_WRITE_REG32(io_ctx, &(((uint32_t*)container->regs->_reg)[num]), data); \
503 #define dwc_define_read_write_reg(_reg,_container_type) \
504 static inline uint32_t dwc_read_##_reg(void *io_ctx, _container_type *container) { \
505 return DWC_READ_REG32(io_ctx, &container->regs->_reg); \
507 static inline void dwc_write_##_reg(void *io_ctx, _container_type *container, uint32_t data) { \
508 DWC_WRITE_REG32(io_ctx, &container->regs->_reg, data); \
511 # endif /* DWC_DEBUG_REGS */
513 #endif /* DWC_FREEBSD || DWC_NETBSD */
519 /** @name Crypto Functions
521 * These are the low-level cryptographic functions used by the driver. */
523 /** Perform AES CBC */
524 extern int DWC_AES_CBC(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t iv[16], uint8_t *out);
525 #define dwc_aes_cbc DWC_AES_CBC
527 /** Fill the provided buffer with random bytes. These should be cryptographic grade random numbers. */
528 extern void DWC_RANDOM_BYTES(uint8_t *buffer, uint32_t length);
529 #define dwc_random_bytes DWC_RANDOM_BYTES
531 /** Perform the SHA-256 hash function */
532 extern int DWC_SHA256(uint8_t *message, uint32_t len, uint8_t *out);
533 #define dwc_sha256 DWC_SHA256
535 /** Calculated the HMAC-SHA256 */
536 extern int DWC_HMAC_SHA256(uint8_t *message, uint32_t messagelen, uint8_t *key, uint32_t keylen, uint8_t *out);
537 #define dwc_hmac_sha256 DWC_HMAC_SHA256
539 #endif /* DWC_CRYPTOLIB */
542 /** @name Memory Allocation
544 * These function provide access to memory allocation. There are only 2 DMA
545 * functions and 3 Regular memory functions that need to be implemented. None
546 * of the memory debugging routines need to be implemented. The allocation
547 * routines all ZERO the contents of the memory.
549 * Defining DWC_DEBUG_MEMORY turns on memory debugging and statistic gathering.
550 * This checks for memory leaks, keeping track of alloc/free pairs. It also
551 * keeps track of how much memory the driver is using at any given time. */
553 #define DWC_PAGE_SIZE 4096
554 #define DWC_PAGE_OFFSET(addr) (((uint32_t)addr) & 0xfff)
555 #define DWC_PAGE_ALIGNED(addr) ((((uint32_t)addr) & 0xfff) == 0)
557 #define DWC_INVALID_DMA_ADDR 0x0
560 /** Type for a DMA address */
561 typedef dma_addr_t dwc_dma_t;
564 #if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
565 typedef bus_addr_t dwc_dma_t;
569 typedef struct dwc_dmactx {
571 bus_dma_tag_t dma_tag;
572 bus_dmamap_t dma_map;
573 bus_addr_t dma_paddr;
579 typedef struct dwc_dmactx {
581 bus_dma_tag_t dma_tag;
582 bus_dmamap_t dma_map;
583 bus_dma_segment_t segs[1];
585 bus_addr_t dma_paddr;
590 /* @todo these functions will be added in the future */
593 * Creates a DMA pool from which you can allocate DMA buffers. Buffers
594 * allocated from this pool will be guaranteed to meet the size, alignment, and
595 * boundary requirements specified.
597 * @param[in] size Specifies the size of the buffers that will be allocated from
599 * @param[in] align Specifies the byte alignment requirements of the buffers
600 * allocated from this pool. Must be a power of 2.
601 * @param[in] boundary Specifies the N-byte boundary that buffers allocated from
602 * this pool must not cross.
604 * @returns A pointer to an internal opaque structure which is not to be
605 * accessed outside of these library functions. Use this handle to specify
606 * which pools to allocate/free DMA buffers from and also to destroy the pool,
607 * when you are done with it.
609 extern dwc_pool_t *DWC_DMA_POOL_CREATE(uint32_t size, uint32_t align, uint32_t boundary);
612 * Destroy a DMA pool. All buffers allocated from that pool must be freed first.
614 extern void DWC_DMA_POOL_DESTROY(dwc_pool_t *pool);
617 * Allocate a buffer from the specified DMA pool and zeros its contents.
619 extern void *DWC_DMA_POOL_ALLOC(dwc_pool_t *pool, uint64_t *dma_addr);
622 * Free a previously allocated buffer from the DMA pool.
624 extern void DWC_DMA_POOL_FREE(dwc_pool_t *pool, void *vaddr, void *daddr);
627 /** Allocates a DMA capable buffer and zeroes its contents. */
628 extern void *__DWC_DMA_ALLOC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr);
630 /** Allocates a DMA capable buffer and zeroes its contents in atomic contest */
631 extern void *__DWC_DMA_ALLOC_ATOMIC(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr);
633 /** Frees a previously allocated buffer. */
634 extern void __DWC_DMA_FREE(void *dma_ctx, uint32_t size, void *virt_addr, dwc_dma_t dma_addr);
636 /** Allocates a block of memory and zeroes its contents. */
637 extern void *__DWC_ALLOC(void *mem_ctx, uint32_t size);
639 /** Allocates a block of memory and zeroes its contents, in an atomic manner
640 * which can be used inside interrupt context. The size should be sufficiently
641 * small, a few KB at most, such that failures are not likely to occur. Can just call
642 * __DWC_ALLOC if it is atomic. */
643 extern void *__DWC_ALLOC_ATOMIC(void *mem_ctx, uint32_t size);
645 /** Frees a previously allocated buffer. */
646 extern void __DWC_FREE(void *mem_ctx, void *addr);
648 #ifndef DWC_DEBUG_MEMORY
650 #define DWC_ALLOC(_size_) __DWC_ALLOC(NULL, _size_)
651 #define DWC_ALLOC_ATOMIC(_size_) __DWC_ALLOC_ATOMIC(NULL, _size_)
652 #define DWC_FREE(_addr_) __DWC_FREE(NULL, _addr_)
655 #define DWC_DMA_ALLOC __DWC_DMA_ALLOC
656 #define DWC_DMA_ALLOC_ATOMIC __DWC_DMA_ALLOC_ATOMIC
657 #define DWC_DMA_FREE __DWC_DMA_FREE
660 # if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
661 #define DWC_DMA_ALLOC __DWC_DMA_ALLOC
662 #define DWC_DMA_FREE __DWC_DMA_FREE
665 #else /* DWC_DEBUG_MEMORY */
667 extern void *dwc_alloc_debug(void *mem_ctx, uint32_t size, char const *func, int line);
668 extern void *dwc_alloc_atomic_debug(void *mem_ctx, uint32_t size, char const *func, int line);
669 extern void dwc_free_debug(void *mem_ctx, void *addr, char const *func, int line);
670 extern void *dwc_dma_alloc_debug(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr,
671 char const *func, int line);
672 extern void *dwc_dma_alloc_atomic_debug(void *dma_ctx, uint32_t size, dwc_dma_t *dma_addr,
673 char const *func, int line);
674 extern void dwc_dma_free_debug(void *dma_ctx, uint32_t size, void *virt_addr,
675 dwc_dma_t dma_addr, char const *func, int line);
677 extern int dwc_memory_debug_start(void *mem_ctx);
678 extern void dwc_memory_debug_stop(void);
679 extern void dwc_memory_debug_report(void);
681 #define DWC_ALLOC(_size_) dwc_alloc_debug(NULL, _size_, __func__, __LINE__)
682 #define DWC_ALLOC_ATOMIC(_size_) dwc_alloc_atomic_debug(NULL, _size_, \
684 #define DWC_FREE(_addr_) dwc_free_debug(NULL, _addr_, __func__, __LINE__)
687 #define DWC_DMA_ALLOC(_size_,_dma_) dwc_dma_alloc_debug(NULL, _size_, \
688 _dma_, __func__, __LINE__)
689 #define DWC_DMA_ALLOC_ATOMIC(_size_,_dma_) dwc_dma_alloc_atomic_debug(NULL, _size_, \
690 _dma_, __func__, __LINE__)
691 #define DWC_DMA_FREE(_size_,_virt_,_dma_) dwc_dma_free_debug(NULL, _size_, \
692 _virt_, _dma_, __func__, __LINE__)
695 # if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
696 #define DWC_DMA_ALLOC(_ctx_,_size_,_dma_) dwc_dma_alloc_debug(_ctx_, _size_, \
697 _dma_, __func__, __LINE__)
698 #define DWC_DMA_FREE(_ctx_,_size_,_virt_,_dma_) dwc_dma_free_debug(_ctx_, _size_, \
699 _virt_, _dma_, __func__, __LINE__)
702 #endif /* DWC_DEBUG_MEMORY */
704 #define dwc_alloc(_size_) DWC_ALLOC(_size_)
705 #define dwc_alloc_atomic(_size_) DWC_ALLOC_ATOMIC(_size_)
706 #define dwc_free(_addr_) DWC_FREE(_addr_)
709 /* Linux doesn't need any extra parameters for DMA buffer allocation, so we
710 * just throw away the DMA context parameter.
712 #define dwc_dma_alloc(_size_,_dma_) DWC_DMA_ALLOC(_size_, _dma_)
713 #define dwc_dma_alloc_atomic(_size_,_dma_) DWC_DMA_ALLOC_ATOMIC(_size_, _dma_)
714 #define dwc_dma_free(_size_,_virt_,_dma_) DWC_DMA_FREE(_size_, _virt_, _dma_)
717 #if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
718 /** BSD needs several extra parameters for DMA buffer allocation, so we pass
719 * them in using the DMA context parameter.
721 #define dwc_dma_alloc DWC_DMA_ALLOC
722 #define dwc_dma_free DWC_DMA_FREE
726 /** @name Memory and String Processing */
728 /** memset() clone */
729 extern void *DWC_MEMSET(void *dest, uint8_t byte, uint32_t size);
730 #define dwc_memset DWC_MEMSET
732 /** memcpy() clone */
733 extern void *DWC_MEMCPY(void *dest, void const *src, uint32_t size);
734 #define dwc_memcpy DWC_MEMCPY
736 /** memmove() clone */
737 extern void *DWC_MEMMOVE(void *dest, void *src, uint32_t size);
738 #define dwc_memmove DWC_MEMMOVE
740 /** memcmp() clone */
741 extern int DWC_MEMCMP(void *m1, void *m2, uint32_t size);
742 #define dwc_memcmp DWC_MEMCMP
744 /** strcmp() clone */
745 extern int DWC_STRCMP(void *s1, void *s2);
746 #define dwc_strcmp DWC_STRCMP
748 /** strncmp() clone */
749 extern int DWC_STRNCMP(void *s1, void *s2, uint32_t size);
750 #define dwc_strncmp DWC_STRNCMP
752 /** strlen() clone, for NULL terminated ASCII strings */
753 extern int DWC_STRLEN(char const *str);
754 #define dwc_strlen DWC_STRLEN
756 /** strcpy() clone, for NULL terminated ASCII strings */
757 extern char *DWC_STRCPY(char *to, const char *from);
758 #define dwc_strcpy DWC_STRCPY
760 /** strdup() clone. If you wish to use memory allocation debugging, this
761 * implementation of strdup should use the DWC_* memory routines instead of
762 * calling a predefined strdup. Otherwise the memory allocated by this routine
763 * will not be seen by the debugging routines. */
764 extern char *DWC_STRDUP(char const *str);
765 #define dwc_strdup(_ctx_,_str_) DWC_STRDUP(_str_)
767 /** NOT an atoi() clone. Read the description carefully. Returns an integer
768 * converted from the string str in base 10 unless the string begins with a "0x"
769 * in which case it is base 16. String must be a NULL terminated sequence of
770 * ASCII characters and may optionally begin with whitespace, a + or -, and a
771 * "0x" prefix if base 16. The remaining characters must be valid digits for
772 * the number and end with a NULL character. If any invalid characters are
773 * encountered or it returns with a negative error code and the results of the
774 * conversion are undefined. On sucess it returns 0. Overflow conditions are
775 * undefined. An example implementation using atoi() can be referenced from the
776 * Linux implementation. */
777 extern int DWC_ATOI(const char *str, int32_t *value);
778 #define dwc_atoi DWC_ATOI
780 /** Same as above but for unsigned. */
781 extern int DWC_ATOUI(const char *str, uint32_t *value);
782 #define dwc_atoui DWC_ATOUI
785 /** This routine returns a UTF16LE unicode encoded string from a UTF8 string. */
786 extern int DWC_UTF8_TO_UTF16LE(uint8_t const *utf8string, uint16_t *utf16string, unsigned len);
787 #define dwc_utf8_to_utf16le DWC_UTF8_TO_UTF16LE
791 /** @name Wait queues
793 * Wait queues provide a means of synchronizing between threads or processes. A
794 * process can block on a waitq if some condition is not true, waiting for it to
795 * become true. When the waitq is triggered all waiting process will get
796 * unblocked and the condition will be check again. Waitqs should be triggered
797 * every time a condition can potentially change.*/
800 /** Type for a waitq */
801 typedef struct dwc_waitq dwc_waitq_t;
803 /** The type of waitq condition callback function. This is called every time
804 * condition is evaluated. */
805 typedef int (*dwc_waitq_condition_t)(void *data);
807 /** Allocate a waitq */
808 extern dwc_waitq_t *DWC_WAITQ_ALLOC(void);
809 #define dwc_waitq_alloc(_ctx_) DWC_WAITQ_ALLOC()
812 extern void DWC_WAITQ_FREE(dwc_waitq_t *wq);
813 #define dwc_waitq_free DWC_WAITQ_FREE
815 /** Check the condition and if it is false, block on the waitq. When unblocked, check the
816 * condition again. The function returns when the condition becomes true. The return value
817 * is 0 on condition true, DWC_WAITQ_ABORTED on abort or killed, or DWC_WAITQ_UNKNOWN on error. */
818 extern int32_t DWC_WAITQ_WAIT(dwc_waitq_t *wq, dwc_waitq_condition_t cond, void *data);
819 #define dwc_waitq_wait DWC_WAITQ_WAIT
821 /** Check the condition and if it is false, block on the waitq. When unblocked,
822 * check the condition again. The function returns when the condition become
823 * true or the timeout has passed. The return value is 0 on condition true or
824 * DWC_TIMED_OUT on timeout, or DWC_WAITQ_ABORTED, or DWC_WAITQ_UNKNOWN on
826 extern int32_t DWC_WAITQ_WAIT_TIMEOUT(dwc_waitq_t *wq, dwc_waitq_condition_t cond,
827 void *data, int32_t msecs);
828 #define dwc_waitq_wait_timeout DWC_WAITQ_WAIT_TIMEOUT
830 /** Trigger a waitq, unblocking all processes. This should be called whenever a condition
831 * has potentially changed. */
832 extern void DWC_WAITQ_TRIGGER(dwc_waitq_t *wq);
833 #define dwc_waitq_trigger DWC_WAITQ_TRIGGER
835 /** Unblock all processes waiting on the waitq with an ABORTED result. */
836 extern void DWC_WAITQ_ABORT(dwc_waitq_t *wq);
837 #define dwc_waitq_abort DWC_WAITQ_ABORT
842 * A thread must be explicitly stopped. It must check DWC_THREAD_SHOULD_STOP
843 * whenever it is woken up, and then return. The DWC_THREAD_STOP function
844 * returns the value from the thread.
849 /** Type for a thread */
850 typedef struct dwc_thread dwc_thread_t;
852 /** The thread function */
853 typedef int (*dwc_thread_function_t)(void *data);
855 /** Create a thread and start it running the thread_function. Returns a handle
857 extern dwc_thread_t *DWC_THREAD_RUN(dwc_thread_function_t func, char *name, void *data);
858 #define dwc_thread_run(_ctx_,_func_,_name_,_data_) DWC_THREAD_RUN(_func_, _name_, _data_)
860 /** Stops a thread. Return the value returned by the thread. Or will return
861 * DWC_ABORT if the thread never started. */
862 extern int DWC_THREAD_STOP(dwc_thread_t *thread);
863 #define dwc_thread_stop DWC_THREAD_STOP
865 /** Signifies to the thread that it must stop. */
867 /* Linux doesn't need any parameters for kthread_should_stop() */
868 extern dwc_bool_t DWC_THREAD_SHOULD_STOP(void);
869 #define dwc_thread_should_stop(_thrd_) DWC_THREAD_SHOULD_STOP()
871 /* No thread_exit function in Linux */
872 #define dwc_thread_exit(_thrd_)
875 #if defined(DWC_FREEBSD) || defined(DWC_NETBSD)
876 /** BSD needs the thread pointer for kthread_suspend_check() */
877 extern dwc_bool_t DWC_THREAD_SHOULD_STOP(dwc_thread_t *thread);
878 #define dwc_thread_should_stop DWC_THREAD_SHOULD_STOP
880 /** The thread must call this to exit. */
881 extern void DWC_THREAD_EXIT(dwc_thread_t *thread);
882 #define dwc_thread_exit DWC_THREAD_EXIT
886 /** @name Work queues
888 * Workqs are used to queue a callback function to be called at some later time,
889 * in another thread. */
892 /** Type for a workq */
893 typedef struct dwc_workq dwc_workq_t;
895 /** The type of the callback function to be called. */
896 typedef void (*dwc_work_callback_t)(void *data);
898 /** Allocate a workq */
899 extern dwc_workq_t *DWC_WORKQ_ALLOC(char *name);
900 #define dwc_workq_alloc(_ctx_,_name_) DWC_WORKQ_ALLOC(_name_)
902 /** Free a workq. All work must be completed before being freed. */
903 extern void DWC_WORKQ_FREE(dwc_workq_t *workq);
904 #define dwc_workq_free DWC_WORKQ_FREE
906 /** Schedule a callback on the workq, passing in data. The function will be
907 * scheduled at some later time. */
908 extern void DWC_WORKQ_SCHEDULE(dwc_workq_t *workq, dwc_work_callback_t cb,
909 void *data, char *format, ...)
911 __attribute__ ((format(printf, 4, 5)));
915 #define dwc_workq_schedule DWC_WORKQ_SCHEDULE
917 /** Schedule a callback on the workq, that will be called until at least
918 * given number miliseconds have passed. */
919 extern void DWC_WORKQ_SCHEDULE_DELAYED(dwc_workq_t *workq, dwc_work_callback_t cb,
920 void *data, uint32_t time, char *format, ...)
922 __attribute__ ((format(printf, 5, 6)));
926 #define dwc_workq_schedule_delayed DWC_WORKQ_SCHEDULE_DELAYED
928 /** The number of processes in the workq */
929 extern int DWC_WORKQ_PENDING(dwc_workq_t *workq);
930 #define dwc_workq_pending DWC_WORKQ_PENDING
932 /** Blocks until all the work in the workq is complete or timed out. Returns <
934 extern int DWC_WORKQ_WAIT_WORK_DONE(dwc_workq_t *workq, int timeout);
935 #define dwc_workq_wait_work_done DWC_WORKQ_WAIT_WORK_DONE
943 /** Type for a tasklet */
944 typedef struct dwc_tasklet dwc_tasklet_t;
946 /** The type of the callback function to be called */
947 typedef void (*dwc_tasklet_callback_t)(void *data);
949 /** Allocates a tasklet */
950 extern dwc_tasklet_t *DWC_TASK_ALLOC(char *name, dwc_tasklet_callback_t cb, void *data);
951 #define dwc_task_alloc(_ctx_,_name_,_cb_,_data_) DWC_TASK_ALLOC(_name_, _cb_, _data_)
953 /** Frees a tasklet */
954 extern void DWC_TASK_FREE(dwc_tasklet_t *task);
955 #define dwc_task_free DWC_TASK_FREE
957 /** Schedules a tasklet to run */
958 extern void DWC_TASK_SCHEDULE(dwc_tasklet_t *task);
959 #define dwc_task_schedule DWC_TASK_SCHEDULE
964 * Callbacks must be small and atomic.
968 /** Type for a timer */
969 typedef struct dwc_timer dwc_timer_t;
971 /** The type of the callback function to be called */
972 typedef void (*dwc_timer_callback_t)(void *data);
974 /** Allocates a timer */
975 extern dwc_timer_t *DWC_TIMER_ALLOC(char *name, dwc_timer_callback_t cb, void *data);
976 #define dwc_timer_alloc(_ctx_,_name_,_cb_,_data_) DWC_TIMER_ALLOC(_name_,_cb_,_data_)
979 extern void DWC_TIMER_FREE(dwc_timer_t *timer);
980 #define dwc_timer_free DWC_TIMER_FREE
982 /** Schedules the timer to run at time ms from now. And will repeat at every
983 * repeat_interval msec therafter
985 * Modifies a timer that is still awaiting execution to a new expiration time.
986 * The mod_time is added to the old time. */
987 extern void DWC_TIMER_SCHEDULE(dwc_timer_t *timer, uint32_t time);
988 #define dwc_timer_schedule DWC_TIMER_SCHEDULE
990 /** Disables the timer from execution. */
991 extern void DWC_TIMER_CANCEL(dwc_timer_t *timer);
992 #define dwc_timer_cancel DWC_TIMER_CANCEL
997 * These locks are used when the work between the lock/unlock is atomic and
998 * short. Interrupts are also disabled during the lock/unlock and thus they are
999 * suitable to lock between interrupt/non-interrupt context. They also lock
1000 * between processes if you have multiple CPUs or Preemption. If you don't have
1001 * multiple CPUS or Preemption, then the you can simply implement the
1002 * DWC_SPINLOCK and DWC_SPINUNLOCK to disable and enable interrupts. Because
1003 * the work between the lock/unlock is atomic, the process context will never
1004 * change, and so you never have to lock between processes. */
1006 struct dwc_spinlock;
1008 /** Type for a spinlock */
1009 typedef struct dwc_spinlock dwc_spinlock_t;
1011 /** Type for the 'flags' argument to spinlock funtions */
1012 typedef unsigned long dwc_irqflags_t;
1014 /** Returns an initialized lock variable. This function should allocate and
1015 * initialize the OS-specific data structure used for locking. This data
1016 * structure is to be used for the DWC_LOCK and DWC_UNLOCK functions and should
1017 * be freed by the DWC_FREE_LOCK when it is no longer used. */
1018 extern dwc_spinlock_t *DWC_SPINLOCK_ALLOC(void);
1019 #define dwc_spinlock_alloc(_ctx_) DWC_SPINLOCK_ALLOC()
1021 /** Frees an initialized lock variable. */
1022 extern void DWC_SPINLOCK_FREE(dwc_spinlock_t *lock);
1023 #define dwc_spinlock_free(_ctx_,_lock_) DWC_SPINLOCK_FREE(_lock_)
1025 /** Disables interrupts and blocks until it acquires the lock.
1027 * @param lock Pointer to the spinlock.
1028 * @param flags Unsigned long for irq flags storage.
1030 extern void DWC_SPINLOCK_IRQSAVE(dwc_spinlock_t *lock, dwc_irqflags_t *flags);
1031 #define dwc_spinlock_irqsave DWC_SPINLOCK_IRQSAVE
1033 /** Re-enables the interrupt and releases the lock.
1035 * @param lock Pointer to the spinlock.
1036 * @param flags Unsigned long for irq flags storage. Must be the same as was
1037 * passed into DWC_LOCK.
1039 extern void DWC_SPINUNLOCK_IRQRESTORE(dwc_spinlock_t *lock, dwc_irqflags_t flags);
1040 #define dwc_spinunlock_irqrestore DWC_SPINUNLOCK_IRQRESTORE
1042 /** Blocks until it acquires the lock.
1044 * @param lock Pointer to the spinlock.
1046 extern void DWC_SPINLOCK(dwc_spinlock_t *lock);
1047 #define dwc_spinlock DWC_SPINLOCK
1049 /** Releases the lock.
1051 * @param lock Pointer to the spinlock.
1053 extern void DWC_SPINUNLOCK(dwc_spinlock_t *lock);
1054 #define dwc_spinunlock DWC_SPINUNLOCK
1059 * Unlike spinlocks Mutexes lock only between processes and the work between the
1060 * lock/unlock CAN block, therefore it CANNOT be called from interrupt context.
1065 /** Type for a mutex */
1066 typedef struct dwc_mutex dwc_mutex_t;
1068 /* For Linux Mutex Debugging make it inline because the debugging routines use
1069 * the symbol to determine recursive locking. This makes it falsely think
1070 * recursive locking occurs. */
1071 #if defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES)
1072 #define DWC_MUTEX_ALLOC_LINUX_DEBUG(__mutexp) ({ \
1073 __mutexp = (dwc_mutex_t *)DWC_ALLOC(sizeof(struct mutex)); \
1074 mutex_init((struct mutex *)__mutexp); \
1078 /** Allocate a mutex */
1079 extern dwc_mutex_t *DWC_MUTEX_ALLOC(void);
1080 #define dwc_mutex_alloc(_ctx_) DWC_MUTEX_ALLOC()
1082 /* For memory leak debugging when using Linux Mutex Debugging */
1083 #if defined(DWC_LINUX) && defined(CONFIG_DEBUG_MUTEXES)
1084 #define DWC_MUTEX_FREE(__mutexp) do { \
1085 mutex_destroy((struct mutex *)__mutexp); \
1086 DWC_FREE(__mutexp); \
1090 extern void DWC_MUTEX_FREE(dwc_mutex_t *mutex);
1091 #define dwc_mutex_free(_ctx_,_mutex_) DWC_MUTEX_FREE(_mutex_)
1095 extern void DWC_MUTEX_LOCK(dwc_mutex_t *mutex);
1096 #define dwc_mutex_lock DWC_MUTEX_LOCK
1098 /** Non-blocking lock returns 1 on successful lock. */
1099 extern int DWC_MUTEX_TRYLOCK(dwc_mutex_t *mutex);
1100 #define dwc_mutex_trylock DWC_MUTEX_TRYLOCK
1102 /** Unlock a mutex */
1103 extern void DWC_MUTEX_UNLOCK(dwc_mutex_t *mutex);
1104 #define dwc_mutex_unlock DWC_MUTEX_UNLOCK
1109 /** Microsecond delay.
1111 * @param usecs Microseconds to delay.
1113 extern void DWC_UDELAY(uint32_t usecs);
1114 #define dwc_udelay DWC_UDELAY
1116 /** Millisecond delay.
1118 * @param msecs Milliseconds to delay.
1120 extern void DWC_MDELAY(uint32_t msecs);
1121 #define dwc_mdelay DWC_MDELAY
1123 /** Non-busy waiting.
1124 * Sleeps for specified number of milliseconds.
1126 * @param msecs Milliseconds to sleep.
1128 extern void DWC_MSLEEP(uint32_t msecs);
1129 #define dwc_msleep DWC_MSLEEP
1132 * Returns number of milliseconds since boot.
1134 extern uint32_t DWC_TIME(void);
1135 #define dwc_time DWC_TIME
1140 /* @mainpage DWC Portability and Common Library
1142 * This is the documentation for the DWC Portability and Common Library.
1144 * @section intro Introduction
1146 * The DWC Portability library consists of wrapper calls and data structures to
1147 * all low-level functions which are typically provided by the OS. The WUDEV
1148 * driver uses only these functions. In order to port the WUDEV driver, only
1149 * the functions in this library need to be re-implemented, with the same
1150 * behavior as documented here.
1152 * The Common library consists of higher level functions, which rely only on
1153 * calling the functions from the DWC Portability library. These common
1154 * routines are shared across modules. Some of the common libraries need to be
1155 * used directly by the driver programmer when porting WUDEV. Such as the
1156 * parameter and notification libraries.
1158 * @section low Portability Library OS Wrapper Functions
1160 * Any function starting with DWC and in all CAPS is a low-level OS-wrapper that
1161 * needs to be implemented when porting, for example DWC_MUTEX_ALLOC(). All of
1162 * these functions are included in the dwc_os.h file.
1164 * There are many functions here covering a wide array of OS services. Please
1165 * see dwc_os.h for details, and implementation notes for each function.
1167 * @section common Common Library Functions
1169 * Any function starting with dwc and in all lowercase is a common library
1170 * routine. These functions have a portable implementation and do not need to
1171 * be reimplemented when porting. The common routines can be used by any
1172 * driver, and some must be used by the end user to control the drivers. For
1173 * example, you must use the Parameter common library in order to set the
1174 * parameters in the WUDEV module.
1176 * The common libraries consist of the following:
1178 * - Connection Contexts - Used internally and can be used by end-user. See dwc_cc.h
1179 * - Parameters - Used internally and can be used by end-user. See dwc_params.h
1180 * - Notifications - Used internally and can be used by end-user. See dwc_notifier.h
1181 * - Lists - Used internally and can be used by end-user. See dwc_list.h
1182 * - Memory Debugging - Used internally and can be used by end-user. See dwc_os.h
1183 * - Modpow - Used internally only. See dwc_modpow.h
1184 * - DH - Used internally only. See dwc_dh.h
1185 * - Crypto - Used internally only. See dwc_crypto.h
1188 * @section prereq Prerequistes For dwc_os.h
1189 * @subsection types Data Types
1191 * The dwc_os.h file assumes that several low-level data types are pre defined for the
1192 * compilation environment. These data types are:
1194 * - uint8_t - unsigned 8-bit data type
1195 * - int8_t - signed 8-bit data type
1196 * - uint16_t - unsigned 16-bit data type
1197 * - int16_t - signed 16-bit data type
1198 * - uint32_t - unsigned 32-bit data type
1199 * - int32_t - signed 32-bit data type
1200 * - uint64_t - unsigned 64-bit data type
1201 * - int64_t - signed 64-bit data type
1203 * Ensure that these are defined before using dwc_os.h. The easiest way to do
1204 * that is to modify the top of the file to include the appropriate header.
1205 * This is already done for the Linux environment. If the DWC_LINUX macro is
1206 * defined, the correct header will be added. A standard header <stdint.h> is
1207 * also used for environments where standard C headers are available.
1209 * @subsection stdarg Variable Arguments
1211 * Variable arguments are provided by a standard C header <stdarg.h>. it is
1212 * available in Both the Linux and ANSI C enviornment. An equivalent must be
1213 * provided in your enviornment in order to use dwc_os.h with the debug and
1214 * tracing message functionality.
1216 * @subsection thread Threading
1218 * WUDEV Core must be run on an operating system that provides for multiple
1219 * threads/processes. Threading can be implemented in many ways, even in
1220 * embedded systems without an operating system. At the bare minimum, the
1221 * system should be able to start any number of processes at any time to handle
1222 * special work. It need not be a pre-emptive system. Process context can
1223 * change upon a call to a blocking function. The hardware interrupt context
1224 * that calls the module's ISR() function must be differentiable from process
1225 * context, even if your processes are impemented via a hardware interrupt.
1226 * Further locking mechanism between process must exist (or be implemented), and
1227 * process context must have a way to disable interrupts for a period of time to
1228 * lock them out. If all of this exists, the functions in dwc_os.h related to
1229 * threading should be able to be implemented with the defined behavior.
1237 #endif /* _DWC_OS_H_ */