| /* |
| <:copyright-BRCM:2016:DUAL/GPL:standard |
| |
| Broadcom Proprietary and Confidential.(c) 2016 Broadcom |
| All Rights Reserved |
| |
| Unless you and Broadcom execute a separate written software license |
| agreement governing use of this software, this software is licensed |
| to you under the terms of the GNU General Public License version 2 |
| (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php, |
| with the following added to such license: |
| |
| As a special exception, the copyright holders of this software give |
| you permission to link this software with independent modules, and |
| to copy and distribute the resulting executable under terms of your |
| choice, provided that you also meet, for each linked independent |
| module, the terms and conditions of the license of that module. |
| An independent module is a module which is not derived from this |
| software. The special exception does not apply to any modifications |
| of the software. |
| |
| Not withstanding the above, under no circumstances may you combine |
| this software in any way with any other Broadcom software provided |
| under a license other than the GPL, without Broadcom's express prior |
| written consent. |
| |
| :> |
| */ |
| |
| #ifndef BCMOS_COMMON2_H_ |
| #define BCMOS_COMMON2_H_ |
| |
| #ifndef BCMOS_SYSTEM_H_ |
| #error Please do not include bcmos_common2.h directly. Include bcmos_system.h |
| #endif |
| |
| #include "bcmos_endian.h" |
| |
| /* \addtogroup system |
| * @{ |
| */ |
| |
| #define BCMOS_MAX_NAME_LENGTH 48 |
| |
| /** \addtogroup system_task |
| * @{ |
| */ |
| |
| /** Task control block */ |
| struct bcmos_task |
| { |
| /* OS independent fields */ |
| bcmos_task_parm parm; /**< Task creation parameters */ |
| bcmos_module *modules[BCMOS_MAX_MODULES_PER_TASK]; |
| uint32_t active_modules; /**< Bitmask of modules for which events are pending */ |
| bcmos_sem active_sem; /**< Semaphore used to wait for module activity */ |
| bcmos_fastlock active_lock; /**< Lock protecting active_modules */ |
| bcmos_module_id current_module; /**< Current module */ |
| bcmos_bool destroy_request; /**< Task destroy request pending */ |
| bcmos_bool destroyed; /**< Set by task handler before it terminates */ |
| STAILQ_ENTRY(bcmos_task) list; /**< Next task pointer */ |
| char name[BCMOS_MAX_NAME_LENGTH]; /**< Task name */ |
| bcmos_sys_task sys_task; /**< OS-specific task extension */ |
| uint32_t magic; /* magic number */ |
| #define BCMOS_TASK_MAGIC (('t' << 24) | ('a' << 16) | ('s' << 8) | 'k') |
| #define BCMOS_TASK_MAGIC_DESTROYED (('t' << 24) | ('a' << 16) | ('s' << 8) | '~') |
| }; |
| |
| /** \addtogroup system_mem |
| * @{ |
| */ |
| |
| #ifndef BCMOS_CALLOC_INLINE |
| |
| /** Allocate memory from the main heap and clear it |
| * \ingroup system_heap |
| * \param[in] size |
| * \returns memory block pointer or NULL |
| */ |
| static inline void *bcmos_calloc(uint32_t size) |
| { |
| void *ptr = bcmos_alloc(size); |
| if (ptr) |
| memset(ptr, 0, size); |
| return ptr; |
| } |
| #endif /* #ifndef BCMOS_CALLOC_INLINE */ |
| |
| #ifndef BCMOS_DMA_ALLOC_FREE_INLINE |
| |
| /** Allocate DMA-able memory |
| * \param[in] device Device id |
| * \param[in] size Block size (bytes) |
| * \returns memory block pointer or NULL |
| */ |
| void *bcmos_dma_alloc(uint8_t device, uint32_t size); |
| |
| /** Release DMA-able memory |
| * \param[in] device Device id |
| * \param[in] ptr Block pointer |
| */ |
| void bcmos_dma_free(uint8_t device, void *ptr); |
| |
| #endif /* #ifndef BCMOS_DMA_ALLOC_FREE_INLINE */ |
| |
| #ifndef BCMOS_VIRT_TO_PHYS_INLINE |
| |
| /** Convert virtual address to physical address |
| * |
| * \param[in] va Virtual address |
| * \returns - physical address va is mapped to |
| */ |
| unsigned long bcmos_virt_to_phys(void *va); |
| |
| #endif /* #ifndef BCMOS_VIRT_TO_PHYS_INLINE */ |
| |
| /** @} */ |
| |
| /** \addtogroup blk_pool |
| * @{ |
| */ |
| |
| /* Memory block header */ |
| typedef struct bcmos_memblk bcmos_memblk; |
| |
| /* Memory block list */ |
| typedef STAILQ_HEAD(, bcmos_memblk) bcmos_memblk_list; |
| |
| /* Block memory pool control block */ |
| struct bcmos_blk_pool |
| { |
| bcmos_fastlock lock; /**< Pool protection lock */ |
| bcmos_memblk_list free_list;/**< Free block list */ |
| bcmos_blk_pool_parm parm; /**< Pool parameters */ |
| bcmos_blk_pool_stat stat; /**< Pool statistics */ |
| void *start; /**< Pool start pointer */ |
| char name[BCMOS_MAX_NAME_LENGTH]; /**< Pool name */ |
| uint32_t magic; /**< magic number */ |
| #define BCMOS_BLK_POOL_VALID (('b'<<24) | ('l' << 16) | ('p' << 8) | 'o') |
| #define BCMOS_BLK_POOL_DELETED (('b'<<24) | ('l' << 16) | ('p' << 8) | '~') |
| STAILQ_ENTRY(bcmos_blk_pool) list; /* Pool list */ |
| }; |
| |
| /* Total memory occupied by all block pools */ |
| extern uint32_t bcmos_total_blk_pool_size; |
| |
| /** @} blk_pool */ |
| |
| /** \addtogroup system_msg |
| * @{ |
| */ |
| |
| /** Release message |
| * \param[in] msg Message handle |
| */ |
| static inline void bcmos_msg_free(bcmos_msg *msg) |
| { |
| if (msg->release) |
| { |
| msg->release(msg); |
| } |
| else |
| { |
| bcmos_free(msg); |
| } |
| } |
| |
| typedef STAILQ_HEAD(, bcmos_msg) bcmos_msg_list; |
| |
| /** Simple Message queue control block. |
| * Simple message queue doesn't support waiting on. |
| * It is used in module queue mechanisms. |
| */ |
| typedef struct bcmos_msg_queue_nw |
| { |
| bcmos_msg_queue_parm parm; /**< Queue parameters */ |
| bcmos_msg_queue_stat stat; /**< Queue statistics */ |
| bcmos_fastlock lock; /**< Queue protection lock */ |
| bcmos_msg_list msgl; /**< Message list */ |
| bcmos_msg_list msgl_urg; /**< Urgent message list */ |
| uint32_t flags; /**< Queue flags */ |
| } bcmos_msg_queue_nw; |
| |
| /** Message queue control block */ |
| struct bcmos_msg_queue |
| { |
| bcmos_msg_queue_nw q; /**< Queue control block */ |
| bcmos_sem m; /**< Mutex to suspend waiting task on */ |
| bcmos_bool is_waiting; /**< TRUE if task is waiting on queue */ |
| char name[BCMOS_MAX_NAME_LENGTH]; /**< Queue name */ |
| #ifdef BCMOS_MSG_QUEUE_REMOTE_SUPPORT |
| long ep; /**< Endpoint handle (e.g., socket) */ |
| void *ep_extra_data; /**< Extra data - depending on ep type */ |
| uint32_t ep_extra_data_size;/**< Extra data size */ |
| uint8_t *send_buf; /**< Send buffer */ |
| uint8_t *recv_buf; /**< Receive buffer */ |
| bcmos_mutex send_lock; /**< Mutex that protects send_buf */ |
| #endif |
| uint32_t magic; /**< magic number */ |
| #define BCMOS_MSG_QUEUE_VALID (('m'<<24) | ('q' << 16) | ('u' << 8) | 'e') |
| #define BCMOS_MSG_QUEUE_DELETED (('m'<<24) | ('q' << 16) | ('u' << 8) | '~') |
| STAILQ_ENTRY(bcmos_msg_queue) list; /* Queue list */ |
| }; |
| |
| /** Message queue group control block */ |
| struct bcmos_msg_qgroup |
| { |
| bcmos_msg_qgroup_parm parm; /**< Queue group parameters */ |
| bcmos_msg_list *msgl; /**< Array of parm.nqueues message lists */ |
| bcmos_msg_queue_stat stat; /**< Queue group statistics */ |
| bcmos_sem m; /**< Mutex to suspend waiting task on */ |
| bcmos_fastlock lock; /**< Queue group protection lock */ |
| uint32_t active_mask; /**< Bitmask of queues containing messages */ |
| bcmos_bool is_waiting; /**< TRUE if task is waiting on queue group */ |
| char name[BCMOS_MAX_NAME_LENGTH]; /**< Queue group name */ |
| uint32_t magic; /**< magic number */ |
| #define BCMOS_MSG_QGROUP_VALID (('m'<<24) | ('q' << 16) | ('g' << 8) | 'r') |
| #define BCMOS_MSG_QGROUP_DELETED (('m'<<24) | ('q' << 16) | ('g' << 8) | '~') |
| STAILQ_ENTRY(bcmos_msg_qgroup) list; /* Queue group list */ |
| }; |
| |
| /** Message pool control block */ |
| struct bcmos_msg_pool |
| { |
| bcmos_blk_pool blk_pool; /**< Underlying block memory pool */ |
| bcmos_msg_pool_parm parm; /**< Pool parameters */ |
| }; |
| |
| /* Total memory occupied by all message pools */ |
| extern uint32_t bcmos_total_msg_pool_size; |
| |
| /** @} system_msg */ |
| |
| /** \addtogroup system_timer */ |
| |
| /* Timer precision. Must be a multiple of 2. |
| * Timed expiration timestamp is rounded up to the nearest multiple of timer precision |
| */ |
| #define BCMOS_TIMER_PRECISION_US 32 |
| #if (BCMOS_TIMER_PRECISION_US & (BCMOS_TIMER_PRECISION_US - 1)) |
| #error BCMOS_TIMER_PRECISION_US must be a multiple of 2 |
| #endif |
| |
| /* There are 2 timer implementations |
| * - DLIST-based - works well when most of active timers have the same duration |
| * - RB-tree based - more expensive in simple case, but scales better for large number of timers |
| * with arbitrary durations |
| */ |
| #define BCMOS_TIMER_RB_TREE |
| |
| /** Timer control block */ |
| struct bcmos_timer |
| { |
| bcmos_msg msg; /**< Timer message */ |
| bcmos_timer_parm parm; /**< Timer parameters */ |
| F_bcmos_timer_handler handler; /**< Timer handler */ |
| uint32_t period; /**< Timer period (us) if periodic */ |
| uint32_t expire_at; /**< Timestamp when timer should expire */ |
| uint32_t flags; /* Internal flags */ |
| #define BCMOS_TIMER_FLAG_RUNNING 0x00000001 /* Timer is running */ |
| #define BCMOS_TIMER_FLAG_EXPIRED 0x00000002 /* Timer has expired, but not yet handled */ |
| #define BCMOS_TIMER_FLAG_ACTIVE (BCMOS_TIMER_FLAG_RUNNING | BCMOS_TIMER_FLAG_EXPIRED) |
| #define BCMOS_TIMER_FLAG_VALID 0x00000004 |
| bcmos_msg_queue_nw *queue; /**< Queue expired timer is on */ |
| bcmos_task *task; /**< Task that executes timer handler */ |
| #ifdef BCMOS_TIMER_RB_TREE |
| RB_ENTRY(bcmos_timer) entry; /**< Timer pool entry */ |
| #else |
| TAILQ_ENTRY(bcmos_timer) entry; |
| #endif |
| }; |
| |
| /** Check if timer is running |
| * \param[in] timer Timer handle |
| * \returns TRUE if timer is running |
| */ |
| static inline bcmos_bool bcmos_timer_is_running(const bcmos_timer *timer) |
| { |
| bcmos_bool running = ((timer->flags & BCMOS_TIMER_FLAG_RUNNING) != 0) || |
| (timer->parm.periodic && ((timer->flags & BCMOS_TIMER_FLAG_EXPIRED) != 0)); |
| return running; |
| } |
| |
| static inline bcmos_timer *_bcmos_msg_to_timer(bcmos_msg *msg) |
| { |
| BUG_ON(msg->type != BCMOS_MSG_ID_INTERNAL_TIMER); |
| return (bcmos_timer *)msg; |
| } |
| |
| /** @} */ |
| |
| /** \addtogroup system_module |
| * @{ |
| */ |
| |
| /** Module control block */ |
| struct bcmos_module |
| { |
| bcmos_module_parm parm; /**< Module parameters */ |
| bcmos_module_id id; /**< Module id */ |
| int idx; /**< Module index in task control block */ |
| bcmos_msg_queue_nw msgq; /**< Message queue */ |
| bcmos_task *my_task; /**< Task the module is associated with */ |
| void *context; /**< User-defined context */ |
| char name[BCMOS_MAX_NAME_LENGTH]; /**< Module name */ |
| }; |
| |
| /** @} system_module */ |
| |
| /** \addtogroup system_event |
| * @{ |
| */ |
| |
| /** Event control block */ |
| struct bcmos_event |
| { |
| bcmos_msg msg; /**< Message header. Used to deliver event to module's queue */ |
| bcmos_event_id id; /**< Event set id */ |
| bcmos_event_parm parm; /**< Event parameters */ |
| bcmos_fastlock lock; /**< Protects event control block */ |
| uint32_t active_bits; /**< Active event bits */ |
| |
| bcmos_sem m; /**< Mutex to suspend task on. Traditional mode only */ |
| bcmos_bool is_waiting; /**< TRUE if task is waiting for event */ |
| char name[BCMOS_MAX_NAME_LENGTH]; /**< Event name */ |
| }; |
| |
| |
| static inline bcmos_event *_bcmos_msg_to_event(bcmos_msg *msg) |
| { |
| BUG_ON(msg->type != BCMOS_MSG_ID_INTERNAL_EVENT); |
| return (bcmos_event *)msg; |
| } |
| |
| /* |
| * Low level services |
| */ |
| |
| /** \addtogroup system_buf |
| * @{ |
| */ |
| |
| #ifndef BCMOS_BUF_OS_SPECIFIC |
| #define BCMOS_BUF_DATA_INLINE |
| #endif |
| |
| #ifdef BCMOS_BUF_INLINE |
| #define BCMOS_BUF_ALLOC_FREE_INLINE |
| #define BCMOS_BUF_DATA_INLINE |
| #endif |
| |
| #ifndef BCMOS_BUF_DATA_GUARD |
| #define BCMOS_BUF_DATA_GUARD 0 |
| #endif |
| |
| #ifndef BCMOS_BUF_DATA_ALIGNMENT |
| #define BCMOS_BUF_DATA_ALIGNMENT 64 |
| #endif |
| |
| #ifndef BCMOS_BUF_ALLOC_FREE_INLINE |
| |
| /** Allocate transport buffer. |
| * The buffer can accommodate up to size bytes of data. |
| * In addition it reserves BCMTR_BUF_EXTRA_HEADROOM headroom bytes |
| * for extra headers. |
| * |
| * \param[in] size Data size |
| * \returns buffer pointer or NULL if no memory |
| */ |
| bcmos_buf *bcmos_buf_alloc(uint32_t size); |
| |
| /** Release transport buffer allocated by bcmos_buf_alloc() |
| * |
| * \param[in] buf Buffer to be released |
| */ |
| void bcmos_buf_free(bcmos_buf *buf); |
| |
| #endif /* BCMOS_BUF_ALLOC_FREE_INLINE */ |
| |
| #ifndef BCMOS_BUF_DATA_INLINE |
| |
| /** Get data length |
| * |
| * \param[in] buf Buffer |
| * \returns data length |
| */ |
| uint32_t bcmos_buf_length(bcmos_buf *buf); |
| |
| /** Set data length |
| * |
| * \param[in] buf Buffer |
| * \param[in] length Data length |
| * \returns 0=OK, or BCM_ERR_OVERFLOW if length exceeds size |
| */ |
| bcmos_errno bcmos_buf_length_set(bcmos_buf *buf, uint32_t length); |
| |
| /** Get buffer data pointer. |
| * \param[in] buf Buffer |
| * \returns data pointer |
| */ |
| uint8_t *bcmos_buf_data(bcmos_buf *buf); |
| |
| #endif /* BCMOS_BUF_DATA_INLINE */ |
| |
| #ifndef BCMOS_BUF_OS_SPECIFIC |
| |
| #ifndef unlikely |
| #define unlikely(x) (x) |
| #endif |
| |
| /* Generic (not os-specific) sysb implementation */ |
| |
| /* |
| * Network / transport buffer |
| */ |
| |
| |
| /* Memory block list */ |
| typedef STAILQ_HEAD(, bcmos_buf) bcmos_buf_list_head; |
| |
| typedef struct |
| { |
| bcmos_buf_list_head head; /**< Buffer list head */ |
| } bcmos_buf_queue; |
| |
| /* System buffer. We probably can use mbuf as well. */ |
| struct bcmos_buf |
| { |
| uint8_t *start; |
| uint8_t *data; |
| bcmos_blk_pool *pool; |
| uint32_t size; |
| uint32_t len; |
| STAILQ_ENTRY(bcmos_buf) list; /**< Next buffer pointer */ |
| uint8_t channel; |
| }; |
| |
| |
| #ifndef BCMTR_BUF_EXTRA_HEADROOM |
| #define BCMTR_BUF_EXTRA_HEADROOM 0 |
| #endif |
| |
| |
| /** Initialize buffer queue |
| * \param[in] q Buffer queue |
| */ |
| static inline void bcmos_buf_queue_init(bcmos_buf_queue *q) |
| { |
| STAILQ_INIT(&q->head); |
| } |
| |
| /* Check if buffer queue is empty |
| * \param[in] q Buffer queue |
| * \returns TRUE if the queue is empty |
| */ |
| static inline bcmos_bool bcmos_buf_queue_is_empty(bcmos_buf_queue *q) |
| { |
| return (bcmos_bool)STAILQ_EMPTY(&q->head); |
| } |
| |
| /** Enqueue buffer |
| * |
| * Must be called under lock, e.g., q->lock |
| * |
| * \param[in] q Buffer queue |
| * \param[in] buf Buffer |
| */ |
| static inline void bcmos_buf_queue_put(bcmos_buf_queue *q, bcmos_buf *buf) |
| { |
| STAILQ_INSERT_TAIL(&q->head, buf, list); |
| } |
| |
| /* Dequeue buffer |
| * |
| * Must be called under lock, e.g., q->lock |
| * |
| * Remove and return the 1st queued buffer. |
| * \param[in] q Buffer queue |
| * \returns the buffer pointer |
| */ |
| static inline bcmos_buf *bcmos_buf_queue_get(bcmos_buf_queue *q) |
| { |
| bcmos_buf *buf; |
| buf = STAILQ_FIRST(&q->head); |
| if (buf) |
| STAILQ_REMOVE_HEAD(&q->head, list); |
| return buf; |
| } |
| |
| /* Peek into queue and return the 1st buffer without dequeing it |
| * |
| * Must be called under lock, e.g., q->lock |
| * \param[in] q Buffer queue |
| * \returns the buffer pointer |
| */ |
| static inline bcmos_buf *bcmos_buf_queue_peek(bcmos_buf_queue *q) |
| { |
| return STAILQ_FIRST(&q->head); |
| } |
| |
| /* Initialize buffer */ |
| static inline bcmos_buf *bcmos_buf_init(bcmos_buf *buf, uint8_t *start, |
| uint8_t *data, uint32_t size, uint32_t len) |
| { |
| BUG_ON((void *)(buf +1) != start); |
| buf->start = start; |
| buf->data = data; |
| buf->size = size; |
| buf->len = len; |
| buf->pool = NULL; |
| return buf; |
| } |
| |
| /* Get data length */ |
| static inline uint32_t bcmos_buf_length(bcmos_buf *buf) |
| { |
| return buf->len; |
| } |
| |
| /* Set data length */ |
| static inline bcmos_errno bcmos_buf_length_set(bcmos_buf *buf, uint32_t length) |
| { |
| if (unlikely(length > buf->size - (buf->data - buf->start))) |
| { |
| BCMOS_TRACE_ERR("!!!%s: length=%u size=%u data=%p start=%p data-start=%u\n", |
| __FUNCTION__, length, buf->size, buf->data, buf->start, (uint32_t)(buf->data - buf->start)); |
| return BCM_ERR_OVERFLOW; |
| } |
| buf->len = length; |
| return BCM_ERR_OK; |
| } |
| |
| /* Get buffer data pointer. */ |
| static inline uint8_t *bcmos_buf_data(bcmos_buf *buf) |
| { |
| return buf->data; |
| } |
| |
| /* Get buffer channel. */ |
| static inline uint8_t bcmos_buf_channel(bcmos_buf *buf) |
| { |
| return buf->channel; |
| } |
| |
| /* Set buffer channel. */ |
| static inline void bcmos_buf_channel_set(bcmos_buf *buf, uint8_t channel) |
| { |
| buf->channel = channel; |
| } |
| |
| #endif /* #ifndef BCMOS_BUF_OS_SPECIFIC */ |
| |
| /** @} bcmos_buf */ |
| |
| /** \addtogroup system_cache |
| * @{ |
| */ |
| |
| #ifndef BCMOS_CACHE_INLINE |
| |
| /** Invalidate address area in data cache. Dirty cache lines content is discarded. |
| * \param[in] start Address area start |
| * \param[in] size Address area size |
| */ |
| void bcmos_dcache_inv(void *start, uint32_t size); |
| |
| /** Flush address area in data cache. Dirty cache lines are committed to memory. |
| * \param[in] start Address area start |
| * \param[in] size Address area size |
| */ |
| void bcmos_dcache_flush(void *start, uint32_t size); |
| |
| #endif /* BCMOS_CACHE_INLINE */ |
| |
| /** Prepare for DMA write. |
| * On h/w platforms that support DMA-cache coherency, this function should |
| * perform write barrier. |
| * On platforms that don't support DMA cache coherency this function should |
| * flush the relevant dcache area |
| * |
| * \param[in] start DMA buffer start address |
| * \param[in] size DMA buffer size |
| */ |
| static inline void bcmos_prepare_for_dma_write(void *start, uint32_t size) |
| { |
| #ifdef BCMOS_DMA_CACHE_COHERENCY |
| bcmos_barrier(); |
| #else |
| bcmos_dcache_flush(start, size); |
| #endif |
| } |
| |
| /** Prepare for DMA read. |
| * On h/w platforms that support DMA-cache coherency, this function should |
| * perform write barrier. |
| * On platforms that don't support DMA cache coherency this function should |
| * invalidate the relevant dcache area |
| * |
| * \param[in] start DMA buffer start address |
| * \param[in] size DMA buffer size |
| */ |
| static inline void bcmos_prepare_for_dma_read(void *start, uint32_t size) |
| { |
| #ifdef BCMOS_DMA_CACHE_COHERENCY |
| bcmos_barrier(); |
| #else |
| bcmos_dcache_inv(start, size); |
| #endif |
| } |
| |
| /** @} system_cache */ |
| |
| /** \addtogroup system_interrupt |
| * @{ |
| */ |
| |
| #ifdef BCMOS_INTERRUPT_INLINE |
| #define BCMOS_INTERRUPT_CONNECT_DISCONNECT_INLINE |
| #define BCMOS_INTERRUPT_ENABLE_DISABLE_INLINE |
| #endif |
| |
| #ifndef BCMOS_INTERRUPT_CONNECT_DISCONNECT_INLINE |
| /** Connect system interrupt |
| * \param[in] irq IRQ number |
| * \param[in] cpu CPU number (for SMP) |
| * \param[in] flags IRQ flags |
| * \param[in] isr ISR |
| * \param[in] name device name |
| * \param[in] priv Private cookie |
| * \returns 0=OK, <0- error |
| */ |
| int bcmos_int_connect(int irq, int cpu, int flags, |
| int (*isr)(int irq, void *priv), const char *name, void *priv); |
| |
| /** Disconnect system interrupt |
| * \param[in] irq IRQ number |
| * \param[in] priv Private cookie passed in bcmos_int_connect() |
| * \returns 0=OK, <0- error |
| */ |
| void bcmos_int_disconnect(int irq, void *priv); |
| #endif |
| |
| #ifndef BCMOS_INTERRUPT_ENABLE_DISABLE_INLINE |
| /** Unmask IRQ |
| * \param[in] irq IRQ |
| */ |
| void bcmos_int_enable(int irq); |
| |
| /** Mask IRQ |
| * \param[in] irq IRQ |
| */ |
| void bcmos_int_disable(int irq); |
| #endif |
| |
| /** @} */ |
| |
| /* Get char, put char support */ |
| #ifndef BCMOS_GETCHAR_INLINE |
| static inline int bcmos_getchar(void) |
| { |
| return getchar(); |
| } |
| #endif |
| |
| #ifndef BCMOS_PUTCHAR_INLINE |
| void bcmos_putchar(int c); |
| #endif |
| |
| #ifndef BCMOS_SEM_POST_IS_ALLOWED_INLINE |
| static inline bcmos_bool bcmos_sem_post_is_allowed(void) |
| { |
| return BCMOS_TRUE; |
| } |
| #endif |
| |
| #endif /* BCMOS_COMMON2_H_ */ |