386 lines
13 KiB
C
386 lines
13 KiB
C
|
/* **********************************************************
|
||
|
* Copyright 1998 - 2009 VMware, Inc. All rights reserved.
|
||
|
* **********************************************************/
|
||
|
|
||
|
/*
|
||
|
* @VMKAPIMOD_LICENSE@
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* Character Devices */ /**
|
||
|
* \defgroup CharDev Character Devices
|
||
|
*
|
||
|
* Interfaces that allow management of vmkernel's UNIX-like character
|
||
|
* device nodes.
|
||
|
*
|
||
|
* @{
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
|
||
|
#ifndef _VMKAPI_CHAR_H_
|
||
|
#define _VMKAPI_CHAR_H_
|
||
|
|
||
|
/** \cond never */
|
||
|
#ifndef VMK_HEADER_INCLUDED_FROM_VMKAPI_H
|
||
|
#error This vmkapi file should never be included directly but only via vmkapi.h
|
||
|
#endif
|
||
|
/** \endcond never */
|
||
|
|
||
|
#include "base/vmkapi_types.h"
|
||
|
#include "base/vmkapi_const.h"
|
||
|
#include "base/vmkapi_module.h"
|
||
|
|
||
|
/**
|
||
|
* \brief Semaphore rank that may be safely used by character devices.
|
||
|
*/
|
||
|
#define VMK_SEMA_RANK_CHAR VMK_SEMA_RANK_LEAF
|
||
|
|
||
|
/*
|
||
|
* UNIX-style open flags supported for character devices
|
||
|
*/
|
||
|
/** \brief Read-only. */
|
||
|
#define VMK_CHARDEV_OFLAG_RDONLY 0x00000000
|
||
|
|
||
|
/** \brief Write-only. */
|
||
|
#define VMK_CHARDEV_OFLAG_WRONLY 0x00000001
|
||
|
|
||
|
/** \brief Read-write. */
|
||
|
#define VMK_CHARDEV_OFLAG_RDWR 0x00000002
|
||
|
|
||
|
/** \brief Mask for read/write flags. */
|
||
|
#define VMK_CHARDEV_OFLAG_RDWR_MASK 0x00000003
|
||
|
|
||
|
/** \brief Exclusive access. */
|
||
|
#define VMK_CHARDEV_OFLAG_EXCLUSIVE 0x00000080
|
||
|
|
||
|
/** \brief Append to end of file. Always set for writes */
|
||
|
#define VMK_CHARDEV_OFLAG_APPEND 0x00000400
|
||
|
|
||
|
/** \brief Don't block for file operations. */
|
||
|
#define VMK_CHARDEV_OFLAG_NONBLOCK 0x00000800
|
||
|
|
||
|
/** \brief Synchronous file operations. */
|
||
|
#define VMK_CHARDEV_OFLAG_SYNC 0x00001000
|
||
|
|
||
|
/** \brief Use direct I/O. */
|
||
|
#define VMK_CHARDEV_OFLAG_DIRECT 0x00004000
|
||
|
|
||
|
|
||
|
/** \brief Flags for poll entry point */
|
||
|
typedef enum vmk_PollEvent {
|
||
|
/** \brief No events are available */
|
||
|
VMKAPI_POLL_NONE = 0x00,
|
||
|
/** \brief The device is ready for reading */
|
||
|
VMKAPI_POLL_READ = 0x01,
|
||
|
/** \brief The device is ready for writing */
|
||
|
VMKAPI_POLL_WRITE = 0x04,
|
||
|
/** \brief The file was closed during polling for read status */
|
||
|
VMKAPI_POLL_RDHUP = 0x08,
|
||
|
/** \brief The file was closed during polling for write status */
|
||
|
VMKAPI_POLL_WRHUP = 0x10,
|
||
|
/** \brief The file is no longer valid */
|
||
|
VMKAPI_POLL_INVALID = 0x20,
|
||
|
} vmk_PollEvent;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* \ingroup CharDev
|
||
|
* \brief Character device's file descriptor's attibutes.
|
||
|
*/
|
||
|
typedef struct vmk_CharDevFdAttr {
|
||
|
/** \brief Character device's major number. */
|
||
|
vmk_uint16 major;
|
||
|
|
||
|
/** \brief Character device's minor number. */
|
||
|
vmk_uint16 minor;
|
||
|
|
||
|
/**
|
||
|
* \brief UNIX-style file flags used when opening the device
|
||
|
* from the host.
|
||
|
*/
|
||
|
vmk_uint32 openFlags;
|
||
|
|
||
|
/**
|
||
|
* \brief Client data associated with the file descriptor.
|
||
|
*
|
||
|
* May be used by the character driver to store information
|
||
|
* persistent across syscalls
|
||
|
*
|
||
|
* The field can be updated by the driver at any time during
|
||
|
* a syscall.
|
||
|
*/
|
||
|
void *clientData; /* For use by the character device driver */
|
||
|
/* across open/ioctl/close calls */
|
||
|
} vmk_CharDevFdAttr;
|
||
|
|
||
|
/**
|
||
|
* \brief Opaque poll token handle.
|
||
|
*/
|
||
|
typedef void *vmk_PollToken;
|
||
|
|
||
|
/**
|
||
|
* \brief Opaque poll context handle.
|
||
|
*/
|
||
|
typedef void *vmk_PollContext;
|
||
|
|
||
|
/**
|
||
|
* \ingroup CharDev
|
||
|
* \brief Character device driver's entry points
|
||
|
*/
|
||
|
typedef struct vmk_CharDevOps {
|
||
|
VMK_ReturnStatus (*open)(vmk_CharDevFdAttr *attr);
|
||
|
VMK_ReturnStatus (*close)(vmk_CharDevFdAttr *attr);
|
||
|
VMK_ReturnStatus (*ioctl)(vmk_CharDevFdAttr *attr, unsigned int cmd,
|
||
|
vmk_uintptr_t userData,
|
||
|
vmk_IoctlCallerSize callerSize,
|
||
|
vmk_int32 *result);
|
||
|
VMK_ReturnStatus (*fasync)(vmk_CharDevFdAttr *attr);
|
||
|
VMK_ReturnStatus (*poll)(vmk_CharDevFdAttr *attr, void *pollCtx,
|
||
|
unsigned *pollMask);
|
||
|
VMK_ReturnStatus (*read)(vmk_CharDevFdAttr *attr, char *buffer,
|
||
|
vmk_size_t nbytes, vmk_loff_t *ppos,
|
||
|
vmk_ssize_t *nread);
|
||
|
VMK_ReturnStatus (*write)(vmk_CharDevFdAttr *attr, char *buffer,
|
||
|
vmk_size_t nbytes, vmk_loff_t *ppos,
|
||
|
vmk_ssize_t *nwritten);
|
||
|
} vmk_CharDevOps;
|
||
|
|
||
|
/**
|
||
|
***********************************************************************
|
||
|
* vmk_CharDevCleanupFn -- */ /**
|
||
|
*
|
||
|
* \ingroup CharDev
|
||
|
* \brief Prototype for a character device driver's cleanup callback.
|
||
|
*
|
||
|
* \param[in] private Optional private data to be used by the callback
|
||
|
*
|
||
|
* \retval VMK_OK The cleanup function executed correctly.
|
||
|
* This is not an indicator of the success or failure of
|
||
|
* the operations in the function, but merely that they
|
||
|
* ran. Any other return value may have undefined
|
||
|
* consequences.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
typedef VMK_ReturnStatus (*vmk_CharDevCleanupFn)(vmk_AddrCookie private);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_CharDevRegister -- */ /**
|
||
|
*
|
||
|
* \ingroup CharDev
|
||
|
* \brief Register the specified character device, to be invoked from
|
||
|
* user-space.
|
||
|
*
|
||
|
* \param[in] module Module that owns the character device.
|
||
|
* \param[in] major Major number of the device. 0 if system
|
||
|
* will allocate the major number.
|
||
|
* \param[in] minor Minor number of the device.
|
||
|
* \param[in] name The name of the device.
|
||
|
* \param[in] ops Table of the driver operations (open,
|
||
|
* close, ioctl, fasync).
|
||
|
* \param[out] assignedMajor Returns the major assigned to the driver
|
||
|
*
|
||
|
* \retval VMK_BUSY The major number is already registered
|
||
|
* \retval VMK_NO_RESOURCES No free major number
|
||
|
* \retval VMK_BAD_PARAM Module ID was invalid, or one or more
|
||
|
* specified driver ops are NULL.
|
||
|
* \retval VMK_NOT_SUPPORTED Minor number is not valid for major number.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus vmk_CharDevRegister(
|
||
|
vmk_ModuleID module,
|
||
|
vmk_uint16 major,
|
||
|
vmk_uint16 minor,
|
||
|
const char *name,
|
||
|
vmk_CharDevOps *ops,
|
||
|
vmk_int32 *assignedMajor);
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_CharDevUnregister -- */ /**
|
||
|
*
|
||
|
* \ingroup CharDev
|
||
|
* \brief Attempt to unregister a character device immediately.
|
||
|
*
|
||
|
* This can fail if the device is currently open. Use
|
||
|
* vmk_CharDevUnregisterAsync if you want to automatically
|
||
|
* unregister the device once the last reference closes.
|
||
|
*
|
||
|
* \param[in] major Major number of the device.
|
||
|
* \param[in] minor Minor number of the device.
|
||
|
* \param[in] name The name of the device.
|
||
|
*
|
||
|
* \retval VMK_NOT_FOUND The device does not exist.
|
||
|
* \retval VMK_BAD_PARAM The device's name does not match the one given.
|
||
|
* \retval VMK_BUSY The device is in use and cannot be unregistered now.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus vmk_CharDevUnregister(
|
||
|
vmk_uint16 major,
|
||
|
vmk_uint16 minor,
|
||
|
const char *name);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_CharDevUnregisterAsync -- */ /**
|
||
|
*
|
||
|
* \ingroup CharDev
|
||
|
* \brief Unregister a character device once all outstanding
|
||
|
* references to the device are closed (may be immediately).
|
||
|
*
|
||
|
* \note This call can block.
|
||
|
*
|
||
|
* "Async" refers to when the requested character device is
|
||
|
* actually unregistered, since it may be completed well after
|
||
|
* vmk_CharDevUnregisterAsync completes.
|
||
|
*
|
||
|
* \param[in] major Major number of the device.
|
||
|
* \param[in] minor Minor number of the device.
|
||
|
* \param[in] name The name of the device.
|
||
|
*
|
||
|
* \retval VMK_NOT_FOUND The device does not exist.
|
||
|
* \retval VMK_BAD_PARAM The device's name does not match the one given.
|
||
|
* \retval VMK_OK The device was either unregistered or queued to be
|
||
|
* unregistered once all references close.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus vmk_CharDevUnregisterAsync(
|
||
|
vmk_uint16 major,
|
||
|
vmk_uint16 minor,
|
||
|
const char *name);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_CharDevRegisterCleanup -- */ /**
|
||
|
*
|
||
|
* \ingroup CharDev
|
||
|
* \brief Register a cleanup callback to be executed after a
|
||
|
* character device has completed its unregistration.
|
||
|
*
|
||
|
* Only one callback can be registered per device. If you
|
||
|
* attempt to register a new callback when one exists,
|
||
|
* vmk_CharDevRegisterCleanup returns VMK_EXISTS.
|
||
|
*
|
||
|
* \param[in] module Module that owns the character device
|
||
|
* \param[in] major Major number of the registered character device
|
||
|
* \param[in] minor Minor number of the registered character device
|
||
|
* \param[in] cleanup Cleanup function to be executed
|
||
|
* \param[in] private Private data to be passed to the cleanup function
|
||
|
*
|
||
|
* \retval VMK_EXISTS A cleanup callback for this device is already registered.
|
||
|
* \retval VMK_BAD_PARAM The module owner for the device does not match
|
||
|
* the module ID given for the cleanup callback.
|
||
|
* \retval VMK_NOT_FOUND No device with the given major/minor is registered.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus vmk_CharDevRegisterCleanup(
|
||
|
vmk_ModuleID module,
|
||
|
vmk_uint16 major,
|
||
|
vmk_uint16 minor,
|
||
|
vmk_CharDevCleanupFn cleanup,
|
||
|
vmk_AddrCookie private);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_CharDevUnregisterCleanup -- */ /**
|
||
|
*
|
||
|
* \ingroup CharDev
|
||
|
* \brief Cancel a cleanup callback that had been registered for
|
||
|
* the given character device.
|
||
|
*
|
||
|
* \param[in] module Module that owns the character device
|
||
|
* \param[in] major Major number of the registered character device
|
||
|
* \param[in] minor Minor number of the registered character device
|
||
|
* \param[in] cleanup Cleanup function that was to be executed
|
||
|
* \param[in] private Private data that was to be passed to the cleanup
|
||
|
* function
|
||
|
*
|
||
|
* \retval VMK_BAD_PARAM The module owner for the device does not match
|
||
|
* the module ID given for the cleanup callback
|
||
|
* being unregistered.
|
||
|
* \retval VMK_NOT_FOUND No device with the given major/minor is registered,
|
||
|
* or no callback with the given function and private
|
||
|
* data is registered.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus vmk_CharDevUnregisterCleanup(
|
||
|
vmk_ModuleID module,
|
||
|
vmk_uint16 major,
|
||
|
vmk_uint16 minor,
|
||
|
vmk_CharDevCleanupFn cleanup,
|
||
|
vmk_AddrCookie private);
|
||
|
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_CharDevWakePollers -- */ /**
|
||
|
*
|
||
|
* \ingroup CharDev
|
||
|
* \brief Wake up all users waiting on a poll call with the specified
|
||
|
* token.
|
||
|
*
|
||
|
* \param[in] token Context on which worlds are waiting.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
void vmk_CharDevWakePollers(void *token);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_CharDevNotifyFasyncComplete -- */ /**
|
||
|
*
|
||
|
* \ingroup CharDev
|
||
|
* \brief Send a signal to processes that have requested notification.
|
||
|
* The device's minor number is assumed to be zero.
|
||
|
*
|
||
|
* \param[in] major Major number of the device.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus
|
||
|
vmk_CharDevNotifyFasyncComplete(vmk_uint16 major);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_CharDevNotifyFasyncCompleteWithMinor -- */ /**
|
||
|
*
|
||
|
* \ingroup CharDev
|
||
|
* \brief Send a signal to processes that have requested notification,
|
||
|
* specifying a nonzero device minor.
|
||
|
*
|
||
|
* \param[in] major Major number of the device.
|
||
|
* \param[in] minor Minor number of the device.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
VMK_ReturnStatus
|
||
|
vmk_CharDevNotifyFasyncCompleteWithMinor(vmk_uint16 major,
|
||
|
vmk_uint16 minor);
|
||
|
|
||
|
/*
|
||
|
***********************************************************************
|
||
|
* vmk_CharDevSetPollCtx -- */ /**
|
||
|
*
|
||
|
* \ingroup CharDev
|
||
|
* \brief Set the poll context of the calling world to the specified
|
||
|
* context.
|
||
|
*
|
||
|
* \param[in] pollCtx The poll context of the calling thread.
|
||
|
* \param[out] token The token to set in the poll context.
|
||
|
*
|
||
|
***********************************************************************
|
||
|
*/
|
||
|
void vmk_CharDevSetPollContext(vmk_PollContext *pollCtx, vmk_PollToken *token);
|
||
|
|
||
|
#endif /* _VMKAPI_CHAR_H_ */
|
||
|
/** @} */
|