portable_os.h

/* * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. *//* * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License * Version 2 or later at the following locations: * * http://www.opensource.org/licenses/gpl-license.html * http://www.gnu.org/copyleft/gpl.html */#ifndef PORTABLE_OS_H#define PORTABLE_OS_H/***************************************************************************//* * Add support for your target OS by checking appropriate flags and then * including the appropriate file. Don't forget to document the conditions * in the later documentation section at the beginning of the * DOXYGEN_PORTABLE_OS_DOC. */#if defined(LINUX_KERNEL)#include "linux_port.h"#elif defined(PORTABLE_OS)#include "check_portability.h"#else#error Target OS unsupported or unspecified#endif/***************************************************************************//*! * @file portable_os.h * * This file should be included by portable driver code in order to gain access * to the OS-specific header files. It is the only OS-related header file that * the writer of a portable driver should need. * * This file also contains the documentation for the common API. * * Begin reading the documentation for this file at the @ref index "main page". * *//*! * @if USE_MAINPAGE * @mainpage Generic OS API for STC Drivers * @endif * * @section intro_sec Introduction * * This defines the API / kernel programming environment for portable drivers. * * This API is broken up into several functional areas. It greatly limits the * choices of a device-driver author, but at the same time should allow for * greater portability of the resulting code. * * Each kernel-to-driver function (initialization function, interrupt service * routine, etc.) has a 'portable signature' which must be used, and a specific * function which must be called to generate the return statement. There is * one exception, a background task or "bottom half" routine, which instead has * a specific structure which must be followed. These signatures and function * definitions are found in @ref drsigs. * * None of these kernel-to-driver functions seem to get any arguments passed to * them. Instead, there are @ref drsigargs which allow one of these functions * to get at fairly generic parts of its calling arguments, if there are any. * * Almost every driver will have some need to call the operating system * @ref dkops is the list of services which are available to the driver. * * * @subsection warn_sec Warning * * The specifics of the types, values of the various enumerations * (unless specifically stated, like = 0), etc., are only here for illustrative * purposes. No attempts should be made to make use of any specific knowledge * gleaned from this documentation. These types are only meant to be passed in * and out of the API, and their contents are to be handled only by the * provided OS-specific functions. * * Also, note that the function may be provided as macros in some * implementations, or vice versa. * * * @section dev_sec Writing a Portable Driver * * First off, writing a portable driver means calling no function in an OS * except what is available through this header file. * * Secondly, all OS-called functions in your driver must be invoked and * referenced through the signature routines. * * Thirdly, there might be some rules which you can get away with ignoring or * violating on one OS, yet will cause your code not to be portable to a * different OS. * * * @section limit_sec Limitations * * This API is not expected to handle every type of driver which may be found * in an operating system. For example, it will not be able to handle the * usual design for something like a UART driver, where there are multiple * logical devices to access, because the design usually calls for some sort of * indication to the #OS_DEV_TASK() function or OS_DEV_ISR() to indicate which * channel is to be serviced by that instance of the task/function. This sort * of argument is missing in this API for functions like os_dev_schedule_task() and * os_register_interrupt(). * * * @section port_guide Porting Guidelines * * This section is intended for a developer who needs to port the header file * to an operating system which is not yet supported. * * This interface allows for a lot of flexibility when it comes to porting to * an operating systems device driver interface. There are three main areas to * examine: The use of Driver Routine Signatures, the use of Driver Argument * Access functions, the Calls to Kernel Functions, and Data Types. * * * @subsection port_sig Porting Driver Routine Signatures * * The three macros for each function (e.g. #OS_DEV_INIT(), #OS_DEV_INIT_DCL(), * and #OS_DEV_INIT_REF()) allow the flexibility of having a 'wrapper' function * with the OS-required signature, which would then call the user's function * with some different signature. * * The first form would lay down the wrapper function, followed by the * signature for the user function. The second form would lay down just the * signatures for both functions, and the last function would reference the * wrapper function, since that is the interface function called by the OS. * * Note that the driver author has no visibility at all to the signature of the * routines. The author can access arguments only through a limited set of * functions, and must return via another function. * * The Return Functions allow a lot of flexibility in converting the return * value, or not returning a value at all. These will likely be implemented as * macros. * * * @subsection port_arg Porting Driver Argument Access Functions * * The signatures defined by the guide will usually be replaced with macro * definitions. * * * @subsection port_dki Porting Calls to Kernel Functions * * The signatures defined by the guide may be replaced with macro definitions, * if that makes more sense. * * Implementors are free to ignore arguments which are not applicable to their * OS. * * @subsection port_datatypes Porting Data Types * * *//*************************************************************************** * Compile flags **************************************************************************//* * This compile flag should only be turned on when running doxygen to generate * the API documentation. */#ifdef DOXYGEN_PORTABLE_OS_DOC/*! * @todo module_init()/module_cleanup() for Linux need to be added to OS * abstractions. Also need EXPORT_SYMBOL() equivalent?? * *//* Drop OS differentation documentation here *//*! * \#define this flag to build your driver as a Linux driver */#define LINUX/* end OS differentation documentation *//*! * Symbol to give version number of the implementation file. Earliest * definition is in version 1.1, with value 101 (to mean version 1.1) */#define PORTABLE_OS_VERSION 101/* * NOTICE: The following definitions (the rest of the file) are not meant ever * to be compiled. Instead, they are the documentation for the portable OS * API, to be used by driver writers. * * Each individual OS port will define each of these types, functions, or * macros as appropriate to the target OS. This is why they are under the * DOXYGEN_PORTABLE_OS_DOC flag. *//*************************************************************************** * Type definitions **************************************************************************//*! * Type used for registering and deregistering interrupts. * * This is typically an interrupt channel number. */typedefintos_interrupt_id_t;
/*! * Type used as handle for a process * * See #os_get_process_handle() and #os_send_signal(). */typedefintos_process_handle_t;
/*! * Generic return code for functions which need such a thing. * * No knowledge should be assumed of the value of any of these symbols except * that @c OS_ERROR_OK_S is guaranteed to be zero. * * @todo Any other named values? What about (-EAGAIN? -ERESTARTSYS? Are they * too Linux/Unix-specific read()/write() return values) ? */typedefenum {
OS_ERROR_OK_S = 0, /*!< Success */OS_ERROR_FAIL_S, /*!< Generic driver failure */OS_ERROR_NO_MEMORY_S, /*!< Failure to acquire/use memory */OS_ERROR_BAD_ADDRESS_S, /*!< Bad address */OS_ERROR_BAD_ARG_S/*!< Bad input argument */
} os_error_code;
/*! * Handle to a lock. */typedefint *os_lock_t;
/*! * Context while locking. */typedefintos_lock_context_t;
/*! * An object which can be slept on and later used to wake any/all sleepers. */typedefint os_sleep_object_t;
/*! * Driver registration handle */typedefvoid *os_driver_reg_t;
/*! * Function signature for an #OS_DEV_INIT() function. * * @return A call to os_dev_init_return() function. */typedef void (*os_init_function_t) (void);
/*! * Function signature for an #OS_DEV_SHUTDOWN() function. * * @return A call to os_dev_shutdown_return() function. */typedef void (*os_shutdown_function_t) (void);
/*! * Function signature for a user-driver function. * * @return A call to the appropriate os_dev_xxx_return() function. */typedef void (*os_user_function_t) (void);
/*! * Function signature for the portable interrupt handler * * While it would be nice to know which interrupt is being serviced, the * Least Common Denominator rule says that no arguments get passed in. * * @return A call to #os_dev_isr_return() */typedef void (*os_interrupt_handler_t) (void);
/*! * Function signature for a task function * * Many task function definitions get some sort of generic argument so that the * same function can run across many (queues, channels, ...) as separate task * instances. This has been left out of this API. * * This function must be structured as documented by #OS_DEV_TASK(). * */typedef void (*os_task_fn_t) (void);
/*! * Function types which can be associated with driver entry points. These are * used in os_driver_add_registration(). * * Note that init and shutdown are absent. */typedefenum {
OS_FN_OPEN, /*!< open() operation handler. */OS_FN_CLOSE, /*!< close() operation handler. */OS_FN_READ, /*!< read() operation handler. */OS_FN_WRITE, /*!< write() operation handler. */OS_FN_IOCTL, /*!< ioctl() operation handler. */OS_FN_MMAP/*!< mmap() operation handler. */
} os_driver_fn_t;
/*************************************************************************** * Driver-to-Kernel Operations **************************************************************************//*! * @defgroup dkops Driver-to-Kernel Operations * * These are the operations which drivers should call to get the OS to perform * services. *//*! @addtogroup dkops *//*! @{ *//*! * Register an interrupt handler. * * @param driver_name The name of the driver * @param interrupt_id The interrupt line to monitor (type * #os_interrupt_id_t) * @param function The function to be called to handle an interrupt * * @return #os_error_code */os_error_codeos_register_interrupt(char *driver_name,
os_interrupt_id_t interrupt_id,
os_interrupt_handler_t function);
/*! * Deregister an interrupt handler. * * @param interrupt_id The interrupt line to stop monitoring * * @return #os_error_code */os_error_codeos_deregister_interrupt(os_interrupt_id_t interrupt_id);
/*! * Initialize driver registration. * * If the driver handles open(), close(), ioctl(), read(), write(), or mmap() * calls, then it needs to register their location with the kernel so that they * get associated with the device. * * @param handle The handle object to be used with this registration. The * object must live (be in memory somewhere) at least until * os_driver_remove_registration() is called. * * @return An os error code. */os_error_codeos_driver_init_registration(os_driver_reg_t handle);
/*! * Add a function registration to driver registration. * * @param handle The handle used with #os_driver_init_registration(). * @param name Which function is being supported. * @param function The result of a call to a @c _REF version of one of the * driver function signature macros * driver function signature macros * @return void */voidos_driver_add_registration(os_driver_reg_t handle, os_driver_fn_t name,
void *function);
/*! * Finalize the driver registration with the kernel. * * Upon return from this call, the driver may begin receiving calls at the * defined entry points. * * @param handle The handle used with #os_driver_init_registration(). * @param major The major device number to be associated with the driver. * If this value is zero, a major number may be assigned. * See #os_driver_get_major() to determine final value. * #os_driver_remove_registration(). * @param driver_name The driver name. Can be used as part of 'device node' * name on platforms which support such a feature. * * @return An error code */os_error_codeos_driver_complete_registration(os_driver_reg_t handle,
int major, char *driver_name);
/*! * Get driver Major Number from handle after a successful registration. * * @param handle A handle which has completed registration. * * @return The major number (if any) associated with the handle. */
uint32_t os_driver_get_major(os_driver_reg_t handle);
/*! * Remove the driver's registration with the kernel. * * Upon return from this call, the driver not receive any more calls at the * defined entry points (other than ISR and shutdown). * * @param major The major device number to be associated with the driver. * @param driver_name The driver name * * @return An error code. */os_error_codeos_driver_remove_registration(int major, char *driver_name);
/*! * Print a message to console / into log file. After the @c msg argument a * number of printf-style arguments may be added. Types should be limited to * printf string, char, octal, decimal, and hexadecimal types. (This excludes * pointers, and floating point). * * @param msg The message to print to console / system log * * @return (void) */voidos_printk(char *msg, ...);
/*! * Allocate some kernel memory * * @param amount Number of 8-bit bytes to allocate * @param flags Some indication of purpose of memory (needs definition) * * @return Pointer to allocated memory, or NULL if failed. */void *os_alloc_memory(unsigned amount, intflags);
/*! * Free some kernel memory * * @param location The beginning of the region to be freed. * * Do some OSes have separate free() functions which should be * distinguished by passing in @c flags here, too? Don't some also require the * size of the buffer being freed? Perhaps separate routines for each * alloc/free pair (DMAable, etc.)? */voidos_free_memory(void *location);
/*! * Allocate cache-coherent memory * * @param amount Number of bytes to allocate * @param[out] dma_addrp Location to store physical address of allocated * memory. * @param flags Some indication of purpose of memory (needs * definition). * * @return (virtual space) pointer to allocated memory, or NULL if failed. * */void *os_alloc_coherent(unsigned amount, uint32_t * dma_addrp, intflags);
/*! * Free cache-coherent memory * * @param size Number of bytes which were allocated. * @param[out] virt_addr Virtual(kernel) address of memory.to be freed, as * returned by #os_alloc_coherent(). * @param[out] dma_addr Physical address of memory.to be freed, as returned * by #os_alloc_coherent(). * * @return void * */voidos_free_coherent(unsigned size, void *virt_addr, uint32_t dma_addr);
/*! * Map an I/O space into kernel memory space * * @param start The starting address of the (physical / io space) region * @param range_bytes The number of bytes to map * * @return A pointer to the mapped area, or NULL on failure */void *os_map_device(uint32_t start, unsigned range_bytes);
/*! * Unmap an I/O space from kernel memory space * * @param start The starting address of the (virtual) region * @param range_bytes The number of bytes to unmap * * @return None */voidos_unmap_device(void *start, unsigned range_bytes);
/*! * Copy data from Kernel space to User space * * @param to The target location in user memory * @param from The source location in kernel memory * @param size The number of bytes to be copied * * @return #os_error_code */os_error_codeos_copy_to_user(void *to, void *from, unsigned size);
/*! * Copy data from User space to Kernel space * * @param to The target location in kernel memory * @param from The source location in user memory * @param size The number of bytes to be copied * * @return #os_error_code */os_error_codeos_copy_from_user(void *to, void *from, unsigned size);
/*! * Read an 8-bit device register * * @param register_address The (bus) address of the register to write to * @return The value in the register */
uint8_t os_read8(uint8_t * register_address);
/*! * Write an 8-bit device register * * @param register_address The (bus) address of the register to write to * @param value The value to write into the register */voidos_write8(uint8_t * register_address, uint8_t value);
/*! * Read a 16-bit device register * * @param register_address The (bus) address of the register to write to * @return The value in the register */
uint16_t os_read16(uint16_t * register_address);
/*! * Write a 16-bit device register * * @param register_address The (bus) address of the register to write to * @param value The value to write into the register */voidos_write16(uint16_t * register_address, uint16_t value);
/*! * Read a 32-bit device register * * @param register_address The (bus) address of the register to write to * @return The value in the register */
uint32_t os_read32(uint32_t * register_address);
/*! * Write a 32-bit device register * * @param register_address The (bus) address of the register to write to * @param value The value to write into the register */voidos_write32(uint32_t * register_address, uint32_t value);
/*! * Read a 64-bit device register * * @param register_address The (bus) address of the register to write to * @return The value in the register */
uint64_t os_read64(uint64_t * register_address);
/*! * Write a 64-bit device register * * @param register_address The (bus) address of the register to write to * @param value The value to write into the register */voidos_write64(uint64_t * register_address, uint64_t value);
/*! * Prepare a task to execute the given function. This should only be done once * per task, during the driver's initialization routine. * * @param task_fn Name of the OS_DEV_TASK() function to be created. * * @return an OS ERROR code. */
os_error os_create_task(os_task_fn_t * task_fn);
/*! * Run the task associated with an #OS_DEV_TASK() function * * The task will begin execution sometime after or during this call. * * @param task_fn Name of the OS_DEV_TASK() function to be scheduled. * * @return void */voidos_dev_schedule_task(os_task_fn_t * task_fn);
/*! * Make sure that task is no longer running and will no longer run. * * This function will not return until both are true. This is useful when * shutting down a driver. * * @param task_fn Name of the OS_DEV_TASK() funciton to be stopped. * */void os_stop_task(os_task_fn_t * task_fn);
/*! * Delay some number of microseconds * * Note that this is a busy-loop, not a suspension of the task/process. * * @param msecs The number of microseconds to delay * * @return void */voidos_mdelay(unsignedlong msecs);
/*! * Calculate virtual address from physical address * * @param pa Physical address * * @return virtual address * * @note this assumes that addresses are 32 bits wide */void *os_va(uint32_t pa);
/*! * Calculate physical address from virtual address * * * @param va Virtual address * * @return physical address * * @note this assumes that addresses are 32 bits wide */
uint32_t os_pa(void *va);
/*! * Allocate and initialize a lock, returning a lock handle. * * The lock state will be initialized to 'unlocked'. * * @return A lock handle, or NULL if an error occurred. */os_lock_tos_lock_alloc_init(void);
/*! * Acquire a lock. * * This function should only be called from an interrupt service routine. * * @param lock_handle A handle to the lock to acquire. * * @return void */voidos_lock(os_lock_t lock_handle);
/*! * Unlock a lock. Lock must have been acquired by #os_lock(). * * @param lock_handle A handle to the lock to unlock. * * @return void */voidos_unlock(os_lock_t lock_handle);
/*! * Acquire a lock in non-ISR context * * This function will spin until the lock is available. * * @param lock_handle A handle of the lock to acquire. * @param context Place to save the before-lock context * * @return void */voidos_lock_save_context(os_lock_t lock_handle, os_lock_context_t context);
/*! * Release a lock in non-ISR context * * @param lock_handle A handle of the lock to release. * @param context Place where before-lock context was saved. * * @return void */voidos_unlock_restore_context(os_lock_t lock_handle,
os_lock_context_t context);
/*! * Deallocate a lock handle. * * @param lock_handle An #os_lock_t that has been allocated. * * @return void */voidos_lock_deallocate(os_lock_t lock_handle);
/*! * Determine process handle * * The process handle of the current user is returned. * * @return A handle on the current process. */os_process_handle_tos_get_process_handle();
/*! * Send a signal to a process * * @param proc A handle to the target process. * @param sig The POSIX signal to send to that process. */voidos_send_signal(os_process_handle_t proc, int sig);
/*! * Get some random bytes * * @param buf The location to store the random data. * @param count The number of bytes to store. * * @return void */voidos_get_random_bytes(void *buf, unsigned count);
/*! * Go to sleep on an object. * * Example: code = os_sleep(my_queue, available_count == 0, 0); * * @param object The object on which to sleep * @param condition An expression to check for sleep completion. Must be * coded so that it can be referenced more than once inside * macro, i.e., no ++ or other modifying expressions. * @param atomic Non-zero if sleep must not return until condition. * * @return error code -- OK or sleep interrupted?? */os_error_codeos_sleep(os_sleep_object_t object, unsigned condition,
unsigned atomic);
/*! * Wake up whatever is sleeping on sleep object * * @param object The object on which things might be sleeping * * @return none */voidos_wake_sleepers(os_sleep_object_t object);
/*! @} *//* dkops *//***************************************************************************** * Function-signature-generating macros *****************************************************************************//*! * @defgroup drsigs Driver Function Signatures * * These macros will define the entry point signatures for interrupt handlers; * driver initialization and shutdown; device open/close; etc. They are to be * used whenever the Kernel will call into the Driver. They are not * appropriate for driver calls to other routines in the driver. * * There are three versions of each macro for a given Driver Entry Point. The * first version is used to define a function and its implementation in the * driver.c file, e.g. #OS_DEV_INIT(). * * The second form is used whenever a forward declaration (prototype) is * needed. It has the letters @c _DCL appended to the name of the definition * function. These are not otherwise mentioned in this documenation. * * There is a third form used when a reference to a function is required, for * instance when passing the routine as a pointer to a function. It has the * letters @c _REF appended to the name of the definition function * (e.g. DEV_IOCTL_REF). * * Note that these two extra forms are required because of the possibility of * having an invisible 'wrapper function' created by the os-specific header * file which would need to be invoked by the operating system, and which in * turn would invoke the generic function. * * Example: * * (in a header file) * @code * OS_DEV_INIT_DCL(widget_init); * OS_DEV_ISR_DCL(widget_isr); * @endcode * * (in an implementation file) * @code * OS_DEV_INIT(widget, widget_init) * { * * os_register_interrupt("widget", WIDGET_IRQ, OS_DEV_ISR_REF(widget_isr)); * * os_dev_init_return(OS_RETURN_NO_ERROR_S); * } * * OS_DEV_ISR(widget_isr) * { * os_dev_isr_return(TRUE); * } * @endcode *//*! @addtogroup drsigs *//*! @{ *//*! * Define a function which will handle device initialization * * This is tne driver initialization routine. This is normally where the * part would be initialized; queues, locks, interrupts handlers defined; * long-term dynamic memory allocated for driver use; etc. * * @param function_name The name of the portable initialization function. * * @return A call to #os_dev_init_return() * */#define OS_DEV_INIT(function_name)/*! * Define a function which will handle device shutdown * * This is the reverse of the #OS_DEV_INIT() routine. * * @param function_name The name of the portable driver shutdown routine. * * @return A call to #os_dev_shutdown_return() */#define OS_DEV_SHUTDOWN(function_name)/*! * Define a function which will open the device for a user. * * @param function_name The name of the driver open() function * * @return A call to #os_dev_open_return() */#define OS_DEV_OPEN(function_name)/*! * Define a function which will handle a user's ioctl() request * * @param function_name The name of the driver ioctl() function * * @return A call to #os_dev_ioctl_return() */#define OS_DEV_IOCTL(function_name)/*! * Define a function which will handle a user's read() request * * @param function_name The name of the driver read() function * * @return A call to #os_dev_read_return() */#define OS_DEV_READ(function_name)/*! * Define a function which will handle a user's write() request * * @param function_name The name of the driver write() function * * @return A call to #os_dev_write_return() */#define OS_DEV_WRITE(function_name)/*! * Define a function which will handle a user's mmap() request * * The mmap() function requests the driver to map some memory into user space. * * @todo Determine what support functions are needed for mmap() handling. * * @param function_name The name of the driver mmap() function * * @return A call to #os_dev_mmap_return() */#define OS_DEV_MMAP(function_name)/*! * Define a function which will close the device - opposite of OS_DEV_OPEN() * * @param function_name The name of the driver close() function * * @return A call to #os_dev_close_return() */#define OS_DEV_CLOSE(function_name)/*! * Define a function which will handle an interrupt * * No arguments are available to the generic function. It must not invoke any * OS functions which are illegal in a ISR. It gets no parameters, and must * have a call to #os_dev_isr_return() instead of any/all return statements. * * Example: * @code * OS_DEV_ISR(widget, widget_isr, WIDGET_IRQ_NUMBER) * { * os_dev_isr_return(1); * } * @endcode * * @param function_name The name of the driver ISR function * * @return A call to #os_dev_isr_return() */#define OS_DEV_ISR(function_name)/*! * Define a function which will operate as a background task / bottom half. * * The function implementation must be structured in the following manner: * @code * OS_DEV_TASK(widget_task) * { * OS_DEV_TASK_SETUP(widget_task); * * while OS_DEV_TASK_CONDITION(widget_task) } * * }; * } * @endcode * * @todo In some systems the OS_DEV_TASK_CONDITION() will be an action which * will cause the task to sleep on some event triggered by os_run_task(). In * others, the macro will reference a variable laid down by * OS_DEV_TASK_SETUP() to make sure that the loop is only performed once. * * @param function_name The name of this background task function */#define OS_DEV_TASK(function_name) /*! @} *//* drsigs *//*! @defgroup dclsigs Routines to declare Driver Signature routines * * These macros drop prototypes suitable for forward-declaration of * @ref drsigs "function signatures". *//*! @addtogroup dclsigs *//*! @{ *//*! * Declare prototype for the device initialization function * * @param function_name The name of the portable initialization function. */#define OS_DEV_INIT_DCL(function_name)/*! * Declare prototype for the device shutdown function * * @param function_name The name of the portable driver shutdown routine. * * @return A call to #os_dev_shutdown_return() */#define OS_DEV_SHUTDOWN_DCL(function_name)/*! * Declare prototype for the open() function. * * @param function_name The name of the driver open() function * * @return A call to #os_dev_open_return() */#define OS_DEV_OPEN_DCL(function_name)/*! * Declare prototype for the user's ioctl() request function * * @param function_name The name of the driver ioctl() function * * @return A call to #os_dev_ioctl_return() */#define OS_DEV_IOCTL_DCL(function_name)/*! * Declare prototype for the function a user's read() request * * @param function_name The name of the driver read() function */#define OS_DEV_READ_DCL(function_name)/*! * Declare prototype for the user's write() request function * * @param function_name The name of the driver write() function */#define OS_DEV_WRITE_DCL(function_name)/*! * Declare prototype for the user's mmap() request function * * @param function_name The name of the driver mmap() function */#define OS_DEV_MMAP_DCL(function_name)/*! * Declare prototype for the close function * * @param function_name The name of the driver close() function * * @return A call to #os_dev_close_return() */#define OS_DEV_CLOSE_DCL(function_name)/*! * Declare prototype for the interrupt handling function * * @param function_name The name of the driver ISR function */#define OS_DEV_ISR_DCL(function_name)/*! * Declare prototype for a background task / bottom half function * * @param function_name The name of this background task function */#define OS_DEV_TASK_DCL(function_name) /*! @} *//* dclsigs *//***************************************************************************** * Functions for Returning Values from Driver Signature routines *****************************************************************************//*! * @defgroup retfns Functions to Return Values from Driver Signature routines *//*! @addtogroup retfns *//*! @{ *//*! * Return from the #OS_DEV_INIT() function * * @param code An error code to report success or failure. * */voidos_dev_init_return(os_error_code code);
/*! * Return from the #OS_DEV_SHUTDOWN() function * * @param code An error code to report success or failure. * */voidos_dev_shutdown_return(os_error_code code);
/*! * Return from the #OS_DEV_ISR() function * * The function should verify that it really was supposed to be called, * and that its device needed attention, in order to properly set the * return code. * * @param code non-zero if interrupt handled, zero otherwise. * */voidos_dev_isr_return(int code);
/*! * Return from the #OS_DEV_OPEN() function * * @param code An error code to report success or failure. * */voidos_dev_open_return(os_error_code code);
/*! * Return from the #OS_DEV_IOCTL() function * * @param code An error code to report success or failure. * */voidos_dev_ioctl_return(os_error_code code);
/*! * Return from the #OS_DEV_READ() function * * @param code Number of bytes read, or an error code to report failure. * */voidos_dev_read_return(os_error_code code);
/*! * Return from the #OS_DEV_WRITE() function * * @param code Number of bytes written, or an error code to report failure. * */voidos_dev_write_return(os_error_code code);
/*! * Return from the #OS_DEV_MMAP() function * * @param code Number of bytes written, or an error code to report failure. * */void os_dev_mmap_return(os_error_code code);
/*! * Return from the #OS_DEV_CLOSE() function * * @param code An error code to report success or failure. * */voidos_dev_close_return(os_error_code code);
/*! * Start the #OS_DEV_TASK() function * * In some implementations, this could be turned into a label for * the os_dev_task_return() call. * * For a more portable interface, should this take the sleep object as an * argument??? * * @return none */voidos_dev_task_begin(void);
/*! * Return from the #OS_DEV_TASK() function * * In some implementations, this could be turned into a sleep followed * by a jump back to the os_dev_task_begin() call. * * @param code An error code to report success or failure. * */voidos_dev_task_return(os_error_code code);
/*! @} *//* retfns *//***************************************************************************** * Functions/Macros for accessing arguments from Driver Signature routines *****************************************************************************//*! @defgroup drsigargs Functions for Getting Arguments in Signature functions * *//* @addtogroup @drsigargs *//*! @{ *//*! * Check whether user is requesting read (permission) on the file/device. * Usable in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() * and #OS_DEV_WRITE() routines. */intos_dev_is_flag_read(void);
/*! * Check whether user is requesting write (permission) on the file/device. * Usable in #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() * and #OS_DEV_WRITE() routines. */intos_dev_is_flag_write(void);
/*! * Check whether user is requesting non-blocking I/O. Usable in * #OS_DEV_OPEN(), #OS_DEV_CLOSE(), #OS_DEV_IOCTL(), #OS_DEV_READ() and * #OS_DEV_WRITE() routines. * * @todo Specify required behavior when nonblock is requested and (sufficient?) * data are not available to fulfill the request. * */intos_dev_is_flag_nonblock(void);
/*! * Determine which major device is being accessed. Usable in #OS_DEV_OPEN() * and #OS_DEV_CLOSE(). */intos_dev_get_major(void);
/*! * Determine which minor device is being accessed. Usable in #OS_DEV_OPEN() * and #OS_DEV_CLOSE(). */intos_dev_get_minor(void);
/*! * Determine which operation the user wants performed. Usable in * #OS_DEV_IOCTL(). * * @return Value of the operation. * * @todo Define some generic way to define the individual operations. */unsignedos_dev_get_ioctl_op(void);
/*! * Retrieve the associated argument for the desired operation. Usable in * #OS_DEV_IOCTL(). * * @return A value which can be cast to a struct pointer or used as * int/long. */
os_dev_ioctl_arg_t os_dev_get_ioctl_arg(void);
/*! * Determine the requested byte count. This should be the size of buffer at * #os_dev_get_user_buffer(). Usable in OS_DEV_READ() and OS_DEV_WRITE() * routines. * * @return A count of bytes */unsignedos_dev_get_count(void);
/*! * Get the pointer to the user's data buffer. Usable in OS_DEV_READ(), * OS_DEV_WRITE(), and OS_DEV_MMAP() routines. * * @return Pointer to user buffer (in user space). See #os_copy_to_user() * and #os_copy_from_user(). */void *os_dev_get_user_buffer(void);
/*! * Get the POSIX flags field for the associated open file. Usable in * OS_DEV_READ(), OS_DEV_WRITE(), and OS_DEV_IOCTL() routines. * * @return The flags associated with the file. */unsignedos_dev_get_file_flags(void);
/*! * Set the driver's private structure associated with this file/open. * * Generally used during #OS_DEV_OPEN(). May also be used during * #OS_DEV_READ(), #OS_DEV_WRITE(), #OS_DEV_IOCTL(), #OS_DEV_MMAP(), and * #OS_DEV_CLOSE(). See also #os_dev_get_user_private(). * * @param struct_p The driver data structure to associate with this user. */voidos_dev_set_user_private(void *struct_p);
/*! * Get the driver's private structure associated with this file. * * May be used during #OS_DEV_OPEN(), #OS_DEV_READ(), #OS_DEV_WRITE(), * #OS_DEV_IOCTL(), #OS_DEV_MMAP(), and #OS_DEV_CLOSE(). See * also #os_dev_set_user_private(). * * @return The driver data structure to associate with this user. */void *os_dev_get_user_private(void);
/*! * Get the IRQ associated with this call to the #OS_DEV_ISR() function. * * @return The IRQ (integer) interrupt number. */intos_dev_get_irq(void);
/*! @} *//* drsigargs *//***************************************************************************** * Functions for Generating References to Driver Routines *****************************************************************************//*! * @defgroup drref Functions for Generating References to Driver Routines * * These functions will most likely be implemented as macros. They are a * necessary part of the portable API to guarantee portability. The @c symbol * type in here is the same symbol passed to the associated * signature-generating macro. * * These macros must be used whenever referring to a * @ref drsigs "driver signature function", for instance when storing or * passing a pointer to the function. *//*! @addtogroup drref *//*! @{ *//*! * Generate a reference to an #OS_DEV_INIT() function * * @param function_name The name of the init function being referenced. * * @return A reference to the function */
os_init_function_t OS_DEV_INIT_REF(symbol function_name);
/*! * Generate a reference to an #OS_DEV_SHUTDOWN() function * * @param function_name The name of the shutdown function being referenced. * * @return A reference to the function */
os_shutdown_function_t OS_DEV_SHUTDOWN_REF(symbol function_name);
/*! * Generate a reference to an #OS_DEV_OPEN() function * * @param function_name The name of the open function being referenced. * * @return A reference to the function */
os_user_function_t OS_DEV_OPEN_REF(symbol function_name);
/*! * Generate a reference to an #OS_DEV_CLOSE() function * * @param function_name The name of the close function being referenced. * * @return A reference to the function */
os_user_function_t OS_DEV_CLOSE_REF(symbol function_name);
/*! * Generate a reference to an #OS_DEV_READ() function * * @param function_name The name of the read function being referenced. * * @return A reference to the function */
os_user_function_t OS_DEV_READ_REF(symbol function_name);
/*! * Generate a reference to an #OS_DEV_WRITE() function * * @param function_name The name of the write function being referenced. * * @return A reference to the function */
os_user_function_t OS_DEV_WRITE_REF(symbol function_name);
/*! * Generate a reference to an #OS_DEV_IOCTL() function * * @param function_name The name of the ioctl function being referenced. * * @return A reference to the function */
os_user_function_t OS_DEV_IOCTL_REF(symbol function_name);
/*! * Generate a reference to an #OS_DEV_MMAP() function * * @param function_name The name of the mmap function being referenced. * * @return A reference to the function */
os_user_function_t OS_DEV_MMAP_REF(symbol function_name);
/*! * Generate a reference to an #OS_DEV_ISR() function * * @param function_name The name of the isr being referenced. * * @return a reference to the function */os_interrupt_handler_tOS_DEV_ISR_REF(symbol function_name);
/*! @} *//* drref *//*! * Flush and invalidate all cache lines. */voidos_flush_cache_all(void);
/*! * Flush a range of addresses from the cache * * @param start Starting virtual address * @param len Number of bytes to flush */voidos_cache_flush_range(void *start, uint32_t len);
/*! * Invalidate a range of addresses in the cache * * @param start Starting virtual address * @param len Number of bytes to flush */voidos_cache_inv_range(void *start, uint32_t len);
/*! * Clean a range of addresses from the cache * * @param start Starting virtual address * @param len Number of bytes to flush */voidos_cache_clean_range(void *start, uint32_t len);
/*! * @example widget.h *//*! * @example widget.c *//*! * @example rng_driver.h *//*! * @example rng_driver.c *//*! * @example shw_driver.h *//*! * @example shw_driver.c */#endif /* DOXYGEN_PORTABLE_OS_DOC */#endif /* PORTABLE_OS_H */