1ef270ab1SKenneth D. Merry /*-
2ef270ab1SKenneth D. Merry * Copyright (c) 2017 Broadcom. All rights reserved.
3ef270ab1SKenneth D. Merry * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
4ef270ab1SKenneth D. Merry *
5ef270ab1SKenneth D. Merry * Redistribution and use in source and binary forms, with or without
6ef270ab1SKenneth D. Merry * modification, are permitted provided that the following conditions are met:
7ef270ab1SKenneth D. Merry *
8ef270ab1SKenneth D. Merry * 1. Redistributions of source code must retain the above copyright notice,
9ef270ab1SKenneth D. Merry * this list of conditions and the following disclaimer.
10ef270ab1SKenneth D. Merry *
11ef270ab1SKenneth D. Merry * 2. Redistributions in binary form must reproduce the above copyright notice,
12ef270ab1SKenneth D. Merry * this list of conditions and the following disclaimer in the documentation
13ef270ab1SKenneth D. Merry * and/or other materials provided with the distribution.
14ef270ab1SKenneth D. Merry *
15ef270ab1SKenneth D. Merry * 3. Neither the name of the copyright holder nor the names of its contributors
16ef270ab1SKenneth D. Merry * may be used to endorse or promote products derived from this software
17ef270ab1SKenneth D. Merry * without specific prior written permission.
18ef270ab1SKenneth D. Merry *
19ef270ab1SKenneth D. Merry * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20ef270ab1SKenneth D. Merry * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21ef270ab1SKenneth D. Merry * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22ef270ab1SKenneth D. Merry * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23ef270ab1SKenneth D. Merry * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24ef270ab1SKenneth D. Merry * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25ef270ab1SKenneth D. Merry * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26ef270ab1SKenneth D. Merry * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27ef270ab1SKenneth D. Merry * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28ef270ab1SKenneth D. Merry * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29ef270ab1SKenneth D. Merry * POSSIBILITY OF SUCH DAMAGE.
30ef270ab1SKenneth D. Merry */
31ef270ab1SKenneth D. Merry
32ef270ab1SKenneth D. Merry /**
33ef270ab1SKenneth D. Merry * @file
34ef270ab1SKenneth D. Merry * bsd specific headers common to the driver
35ef270ab1SKenneth D. Merry */
36ef270ab1SKenneth D. Merry
37ef270ab1SKenneth D. Merry #ifndef _OCS_OS_H
38ef270ab1SKenneth D. Merry #define _OCS_OS_H
39ef270ab1SKenneth D. Merry
40ef270ab1SKenneth D. Merry /***************************************************************************
41ef270ab1SKenneth D. Merry * OS specific includes
42ef270ab1SKenneth D. Merry */
435eaf9435SRam Kishore Vegesna #include "opt_stack.h"
445eaf9435SRam Kishore Vegesna
45ef270ab1SKenneth D. Merry #include <sys/param.h>
46ef270ab1SKenneth D. Merry #include <sys/systm.h>
47ef270ab1SKenneth D. Merry #include <sys/malloc.h>
48ef270ab1SKenneth D. Merry #include <sys/kernel.h>
49ef270ab1SKenneth D. Merry #include <sys/module.h>
50ef270ab1SKenneth D. Merry #include <sys/bus.h>
51ef270ab1SKenneth D. Merry #include <sys/rman.h>
52ef270ab1SKenneth D. Merry #include <sys/endian.h>
53ef270ab1SKenneth D. Merry #include <sys/stddef.h>
54ef270ab1SKenneth D. Merry #include <sys/lock.h>
55ef270ab1SKenneth D. Merry #include <sys/mutex.h>
56ef270ab1SKenneth D. Merry #include <sys/taskqueue.h>
57ef270ab1SKenneth D. Merry #include <sys/bitstring.h>
58ef270ab1SKenneth D. Merry #include <sys/stack.h>
59ef270ab1SKenneth D. Merry
60ef270ab1SKenneth D. Merry #include <machine/atomic.h>
61ef270ab1SKenneth D. Merry #include <machine/bus.h>
62ef270ab1SKenneth D. Merry #include <machine/stdarg.h>
63ef270ab1SKenneth D. Merry
64ef270ab1SKenneth D. Merry #include <dev/pci/pcivar.h>
65ef270ab1SKenneth D. Merry
66ef270ab1SKenneth D. Merry #include <sys/sema.h>
67ef270ab1SKenneth D. Merry #include <sys/time.h>
68ef270ab1SKenneth D. Merry
69ef270ab1SKenneth D. Merry #include <sys/proc.h>
70ef270ab1SKenneth D. Merry #include <sys/kthread.h>
71ef270ab1SKenneth D. Merry #include <sys/unistd.h>
72ef270ab1SKenneth D. Merry #include <sys/sched.h>
73ef270ab1SKenneth D. Merry
74ef270ab1SKenneth D. Merry #include <sys/conf.h>
75ef270ab1SKenneth D. Merry #include <sys/sysctl.h>
76ef270ab1SKenneth D. Merry #include <sys/ioccom.h>
77ef270ab1SKenneth D. Merry #include <sys/ctype.h>
78ef270ab1SKenneth D. Merry
795eaf9435SRam Kishore Vegesna #include <sys/linker.h> /* for debug of memory allocations */
805eaf9435SRam Kishore Vegesna
81ef270ab1SKenneth D. Merry /* OCS_OS_MAX_ISR_TIME_MSEC - maximum time driver code should spend in an interrupt
82ef270ab1SKenneth D. Merry * or kernel thread context without yielding
83ef270ab1SKenneth D. Merry */
84ef270ab1SKenneth D. Merry #define OCS_OS_MAX_ISR_TIME_MSEC 1000
85ef270ab1SKenneth D. Merry
86ef270ab1SKenneth D. Merry /* BSD driver specific definitions */
87ef270ab1SKenneth D. Merry
88ef270ab1SKenneth D. Merry #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
89ef270ab1SKenneth D. Merry
90ef270ab1SKenneth D. Merry #define OCS_MAX_LUN 512
91ef270ab1SKenneth D. Merry #define OCS_NUM_UNSOLICITED_FRAMES 1024
92ef270ab1SKenneth D. Merry
93ef270ab1SKenneth D. Merry #define OCS_MAX_DOMAINS 1
94ef270ab1SKenneth D. Merry #define OCS_MAX_REMOTE_NODES 2048
95ef270ab1SKenneth D. Merry #define OCS_MAX_TARGETS 1024
96ef270ab1SKenneth D. Merry #define OCS_MAX_INITIATORS 1024
97ef270ab1SKenneth D. Merry /** Reserve this number of IO for each intiator to return FULL/BUSY status */
98ef270ab1SKenneth D. Merry #define OCS_RSVD_INI_IO 8
99ef270ab1SKenneth D. Merry
100ef270ab1SKenneth D. Merry #define OCS_MIN_DMA_ALIGNMENT 16
1017b56cb04SGordon Bergling #define OCS_MAX_DMA_ALLOC (64*1024) /* maximum DMA allocation that is expected to reliably succeed */
102ef270ab1SKenneth D. Merry
103ef270ab1SKenneth D. Merry /*
104ef270ab1SKenneth D. Merry * Macros used to size the CQ hash table. We want to round up to the next
105ef270ab1SKenneth D. Merry * power of 2 for the hash.
106ef270ab1SKenneth D. Merry */
107ef270ab1SKenneth D. Merry #define B2(x) ( (x) | ( (x) >> 1) )
108ef270ab1SKenneth D. Merry #define B4(x) ( B2(x) | ( B2(x) >> 2) )
109ef270ab1SKenneth D. Merry #define B8(x) ( B4(x) | ( B4(x) >> 4) )
110ef270ab1SKenneth D. Merry #define B16(x) ( B8(x) | ( B8(x) >> 8) )
111ef270ab1SKenneth D. Merry #define B32(x) (B16(x) | (B16(x) >>16) )
112ef270ab1SKenneth D. Merry #define B32_NEXT_POWER_OF_2(x) (B32((x)-1) + 1)
113ef270ab1SKenneth D. Merry
114ef270ab1SKenneth D. Merry /*
115ef270ab1SKenneth D. Merry * likely/unlikely - branch prediction hint
116ef270ab1SKenneth D. Merry */
117ef270ab1SKenneth D. Merry #define likely(x) __builtin_expect(!!(x), 1)
118ef270ab1SKenneth D. Merry #define unlikely(x) __builtin_expect(!!(x), 0)
119ef270ab1SKenneth D. Merry
120ef270ab1SKenneth D. Merry /***************************************************************************
121ef270ab1SKenneth D. Merry * OS abstraction
122ef270ab1SKenneth D. Merry */
123ef270ab1SKenneth D. Merry
124ef270ab1SKenneth D. Merry /**
125ef270ab1SKenneth D. Merry * @brief Min/Max macros
126ef270ab1SKenneth D. Merry *
127ef270ab1SKenneth D. Merry */
128ef270ab1SKenneth D. Merry #define OCS_MAX(x, y) ((x) > (y) ? (x) : (y))
129ef270ab1SKenneth D. Merry #define OCS_MIN(x, y) ((x) < (y) ? (x) : (y))
130ef270ab1SKenneth D. Merry
131ef270ab1SKenneth D. Merry #define PRIX64 "lX"
132ef270ab1SKenneth D. Merry #define PRIx64 "lx"
133ef270ab1SKenneth D. Merry #define PRId64 "ld"
134ef270ab1SKenneth D. Merry #define PRIu64 "lu"
135ef270ab1SKenneth D. Merry
136ef270ab1SKenneth D. Merry /**
137ef270ab1SKenneth D. Merry * Enable optional features
138ef270ab1SKenneth D. Merry * - OCS_INCLUDE_DEBUG include low-level SLI debug support
139ef270ab1SKenneth D. Merry */
140ef270ab1SKenneth D. Merry #define OCS_INCLUDE_DEBUG
141ef270ab1SKenneth D. Merry
142ef270ab1SKenneth D. Merry /**
143ef270ab1SKenneth D. Merry * @brief Set the Nth bit
144ef270ab1SKenneth D. Merry *
145ef270ab1SKenneth D. Merry * @todo move to a private file used internally?
146ef270ab1SKenneth D. Merry */
147ef270ab1SKenneth D. Merry #ifndef BIT
148ef270ab1SKenneth D. Merry #define BIT(n) (1U << (n))
149ef270ab1SKenneth D. Merry #endif
150ef270ab1SKenneth D. Merry
151ef270ab1SKenneth D. Merry /***************************************************************************
152ef270ab1SKenneth D. Merry * Platform specific operations
153ef270ab1SKenneth D. Merry */
154ef270ab1SKenneth D. Merry
1555eaf9435SRam Kishore Vegesna typedef struct ocs_softc ocs_t;
1565eaf9435SRam Kishore Vegesna
157ef270ab1SKenneth D. Merry /**
158ef270ab1SKenneth D. Merry * @ingroup os
159ef270ab1SKenneth D. Merry * @typedef ocs_os_handle_t
160ef270ab1SKenneth D. Merry * @brief OS specific handle or driver context
161ef270ab1SKenneth D. Merry *
162ef270ab1SKenneth D. Merry * This can be anything from a void * to some other OS specific type. The lower
163ef270ab1SKenneth D. Merry * layers make no assumption about its value and pass it back as the first
164ef270ab1SKenneth D. Merry * parameter to most OS functions.
165ef270ab1SKenneth D. Merry */
166ef270ab1SKenneth D. Merry typedef ocs_t * ocs_os_handle_t;
167ef270ab1SKenneth D. Merry
168ef270ab1SKenneth D. Merry /**
169ef270ab1SKenneth D. Merry * @ingroup os
170ef270ab1SKenneth D. Merry * @brief return the lower 32-bits of a bus address
171ef270ab1SKenneth D. Merry *
172ef270ab1SKenneth D. Merry * @param addr Physical or bus address to convert
173ef270ab1SKenneth D. Merry * @return lower 32-bits of a bus address
174ef270ab1SKenneth D. Merry *
175ef270ab1SKenneth D. Merry * @note this may be a good cadidate for an inline or macro
176ef270ab1SKenneth D. Merry */
ocs_addr32_lo(uintptr_t addr)177ef270ab1SKenneth D. Merry static inline uint32_t ocs_addr32_lo(uintptr_t addr)
178ef270ab1SKenneth D. Merry {
179ef270ab1SKenneth D. Merry #if defined(__LP64__)
180ef270ab1SKenneth D. Merry return (uint32_t)(addr & 0xffffffffUL);
181ef270ab1SKenneth D. Merry #else
182ef270ab1SKenneth D. Merry return addr;
183ef270ab1SKenneth D. Merry #endif
184ef270ab1SKenneth D. Merry }
185ef270ab1SKenneth D. Merry
186ef270ab1SKenneth D. Merry /**
187ef270ab1SKenneth D. Merry * @ingroup os
188ef270ab1SKenneth D. Merry * @brief return the upper 32-bits of a bus address
189ef270ab1SKenneth D. Merry *
190ef270ab1SKenneth D. Merry * @param addr Physical or bus address to convert
191ef270ab1SKenneth D. Merry * @return upper 32-bits of a bus address
192ef270ab1SKenneth D. Merry *
193ef270ab1SKenneth D. Merry * @note this may be a good cadidate for an inline or macro
194ef270ab1SKenneth D. Merry */
ocs_addr32_hi(uintptr_t addr)195ef270ab1SKenneth D. Merry static inline uint32_t ocs_addr32_hi(uintptr_t addr)
196ef270ab1SKenneth D. Merry {
197ef270ab1SKenneth D. Merry #if defined(__LP64__)
198ef270ab1SKenneth D. Merry return (uint32_t)(addr >> 32);
199ef270ab1SKenneth D. Merry #else
200ef270ab1SKenneth D. Merry return 0;
201ef270ab1SKenneth D. Merry #endif
202ef270ab1SKenneth D. Merry }
203ef270ab1SKenneth D. Merry
204ef270ab1SKenneth D. Merry /**
205ef270ab1SKenneth D. Merry * @ingroup os
206ef270ab1SKenneth D. Merry * @brief return the log2(val)
207ef270ab1SKenneth D. Merry *
208ef270ab1SKenneth D. Merry * @param val number to use (assumed to be exact power of 2)
209ef270ab1SKenneth D. Merry *
210ef270ab1SKenneth D. Merry * @return log base 2 of val
211ef270ab1SKenneth D. Merry */
ocs_lg2(uint32_t val)212ef270ab1SKenneth D. Merry static inline uint32_t ocs_lg2(uint32_t val)
213ef270ab1SKenneth D. Merry {
214ef270ab1SKenneth D. Merry #if defined(__GNUC__)
215ef270ab1SKenneth D. Merry /*
216ef270ab1SKenneth D. Merry * clz = "count leading zero's"
217ef270ab1SKenneth D. Merry *
218ef270ab1SKenneth D. Merry * Assuming val is an exact power of 2, the most significant bit
219ef270ab1SKenneth D. Merry * will be the log base 2 of val
220ef270ab1SKenneth D. Merry */
221ef270ab1SKenneth D. Merry return 31 - __builtin_clz(val);
222ef270ab1SKenneth D. Merry #else
223ef270ab1SKenneth D. Merry #error You need to provide a non-GCC version of this function
224ef270ab1SKenneth D. Merry #endif
225ef270ab1SKenneth D. Merry }
226ef270ab1SKenneth D. Merry
227ef270ab1SKenneth D. Merry /**
228ef270ab1SKenneth D. Merry * @ingroup os
229ef270ab1SKenneth D. Merry * @brief optimization barrier
230ef270ab1SKenneth D. Merry *
231ef270ab1SKenneth D. Merry * Optimization barrier. Prevents compiler re-ordering
232ef270ab1SKenneth D. Merry * instructions across barrier.
233ef270ab1SKenneth D. Merry *
234ef270ab1SKenneth D. Merry * @return none
235ef270ab1SKenneth D. Merry */
236ef270ab1SKenneth D. Merry #define ocs_barrier() __asm __volatile("" : : : "memory");
237ef270ab1SKenneth D. Merry
238ef270ab1SKenneth D. Merry /**
239ef270ab1SKenneth D. Merry * @ingroup os
240ef270ab1SKenneth D. Merry * @brief convert a big endian 32 bit value to the host's native format
241ef270ab1SKenneth D. Merry *
242ef270ab1SKenneth D. Merry * @param val 32 bit big endian value
243ef270ab1SKenneth D. Merry *
244ef270ab1SKenneth D. Merry * @return value converted to the host's native endianness
245ef270ab1SKenneth D. Merry */
246ef270ab1SKenneth D. Merry #define ocs_be32toh(val) be32toh(val)
247ef270ab1SKenneth D. Merry
248ef270ab1SKenneth D. Merry /**
249ef270ab1SKenneth D. Merry * @ingroup os
250ef270ab1SKenneth D. Merry * @brief convert a 32 bit value from the host's native format to big endian
251ef270ab1SKenneth D. Merry *
252ef270ab1SKenneth D. Merry * @param val 32 bit native endian value
253ef270ab1SKenneth D. Merry *
254ef270ab1SKenneth D. Merry * @return value converted to big endian
255ef270ab1SKenneth D. Merry */
256ef270ab1SKenneth D. Merry #define ocs_htobe32(val) htobe32(val)
257ef270ab1SKenneth D. Merry
258ef270ab1SKenneth D. Merry /**
259ef270ab1SKenneth D. Merry * @ingroup os
260ef270ab1SKenneth D. Merry * @brief convert a 16 bit value from the host's native format to big endian
261ef270ab1SKenneth D. Merry *
262ef270ab1SKenneth D. Merry * @param v 16 bit native endian value
263ef270ab1SKenneth D. Merry *
264ef270ab1SKenneth D. Merry * @return value converted to big endian
265ef270ab1SKenneth D. Merry */
266ef270ab1SKenneth D. Merry #define ocs_htobe16(v) htobe16(v)
267ef270ab1SKenneth D. Merry #define ocs_be16toh(v) be16toh(v)
268ef270ab1SKenneth D. Merry
269ef270ab1SKenneth D. Merry #define ocs_htobe64(v) htobe64(v)
270ef270ab1SKenneth D. Merry #define ocs_be64toh(v) be64toh(v)
271ef270ab1SKenneth D. Merry
272ef270ab1SKenneth D. Merry /**
273ef270ab1SKenneth D. Merry * @ingroup os
274ef270ab1SKenneth D. Merry * @brief Delay execution by the given number of micro-seconds
275ef270ab1SKenneth D. Merry *
276ef270ab1SKenneth D. Merry * @param usec number of micro-seconds to "busy-wait"
277ef270ab1SKenneth D. Merry *
278ef270ab1SKenneth D. Merry * @note The value of usec may be greater than 1,000,000
279ef270ab1SKenneth D. Merry */
280ef270ab1SKenneth D. Merry #define ocs_udelay(usec) DELAY(usec)
281ef270ab1SKenneth D. Merry
282ef270ab1SKenneth D. Merry /**
283ef270ab1SKenneth D. Merry * @ingroup os
284ef270ab1SKenneth D. Merry * @brief Delay execution by the given number of milli-seconds
285ef270ab1SKenneth D. Merry *
286ef270ab1SKenneth D. Merry * @param msec number of milli-seconds to "busy-wait"
287ef270ab1SKenneth D. Merry *
288ef270ab1SKenneth D. Merry * @note The value of usec may be greater than 1,000,000
289ef270ab1SKenneth D. Merry */
290ef270ab1SKenneth D. Merry #define ocs_msleep(msec) ocs_udelay((msec)*1000)
291ef270ab1SKenneth D. Merry
292ef270ab1SKenneth D. Merry /**
293ef270ab1SKenneth D. Merry * @ingroup os
294ef270ab1SKenneth D. Merry * @brief Get time of day in msec
295ef270ab1SKenneth D. Merry *
296ef270ab1SKenneth D. Merry * @return time of day in msec
297ef270ab1SKenneth D. Merry */
298ef270ab1SKenneth D. Merry static inline time_t
ocs_msectime(void)299ef270ab1SKenneth D. Merry ocs_msectime(void)
300ef270ab1SKenneth D. Merry {
301ef270ab1SKenneth D. Merry struct timeval tv;
302ef270ab1SKenneth D. Merry
303ef270ab1SKenneth D. Merry getmicrotime(&tv);
304ef270ab1SKenneth D. Merry return (tv.tv_sec*1000) + (tv.tv_usec / 1000);
305ef270ab1SKenneth D. Merry }
306ef270ab1SKenneth D. Merry
307ef270ab1SKenneth D. Merry /**
308ef270ab1SKenneth D. Merry * @ingroup os
309ef270ab1SKenneth D. Merry * @brief Copy length number of bytes from the source to destination address
310ef270ab1SKenneth D. Merry *
311ef270ab1SKenneth D. Merry * @param d pointer to the destination memory
312ef270ab1SKenneth D. Merry * @param s pointer to the source memory
313ef270ab1SKenneth D. Merry * @param l number of bytes to copy
314ef270ab1SKenneth D. Merry *
315ef270ab1SKenneth D. Merry * @return original value of dst pointer
316ef270ab1SKenneth D. Merry */
317ef270ab1SKenneth D. Merry #define ocs_memcpy(d, s, l) memcpy(d, s, l)
318ef270ab1SKenneth D. Merry
319ef270ab1SKenneth D. Merry #define ocs_strlen(s) strlen(s)
320ef270ab1SKenneth D. Merry #define ocs_strcpy(d,s) strcpy(d, s)
321ef270ab1SKenneth D. Merry #define ocs_strncpy(d,s, n) strncpy(d, s, n)
322ef270ab1SKenneth D. Merry #define ocs_strcat(d, s) strcat(d, s)
323ef270ab1SKenneth D. Merry #define ocs_strtoul(s,ep,b) strtoul(s,ep,b)
324ef270ab1SKenneth D. Merry #define ocs_strtoull(s,ep,b) ((uint64_t)strtouq(s,ep,b))
325ef270ab1SKenneth D. Merry #define ocs_atoi(s) strtol(s, 0, 0)
326ef270ab1SKenneth D. Merry #define ocs_strcmp(d,s) strcmp(d,s)
327ef270ab1SKenneth D. Merry #define ocs_strcasecmp(d,s) strcasecmp(d,s)
328ef270ab1SKenneth D. Merry #define ocs_strncmp(d,s,n) strncmp(d,s,n)
329ef270ab1SKenneth D. Merry #define ocs_strstr(h,n) strstr(h,n)
330ef270ab1SKenneth D. Merry #define ocs_strsep(h, n) strsep(h, n)
331ef270ab1SKenneth D. Merry #define ocs_strchr(s,c) strchr(s,c)
332ef270ab1SKenneth D. Merry #define ocs_copy_from_user(dst, src, n) copyin(src, dst, n)
333ef270ab1SKenneth D. Merry #define ocs_copy_to_user(dst, src, n) copyout(src, dst, n)
334ef270ab1SKenneth D. Merry #define ocs_snprintf(buf, n, fmt, ...) snprintf(buf, n, fmt, ##__VA_ARGS__)
335ef270ab1SKenneth D. Merry #define ocs_vsnprintf(buf, n, fmt, ap) vsnprintf((char*)buf, n, fmt, ap)
336ef270ab1SKenneth D. Merry #define ocs_sscanf(buf,fmt, ...) sscanf(buf, fmt, ##__VA_ARGS__)
337ef270ab1SKenneth D. Merry #define ocs_printf printf
338ef270ab1SKenneth D. Merry #define ocs_isspace(c) isspace(c)
339ef270ab1SKenneth D. Merry #define ocs_isdigit(c) isdigit(c)
340ef270ab1SKenneth D. Merry #define ocs_isxdigit(c) isxdigit(c)
341ef270ab1SKenneth D. Merry
342ef270ab1SKenneth D. Merry extern uint64_t ocs_get_tsc(void);
343ef270ab1SKenneth D. Merry extern void *ocs_ioctl_preprocess(ocs_os_handle_t os, void *arg, size_t size);
344ef270ab1SKenneth D. Merry extern int32_t ocs_ioctl_postprocess(ocs_os_handle_t os, void *arg, void *kern_ptr, size_t size);
345ef270ab1SKenneth D. Merry extern void ocs_ioctl_free(ocs_os_handle_t os, void *kern_ptr, size_t size);
346ef270ab1SKenneth D. Merry extern char *ocs_strdup(const char *s);
347ef270ab1SKenneth D. Merry
348ef270ab1SKenneth D. Merry /**
349ef270ab1SKenneth D. Merry * @ingroup os
350ef270ab1SKenneth D. Merry * @brief Set the value of each byte in memory
351ef270ab1SKenneth D. Merry *
352ef270ab1SKenneth D. Merry * @param b pointer to the memory
353ef270ab1SKenneth D. Merry * @param c value used to set memory
354ef270ab1SKenneth D. Merry * @param l number of bytes to set
355ef270ab1SKenneth D. Merry *
356ef270ab1SKenneth D. Merry * @return original value of mem pointer
357ef270ab1SKenneth D. Merry */
358ef270ab1SKenneth D. Merry #define ocs_memset(b, c, l) memset(b, c, l)
359ef270ab1SKenneth D. Merry
360ef270ab1SKenneth D. Merry #define LOG_CRIT 0
361ef270ab1SKenneth D. Merry #define LOG_ERR 1
362ef270ab1SKenneth D. Merry #define LOG_WARN 2
363ef270ab1SKenneth D. Merry #define LOG_INFO 3
364ef270ab1SKenneth D. Merry #define LOG_TEST 4
365ef270ab1SKenneth D. Merry #define LOG_DEBUG 5
366ef270ab1SKenneth D. Merry
367ef270ab1SKenneth D. Merry extern int loglevel;
368ef270ab1SKenneth D. Merry
369ef270ab1SKenneth D. Merry extern void _ocs_log(ocs_t *ocs, const char *func, int line, const char *fmt, ...);
370ef270ab1SKenneth D. Merry
371ef270ab1SKenneth D. Merry #define ocs_log_crit(os, fmt, ...) ocs_log(os, LOG_CRIT, fmt, ##__VA_ARGS__);
372ef270ab1SKenneth D. Merry #define ocs_log_err(os, fmt, ...) ocs_log(os, LOG_ERR, fmt, ##__VA_ARGS__);
373ef270ab1SKenneth D. Merry #define ocs_log_warn(os, fmt, ...) ocs_log(os, LOG_WARN, fmt, ##__VA_ARGS__);
374ef270ab1SKenneth D. Merry #define ocs_log_info(os, fmt, ...) ocs_log(os, LOG_INFO, fmt, ##__VA_ARGS__);
375ef270ab1SKenneth D. Merry #define ocs_log_test(os, fmt, ...) ocs_log(os, LOG_TEST, fmt, ##__VA_ARGS__);
376ef270ab1SKenneth D. Merry #define ocs_log_debug(os, fmt, ...) ocs_log(os, LOG_DEBUG, fmt, ##__VA_ARGS__);
377ef270ab1SKenneth D. Merry
378ef270ab1SKenneth D. Merry #define ocs_log(os, level, fmt, ...) \
379ef270ab1SKenneth D. Merry do { \
380ef270ab1SKenneth D. Merry if (level <= loglevel) { \
381ef270ab1SKenneth D. Merry _ocs_log(os, __func__, __LINE__, fmt, ##__VA_ARGS__); \
382ef270ab1SKenneth D. Merry } \
383ef270ab1SKenneth D. Merry } while (0)
384ef270ab1SKenneth D. Merry
ocs_roundup(uint32_t x,uint32_t y)385ef270ab1SKenneth D. Merry static inline uint32_t ocs_roundup(uint32_t x, uint32_t y)
386ef270ab1SKenneth D. Merry {
387ef270ab1SKenneth D. Merry return (((x + y - 1) / y) * y);
388ef270ab1SKenneth D. Merry }
389ef270ab1SKenneth D. Merry
ocs_rounddown(uint32_t x,uint32_t y)390ef270ab1SKenneth D. Merry static inline uint32_t ocs_rounddown(uint32_t x, uint32_t y)
391ef270ab1SKenneth D. Merry {
392ef270ab1SKenneth D. Merry return ((x / y) * y);
393ef270ab1SKenneth D. Merry }
394ef270ab1SKenneth D. Merry
395ef270ab1SKenneth D. Merry /***************************************************************************
396ef270ab1SKenneth D. Merry * Memory allocation interfaces
397ef270ab1SKenneth D. Merry */
398ef270ab1SKenneth D. Merry
399ef270ab1SKenneth D. Merry #define OCS_M_ZERO M_ZERO
400ef270ab1SKenneth D. Merry #define OCS_M_NOWAIT M_NOWAIT
401ef270ab1SKenneth D. Merry
402ef270ab1SKenneth D. Merry /**
403ef270ab1SKenneth D. Merry * @ingroup os
404ef270ab1SKenneth D. Merry * @brief Allocate host memory
405ef270ab1SKenneth D. Merry *
406ef270ab1SKenneth D. Merry * @param os OS handle
407ef270ab1SKenneth D. Merry * @param size number of bytes to allocate
408ef270ab1SKenneth D. Merry * @param flags additional options
409ef270ab1SKenneth D. Merry *
410ef270ab1SKenneth D. Merry * Flags include
411ef270ab1SKenneth D. Merry * - OCS_M_ZERO zero memory after allocating
412ef270ab1SKenneth D. Merry * - OCS_M_NOWAIT do not block/sleep waiting for an allocation request
413ef270ab1SKenneth D. Merry *
414ef270ab1SKenneth D. Merry * @return pointer to allocated memory, NULL otherwise
415ef270ab1SKenneth D. Merry */
416ef270ab1SKenneth D. Merry extern void *ocs_malloc(ocs_os_handle_t os, size_t size, int32_t flags);
417ef270ab1SKenneth D. Merry
418ef270ab1SKenneth D. Merry /**
419ef270ab1SKenneth D. Merry * @ingroup os
420ef270ab1SKenneth D. Merry * @brief Free host memory
421ef270ab1SKenneth D. Merry *
422ef270ab1SKenneth D. Merry * @param os OS handle
423ef270ab1SKenneth D. Merry * @param addr pointer to memory
424ef270ab1SKenneth D. Merry * @param size bytes to free
425ef270ab1SKenneth D. Merry */
426ef270ab1SKenneth D. Merry extern void ocs_free(ocs_os_handle_t os, void *addr, size_t size);
427ef270ab1SKenneth D. Merry
428ef270ab1SKenneth D. Merry /**
429ef270ab1SKenneth D. Merry * @ingroup os
430ef270ab1SKenneth D. Merry * @brief generic DMA memory descriptor for driver allocations
431ef270ab1SKenneth D. Merry *
432ef270ab1SKenneth D. Merry * Memory regions ultimately used by the hardware are described using
433ef270ab1SKenneth D. Merry * this structure. All implementations must include the structure members
434ef270ab1SKenneth D. Merry * defined in the first section, and they may also add their own structure
435ef270ab1SKenneth D. Merry * members in the second section.
436ef270ab1SKenneth D. Merry *
437ef270ab1SKenneth D. Merry * Note that each region described by ocs_dma_s is assumed to be physically
438ef270ab1SKenneth D. Merry * contiguous.
439ef270ab1SKenneth D. Merry */
440ef270ab1SKenneth D. Merry typedef struct ocs_dma_s {
441ef270ab1SKenneth D. Merry /*
442ef270ab1SKenneth D. Merry * OCS layer requires the following members
443ef270ab1SKenneth D. Merry */
444ef270ab1SKenneth D. Merry void *virt; /**< virtual address of the memory used by the CPU */
445ef270ab1SKenneth D. Merry void *alloc; /**< originally allocated virtual address used to restore virt if modified */
446ef270ab1SKenneth D. Merry uintptr_t phys; /**< physical or bus address of the memory used by the hardware */
447ef270ab1SKenneth D. Merry size_t size; /**< size in bytes of the memory */
448ef270ab1SKenneth D. Merry /*
449ef270ab1SKenneth D. Merry * Implementation specific fields allowed here
450ef270ab1SKenneth D. Merry */
451ef270ab1SKenneth D. Merry size_t len; /**< application specific length */
452ef270ab1SKenneth D. Merry bus_dma_tag_t tag;
453ef270ab1SKenneth D. Merry bus_dmamap_t map;
454ef270ab1SKenneth D. Merry } ocs_dma_t;
455ef270ab1SKenneth D. Merry
456ef270ab1SKenneth D. Merry /**
457ef270ab1SKenneth D. Merry * @ingroup os
458ef270ab1SKenneth D. Merry * @brief Returns maximum supported DMA allocation size
459ef270ab1SKenneth D. Merry *
460ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
461ef270ab1SKenneth D. Merry * @param align alignment requirement for DMA allocation
462ef270ab1SKenneth D. Merry *
463ef270ab1SKenneth D. Merry * Return maximum supported DMA allocation size, given alignment
464ef270ab1SKenneth D. Merry * requirement.
465ef270ab1SKenneth D. Merry *
4667b56cb04SGordon Bergling * @return maximum supported DMA allocation size
467ef270ab1SKenneth D. Merry */
ocs_max_dma_alloc(ocs_os_handle_t os,size_t align)468ef270ab1SKenneth D. Merry static inline uint32_t ocs_max_dma_alloc(ocs_os_handle_t os, size_t align)
469ef270ab1SKenneth D. Merry {
470ef270ab1SKenneth D. Merry return ~((uint32_t)0); /* no max */
471ef270ab1SKenneth D. Merry }
472ef270ab1SKenneth D. Merry
473ef270ab1SKenneth D. Merry /**
474ef270ab1SKenneth D. Merry * @ingroup os
475ef270ab1SKenneth D. Merry * @brief Allocate a DMA capable block of memory
476ef270ab1SKenneth D. Merry *
477ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
478ef270ab1SKenneth D. Merry * @param dma DMA descriptor containing results of memory allocation
479ef270ab1SKenneth D. Merry * @param size Size in bytes of desired allocation
480ef270ab1SKenneth D. Merry * @param align Alignment in bytes of the requested allocation
481ef270ab1SKenneth D. Merry *
482ef270ab1SKenneth D. Merry * @return 0 on success, non-zero otherwise
483ef270ab1SKenneth D. Merry */
484ef270ab1SKenneth D. Merry extern int32_t ocs_dma_alloc(ocs_os_handle_t, ocs_dma_t *, size_t, size_t);
485ef270ab1SKenneth D. Merry
486ef270ab1SKenneth D. Merry /**
487ef270ab1SKenneth D. Merry * @ingroup os
488ef270ab1SKenneth D. Merry * @brief Free a DMA capable block of memory
489ef270ab1SKenneth D. Merry *
490ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
491ef270ab1SKenneth D. Merry * @param dma DMA descriptor for memory to be freed
492ef270ab1SKenneth D. Merry *
493ef270ab1SKenneth D. Merry * @return 0 if memory is de-allocated, non-zero otherwise
494ef270ab1SKenneth D. Merry */
495ef270ab1SKenneth D. Merry extern int32_t ocs_dma_free(ocs_os_handle_t, ocs_dma_t *);
496ef270ab1SKenneth D. Merry extern int32_t ocs_dma_copy_in(ocs_dma_t *dma, void *buffer, uint32_t buffer_length);
497ef270ab1SKenneth D. Merry extern int32_t ocs_dma_copy_out(ocs_dma_t *dma, void *buffer, uint32_t buffer_length);
498ef270ab1SKenneth D. Merry
ocs_dma_valid(ocs_dma_t * dma)499ef270ab1SKenneth D. Merry static inline int32_t ocs_dma_valid(ocs_dma_t *dma)
500ef270ab1SKenneth D. Merry {
501ef270ab1SKenneth D. Merry return (dma->size != 0);
502ef270ab1SKenneth D. Merry }
503ef270ab1SKenneth D. Merry
504ef270ab1SKenneth D. Merry /**
505ef270ab1SKenneth D. Merry * @ingroup os
506ef270ab1SKenneth D. Merry * @brief Synchronize the DMA buffer memory
507ef270ab1SKenneth D. Merry *
508ef270ab1SKenneth D. Merry * Ensures memory coherency between the CPU and device
509ef270ab1SKenneth D. Merry *
510ef270ab1SKenneth D. Merry * @param dma DMA descriptor of memory to synchronize
511ef270ab1SKenneth D. Merry * @param flags Describes direction of synchronization
512ef270ab1SKenneth D. Merry * - OCS_DMASYNC_PREREAD sync needed before hardware updates host memory
513ef270ab1SKenneth D. Merry * - OCS_DMASYNC_PREWRITE sync needed after CPU updates host memory but before hardware can access
514ef270ab1SKenneth D. Merry * - OCS_DMASYNC_POSTREAD sync needed after hardware updates host memory but before CPU can access
515ef270ab1SKenneth D. Merry * - OCS_DMASYNC_POSTWRITE sync needed after hardware updates host memory
516ef270ab1SKenneth D. Merry */
517ef270ab1SKenneth D. Merry extern void ocs_dma_sync(ocs_dma_t *, uint32_t);
518ef270ab1SKenneth D. Merry
519ef270ab1SKenneth D. Merry #define OCS_DMASYNC_PREWRITE BUS_DMASYNC_PREWRITE
520ef270ab1SKenneth D. Merry #define OCS_DMASYNC_POSTREAD BUS_DMASYNC_POSTREAD
521ef270ab1SKenneth D. Merry
522ef270ab1SKenneth D. Merry /***************************************************************************
523ef270ab1SKenneth D. Merry * Locking
524ef270ab1SKenneth D. Merry */
525ef270ab1SKenneth D. Merry
526ef270ab1SKenneth D. Merry /**
527ef270ab1SKenneth D. Merry * @ingroup os
528ef270ab1SKenneth D. Merry * @typedef ocs_lock_t
529ef270ab1SKenneth D. Merry * @brief Define the type used implement locking
530ef270ab1SKenneth D. Merry */
531ef270ab1SKenneth D. Merry #define MAX_LOCK_DESC_LEN 64
532ef270ab1SKenneth D. Merry typedef struct ocs_lock_s {
533ef270ab1SKenneth D. Merry struct mtx lock;
534ef270ab1SKenneth D. Merry char name[MAX_LOCK_DESC_LEN];
535ef270ab1SKenneth D. Merry } ocs_lock_t;
536ef270ab1SKenneth D. Merry
537ef270ab1SKenneth D. Merry /**
538ef270ab1SKenneth D. Merry * @ingroup os
539ef270ab1SKenneth D. Merry * @brief Initialize a lock
540ef270ab1SKenneth D. Merry *
541ef270ab1SKenneth D. Merry * @param lock lock to initialize
542ef270ab1SKenneth D. Merry * @param name string identifier for the lock
543ef270ab1SKenneth D. Merry */
544ef270ab1SKenneth D. Merry extern void ocs_lock_init(void *os, ocs_lock_t *lock, const char *name, ...);
545ef270ab1SKenneth D. Merry
546ef270ab1SKenneth D. Merry /**
547ef270ab1SKenneth D. Merry * @ingroup os
548ef270ab1SKenneth D. Merry * @brief Free a previously allocated lock
549ef270ab1SKenneth D. Merry *
550ef270ab1SKenneth D. Merry * @param lock lock to free
551ef270ab1SKenneth D. Merry */
552ef270ab1SKenneth D. Merry static inline void
ocs_lock_free(ocs_lock_t * lock)553ef270ab1SKenneth D. Merry ocs_lock_free(ocs_lock_t *lock)
554ef270ab1SKenneth D. Merry {
555ef270ab1SKenneth D. Merry
556ef270ab1SKenneth D. Merry if (mtx_initialized(&(lock)->lock)) {
557ef270ab1SKenneth D. Merry mtx_assert(&(lock)->lock, MA_NOTOWNED);
558ef270ab1SKenneth D. Merry mtx_destroy(&(lock)->lock);
559ef270ab1SKenneth D. Merry } else {
560ef270ab1SKenneth D. Merry panic("XXX trying to free with un-initialized mtx!?!?\n");
561ef270ab1SKenneth D. Merry }
562ef270ab1SKenneth D. Merry }
563ef270ab1SKenneth D. Merry
564ef270ab1SKenneth D. Merry /**
565ef270ab1SKenneth D. Merry * @ingroup os
566ef270ab1SKenneth D. Merry * @brief Acquire a lock
567ef270ab1SKenneth D. Merry *
568ef270ab1SKenneth D. Merry * @param lock lock to obtain
569ef270ab1SKenneth D. Merry */
570ef270ab1SKenneth D. Merry static inline void
ocs_lock(ocs_lock_t * lock)571ef270ab1SKenneth D. Merry ocs_lock(ocs_lock_t *lock)
572ef270ab1SKenneth D. Merry {
573ef270ab1SKenneth D. Merry
574ef270ab1SKenneth D. Merry if (mtx_initialized(&(lock)->lock)) {
575ef270ab1SKenneth D. Merry mtx_assert(&(lock)->lock, MA_NOTOWNED);
576ef270ab1SKenneth D. Merry mtx_lock(&(lock)->lock);
577ef270ab1SKenneth D. Merry } else {
578ef270ab1SKenneth D. Merry panic("XXX trying to lock with un-initialized mtx!?!?\n");
579ef270ab1SKenneth D. Merry }
580ef270ab1SKenneth D. Merry }
581ef270ab1SKenneth D. Merry
582ef270ab1SKenneth D. Merry /**
583ef270ab1SKenneth D. Merry * @ingroup os
584ef270ab1SKenneth D. Merry * @brief Release a lock
585ef270ab1SKenneth D. Merry *
586ef270ab1SKenneth D. Merry * @param lock lock to release
587ef270ab1SKenneth D. Merry */
588ef270ab1SKenneth D. Merry static inline void
ocs_unlock(ocs_lock_t * lock)589ef270ab1SKenneth D. Merry ocs_unlock(ocs_lock_t *lock)
590ef270ab1SKenneth D. Merry {
591ef270ab1SKenneth D. Merry
592ef270ab1SKenneth D. Merry if (mtx_initialized(&(lock)->lock)) {
593ef270ab1SKenneth D. Merry mtx_assert(&(lock)->lock, MA_OWNED | MA_NOTRECURSED);
594ef270ab1SKenneth D. Merry mtx_unlock(&(lock)->lock);
595ef270ab1SKenneth D. Merry } else {
596ef270ab1SKenneth D. Merry panic("XXX trying to unlock with un-initialized mtx!?!?\n");
597ef270ab1SKenneth D. Merry }
598ef270ab1SKenneth D. Merry }
599ef270ab1SKenneth D. Merry
600ef270ab1SKenneth D. Merry /**
601ef270ab1SKenneth D. Merry * @ingroup os
602ef270ab1SKenneth D. Merry * @typedef ocs_lock_t
603ef270ab1SKenneth D. Merry * @brief Define the type used implement recursive locking
604ef270ab1SKenneth D. Merry */
605ef270ab1SKenneth D. Merry typedef struct ocs_lock_s ocs_rlock_t;
606ef270ab1SKenneth D. Merry
607ef270ab1SKenneth D. Merry /**
608ef270ab1SKenneth D. Merry * @ingroup os
609ef270ab1SKenneth D. Merry * @brief Initialize a recursive lock
610ef270ab1SKenneth D. Merry *
611ef270ab1SKenneth D. Merry * @param ocs pointer to ocs structure
612ef270ab1SKenneth D. Merry * @param lock lock to initialize
613ef270ab1SKenneth D. Merry * @param name string identifier for the lock
614ef270ab1SKenneth D. Merry */
615ef270ab1SKenneth D. Merry static inline void
ocs_rlock_init(ocs_t * ocs,ocs_rlock_t * lock,const char * name)616ef270ab1SKenneth D. Merry ocs_rlock_init(ocs_t *ocs, ocs_rlock_t *lock, const char *name)
617ef270ab1SKenneth D. Merry {
618ef270ab1SKenneth D. Merry ocs_strncpy(lock->name, name, MAX_LOCK_DESC_LEN);
619ef270ab1SKenneth D. Merry mtx_init(&(lock)->lock, lock->name, NULL, MTX_DEF | MTX_RECURSE | MTX_DUPOK);
620ef270ab1SKenneth D. Merry }
621ef270ab1SKenneth D. Merry
622ef270ab1SKenneth D. Merry /**
623ef270ab1SKenneth D. Merry * @ingroup os
624ef270ab1SKenneth D. Merry * @brief Free a previously allocated recursive lock
625ef270ab1SKenneth D. Merry *
626ef270ab1SKenneth D. Merry * @param lock lock to free
627ef270ab1SKenneth D. Merry */
628ef270ab1SKenneth D. Merry static inline void
ocs_rlock_free(ocs_rlock_t * lock)629ef270ab1SKenneth D. Merry ocs_rlock_free(ocs_rlock_t *lock)
630ef270ab1SKenneth D. Merry {
631ef270ab1SKenneth D. Merry if (mtx_initialized(&(lock)->lock)) {
632ef270ab1SKenneth D. Merry mtx_destroy(&(lock)->lock);
633ef270ab1SKenneth D. Merry } else {
634ef270ab1SKenneth D. Merry panic("XXX trying to free with un-initialized mtx!?!?\n");
635ef270ab1SKenneth D. Merry }
636ef270ab1SKenneth D. Merry }
637ef270ab1SKenneth D. Merry
638ef270ab1SKenneth D. Merry /**
639ef270ab1SKenneth D. Merry * @brief try to acquire a recursive lock
640ef270ab1SKenneth D. Merry *
641ef270ab1SKenneth D. Merry * Attempt to acquire a recursive lock, return TRUE if successful
642ef270ab1SKenneth D. Merry *
643ef270ab1SKenneth D. Merry * @param lock pointer to recursive lock
644ef270ab1SKenneth D. Merry *
645ef270ab1SKenneth D. Merry * @return TRUE if lock was acquired, FALSE if not
646ef270ab1SKenneth D. Merry */
647ef270ab1SKenneth D. Merry static inline int32_t
ocs_rlock_try(ocs_rlock_t * lock)648ef270ab1SKenneth D. Merry ocs_rlock_try(ocs_rlock_t *lock)
649ef270ab1SKenneth D. Merry {
650ef270ab1SKenneth D. Merry int rc = mtx_trylock(&(lock)->lock);
651ef270ab1SKenneth D. Merry
652ef270ab1SKenneth D. Merry return rc != 0;
653ef270ab1SKenneth D. Merry }
654ef270ab1SKenneth D. Merry
655ef270ab1SKenneth D. Merry /**
656ef270ab1SKenneth D. Merry * @ingroup os
657ef270ab1SKenneth D. Merry * @brief Acquire a recursive lock
658ef270ab1SKenneth D. Merry *
659ef270ab1SKenneth D. Merry * @param lock lock to obtain
660ef270ab1SKenneth D. Merry */
661ef270ab1SKenneth D. Merry static inline void
ocs_rlock_acquire(ocs_rlock_t * lock)662ef270ab1SKenneth D. Merry ocs_rlock_acquire(ocs_rlock_t *lock)
663ef270ab1SKenneth D. Merry {
664ef270ab1SKenneth D. Merry if (mtx_initialized(&(lock)->lock)) {
665ef270ab1SKenneth D. Merry mtx_lock(&(lock)->lock);
666ef270ab1SKenneth D. Merry } else {
667ef270ab1SKenneth D. Merry panic("XXX trying to lock with un-initialized mtx!?!?\n");
668ef270ab1SKenneth D. Merry }
669ef270ab1SKenneth D. Merry }
670ef270ab1SKenneth D. Merry
671ef270ab1SKenneth D. Merry /**
672ef270ab1SKenneth D. Merry * @ingroup os
673ef270ab1SKenneth D. Merry * @brief Release a recursive lock
674ef270ab1SKenneth D. Merry *
675ef270ab1SKenneth D. Merry * @param lock lock to release
676ef270ab1SKenneth D. Merry */
677ef270ab1SKenneth D. Merry static inline void
ocs_rlock_release(ocs_rlock_t * lock)678ef270ab1SKenneth D. Merry ocs_rlock_release(ocs_rlock_t *lock)
679ef270ab1SKenneth D. Merry {
680ef270ab1SKenneth D. Merry if (mtx_initialized(&(lock)->lock)) {
681ef270ab1SKenneth D. Merry mtx_assert(&(lock)->lock, MA_OWNED);
682ef270ab1SKenneth D. Merry mtx_unlock(&(lock)->lock);
683ef270ab1SKenneth D. Merry } else {
684ef270ab1SKenneth D. Merry panic("XXX trying to unlock with un-initialized mtx!?!?\n");
685ef270ab1SKenneth D. Merry }
686ef270ab1SKenneth D. Merry }
687ef270ab1SKenneth D. Merry
688ef270ab1SKenneth D. Merry /**
689ef270ab1SKenneth D. Merry * @brief counting semaphore
690ef270ab1SKenneth D. Merry *
691ef270ab1SKenneth D. Merry * Declaration of the counting semaphore object
692ef270ab1SKenneth D. Merry *
693ef270ab1SKenneth D. Merry */
694ef270ab1SKenneth D. Merry typedef struct {
695ef270ab1SKenneth D. Merry char name[32];
696ef270ab1SKenneth D. Merry struct sema sem; /**< OS counting semaphore structure */
697ef270ab1SKenneth D. Merry } ocs_sem_t;
698ef270ab1SKenneth D. Merry
699ef270ab1SKenneth D. Merry #define OCS_SEM_FOREVER (-1)
700ef270ab1SKenneth D. Merry #define OCS_SEM_TRY (0)
701ef270ab1SKenneth D. Merry
702ef270ab1SKenneth D. Merry /**
703ef270ab1SKenneth D. Merry * @brief Initialize a counting semaphore
704ef270ab1SKenneth D. Merry *
705ef270ab1SKenneth D. Merry * The semaphore is initiatlized to the value
706ef270ab1SKenneth D. Merry *
707ef270ab1SKenneth D. Merry * @param sem pointer to semaphore
708ef270ab1SKenneth D. Merry * @param val initial value
709ef270ab1SKenneth D. Merry * @param name label for the semaphore
710ef270ab1SKenneth D. Merry *
711ef270ab1SKenneth D. Merry * @return returns 0 for success, a negative error code value for failure.
712ef270ab1SKenneth D. Merry */
713ef270ab1SKenneth D. Merry
714ef270ab1SKenneth D. Merry extern int ocs_sem_init(ocs_sem_t *sem, int val, const char *name, ...) __attribute__((format(printf, 3, 4)));
715ef270ab1SKenneth D. Merry
716ef270ab1SKenneth D. Merry /**
717ef270ab1SKenneth D. Merry * @brief execute a P (decrement) operation
718ef270ab1SKenneth D. Merry *
719ef270ab1SKenneth D. Merry * A P (decrement and block if negative) operation is performed on the semaphore.
720ef270ab1SKenneth D. Merry *
721ef270ab1SKenneth D. Merry * If timeout_usec is zero, the semaphore attempts one time and returns 0 if acquired.
722ef270ab1SKenneth D. Merry * If timeout_usec is greater than zero, then the call will block until the semaphore
723ef270ab1SKenneth D. Merry * is acquired, or a timeout occurred. If timeout_usec is less than zero, then
724ef270ab1SKenneth D. Merry * the call will block until the semaphore is acquired.
725ef270ab1SKenneth D. Merry *
726ef270ab1SKenneth D. Merry * @param sem pointer to semaphore
727ef270ab1SKenneth D. Merry * @param timeout_usec timeout in microseconds
728ef270ab1SKenneth D. Merry *
729ef270ab1SKenneth D. Merry * @return returns 0 for success, negative value if the semaphore was not acquired.
730ef270ab1SKenneth D. Merry */
731ef270ab1SKenneth D. Merry
732ef270ab1SKenneth D. Merry static inline int
ocs_sem_p(ocs_sem_t * sem,int timeout_usec)733ef270ab1SKenneth D. Merry ocs_sem_p(ocs_sem_t *sem, int timeout_usec)
734ef270ab1SKenneth D. Merry {
735ef270ab1SKenneth D. Merry int32_t rc = 0;
736ef270ab1SKenneth D. Merry
737ef270ab1SKenneth D. Merry if (timeout_usec == 0) {
738ef270ab1SKenneth D. Merry rc = sema_trywait(&sem->sem);
739ef270ab1SKenneth D. Merry if (rc == 0) {
740ef270ab1SKenneth D. Merry rc = -1;
741ef270ab1SKenneth D. Merry }
742ef270ab1SKenneth D. Merry } else if (timeout_usec > 0) {
743ef270ab1SKenneth D. Merry struct timeval tv;
744ef270ab1SKenneth D. Merry uint32_t ticks;
745ef270ab1SKenneth D. Merry
746ef270ab1SKenneth D. Merry tv.tv_sec = timeout_usec / 1000000;
747ef270ab1SKenneth D. Merry tv.tv_usec = timeout_usec % 1000000;
748ef270ab1SKenneth D. Merry ticks = tvtohz(&tv);
749ef270ab1SKenneth D. Merry if (ticks == 0) {
750ef270ab1SKenneth D. Merry ticks ++;
751ef270ab1SKenneth D. Merry }
752ef270ab1SKenneth D. Merry rc = sema_timedwait(&sem->sem, ticks);
753ef270ab1SKenneth D. Merry if (rc != 0) {
754ef270ab1SKenneth D. Merry rc = -1;
755ef270ab1SKenneth D. Merry }
756ef270ab1SKenneth D. Merry } else {
757ef270ab1SKenneth D. Merry sema_wait(&sem->sem);
758ef270ab1SKenneth D. Merry }
759ef270ab1SKenneth D. Merry if (rc)
760ef270ab1SKenneth D. Merry rc = -1;
761ef270ab1SKenneth D. Merry
762ef270ab1SKenneth D. Merry return rc;
763ef270ab1SKenneth D. Merry }
764ef270ab1SKenneth D. Merry
765ef270ab1SKenneth D. Merry /**
766ef270ab1SKenneth D. Merry * @brief perform a V (increment) operation on a counting semaphore
767ef270ab1SKenneth D. Merry *
768ef270ab1SKenneth D. Merry * The semaphore is incremented, unblocking one thread that is waiting on the
769ef270ab1SKenneth D. Merry * sempahore
770ef270ab1SKenneth D. Merry *
771ef270ab1SKenneth D. Merry * @param sem pointer to the semaphore
772ef270ab1SKenneth D. Merry *
773ef270ab1SKenneth D. Merry * @return none
774ef270ab1SKenneth D. Merry */
775ef270ab1SKenneth D. Merry
776ef270ab1SKenneth D. Merry static inline void
ocs_sem_v(ocs_sem_t * sem)777ef270ab1SKenneth D. Merry ocs_sem_v(ocs_sem_t *sem)
778ef270ab1SKenneth D. Merry {
779ef270ab1SKenneth D. Merry sema_post(&sem->sem);
780ef270ab1SKenneth D. Merry }
781ef270ab1SKenneth D. Merry
782ef270ab1SKenneth D. Merry /***************************************************************************
783ef270ab1SKenneth D. Merry * Bitmap
784ef270ab1SKenneth D. Merry */
785ef270ab1SKenneth D. Merry
786ef270ab1SKenneth D. Merry /**
787ef270ab1SKenneth D. Merry * @ingroup os
788ef270ab1SKenneth D. Merry * @typedef ocs_bitmap_t
789ef270ab1SKenneth D. Merry * @brief Define the type used implement bit-maps
790ef270ab1SKenneth D. Merry */
791ef270ab1SKenneth D. Merry typedef bitstr_t ocs_bitmap_t;
792ef270ab1SKenneth D. Merry
793ef270ab1SKenneth D. Merry /**
794ef270ab1SKenneth D. Merry * @ingroup os
795ef270ab1SKenneth D. Merry * @brief Allocate a bitmap
796ef270ab1SKenneth D. Merry *
797ef270ab1SKenneth D. Merry * @param n_bits Minimum number of entries in the bit-map
798ef270ab1SKenneth D. Merry *
799ef270ab1SKenneth D. Merry * @return pointer to the bit-map or NULL on error
800ef270ab1SKenneth D. Merry */
801ef270ab1SKenneth D. Merry extern ocs_bitmap_t *ocs_bitmap_alloc(uint32_t n_bits);
802ef270ab1SKenneth D. Merry
803ef270ab1SKenneth D. Merry /**
804ef270ab1SKenneth D. Merry * @ingroup os
805ef270ab1SKenneth D. Merry * @brief Free a bit-map
806ef270ab1SKenneth D. Merry *
807ef270ab1SKenneth D. Merry * @param bitmap Bit-map to free
808ef270ab1SKenneth D. Merry */
809ef270ab1SKenneth D. Merry extern void ocs_bitmap_free(ocs_bitmap_t *bitmap);
810ef270ab1SKenneth D. Merry
811ef270ab1SKenneth D. Merry /**
812ef270ab1SKenneth D. Merry * @ingroup os
813ef270ab1SKenneth D. Merry * @brief Find next unset bit and set it
814ef270ab1SKenneth D. Merry *
815ef270ab1SKenneth D. Merry * @param bitmap bit map to search
816ef270ab1SKenneth D. Merry * @param n_bits number of bits in map
817ef270ab1SKenneth D. Merry *
818ef270ab1SKenneth D. Merry * @return bit position or -1 if map is full
819ef270ab1SKenneth D. Merry */
820ef270ab1SKenneth D. Merry extern int32_t ocs_bitmap_find(ocs_bitmap_t *bitmap, uint32_t n_bits);
821ef270ab1SKenneth D. Merry
822ef270ab1SKenneth D. Merry /**
823ef270ab1SKenneth D. Merry * @ingroup os
824ef270ab1SKenneth D. Merry * @brief search for next (un)set bit
825ef270ab1SKenneth D. Merry *
826ef270ab1SKenneth D. Merry * @param bitmap bit map to search
827ef270ab1SKenneth D. Merry * @param set search for a set or unset bit
828ef270ab1SKenneth D. Merry * @param n_bits number of bits in map
829ef270ab1SKenneth D. Merry *
830ef270ab1SKenneth D. Merry * @return bit position or -1
831ef270ab1SKenneth D. Merry */
832ef270ab1SKenneth D. Merry extern int32_t ocs_bitmap_search(ocs_bitmap_t *bitmap, uint8_t set, uint32_t n_bits);
833ef270ab1SKenneth D. Merry
834ef270ab1SKenneth D. Merry /**
835ef270ab1SKenneth D. Merry * @ingroup os
836ef270ab1SKenneth D. Merry * @brief clear the specified bit
837ef270ab1SKenneth D. Merry *
838ef270ab1SKenneth D. Merry * @param bitmap pointer to bit map
839ef270ab1SKenneth D. Merry * @param bit bit number to clear
840ef270ab1SKenneth D. Merry */
841ef270ab1SKenneth D. Merry extern void ocs_bitmap_clear(ocs_bitmap_t *bitmap, uint32_t bit);
842ef270ab1SKenneth D. Merry
843ef270ab1SKenneth D. Merry extern int32_t ocs_get_property(const char *prop_name, char *buffer, uint32_t buffer_len);
844ef270ab1SKenneth D. Merry
845ef270ab1SKenneth D. Merry /***************************************************************************
846ef270ab1SKenneth D. Merry * Timer Routines
847ef270ab1SKenneth D. Merry *
848ef270ab1SKenneth D. Merry * Functions for setting, querying and canceling timers.
849ef270ab1SKenneth D. Merry */
850ef270ab1SKenneth D. Merry typedef struct {
851ef270ab1SKenneth D. Merry struct callout callout;
852ef270ab1SKenneth D. Merry struct mtx lock;
853ef270ab1SKenneth D. Merry
854ef270ab1SKenneth D. Merry void (*func)(void *);
855ef270ab1SKenneth D. Merry void *data;
856ef270ab1SKenneth D. Merry } ocs_timer_t;
857ef270ab1SKenneth D. Merry
858ef270ab1SKenneth D. Merry /**
859ef270ab1SKenneth D. Merry * @ingroup os
860ef270ab1SKenneth D. Merry * @brief Initialize and set a timer
861ef270ab1SKenneth D. Merry *
862ef270ab1SKenneth D. Merry * @param os OS handle
863ef270ab1SKenneth D. Merry * @param timer pointer to the structure allocated for this timer
864ef270ab1SKenneth D. Merry * @param func the function to call when the timer expires
865ef270ab1SKenneth D. Merry * @param data Data to pass to the provided timer function when the timer
866ef270ab1SKenneth D. Merry * expires.
867ef270ab1SKenneth D. Merry * @param timeout_ms the timeout in milliseconds
868ef270ab1SKenneth D. Merry */
869ef270ab1SKenneth D. Merry extern int32_t ocs_setup_timer(ocs_os_handle_t os, ocs_timer_t *timer, void(*func)(void *arg),
870ef270ab1SKenneth D. Merry void *data, uint32_t timeout_ms);
871ef270ab1SKenneth D. Merry
872ef270ab1SKenneth D. Merry /**
873ef270ab1SKenneth D. Merry * @ingroup os
874ef270ab1SKenneth D. Merry * @brief Modify a timer's expiration
875ef270ab1SKenneth D. Merry *
876ef270ab1SKenneth D. Merry * @param timer pointer to the structure allocated for this timer
877ef270ab1SKenneth D. Merry * @param timeout_ms the timeout in milliseconds
878ef270ab1SKenneth D. Merry */
879ef270ab1SKenneth D. Merry extern int32_t ocs_mod_timer(ocs_timer_t *timer, uint32_t timeout_ms);
880ef270ab1SKenneth D. Merry
881ef270ab1SKenneth D. Merry /**
882ef270ab1SKenneth D. Merry * @ingroup os
883ef270ab1SKenneth D. Merry * @brief Queries to see if a timer is pending.
884ef270ab1SKenneth D. Merry *
885ef270ab1SKenneth D. Merry * @param timer pointer to the structure allocated for this timer
886ef270ab1SKenneth D. Merry *
887ef270ab1SKenneth D. Merry * @return non-zero if the timer is pending
888ef270ab1SKenneth D. Merry */
889ef270ab1SKenneth D. Merry extern int32_t ocs_timer_pending(ocs_timer_t *timer);
890ef270ab1SKenneth D. Merry
891ef270ab1SKenneth D. Merry /**
892ef270ab1SKenneth D. Merry * @ingroup os
893ef270ab1SKenneth D. Merry * @brief Remove a pending timer
894ef270ab1SKenneth D. Merry *
895ef270ab1SKenneth D. Merry * @param timer pointer to the structure allocated for this timer
896ef270ab1SKenneth D. Merry * expires.
897ef270ab1SKenneth D. Merry */
898ef270ab1SKenneth D. Merry extern int32_t ocs_del_timer(ocs_timer_t *timer);
899ef270ab1SKenneth D. Merry
900ef270ab1SKenneth D. Merry /***************************************************************************
901ef270ab1SKenneth D. Merry * Atomics
902ef270ab1SKenneth D. Merry *
903ef270ab1SKenneth D. Merry */
904ef270ab1SKenneth D. Merry
905ef270ab1SKenneth D. Merry typedef uint32_t ocs_atomic_t;
906ef270ab1SKenneth D. Merry
907ef270ab1SKenneth D. Merry /**
908ef270ab1SKenneth D. Merry * @ingroup os
909ef270ab1SKenneth D. Merry * @brief initialize an atomic
910ef270ab1SKenneth D. Merry *
911ef270ab1SKenneth D. Merry * @param a pointer to the atomic object
912ef270ab1SKenneth D. Merry * @param v initial value
913ef270ab1SKenneth D. Merry *
914ef270ab1SKenneth D. Merry * @return none
915ef270ab1SKenneth D. Merry */
916ef270ab1SKenneth D. Merry #define ocs_atomic_init(a, v) ocs_atomic_set(a, v)
917ef270ab1SKenneth D. Merry
918ef270ab1SKenneth D. Merry /**
919ef270ab1SKenneth D. Merry * @ingroup os
920ef270ab1SKenneth D. Merry * @brief adds an integer to an atomic value
921ef270ab1SKenneth D. Merry *
922ef270ab1SKenneth D. Merry * @param a pointer to the atomic object
923ef270ab1SKenneth D. Merry * @param v value to increment
924ef270ab1SKenneth D. Merry *
925ef270ab1SKenneth D. Merry * @return the value of the atomic before incrementing.
926ef270ab1SKenneth D. Merry */
927ef270ab1SKenneth D. Merry #define ocs_atomic_add_return(a, v) atomic_fetchadd_32(a, v)
928ef270ab1SKenneth D. Merry
929ef270ab1SKenneth D. Merry /**
930ef270ab1SKenneth D. Merry * @ingroup os
931ef270ab1SKenneth D. Merry * @brief subtracts an integer to an atomic value
932ef270ab1SKenneth D. Merry *
933ef270ab1SKenneth D. Merry * @param a pointer to the atomic object
934ef270ab1SKenneth D. Merry * @param v value to increment
935ef270ab1SKenneth D. Merry *
936ef270ab1SKenneth D. Merry * @return the value of the atomic before subtracting.
937ef270ab1SKenneth D. Merry */
938ef270ab1SKenneth D. Merry #define ocs_atomic_sub_return(a, v) atomic_fetchadd_32(a, (-(v)))
939ef270ab1SKenneth D. Merry
940ef270ab1SKenneth D. Merry /**
941ef270ab1SKenneth D. Merry * @ingroup os
942ef270ab1SKenneth D. Merry * @brief returns the current value of an atomic object
943ef270ab1SKenneth D. Merry *
944ef270ab1SKenneth D. Merry * @param a pointer to the atomic object
945ef270ab1SKenneth D. Merry *
946ef270ab1SKenneth D. Merry * @return the value of the atomic.
947ef270ab1SKenneth D. Merry */
948ef270ab1SKenneth D. Merry #define ocs_atomic_read(a) atomic_load_acq_32(a)
949ef270ab1SKenneth D. Merry
950ef270ab1SKenneth D. Merry /**
951ef270ab1SKenneth D. Merry * @ingroup os
952ef270ab1SKenneth D. Merry * @brief sets the current value of an atomic object
953ef270ab1SKenneth D. Merry *
954ef270ab1SKenneth D. Merry * @param a pointer to the atomic object
955ef270ab1SKenneth D. Merry */
956ef270ab1SKenneth D. Merry #define ocs_atomic_set(a, v) atomic_store_rel_32(a, v)
957ef270ab1SKenneth D. Merry
958ef270ab1SKenneth D. Merry /**
959ef270ab1SKenneth D. Merry * @ingroup os
960ef270ab1SKenneth D. Merry * @brief Sets atomic to 0, returns previous value
961ef270ab1SKenneth D. Merry *
962ef270ab1SKenneth D. Merry * @param a pointer to the atomic object
963ef270ab1SKenneth D. Merry *
964ef270ab1SKenneth D. Merry * @return the value of the atomic before the operation.
965ef270ab1SKenneth D. Merry */
966ef270ab1SKenneth D. Merry #define ocs_atomic_read_and_clear atomic_readandclear_32(a)
967ef270ab1SKenneth D. Merry
968ef270ab1SKenneth D. Merry /**
969ef270ab1SKenneth D. Merry * @brief OCS thread structure
970ef270ab1SKenneth D. Merry *
971ef270ab1SKenneth D. Merry */
972ef270ab1SKenneth D. Merry
973ef270ab1SKenneth D. Merry typedef struct ocs_thread_s ocs_thread_t;
974ef270ab1SKenneth D. Merry
975ef270ab1SKenneth D. Merry typedef int32_t (*ocs_thread_fctn)(ocs_thread_t *mythread);
976ef270ab1SKenneth D. Merry
977ef270ab1SKenneth D. Merry struct ocs_thread_s {
978ef270ab1SKenneth D. Merry struct thread *tcb; /*<< thread control block */
979ef270ab1SKenneth D. Merry ocs_thread_fctn fctn; /*<< thread function */
980ef270ab1SKenneth D. Merry char *name; /*<< name of thread */
981ef270ab1SKenneth D. Merry void *arg; /*<< pointer to thread argument */
982ef270ab1SKenneth D. Merry ocs_atomic_t terminate; /*<< terminate request */
983ef270ab1SKenneth D. Merry int32_t retval; /*<< return value */
984ef270ab1SKenneth D. Merry uint32_t cpu_affinity; /*<< cpu affinity */
985ef270ab1SKenneth D. Merry };
986ef270ab1SKenneth D. Merry #define OCS_THREAD_DEFAULT_STACK_SIZE_PAGES 8
987ef270ab1SKenneth D. Merry
988ef270ab1SKenneth D. Merry /**
989ef270ab1SKenneth D. Merry * @brief OCS thread start options
990ef270ab1SKenneth D. Merry *
991ef270ab1SKenneth D. Merry */
992ef270ab1SKenneth D. Merry
993ef270ab1SKenneth D. Merry typedef enum {
994ef270ab1SKenneth D. Merry OCS_THREAD_RUN, /*<< run immediately */
995ef270ab1SKenneth D. Merry OCS_THREAD_CREATE, /*<< create and wait for start request */
996ef270ab1SKenneth D. Merry } ocs_thread_start_e;
997ef270ab1SKenneth D. Merry
998ef270ab1SKenneth D. Merry extern int32_t ocs_thread_create(ocs_os_handle_t os, ocs_thread_t *thread, ocs_thread_fctn fctn,
999ef270ab1SKenneth D. Merry const char *name, void *arg, ocs_thread_start_e start_option);
1000ef270ab1SKenneth D. Merry extern int32_t ocs_thread_start(ocs_thread_t *thread);
1001ef270ab1SKenneth D. Merry extern void *ocs_thread_get_arg(ocs_thread_t *mythread);
1002ef270ab1SKenneth D. Merry extern int32_t ocs_thread_terminate(ocs_thread_t *thread);
1003ef270ab1SKenneth D. Merry extern int32_t ocs_thread_terminate_requested(ocs_thread_t *thread);
1004ef270ab1SKenneth D. Merry extern int32_t ocs_thread_get_retval(ocs_thread_t *thread);
1005ef270ab1SKenneth D. Merry extern void ocs_thread_yield(ocs_thread_t *thread);
1006ef270ab1SKenneth D. Merry extern ocs_thread_t *ocs_thread_self(void);
1007ef270ab1SKenneth D. Merry extern int32_t ocs_thread_setcpu(ocs_thread_t *thread, uint32_t cpu);
1008ef270ab1SKenneth D. Merry extern int32_t ocs_thread_getcpu(void);
1009ef270ab1SKenneth D. Merry
1010ef270ab1SKenneth D. Merry /***************************************************************************
1011ef270ab1SKenneth D. Merry * PCI
1012ef270ab1SKenneth D. Merry *
1013ef270ab1SKenneth D. Merry * Several functions below refer to a "register set". This is one or
1014ef270ab1SKenneth D. Merry * more PCI BARs that constitute a PCI address. For example, if a MMIO
1015ef270ab1SKenneth D. Merry * region is described using both BAR[0] and BAR[1], the combination of
1016ef270ab1SKenneth D. Merry * BARs defines register set 0.
1017ef270ab1SKenneth D. Merry */
1018ef270ab1SKenneth D. Merry
1019ef270ab1SKenneth D. Merry /**
1020ef270ab1SKenneth D. Merry * @brief tracks mapped PCI memory regions
1021ef270ab1SKenneth D. Merry */
1022ef270ab1SKenneth D. Merry typedef struct ocs_pci_reg_s {
1023ef270ab1SKenneth D. Merry uint32_t rid;
1024ef270ab1SKenneth D. Merry struct resource *res;
1025ef270ab1SKenneth D. Merry bus_space_tag_t btag;
1026ef270ab1SKenneth D. Merry bus_space_handle_t bhandle;
1027ef270ab1SKenneth D. Merry } ocs_pci_reg_t;
1028ef270ab1SKenneth D. Merry
1029ef270ab1SKenneth D. Merry #define PCI_MAX_BAR 6
1030ef270ab1SKenneth D. Merry #define PCI_64BIT_BAR0 0
1031ef270ab1SKenneth D. Merry
1032ef270ab1SKenneth D. Merry #define PCI_VENDOR_EMULEX 0x10df /* Emulex */
1033ef270ab1SKenneth D. Merry
1034ef270ab1SKenneth D. Merry #define PCI_PRODUCT_EMULEX_OCE16001 0xe200 /* OneCore 16Gb FC (lancer) */
1035ef270ab1SKenneth D. Merry #define PCI_PRODUCT_EMULEX_OCE16002 0xe200 /* OneCore 16Gb FC (lancer) */
1036ef270ab1SKenneth D. Merry #define PCI_PRODUCT_EMULEX_LPE31004 0xe300 /* LightPulse 16Gb x 4 FC (lancer-g6) */
1037ef270ab1SKenneth D. Merry #define PCI_PRODUCT_EMULEX_LPE32002 0xe300 /* LightPulse 32Gb x 2 FC (lancer-g6) */
10383bf42363SRam Kishore Vegesna #define PCI_PRODUCT_EMULEX_LANCER_G7 0xf400 /* LightPulse 32Gb x 4 FC (lancer-g7) */
10393bf42363SRam Kishore Vegesna
1040ef270ab1SKenneth D. Merry #define PCI_PRODUCT_EMULEX_OCE1600_VF 0xe208
1041ef270ab1SKenneth D. Merry #define PCI_PRODUCT_EMULEX_OCE50102 0xe260 /* OneCore FCoE (lancer) */
1042ef270ab1SKenneth D. Merry #define PCI_PRODUCT_EMULEX_OCE50102_VF 0xe268
1043ef270ab1SKenneth D. Merry
1044ef270ab1SKenneth D. Merry /**
1045ef270ab1SKenneth D. Merry * @ingroup os
1046ef270ab1SKenneth D. Merry * @brief Get the PCI bus, device, and function values
1047ef270ab1SKenneth D. Merry *
1048ef270ab1SKenneth D. Merry * @param ocs OS specific handle or driver context
1049ef270ab1SKenneth D. Merry * @param bus Pointer to location to store the bus number.
1050ef270ab1SKenneth D. Merry * @param dev Pointer to location to store the device number.
1051ef270ab1SKenneth D. Merry * @param func Pointer to location to store the function number.
1052ef270ab1SKenneth D. Merry *
1053ef270ab1SKenneth D. Merry */
105429e2dbd4SRam Kishore Vegesna extern void
1055ef270ab1SKenneth D. Merry ocs_get_bus_dev_func(ocs_t *ocs, uint8_t* bus, uint8_t* dev, uint8_t* func);
1056ef270ab1SKenneth D. Merry
1057ef270ab1SKenneth D. Merry extern ocs_t *ocs_get_instance(uint32_t index);
1058ef270ab1SKenneth D. Merry extern uint32_t ocs_instance(void *os);
1059ef270ab1SKenneth D. Merry
1060ef270ab1SKenneth D. Merry /**
1061ef270ab1SKenneth D. Merry * @ingroup os
1062ef270ab1SKenneth D. Merry * @brief Read a 32 bit value from the specified configuration register
1063ef270ab1SKenneth D. Merry *
1064ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1065ef270ab1SKenneth D. Merry * @param reg register offset
1066ef270ab1SKenneth D. Merry *
1067ef270ab1SKenneth D. Merry * @return The 32 bit value
1068ef270ab1SKenneth D. Merry */
1069ef270ab1SKenneth D. Merry extern uint32_t ocs_config_read32(ocs_os_handle_t os, uint32_t reg);
1070ef270ab1SKenneth D. Merry
1071ef270ab1SKenneth D. Merry /**
1072ef270ab1SKenneth D. Merry * @ingroup os
1073ef270ab1SKenneth D. Merry * @brief Read a 16 bit value from the specified configuration
1074ef270ab1SKenneth D. Merry * register
1075ef270ab1SKenneth D. Merry *
1076ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1077ef270ab1SKenneth D. Merry * @param reg register offset
1078ef270ab1SKenneth D. Merry *
1079ef270ab1SKenneth D. Merry * @return The 16 bit value
1080ef270ab1SKenneth D. Merry */
1081ef270ab1SKenneth D. Merry extern uint16_t ocs_config_read16(ocs_os_handle_t os, uint32_t reg);
1082ef270ab1SKenneth D. Merry
1083ef270ab1SKenneth D. Merry /**
1084ef270ab1SKenneth D. Merry * @ingroup os
1085ef270ab1SKenneth D. Merry * @brief Read a 8 bit value from the specified configuration
1086ef270ab1SKenneth D. Merry * register
1087ef270ab1SKenneth D. Merry *
1088ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1089ef270ab1SKenneth D. Merry * @param reg register offset
1090ef270ab1SKenneth D. Merry *
1091ef270ab1SKenneth D. Merry * @return The 8 bit value
1092ef270ab1SKenneth D. Merry */
1093ef270ab1SKenneth D. Merry extern uint8_t ocs_config_read8(ocs_os_handle_t os, uint32_t reg);
1094ef270ab1SKenneth D. Merry
1095ef270ab1SKenneth D. Merry /**
1096ef270ab1SKenneth D. Merry * @ingroup os
1097ef270ab1SKenneth D. Merry * @brief Write a 8 bit value to the specified configuration
1098ef270ab1SKenneth D. Merry * register
1099ef270ab1SKenneth D. Merry *
1100ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1101ef270ab1SKenneth D. Merry * @param reg register offset
1102ef270ab1SKenneth D. Merry * @param val value to write
1103ef270ab1SKenneth D. Merry *
1104ef270ab1SKenneth D. Merry * @return None
1105ef270ab1SKenneth D. Merry */
1106ef270ab1SKenneth D. Merry extern void ocs_config_write8(ocs_os_handle_t os, uint32_t reg, uint8_t val);
1107ef270ab1SKenneth D. Merry
1108ef270ab1SKenneth D. Merry /**
1109ef270ab1SKenneth D. Merry * @ingroup os
1110ef270ab1SKenneth D. Merry * @brief Write a 16 bit value to the specified configuration
1111ef270ab1SKenneth D. Merry * register
1112ef270ab1SKenneth D. Merry *
1113ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1114ef270ab1SKenneth D. Merry * @param reg register offset
1115ef270ab1SKenneth D. Merry * @param val value to write
1116ef270ab1SKenneth D. Merry *
1117ef270ab1SKenneth D. Merry * @return None
1118ef270ab1SKenneth D. Merry */
1119ef270ab1SKenneth D. Merry extern void ocs_config_write16(ocs_os_handle_t os, uint32_t reg, uint16_t val);
1120ef270ab1SKenneth D. Merry
1121ef270ab1SKenneth D. Merry /**
1122ef270ab1SKenneth D. Merry * @ingroup os
1123ef270ab1SKenneth D. Merry * @brief Write a 32 bit value to the specified configuration
1124ef270ab1SKenneth D. Merry * register
1125ef270ab1SKenneth D. Merry *
1126ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1127ef270ab1SKenneth D. Merry * @param reg register offset
1128ef270ab1SKenneth D. Merry * @param val value to write
1129ef270ab1SKenneth D. Merry *
1130ef270ab1SKenneth D. Merry * @return None
1131ef270ab1SKenneth D. Merry */
1132ef270ab1SKenneth D. Merry extern void ocs_config_write32(ocs_os_handle_t os, uint32_t reg, uint32_t val);
1133ef270ab1SKenneth D. Merry
1134ef270ab1SKenneth D. Merry /**
1135ef270ab1SKenneth D. Merry * @ingroup os
1136ef270ab1SKenneth D. Merry * @brief Read a PCI register
1137ef270ab1SKenneth D. Merry *
1138ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1139ef270ab1SKenneth D. Merry * @param rset Which "register set" to use
1140ef270ab1SKenneth D. Merry * @param off Register offset
1141ef270ab1SKenneth D. Merry *
1142ef270ab1SKenneth D. Merry * @return 32 bit conents of the register
1143ef270ab1SKenneth D. Merry */
1144ef270ab1SKenneth D. Merry extern uint32_t ocs_reg_read32(ocs_os_handle_t os, uint32_t rset, uint32_t off);
1145ef270ab1SKenneth D. Merry
1146ef270ab1SKenneth D. Merry /**
1147ef270ab1SKenneth D. Merry * @ingroup os
1148ef270ab1SKenneth D. Merry * @brief Read a PCI register
1149ef270ab1SKenneth D. Merry *
1150ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1151ef270ab1SKenneth D. Merry * @param rset Which "register set" to use
1152ef270ab1SKenneth D. Merry * @param off Register offset
1153ef270ab1SKenneth D. Merry *
1154ef270ab1SKenneth D. Merry * @return 16 bit conents of the register
1155ef270ab1SKenneth D. Merry */
1156ef270ab1SKenneth D. Merry extern uint16_t ocs_reg_read16(ocs_os_handle_t os, uint32_t rset, uint32_t off);
1157ef270ab1SKenneth D. Merry
1158ef270ab1SKenneth D. Merry /**
1159ef270ab1SKenneth D. Merry * @ingroup os
1160ef270ab1SKenneth D. Merry * @brief Read a PCI register
1161ef270ab1SKenneth D. Merry *
1162ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1163ef270ab1SKenneth D. Merry * @param rset Which "register set" to use
1164ef270ab1SKenneth D. Merry * @param off Register offset
1165ef270ab1SKenneth D. Merry *
1166ef270ab1SKenneth D. Merry * @return 8 bit conents of the register
1167ef270ab1SKenneth D. Merry */
1168ef270ab1SKenneth D. Merry extern uint8_t ocs_reg_read8(ocs_os_handle_t os, uint32_t rset, uint32_t off);
1169ef270ab1SKenneth D. Merry
1170ef270ab1SKenneth D. Merry /**
1171ef270ab1SKenneth D. Merry * @ingroup os
1172ef270ab1SKenneth D. Merry * @brief Write a PCI register
1173ef270ab1SKenneth D. Merry *
1174ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1175ef270ab1SKenneth D. Merry * @param rset Which "register set" to use
1176ef270ab1SKenneth D. Merry * @param off Register offset
1177ef270ab1SKenneth D. Merry * @param val 32-bit value to write
1178ef270ab1SKenneth D. Merry */
1179ef270ab1SKenneth D. Merry extern void ocs_reg_write32(ocs_os_handle_t os, uint32_t rset, uint32_t off, uint32_t val);
1180ef270ab1SKenneth D. Merry
1181ef270ab1SKenneth D. Merry /**
1182ef270ab1SKenneth D. Merry * @ingroup os
1183ef270ab1SKenneth D. Merry * @brief Write a PCI register
1184ef270ab1SKenneth D. Merry *
1185ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1186ef270ab1SKenneth D. Merry * @param rset Which "register set" to use
1187ef270ab1SKenneth D. Merry * @param off Register offset
1188ef270ab1SKenneth D. Merry * @param val 16-bit value to write
1189ef270ab1SKenneth D. Merry */
1190ef270ab1SKenneth D. Merry extern void ocs_reg_write16(ocs_os_handle_t os, uint32_t rset, uint32_t off, uint16_t val);
1191ef270ab1SKenneth D. Merry
1192ef270ab1SKenneth D. Merry /**
1193ef270ab1SKenneth D. Merry * @ingroup os
1194ef270ab1SKenneth D. Merry * @brief Write a PCI register
1195ef270ab1SKenneth D. Merry *
1196ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1197ef270ab1SKenneth D. Merry * @param rset Which "register set" to use
1198ef270ab1SKenneth D. Merry * @param off Register offset
1199ef270ab1SKenneth D. Merry * @param val 8-bit value to write
1200ef270ab1SKenneth D. Merry */
1201ef270ab1SKenneth D. Merry extern void ocs_reg_write8(ocs_os_handle_t os, uint32_t rset, uint32_t off, uint8_t val);
1202ef270ab1SKenneth D. Merry
1203ef270ab1SKenneth D. Merry /**
1204ef270ab1SKenneth D. Merry * @ingroup os
1205ef270ab1SKenneth D. Merry * @brief Disable interrupts
1206ef270ab1SKenneth D. Merry *
1207ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1208ef270ab1SKenneth D. Merry */
1209ef270ab1SKenneth D. Merry extern void ocs_intr_disable(ocs_os_handle_t os);
1210ef270ab1SKenneth D. Merry
1211ef270ab1SKenneth D. Merry /**
1212ef270ab1SKenneth D. Merry * @ingroup os
1213ef270ab1SKenneth D. Merry * @brief Enable interrupts
1214ef270ab1SKenneth D. Merry *
1215ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1216ef270ab1SKenneth D. Merry */
1217ef270ab1SKenneth D. Merry extern void ocs_intr_enable(ocs_os_handle_t os);
1218ef270ab1SKenneth D. Merry
1219ef270ab1SKenneth D. Merry /**
1220ef270ab1SKenneth D. Merry * @ingroup os
1221ef270ab1SKenneth D. Merry * @brief Return model string
1222ef270ab1SKenneth D. Merry *
1223ef270ab1SKenneth D. Merry * @param os OS specific handle or driver context
1224ef270ab1SKenneth D. Merry */
1225ef270ab1SKenneth D. Merry extern const char *ocs_pci_model(uint16_t vendor, uint16_t device);
1226ef270ab1SKenneth D. Merry
1227ef270ab1SKenneth D. Merry extern void ocs_print_stack(void);
1228ef270ab1SKenneth D. Merry
1229ef270ab1SKenneth D. Merry extern void ocs_abort(void) __attribute__((noreturn));
1230ef270ab1SKenneth D. Merry
1231ef270ab1SKenneth D. Merry /***************************************************************************
1232ef270ab1SKenneth D. Merry * Reference counting
1233ef270ab1SKenneth D. Merry *
1234ef270ab1SKenneth D. Merry */
1235ef270ab1SKenneth D. Merry
1236ef270ab1SKenneth D. Merry /**
1237ef270ab1SKenneth D. Merry * @ingroup os
1238ef270ab1SKenneth D. Merry * @brief reference counter object
1239ef270ab1SKenneth D. Merry */
1240ef270ab1SKenneth D. Merry typedef void (*ocs_ref_release_t)(void *arg);
1241ef270ab1SKenneth D. Merry typedef struct ocs_ref_s {
1242ef270ab1SKenneth D. Merry ocs_ref_release_t release; /* release function to call */
1243ef270ab1SKenneth D. Merry void *arg;
1244ef270ab1SKenneth D. Merry uint32_t count; /* ref count; no need to be atomic if we have a lock */
1245ef270ab1SKenneth D. Merry } ocs_ref_t;
1246ef270ab1SKenneth D. Merry
1247ef270ab1SKenneth D. Merry /**
1248ef270ab1SKenneth D. Merry * @ingroup os
1249ef270ab1SKenneth D. Merry * @brief initialize given reference object
1250ef270ab1SKenneth D. Merry *
1251ef270ab1SKenneth D. Merry * @param ref Pointer to reference object
1252ef270ab1SKenneth D. Merry * @param release Function to be called when count is 0.
1253ef270ab1SKenneth D. Merry * @param arg Argument to be passed to release function.
1254ef270ab1SKenneth D. Merry */
1255ef270ab1SKenneth D. Merry static inline void
ocs_ref_init(ocs_ref_t * ref,ocs_ref_release_t release,void * arg)1256ef270ab1SKenneth D. Merry ocs_ref_init(ocs_ref_t *ref, ocs_ref_release_t release, void *arg)
1257ef270ab1SKenneth D. Merry {
1258ef270ab1SKenneth D. Merry ref->release = release;
1259ef270ab1SKenneth D. Merry ref->arg = arg;
1260ef270ab1SKenneth D. Merry ocs_atomic_init(&ref->count, 1);
1261ef270ab1SKenneth D. Merry }
1262ef270ab1SKenneth D. Merry
1263ef270ab1SKenneth D. Merry /**
1264ef270ab1SKenneth D. Merry * @ingroup os
1265ef270ab1SKenneth D. Merry * @brief Return reference count value
1266ef270ab1SKenneth D. Merry *
1267ef270ab1SKenneth D. Merry * @param ref Pointer to reference object
1268ef270ab1SKenneth D. Merry *
1269ef270ab1SKenneth D. Merry * @return Count value of given reference object
1270ef270ab1SKenneth D. Merry */
1271ef270ab1SKenneth D. Merry static inline uint32_t
ocs_ref_read_count(ocs_ref_t * ref)1272ef270ab1SKenneth D. Merry ocs_ref_read_count(ocs_ref_t *ref)
1273ef270ab1SKenneth D. Merry {
1274ef270ab1SKenneth D. Merry return ocs_atomic_read(&ref->count);
1275ef270ab1SKenneth D. Merry }
1276ef270ab1SKenneth D. Merry
1277ef270ab1SKenneth D. Merry /**
1278ef270ab1SKenneth D. Merry * @ingroup os
1279ef270ab1SKenneth D. Merry * @brief Set count on given reference object to a value.
1280ef270ab1SKenneth D. Merry *
1281ef270ab1SKenneth D. Merry * @param ref Pointer to reference object
1282ef270ab1SKenneth D. Merry * @param i Set count to this value
1283ef270ab1SKenneth D. Merry */
1284ef270ab1SKenneth D. Merry static inline void
ocs_ref_set(ocs_ref_t * ref,int i)1285ef270ab1SKenneth D. Merry ocs_ref_set(ocs_ref_t *ref, int i)
1286ef270ab1SKenneth D. Merry {
1287ef270ab1SKenneth D. Merry ocs_atomic_set(&ref->count, i);
1288ef270ab1SKenneth D. Merry }
1289ef270ab1SKenneth D. Merry
1290ef270ab1SKenneth D. Merry /**
1291ef270ab1SKenneth D. Merry * @ingroup os
1292ef270ab1SKenneth D. Merry * @brief Take a reference on given object.
1293ef270ab1SKenneth D. Merry *
1294ef270ab1SKenneth D. Merry * @par Description
1295ef270ab1SKenneth D. Merry * This function takes a reference on an object.
1296ef270ab1SKenneth D. Merry *
1297ef270ab1SKenneth D. Merry * Note: this function should only be used if the caller can
1298ef270ab1SKenneth D. Merry * guarantee that the reference count is >= 1 and will stay >= 1
1299ef270ab1SKenneth D. Merry * for the duration of this call (i.e. won't go to zero). If it
1300ef270ab1SKenneth D. Merry * can't (the refcount may go to zero during this call),
1301ef270ab1SKenneth D. Merry * ocs_ref_get_unless_zero() should be used instead.
1302ef270ab1SKenneth D. Merry *
1303ef270ab1SKenneth D. Merry * @param ref Pointer to reference object
1304ef270ab1SKenneth D. Merry *
1305ef270ab1SKenneth D. Merry */
1306ef270ab1SKenneth D. Merry static inline void
ocs_ref_get(ocs_ref_t * ref)1307ef270ab1SKenneth D. Merry ocs_ref_get(ocs_ref_t *ref)
1308ef270ab1SKenneth D. Merry {
1309ef270ab1SKenneth D. Merry ocs_atomic_add_return(&ref->count, 1);
1310ef270ab1SKenneth D. Merry }
1311ef270ab1SKenneth D. Merry
1312ef270ab1SKenneth D. Merry /**
1313ef270ab1SKenneth D. Merry * @ingroup os
1314ef270ab1SKenneth D. Merry * @brief Take a reference on given object if count is not zero.
1315ef270ab1SKenneth D. Merry *
1316ef270ab1SKenneth D. Merry * @par Description
1317ef270ab1SKenneth D. Merry * This function takes a reference on an object if and only if
1318ef270ab1SKenneth D. Merry * the given reference object is "active" or valid.
1319ef270ab1SKenneth D. Merry *
1320ef270ab1SKenneth D. Merry * @param ref Pointer to reference object
1321ef270ab1SKenneth D. Merry *
1322ef270ab1SKenneth D. Merry * @return non-zero if "get" succeeded; Return zero if ref count
1323ef270ab1SKenneth D. Merry * is zero.
1324ef270ab1SKenneth D. Merry */
1325ef270ab1SKenneth D. Merry static inline uint32_t
ocs_ref_get_unless_zero(ocs_ref_t * ref)1326ef270ab1SKenneth D. Merry ocs_ref_get_unless_zero(ocs_ref_t *ref)
1327ef270ab1SKenneth D. Merry {
1328ef270ab1SKenneth D. Merry uint32_t rc = 0;
1329ef270ab1SKenneth D. Merry rc = ocs_atomic_read(&ref->count);
1330ef270ab1SKenneth D. Merry if (rc != 0) {
1331ef270ab1SKenneth D. Merry ocs_atomic_add_return(&ref->count, 1);
1332ef270ab1SKenneth D. Merry }
1333ef270ab1SKenneth D. Merry return rc;
1334ef270ab1SKenneth D. Merry }
1335ef270ab1SKenneth D. Merry
1336ef270ab1SKenneth D. Merry /**
1337ef270ab1SKenneth D. Merry * @ingroup os
1338ef270ab1SKenneth D. Merry * @brief Decrement reference on given object
1339ef270ab1SKenneth D. Merry *
1340ef270ab1SKenneth D. Merry * @par Description
1341ef270ab1SKenneth D. Merry * This function decrements the reference count on the given
1342ef270ab1SKenneth D. Merry * reference object. If the reference count becomes zero, the
1343ef270ab1SKenneth D. Merry * "release" function (set during "init" time) is called.
1344ef270ab1SKenneth D. Merry *
1345ef270ab1SKenneth D. Merry * @param ref Pointer to reference object
1346ef270ab1SKenneth D. Merry *
1347ef270ab1SKenneth D. Merry * @return non-zero if release function was called; zero
1348ef270ab1SKenneth D. Merry * otherwise.
1349ef270ab1SKenneth D. Merry */
1350ef270ab1SKenneth D. Merry static inline uint32_t
ocs_ref_put(ocs_ref_t * ref)1351ef270ab1SKenneth D. Merry ocs_ref_put(ocs_ref_t *ref)
1352ef270ab1SKenneth D. Merry {
1353ef270ab1SKenneth D. Merry uint32_t rc = 0;
1354ef270ab1SKenneth D. Merry if (ocs_atomic_sub_return(&ref->count, 1) == 1) {
1355ef270ab1SKenneth D. Merry ref->release(ref->arg);
1356ef270ab1SKenneth D. Merry rc = 1;
1357ef270ab1SKenneth D. Merry }
1358ef270ab1SKenneth D. Merry return rc;
1359ef270ab1SKenneth D. Merry }
1360ef270ab1SKenneth D. Merry
1361ef270ab1SKenneth D. Merry /**
1362ef270ab1SKenneth D. Merry * @ingroup os
1363ef270ab1SKenneth D. Merry * @brief Get the OS system ticks
1364ef270ab1SKenneth D. Merry *
1365ef270ab1SKenneth D. Merry * @return number of ticks that have occurred since the system
1366ef270ab1SKenneth D. Merry * booted.
1367ef270ab1SKenneth D. Merry */
1368ef270ab1SKenneth D. Merry static inline uint64_t
ocs_get_os_ticks(void)1369ef270ab1SKenneth D. Merry ocs_get_os_ticks(void)
1370ef270ab1SKenneth D. Merry {
1371ef270ab1SKenneth D. Merry return ticks;
1372ef270ab1SKenneth D. Merry }
1373ef270ab1SKenneth D. Merry
1374ef270ab1SKenneth D. Merry /**
1375ef270ab1SKenneth D. Merry * @ingroup os
1376ef270ab1SKenneth D. Merry * @brief Get the OS system tick frequency
1377ef270ab1SKenneth D. Merry *
1378ef270ab1SKenneth D. Merry * @return frequency of system ticks.
1379ef270ab1SKenneth D. Merry */
1380ef270ab1SKenneth D. Merry static inline uint32_t
ocs_get_os_tick_freq(void)1381ef270ab1SKenneth D. Merry ocs_get_os_tick_freq(void)
1382ef270ab1SKenneth D. Merry {
1383ef270ab1SKenneth D. Merry return hz;
1384ef270ab1SKenneth D. Merry }
1385ef270ab1SKenneth D. Merry
1386ef270ab1SKenneth D. Merry /*****************************************************************************
1387ef270ab1SKenneth D. Merry *
1388ef270ab1SKenneth D. Merry * CPU topology API
1389ef270ab1SKenneth D. Merry */
1390ef270ab1SKenneth D. Merry
1391ef270ab1SKenneth D. Merry typedef struct {
1392ef270ab1SKenneth D. Merry uint32_t num_cpus; /* Number of CPU cores */
1393ef270ab1SKenneth D. Merry uint8_t hyper; /* TRUE if threaded CPUs */
1394ef270ab1SKenneth D. Merry } ocs_cpuinfo_t;
1395ef270ab1SKenneth D. Merry
1396ef270ab1SKenneth D. Merry extern int32_t ocs_get_cpuinfo(ocs_cpuinfo_t *cpuinfo);
1397ef270ab1SKenneth D. Merry extern uint32_t ocs_get_num_cpus(void);
1398ef270ab1SKenneth D. Merry
1399ef270ab1SKenneth D. Merry #include "ocs_list.h"
1400ef270ab1SKenneth D. Merry #include "ocs_utils.h"
1401ef270ab1SKenneth D. Merry #include "ocs_mgmt.h"
1402ef270ab1SKenneth D. Merry #include "ocs_common.h"
1403ef270ab1SKenneth D. Merry
1404ef270ab1SKenneth D. Merry #endif /* !_OCS_OS_H */
1405