1/*- 2 * Copyright (c) 2010 Isilon Systems, Inc. 3 * Copyright (c) 2010 iX Systems, Inc. 4 * Copyright (c) 2010 Panasas, Inc. 5 * Copyright (c) 2013-2016 Mellanox Technologies, Ltd. 6 * Copyright (c) 2014-2015 François Tigeot 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice unmodified, this list of conditions, and the following 14 * disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30#ifndef _LINUXKPI_LINUX_KERNEL_H_ 31#define _LINUXKPI_LINUX_KERNEL_H_ 32 33#include "errno.h" 34#include "string.h" 35#include "unistd.h" 36#include "pthread.h" 37#include "sys/systm.h" 38#include "sys/time.h" 39#include "sys/mman.h" 40 41#include "linux/types.h" 42#include "linux/slab.h" 43#include "linux/semaphore.h" 44#include "linux/atomic.h" 45#include "linux/spinlock.h" 46#include "linux/list.h" 47#include "linux/io.h" 48#include "linux/compiler.h" 49#include "user_copy.h" 50#ifdef LOSCFG_FS_VFS 51#include "fs/fs.h" 52#endif 53#include "los_exc.h" 54 55#ifdef __cplusplus 56#if __cplusplus 57extern "C" { 58#endif /* __cplusplus */ 59#endif /* __cplusplus */ 60 61#define printk dprintf /* Do not modify for code check */ 62 63#define jiffies 0 64#ifndef HZ 65#define HZ LOSCFG_BASE_CORE_TICK_PER_SECOND 66#endif 67 68#define SZ_1K (0x00000400) 69#define __init 70#define __exit 71#define __user 72 73#define ERR_PTR(err) ((void*)(unsigned long)(err)) 74#define PTR_ERR(err) ((unsigned long)(err)) 75#define IS_ERR(err) ((unsigned long)(err) > (unsigned long)-1000L) 76#define ERR_CAST(err) ((void *)err) 77 78#define COMPAT_KERN_EMERG "<0>" /* system is unusable */ 79#define COMPAT_KERN_ALERT "<1>" /* action must be taken immediately */ 80#define COMPAT_KERN_CRIT "<2>" /* critical conditions */ 81#define COMPAT_KERN_ERR "<3>" /* error conditions */ 82#define COMPAT_KERN_WARNING "<4>" /* warning conditions */ 83#define COMPAT_KERN_NOTICE "<5>" /* normal but significant condition */ 84#define COMPAT_KERN_INFO "<6>" /* informational */ 85#define COMPAT_KERN_DEBUG "<7>" /* debug-level messages */ 86#define COMPAT_KERN_CONT "<c>" 87 88#ifndef pr_fmt 89#define pr_fmt(fmt) fmt 90#endif 91 92#define pr_emerg(fmt, ...) \ 93 dprintf(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__) 94#define pr_alert(fmt, ...) \ 95 dprintf(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) 96#define pr_crit(fmt, ...) \ 97 dprintf(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) 98#define pr_err(fmt, ...) \ 99 dprintf(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) 100#define pr_warning(fmt, ...) \ 101 dprintf(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) 102#define pr_warn pr_warning 103#define pr_notice(fmt, ...) \ 104 dprintf(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) 105#define pr_info(fmt, ...) \ 106 dprintf(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) 107#define pr_cont(fmt, ...) \ 108 dprintf(KERN_CONT fmt, ##__VA_ARGS__) 109 110/* pr_devel() should produce zero code unless DEBUG is defined */ 111#ifdef DEBUG 112#define pr_devel(fmt, ...) \ 113 dprintf(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) 114#else 115#define pr_devel(fmt, ...) do {} while (0) 116#endif 117/* If you are writing a driver, please use dev_dbg instead */ 118#if defined(DEBUG) 119#define pr_debug(fmt, ...) \ 120 dprintf(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) 121#else 122#define pr_debug(fmt, ...) do {} while (0) 123#endif 124 125#define WARN_ON(condition) do {} while (0) 126 127#ifndef min 128#define min(x, y) ((x) < (y) ? (x) : (y)) 129#endif 130 131#ifndef max 132#define max(x, y) ((x) < (y) ? (y) : (x)) 133#endif 134 135#ifndef min_t 136#define min_t(t, x, y) ((t)(x) < (t)(y) ? (t)(x) : (t)(y)) 137#endif 138 139#define BUG() do { \ 140 panic("BUG() at %s %d\n", __FUNCTION__, __LINE__); \ 141} while (0) 142 143#define BUG_ON(condition) do { \ 144 if (condition) { \ 145 BUG(); \ 146 } \ 147} while (0) 148 149#define __setup(str, fn) 150 151/** 152 * @ingroup linux_kernel 153 * @brief change jiffies time to tick (not supported). 154 * 155 * @par Description: 156 * This API is used to change jiffies time to tick time. 157 * 158 * @attention 159 * <ul> 160 * <li>None.</li> 161 * </ul> 162 * 163 * @param j [IN] the jiffies time value. 164 * 165 * @retval Tick time value The value of tick time. 166 * @par Dependency: 167 * <ul><li> kernel.h: the header file that contains the API declaration.</li></ul> 168 * @see None. 169 */ 170extern UINT64 jiffies_to_tick(unsigned long j); 171 172/** 173 * @ingroup linux_kernel 174 * @brief Delay a task. 175 * 176 * @par Description: 177 * This API is used to delay the execution of the current task. The task is able to be scheduled 178 * after it is delayed for a specified number of Ticks. 179 * 180 * @attention 181 * <ul> 182 * <li>The task fails to be delayed if it is being delayed during interrupt processing or it is locked.</li> 183 * <li>If 0 is passed in and the task scheduling is not locked, execute the next task in the queue of 184 * tasks with the priority of the current task. 185 * If no ready task with the priority of the current task is available, the task scheduling will not occur, 186 * and the current task continues to be executed.</li> 187 * </ul> 188 * 189 * @param timeout [IN] Type #signed long Number of Ticks for which the task is delayed(unit: Tick). 190 * 191 * @retval #LOS_ERRNO_SWTMR_HWI_ACTIVE The software timer is being used during an interrupt. 192 * @retval #LOS_OK The task is successfully delayed. 193 * @retval #LOS_ERRNO_SWTMR_NOT_STARTED The software timer is not started. 194 * @par Dependency: 195 * <ul><li>kernel.h: the header file that contains the API declaration.</li></ul> 196 * @see 197 */ 198signed long schedule_timeout(signed long timeout); 199#define schedule_timeout_uninterruptible(t) schedule_timeout(t) 200#define schedule_timeout_interruptible(t) schedule_timeout(t) 201 202#define in_interrupt() (0) 203 204/** 205 * @ingroup linux_kernel 206 * @brief do division implimentation. 207 * 208 * @par Description: 209 * This API is used to do a division implimentation,and return the remainder 210 * 211 * @attention 212 * <ul> 213 * <li>the param n should point to a valid address.</li> 214 * <li>the param base should not be 0.</li> 215 * </ul> 216 * 217 * @param n [IN/OUT] the dividend as IN,the quotient as OUT 218 * @param base [IN] the divisor 219 * @retval remainder 220 * @par Dependency: 221 * <ul><li>kernel.h: the header file that contains the API declaration.</li></ul> 222 * @see 223 */ 224extern UINT32 do_div_imp(UINT64 *n, UINT32 base); 225 226/** 227 * @ingroup linux_kernel 228 * @brief do division implimentation. 229 * 230 * @par Description: 231 * This API is used to do a division implimentation,and return the remainder 232 * 233 * @attention 234 * <ul> 235 * <li>the param n should point to a valid address.</li> 236 * <li>the param base should not be 0.</li> 237 * </ul> 238 * 239 * @param n [IN/OUT] the dividend as IN,the quotient as OUT 240 * @param base [IN] the divisor > 0 241 * @retval remainder 242 * @par Dependency: 243 * <ul><li>kernel.h: the header file that contains the API declaration.</li></ul> 244 * @see 245 */ 246extern INT32 do_div_s64_imp(INT64 *n, INT32 base); 247 248/** 249 * @ingroup linux_kernel 250 * @brief do division implimentation. 251 * 252 * @par Description: 253 * This API is used to do a division implimentation,and return the quotient 254 * 255 * @attention 256 * <ul> 257 * <li>the param divisor should not be 0.</li> 258 * </ul> 259 * 260 * @param dividend [IN] the dividend as IN 261 * @param divisor [IN] the divisor > 0 262 * @retval quotient 263 * @par Dependency: 264 * <ul><li>kernel.h: the header file that contains the API declaration.</li></ul> 265 * @see 266 */ 267static inline UINT64 div64_u64(UINT64 dividend, UINT64 divisor) 268{ 269 return dividend / divisor; 270} 271 272/** 273 * @ingroup linux_kernel 274 * @brief do division implimentation. 275 * 276 * @par Description: 277 * This API is used to do a division implimentation,and return the quotient 278 * 279 * @attention 280 * <ul> 281 * <li>the param divisor should not be 0.</li> 282 * </ul> 283 * 284 * @param dividend [IN] the dividend as IN 285 * @param divisor [IN] the divisor not is 0 286 * @retval quotient 287 * @par Dependency: 288 * <ul><li>kernel.h: the header file that contains the API declaration.</li></ul> 289 * @see 290 */ 291static inline INT64 div64_s64(INT64 dividend, INT64 divisor) 292{ 293 return dividend / divisor; 294} 295 296#define do_div(n, base) ({ \ 297 UINT32 tmpBase = (base); \ 298 UINT32 rem; \ 299 rem = ((UINT64)(n)) % tmpBase; \ 300 (n) = ((UINT64)(n)) / tmpBase; \ 301 rem; \ 302}) 303 304/** 305 * @ingroup linux_kernel 306 * @brief do division implimentation. 307 * 308 * @par Description: 309 * This API is used to do a division implimentation,and return the quotient ,and remainder as OUT 310 * 311 * @attention 312 * <ul> 313 * <li>the param divisor should not be 0.</li> 314 * <li>the param remainder should point to a valid address.</li> 315 * </ul> 316 * 317 * @param dividend [IN] the dividend as IN 318 * @param divisor [IN] the divisor is not 0 ,and as IN 319 * @param remainder [OUT] the remainder should point to a valid address. remainder as OUT 320 * @retval quotient 321 * @par Dependency: 322 * <ul><li>kernel.h: the header file that contains the API declaration and implimentation.</li></ul> 323 * @see 324 */ 325static inline INT64 div_s64_rem(INT64 dividend, INT32 divisor, INT32 *remainder) 326{ 327 *remainder = dividend % divisor; 328 return dividend / divisor; 329} 330 331/** 332 * @ingroup linux_kernel 333 * @brief do division implimentation. 334 * 335 * @par Description: 336 * This API is used to do a division implimentation,and return the quotient, and remainder as OUT 337 * 338 * @attention 339 * <ul> 340 * <li>the param divisor should be greater than 0.</li> 341 * <li>the param remainder should point to a valid address.</li> 342 * </ul> 343 * 344 * @param dividend [IN] the dividend as IN 345 * @param divisor [IN] the divisor is greater than 0, and as IN 346 * @param remainder [OUT] the remainder should point to a valid address. remainder as OUT 347 * @retval quotient 348 * @par Dependency: 349 * <ul><li>kernel.h: the header file that contains the API declaration and implimentation.</li></ul> 350 * @see 351 */ 352static inline UINT64 div64_u64_rem(UINT64 dividend, UINT64 divisor, UINT64 *remainder) 353{ 354 *remainder = dividend % divisor; 355 return dividend / divisor; 356} 357 358/** 359 * @ingroup linux_kernel 360 * @brief do division implimentation. 361 * 362 * @par Description: 363 * This API is used to do a division implimentation,and return the quotient,and remainder as OUT 364 * 365 * @attention 366 * <ul> 367 * <li>the param divisor should be greater than 0.</li> 368 * <li>the param remainder should point to a valid address.</li> 369 * </ul> 370 * 371 * @param dividend [IN] the dividend as IN 372 * @param divisor [IN] the divisor is greater than 0, and as IN 373 * @param remainder [OUT] the remainder should point to a valid address. remainder as OUT 374 * @retval quotient 375 * @par Dependency: 376 * <ul><li>kernel.h: the header file that contains the API declaration and implimentation.</li></ul> 377 * @see 378 */ 379static inline UINT64 div_u64_rem(UINT64 dividend, UINT32 divisor, UINT32 *remainder) 380{ 381 *remainder = dividend % divisor; 382 return dividend / divisor; 383} 384 385/** 386 * @ingroup linux_kernel 387 * @brief do division implimentation. 388 * 389 * @par Description: 390 * This API is used to do a division implimentation,and return the quotient 391 * 392 * @attention 393 * <ul> 394 * <li>the param divisor should not be 0.</li> 395 * </ul> 396 * 397 * @param dividend [IN] the dividend as IN 398 * @param divisor [IN] the divisor is not 0, and as IN 399 * @retval quotient 400 * @par Dependency: 401 * <ul><li>kernel.h: the header file that contains the API declaration and implimentation.</li></ul> 402 * @see 403 */ 404static inline INT64 div_s64(INT64 dividend, INT32 divisor) 405{ 406 INT32 remainder; 407 return div_s64_rem(dividend, divisor, &remainder); 408} 409 410/** 411 * @ingroup linux_kernel 412 * @brief do division implimentation. 413 * 414 * @par Description: 415 * This API is used to do a division implimentation,and return the quotient 416 * 417 * @attention 418 * <ul> 419 * <li>the param divisor should be greater than 0.</li> 420 * </ul> 421 * 422 * @param dividend [IN] the dividend as IN 423 * @param divisor [IN] the divisor is greater than 0, and as IN 424 * @retval quotient 425 * @par Dependency: 426 * <ul><li>kernel.h: the header file that contains the API declaration and implimentation.</li></ul> 427 * @see 428 */ 429static inline UINT64 div_u64(UINT64 dividend, UINT32 divisor) 430{ 431 UINT32 remainder; 432 return div_u64_rem(dividend, divisor, &remainder); 433} 434 435static inline unsigned long copy_from_user(void *to, const void *from, unsigned long n) 436{ 437 if ((to == NULL) || (from == NULL)) { 438 return (unsigned long)-1; 439 } 440 441 return LOS_ArchCopyFromUser(to, from, n); 442} 443 444static inline unsigned long copy_to_user(void *to, const void *from, unsigned long n) 445{ 446 if ((to == NULL) || (from == NULL)) { 447 return (unsigned long)-1; 448 } 449 450 return LOS_ArchCopyToUser(to, from, n); 451} 452 453extern void *ioremap(unsigned long phys_addr, unsigned long size); 454extern void *ioremap_cached(unsigned long phys_addr, unsigned long size); 455extern void *ioremap_nocache(unsigned long phys_addr, unsigned long size); 456extern void iounmap(void *addr); 457extern int remap_pfn_range(unsigned long addr, unsigned long pfn, unsigned long size, unsigned long prot); 458 459#ifndef io_remap_pfn_range 460#define io_remap_pfn_range remap_pfn_range 461#endif 462 463#define EXPORT_SYMBOL(x) 464 465typedef VOID (*unused_func_t)(VOID); 466 467struct file_operations { 468 struct module *owner; 469 unused_func_t llseek; 470 unused_func_t read; 471 unused_func_t write; 472 unused_func_t aio_read; 473 unused_func_t aio_write; 474 unused_func_t readdir; 475 unused_func_t poll; 476 unused_func_t unlocked_ioctl; 477 unused_func_t compat_ioctl; 478 unused_func_t mmap; 479 unused_func_t open; 480 unused_func_t flush; 481 unused_func_t release; 482 unused_func_t fsync; 483 unused_func_t aio_fsync; 484 unused_func_t fasync; 485 unused_func_t lock; 486 unused_func_t sendpage; 487 unused_func_t get_unmapped_area; 488 unused_func_t check_flags; 489 unused_func_t flock; 490 unused_func_t splice_write; 491 unused_func_t splice_read; 492 unused_func_t setlease; 493 unused_func_t fallocate; 494}; 495 496#define simple_strtol strtol 497#define do_gettimeofday(a) gettimeofday(a, NULL) 498#define DEFINE_MUTEX(m) pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; 499#define mutex_lock pthread_mutex_lock 500#define mutex_unlock pthread_mutex_unlock 501#define mutex_init(m) pthread_mutex_init(m, NULL) 502#define mutex_destroy(m) pthread_mutex_destroy((m)) 503 504static inline void printtime(void) 505{ 506 struct timeval time; 507 508 (VOID)gettimeofday(&time, NULL); 509 PRINTK("[time:%d.%03d]", time.tv_sec, time.tv_usec / 1000); /* 1000: millisecond to microseconds */ 510 return; 511} 512 513#define TRACETIME() do { \ 514 printtime(); \ 515 printk("func:%s, line %d\r\n", __FUNCTION__, __LINE__); \ 516} while (0) 517 518extern void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); 519extern int munmap(void *addr, size_t length); 520 521#define KERN_EMERG COMPAT_KERN_EMERG 522#define KERN_ALERT COMPAT_KERN_ALERT 523#define KERN_CRIT COMPAT_KERN_CRIT 524#define KERN_ERR COMPAT_KERN_ERR 525#define KERN_WARNING COMPAT_KERN_WARNING 526#define KERN_NOTICE COMPAT_KERN_NOTICE 527#define KERN_INFO COMPAT_KERN_INFO 528#define KERN_DEBUG COMPAT_KERN_DEBUG 529#define KERN_CONT COMPAT_KERN_CONT 530 531#ifdef __cplusplus 532#if __cplusplus 533} 534#endif /* __cplusplus */ 535#endif /* __cplusplus */ 536 537#endif /* _LINUXKPI_LINUX_KERNEL_H_ */ 538