ESXi-5.5-GA
This commit is contained in:
parent
8564209306
commit
91e0d39c98
839 changed files with 589905 additions and 680866 deletions
|
@ -6,5 +6,5 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.vmkplexer", "2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "2.0"
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.vmkplexer", "3.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "3.0"
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,6 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.broadcom.cnic_register", "9.2.1.0");
|
||||
VMK_NAMESPACE_PROVIDES("com.broadcom.bnx2", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.broadcom.cnic_register", "9.2.2.0");
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
/*
|
||||
* DO NOT EDIT THIS FILE - IT IS GENERATED BY THE DRIVER BUILD.
|
||||
*
|
||||
* If you need to change the driver's name spaces, look in the scons
|
||||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.broadcom.cnic", "9.2.2.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfcoe", "9.2.2.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfc", "9.2.2.0");
|
|
@ -6,5 +6,6 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.broadcom.cnic", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.iscsi_linux", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.broadcom.cnic", "9.2.2.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.broadcom.cnic_register", "9.2.2.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.iscsi_linux", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,6 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.broadcom.cnic_register", "9.2.1.0");
|
||||
VMK_NAMESPACE_PROVIDES("com.broadcom.bnx2x", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.broadcom.cnic_register", "9.2.2.0");
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.broadcom.cnic", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.broadcom.cnic_register", "9.2.1.0");
|
||||
VMK_NAMESPACE_PROVIDES("com.broadcom.cnic", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.broadcom.cnic_register", "9.2.2.0");
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.broadcom.cnic_register", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_PROVIDES("com.broadcom.cnic_register", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfc", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfcoe", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfc", "9.2.2.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfcoe", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.ipmi", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.ipmi", "9.2.2.0");
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.ipmi", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.ipmi", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.ipmi", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.ipmi", "9.2.2.0");
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.lsi.megaraid_mbox", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_PROVIDES("com.lsi.megaraid_mbox", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
/*
|
||||
* DO NOT EDIT THIS FILE - IT IS GENERATED BY THE DRIVER BUILD.
|
||||
*
|
||||
* If you need to change the driver's name spaces, look in the scons
|
||||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.mellanox.mlx4_core", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
/*
|
||||
* DO NOT EDIT THIS FILE - IT IS GENERATED BY THE DRIVER BUILD.
|
||||
*
|
||||
* If you need to change the driver's name spaces, look in the scons
|
||||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.mellanox.mlx4_core", "9.2.2.0");
|
|
@ -6,5 +6,5 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.netxen.nx_nic", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_PROVIDES("com.netxen.nx_nic", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.qla4xxx", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.iscsi_linux", "9.2.1.0");
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.qla4xxx", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.iscsi_linux", "9.2.2.0");
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.random", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.random", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.broadcom.tg3", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_PROVIDES("com.broadcom.tg3", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
|
|
|
@ -44,7 +44,9 @@ static inline struct task_struct *get_current(void)
|
|||
* Pointer to current task of type task_struct
|
||||
*
|
||||
*/
|
||||
/* _VMKLNX_CODECHECK_: current */
|
||||
/* If the macro 'current' or its comments are changed please
|
||||
* update the documentation for 'current' in vmkdrivers/src_92/doc/dummyDefs.doc
|
||||
*/
|
||||
#define current get_current()
|
||||
|
||||
#else
|
||||
|
|
|
@ -185,11 +185,16 @@ static inline void * phys_to_virt(unsigned long address)
|
|||
|
||||
/**
|
||||
* page_to_phys - page handle to machine address
|
||||
* @maddr : machine address
|
||||
* @page : page handle
|
||||
*
|
||||
* Gets the machine address that corresponds to the page parameter
|
||||
*
|
||||
* ESX Deviation Notes:
|
||||
* None.
|
||||
*
|
||||
* RETURN VALUE:
|
||||
* A machine address
|
||||
*
|
||||
*/
|
||||
/* _VMKLNX_CODECHECK_: page_to_phys */
|
||||
#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
|
||||
|
|
|
@ -352,9 +352,6 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
|||
/* _VMKLNX_CODECHECK_: rmb */
|
||||
#define rmb() asm volatile("lfence":::"memory")
|
||||
|
||||
#ifdef CONFIG_UNORDERED_IO
|
||||
#define wmb() asm volatile("sfence" ::: "memory")
|
||||
#else
|
||||
/**
|
||||
* wmb - write memory barrier
|
||||
*
|
||||
|
@ -368,9 +365,16 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
|||
* RETURN VALUE:
|
||||
* NONE
|
||||
*/
|
||||
/*
|
||||
* VMware : 2013
|
||||
*
|
||||
* As mentioned in PR 891237, CONFIG_UNORDERED_IO was removed from Linux
|
||||
* on 03/25/2006 by Andi Kleen ("x86_64: Remove CONFIG_UNORDERED_IO"). Here
|
||||
* wmb() is being changed to a real sfence instead of just a compile barrier.
|
||||
*/
|
||||
/* _VMKLNX_CODECHECK_: wmb */
|
||||
#define wmb() asm volatile("" ::: "memory")
|
||||
#endif
|
||||
#define wmb() asm volatile("sfence" ::: "memory")
|
||||
|
||||
#define read_barrier_depends() do {} while(0)
|
||||
#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
|
||||
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usb", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usbnet", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usb", "9.2.2.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usbnet", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usb", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usb", "9.2.2.0");
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfcoe", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfc", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfcoe", "9.2.2.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfc", "9.2.2.0");
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.usbhid", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usb", "9.2.1.0");
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.usbhid", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usb", "9.2.2.0");
|
||||
|
|
|
@ -8,4 +8,4 @@
|
|||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.iscsi_linux", "9.2.0.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.0.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.iscsi_linux", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.iscsi_linux", "9.2.2.0");
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
/*
|
||||
* DO NOT EDIT THIS FILE - IT IS GENERATED BY THE DRIVER BUILD.
|
||||
*
|
||||
* If you need to change the driver's name spaces, look in the scons
|
||||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.iscsi_linux", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.iscsi_linux", "9.2.2.0");
|
|
@ -6,5 +6,5 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.libata", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.libata", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
|
|
|
@ -8,4 +8,4 @@
|
|||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.libata", "9.2.0.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.0.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
/*
|
||||
* DO NOT EDIT THIS FILE - IT IS GENERATED BY THE DRIVER BUILD.
|
||||
*
|
||||
* If you need to change the driver's name spaces, look in the scons
|
||||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.libata", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libata", "9.2.2.0");
|
|
@ -6,5 +6,5 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.libfc", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.libfc", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
|
|
|
@ -8,4 +8,4 @@
|
|||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.libfc", "9.2.0.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.0.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfc", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfc", "9.2.2.0");
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
/*
|
||||
* DO NOT EDIT THIS FILE - IT IS GENERATED BY THE DRIVER BUILD.
|
||||
*
|
||||
* If you need to change the driver's name spaces, look in the scons
|
||||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.libfc", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfc", "9.2.2.0");
|
|
@ -6,6 +6,6 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.libfcoe", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfc", "9.2.1.0");
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.libfcoe", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfc", "9.2.2.0");
|
||||
|
|
|
@ -8,4 +8,4 @@
|
|||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.libfcoe", "9.2.0.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.0.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfcoe", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfcoe", "9.2.2.0");
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
/*
|
||||
* DO NOT EDIT THIS FILE - IT IS GENERATED BY THE DRIVER BUILD.
|
||||
*
|
||||
* If you need to change the driver's name spaces, look in the scons
|
||||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.libfcoe", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.libfcoe", "9.2.2.0");
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usb", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usb", "9.2.2.0");
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.usbstorage", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usb", "9.2.1.0");
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.usbstorage", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usb", "9.2.2.0");
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usb", "9.2.1.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usb", "9.2.2.0");
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.usb", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.usb", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.usbnet", "9.2.1.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.1.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usb", "9.2.1.0");
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.usbnet", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.usb", "9.2.2.0");
|
||||
|
|
|
@ -8,4 +8,4 @@
|
|||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.driverAPI", "9.2");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.vmkplexer", "2.0");
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.vmkplexer", "3.0");
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
/*
|
||||
* DO NOT EDIT THIS FILE - IT IS GENERATED BY THE DRIVER BUILD.
|
||||
*
|
||||
* If you need to change the driver's name spaces, look in the scons
|
||||
* files for the driver's defineVmkDriver() rule.
|
||||
*/
|
||||
|
||||
VMK_NAMESPACE_PROVIDES("com.vmware.driverAPI", "9.2.2.0");
|
||||
#define VMKLNX_MY_NAMESPACE_VERSION "9.2.2.0"
|
||||
VMK_NAMESPACE_REQUIRED("com.vmware.driverAPI", "9.2");
|
|
@ -129,7 +129,7 @@ static inline void vmk_AtomicDec64(
|
|||
{
|
||||
vmk_AtomicPrologue();
|
||||
__asm__ __volatile__(
|
||||
"lock; decl %0"
|
||||
"lock; decq %0"
|
||||
: "+m" (*var)
|
||||
:
|
||||
: "cc"
|
||||
|
@ -158,7 +158,7 @@ static inline void vmk_AtomicAdd64(
|
|||
__asm__ __volatile__(
|
||||
"lock; addq %1, %0"
|
||||
: "+m" (*var)
|
||||
: "ri" (val)
|
||||
: "re" (val)
|
||||
: "cc"
|
||||
);
|
||||
vmk_AtomicEpilogue();
|
||||
|
@ -184,7 +184,7 @@ static inline void vmk_AtomicSub64(
|
|||
__asm__ __volatile__(
|
||||
"lock; subq %1, %0"
|
||||
: "+m" (*var)
|
||||
: "ri" (val)
|
||||
: "re" (val)
|
||||
: "cc"
|
||||
);
|
||||
vmk_AtomicEpilogue();
|
||||
|
@ -211,7 +211,7 @@ static inline void vmk_AtomicOr64(
|
|||
__asm__ __volatile__(
|
||||
"lock; orq %1, %0"
|
||||
: "+m" (*var)
|
||||
: "ri" (val)
|
||||
: "re" (val)
|
||||
: "cc"
|
||||
);
|
||||
vmk_AtomicEpilogue();
|
||||
|
@ -237,7 +237,7 @@ static inline void vmk_AtomicAnd64(
|
|||
__asm__ __volatile__(
|
||||
"lock; andq %1, %0"
|
||||
: "+m" (*var)
|
||||
: "ri" (val)
|
||||
: "re" (val)
|
||||
: "cc"
|
||||
);
|
||||
vmk_AtomicEpilogue();
|
||||
|
@ -263,7 +263,7 @@ static inline void vmk_AtomicXor64(
|
|||
__asm__ __volatile__(
|
||||
"lock; xorq %1, %0"
|
||||
: "+m" (*var)
|
||||
: "ri" (val)
|
||||
: "re" (val)
|
||||
: "cc"
|
||||
);
|
||||
vmk_AtomicEpilogue();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* **********************************************************
|
||||
* Copyright 1998 - 2010 VMware, Inc. All rights reserved.
|
||||
* Copyright 1998 - 2010,2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
|
@ -51,8 +51,11 @@
|
|||
/** \brief Don't block for file operations. */
|
||||
#define VMK_CHARDEV_OFLAG_NONBLOCK 0x00000800
|
||||
|
||||
/** \brief Synchronous file operations. */
|
||||
#define VMK_CHARDEV_OFLAG_SYNC 0x00001000
|
||||
/** \brief File integerity for synchronous file I/O. */
|
||||
#define VMK_CHARDEV_OFLAG_SYNC 0x00101000
|
||||
|
||||
/** \brief Data integrity for synchronous file I/O. */
|
||||
#define VMK_CHARDEV_OFLAG_DSYNC 0x00001000
|
||||
|
||||
/** \brief Use direct I/O. */
|
||||
#define VMK_CHARDEV_OFLAG_DIRECT 0x00004000
|
||||
|
@ -106,16 +109,6 @@ typedef struct vmk_CharDevFdAttr {
|
|||
/* across open/ioctl/close calls */
|
||||
} vmk_CharDevFdAttr;
|
||||
|
||||
/**
|
||||
* \brief Opaque handle to a character device.
|
||||
*/
|
||||
typedef struct vmkCharDevInt* vmk_CharDev;
|
||||
|
||||
/**
|
||||
* \brief A default initialization value for a vmk_CharDev.
|
||||
*/
|
||||
#define VMK_INVALID_CHARDEV (NULL)
|
||||
|
||||
/**
|
||||
* \brief Opaque poll token handle.
|
||||
*/
|
||||
|
@ -126,6 +119,26 @@ typedef void *vmk_PollToken;
|
|||
*/
|
||||
typedef void *vmk_PollContext;
|
||||
|
||||
/**
|
||||
* \brief Identifier for logical graphics devices.
|
||||
*/
|
||||
#define VMK_CHARDEV_IDENTIFIER_GRAPHICS "com.vmware.graphics"
|
||||
|
||||
/**
|
||||
* \brief Character device driver's entry points.
|
||||
*/
|
||||
struct vmk_CharDevOps;
|
||||
|
||||
/** \brief Character device registration data. */
|
||||
typedef struct vmk_CharDevRegData {
|
||||
/** \brief Module creating this device. */
|
||||
vmk_ModuleID moduleID;
|
||||
/** \brief Device operations. */
|
||||
const struct vmk_CharDevOps *fileOps;
|
||||
/** \brief Device private data. */
|
||||
vmk_AddrCookie devicePrivate;
|
||||
} vmk_CharDevRegData;
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_CharDevOpenFn -- */ /**
|
||||
|
@ -330,93 +343,6 @@ typedef struct vmk_CharDevOps {
|
|||
vmk_CharDevWriteFn write;
|
||||
} vmk_CharDevOps;
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_CharDevCleanupFn -- */ /**
|
||||
*
|
||||
* \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 is not allowed.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef VMK_ReturnStatus (*vmk_CharDevCleanupFn)(vmk_AddrCookie private);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_CharDevRegister -- */ /**
|
||||
*
|
||||
* \brief Register the specified character device, to be invoked from
|
||||
* user-space.
|
||||
*
|
||||
* \param[in] module Module that owns the character device.
|
||||
* \param[in] name The name of the device - this must be unique.
|
||||
* \param[in] fileOps Table of the driver file operations.
|
||||
* Neither open nor close can be supplied
|
||||
* without the other.
|
||||
* If read or write operations are supplied,
|
||||
* then open and close must also be supplied.
|
||||
* \param[in] cleanup Function automatically invoked to clean up
|
||||
* after all file ops have ceased and the
|
||||
* device has been unregistered. May be NULL.
|
||||
* \param[in] devicePrivate Data given to the driver for each file
|
||||
* op and cleaned up after unregistration.
|
||||
* \param[out] assignedHandle Handle to the registered character device.
|
||||
*
|
||||
* \retval VMK_EXISTS A device with that name is already registered
|
||||
* \retval VMK_FAILURE Unable to allocate internal slot for the device
|
||||
* \retval VMK_NO_MEMORY Unable to allocate memory for device metadata
|
||||
* \retval VMK_BAD_PARAM Module ID was invalid, name was invalid,
|
||||
* or one or more specified driver ops are NULL
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_CharDevRegister(
|
||||
vmk_ModuleID module,
|
||||
const char *name,
|
||||
const vmk_CharDevOps *fileOps,
|
||||
vmk_CharDevCleanupFn cleanup,
|
||||
vmk_AddrCookie devicePrivate,
|
||||
vmk_CharDev *assignedHandle);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_CharDevUnregister -- */ /**
|
||||
*
|
||||
* \brief Unregister a character device.
|
||||
*
|
||||
* The character device will be unregistered automatically by
|
||||
* the kernel only after all open files to the device have been
|
||||
* closed. If no files are open when vmk_CharDevUnregister is
|
||||
* called, the device may be unregistered immediately and have the
|
||||
* cleanup function registered with it invoked. If the device has
|
||||
* files open, vmk_CharDevUnregister internally defers the device for
|
||||
* later automatic removal and returns to the caller immediately. When
|
||||
* the last file is closed, the device will then be destroyed and the
|
||||
* cleanup function invoked.
|
||||
*
|
||||
* \note No new open files to the device can be created after calling
|
||||
* vmk_CharDevUnregister.
|
||||
* \note The vmkernel will prevent a module from being unloaded while
|
||||
* it has open files associated with a character device, even
|
||||
* if that device has been requested to be unregistered.
|
||||
*
|
||||
* \param[in] deviceHandle Handle of device assigned during registration.
|
||||
*
|
||||
* \retval VMK_NOT_FOUND The device does not exist.
|
||||
* \retval VMK_OK The device was either unregistered or internally
|
||||
* deferred for unregistration once all associated files
|
||||
* close.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_CharDevUnregister(vmk_CharDev deviceHandle);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_CharDevWakePollers -- */ /**
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* Character Devices */ /**
|
||||
* \addtogroup CharDev
|
||||
*
|
||||
* Interfaces that allow registration of generic vmkernel character
|
||||
* device nodes.
|
||||
*
|
||||
* @{
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _VMKAPI_CHAR_LEGACY_H_
|
||||
#define _VMKAPI_CHAR_LEGACY_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 */
|
||||
|
||||
/**
|
||||
* \brief Opaque handle to a character device.
|
||||
*/
|
||||
typedef struct vmkCharDevInt* vmk_CharDev;
|
||||
|
||||
/**
|
||||
* \brief A default initialization value for a vmk_CharDev.
|
||||
*/
|
||||
#define VMK_INVALID_CHARDEV (NULL)
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_CharDevCleanupFn -- */ /**
|
||||
*
|
||||
* \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 is not allowed.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef VMK_ReturnStatus (*vmk_CharDevCleanupFn)(vmk_AddrCookie private);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_CharDevRegister -- */ /**
|
||||
*
|
||||
* \brief Register the specified character device, to be invoked from
|
||||
* user-space.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \param[in] module Module that owns the character device.
|
||||
* \param[in] name The name of the device - this must be unique.
|
||||
* \param[in] fileOps Table of the driver file operations.
|
||||
* Neither open nor close can be supplied
|
||||
* without the other.
|
||||
* If read or write operations are supplied,
|
||||
* then open and close must also be supplied.
|
||||
* \param[in] cleanup Function automatically invoked to clean up
|
||||
* after all file ops have ceased and the
|
||||
* device has been unregistered. May be NULL.
|
||||
* \param[in] devicePrivate Data given to the driver for each file
|
||||
* op and cleaned up after unregistration.
|
||||
* \param[out] assignedHandle Handle to the registered character device.
|
||||
*
|
||||
* \retval VMK_EXISTS A device with that name is already registered
|
||||
* \retval VMK_FAILURE Unable to allocate internal slot for the device
|
||||
* \retval VMK_NO_MEMORY Unable to allocate memory for device metadata
|
||||
* \retval VMK_BAD_PARAM Module ID was invalid, name was invalid,
|
||||
* or one or more specified driver ops are NULL
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_CharDevRegister(
|
||||
vmk_ModuleID module,
|
||||
const char *name,
|
||||
const vmk_CharDevOps *fileOps,
|
||||
vmk_CharDevCleanupFn cleanup,
|
||||
vmk_AddrCookie devicePrivate,
|
||||
vmk_CharDev *assignedHandle);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_CharDevUnregister -- */ /**
|
||||
*
|
||||
* \brief Unregister a character device.
|
||||
*
|
||||
* The character device will be unregistered automatically by
|
||||
* the kernel only after all open files to the device have been
|
||||
* closed. If no files are open when vmk_CharDevUnregister is
|
||||
* called, the device may be unregistered immediately and have the
|
||||
* cleanup function registered with it invoked. If the device has
|
||||
* files open, vmk_CharDevUnregister internally defers the device for
|
||||
* later automatic removal and returns to the caller immediately. When
|
||||
* the last file is closed, the device will then be destroyed and the
|
||||
* cleanup function invoked.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
* \note No new open files to the device can be created after calling
|
||||
* vmk_CharDevUnregister.
|
||||
* \note The vmkernel will prevent a module from being unloaded while
|
||||
* it has open files associated with a character device, even
|
||||
* if that device has been requested to be unregistered.
|
||||
*
|
||||
* \param[in] deviceHandle Handle of device assigned during registration.
|
||||
*
|
||||
* \retval VMK_NOT_FOUND The device does not exist.
|
||||
* \retval VMK_OK The device was either unregistered or internally
|
||||
* deferred for unregistration once all associated files
|
||||
* close.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_CharDevUnregister(vmk_CharDev deviceHandle);
|
||||
|
||||
#endif /* _VMKAPI_CHAR_LEGACY_H_ */
|
||||
/** @} */
|
|
@ -188,6 +188,31 @@ VMK_ReturnStatus vmk_HeapCreate(vmk_HeapCreateProps *props,
|
|||
*/
|
||||
void vmk_HeapDestroy(vmk_HeapID heap);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_HeapDestroySync -- */ /**
|
||||
*
|
||||
* \brief Destroy a dynamic heap. If the heap is non-empty, wait
|
||||
* for it to become empty before destroying.
|
||||
*
|
||||
* \note This function may block if the heap is non-empty.
|
||||
*
|
||||
* \param[in] heap Heap to destroy.
|
||||
* \param[in] timeoutMS Timeout in milliseconds. Zero means no timeout.
|
||||
*
|
||||
* \retval VMK_OK Heap was destroyed successfully.
|
||||
* \retval VMK_DEATH_PENDING World was killed while waiting and the
|
||||
* heap was not destroyed.
|
||||
* \retval VMK_WAIT_INTERRUPTED The wait was interrupted and the heap
|
||||
* was not destroyed.
|
||||
* \retval VMK_TIMEOUT The wait timed out and the heap was
|
||||
* not destroyed.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_HeapDestroySync(vmk_HeapID heap,
|
||||
vmk_int64 timeoutMS);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_HeapFree -- */ /**
|
||||
|
|
|
@ -202,6 +202,20 @@ VMK_ReturnStatus vmk_LogRegister(
|
|||
VMK_ReturnStatus vmk_LogUnregister(
|
||||
vmk_LogComponent handle);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_LogHeapAllocSize -- */ /**
|
||||
*
|
||||
* \brief Amount of heap space needed per registered log component
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \retval Number of bytes to set aside in a heap per log component
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
vmk_ByteCount vmk_LogHeapAllocSize(void);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_LogGetName -- */ /**
|
||||
|
@ -311,7 +325,7 @@ vmk_int32 vmk_LogGetCurrentLogLevel(
|
|||
#define vmk_Warning(handle, fmt, args...) \
|
||||
vmk_LogLevel(VMK_LOG_URGENCY_WARNING, \
|
||||
handle, vmk_LogGetCurrentLogLevel(handle), \
|
||||
"%s: %s:%d:" fmt "\n", vmk_LogGetName(handle), \
|
||||
"%s: %s:%d: " fmt "\n", vmk_LogGetName(handle), \
|
||||
__FUNCTION__, __LINE__, ##args)
|
||||
|
||||
/*
|
||||
|
@ -335,7 +349,7 @@ vmk_int32 vmk_LogGetCurrentLogLevel(
|
|||
#define vmk_Alert(handle, fmt, args...) \
|
||||
vmk_LogLevel(VMK_LOG_URGENCY_ALERT, \
|
||||
handle, vmk_LogGetCurrentLogLevel(handle), \
|
||||
"%s: %s:%d:" fmt "\n", vmk_LogGetName(handle), \
|
||||
"%s: %s:%d: " fmt "\n", vmk_LogGetName(handle), \
|
||||
__FUNCTION__, __LINE__, ##args)
|
||||
|
||||
/*
|
||||
|
|
|
@ -0,0 +1,358 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2012 - 2013 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* Management Interfaces */ /**
|
||||
* \defgroup Mgmt Management
|
||||
*
|
||||
* Interfaces that allow management of vmkapi modules (runtime
|
||||
* parameterization, notifications to modules from user space and
|
||||
* to user space from modules).
|
||||
*
|
||||
* @{
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* vmkapi_mgmt.h --
|
||||
*
|
||||
* vmkernel declarations for datatypes & functions used for
|
||||
* enabling per-module management APIs between user-space and
|
||||
* vmkernel modules.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _VMKAPI_MGMT_H_
|
||||
#define _VMKAPI_MGMT_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_mgmt_types.h"
|
||||
|
||||
/** \brief Opaque generic handle allocated by the API */
|
||||
typedef struct vmkMgmtHandleInt * vmk_MgmtHandle;
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtCleanupFn -- */ /**
|
||||
*
|
||||
* \brief Prototype for a management interface's cleanup callback.
|
||||
*
|
||||
* \param[in] private Optional cookie data to be used by the callback,
|
||||
* as was originally provided to vmk_MgmtInit().
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef void (*vmk_MgmtCleanupFn)(vmk_uint64 cookie);
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtKeyGetFn -- */ /**
|
||||
*
|
||||
* \brief Prototype for get-key function.
|
||||
*
|
||||
* \note This prototype is for a module-supplied "get" function
|
||||
* for fetching a key's value, for a key that was registered
|
||||
* using vmk_MgmtAddKey.
|
||||
*
|
||||
* \param[in] cookie Cookie supplied with vmk_MgmtInit.
|
||||
* \param[out] keyVal Value of the key that was read. The type of
|
||||
* pointer this represents depends on the type
|
||||
* of key that was added using this function.
|
||||
*
|
||||
* \retval VMK_OK The 'get' function executed correctly.
|
||||
* This is not an indicator of the success or failure of
|
||||
* the operations in the function, but merely that they
|
||||
* ran.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef VMK_ReturnStatus (*vmk_MgmtKeyGetFn)(vmk_uint64 cookie,
|
||||
void *keyVal);
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtKeySetFn -- */ /**
|
||||
*
|
||||
* \brief Prototype for set-key function.
|
||||
*
|
||||
* \note This prototype is for a module-supplied "set" function
|
||||
* for storing a key's value, for a key that was registered
|
||||
* using vmk_MgmtAddKey.
|
||||
*
|
||||
* \param[in] cookie Cookie supplied with vmk_MgmtKeyValueInit.
|
||||
* \param[in] keyVal Value of the key to set. The type of
|
||||
* pointer this represents depends on the type
|
||||
* of key that was added using this function.
|
||||
*
|
||||
* \retval VMK_OK The 'set' function executed correctly.
|
||||
* This is not an indicator of the success or failure of
|
||||
* the operations in the function, but merely that they
|
||||
* ran.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef VMK_ReturnStatus (*vmk_MgmtKeySetFn)(vmk_uint64 cookie,
|
||||
void *keyVal);
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtInit */ /**
|
||||
*
|
||||
* \brief Initialize the kernel side of a user/kernel management API
|
||||
*
|
||||
* \note The API passed must have an equivalent signature that is passed
|
||||
* to the library interface in userland.
|
||||
*
|
||||
* \param[in] modId The module ID of the kernel module registering
|
||||
* the API.
|
||||
* \param[in] heapId The heap ID to use for allocating temporary
|
||||
* metadata and parameter passing in event delivery.
|
||||
* \param[in] sig The API signature of the API being registered.
|
||||
* Callbacks 0 through VMK_MGMT_RESERVED_CALLBACKS
|
||||
* are reserved and may not be used.
|
||||
* \param[in] cleanupFn Optional cleanup function that is executed
|
||||
* after the last in-flight operation
|
||||
* concludes. Note that in-flight management
|
||||
* operations can be going on during a vmk_MgmtDestroy.
|
||||
* \param[in] cookie A data cookie that will be provided as the
|
||||
* first argument to all kernel-space callbacks
|
||||
* and the cleanup function that are invoked.
|
||||
* \param[in,out] handle The handle that will be allocated for accessing
|
||||
* this API.
|
||||
*
|
||||
* \retval VMK_OK Initialization succeeded.
|
||||
* \retval VMK_BAD_PARAM Either the modId or signature were invalid.
|
||||
* \retval VMK_NO_MEMORY Internal metadata for operation could not be
|
||||
* allocated.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_MgmtInit(vmk_ModuleID modId,
|
||||
vmk_HeapID heapId,
|
||||
vmk_MgmtApiSignature *sig,
|
||||
vmk_MgmtCleanupFn cleanupFn,
|
||||
vmk_uint64 cookie,
|
||||
vmk_MgmtHandle *handle);
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtRegisterInstanceCallbacks */ /**
|
||||
*
|
||||
* \brief Register instance-specific management callbacks.
|
||||
*
|
||||
* \note This API registers an instance and instance-specific callbacks
|
||||
* that will be associated with a given management handle. If
|
||||
* you provide instance-specific callbacks, those callbacks will
|
||||
* be invoked instead of the default corresponding callbacks that
|
||||
* were originally registered with the handle. Note that it is
|
||||
* valid to supply a subset of instance-specific callbacks
|
||||
* (or even none).
|
||||
*
|
||||
* \param[in] handle The management handle that was initialized.
|
||||
* \param[in] instanceId The unique instance that will have its
|
||||
* callbacks registered. Must be unique for
|
||||
* the current handle, and must not be 0.
|
||||
* \param[in] modId The modId of the module where the
|
||||
* callbacks reside.
|
||||
* \param[in] heapId The heapId from the module where the
|
||||
* callbacks reside.
|
||||
* \param[in] displayName The name that will be displayed for
|
||||
* this instance when it's listed.
|
||||
* \param[in] numCallbacks The number of instance-specific
|
||||
* callbacks that are being registered. 0
|
||||
* is valid, if the instance does not
|
||||
* supply instance-specific callbacks.
|
||||
* \param[in] callbacks The callback information for each
|
||||
* instance-specific callback, corresponding
|
||||
* to callbacks that override those
|
||||
* registered in the API signature
|
||||
* for this handle.
|
||||
*
|
||||
* \retval VMK_OK Initialization succeeded.
|
||||
* \retval VMK_BAD_PARAM Parameters couldn't be validated.
|
||||
* \retval VMK_NO_MEMORY Internal metadata for operation could not be
|
||||
* allocated.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_MgmtRegisterInstanceCallbacks(vmk_MgmtHandle handle,
|
||||
vmk_uint64 instanceId,
|
||||
vmk_ModuleID modId,
|
||||
vmk_HeapID heapId,
|
||||
vmk_Name *displayName,
|
||||
vmk_uint32 numCallbacks,
|
||||
vmk_MgmtCallbackInfo *callbacks);
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtUnregisterInstanceCallbacks */ /**
|
||||
*
|
||||
* \brief Unregister an instance from being management handle.
|
||||
*
|
||||
* \param[in] handle The management handle that was initialized
|
||||
* and to which this instance is associated.
|
||||
* \param[in] instanceId The unique instance that was already
|
||||
* registered for management.
|
||||
*
|
||||
* \retval VMK_OK Unregistration succeeded.
|
||||
* \retval VMK_BAD_PARAM The instance was not already registered.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_MgmtUnregisterInstanceCallbacks(vmk_MgmtHandle handle,
|
||||
vmk_uint64 instanceId);
|
||||
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtDestroy */ /**
|
||||
*
|
||||
* \brief Destroy the kernel side of a user/kernel management API
|
||||
*
|
||||
* \param[in] handle The handle that was passed and initialized with
|
||||
* vmk_MgmtInit
|
||||
*
|
||||
* \note The heap that was passed to vmk_MgmtInit should not be
|
||||
* destroyed until all access to the management channel has stopped,
|
||||
* and thus the cleanup function has run. If you call
|
||||
* vmk_MgmtDestroy during module-unload, you are assured that the
|
||||
* management channel is not in use & thus you can safely destroy
|
||||
* the heap immediately.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM The API has already been destroyed or has
|
||||
* already been requested to be destroyed.
|
||||
* \retval VMK_OK The API will be destroyed once all in-flight
|
||||
* operations conclude (may be immediate, if
|
||||
* none are currently in-flight).
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_MgmtDestroy(vmk_MgmtHandle handle);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_MgmtCallbackInvokeInt --
|
||||
*
|
||||
* This is used by vmk_MgmtCallbackInvoke(). VMKAPI clients should
|
||||
* never call this function directly.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/** \cond nodoc */
|
||||
VMK_ReturnStatus
|
||||
vmk_MgmtCallbackInvokeInt(vmk_MgmtHandle handle,
|
||||
vmk_uint64 instanceId,
|
||||
vmk_uint64 callbackId,
|
||||
vmk_uint32 argCount,
|
||||
...);
|
||||
/** \endcond */
|
||||
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtCallbackInvoke */ /**
|
||||
*
|
||||
* \brief Invoke a user-space callback that has zero or more parameters.
|
||||
* \note The callback will be asynchronously delivered to user-space,
|
||||
* but only if there currently is a user-space process associated
|
||||
* with this management handle that is listening for callback
|
||||
* requests. This call does not block.
|
||||
* \note Parameters are immediately copied for delivery. Sizes are
|
||||
* determined by the API signature that was registered with
|
||||
* vmk_MgmtInit. Additionally, the data cookie that was
|
||||
* registered with the receiver (in user space) will be provided
|
||||
* as the first argument to the callback that is delivered in
|
||||
* user space.
|
||||
*
|
||||
* \param[in] handle The handle that was passed and initialized with
|
||||
* vmk_MgmtInit
|
||||
* \param[in] instanceId The unique instance ID from which this callback
|
||||
* is originating. If this is not an instance-
|
||||
* specific invocation, use VMK_MGMT_NO_INSTANCE_ID.
|
||||
* \param[in] callbackId The unique ID corresponding to the callback to
|
||||
* invoke, as registered with the API signature.
|
||||
* \param[in] ... Pointers to the parameters to copy and pass.
|
||||
* The number of parameters passed here must match
|
||||
* the number used by the callback indicated by
|
||||
* callbackId.
|
||||
*
|
||||
* \retval VMK_OK The callback was prepared for delivery. This
|
||||
does not indicate that it has run, however.
|
||||
* \retval VMK_BAD_PARAM The callback or number of parameters supplied
|
||||
* was invalid.
|
||||
* \retval VMK_NO_MEMORY Temporary storage required to deliver the event
|
||||
* was unavailable.
|
||||
* \retval VMK_NOT_FOUND There is no listening user-space process
|
||||
* running that can receive this callback request.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#define vmk_MgmtCallbackInvoke( \
|
||||
/* (vmk_MgmtHandle) */ handle, \
|
||||
/* (vmk_uint64) */ instanceId, \
|
||||
/* (vmk_uint64) */ callbackId, \
|
||||
...) \
|
||||
vmk_MgmtCallbackInvokeInt(handle, instanceId, callbackId, VMK_UTIL_NUM_ARGS(__VA_ARGS__), ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtAddKey */ /**
|
||||
*
|
||||
* \brief Add a key to be managed as a key-value pair.
|
||||
*
|
||||
* \note This creates a key-value pair that can be managed using
|
||||
* the vmkmgmt_keyval utility. The name of the management
|
||||
* handle that was initialized is the name of the key-value
|
||||
* instance that would be the "instance" argument to
|
||||
* vmkmgmt_keyval. For the get and set functions registered
|
||||
* here, the cookie that is given back is the cookie that
|
||||
* was initialized with vmk_MgmtInit.
|
||||
*
|
||||
* \param[in] handle The handle that was initialized by
|
||||
* vmk_MgmtInit.
|
||||
* \param[in] keyType The type of the key being added.
|
||||
* \param[in] keyName The name of the key being added. Must be
|
||||
* unique compared to other registered
|
||||
* keys for this management handle.
|
||||
* \param[in] getFn The function that will be used to get the key
|
||||
* value at runtime.
|
||||
* \param[in] setFn The function that will be used to set the key
|
||||
* value at runtime.
|
||||
*
|
||||
* \note Both the getFn and setFn must be provided.
|
||||
*
|
||||
* \retval VMK_OK The key was added.
|
||||
* \retval VMK_BAD_PARAM A bad parameter was given.
|
||||
* \retval VMK_NO_MEMORY Memory was not available to allocate the required
|
||||
* metadata structures.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_MgmtAddKey(vmk_MgmtHandle handle,
|
||||
vmk_MgmtKeyType keyType,
|
||||
vmk_Name *keyName,
|
||||
vmk_MgmtKeyGetFn getFn,
|
||||
vmk_MgmtKeySetFn setFn);
|
||||
|
||||
|
||||
#endif /* _VMKAPI_MGMT_H_ */
|
||||
/** @} */
|
|
@ -0,0 +1,284 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2012 - 2013 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Management Types */ /**
|
||||
* \addtogroup Mgmt
|
||||
*
|
||||
* User-facing interfaces exported by vmkmgmt_lib, for use when communicating
|
||||
* with vmkapi modules using vmk_Mgmt APIs.
|
||||
*
|
||||
* @{
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* vmkapi_mgmt_lib.h --
|
||||
* user-space declarations for datatypes & functions used to interact
|
||||
* with vmkapi modules that use the vmk_Mgmt APIs. Note that user-space
|
||||
* management APIs and user-specific types are prefixed with "vmk_MgmtUser",
|
||||
* even when they may be used to invoke actions in the kernel.
|
||||
*/
|
||||
|
||||
#ifndef _VMKAPI_MGMT_LIB_H_
|
||||
#define _VMKAPI_MGMT_LIB_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_mgmt_types.h"
|
||||
|
||||
/** \brief An opaque handle that is allocated and managed by the library */
|
||||
typedef struct vmkMgmtUserHandleInt * vmk_MgmtUserHandle;
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtUserInit */ /**
|
||||
*
|
||||
* \brief Initialize user-space management of a kernel module.
|
||||
*
|
||||
* \note This initializes your application for interaction with a
|
||||
* kernel module that has an API signature matching the one you
|
||||
* provide here with vmk_MgmtUserInit. Note that the kernel side
|
||||
* of the API must be successfully registered with
|
||||
* vmk_MgmtInit prior to attempting to initialize the
|
||||
* user-space side. There can be multiple applications or
|
||||
* threads using vmk_MgmtUserInit for the same API signature,
|
||||
* but only one kernel module can service that API signature.
|
||||
*
|
||||
* \note The signature provided here must be compatible with the
|
||||
* signature of the API that has been registered with the kernel.
|
||||
* if "vendor" is specified (non-null) in the signature, a
|
||||
* connection will only be made if the vendor matches.
|
||||
*
|
||||
* \param[in] sig The API signature describing the
|
||||
* management operations that can be done.
|
||||
* Must match a signature registered in the
|
||||
* kernel.
|
||||
* \param[in] userCookie A data cookie that will be provided as
|
||||
* the first argument to all user-space
|
||||
* callbacks.
|
||||
* \param[out] handle An opaque handle that will be used for
|
||||
* further interaction with the API.
|
||||
*
|
||||
* \retval 0 Initialization succeeded.
|
||||
* \retval other A UNIX-style error code.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
int
|
||||
vmk_MgmtUserInit(vmk_MgmtApiSignature *sig,
|
||||
vmk_uint64 userCookie,
|
||||
vmk_MgmtUserHandle *handle);
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtUserGetInstances */ /**
|
||||
*
|
||||
* \brief Get instance information for all kernel-registered instances.
|
||||
*
|
||||
* \note The instanceIds populated in the vmk_MgmtInstances structure
|
||||
* can be subsequently used to send a callback request to a
|
||||
* specific instance with vmk_MgmtUserCallbackInvoke
|
||||
*
|
||||
* \param[in] handle Management handle that was initialized
|
||||
* \param[out] instances Current instance information for given handle
|
||||
*
|
||||
* \retval 0 Succeeded getting instances.
|
||||
* \retval other A UNIX-style error code.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
int
|
||||
vmk_MgmtUserGetInstances(vmk_MgmtUserHandle handle,
|
||||
vmk_MgmtInstances *instances);
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtUserBegin */ /**
|
||||
*
|
||||
* \brief Begin execution of user callbacks.
|
||||
*
|
||||
* \note This call creates a separate thread to monitor incoming
|
||||
* callback requests from the kernel for the given management
|
||||
* handle and immediately begins execution of those callbacks
|
||||
* as they arrive.
|
||||
* \note This is not necessary if your application is not meant to
|
||||
* handle callbacks delivered from the kernel.
|
||||
*
|
||||
*
|
||||
* param[in] handle Management handle that was initialized
|
||||
*
|
||||
* \retval 0 Succeeded initializing callback execution
|
||||
* \retval other A UNIX-style error code
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
int
|
||||
vmk_MgmtUserBegin(vmk_MgmtUserHandle handle);
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtUserContinue */ /**
|
||||
*
|
||||
* \brief Indefinitely continue monitoring and executing incoming kernel
|
||||
* callback requests in user space.
|
||||
*
|
||||
* \note vmk_MgmtUserBegin must have been successfully executed prior
|
||||
* to calling vmk_MgmtUserContinue.
|
||||
* \note Invoking vmk_MgmtUserContinue effectively makes the current
|
||||
* (calling) thread run indefinitely, in a monitoring mode. This
|
||||
* is typically used by resident CIM providers. To terminate
|
||||
* monitoring on a particular management handle after
|
||||
* vmk_MgmtUserBegin or vmk_MgmtUserContinue has been executed,
|
||||
* vmk_MgmtUserEnd. vmk_MgmtUserContinue does not return until
|
||||
* vmk_MgmtUserEnd is separately executed on the same handle
|
||||
* from within the same process. To use vmk_MgmtUserEnd after
|
||||
* vmk_MgmtUserContinue, you must create a separate pthread that
|
||||
* will invoke vmk_MgmtUserEnd sometime later after your main
|
||||
* thread has invoked vmk_MgmtUserContinue.
|
||||
*
|
||||
* \param[in] handle Management handle that was initialized
|
||||
*
|
||||
* \retval 0 Execution succeeded and was ended without error.
|
||||
* This will happen at some future moment in time,
|
||||
* after vmk_MgmtUserEnd has been used.
|
||||
* \retval Other A UNIX error code. Execution terminated,
|
||||
* possibly early with error.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
int
|
||||
vmk_MgmtUserContinue(vmk_MgmtUserHandle handle);
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtUserEnd */ /**
|
||||
*
|
||||
* \brief Terminate monitoring and execution of kernel-to-user callbacks.
|
||||
*
|
||||
* \note This may be called after either vmk_MgmtUserBegin or
|
||||
* vmk_MgmtUserContinue.
|
||||
* \note Because vmk_MgmtUserContinue does not return, a separate
|
||||
* thread within the same process space is required to invoked
|
||||
* vmk_MgmtUserEnd. The effect of vmk_MgmtUserEnd will be to
|
||||
* cease processing of any additional incoming callback requests
|
||||
* from the kernel, but the management handle will remain open.
|
||||
* Processing of inbound callback requests from the kernel can
|
||||
* be resumed if vmk_MgmtUserBegin is subsequently used on the
|
||||
* given handle.
|
||||
*
|
||||
* \param[in] handle Management handle that was initialized.
|
||||
*
|
||||
* \retval 0 Execution was successfully ended.
|
||||
* \retval Other A UNIX-style error code indicating the nature of
|
||||
* an error that was encountered.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
int
|
||||
vmk_MgmtUserEnd(vmk_MgmtUserHandle handle);
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtUserDestroy */ /**
|
||||
*
|
||||
* \brief Destroy the user side connection to a management handle.
|
||||
*
|
||||
* \note This will terminate receiving of callback requests from the
|
||||
* kernel and terminate the ability to send new callback
|
||||
* requests to the kernel.
|
||||
*
|
||||
* \param[in] handle Management handle that was initialized.
|
||||
*
|
||||
* \retval 0 Handle was destroyed completely without error.
|
||||
* \retval Other A UNIX-style error code indicating the nature
|
||||
* of the failure. The handle should not be used
|
||||
* again even after a failure, however.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
int
|
||||
vmk_MgmtUserDestroy(vmk_MgmtUserHandle handle);
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_MgmtUserCallbackInvoke */ /**
|
||||
*
|
||||
* \brief From user space, invoke a callback inside the kernel.
|
||||
*
|
||||
* \note Parameter handling: For asynchronous callbacks, all
|
||||
* parameters are internally copied for delivery to the kernel.
|
||||
* For synchronous callbacks, input and input-output parameters
|
||||
* are copied internally and delivered to the kernel. For
|
||||
* input-output and output parameters, such parameters are copied
|
||||
* from the kernel back to user-space (to the pointer indicated
|
||||
* by the corresponding parameter given to this function) after
|
||||
* the callback has executed. In addition to the payload
|
||||
* parameters passed here, the receiving callback in the kernel
|
||||
* will be provided the kernel-side data cookie that the
|
||||
* receiver registered with vmk_MgmtInit and the instanceId
|
||||
* specificed here. If an instanceId is specified, the callback
|
||||
* function invoked in the kernel will be the instance-specific
|
||||
* callback (if it was specified when the instance was added) or
|
||||
* the default callback function registered with the API
|
||||
* signature (if no instance-specific callback was specified
|
||||
* for this callback when the instance was added).
|
||||
*
|
||||
* \param[in] handle Management handle that was initialized.
|
||||
* \param[in] instanceId The unique instance ID to send this callback
|
||||
* to. If this is not an instance-specific
|
||||
* invocation, use VMK_MGMT_NO_INSTANCE_ID.
|
||||
* \param[in] callbackId The unique ID corresponding to the callback
|
||||
* to invoke, as registered with the API
|
||||
* signature.
|
||||
* \param[in] ... A variable list of parameters, each one
|
||||
* a (void *) pointer to the parameter
|
||||
* being passed to the callback. The number
|
||||
* of parameters must match that described for
|
||||
* the given callbackId when the API signature
|
||||
* was registered.
|
||||
* \retval 0 For asynchronous callbacks, this means that the callback
|
||||
* successfully was queued. For synchronous callbacks,
|
||||
* this means that the callback has executed completely.
|
||||
* \retval Other A UNIX-style error code corresponding to the error
|
||||
* encountered when attempting to queue or execute the
|
||||
* callback.
|
||||
* \note The return value is not a indication or return code of the
|
||||
* callback itself.
|
||||
*
|
||||
*/
|
||||
#define vmk_MgmtUserCallbackInvoke( \
|
||||
/* (vmk_MgmtHandle *) */ handle, \
|
||||
/* (vmk_uint64) */ instanceId, \
|
||||
/* (vmk_uint64) */ callbackId, \
|
||||
...) \
|
||||
vmk_MgmtUserCallbackInvokeInt(handle, instanceId, callbackId, VMK_UTIL_NUM_ARGS(__VA_ARGS__), ##__VA_ARGS__)
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_MgmtUserCallbackInvokeInt --
|
||||
*
|
||||
* This is used by vmk_MgmtUserCallbackInvoke(). VMKAPI clients should
|
||||
* never call this function directly.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
int
|
||||
vmk_MgmtUserCallbackInvokeInt(vmk_MgmtUserHandle handle,
|
||||
vmk_uint64 instanceId,
|
||||
vmk_uint64 callbackId,
|
||||
vmk_uint32 argCount,
|
||||
...);
|
||||
|
||||
#endif /* _VMKAPI_MGMT_LIB_H_ */
|
||||
/** @} */
|
|
@ -0,0 +1,228 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2012 - 2013 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Management Types */ /**
|
||||
* \addtogroup Mgmt
|
||||
*
|
||||
* Types used by user- and kernel-space when interacting with the vmkapi
|
||||
* management interfaces and library.
|
||||
*
|
||||
* @{
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* vmkapi_mgmt_types.h --
|
||||
*
|
||||
* Interfaces for defining management APIs for vmkernel-based
|
||||
* modules, which need to be shared with user-space.
|
||||
*/
|
||||
|
||||
#ifndef _VMKAPI_MGMT_TYPES_H_
|
||||
#define _VMKAPI_MGMT_TYPES_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 "lib/vmkapi_name.h"
|
||||
#include "lib/vmkapi_revision.h"
|
||||
|
||||
/**
|
||||
* The maximum number of data payload parameters per callback,
|
||||
* excluding the cookie and instance parameters.
|
||||
*/
|
||||
#define VMK_MGMT_MAX_CALLBACK_PARMS 4
|
||||
|
||||
/**
|
||||
* \brief Callback IDs 0 through VMK_MGMT_RESERVED_CALLBACKS inclusive
|
||||
* are reserved by the system and may not be used by consumers
|
||||
* of the API.
|
||||
*/
|
||||
#define VMK_MGMT_RESERVED_CALLBACKS 15
|
||||
|
||||
#define VMK_MGMT_NO_INSTANCE_ID 0
|
||||
|
||||
/**
|
||||
* \brief The type of a key used in a key-value management channel.
|
||||
*/
|
||||
typedef enum vmk_MgmtKeyType {
|
||||
/**
|
||||
* \brief An 8-byte integer
|
||||
*/
|
||||
VMK_MGMT_KEY_TYPE_LONG = 1,
|
||||
/**
|
||||
* \brief A 4096-byte (including nul) character string.
|
||||
*/
|
||||
VMK_MGMT_KEY_TYPE_STRING = 2,
|
||||
} vmk_MgmtKeyType;
|
||||
|
||||
/**
|
||||
* \brief The maximum number of bytes in a VMK_MGMT_KEY_TYPE_STRING key.
|
||||
*/
|
||||
#define VMK_MGMT_KEY_STRING_MAXLEN 4096
|
||||
|
||||
/**
|
||||
* \brief The maximum number of keys that can be added to a
|
||||
* vmk_MgmtHandle instance.
|
||||
*/
|
||||
#define VMK_MGMT_MAX_KEYS_PER_INSTANCE 32
|
||||
|
||||
/**
|
||||
* \brief The maximum number of instances that can be added to a management handle.
|
||||
*/
|
||||
#define VMK_MGMT_MAX_INSTANCES 32
|
||||
|
||||
/**
|
||||
* \brief The location where a callback will execute.
|
||||
*/
|
||||
typedef enum vmk_MgmtCallbackLocation {
|
||||
VMK_MGMT_CALLBACK_KERNEL = 1,
|
||||
VMK_MGMT_CALLBACK_USER,
|
||||
} vmk_MgmtCallbackLocation;
|
||||
|
||||
/**
|
||||
* \brief The type of a parameter to a callback
|
||||
*/
|
||||
typedef enum vmk_MgmtParm {
|
||||
/** \brief An input parameter to a callback. The contents of the
|
||||
* parameter will be copied before invoking the callback.
|
||||
*/
|
||||
VMK_MGMT_PARMTYPE_IN = 0,
|
||||
/**
|
||||
* \brief An output parameter to a callback. Only valid for
|
||||
* synchronous callbacks that are executed in the kernel. The
|
||||
* contents of the parameter will be copied back to the caller
|
||||
* after the callback has executed.
|
||||
*/
|
||||
VMK_MGMT_PARMTYPE_OUT,
|
||||
/**
|
||||
* \brief An input-output parameter to a callback. Only valid
|
||||
* for synchronous callbacks that are executed in the kernel.
|
||||
* The contents of the parameter will be copied before the
|
||||
* callback has executed and again copied back to the caller after
|
||||
* execution.
|
||||
*/
|
||||
VMK_MGMT_PARMTYPE_INOUT,
|
||||
} vmk_MgmtParmType;
|
||||
|
||||
/**
|
||||
* \brief A description of a single callback that is part of an overall API.
|
||||
*/
|
||||
typedef struct vmk_MgmtCallbackInfo {
|
||||
/** \brief The location where the callback runs. */
|
||||
vmk_MgmtCallbackLocation location;
|
||||
/**
|
||||
* \brief A function pointer to the callback.
|
||||
* A callback function pointer only needs to be provided if this
|
||||
* signature is being registered where this callback would run. For
|
||||
* example, if the API is being registered with the kernel, only
|
||||
* VMK_MGMT_CALLBACK_KERNEL callbacks require a value here.
|
||||
* Callback functions must not assume that they execute with any kind of
|
||||
* serialization. If multiple management handle instances specify the same
|
||||
* callback function, then that callback function can be executed simultaneously.
|
||||
* By separate callers. If your callback function requires synchronization
|
||||
* among multiple potential callers, then your callback function must
|
||||
* implement that synchronization.
|
||||
*/
|
||||
void *callback;
|
||||
/** \brief Indicates if this callback is executed synchronously to the caller.
|
||||
* As noted for the callback parameter, even if a callback is
|
||||
* marked "synchronous", a callback could be invoked simultaneously
|
||||
* by multiple callers. "synchronous" describes the semantics as
|
||||
* viewed by the caller, not that the callee (the callback) can assume
|
||||
* that it is invoked atomically.
|
||||
*/
|
||||
vmk_Bool synchronous;
|
||||
/**
|
||||
* Number of parameters to the callback, excluding the data
|
||||
* cookie and instance parameters (which are provided as the first two
|
||||
* arguments). For example, a numParms value of 0 means that the callback
|
||||
* must take two arguments - the data cookie and instance ID - but no
|
||||
* payload parameters.
|
||||
*/
|
||||
vmk_uint8 numParms;
|
||||
/**
|
||||
* \brief The size of each callback, in the order that they are passed.
|
||||
* \note Excludes the data cookie and instance ID.
|
||||
*/
|
||||
int parmSizes[VMK_MGMT_MAX_CALLBACK_PARMS];
|
||||
/**
|
||||
* \brief The type of each callback, in the order that they are passed.
|
||||
* \note Excludes the data cookie and instance ID.
|
||||
*/
|
||||
vmk_MgmtParmType parmTypes[VMK_MGMT_MAX_CALLBACK_PARMS];
|
||||
/**
|
||||
* \brief An identifier for this callback.
|
||||
* \note Must be unique within the scope of call callbacks registered
|
||||
* in an API signature. May not be 0.
|
||||
*/
|
||||
vmk_uint64 callbackId;
|
||||
} vmk_MgmtCallbackInfo;
|
||||
|
||||
/**
|
||||
* \brief The signature for an API being initialized at either the kernel
|
||||
* or user layer
|
||||
*/
|
||||
typedef struct vmk_MgmtApiSignature {
|
||||
/**
|
||||
* \brief Version of the API. By default, versions of an API with the
|
||||
* same major and minor are compatible with each other and will
|
||||
* allow initialization and communication between the registered
|
||||
* instances on the user or kernel side. The minor, update,
|
||||
* and patch numbers will be used for distinguishing minor
|
||||
* differences that can be shimmed by providers.
|
||||
*/
|
||||
vmk_revnum version;
|
||||
/**
|
||||
* \brief Name of the API. The version and name must be unique.
|
||||
*/
|
||||
vmk_Name name;
|
||||
/**
|
||||
* \brief Vendor implementing this side (user or kernel) of the API.
|
||||
* Optional.
|
||||
*/
|
||||
vmk_Name vendor;
|
||||
/** \brief The number of callbacks this API has. */
|
||||
int numCallbacks;
|
||||
/** \brief The information describing each callback */
|
||||
vmk_MgmtCallbackInfo *callbacks;
|
||||
} vmk_MgmtApiSignature;
|
||||
|
||||
|
||||
/**
|
||||
* \brief A description of specific instances registered to a management handle.
|
||||
* \note An application can get the instances associated with a handle and
|
||||
* then can subsequently send callbacks to instances using the
|
||||
* instanceIds as reported in this structure.
|
||||
*/
|
||||
typedef struct vmk_MgmtInstances {
|
||||
/**
|
||||
* /brief The number of instances managed on this API handle.
|
||||
*/
|
||||
vmk_uint8 numInstances;
|
||||
|
||||
/**
|
||||
* /brief The instance IDs that are managed.
|
||||
*/
|
||||
vmk_uint64 instanceIds[VMK_MGMT_MAX_INSTANCES];
|
||||
|
||||
/**
|
||||
* \brief The presentation names for each of the instances.
|
||||
*/
|
||||
vmk_Name instanceNames[VMK_MGMT_MAX_INSTANCES];
|
||||
} vmk_MgmtInstances;
|
||||
|
||||
#endif /* _VMKAPI_MGMT_TYPES_H_ */
|
||||
/** @} */
|
||||
|
|
@ -48,7 +48,7 @@
|
|||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
#define VMK_NAMESPACE_CURRENT_VERSION "v2_1_0_0"
|
||||
#define VMK_NAMESPACE_CURRENT_VERSION "v2_2_0_0"
|
||||
|
||||
#endif /* _VMKAPI_MODULE_NS_H_ */
|
||||
/** @} */
|
||||
|
|
|
@ -53,6 +53,8 @@ typedef vmk_uintptr_t vmk_CPUFlags;
|
|||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
void vmk_CPUDisableInterrupts(void);
|
||||
|
@ -66,6 +68,8 @@ void vmk_CPUDisableInterrupts(void);
|
|||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
void vmk_CPUEnableInterrupts(void);
|
||||
|
@ -82,6 +86,8 @@ void vmk_CPUEnableInterrupts(void);
|
|||
* \retval VMK_TRUE Interrupts are enabled on the current CPU.
|
||||
* \retval VMK_FALSE Interrupts are disabled on the current CPU.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
vmk_Bool vmk_CPUHasIntsEnabled(void);
|
||||
|
@ -93,6 +99,8 @@ vmk_Bool vmk_CPUHasIntsEnabled(void);
|
|||
* \ingroup Platform
|
||||
* \brief Assert that interrupts are enabled on the current CPU.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
#define VMK_ASSERT_CPU_HAS_INTS_ENABLED() \
|
||||
|
@ -121,6 +129,8 @@ vmk_Bool vmk_CPUHasIntsEnabled(void);
|
|||
*
|
||||
* \return The current CPU's interrupt flags.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
vmk_CPUFlags vmk_CPUGetFlags(void);
|
||||
|
@ -134,6 +144,8 @@ vmk_CPUFlags vmk_CPUGetFlags(void);
|
|||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
void vmk_CPUSetFlags(
|
||||
|
@ -200,5 +212,49 @@ static VMK_ALWAYS_INLINE void vmk_CPUMemFenceReadWrite(void)
|
|||
asm volatile ("mfence" ::: "memory");
|
||||
}
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_CPUCacheFlush -- */ /**
|
||||
*
|
||||
* \ingroup Platform
|
||||
* \brief Flushes the cache lines on the local PCPU for the memory
|
||||
* region specified.
|
||||
*
|
||||
* \note If a specific operation required flushing the cache line of
|
||||
* the local PCPU, both that operation and this call should
|
||||
* come within the same VMK_WITH_PCPU_DO region.
|
||||
*
|
||||
* \param[in] pcpu PCPU ID obtained from VMK_WITH_PCPU_DO.
|
||||
* \param[in] va Starting virtual address of memory region.
|
||||
* \param[in] size Size of memory region.
|
||||
*
|
||||
* \retval VMK_OK Cache lines successfully flushed.
|
||||
* \retval VMK_BAD_PARAM An invalid parameter was specified.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_CPUCacheFlush(
|
||||
vmk_PCPUID pcpu,
|
||||
vmk_VA va,
|
||||
vmk_ByteCount size);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_CPUGlobalCacheFlush -- */ /**
|
||||
*
|
||||
* \ingroup Platform
|
||||
* \brief Flushes all modified cache lines on all PCPUs.
|
||||
*
|
||||
* \note This function will block.
|
||||
*
|
||||
* \note This is an expensive operation that should be used rarely and
|
||||
* not at all on fast paths.
|
||||
*
|
||||
* \retval VMK_OK Cachelines successfully flushed.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_CPUGlobalCacheFlush(void);
|
||||
|
||||
#endif /* _VMKAPI_PLATFORM_H_ */
|
||||
/* @} */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2004 - 2009 VMware, Inc. All rights reserved.
|
||||
* Copyright 2004 - 2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
|
@ -216,7 +216,7 @@
|
|||
DEFINE_VMK_ERR(VMK_MEM_MIN_GT_MEMSIZE, "Memory min exceeds memSize", EINVAL )\
|
||||
DEFINE_VMK_ERR(VMK_NO_SUCH_VT, "No virtual terminal for number", ENXIO )\
|
||||
DEFINE_VMK_ERR(VMK_TOO_MANY_ELEMENTS, "Too many elements for list", E2BIG )\
|
||||
DEFINE_VMK_ERR(VMK_SHAREDAREA_MISMATCH, "VMM<->VMK shared are mismatch", ENOSYS )\
|
||||
DEFINE_VMK_ERR(VMK_SHAREDAREA_MISMATCH, "VMM<->VMK shared area mismatch", ENOSYS )\
|
||||
DEFINE_VMK_ERR(VMK_EXEC_FAILURE, "Failure during exec while original state already lost", ESRCH )\
|
||||
DEFINE_VMK_ERR(VMK_INVALID_MODULE, "Invalid module", EINVAL )\
|
||||
DEFINE_VMK_ERR(VMK_UNALIGNED_ADDRESS, "Address is not aligned on required boundary", EINVAL )\
|
||||
|
@ -349,7 +349,7 @@
|
|||
DEFINE_VMK_ERR(VMK_MODULE_NONAMESPACE, "Module tried to export a symbol but didn't provide a name space", ENOENT )\
|
||||
DEFINE_VMK_ERR(VMK_FS_OBJECT_UNLINKED, "File system object is unlinked", EINVAL )\
|
||||
DEFINE_VMK_ERR(VMK_HBR_WIRE_INSTANCE_ABORTED, "Replication instance was aborted", ECANCELED )\
|
||||
DEFINE_VMK_ERR(VMK_HBR_WIRE_NEED_FULL_SYNC, "Replicated disk needs full sync", EINVAL )\
|
||||
DEFINE_VMK_ERR(VMK_HBR_WIRE_NEED_FULL_SYNC, "Replicated disk needs full synchronization", EINVAL )\
|
||||
DEFINE_VMK_ERR(VMK_HBR_WIRE_DISK_SET_MISMATCH, "The set of disks on the replication server doesn't match", EINVAL )\
|
||||
DEFINE_VMK_ERR(VMK_HBR_WIRE_REQUEST_CHECKSUM_MISMATCH, "The checksum for the replication request was invalid", EINVAL )\
|
||||
DEFINE_VMK_ERR(VMK_HBR_WIRE_RESPONSE_CHECKSUM_MISMATCH, "The checksum for the replication response was invalid", EINVAL )\
|
||||
|
@ -362,7 +362,12 @@
|
|||
DEFINE_VMK_ERR(VMK_EPROTOTYPE, "Invalid protocol for connection", EPROTOTYPE )\
|
||||
DEFINE_VMK_ERR(VMK_MODULE_CONSUMED_RESOURCE_COUNT_NOT_ZERO, "Consumed resource count of module is not zero", EBUSY )\
|
||||
DEFINE_VMK_ERR(VMK_HBR_SERVER_DOES_NOT_SUPPORT_REQUEST, "vSphere Replication Server does not support request", EOPNOTSUPP )\
|
||||
DEFINE_VMK_ERR(VMK_STALE_FILEHANDLE, "Stale file handle", ESTALE)\
|
||||
DEFINE_VMK_ERR(VMK_STALE_FILEHANDLE, "Stale file handle", ESTALE )\
|
||||
DEFINE_VMK_ERR(VMK_VVOL_UNBOUND, "Virtual volume not bound", ENODEV )\
|
||||
DEFINE_VMK_ERR(VMK_DEVICE_NOT_READY_FAIL_OPEN, "Device open failed with no-retry", EPERM )\
|
||||
DEFINE_VMK_ERR(VMK_NOT_THIS_DEVICE, "Not for this device", EINVAL )\
|
||||
DEFINE_VMK_ERR(VMK_IGNORE, "Ignore", EINVAL )\
|
||||
DEFINE_VMK_ERR(VMK_OBJECT_DESTROYED, "Object is being or has been destroyed.", EINVAL )\
|
||||
/* --- ADD NEW ERROR CODES ABOVE THIS COMMENT. VMK_GENERIC_LINUX_ERROR must be last. --- */ \
|
||||
DEFINE_VMK_ERR_AT(VMK_GENERIC_LINUX_ERROR, "Generic service console error", 0x2bad0000, EIO )
|
||||
/* --- Don't add ERR_AT with negative value. --- */
|
||||
|
|
|
@ -30,12 +30,15 @@
|
|||
/** \brief Known invalid value for a timer */
|
||||
#define VMK_INVALID_TIMER ((vmk_Timer)NULL)
|
||||
|
||||
/** \brief Known invalid value for a timer queue */
|
||||
#define VMK_INVALID_TIMER_QUEUE ((vmk_TimerQueue)NULL)
|
||||
|
||||
typedef vmk_int64 vmk_TimerRelCycles;
|
||||
typedef vmk_uint64 vmk_TimerCycles;
|
||||
|
||||
typedef vmk_AddrCookie vmk_TimerCookie;
|
||||
typedef void (*vmk_TimerCallback)(vmk_TimerCookie data);
|
||||
typedef struct vmk_TimerInt *vmk_Timer;
|
||||
typedef struct vmk_TimerQueueInt *vmk_TimerQueue;
|
||||
|
||||
/**
|
||||
* \brief Representation for Time
|
||||
|
@ -45,6 +48,27 @@ typedef struct {
|
|||
vmk_int64 usec; /* microseconds */
|
||||
} vmk_TimeVal;
|
||||
|
||||
/**
|
||||
* \brief Attributes dictating timer queue behavior
|
||||
*/
|
||||
typedef vmk_uint64 vmk_TimerQueueAttributes;
|
||||
|
||||
/** normal timer queue */
|
||||
#define VMK_TIMER_QUEUE_ATTR_NONE (0)
|
||||
|
||||
/** low latency timer queue */
|
||||
#define VMK_TIMER_QUEUE_ATTR_LOW_LATENCY (1 << 0)
|
||||
|
||||
/**
|
||||
* \brief Properties for a new timer queue
|
||||
*/
|
||||
typedef struct {
|
||||
vmk_Name name;
|
||||
vmk_ModuleID moduleID;
|
||||
vmk_HeapID heapID;
|
||||
vmk_TimerQueueAttributes attribs;
|
||||
} vmk_TimerQueueProps;
|
||||
|
||||
/**
|
||||
* \brief Timer Attributes
|
||||
*/
|
||||
|
@ -54,6 +78,8 @@ typedef vmk_uint64 vmk_TimerAttributes;
|
|||
#define VMK_TIMER_ATTR_NONE (0)
|
||||
/** Periodic timer */
|
||||
#define VMK_TIMER_ATTR_PERIODIC (1 << 0)
|
||||
/** Default tolerance value */
|
||||
#define VMK_TIMER_DEFAULT_TOLERANCE (-1)
|
||||
|
||||
|
||||
/* Convenient time constants */
|
||||
|
@ -74,6 +100,24 @@ typedef vmk_uint64 vmk_TimerAttributes;
|
|||
#define VMK_TIMEOUT_UNLIMITED_MS (VMK_UINT32_MAX)
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_TimerCallback -- */ /**
|
||||
*
|
||||
* \brief Callback function invoked when timer fires.
|
||||
*
|
||||
* \note This callback is allowed to block; however, ready timers on
|
||||
* the same vmk_TimerQueue will not fire until the firing timer
|
||||
* has finished, so blocking in this callback may delay other
|
||||
* scheduled timers.
|
||||
*
|
||||
* \param[in] data vmk_TimerCookie provided when timer scheduled.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef void (*vmk_TimerCallback)(vmk_TimerCookie data);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_GetTimerCycles -- */ /**
|
||||
|
@ -286,7 +330,7 @@ void vmk_DelayUsecs(
|
|||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_TimerSchedule -- */ /**
|
||||
* vmk_TimerScheduleCustom -- */ /**
|
||||
*
|
||||
* \brief Schedule a timer
|
||||
*
|
||||
|
@ -300,10 +344,78 @@ void vmk_DelayUsecs(
|
|||
* system-wide, and exceeding the limit is a fatal error.
|
||||
*
|
||||
* \param[in] moduleID ID of the module to which callback belongs
|
||||
* \param[in] queue The timer queue to use for the timer
|
||||
* \param[in] callback Timer callback.
|
||||
* \param[in] data Argument passed to the timer callback on
|
||||
* timeout.
|
||||
* \param[in] timeoutUS Timeout in microseconds.
|
||||
* \param[in] toleranceUS Tolerance in microseconds. Indicates a
|
||||
* request that the timer fire approximately
|
||||
* no later than the provided value from the
|
||||
* requested time. The majority of callers
|
||||
* should specify a tolerance of
|
||||
* VMK_TIMER_DEFAULT_TOLERANCE and only use
|
||||
* other values for timers that have strict
|
||||
* timing requirements.
|
||||
* \param[in] attributes Additional timer attributes
|
||||
* \param[in] lockDomain Lock domain in which to check the lock rank.
|
||||
* Note that if lockDomain is set to invalid
|
||||
* then rank has to be set to unranked and if
|
||||
* lockDomain is set to a valid value then
|
||||
* rank has to contain a valid rank value.
|
||||
* \param[in] lockRank Rank of the timer
|
||||
* \param[out] wasPending If rescheduling a timer, was it previously
|
||||
* pending? (optional)
|
||||
* \param[out] timer Timer Handle
|
||||
*
|
||||
* \retval VMK_NO_RESOURCES Couldn't schedule the timer.
|
||||
* \retval VMK_OK The timer was successfully scheduled.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
VMK_ReturnStatus vmk_TimerScheduleCustom(
|
||||
vmk_ModuleID moduleID,
|
||||
vmk_TimerQueue queue,
|
||||
vmk_TimerCallback callback,
|
||||
vmk_TimerCookie data,
|
||||
vmk_int64 timeoutUS,
|
||||
vmk_int64 toleranceUS,
|
||||
vmk_TimerAttributes attributes,
|
||||
vmk_LockDomainID lockDomain,
|
||||
vmk_LockRank lockRank,
|
||||
vmk_Bool *wasPending,
|
||||
vmk_Timer *timer);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_TimerSchedule -- */ /**
|
||||
*
|
||||
* \brief Schedule a timer
|
||||
*
|
||||
* The VMKernel can schedule simultaneously a limited number of timers
|
||||
* for each CPU.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \warning Timers are a limited resource. The VMKernel does not
|
||||
* guarantee to provide more than 100 concurrent timers per CPU
|
||||
* system-wide, and exceeding the limit is a fatal error.
|
||||
*
|
||||
* \param[in] queue The timer queue to use for the timer
|
||||
* \param[in] callback Timer callback.
|
||||
* \param[in] data Argument passed to the timer callback on
|
||||
* timeout.
|
||||
* \param[in] timeoutUS Timeout in microseconds.
|
||||
* \param[in] toleranceUS Tolerance in microseconds. Indicates a
|
||||
* request that the timer fire approximately
|
||||
* no later than the provided value from the
|
||||
* requested time. The majority of callers
|
||||
* should specify a tolerance of
|
||||
* VMK_TIMER_DEFAULT_TOLERANCE and only use
|
||||
* other values for timers that have strict
|
||||
* timing requirements.
|
||||
* \param[in] attributes Additional timer attributes
|
||||
* \param[in] lockDomain Lock domain in which to check the lock rank.
|
||||
* Note that if lockDomain is set to invalid
|
||||
|
@ -320,10 +432,11 @@ void vmk_DelayUsecs(
|
|||
*/
|
||||
|
||||
VMK_ReturnStatus vmk_TimerSchedule(
|
||||
vmk_ModuleID moduleID,
|
||||
vmk_TimerQueue queue,
|
||||
vmk_TimerCallback callback,
|
||||
vmk_TimerCookie data,
|
||||
vmk_int64 timeoutUS,
|
||||
vmk_int64 toleranceUS,
|
||||
vmk_TimerAttributes attributes,
|
||||
vmk_LockDomainID lockDomain,
|
||||
vmk_LockRank lockRank,
|
||||
|
@ -389,9 +502,63 @@ VMK_ReturnStatus vmk_TimerCancel(
|
|||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
vmk_Bool vmk_TimerIsPending(
|
||||
vmk_Timer timer);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_TimerQueueCreate -- */ /**
|
||||
*
|
||||
* \brief Create a timer queue.
|
||||
*
|
||||
* \note This function will may block.
|
||||
*
|
||||
* \param[in] props Properties of the new timer queue.
|
||||
*
|
||||
* \param[out] queue The newly created queue.
|
||||
*
|
||||
* \retval VMK_OK The timer queue was created successfuly,
|
||||
* and can now be used to schedule timers.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM Invalid parameters passed into the function.
|
||||
* Make sure that all fields in the provided
|
||||
* properties are valid.
|
||||
*
|
||||
* \retval VMK_NO_RESOURCES Ran out of resources to create the timer
|
||||
* queue.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
VMK_ReturnStatus vmk_TimerQueueCreate(
|
||||
vmk_TimerQueueProps *props,
|
||||
vmk_TimerQueue *queue);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_TimerQueueDestroy -- */ /**
|
||||
*
|
||||
* \brief Destroy a timer queue. All timers in the queue are cancelled.
|
||||
* Memory for the timer queue and associate timers is released
|
||||
* back to the heap that the queue was allocated from.
|
||||
*
|
||||
* \note This function will may block.
|
||||
*
|
||||
* \param[in] queue The queue.
|
||||
*
|
||||
* \retval VMK_OK The timer queue is destroyed.
|
||||
*
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
VMK_ReturnStatus vmk_TimerQueueDestroy(
|
||||
vmk_TimerQueue queue);
|
||||
|
||||
|
||||
#endif /* _VMKAPI_TIME_H_ */
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
/* **********************************************************
|
||||
* Copyright 1998 - 2012VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* VersionedAtomic */ /**
|
||||
* \defgroup VersionedAtomic Version Atomic
|
||||
*
|
||||
* \par Versioned atomic synchronization:
|
||||
* These synchronization macros allow single-writer/many-reader access
|
||||
* to data, based on Leslie Lamport's paper "Concurrent Reading and
|
||||
* Writing", Communications of the ACM, November 1977.\n
|
||||
* \n
|
||||
* Many-writer/many-reader can be implemented on top of versioned
|
||||
* atomics by using an additional spin lock to synchronize writers.
|
||||
* This is preferable for cases where readers are expected to greatly
|
||||
* outnumber writers.\n
|
||||
* \n
|
||||
* Multiple concurrent writers to the version variables are not allowed.
|
||||
* Even if writers are working on lock-free or disjoint data, the
|
||||
* version counters are not interlocked for read-modify-write.\n
|
||||
* \n
|
||||
* Recursive use of versioned atomics in writers is currently not
|
||||
* supported.
|
||||
*
|
||||
* @{
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _VMKAPI_VERSIONED_ATOMIC_H
|
||||
#define _VMKAPI_VERSIONED_ATOMIC_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 */
|
||||
|
||||
|
||||
/**
|
||||
* \brief Versioned Atomic
|
||||
*/
|
||||
|
||||
typedef struct vmk_VersionedAtomic {
|
||||
/** version 0 */
|
||||
volatile vmk_uint32 v0;
|
||||
|
||||
/** version 1 */
|
||||
volatile vmk_uint32 v1;
|
||||
} VMK_ATTRIBUTE_ALIGN(4) vmk_VersionedAtomic;
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_VersionedAtomicInit -- */ /**
|
||||
*
|
||||
* \brief Intiialize a versioned atomic
|
||||
* \param[in] versions Pointer to the versioned atomic to be
|
||||
* initialized
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
static VMK_ALWAYS_INLINE void
|
||||
vmk_VersionedAtomicInit(vmk_VersionedAtomic *versions)
|
||||
{
|
||||
versions->v0 = 0;
|
||||
versions->v1 = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_VersionedAtomicBeginWrite -- */ /**
|
||||
*
|
||||
* \brief Writer begins write to protected data
|
||||
*
|
||||
* Called by a writer to indicate that the data protected by a given
|
||||
* atomic version is about to change. Effectively locks out all readers
|
||||
* until EndWrite is called.
|
||||
*
|
||||
* \param[in] versions Pointer to the versioned atomic protecting
|
||||
* the data
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
static VMK_ALWAYS_INLINE void
|
||||
vmk_VersionedAtomicBeginWrite(vmk_VersionedAtomic *versions)
|
||||
{
|
||||
VMK_ASSERT(((vmk_uint64)(&versions->v0) & (sizeof(versions->v0) - 1)) == 0);
|
||||
VMK_ASSERT(versions->v1 == versions->v0);
|
||||
versions->v0++;
|
||||
vmk_CPUMemFenceReadWrite();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_VersionedAtomicEndWrite -- */ /**
|
||||
*
|
||||
* \brief Writer finishes writing to protected data
|
||||
*
|
||||
* Called by a writer after it is done updating shared data. Lets
|
||||
* pending and new readers proceed on shared data.
|
||||
*
|
||||
* \param[in] versions Pointer to the versioned atomic protecting
|
||||
* the data
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
static VMK_ALWAYS_INLINE void
|
||||
vmk_VersionedAtomicEndWrite(vmk_VersionedAtomic *versions)
|
||||
{
|
||||
VMK_ASSERT(((vmk_uint64)(&versions->v1) & (sizeof(versions->v1) - 1)) == 0);
|
||||
VMK_ASSERT(versions->v1 + 1 == versions->v0);
|
||||
vmk_CPUMemFenceReadWrite();
|
||||
versions->v1 = versions->v0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_VersionedAtomicBeginTryRead -- */ /**
|
||||
*
|
||||
* \brief Reader tries to read protected data
|
||||
*
|
||||
* Called by a reader before it tried to read shared data.
|
||||
*
|
||||
* \param[in] versions Pointer to the versioned atomic protecting
|
||||
* the data
|
||||
*
|
||||
* \retval Returns a version number to the reader. This
|
||||
* version number is required to confirm
|
||||
* validity of the read operation when reader
|
||||
* calls vmk_VersionedAtomicEndTryRead.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
static VMK_ALWAYS_INLINE vmk_uint32
|
||||
vmk_VersionedAtomicBeginTryRead(const vmk_VersionedAtomic *versions)
|
||||
{
|
||||
vmk_uint32 readVersion;
|
||||
|
||||
readVersion = versions->v1;
|
||||
vmk_CPUMemFenceReadWrite();
|
||||
|
||||
return readVersion;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_VersionedAtomicEndTryRead -- */ /**
|
||||
*
|
||||
* \brief Reader finished reading protected data
|
||||
*
|
||||
* Called by a reader after it finishes reading shared data, to confirm
|
||||
* validity of the data that was just read, to make sure that a writer
|
||||
* did not intervene while the read was in progress.
|
||||
*
|
||||
* \param[in] versions Pointer to the versioned atomic protecting
|
||||
* the data
|
||||
* \param[in] readVersion The version number the reader just read,
|
||||
* returned by vmk_VersionedAtomicBeginTryRead
|
||||
*
|
||||
* \retval VMK_TRUE if the data read between
|
||||
* vmk_VersionedAtomicBeginTryRead() and this
|
||||
* call is valid.
|
||||
* \retval VMK_FALSE otherwise.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
static VMK_ALWAYS_INLINE vmk_Bool
|
||||
vmk_VersionedAtomicEndTryRead(const vmk_VersionedAtomic *versions,
|
||||
vmk_uint32 readVersion)
|
||||
{
|
||||
vmk_CPUMemFenceReadWrite();
|
||||
return VMK_LIKELY(versions->v0 == readVersion);
|
||||
}
|
||||
|
||||
#endif //__VMKAPI_VERSIONED_ATOMIC_H
|
||||
/** @} */
|
|
@ -1,5 +1,5 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2007 - 2009 VMware, Inc. All rights reserved.
|
||||
* Copyright 2007 - 2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
|
@ -15,7 +15,16 @@
|
|||
* are used to represent kernel threads, user processes, virtual CPUs,
|
||||
* etc. Each world is identified by an ID that is unique within the
|
||||
* system called the World ID. Worlds are blockable contexts; it is safe
|
||||
* to call functions that may block from a world context.
|
||||
* to call functions that may block from a world context.
|
||||
*
|
||||
* User processes also belong to cartels. A cartel is a group of worlds
|
||||
* that share certain resources including but not limited to their
|
||||
* address space. A cartel can be thought of as a user process and the
|
||||
* individual worlds that make up the cartel can be thought of as user
|
||||
* threads. Each user world will have a world ID and a cartel ID. Each
|
||||
* world in a cartel will share the same cartel ID. Note that it is
|
||||
* possible for a world's world ID and cartel ID to be equal, but
|
||||
* this can only be true for at most one world in the cartel.
|
||||
*
|
||||
*@{
|
||||
***********************************************************************
|
||||
|
@ -30,6 +39,8 @@
|
|||
#endif
|
||||
/** \endcond never */
|
||||
|
||||
#include "device/vmkapi_vector_types.h"
|
||||
|
||||
/**
|
||||
* \brief Event to block on.
|
||||
*
|
||||
|
@ -45,11 +56,63 @@ typedef vmk_int32 vmk_WorldID;
|
|||
|
||||
#define VMK_INVALID_WORLD_ID ((vmk_WorldID)0)
|
||||
|
||||
/** \brief Special vmk_WorldEventID for a no-event wait
|
||||
*
|
||||
* When used as the eventId parameter to vmk_WorldWait(),
|
||||
* the world will wait without being added to the system's
|
||||
* internal event queue. This allows for a lighter weight
|
||||
* synchronization mechanism, though the world sleeping in
|
||||
* this fashion can be awoken only by vmk_WorldForceWakeup(),
|
||||
* by a timeout, or if the world is being destroyed.
|
||||
*/
|
||||
#define VMK_EVENT_NONE ((vmk_WorldEventID)0)
|
||||
|
||||
/**
|
||||
* \brief Indication of unlimited CPU allocation (max)
|
||||
*/
|
||||
#define VMK_CPU_ALLOC_UNLIMITED ((vmk_uint32) -1)
|
||||
|
||||
/**
|
||||
* \brief Scheduler Class for a World
|
||||
*
|
||||
* Worlds of class VMK_WORLD_SCHED_CLASS_QUICK will be scheduled
|
||||
* to run ahead of worlds of class VMK_WORLD_SCHED_CLASS_DEFAULT.
|
||||
* Please be careful to use VMK_WORLD_SCHED_CLASS_QUICK only for
|
||||
* small deferred tasks that must execute promptly.
|
||||
*
|
||||
* If unsure of what class to use, pick VMK_WORLD_SCHED_CLASS_DEFAULT.
|
||||
*/
|
||||
typedef enum {
|
||||
|
||||
/** Default scheduler class for kernel threads. */
|
||||
VMK_WORLD_SCHED_CLASS_DEFAULT = 1,
|
||||
|
||||
/** Scheduler class for kernel threads that must execute prompty. */
|
||||
VMK_WORLD_SCHED_CLASS_QUICK = 100,
|
||||
|
||||
} vmk_WorldSchedClass;
|
||||
|
||||
/**
|
||||
* \brief Properties for creating a new world.
|
||||
*/
|
||||
typedef struct vmk_WorldProps {
|
||||
/** \brief Name associated with this world. */
|
||||
const char *name;
|
||||
|
||||
/** \brief Module ID of the module creating this world. */
|
||||
vmk_ModuleID moduleID;
|
||||
|
||||
/** \brief Function that the world begins executing at creation. */
|
||||
vmk_WorldStartFunc startFunction;
|
||||
|
||||
/** \brief Opaque argument to the startFunction. */
|
||||
void *data;
|
||||
|
||||
/** \brief Scheduler class for the new world. */
|
||||
vmk_WorldSchedClass schedClass;
|
||||
|
||||
} vmk_WorldProps;
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_WorldCreate -- */ /**
|
||||
|
@ -59,34 +122,51 @@ typedef vmk_int32 vmk_WorldID;
|
|||
*
|
||||
* \note This function may block.
|
||||
*
|
||||
* \warning Code running inside a world should allow the scheduler to
|
||||
* run as often as possible. This can be achieved by calling
|
||||
* vmk_WorldYield. At most code should run 30ms without calling
|
||||
* vmk_WorldYield.
|
||||
* \warning Code running inside a system world can be preempted by
|
||||
* default. Code should be careful not to access Per-PCPU
|
||||
* Storage, or to hold locks of type VMK_SPINLOCK_IRQ, for
|
||||
* a period time exceeding 10us - since these acquisitions
|
||||
* block preemption.
|
||||
*
|
||||
* \param[in] moduleID Module on whose behalf the world is running.
|
||||
* \param[in] name A string that describes the world. The name
|
||||
* will show up as debug information.
|
||||
* \param[in] startFunction Function that the world begins executing
|
||||
* on creation.
|
||||
* \param[in] data Argument to be passed to startFunction.
|
||||
* \param[in] props Properties of this world.
|
||||
* \param[out] worldId World ID associated with the newly
|
||||
* created world. May be set to NULL if
|
||||
* the caller does not need the World ID.
|
||||
* created world. If caller sets this
|
||||
* poitner to NULL, then the World ID is
|
||||
* not returned.
|
||||
*
|
||||
* \retval VMK_OK World created.
|
||||
* \retval VMK_NO_MEMORY Ran out of memory.
|
||||
* \retval VMK_DEATH_PENDING World is in the process of dying.
|
||||
* \retval VMK_NO_MODULE_HEAP The module's heap is not set.
|
||||
* \retval VMK_BAD_PARAM The priority specified is in the
|
||||
* properties is invalid.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_WorldCreate(
|
||||
vmk_ModuleID moduleID,
|
||||
const char *name,
|
||||
vmk_WorldStartFunc startFunction,
|
||||
void *data,
|
||||
vmk_WorldID *worldId);
|
||||
VMK_ReturnStatus vmk_WorldCreate(vmk_WorldProps *props,
|
||||
vmk_WorldID *worldId);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_WorldDestroy -- */ /**
|
||||
*
|
||||
* \ingroup Worlds
|
||||
* \brief Destroy a world created by vmk_WorldCreate.
|
||||
*
|
||||
* \note This function may block.
|
||||
*
|
||||
* \note This function does not wait for the world to actually die.
|
||||
* Use vmk_WorldWaitForDeath() to wait for death.
|
||||
*
|
||||
* \param[in] worldID vmk_WorldID of the world to destroy.
|
||||
*
|
||||
* \retval VMK_OK Kill was successfully posted.
|
||||
* \retval VMK_NOT_FOUND Specified worldID was not found.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_WorldDestroy(
|
||||
vmk_WorldID worldID);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
|
@ -121,6 +201,42 @@ void vmk_WorldExit(VMK_ReturnStatus status);
|
|||
vmk_WorldID vmk_WorldGetID(
|
||||
void);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_WorldGetCartelID -- */ /**
|
||||
*
|
||||
* \ingroup Worlds
|
||||
* \brief Get the Cartel ID of the current world.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \return WorldID of the cartel of the currently running world that
|
||||
* this call was invoked from or VMK_INVALID_WORLD_ID if
|
||||
* this call was not invoked from a user world context.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
vmk_WorldID vmk_WorldGetCartelID(
|
||||
void);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_WorldIDToCartelID -- */ /**
|
||||
*
|
||||
* \ingroup Worlds
|
||||
* \brief Get the Cartel ID of the specified world.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \return WorldID of the cartel of the provided world ID or
|
||||
* VMK_INVALID_WORLD_ID if the provided world is not a user
|
||||
* world context.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
vmk_WorldID vmk_WorldIDToCartelID(
|
||||
vmk_WorldID worldID);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_WorldAssertIsSafeToBlockInt --
|
||||
|
@ -168,16 +284,19 @@ vmk_WorldAssertIsSafeToBlock(
|
|||
*
|
||||
* \note This function may block.
|
||||
*
|
||||
* \note Spurious wakeups are possible
|
||||
* \note Spurious wakeups are possible. Specifially, users of this
|
||||
* API must always verify that the condition on which they
|
||||
* are waiting has actually occurred before taking action.
|
||||
*
|
||||
* \note For worlds holding IRQ locks, use vmk_WorldWaitIRQ().
|
||||
*
|
||||
* \param[in] eventId System wide unique identifier of the event
|
||||
* to sleep on.
|
||||
* \param[in] lock Lock of type VMK_SPINLOCK or VMK_SPINLOCK_IRQ
|
||||
* to release before descheduling the world.
|
||||
* VMK_LOCK_INVALID indicates that no lock needs
|
||||
* to be released before descheduling the world.
|
||||
* \param[in] eventId Either a system wide unique identifier for the
|
||||
* event to sleep on, or VMK_EVENT_NONE. When
|
||||
* VMK_EVENT_NONE is specified, the world can be
|
||||
* awoken only by vmk_WorldForceWakeup(), by a
|
||||
* timeout, or if the world is being destroyed.
|
||||
* \param[in] lock Lock of type VMK_SPINLOCK to release before
|
||||
* descheduling the world. VMK_LOCK_INVALID
|
||||
* indicates that no lock needs to be released
|
||||
* before descheduling the world.
|
||||
* \param[in] timeoutMS Number of milliseconds before timeout
|
||||
* VMK_TIMEOUT_UNLIMITED_MS indicates that the
|
||||
* caller wants to block forever.
|
||||
|
@ -213,63 +332,6 @@ VMK_ReturnStatus vmk_WorldWait(
|
|||
const char *reason);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_WorldWaitIRQ -- */ /**
|
||||
*
|
||||
* \brief Deschedule a World holding an IRQ Lock until awakened or until
|
||||
* the specified timeout expires.
|
||||
*
|
||||
* \note This function may block.
|
||||
*
|
||||
* \note Spurious wakeups are possible
|
||||
*
|
||||
* \note For worlds holding non-IRQ locks, use vmk_WorldWait().
|
||||
*
|
||||
* \param[in] eventId System wide unique identifier of the event
|
||||
* to sleep on.
|
||||
* \param[in] lock Lock of type VMK_SPINLOCK or VMK_SPINLOCK_IRQ
|
||||
* to release before descheduling the world.
|
||||
* VMK_LOCK_INVALID indicates that no lock needs
|
||||
* to be released before descheduling the world.
|
||||
* \param[in] irql IRQ level of lock provided by
|
||||
* vmk_SpinlockLockIRQ().
|
||||
* \param[in] timeoutMS Number of milliseconds before timeout
|
||||
* VMK_TIMEOUT_UNLIMITED_MS indicates that the
|
||||
* caller wants to block forever.
|
||||
* VMK_TIMEOUT_NONBLOCKING is not a valid value
|
||||
* in this context.
|
||||
* \param[in] reason A short string that explains the reason for
|
||||
* the vmk_WorldWait call.
|
||||
*
|
||||
* \retval VMK_OK World was descheduled and awoken by a
|
||||
* vmk_WorldWakeup on eventId.
|
||||
* \retval VMK_BAD_PARAM World was not descheduled because a
|
||||
* provided parameter was invalid. If a
|
||||
* lock was provided then it was not
|
||||
* released.
|
||||
* \retval VMK_TIMEOUT World was descheduled and awoken
|
||||
* because of timeout expiration.
|
||||
* \retval VMK_DEATH_PENDING World was descheduled and awoken
|
||||
* because the world is dying and being
|
||||
* reaped by the scheduler. The caller is
|
||||
* expected to return as soon as possible.
|
||||
* \retval VMK_WAIT_INTERRUPTED World was descheduled and awoken for
|
||||
* some other reason not specified by
|
||||
* previous return codes. The caller is
|
||||
* allowed to re-enter vmk_WorldWait.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
VMK_ReturnStatus vmk_WorldWaitIRQ(
|
||||
vmk_WorldEventID eventId,
|
||||
vmk_Lock lock,
|
||||
vmk_LockIRQL irql,
|
||||
vmk_uint32 timeoutMS,
|
||||
const char *reason);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_WorldWakeup -- */ /**
|
||||
|
@ -289,6 +351,35 @@ VMK_ReturnStatus vmk_WorldWaitIRQ(
|
|||
VMK_ReturnStatus vmk_WorldWakeup(
|
||||
vmk_WorldEventID eventId);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_WorldForceWakeup -- */ /**
|
||||
*
|
||||
* \ingroup Worlds
|
||||
* \brief Wake up a specific world directly, regardless of what
|
||||
* event it is waiting on.
|
||||
*
|
||||
* \note This function may block.
|
||||
*
|
||||
* \note A forced wakeup is special, in that the wakeup it generates
|
||||
* is "stateful" when used in conjuction with VMK_EVENT_NONE.
|
||||
* Specifically, if a world is not waiting when a forced wakeup
|
||||
* is generated, then the wakeup goes pending. If the world
|
||||
* then attempts to wait on VMK_EVENT_NONE, the world will
|
||||
* not sleep (and the pending is cleared).
|
||||
*
|
||||
* \param[in] worldID World ID of the world to wake up.
|
||||
*
|
||||
* \retval VMK_OK The world was awoken.
|
||||
* \retval VMK_NOT_FOUND The world was not found to need wakeup.
|
||||
* \retval VMK_INVALID_WORLD The world ID did not correspond to an
|
||||
* existing world.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_WorldForceWakeup(
|
||||
vmk_WorldID worldID);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_WorldSleep -- */ /**
|
||||
|
@ -414,7 +505,110 @@ vmk_uint32 vmk_WorldsMax(void);
|
|||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_WorldWaitForDeath(vmk_WorldID worldID);
|
||||
VMK_ReturnStatus vmk_WorldWaitForDeath(
|
||||
vmk_WorldID worldID);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_WorldInterruptSet -- */ /**
|
||||
*
|
||||
* \brief Sets an interrupt association for the specified world.
|
||||
*
|
||||
* Interrupts will be delivered to the same PCPU that this world is
|
||||
* running on.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] worldID ID of the world to set interrupt
|
||||
* association for.
|
||||
* \param[in] intrCookie Interrupt cookie previously retrieved via
|
||||
* vmk_IntrRegister
|
||||
*
|
||||
* \retval VMK_OK The vector association has been set.
|
||||
* \retval VMK_BAD_PARAM The specified vector is invalid.
|
||||
* \retval VMK_LIMIT_EXCEEDED The specified vector cannot be added.
|
||||
* \retval VMK_INVALID_WORLD The specified world id was invalid.
|
||||
* \retval VMK_FAILURE The interrupt association cannot be set.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_WorldInterruptSet(
|
||||
vmk_WorldID worldID,
|
||||
vmk_IntrCookie intrCookie);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_WorldInterruptUnset -- */ /**
|
||||
*
|
||||
* \ingroup Worlds
|
||||
* \brief Unsets an interrupt association for the specified world.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] worldID ID of the world to unset interrupt
|
||||
* association for.
|
||||
* \param[in] intrCookie Interrupt cookie previously retrieved via
|
||||
* vmk_IntrRegister
|
||||
*
|
||||
* \retval VMK_OK The interrupt association has been unset.
|
||||
* \retval VMK_NOT_FOUND The interrupt is currently not associated
|
||||
* with the world.
|
||||
* \retval VMK_INVALID_WORLD The specified world id was invalid.
|
||||
* \retval VMK_FAILURE The interrupt association cannot be unset.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_WorldInterruptUnset(
|
||||
vmk_WorldID worldID,
|
||||
vmk_IntrCookie intrCookie);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_WorldRelationAdd -- */ /**
|
||||
*
|
||||
* \brief Add a relationship between two worlds
|
||||
*
|
||||
* This interface should be used to give a hint to the scheduler that there is a
|
||||
* communication flow from world A to world B. This is useful for multi-threaded
|
||||
* producer-consumer implementations. World A would equal the producer and world
|
||||
* B would equal the consumer. If both worlds can be a producer and consumer
|
||||
* then the interface should be called twice.
|
||||
* Establishing a relationship between worlds is an important performance
|
||||
* optimization and should always be done for worlds that are part of a hot
|
||||
* path.
|
||||
*
|
||||
* \note This function might block.
|
||||
*
|
||||
* \param[in] worldA ID of the world initiating the communication.
|
||||
* \param[in] worldB ID of the world receiving the communication.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
VMK_ReturnStatus vmk_WorldRelationAdd(
|
||||
vmk_WorldID worldA,
|
||||
vmk_WorldID worldB);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_WorldRelationRemove -- */ /**
|
||||
*
|
||||
* \brief Remove a relationship between two worlds
|
||||
*
|
||||
* The relationship must have previously been set through vmk_WorldRelationAdd.
|
||||
*
|
||||
* \note This function might block.
|
||||
*
|
||||
* \param[in] worldA ID of the world initiating the communication.
|
||||
* \param[in] worldB ID of the world receiving the communication.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
VMK_ReturnStatus vmk_WorldRelationRemove(
|
||||
vmk_WorldID worldA,
|
||||
vmk_WorldID worldB);
|
||||
|
||||
#endif /* _VMKAPI_WORLD_H_ */
|
||||
/** @} */
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* Worlds */ /**
|
||||
*
|
||||
* \addtogroup Core
|
||||
* @{
|
||||
* \addtogroup Worlds
|
||||
* @{
|
||||
* \defgroup Deprecated Deprecated APIs
|
||||
* @{
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _VMKAPI_WORLDS_DEPRECATED_H_
|
||||
#define _VMKAPI_WORLDS_DEPRECATED_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 */
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_WorldWaitIRQ -- */ /**
|
||||
*
|
||||
* \brief Deschedule a World holding an IRQ Lock until awakened or until
|
||||
* the specified timeout expires.
|
||||
*
|
||||
* \deprecated
|
||||
*
|
||||
* \note This function may block.
|
||||
*
|
||||
* \note Spurious wakeups are possible
|
||||
*
|
||||
* \note For worlds holding non-IRQ locks, use vmk_WorldWait().
|
||||
*
|
||||
* \param[in] eventId System wide unique identifier of the event
|
||||
* to sleep on.
|
||||
* \param[in] lock Lock of type VMK_SPINLOCK or VMK_SPINLOCK_IRQ
|
||||
* to release before descheduling the world.
|
||||
* VMK_LOCK_INVALID indicates that no lock needs
|
||||
* to be released before descheduling the world.
|
||||
* \param[in] irql IRQ level of lock provided by
|
||||
* vmk_SpinlockLockIRQ().
|
||||
* \param[in] timeoutMS Number of milliseconds before timeout
|
||||
* VMK_TIMEOUT_UNLIMITED_MS indicates that the
|
||||
* caller wants to block forever.
|
||||
* VMK_TIMEOUT_NONBLOCKING is not a valid value
|
||||
* in this context.
|
||||
* \param[in] reason A short string that explains the reason for
|
||||
* the vmk_WorldWait call.
|
||||
*
|
||||
* \retval VMK_OK World was descheduled and awoken by a
|
||||
* vmk_WorldWakeup on eventId.
|
||||
* \retval VMK_BAD_PARAM World was not descheduled because a
|
||||
* provided parameter was invalid. If a
|
||||
* lock was provided then it was not
|
||||
* released.
|
||||
* \retval VMK_TIMEOUT World was descheduled and awoken
|
||||
* because of timeout expiration.
|
||||
* \retval VMK_DEATH_PENDING World was descheduled and awoken
|
||||
* because the world is dying and being
|
||||
* reaped by the scheduler. The caller is
|
||||
* expected to return as soon as possible.
|
||||
* \retval VMK_WAIT_INTERRUPTED World was descheduled and awoken for
|
||||
* some other reason not specified by
|
||||
* previous return codes. The caller is
|
||||
* allowed to re-enter vmk_WorldWait.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
VMK_ReturnStatus vmk_WorldWaitIRQ(
|
||||
vmk_WorldEventID eventId,
|
||||
vmk_Lock lock,
|
||||
vmk_LockIRQL irql,
|
||||
vmk_uint32 timeoutMS,
|
||||
const char *reason);
|
||||
|
||||
|
||||
#endif
|
||||
/** @} */
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -38,10 +38,11 @@ typedef vmk_uint32 vmk_WorldletID;
|
|||
#define VMK_INVALID_WORLDLET_ID ((vmk_WorldletID)-1)
|
||||
|
||||
/** \cond nodoc */
|
||||
#define VMK_WDT_OPT_LIST(action) \
|
||||
action(WDT_OPT_FORCE_IPI_DISPATCH, "force IPI dispatch", ForceIPIDispatch) \
|
||||
action(WDT_OPT_NON_INTERFERING, "ignore interference effect", NonInterfering)\
|
||||
action(WDT_OPT_ACTION_AFFINITY, "action affinity", ActionAffinity)
|
||||
#define VMK_WDT_OPT_LIST(action) \
|
||||
action(WDT_OPT_FORCE_IPI_DISPATCH, "force IPI dispatch", ForceIPIDispatch) \
|
||||
action(WDT_OPT_NON_INTERFERING, "ignore interference effect", NonInterfering) \
|
||||
action(WDT_OPT_ACTION_AFFINITY, "action affinity", ActionAffinity) \
|
||||
action(WDT_OPT_ENABLED_VMKSTATS, "enable vmkstats", EnableVmkstats)
|
||||
|
||||
#define VMK_WDT_OPT_LIST_POPULATE(name, ignore1, ignore2) \
|
||||
/** \brief Option name */ VMK_##name,
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
*/
|
||||
#define VMK_SERVICE_ACCT_NAME_KERNEL "kernel"
|
||||
#define VMK_SERVICE_ACCT_NAME_SCSI "scsi"
|
||||
#define VMK_SERVICE_ACCT_NAME_NET "net"
|
||||
|
||||
/**
|
||||
* \ingroup Accounting
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/***************************************************************************
|
||||
* Copyright 2010 VMware, Inc. All rights reserved.
|
||||
* Copyright 2010,2012 VMware, Inc. All rights reserved.
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
|
@ -30,56 +30,6 @@ typedef struct vmkBusType* vmk_BusType;
|
|||
/** \brief A null bustype handle. */
|
||||
#define VMK_BUSTYPE_NONE ((vmk_BusType)0)
|
||||
|
||||
/** \brief Properties of a bus type needed for registration. */
|
||||
typedef struct {
|
||||
/** Module registering the bustype */
|
||||
vmk_ModuleID moduleID;
|
||||
/** Name of bustype */
|
||||
vmk_Name name;
|
||||
} vmk_BusTypeProps;
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_BusTypeRegister -- */ /**
|
||||
*
|
||||
* \brief Register a bus type with the device subsystem.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] busProps Bus type description data.
|
||||
* \param[out] busHandle Handle to registered bus type.
|
||||
*
|
||||
* \retval VMK_OK Success.
|
||||
* \retval VMK_EXISTS Bus type is already registered.
|
||||
* \retval VMK_NO_MEMORY Unable to allocate memory for bus type handle.
|
||||
* \retval VMK_BAD_PARAM Input parameter is invalid.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_BusTypeRegister(vmk_BusTypeProps *busProps,
|
||||
vmk_BusType *busHandle);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_BusTypeUnregister -- */ /**
|
||||
*
|
||||
* \brief Unregister a bus type.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] busHandle Handle to registered bus type.
|
||||
*
|
||||
* \retval VMK_OK Success
|
||||
* \retval VMK_BAD_PARAM No bus type object matching given handle.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_BusTypeUnregister(vmk_BusType busHandle);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_BusTypeFind -- */ /**
|
||||
|
|
|
@ -97,6 +97,10 @@ void _vmk_PCPURelease(vmk_PCPUID pcpu,
|
|||
* \note Callers are responsible for surrendering the PCPU by calling
|
||||
* VMK_END_WITH_PCPU as quickly as possible
|
||||
*
|
||||
* \note No locks may be acquired in a VMK_WITH_PCPU_DO / VMK_END_WITH_PCPU
|
||||
* block. If any locks are required, acquire them before entering the PCPU
|
||||
* region.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#define VMK_WITH_PCPU_DO(_pcpu) \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/***************************************************************************
|
||||
* Copyright 2007 - 2009 VMware, Inc. All rights reserved.
|
||||
* Copyright 2007 - 2013 VMware, Inc. All rights reserved.
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
|
@ -23,19 +23,6 @@
|
|||
#endif
|
||||
/** \endcond never */
|
||||
|
||||
/**
|
||||
* \brief Opaque device type
|
||||
*/
|
||||
typedef struct vmkDevice* vmk_Device;
|
||||
|
||||
/** \brief A null device handle. */
|
||||
#define VMK_DEVICE_NONE ((vmk_Device )0)
|
||||
|
||||
/**
|
||||
* \brief Opaque driver type.
|
||||
*/
|
||||
typedef struct vmkDriver* vmk_Driver;
|
||||
|
||||
/**
|
||||
* \brief Device identification.
|
||||
*/
|
||||
|
@ -44,11 +31,17 @@ typedef struct {
|
|||
vmk_BusType busType;
|
||||
/** Bus-specific address for device */
|
||||
char *busAddress;
|
||||
/** Length of bus-specific address */
|
||||
/**
|
||||
* String length of bus-specific address (excluding terminating NUL).
|
||||
* The maximum length supported is 511.
|
||||
*/
|
||||
vmk_uint32 busAddressLen;
|
||||
/** Bus-specific identifier for device */
|
||||
char *busIdentifier;
|
||||
/** Length of bus-specific identifier */
|
||||
/**
|
||||
* String length of bus-specific identifier (excluding terminating NUL).
|
||||
* The maximum length supported is 63.
|
||||
*/
|
||||
vmk_uint32 busIdentifierLen;
|
||||
} vmk_DeviceID;
|
||||
|
||||
|
@ -59,14 +52,26 @@ typedef struct {
|
|||
* \ingroup Device
|
||||
* \brief Remove a device.
|
||||
*
|
||||
* Driver should carry out any operations required for the physical
|
||||
* removal of a device, and unregister the device object using
|
||||
* vmk_DeviceUnregister().
|
||||
* This callback is invoked only on devices in an unclaimed state.
|
||||
* A device may be removed for operations such as system shutdown,
|
||||
* driver unload, or explicit device removal.
|
||||
*
|
||||
* Driver should carry out any operations required for the physical
|
||||
* removal of the device, and the device object must be unregistered
|
||||
* by calling vmk_DeviceUnregister(). Driver's private data for the
|
||||
* device, including registeringDriverData, must be freed only after
|
||||
* successful unregistration of the device.
|
||||
*
|
||||
* If the device is not unregistered, this callback may be invoked
|
||||
* again later.
|
||||
*
|
||||
* \param[in] device Handle to device to be removed.
|
||||
*
|
||||
* \retval VMK_OK Success
|
||||
*
|
||||
* \retval VMK_OK Device unregistered successfully.
|
||||
* \retval VMK_FAILURE Driver could not unregister device.
|
||||
* All other error codes are treated as
|
||||
* VMK_FAILURE.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
|
@ -84,14 +89,16 @@ typedef struct {
|
|||
* \brief Device registration data.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Module registering this device */
|
||||
vmk_ModuleID moduleID;
|
||||
/** Driver registering this device */
|
||||
vmk_Driver registeringDriver;
|
||||
/** Device identification */
|
||||
vmk_DeviceID *deviceID;
|
||||
/** Device operations */
|
||||
vmk_DeviceOps *deviceOps;
|
||||
/** Opaque bus-specific data for this device */
|
||||
vmk_AddrCookie busDriverData;
|
||||
/** Opaque data set by registering driver for its private use */
|
||||
vmk_AddrCookie registeringDriverData;
|
||||
/** Opaque data set by registering driver for attaching driver */
|
||||
vmk_AddrCookie registrationData;
|
||||
} vmk_DeviceProps;
|
||||
|
||||
/*
|
||||
|
@ -99,12 +106,21 @@ typedef struct {
|
|||
* vmk_DeviceRegister -- */ /**
|
||||
*
|
||||
* \ingroup Device
|
||||
* \brief Register a device with the device database and get a
|
||||
* a device handle back.
|
||||
* \brief Register a device with the device database and get a device
|
||||
* handle back.
|
||||
*
|
||||
* This function should be used only by a driver that discovers
|
||||
* new physical devices on any buses spawned from the device
|
||||
* that it is the driver for, e.g. a PCI bridge driver.
|
||||
* A device can be physical (e.g. a PCI device) or logical
|
||||
* (e.g. an uplink, or a similar software construct).
|
||||
*
|
||||
* Devices can be registered only from a driver's scan callback.
|
||||
*
|
||||
* The '#' character is not permitted in the busAddress of the device,
|
||||
* except if it is a logical device whose busAddress is generated using
|
||||
* vmk_LogicalCreateBusAddress.
|
||||
*
|
||||
* The registering driver's module heap is used for temporary scratch
|
||||
* purposes by this service. No memory allocated from this heap will
|
||||
* persist after vmk_DeviceRegister returns.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
|
@ -112,11 +128,21 @@ typedef struct {
|
|||
* \param[in] parent Parent device handle.
|
||||
* \param[out] newDevice New device handle.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM Device ID is NULL or incomplete.
|
||||
* \retval VMK_EXISTS Device with this data already registered.
|
||||
* \retval VMK_NO_MEMORY Unable to allocate memory for device handle.
|
||||
* \retval VMK_OK Successfully registered device.
|
||||
*
|
||||
* \retval VMK_OK Successfully registered device.
|
||||
* \retval VMK_NOT_SUPPORTED Registration not from a driver's scan
|
||||
* callback.
|
||||
* \retval VMK_BAD_PARAM Device ID is NULL or incomplete.
|
||||
* \retval VMK_BAD_PARAM The deviceID's busAddress is improperly
|
||||
* formatted for the specified bus type.
|
||||
* \retval VMK_EXISTS Device with this data already registered.
|
||||
* \retval VMK_NO_MEMORY Unable to allocate memory for device
|
||||
* handle.
|
||||
* \retval VMK_NO_MODULE_HEAP The registeringDriver's module
|
||||
* (specified in deviceProps) has no heap.
|
||||
* \retval VMK_NAME_TOO_LONG The deviceID's busAddressLen is greater
|
||||
* then the system defined maximum.
|
||||
* \retval VMK_NAME_TOO_LONG The deviceID's busIdentifierLen is
|
||||
* greater then the system defined maximum.
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
|
@ -130,19 +156,20 @@ vmk_DeviceRegister(vmk_DeviceProps *deviceProps,
|
|||
* vmk_DeviceUnregister -- */ /**
|
||||
*
|
||||
* \ingroup Device
|
||||
* \brief Remove a device from the device database.
|
||||
* \brief Unregister a device from the device database.
|
||||
*
|
||||
* Devices should typically be unregistered only from the device
|
||||
* remove callback.
|
||||
* A device must be unregistered only from its device remove callback
|
||||
* provided by the registering driver.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] device Device handle.
|
||||
*
|
||||
* \retval VMK_OK Successfully unregistered device.
|
||||
* \retval VMK_NOT_SUPPORTED Unregistration was not from the device's
|
||||
* remove callback.
|
||||
* \retval VMK_BAD_PARAM Device handle is invalid.
|
||||
* \retval VMK_BUSY Device has references. Will be freed after
|
||||
* last reference is released.
|
||||
* \retval VMK_BUSY Device has references or resources allocated.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
@ -158,15 +185,19 @@ vmk_DeviceUnregister(vmk_Device device);
|
|||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] heap Heap from which device ID should be allocated.
|
||||
* \param[in] device Device handle.
|
||||
* \param[out] devID Device identification data.
|
||||
*
|
||||
* \retval VMK_OK Successfully returned device id.
|
||||
* \retval VMK_BAD_PARAM Device handle is invalid.
|
||||
* \retval VMK_NO_MEMORY Unable to allocate memory for device ID.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_DeviceGetDeviceID(vmk_Device device,
|
||||
vmk_DeviceGetDeviceID(vmk_HeapID heap,
|
||||
vmk_Device device,
|
||||
vmk_DeviceID **devID);
|
||||
|
||||
/*
|
||||
|
@ -174,10 +205,11 @@ vmk_DeviceGetDeviceID(vmk_Device device,
|
|||
* vmk_DevicePutDeviceID -- */ /**
|
||||
*
|
||||
* \ingroup Device
|
||||
* \brief Return a handle to device identification data.
|
||||
* \brief Release device identification data.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] heap Heap from which device ID was allocated.
|
||||
* \param[in] devID Device identification data.
|
||||
*
|
||||
* \retval VMK_OK Successfully released device id data.
|
||||
|
@ -185,120 +217,96 @@ vmk_DeviceGetDeviceID(vmk_Device device,
|
|||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_DevicePutDeviceID(vmk_DeviceID *devID);
|
||||
vmk_DevicePutDeviceID(vmk_HeapID heap,
|
||||
vmk_DeviceID *devID);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DeviceGetBusDriverData -- */ /**
|
||||
* vmk_DeviceGetRegisteringDriverData -- */ /**
|
||||
*
|
||||
* \ingroup Device
|
||||
* \brief Get bus-driver data for device.
|
||||
* \brief Get registering driver's private data for device.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] device Device handle.
|
||||
* \param[out] data Bus-specific data for device.
|
||||
* \param[out] data Registering driver's private data for device.
|
||||
*
|
||||
* \retval VMK_OK Successfully returned device data.
|
||||
* \retval VMK_BAD_PARAM Invalid device handle.
|
||||
* \retval VMK_BAD_PARAM data argument is NULL.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_DeviceGetBusDriverData(vmk_Device device,
|
||||
vmk_AddrCookie *data);
|
||||
vmk_DeviceGetRegisteringDriverData(vmk_Device device,
|
||||
vmk_AddrCookie *data);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DeviceSetFunctionDriverData -- */ /**
|
||||
* vmk_DeviceGetRegistrationData -- */ /**
|
||||
*
|
||||
* \ingroup Device
|
||||
* \brief Set function-driver data for device.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] device Device handle.
|
||||
* \param[in] data Device data.
|
||||
*
|
||||
* \retval VMK_OK Successfully set private data.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_DeviceSetFunctionDriverData(vmk_Device device,
|
||||
vmk_AddrCookie data);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DeviceGetFunctionDriverData -- */ /**
|
||||
*
|
||||
* \ingroup Device
|
||||
* \brief Get function-driver data for device.
|
||||
* \brief Get device registration data for attaching driver.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] device Device handle.
|
||||
* \param[out] data Device data.
|
||||
* \param[out] data Device registration data.
|
||||
*
|
||||
* \retval VMK_OK Successfully returned private data.
|
||||
* \retval VMK_OK Successfully returned device data.
|
||||
* \retval VMK_BAD_PARAM Invalid device handle.
|
||||
* \retval VMK_BAD_PARAM data argument is NULL.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_DeviceGetFunctionDriverData(vmk_Device device,
|
||||
vmk_DeviceGetRegistrationData(vmk_Device device,
|
||||
vmk_AddrCookie *data);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DeviceGetAttachedDriverData -- */ /**
|
||||
*
|
||||
* \ingroup Device
|
||||
* \brief Get attached driver's private data for device.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] device Device handle.
|
||||
* \param[out] data Attached driver's private data for device.
|
||||
*
|
||||
* \retval VMK_OK Successfully returned private data.
|
||||
* \retval VMK_BAD_PARAM Invalid device handle.
|
||||
* \retval VMK_BAD_PARAM data argument is NULL.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_DeviceGetAttachedDriverData(vmk_Device device,
|
||||
vmk_AddrCookie *data);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DeviceFindDeviceByIdentifier -- */ /**
|
||||
* vmk_DeviceSetAttachedDriverData -- */ /**
|
||||
*
|
||||
* \ingroup Device
|
||||
* \brief Return a reference to the device that matches the bus type &
|
||||
* identifier in the given identification data.
|
||||
* \brief Set attached driver's private data for device.
|
||||
*
|
||||
* If device identifiers are not unique, this function will return
|
||||
* the first device found matching the given identifier.
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \note Reference must be released using vmk_DeviceRelease.
|
||||
* \note This function may block.
|
||||
* \param[in] device Device handle.
|
||||
* \param[in] data Attached driver's private data for device.
|
||||
*
|
||||
* \param[in] deviceID Device identification.
|
||||
* \param[out] device Reference to device matching requested
|
||||
* identification.
|
||||
*
|
||||
* \retval VMK_OK Successfully returned reference to
|
||||
* matching device.
|
||||
* \retval VMK_NOT_FOUND No device with given identification.
|
||||
* \retval VMK_OK Successfully set private data.
|
||||
* \retval VMK_BAD_PARAM Invalid device handle.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_DeviceFindDeviceByIdentifier(vmk_DeviceID *deviceID,
|
||||
vmk_Device *device);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DeviceFindDeviceByAddress -- */ /**
|
||||
*
|
||||
* \ingroup Device
|
||||
* \brief Return a handle to the device that matches the bus & address
|
||||
* in the given identification data.
|
||||
*
|
||||
* \note Reference must be released using vmk_DeviceRelease.
|
||||
* \note This function may block.
|
||||
*
|
||||
* \param[in] deviceID Device identification.
|
||||
* \param[out] device Reference to device matching requested
|
||||
* identification.
|
||||
*
|
||||
* \retval VMK_OK Successfully returned reference to
|
||||
* matching device.
|
||||
* \retval VMK_NOT_FOUND No device with given identification.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_DeviceFindDeviceByAddress(vmk_DeviceID *deviceID,
|
||||
vmk_Device *device);
|
||||
VMK_ReturnStatus
|
||||
vmk_DeviceSetAttachedDriverData(vmk_Device device,
|
||||
vmk_AddrCookie data);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
|
@ -322,79 +330,26 @@ vmk_DeviceRelease(vmk_Device device);
|
|||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DeviceGetParent-- */ /**
|
||||
* vmk_DeviceRequestRescan -- */ /**
|
||||
*
|
||||
* \ingroup Device
|
||||
* \brief Obtain a handle to the parent device of the given device.
|
||||
*
|
||||
* \note Parent device reference must be released using vmk_DeviceRelease.
|
||||
* \note This function may block.
|
||||
*
|
||||
* \param[in] device Device handle
|
||||
* \param[out] parent Parent handle
|
||||
*
|
||||
* \retval VMK_OK Success
|
||||
* \retval VMK_BAD_PARAM Invalid device handle.
|
||||
* \retval VMK_NOT_FOUND Device has no parent.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_DeviceGetParent(vmk_Device device,
|
||||
vmk_Device *parent);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DeviceGetSibling -- */ /**
|
||||
*
|
||||
* \ingroup Device
|
||||
* \brief Obtain a handle to the immediate sibling device of the given
|
||||
* device.
|
||||
* \brief Request a rescan of the device to register new children.
|
||||
*
|
||||
* This always returns a handle to the immediate sibling of a device
|
||||
* even if the given device has multiple sibling devices.
|
||||
* This call submits a request to the device layer to schedule an
|
||||
* invocation of the device driver's vmk_DriverScanDevice() callback.
|
||||
*
|
||||
* \note Sibling device reference must be released using vmk_DeviceRelease.
|
||||
* \note This function may block.
|
||||
* \param[in] driver Requesting driver
|
||||
* \param[in] device Device to be scanned
|
||||
*
|
||||
* \param[in] device Device handle
|
||||
* \param[out] sibling Sibling handle
|
||||
*
|
||||
* \retval VMK_OK Success
|
||||
* \retval VMK_BAD_PARAM Invalid device handle.
|
||||
* \retval VMK_NOT_FOUND Device has no siblings.
|
||||
* \retval VMK_OK Request accepted.
|
||||
* \retval VMK_BAD_PARAM Invalid device handle.
|
||||
* \retval VMK_NO_PERMISSION Driver cannot submit this request.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_DeviceGetSibling(vmk_Device device,
|
||||
vmk_Device *sibling);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DeviceGetChild -- */ /**
|
||||
*
|
||||
* \ingroup Device
|
||||
* \brief Obtain a handle to the first child device of the given device.
|
||||
*
|
||||
* This always returns a handle to the first child of a device even if
|
||||
* the given device has multiple child devices.
|
||||
*
|
||||
* \note Child device reference must be released using vmk_DeviceRelease.
|
||||
* \note This function may block.
|
||||
*
|
||||
* \param[in] device Device handle
|
||||
* \param[out] child Child handle
|
||||
*
|
||||
* \retval VMK_OK Success
|
||||
* \retval VMK_BAD_PARAM Invalid device handle.
|
||||
* \retval VMK_NOT_FOUND Device has no children.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_DeviceGetChild(vmk_Device device,
|
||||
vmk_Device *child);
|
||||
vmk_DeviceRequestRescan(vmk_Driver driver,
|
||||
vmk_Device device);
|
||||
|
||||
#endif /* _VMKAPI_DEVICE_H_ */
|
||||
/** @} */
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/***************************************************************************
|
||||
* Copyright 2007 - 2012 VMware, Inc. All rights reserved.
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* Devices */ /**
|
||||
* \defgroup Device Device interface
|
||||
* @{
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _VMKAPI_DEVICE_TYPES_H_
|
||||
#define _VMKAPI_DEVICE_TYPES_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 */
|
||||
|
||||
/**
|
||||
* \brief Opaque device type
|
||||
*/
|
||||
typedef struct vmkDevice* vmk_Device;
|
||||
|
||||
/** \brief A null device handle. */
|
||||
#define VMK_DEVICE_NONE ((vmk_Device )0)
|
||||
|
||||
/**
|
||||
* \brief Opaque driver type.
|
||||
*/
|
||||
typedef struct vmkDriver* vmk_Driver;
|
||||
|
||||
/** \brief Invalid driver handle. */
|
||||
#define VMK_DRIVER_NONE ((vmk_Driver)0)
|
||||
|
||||
#endif /* _VMKAPI_DEVICE_TYPES_H_ */
|
||||
/** @} */
|
|
@ -600,6 +600,147 @@ VMK_ReturnStatus vmk_DMAUnmapSg(vmk_DMAEngine engine,
|
|||
vmk_SgOpsHandle sgOps,
|
||||
vmk_SgArray *sg);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DMAMapElem -- */ /**
|
||||
*
|
||||
* \brief Map machine memory of a single MA range to an IOA range.
|
||||
*
|
||||
* This call will attempt to map a single machine-address range and
|
||||
* create a new IO-address address range that maps to it.
|
||||
*
|
||||
* \note The input range must not be freed or modified while it
|
||||
* is mapped or the results are undefined.
|
||||
*
|
||||
* \note If the range is simultaneously mapped with multiple DMA
|
||||
* directions, the contents of the memory the SG array represents
|
||||
* are undefined.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] engine A handle representing a DMA engine to map to.
|
||||
* \param[in] direction Direction of the DMA transfer for the mapping.
|
||||
* \param[in] in A single SG array element containing a single
|
||||
* machine addresse range to map for the
|
||||
* DMA engine.
|
||||
* \param[in] lastElem Indicates if this is the last element in
|
||||
* the transfer.
|
||||
* \param[out] out A single SG array element to hold the mapped
|
||||
* IO address for the range. Note that this
|
||||
* may be the same SG element as the element
|
||||
* passed in depending on choices made by the
|
||||
* kernel's mapping code.
|
||||
* \param[out] err If this call fails with VMK_DMA_MAPPING_FAILED,
|
||||
* additional information about the failure may
|
||||
* be found here. This may be set to NULL if the
|
||||
* information is not desired.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM The specified DMA engine is invalid.
|
||||
* \retval VMK_DMA_MAPPING_FAILED The mapping failed because the
|
||||
* DMA constraints could not be met.
|
||||
* Additional information about the
|
||||
* failure can be found in the "err"
|
||||
* argument.
|
||||
* \retval VMK_NO_MEMORY There is currently insufficient
|
||||
* memory available to construct the
|
||||
* mapping.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_DMAMapElem(vmk_DMAEngine engine,
|
||||
vmk_DMADirection direction,
|
||||
vmk_SgElem *in,
|
||||
vmk_Bool lastElem,
|
||||
vmk_SgElem *out,
|
||||
vmk_DMAMapErrorInfo *err);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DMAFlushElem -- */ /**
|
||||
*
|
||||
* \brief Synchronize a DMA mapping for a single IO address range.
|
||||
*
|
||||
* This call is used to synchronize data if the CPU needs to read or
|
||||
* write after an DMA mapping is active on a region of machine memory
|
||||
* but before the DMA mapping is unmapped.
|
||||
*
|
||||
* If the specified memory is DMA-mapped this call must be invoked
|
||||
* with VMK_DMA_DIRECTION_FROM_MEMORY after CPU writes are complete but
|
||||
* before any new DMA read transactions occur on the memory.
|
||||
*
|
||||
* If the specified memory is DMA-mapped this call must be invoked
|
||||
* with VMK_DMA_DIRECTION_TO_MEMORY before CPU reads but after
|
||||
* any write DMA transactions complete on the memory.
|
||||
*
|
||||
* DMA map and unmap calls will implicitly perform a flush of the
|
||||
* element.
|
||||
*
|
||||
* The code may flush bytes rounded up to the nearest page or other
|
||||
* HW-imposed increment.
|
||||
*
|
||||
* \note The IO element supplied to this function must be an element
|
||||
* output from vmk_DMAMapElem or the results of this call are
|
||||
* undefined.
|
||||
*
|
||||
* Do not use this to flush a single element in an SG array
|
||||
* that was mapped by vmk_DMAMapSg.
|
||||
*
|
||||
* \note The original element supplied to this function must be
|
||||
* the one supplied to vmk_DMAMapElem when the IO element
|
||||
* was created or the results of this call are undefined.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] engine A handle representing the DMA engine used
|
||||
* for the mapping.
|
||||
* \param[in] direction Direction of the DMA transfer for the
|
||||
* mapping.
|
||||
* \param[in] IOElem Scatter-gather element contained the
|
||||
* IO-address range to flush.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM Unknown duration or direction, or
|
||||
* unsupported direction.
|
||||
* \retval VMK_INVALID_ADDRESS Memory in the specified element
|
||||
* is not mapped.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_DMAFlushElem(vmk_DMAEngine engine,
|
||||
vmk_DMADirection direction,
|
||||
vmk_SgElem *IOElem);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DMAUnmapElem -- */ /**
|
||||
*
|
||||
* \brief Unmaps previously mapped IO address range.
|
||||
*
|
||||
* \note The direction must match the direction at the time of mapping
|
||||
* or the results of this call are undefined.
|
||||
*
|
||||
* \note The element supplied to this function must be one mapped with
|
||||
* vmk_DMAMapElem or the results of this call are undefined.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] engine A handle representing a DMA engine
|
||||
* to unmap from.
|
||||
* \param[in] direction Direction of the DMA transfer for the
|
||||
* mapping.
|
||||
* \param[in] IOElem Scatter-gather element contained the
|
||||
* IO-address range to unmap.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM Unknown direction, or unsupported
|
||||
* direction.
|
||||
* \retval VMK_INVALID_ADDRESS One ore more pages in the specified
|
||||
* machine address range are not mapped.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_DMAUnmapElem(vmk_DMAEngine engine,
|
||||
vmk_DMADirection direction,
|
||||
vmk_SgElem *IOElem);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DMAGetAllocAddrConstraint -- */ /**
|
||||
|
|
|
@ -28,34 +28,125 @@
|
|||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DriverAttachDevice -- */ /**
|
||||
* vmk_DriverAttachDevice -- */ /**
|
||||
*
|
||||
* \brief Attach a device to a driver.
|
||||
*
|
||||
* The driver should start driving this device. If the driver is not
|
||||
* capable of driving the given device, an appropriate error should be
|
||||
* returned, and the device must be restored to its original state at
|
||||
* entry.
|
||||
* This callback is invoked to offer an unclaimed device to a driver.
|
||||
*
|
||||
* The driver should check whether it is capable of driving the given
|
||||
* device, and do initial device set up, e.g. allocate device resources.
|
||||
* If the driver is not capable of driving the given device, the device
|
||||
* must be restored to its original state at callback entry, and an
|
||||
* error should be returned.
|
||||
*
|
||||
* \param[in] device Handle to device to be added to the driver.
|
||||
*
|
||||
* \retval VMK_OK Success
|
||||
* \retval VMK_OK Driver has claimed this device.
|
||||
* \retval VMK_FAILURE Driver did not claim this device.
|
||||
* All other error codes are treated as
|
||||
* VMK_FAILURE.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef VMK_ReturnStatus (*vmk_DriverAttachDevice)(vmk_Device device);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DriverStartDevice-- */ /**
|
||||
*
|
||||
* \brief Prepare a device to accept IO.
|
||||
*
|
||||
* This callback is invoked to place the device in an IO-able state.
|
||||
* This can be when the device is implicitly in a quiescent state after
|
||||
* a successful driver attach operation, or at any other time when the
|
||||
* device has been explicitly put in a quiescent state by the callback
|
||||
* vmk_DriverQuiesceDevice().
|
||||
*
|
||||
* The driver should prepare the device for IO.
|
||||
*
|
||||
* \param[in] device Handle to device to prepare for IO.
|
||||
*
|
||||
* \retval VMK_OK Driver will accept IO for this device.
|
||||
* \retval VMK_FAILURE Driver could not prepare device for IO.
|
||||
* All other error codes are treated as
|
||||
* VMK_FAILURE.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef VMK_ReturnStatus (*vmk_DriverStartDevice)(vmk_Device device);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DriverScanDevice -- */ /**
|
||||
*
|
||||
* \brief Register any child devices.
|
||||
*
|
||||
* This callback is invoked only on devices in IO-able state. It is
|
||||
* invoked at least once after a device has been successfully attached
|
||||
* to a driver and started. It may be invoked for other device hotplug
|
||||
* events as appropriate.
|
||||
*
|
||||
* The driver may register new devices by calling vmk_DeviceRegister()
|
||||
* from this callback. New devices may be registered only from this
|
||||
* callback.
|
||||
*
|
||||
* \param[in] device Handle to device whose children may be registered.
|
||||
*
|
||||
* \retval VMK_OK Devices registered, or nothing to register.
|
||||
* \retval VMK_FAILURE Driver could not register a child device.
|
||||
* All other error codes are treated as
|
||||
* VMK_FAILURE.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef VMK_ReturnStatus (*vmk_DriverScanDevice)(vmk_Device device);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DriverQuiesceDevice -- */ /**
|
||||
*
|
||||
* \brief Place a device in quiescent state.
|
||||
*
|
||||
* This callback may be invoked any time after a device is in an IO-able
|
||||
* state, in preparation for operations such as system shutdown, driver
|
||||
* unload, or device removal.
|
||||
*
|
||||
* The driver should complete any IO on the device and flush any device
|
||||
* caches as necessary to place the device in a quiescent state. When a
|
||||
* device is in quiescent state, the driver must not report any IO to,
|
||||
* and will not receive any IO from, any kernel subsystem.
|
||||
*
|
||||
* \param[in] device Handle to device to be quiesced.
|
||||
*
|
||||
* \retval VMK_OK Device has been quiesced.
|
||||
* \retval VMK_FAILURE Driver could not quiesce IO on device.
|
||||
* All other error codes are treated as
|
||||
* VMK_FAILURE.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef VMK_ReturnStatus (*vmk_DriverQuiesceDevice)(vmk_Device device);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DriverDetachDevice -- */ /**
|
||||
*
|
||||
* \brief Detach a device from its driver.
|
||||
*
|
||||
* The driver should stop driving this device, and release its resources.
|
||||
*
|
||||
* \param[in] device Handle to device to be removed from the driver.
|
||||
* This callback is invoked only on devices in a quiescent state.
|
||||
* A device may be detached for operations such as system shutdown,
|
||||
* driver unload, or device removal.
|
||||
*
|
||||
* \retval VMK_OK Success
|
||||
* The driver should stop driving this device, and undo all device setup
|
||||
* performed in vmk_DriverAttachDevice. E.g. release device resources.
|
||||
*
|
||||
* \param[in] device Handle to device to be detached.
|
||||
*
|
||||
* \retval VMK_OK Device has been released.
|
||||
* \retval VMK_FAILURE Driver could not detach itself from device.
|
||||
* All other error codes are treated as
|
||||
* VMK_FAILURE.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
@ -64,41 +155,23 @@ typedef VMK_ReturnStatus (*vmk_DriverDetachDevice)(vmk_Device device);
|
|||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DriverQuiesceDevice -- */ /**
|
||||
* vmk_DriverForgetDevice-- */ /**
|
||||
*
|
||||
* \brief Quiesce a device.
|
||||
*
|
||||
* This callback is invoked in preparation for device removal or
|
||||
* system shutdown. The driver should complete any IO on the device
|
||||
* and flush any device caches as necessary to put the device in a
|
||||
* quiescent state.
|
||||
*
|
||||
* \param[in] device Handle to device to be quiesced.
|
||||
*
|
||||
* \retval VMK_OK Success
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef VMK_ReturnStatus (*vmk_DriverQuiesceDevice)(vmk_Device device);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_DriverScanDevice -- */ /**
|
||||
*
|
||||
* \brief Scan a device for new children and register them.
|
||||
* \brief Mark a device as inaccessible.
|
||||
*
|
||||
* Only bus drivers will typically need to implement this entry.
|
||||
* This function is called at least once after a device has been
|
||||
* successfully attached to a driver. It may be called at other
|
||||
* device hotplug events as appropriate.
|
||||
* This callback is a notification. It may be invoked at any time to
|
||||
* notify the driver that a device is inaccessible, so that the driver
|
||||
* does not wait indefinitely for any subsequent device operations.
|
||||
*
|
||||
* The driver must note that the device is inaccessible. The driver must
|
||||
* return successfully, in deterministic time, on any subsequent device
|
||||
* callbacks, e.g. vmk_DriverQuiesceDevice, vmk_DriverDetachDevice.
|
||||
*
|
||||
* \param[in] device Handle to device to scan.
|
||||
*
|
||||
* \retval VMK_OK Success
|
||||
* \param[in] device Handle to device that is inaccessible.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef VMK_ReturnStatus (*vmk_DriverScanDevice)(vmk_Device device);
|
||||
typedef void (*vmk_DriverForgetDevice)(vmk_Device device);
|
||||
|
||||
/**
|
||||
* \brief Driver operations.
|
||||
|
@ -110,8 +183,12 @@ typedef struct {
|
|||
vmk_DriverScanDevice scanDevice;
|
||||
/** \brief Detach a device from its driver */
|
||||
vmk_DriverDetachDevice detachDevice;
|
||||
/** \brief Quiesce a device for system shutdown */
|
||||
/** \brief Quiesce a device */
|
||||
vmk_DriverQuiesceDevice quiesceDevice;
|
||||
/** \brief Prepare device for IO */
|
||||
vmk_DriverStartDevice startDevice;
|
||||
/** \brief Notify driver of a lost device */
|
||||
vmk_DriverForgetDevice forgetDevice;
|
||||
} vmk_DriverOps;
|
||||
|
||||
/**
|
||||
|
@ -132,17 +209,23 @@ typedef struct {
|
|||
***********************************************************************
|
||||
* vmk_DriverRegister -- */ /**
|
||||
*
|
||||
* \brief Register a driver with the driver database and get a
|
||||
* a driver handle back.
|
||||
* \brief Register a driver with the driver database
|
||||
*
|
||||
* vmk_DriverRegister must be called from within the driver module's
|
||||
* initialization routine. A successful registration returns a
|
||||
* a new driver handle to the caller.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] driverProps Driver registration data
|
||||
* \param[out] driver New driver handle.
|
||||
* \param[in] driverProps Driver registration data
|
||||
* \param[out] driver New driver handle.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM Name or ops argument is NULL.
|
||||
* \retval VMK_NO_MEMORY Unable to allocate memory for device handle.
|
||||
* \retval VMK_OK Successfully registered driver.
|
||||
* \retval VMK_BAD_PARAM Name or ops argument is NULL.
|
||||
* \retval VMK_EXISTS A driver by this name is already registered.
|
||||
* \retval VMK_NO_MEMORY Unable to allocate memory for device handle.
|
||||
* \retval VMK_NOT_FOUND Unable to find module registering this driver.
|
||||
* \retval VMK_OK Successfully registered driver.
|
||||
* \retval VMK_MODULE_FAILED Call was not from the module's initialization routine.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
@ -154,13 +237,19 @@ vmk_DriverRegister(vmk_DriverProps *driverProps,
|
|||
***********************************************************************
|
||||
* vmk_DriverUnregister -- */ /**
|
||||
*
|
||||
* \brief Unregister a driver from the driver database.
|
||||
* \brief Unregister a driver from the driver database.
|
||||
*
|
||||
* vmk_DriverUnregister is normally called from within the driver module's
|
||||
* cleanup routine. A driver is also permitted to call it from its
|
||||
* initialization routine if the module fails to initialize (load failure).
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] driver Driver handle
|
||||
* \param[in] driver Driver handle
|
||||
*
|
||||
* \retval VMK_OK Successfully unregistered driver.
|
||||
* \retval VMK_OK Successfully unregistered driver.
|
||||
* \retval VMK_MODULE_FAILED Call was not from the module's cleanup or
|
||||
* initialization routines.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
@ -180,6 +269,7 @@ vmk_DriverUnregister(vmk_Driver driver);
|
|||
*
|
||||
* \retval VMK_OK Successfully returned driver private data.
|
||||
* \retval VMK_BAD_PARAM Invalid driver handle.
|
||||
* \retval VMK_BAD_PARAM data argument is NULL.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
@ -191,3 +281,5 @@ vmk_DriverGetPrivateData(vmk_Driver driver,
|
|||
/** @} */
|
||||
/** @} */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* Dump */ /**
|
||||
* \addtogroup Core
|
||||
* @{
|
||||
* \defgroup Dump VMKernel Crash Dumps
|
||||
*
|
||||
* Functions related to VMKernel Crash Dumps. These functions allow
|
||||
* vmkapi users to register files to be created in a zdump file.
|
||||
*
|
||||
* @{
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _VMKAPI_DUMP_H_
|
||||
#define _VMKAPI_DUMP_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 */
|
||||
|
||||
|
||||
/**
|
||||
* \brief Prototype for a dump callback function.
|
||||
*
|
||||
* After being registered for dump callback, this function is called during
|
||||
* system dump time. There are two types of system dump. The first one
|
||||
* is when the system crashes during normal operation and a core dump is
|
||||
* written. The second type, called a live dump, occurs while the system
|
||||
* is still operational and is an additional tool for diagnosing issues
|
||||
* without bringing the whole system down.
|
||||
*
|
||||
* There are two functions a callback can use to add data to the dump.
|
||||
* These are vmk_DumpRange() and vmk_DumpMPN(). vmk_DumpRange() may only
|
||||
* be called on data currently known to be correctly mapped (consistently
|
||||
* across all CPUs), as calls to unmapped spaces will generate page faults.
|
||||
*
|
||||
* For both functions it is also required that there are no side effects
|
||||
* from reading the memory (e.g. a memory mapped PCI device should not
|
||||
* treat reading any piece of memory as an acknowledge of some transaction
|
||||
* for example).
|
||||
*
|
||||
* For the live dump type of call vmk_DumpMPN() is the only safe method
|
||||
* of adding data that may not be currently mapped. This may happen when
|
||||
* unmap events are not managed with any concurrency protection.
|
||||
*
|
||||
* \note This function may only block when liveDump is TRUE.
|
||||
*
|
||||
* \param[in] cookie Private data as specified vmk_DumpAddFileCallback().
|
||||
* \param[in] liveDump TRUE only if the system is still currently functional.
|
||||
* In this case concurrency issues should be considered
|
||||
* as normal for the sub-system. This means that locking
|
||||
* and/or other synchronization should only be performed
|
||||
* when liveDump is TRUE.
|
||||
*/
|
||||
typedef VMK_ReturnStatus (*vmk_DumpFileCallback)(
|
||||
void *cookie,
|
||||
vmk_Bool liveDump);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Dump file handle
|
||||
*
|
||||
* Returned as part of the vmk_DumpAddFileCallback() call. Used for
|
||||
* all other calls.
|
||||
*/
|
||||
typedef void *vmk_DumpFileHandle;
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_DumpAddFileCallback -- */ /**
|
||||
*
|
||||
* \brief Register a file to be created at kernel core dump time.
|
||||
*
|
||||
* This function registers a callback to allow memory to be dumped in a
|
||||
* VMKernel core file under the specified name.
|
||||
*
|
||||
* \param[in] moduleID Module ID of the caller.
|
||||
* \param[in] heapID Heap ID to be used for allocations.
|
||||
* \param[in] name The name of the file to be created by vmkdump_extract.
|
||||
* \param[in] func The callback function itself.
|
||||
* \param[in] cookie Opaque cookie passed to the callback.
|
||||
* \param[in] dumpName Tag used for error messages on this file.
|
||||
* \param[out] outHandle Dump Handle is written here upon success.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \retval VMK_OK Callback successfully added to dump-file table.
|
||||
* \retval VMK_LIMIT_EXCEEDED Dump file table is full.
|
||||
* \retval VMK_NAME_INVALID Specified name was invalid.
|
||||
* \retval VMK_NO_MEMORY Allocation from heapID failed.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_DumpAddFileCallback(
|
||||
vmk_ModuleID moduleID,
|
||||
vmk_HeapID heapID,
|
||||
const char *name,
|
||||
vmk_DumpFileCallback func,
|
||||
void *cookie,
|
||||
char *dumpName,
|
||||
vmk_DumpFileHandle *outHandle);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_DumpDeleteFileCallback -- */ /**
|
||||
*
|
||||
* \brief Unregister a file to be created at kernel core dump time.
|
||||
*
|
||||
* This function unregisters a callback to allow memory to be dumped in a
|
||||
* VMKernel core file under the specified name.
|
||||
*
|
||||
* \param[in] handle Dump handle returned from vmk_DumpAddFileCallback().
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \retval VMK_OK Callback successfully removed to dump-file table.
|
||||
* \retval VMK_NOT_FOUND Dump-file table entry could not be found.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_DumpDeleteFileCallback(
|
||||
vmk_DumpFileHandle handle);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_DumpRange -- */ /**
|
||||
*
|
||||
* \brief Dump a region of memory into a VMKernel core file.
|
||||
*
|
||||
* All errors occurring in an invocation will be logged with the dumpName tag
|
||||
* registered at dump handle creation.
|
||||
*
|
||||
* \param[in] handle Dump handle returned from vmk_DumpAddFileCallback().
|
||||
* \param[in] va Virtual Address to begin dumping. If zero,
|
||||
* dump zero-byte data upto one PAGE_SIZE.
|
||||
* \param[in] size Length of region to dump.
|
||||
*
|
||||
* \note This function is only to be used in a call back registered via
|
||||
* vmk_DumpAddFileCallback().
|
||||
*
|
||||
* \note This function may block when vmk_DumpAddFileCallback() was called
|
||||
* with liveDump is TRUE.
|
||||
*
|
||||
* \retval VMK_OK Region was successfully dumped.
|
||||
* \retval VMK_LIMIT_EXCEEDED More than PAGE_SIZE of zeros requested, or size
|
||||
* of dump exceeded.
|
||||
* \retval VMK_FAILURE Gzip deflate failed.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_DumpRange(
|
||||
vmk_DumpFileHandle handle,
|
||||
vmk_VA va,
|
||||
vmk_uint32 size);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_DumpMPN -- */ /**
|
||||
*
|
||||
* \brief Dump a page of memory into a VMKernel core file.
|
||||
*
|
||||
* All errors occurring in an invocation will be logged with the dumpName tag
|
||||
* registered at dump handle creation.
|
||||
*
|
||||
* \param[in] handle Dump handle returned from vmk_DumpAddFileCallback().
|
||||
* \param[in] mpn VMKernel machine page number to dump.
|
||||
*
|
||||
* \note This function is only to be used in a call back registered via
|
||||
* vmk_DumpAddFileCallback().
|
||||
*
|
||||
* \note This function may block when vmk_DumpAddFileCallback() was called
|
||||
* with liveDump is TRUE.
|
||||
*
|
||||
* \retval VMK_OK Page was successfully dumped.
|
||||
* \retval VMK_LIMIT_EXCEEDED More than PAGE_SIZE of zeros requested, or size
|
||||
* of dump exceeded.
|
||||
* \retval VMK_FAILURE Gzip deflate failed.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_DumpMPN(
|
||||
vmk_DumpFileHandle handle,
|
||||
vmk_MPN mpn);
|
||||
|
||||
|
||||
#endif /* _VMKAPI_DUMP_H_ */
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -0,0 +1,123 @@
|
|||
/***************************************************************************
|
||||
* Copyright 2012 VMware, Inc. All rights reserved.
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* Logical */ /**
|
||||
* \addtogroup Device
|
||||
* @{
|
||||
* \defgroup Logical Logical bus interface
|
||||
* @{
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _VMKAPI_LOGICAL_BUS_H_
|
||||
#define _VMKAPI_LOGICAL_BUS_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 */
|
||||
|
||||
/** \brief Name of the logical bus type. */
|
||||
#define VMK_LOGICAL_BUS_NAME "logical"
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_LogicalCreateBusAddress -- */ /**
|
||||
*
|
||||
* \brief Return a global address for a device on the logical bus.
|
||||
*
|
||||
* A driver registering a device on the logical bustype must use this
|
||||
* call to obtain a globally unique and persistent busAddress for the
|
||||
* device. Driver must provide a logical port component satisfying the
|
||||
* following conditions.
|
||||
*
|
||||
* Locally unique: This means the logical port distinguishes this
|
||||
* logical device from other logical devices created by the same driver
|
||||
* under the same parent device.
|
||||
*
|
||||
* Locally persistent: This means the same logical port is used for
|
||||
* a logical device every time that device is created by the driver.
|
||||
* This is important if the logical device directly represents a
|
||||
* physical hardware component in the system.
|
||||
*
|
||||
* Example : A network driver creates uplinks (logical devices) for a
|
||||
* NIC addressable by a single PCI function (physical parent device).
|
||||
*
|
||||
* Case 1: Single uplink for a single-port NIC.
|
||||
* Driver can use '0' as unique and persistent logical port.
|
||||
*
|
||||
* Case 2: Multiplexing two uplinks for a single-port NIC.
|
||||
* Driver may use '0' and '1' as unique logical ports. As long
|
||||
* as the driver manages multiplexing internally, and logical
|
||||
* ports do not represent physical ports directly, shifting of
|
||||
* logical port numbers is permitted. E.g. if driver is
|
||||
* configured to register only one uplink at next driver load,
|
||||
* logical port '0' may be used, whether it was '0' or '1'
|
||||
* during the previous load.
|
||||
*
|
||||
* Case 3: Two uplinks for a two-port NIC, one per port.
|
||||
* Driver may choose '0' and '1' as unique logical ports for the
|
||||
* uplinks on the first and second port, respectively. Since the
|
||||
* logical devices directly represent physical ports, the driver
|
||||
* must also ensure that the logical ports are never shifted or
|
||||
* mixed up. That is, '0' is always used as the logical port for
|
||||
* the uplink for the first port, and '1' is always used as the
|
||||
* logical port for the uplink for the second port, even if one
|
||||
* of the physical ports fails or is disabled, or if the driver
|
||||
* is configured to use only one port at next driver load.
|
||||
*
|
||||
* \note Memory is allocated for \em globalAddress.
|
||||
* It must be freed using vmk_LogicalFreeBusAddress().
|
||||
*
|
||||
* \param[in] driver Driver creating the device.
|
||||
* \param[in] parent Parent of device being created.
|
||||
* \param[in] uniqueLogicalPort Unique and persistent logical port number.
|
||||
* \param[out] globalAddress Globally unique and persistent address.
|
||||
* \param[out] globalAddressLen Length of globally unique address.
|
||||
*
|
||||
* \retval VMK_OK Success.
|
||||
* \retval VMK_NO_MODULE_HEAP Driver module has no heap to allocate memory.
|
||||
* \retval VMK_NO_MEMORY Could not allocate memory to create address.
|
||||
* \retval VMK_BAD_PARAM Invalid parameter.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
VMK_ReturnStatus
|
||||
vmk_LogicalCreateBusAddress(vmk_Driver driver,
|
||||
vmk_Device parent,
|
||||
vmk_uint32 uniqueLogicalPort,
|
||||
char* *globalAddress,
|
||||
vmk_uint32 *globalAddressLen);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_LogicalFreeBusAddress -- */ /**
|
||||
*
|
||||
* \brief Free memory for logical bus address created using
|
||||
* vmk_LogicalCreateBusAddress().
|
||||
*
|
||||
* \param[in] driver Driver that allocated the bus address.
|
||||
* \param[in] globalAddress Allocated global address.
|
||||
*
|
||||
* \retval VMK_OK Success
|
||||
* \retval VMK_NO_MODULE_HEAP Driver module has no heap to free memory.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_LogicalFreeBusAddress(vmk_Driver driver,
|
||||
char* globalAddress);
|
||||
|
||||
#endif /* _VMKAPI_LOGICAL_BUS_H_ */
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -0,0 +1,200 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* PageSlab */ /**
|
||||
* \addtogroup Core
|
||||
* @{
|
||||
* \defgroup PageSlab Slab page allocator
|
||||
*
|
||||
* Functions related to page slabs. A page slab is a page-wise
|
||||
* allocator that allows for fast page allocations and freeing.
|
||||
*
|
||||
* @{
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _VMKAPI_PAGESLAB_H_
|
||||
#define _VMKAPI_PAGESLAB_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 */
|
||||
|
||||
/** \brief INVALID page slab ID */
|
||||
#define VMK_INVALID_PAGESLAB_ID ((vmk_PageSlabID)NULL)
|
||||
|
||||
/** \brief Page slab ID */
|
||||
typedef struct vmkPageSlabInt* vmk_PageSlabID;
|
||||
|
||||
/**
|
||||
* \brief Properties of a page slab.
|
||||
*/
|
||||
typedef struct vmk_PageSlabCreateProps {
|
||||
/** \brief Heap to allocate page slab metadata from. The size of the
|
||||
* allocation can be retrieved via vmk_PageSlabAllocationSize.
|
||||
*/
|
||||
vmk_HeapID heapID;
|
||||
/** \brief Name for this page slab. */
|
||||
vmk_Name name;
|
||||
/** \brief Minimum number of pages that should be held in the slab.
|
||||
* Please be careful when sizing this number as any memory
|
||||
* that is used for the minimum will be unavailable to VMs, etc.
|
||||
*/
|
||||
vmk_uint32 minPages;
|
||||
/** \brief Maximum number of pages that the slab should provide for. */
|
||||
vmk_uint32 maxPages;
|
||||
/** \brief Restrictions on the physical address space that pages for
|
||||
* the page slab are allocated from. Please choose the least
|
||||
* restrictive constraint possible as memory below 2GB or 4GB
|
||||
* is a scarce resource.
|
||||
*/
|
||||
vmk_MemPhysAddrConstraint physRange;
|
||||
/** \brief Memory pool that the slab should allocate pages from. Set to
|
||||
* VMK_MEMPOOL_INVALID to have vmk_PageSlabCreate create a new
|
||||
* memory pool for the slab.
|
||||
*/
|
||||
vmk_MemPool memPool;
|
||||
} vmk_PageSlabCreateProps;
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PageSlabCreateCustom -- */ /**
|
||||
*
|
||||
* \brief Create a new page slab.
|
||||
*
|
||||
* This function creates a new page slab with the given properties.
|
||||
*
|
||||
* \note This function might block.
|
||||
*
|
||||
* \param[in] moduleID Module ID of the module that this
|
||||
* page slab will belong to.
|
||||
* \param[in] createProps Properties of the new page slab.
|
||||
* \param[out] pageSlabID Handle to the newly created page slab.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
VMK_ReturnStatus
|
||||
vmk_PageSlabCreateCustom(vmk_ModuleID moduleID,
|
||||
vmk_PageSlabCreateProps *createProps,
|
||||
vmk_PageSlabID *pageSlabID);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PageSlabCreate -- */ /**
|
||||
*
|
||||
* \brief Convenience wrapper around vmk_PageSlabCreateCustom
|
||||
*
|
||||
* This function creates a new page slab with the given properties.
|
||||
*
|
||||
* \note This function might block.
|
||||
*
|
||||
* \param[in] createProps Properties of the new page slab.
|
||||
* \param[out] pageSlabID Handle to the newly created page slab.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
static VMK_INLINE VMK_ReturnStatus
|
||||
vmk_PageSlabCreate(vmk_PageSlabCreateProps *createProps,
|
||||
vmk_PageSlabID *pageSlabID)
|
||||
{
|
||||
return vmk_PageSlabCreateCustom(vmk_ModuleCurrentID, createProps, pageSlabID);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PageSlabDestroy -- */ /**
|
||||
*
|
||||
* \brief Destroy a page slab.
|
||||
*
|
||||
* \note The page slab must be empty meaning all previously allocated
|
||||
* pages must have been freed back to the slab.
|
||||
* \note This function might block.
|
||||
*
|
||||
* \param[in] pageSlabID Page slab identifier acquired through a
|
||||
* preceding vmk_PageSlabCreate(Custom) call.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
void
|
||||
vmk_PageSlabDestroy(vmk_PageSlabID pageSlabID);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PageSlabAllocationSize -- */ /**
|
||||
*
|
||||
* \brief Return the amount of memory that vmk_PageSlabCreate is going
|
||||
* to allocate from the passed in heap for each call.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
vmk_ByteCountSmall
|
||||
vmk_PageSlabAllocationSize(void);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PageSlabAlloc -- */ /**
|
||||
*
|
||||
* \brief Allocate a page from the given page slab.
|
||||
*
|
||||
* \note This function may block based on the blocking parameter
|
||||
*
|
||||
* \param[in] pageSlabID Page slab previously created via
|
||||
* vmk_PageSlabCreate(Custom)
|
||||
* \param[in] blocking Allow the page slab to block and wait for
|
||||
* a page to become free if none are readily
|
||||
* available.
|
||||
* \param[out] mpn Machine page number of the new page. Only
|
||||
* filled if return status was VMK_OK;
|
||||
*
|
||||
* \retval VMK_NO_MEMORY The slab was unable to allocate a page.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
VMK_ReturnStatus
|
||||
vmk_PageSlabAlloc(vmk_PageSlabID pageSlabID,
|
||||
vmk_Bool blocking,
|
||||
vmk_MPN *mpn);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PageSlabFree -- */ /**
|
||||
*
|
||||
* \brief Free a page to the given page slab.
|
||||
*
|
||||
* \param[in] pageSlabID Page slab previously created via
|
||||
* vmk_PageSlabCreate(Custom)
|
||||
* \param[in] mpn An machine page number previously returned
|
||||
* by vmk_PageSlabAlloc
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
void
|
||||
vmk_PageSlabFree(vmk_PageSlabID pageSlabID,
|
||||
vmk_MPN mpn);
|
||||
|
||||
|
||||
#endif /* _VMKAPI_PAGESLAB_H_ */
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -88,6 +88,11 @@ typedef struct vmk_SgArray {
|
|||
*/
|
||||
typedef struct vmk_SgOpsHandleInt *vmk_SgOpsHandle;
|
||||
|
||||
/**
|
||||
* \brief Opaque handle for scatter-gather component operations.
|
||||
*/
|
||||
typedef struct vmk_SgComponentOpsHandleInt *vmk_SgComponentOpsHandle;
|
||||
|
||||
/**
|
||||
* \brief The type of position a vmk_SgPosition represents.
|
||||
*/
|
||||
|
@ -140,6 +145,53 @@ typedef struct vmk_SgPosition {
|
|||
};
|
||||
} vmk_SgPosition;
|
||||
|
||||
/**
|
||||
* \brief Scatter-gather component
|
||||
*
|
||||
* A scatter gather component is a scatter gather array as well
|
||||
* as a specific data object offset and length describing
|
||||
* the start location and size of the I/O operation.
|
||||
*/
|
||||
typedef struct vmk_SgComponent {
|
||||
/**
|
||||
* Byte offset within a data object.
|
||||
*/
|
||||
vmk_ByteCount ioOffset;
|
||||
/**
|
||||
* Number of bytes of this I/O operation.
|
||||
*/
|
||||
vmk_ByteCount ioLength;
|
||||
/**
|
||||
* The scatter-gather array specifying the buffer addresses
|
||||
* used to satisfy this piece of the I/O operation.
|
||||
*/
|
||||
vmk_SgArray *sg;
|
||||
} vmk_SgComponent;
|
||||
|
||||
/**
|
||||
* \brief Scatter-gather component array.
|
||||
*
|
||||
* A scatter gather component array is a set of I/O operations to
|
||||
* a given data object where a unique data object offset, size,
|
||||
* and scatter gather array can be specified for each piece of
|
||||
* the operation.
|
||||
*/
|
||||
typedef struct vmk_SgComponentArray {
|
||||
/** \brief The number of SgComponents this array has. */
|
||||
vmk_int32 maxComponents;
|
||||
/** \brief Number of SgComponents currently in-use. */
|
||||
vmk_int32 numComponents;
|
||||
|
||||
/** \brief Reserved. */
|
||||
vmk_uint64 reserved;
|
||||
vmk_uint64 reserved2;
|
||||
|
||||
/** \brief Array of scatter gather components. Should be
|
||||
* set to zero on init.
|
||||
*/
|
||||
vmk_SgComponent sgComponent[0];
|
||||
} vmk_SgComponentArray;
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_SgComputeAllocSize-- */ /**
|
||||
|
@ -193,13 +245,44 @@ typedef VMK_ReturnStatus (*vmk_SgArrayOpAlloc)(vmk_SgOpsHandle handle,
|
|||
vmk_uint32 numElems,
|
||||
void *private);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_SgComponentArrayOpAlloc-- */ /**
|
||||
*
|
||||
* \ingroup ScatterGather
|
||||
* \brief Callback to allocate and initialize a new scatter-gather
|
||||
* component array.
|
||||
*
|
||||
* \note Callbacks of this type may not block.
|
||||
*
|
||||
* The returned array should have its maxLength field set correctly
|
||||
* and length field set to zero.
|
||||
*
|
||||
* \param[in] handle Opaque scatter-gather ops handle.
|
||||
* \param[out] sgComponent The new scatter gather component array.
|
||||
* \param[in] maxComponents Max scatter-gather operations the new
|
||||
* array must support.
|
||||
* \param[in] private Private data from vmk_SgComponentCreateOpsHandle().
|
||||
*
|
||||
* \retval VMK_OK The allocation succeeded.
|
||||
* \retval VMK_NO_MEMORY Not enough memory to allocate a new
|
||||
* scatter-gather component array.
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef VMK_ReturnStatus (*vmk_SgComponentArrayOpAlloc)(
|
||||
vmk_SgComponentOpsHandle handle,
|
||||
vmk_SgComponentArray **sgComponent,
|
||||
vmk_uint32 maxComponents,
|
||||
void *private);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_SgArrayOpFree-- */ /**
|
||||
*
|
||||
* \ingroup ScatterGather
|
||||
* \brief Callback to free an existing scatter-gather array.
|
||||
*
|
||||
*
|
||||
* \note Callbacks of this type may not block.
|
||||
*
|
||||
* \param[in] handle Opaque scatter-gather ops handle.
|
||||
|
@ -214,6 +297,28 @@ typedef VMK_ReturnStatus (*vmk_SgArrayOpFree)(vmk_SgOpsHandle handle,
|
|||
vmk_SgArray *sg,
|
||||
void *private);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_SgComponentArrayOpFree-- */ /**
|
||||
*
|
||||
* \ingroup ScatterGather
|
||||
* \brief Callback to free an existing scatter-gather component array.
|
||||
*
|
||||
* \note Callbacks of this type may not block.
|
||||
*
|
||||
* \param[in] handle Opaque scatter-gather ops handle.
|
||||
* \param[in] sgComponent scatter-gather component array to free.
|
||||
* \param[in] private Private data from vmk_SgCreateOpsHandle().
|
||||
*
|
||||
* \retval VMK_OK The free succeeded.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef VMK_ReturnStatus (*vmk_SgComponentArrayOpFree)(
|
||||
vmk_SgComponentOpsHandle handle,
|
||||
vmk_SgComponentArray *sgComponent,
|
||||
void *private);
|
||||
|
||||
/**
|
||||
* \brief Scatter-gather array operations.
|
||||
*
|
||||
|
@ -230,6 +335,22 @@ typedef struct vmk_SgArrayOps {
|
|||
vmk_SgArrayOpFree free;
|
||||
} vmk_SgArrayOps;
|
||||
|
||||
/**
|
||||
* \brief Scatter-gather components array operations.
|
||||
*
|
||||
* Routines not implemented by the caller must be set to NULL.
|
||||
*
|
||||
* Caller may override default behavior for any routine by supplying
|
||||
* the routines.
|
||||
*/
|
||||
typedef struct vmk_SgComponentArrayOps {
|
||||
/** Handler invoked when allocating scatter-gather component arrays. */
|
||||
vmk_SgComponentArrayOpAlloc alloc;
|
||||
|
||||
/** Handler invoked when freeing scatter-gather component arrays. */
|
||||
vmk_SgComponentArrayOpFree free;
|
||||
} vmk_SgComponentArrayOps;
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_SgComputeMaxEntries-- */ /**
|
||||
|
@ -284,6 +405,45 @@ VMK_ReturnStatus vmk_SgCreateOpsHandle(vmk_HeapID heapId,
|
|||
vmk_SgArrayOps *ops,
|
||||
void *private);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_SgComponentCreateOpsHandle-- */ /**
|
||||
*
|
||||
* \ingroup ScatterGather
|
||||
* \brief Create an opaque handle for scatter-gather component operations.
|
||||
*
|
||||
* The handle is used by other routines to invoke callbacks and track
|
||||
* other state related to scatter-gather component operations.
|
||||
*
|
||||
* \note If ops is non-NULL, both an alloc and a free method must
|
||||
* be provided.
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] heapId HeapID to allocate memory on.
|
||||
* \param[out] handle Opaque scatter-gather component ops handle.
|
||||
* \param[in] ops Scatter-gather compoents ops to associate with
|
||||
* the opaque handle.
|
||||
* If this argument is NULL, then the
|
||||
* default set of scatter-gather component ops
|
||||
* will be used and the supplied heap
|
||||
* will be used to allocate scatter-gather
|
||||
* component arrays.
|
||||
* \param[in] private Private data passed to each
|
||||
* vmk_SgComponentArrayOps method when it
|
||||
* is invoked.
|
||||
*
|
||||
* \retval VMK_OK The handle creation succeeded.
|
||||
* \retval VMK_BAD_PARAM The heapId or ops setting is invalid.
|
||||
* \retval VMK_NO_MEMORY Not enough memory to allocate a new
|
||||
* handle.
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_SgComponentCreateOpsHandle(
|
||||
vmk_HeapID heapId,
|
||||
vmk_SgComponentOpsHandle *handle,
|
||||
vmk_SgComponentArrayOps *ops,
|
||||
void *private);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_SgDestroyOpsHandle-- */ /**
|
||||
|
@ -299,6 +459,24 @@ VMK_ReturnStatus vmk_SgCreateOpsHandle(vmk_HeapID heapId,
|
|||
*/
|
||||
VMK_ReturnStatus vmk_SgDestroyOpsHandle(vmk_SgOpsHandle handle);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_SgComponentDestroyOpsHandle-- */ /**
|
||||
*
|
||||
* \ingroup ScatterGather
|
||||
* \brief Destroy opaque handle for scatter-gather component operations.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] handle Opaque scatter-gather component ops handle to
|
||||
* be destroyed.
|
||||
*
|
||||
* \retval VMK_OK The handle was destroyed.
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_SgComponentDestroyOpsHandle(
|
||||
vmk_SgComponentOpsHandle handle);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_SgAlloc-- */ /**
|
||||
|
@ -309,9 +487,9 @@ VMK_ReturnStatus vmk_SgDestroyOpsHandle(vmk_SgOpsHandle handle);
|
|||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] handle Opaque scatter-gather ops handle.
|
||||
* \param[in] sg New scatter-gather array.
|
||||
* \param[out] sg New scatter-gather array.
|
||||
* \param[in] maxElements Maximum number of elements the new
|
||||
* sactter-gather array should have.
|
||||
* scatter-gather array should have.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
@ -319,6 +497,29 @@ VMK_ReturnStatus vmk_SgAlloc(vmk_SgOpsHandle handle,
|
|||
vmk_SgArray **sg,
|
||||
vmk_uint32 maxElements);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_SgComponentAlloc-- */ /**
|
||||
*
|
||||
* \ingroup ScatterGather
|
||||
* \brief Allocate a scatter-gather component array with a given number
|
||||
* of component entries.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] handle Opaque scatter-gather component ops handle.
|
||||
* \param[out] sgComponent New scatter-gather component array.
|
||||
* \param[in] maxLength Maximum number of components the new
|
||||
* sactter-gather component array should have.
|
||||
*
|
||||
* \retval VMK_OK The allocation succeeded.
|
||||
* \retval VMK_NO_MEMORY Not enough memory to allocate the array.
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_SgComponentAlloc(vmk_SgComponentOpsHandle handle,
|
||||
vmk_SgComponentArray **sgComponent,
|
||||
vmk_uint32 maxLength);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_SgAllocWithInit-- */ /**
|
||||
|
@ -392,6 +593,28 @@ VMK_ReturnStatus vmk_SgInit(vmk_SgOpsHandle handle,
|
|||
VMK_ReturnStatus vmk_SgFree(vmk_SgOpsHandle handle,
|
||||
vmk_SgArray *sgArray);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_SgComponentFree -- */ /**
|
||||
*
|
||||
* \ingroup ScatterGather
|
||||
* \brief Free a scatter-gather component array.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] handle Opaque scatter-gather component ops handle.
|
||||
* \param[in] sgComponentArray Pointer returned by
|
||||
* vmk_SgAllocComponentArray().
|
||||
*
|
||||
* \retval VMK_OK The array was freed.
|
||||
* \retval VMK_BAD_PARAM The handle is invalid.
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_SgComponentFree(
|
||||
vmk_SgComponentOpsHandle handle,
|
||||
vmk_SgComponentArray *sgComponentArray);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_SgCopyData -- */ /**
|
||||
|
@ -466,6 +689,21 @@ VMK_ReturnStatus vmk_SgFindPosition(vmk_SgArray *sgArray,
|
|||
*/
|
||||
vmk_ByteCount vmk_SgGetDataLen(vmk_SgArray *sgArray);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_GetSgComponentDataLen -- */ /**
|
||||
*
|
||||
* \ingroup ScatterGather
|
||||
* \brief Compute the size of a scatter-gather component list's
|
||||
* payload in bytes.
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
vmk_ByteCount vmk_SgComponentGetDataLen(
|
||||
vmk_SgComponentArray *sgComponentArray);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_SgCopyTo-- */ /**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2010 VMware, Inc. All rights reserved.
|
||||
* Copyright 2010-2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
|
@ -13,6 +13,14 @@
|
|||
* \addtogroup Core
|
||||
* @{
|
||||
* \defgroup SpinLocks Spin Locks
|
||||
*
|
||||
* \par Lock acquisition behavior for lock types VMK_SPINLOCK and
|
||||
* VMK_SPINLOCK_RW:\n
|
||||
* In the case of lock contention, locks of types VMK_SPINLOCK and
|
||||
* VMK_SPINLOCK_RW will spin for a short amount of time. If the lock
|
||||
* acquisition does not succeed during the spinning phase, the lock acquisition
|
||||
* function will block.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -34,9 +42,6 @@
|
|||
/** Invalid lock rank */
|
||||
#define VMK_SPINLOCK_RANK_INVALID (0)
|
||||
|
||||
/** Invalid lock irql */
|
||||
#define VMK_SPINLOCK_IRQL_INVALID ((vmk_LockIRQL)-1)
|
||||
|
||||
/** Lock rank for unranked locks */
|
||||
#define VMK_SPINLOCK_UNRANKED (0xFFFF)
|
||||
|
||||
|
@ -48,16 +53,17 @@ typedef struct vmk_LockInt *vmk_Lock;
|
|||
|
||||
|
||||
/**
|
||||
* Spinlock Types
|
||||
* \brief Spinlock Types
|
||||
* @{
|
||||
*/
|
||||
typedef enum vmk_SpinlockType {
|
||||
/** Spinlock usable from a world context */
|
||||
VMK_SPINLOCK = 1,
|
||||
/** Spinlock usable from a world and interrupt handler context */
|
||||
VMK_SPINLOCK_IRQ = 2,
|
||||
/** RW Spinlock usable from a world context */
|
||||
VMK_SPINLOCK_RW = 3,
|
||||
} vmk_SpinlockType;
|
||||
typedef vmk_uint8 vmk_SpinlockType;
|
||||
|
||||
/** Spinlock usable from a world context */
|
||||
#define VMK_SPINLOCK (1)
|
||||
/** RW Spinlock usable from a world context */
|
||||
#define VMK_SPINLOCK_RW (3)
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
|
@ -65,14 +71,9 @@ typedef enum vmk_SpinlockType {
|
|||
*/
|
||||
typedef vmk_uint16 vmk_LockRank;
|
||||
|
||||
/**
|
||||
* \brief IRQ level of a VMK_SPINLOCK_IRQ lock.
|
||||
*/
|
||||
typedef vmk_uint32 vmk_LockIRQL;
|
||||
|
||||
|
||||
/**
|
||||
* Spinlock Creation Properties
|
||||
* \brief Spinlock Creation Properties
|
||||
*/
|
||||
typedef struct vmk_SpinlockCreateProps {
|
||||
/** Module ID for which the spinlock is created */
|
||||
|
@ -157,19 +158,26 @@ vmk_SpinlockAllocSize(vmk_SpinlockType type);
|
|||
******************************************************************************
|
||||
* vmk_SpinlockLock -- */ /**
|
||||
*
|
||||
* Acquire a spinlock of type VMK_SPINLOCK
|
||||
* \brief Acquire a spinlock of type VMK_SPINLOCK
|
||||
*
|
||||
* \param[in,out] lock Spinlock to be acquired
|
||||
*
|
||||
* \return VMK_OK on success, error code otherwise
|
||||
*
|
||||
* \note Lock checks are only executed when enabled for a given build. They
|
||||
* are always enabled for debug builds.
|
||||
* \note A caller has to release the spinlock with a subsequent call to
|
||||
* vmk_SpinlockUnlock
|
||||
* \note Callers are required to minimize the time and code that is executed
|
||||
* while any type of spinlock is held.
|
||||
* \note This function will not block
|
||||
* \note This function might block in case of lock contention
|
||||
* \note The lock acquisition might not succeed if the world receives a
|
||||
* VMK_DEATH_PENDING signal while it is waiting for the lock.
|
||||
*
|
||||
* \retval VMK_OK World acquired the lock.
|
||||
* \retval VMK_DEATH_PENDING World blocked during the lock acquisition
|
||||
* and awoken because the world is dying and
|
||||
* being reaped by the scheduler. The caller
|
||||
* is expected to return as soon as possible.
|
||||
* The lock has not been acquired.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
@ -178,50 +186,30 @@ VMK_ReturnStatus
|
|||
vmk_SpinlockLock(vmk_Lock lock);
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockLockIRQ -- */ /**
|
||||
*
|
||||
* Acquire a spinlock of type VMK_SPINLOCK_IRQ
|
||||
*
|
||||
* \param[in,out] lock IRQ Spinlock to be acquired
|
||||
* \param[out] irql Previous IRQ level of spinlock
|
||||
*
|
||||
* \return VMK_OK on success, error code otherwise
|
||||
*
|
||||
* \note Lock checks are only executed when enabled for a given build. They
|
||||
* are always enabled for debug builds.
|
||||
* \note A caller has to release the spinlock with a subsequent call to
|
||||
* vmk_SpinlockUnlockIRQ, providing the value returned in irql.
|
||||
* \note Callers are required to minimize the time and code that is executed
|
||||
* while any type of spinlock is held.
|
||||
* \note This function will not block.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
VMK_ReturnStatus
|
||||
vmk_SpinlockLockIRQ(vmk_Lock lock,
|
||||
vmk_LockIRQL *irql);
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockReadLock -- */ /**
|
||||
*
|
||||
* Acquire a spinlock of type VMK_SPINLOCK_RW for reading
|
||||
* \brief Acquire a spinlock of type VMK_SPINLOCK_RW for reading
|
||||
*
|
||||
* \param[in,out] lock R/W Spinlock to be acquired
|
||||
*
|
||||
* \return VMK_OK on success, error code otherwise
|
||||
*
|
||||
* \note Lock checks are only executed when enabled for a given build. They
|
||||
* are always enabled for debug builds.
|
||||
* \note A caller has to release the spinlock with a subsequent call to
|
||||
* vmk_SpinlockReadUnlock
|
||||
* \note Callers are required to minimize the time and code that is executed
|
||||
* while any type of spinlock is held.
|
||||
* \note This function will not block
|
||||
* \note This function might block in case of lock contention
|
||||
* \note The lock acquisition might not succeed if the world receives a
|
||||
* VMK_DEATH_PENDING signal while it is waiting for the lock.
|
||||
*
|
||||
* \retval VMK_OK World acquired the read lock.
|
||||
* \retval VMK_DEATH_PENDING World blocked during the lock acquisition
|
||||
* and awoken because the world is dying and
|
||||
* being reaped by the scheduler. The caller
|
||||
* is expected to return as soon as possible.
|
||||
* The read lock has not been acquired.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
@ -234,19 +222,27 @@ vmk_SpinlockReadLock(vmk_Lock lock);
|
|||
******************************************************************************
|
||||
* vmk_SpinlockWriteLock -- */ /**
|
||||
*
|
||||
* Acquire a spinlock of type VMK_SPINLOCK_RW for an exclusive write operation
|
||||
* \brief Acquire a spinlock of type VMK_SPINLOCK_RW for an exclusive write
|
||||
* operation
|
||||
*
|
||||
* \param[in,out] lock R/W Spinlock to be acquired
|
||||
*
|
||||
* \return VMK_OK on success, error code otherwise
|
||||
*
|
||||
* \note Lock checks are only executed when enabled for a given build. They
|
||||
* are always enabled for debug builds.
|
||||
* \note A caller has to release the spinlock with a subsequent call to
|
||||
* vmk_SpinlockUnlock
|
||||
* vmk_SpinlockWriteUnlock
|
||||
* \note Callers are required to minimize the time and code that is executed
|
||||
* while any type of spinlock is held.
|
||||
* \note This function will not block
|
||||
* \note This function might block in case of lock contention
|
||||
* \note The lock acquisition might not succeed if the world receives a
|
||||
* VMK_DEATH_PENDING signal while it is waiting for the lock.
|
||||
*
|
||||
* \retval VMK_OK World acquired the write lock.
|
||||
* \retval VMK_DEATH_PENDING World blocked during the lock acquisition
|
||||
* and awoken because the world is dying and
|
||||
* being reaped by the scheduler. The caller
|
||||
* is expected to return as soon as possible.
|
||||
* The write lock has not been acquired.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
@ -255,11 +251,90 @@ VMK_ReturnStatus
|
|||
vmk_SpinlockWriteLock(vmk_Lock lock);
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockLockIgnoreDeathPending -- */ /**
|
||||
*
|
||||
* \brief Acquire a spinlock of type VMK_SPINLOCK
|
||||
*
|
||||
* \param[in,out] lock Spinlock to be acquired
|
||||
*
|
||||
* \note This functions should only be used by callers that must acquire a
|
||||
* lock, for instance to perform clean up, even after a world has
|
||||
* already received the VMK_DEATH_PENDING signal.
|
||||
* \note Lock checks are only executed when enabled for a given build. They
|
||||
* are always enabled for debug builds.
|
||||
* \note A caller has to release the spinlock with a subsequent call to
|
||||
* vmk_SpinlockUnlock
|
||||
* \note Callers are required to minimize the time and code that is executed
|
||||
* while any type of spinlock is held.
|
||||
* \note This function might block in case of lock contention
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
void
|
||||
vmk_SpinlockLockIgnoreDeathPending(vmk_Lock lock);
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockReadLockIgnoreDeathPending -- */ /**
|
||||
*
|
||||
* \brief Acquire a spinlock of type VMK_SPINLOCK_RW for reading
|
||||
*
|
||||
* \param[in,out] lock R/W Spinlock to be acquired
|
||||
*
|
||||
* \note This functions should only be used by callers that must acquire a
|
||||
* lock, for instance to perform clean up, even after a world has
|
||||
* already received the VMK_DEATH_PENDING signal.
|
||||
* \note Lock checks are only executed when enabled for a given build. They
|
||||
* are always enabled for debug builds.
|
||||
* \note A caller has to release the spinlock with a subsequent call to
|
||||
* vmk_SpinlockReadUnlock
|
||||
* \note Callers are required to minimize the time and code that is executed
|
||||
* while any type of spinlock is held.
|
||||
* \note This function might block in case of lock contention
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
void
|
||||
vmk_SpinlockReadLockIgnoreDeathPending(vmk_Lock lock);
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockWriteLockIgnoreDeathPending -- */ /**
|
||||
*
|
||||
* \brief Acquire a spinlock of type VMK_SPINLOCK_RW for an exclusive write
|
||||
* operation
|
||||
*
|
||||
* \param[in,out] lock R/W Spinlock to be acquired
|
||||
*
|
||||
* \note This functions should only be used by callers that must acquire a
|
||||
* lock, for instance to perform clean up, even after a world has
|
||||
* already received the VMK_DEATH_PENDING signal.
|
||||
* \note Lock checks are only executed when enabled for a given build. They
|
||||
* are always enabled for debug builds.
|
||||
* \note A caller has to release the spinlock with a subsequent call to
|
||||
* vmk_SpinlockWriteUnlock
|
||||
* \note Callers are required to minimize the time and code that is executed
|
||||
* while any type of spinlock is held.
|
||||
* \note This function might block in case of lock contention
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
void
|
||||
vmk_SpinlockWriteLockIgnoreDeathPending(vmk_Lock lock);
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockUnlock -- */ /**
|
||||
*
|
||||
* Release a spinlock previously acquired via vmk_SpinlockLock
|
||||
* \brief Release a spinlock previously acquired via vmk_SpinlockLock
|
||||
*
|
||||
* \param[in,out] lock Spinlock to be released
|
||||
*
|
||||
|
@ -276,30 +351,32 @@ vmk_SpinlockUnlock(vmk_Lock lock);
|
|||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockUnlockIRQ -- */ /**
|
||||
* vmk_SpinlockUnlockOutOfOrder -- */ /**
|
||||
*
|
||||
* Release a IRQ spinlock previously acquired via vmk_SpinlockLockIRQ
|
||||
* \brief Out of order release of a spinlock previously acquired via
|
||||
* vmk_SpinlockLock
|
||||
*
|
||||
* \param[in,out] lock IRQ Spinlock to be released
|
||||
* \param[in] irql IRQ level of spinlock prior to locking
|
||||
* \param[in,out] lock Spinlock to be released
|
||||
*
|
||||
* \note Callers are required to release spinlocks in the reverse order in which
|
||||
* they were acquired
|
||||
* \note Callers are normally required to release spinlocks in the reverse
|
||||
* order in which they were acquired. This function allows for out
|
||||
* of order releases but this should only be done when it is known to
|
||||
* be safe. This function should only be used for out of order releases;
|
||||
* in all other cases vmk_SpinlockUnlock should be used.
|
||||
* \note This function will not block
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
void
|
||||
vmk_SpinlockUnlockIRQ(vmk_Lock lock,
|
||||
vmk_LockIRQL irql);
|
||||
vmk_SpinlockUnlockOutOfOrder(vmk_Lock lock);
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockReadUnlock -- */ /**
|
||||
*
|
||||
* Release a R/W spinlock previously acquired via vmk_SpinlockReadLock
|
||||
* \brief Release a R/W spinlock previously acquired via vmk_SpinlockReadLock
|
||||
*
|
||||
* \param[in,out] lock Spinlock to be released
|
||||
*
|
||||
|
@ -314,11 +391,34 @@ void
|
|||
vmk_SpinlockReadUnlock(vmk_Lock lock);
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockReadUnlockOutOfOrder -- */ /**
|
||||
*
|
||||
* \brief Out of order release of a R/W spinlock previously acquired via
|
||||
* vmk_SpinlockReadLock
|
||||
*
|
||||
* \param[in,out] lock Spinlock to be released
|
||||
*
|
||||
* \note Callers are normally required to release spinlocks in the reverse
|
||||
* order in which they were acquired. This function allows for out
|
||||
* of order releases but this should only be done when it is known to
|
||||
* be safe. This function should only be used for out of order releases;
|
||||
* in all other cases vmk_SpinlockReadUnlock should be used.
|
||||
* \note This function will not block
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
void
|
||||
vmk_SpinlockReadUnlockOutOfOrder(vmk_Lock lock);
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockWriteUnlock -- */ /**
|
||||
*
|
||||
* Release a R/W spinlock previously acquired via vmk_SpinlockWriteLock
|
||||
* \brief Release a R/W spinlock previously acquired via vmk_SpinlockWriteLock
|
||||
*
|
||||
* \param[in,out] lock Spinlock to be released
|
||||
*
|
||||
|
@ -335,9 +435,31 @@ vmk_SpinlockWriteUnlock(vmk_Lock lock);
|
|||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockAssertHeldOnPCPUInt --
|
||||
* vmk_SpinlockWriteUnlockOutOfOrder -- */ /**
|
||||
*
|
||||
* This is used by vmk_SpinlockAssertHeldOnPCPU(). VMKAPI clients should not
|
||||
* \brief Out of order release of a R/W spinlock previously acquired via
|
||||
* vmk_SpinlockWriteLock
|
||||
*
|
||||
* \param[in,out] lock Spinlock to be released
|
||||
*
|
||||
* \note Callers are normally required to release spinlocks in the reverse
|
||||
* order in which they were acquired. This function allows for out
|
||||
* of order releases but this should only be done when it is known to
|
||||
* be safe. This function should only be used for out of order releases;
|
||||
* in all other cases vmk_SpinlockWriteUnlock should be used.
|
||||
* \note This function will not block
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
void
|
||||
vmk_SpinlockWriteUnlockOutOfOrder(vmk_Lock lock);
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockAssertReaderHeldByWorldInt --
|
||||
*
|
||||
* This is used by vmk_SpinlockAssertHeldByWorld(). VMKAPI clients should not
|
||||
* call this function directly.
|
||||
*
|
||||
* \note This function will not block
|
||||
|
@ -347,29 +469,74 @@ vmk_SpinlockWriteUnlock(vmk_Lock lock);
|
|||
|
||||
/** \cond nodoc */
|
||||
void
|
||||
vmk_SpinlockAssertHeldOnPCPUInt(vmk_Lock lock);
|
||||
vmk_SpinlockAssertReaderHeldByWorldInt(vmk_Lock lock);
|
||||
/** \endcond */
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockAssertHeldOnPCPU -- */ /**
|
||||
* vmk_SpinlockAssertReaderHeldByWorld -- */ /**
|
||||
*
|
||||
* \brief Asserts that a lock is held on the current PCPU
|
||||
* \brief Asserts that a VMK_SPINLOCK_RW reader lock is held by the current world
|
||||
*
|
||||
* \param[in] lock Lock to check
|
||||
* \param[in] lock VMK_SPINLOCK_RW reader lock to check
|
||||
*
|
||||
* \note Checks are only executed on debug builds.
|
||||
* \note This function should only be called with a lock of lock type
|
||||
* VMK_SPINLOCK_RW which is holding a VMK_SPINLOCK_RW reader lock.
|
||||
* \note This function will not block
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
static VMK_ALWAYS_INLINE void
|
||||
vmk_SpinlockAssertHeldOnPCPU(
|
||||
vmk_SpinlockAssertReaderHeldByWorld(
|
||||
vmk_Lock lock)
|
||||
{
|
||||
#ifdef VMX86_DEBUG
|
||||
vmk_SpinlockAssertHeldOnPCPUInt(lock);
|
||||
vmk_SpinlockAssertReaderHeldByWorldInt(lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockAssertHeldByWorldInt --
|
||||
*
|
||||
* This is used by vmk_SpinlockAssertHeldByWorld(). VMKAPI clients should not
|
||||
* call this function directly.
|
||||
*
|
||||
* \note This function will not block
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** \cond nodoc */
|
||||
void
|
||||
vmk_SpinlockAssertHeldByWorldInt(vmk_Lock lock);
|
||||
/** \endcond */
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockAssertHeldByWorld -- */ /**
|
||||
*
|
||||
* \brief Asserts that a lock is held by the current world
|
||||
*
|
||||
* \param[in] lock Lock to check
|
||||
*
|
||||
* \note Checks are only executed on debug builds.
|
||||
* \note This function should only be called with a lock of lock type
|
||||
* VMK_SPINLOCK or VMK_SPINLOCK_RW (RW locks that are writer locks only).
|
||||
* For reader locks, use vmk_SpinlockAssertReaderHeldByWorld().
|
||||
* \note This function will not block
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
static VMK_ALWAYS_INLINE void
|
||||
vmk_SpinlockAssertHeldByWorld(
|
||||
vmk_Lock lock)
|
||||
{
|
||||
#ifdef VMX86_DEBUG
|
||||
vmk_SpinlockAssertHeldByWorldInt(lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* Spin Locks */ /**
|
||||
*
|
||||
* \addtogroup Core
|
||||
* @{
|
||||
* \addtogroup SpinLocks
|
||||
* @{
|
||||
* \defgroup Deprecated Deprecated APIs
|
||||
* @{
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _VMKAPI_SPINLOCK_DEPRECATED_H_
|
||||
#define _VMKAPI_SPINLOCK_DEPRECATED_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 */
|
||||
|
||||
|
||||
/** Invalid lock irql */
|
||||
#define VMK_SPINLOCK_IRQL_INVALID ((vmk_LockIRQL)-1)
|
||||
|
||||
|
||||
/**
|
||||
* \brief Spinlock Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Spinlock usable from a world and interrupt handler context */
|
||||
#define VMK_SPINLOCK_IRQ (2)
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* \brief IRQ level of a VMK_SPINLOCK_IRQ lock.
|
||||
*/
|
||||
typedef vmk_uint32 vmk_LockIRQL;
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockLockIRQ -- */ /**
|
||||
*
|
||||
* \brief Acquire a spinlock of type VMK_SPINLOCK_IRQ
|
||||
*
|
||||
* \deprecated
|
||||
*
|
||||
* \param[in,out] lock IRQ Spinlock to be acquired
|
||||
* \param[out] irql Previous IRQ level of spinlock
|
||||
*
|
||||
* \return VMK_OK on success, error code otherwise
|
||||
*
|
||||
* \note Lock checks are only executed when enabled for a given build. They
|
||||
* are always enabled for debug builds.
|
||||
* \note A caller has to release the spinlock with a subsequent call to
|
||||
* vmk_SpinlockUnlockIRQ, providing the value returned in irql.
|
||||
* \note Callers are required to minimize the time and code that is executed
|
||||
* while any type of spinlock is held.
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
VMK_ReturnStatus
|
||||
vmk_SpinlockLockIRQ(vmk_Lock lock,
|
||||
vmk_LockIRQL *irql);
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockUnlockIRQ -- */ /**
|
||||
*
|
||||
* \brief Release a IRQ spinlock previously acquired via vmk_SpinlockLockIRQ
|
||||
*
|
||||
* \deprecated
|
||||
*
|
||||
* \param[in,out] lock IRQ Spinlock to be released
|
||||
* \param[in] irql IRQ level of spinlock prior to locking
|
||||
*
|
||||
* \note Callers are required to release spinlocks in the reverse order in which
|
||||
* they were acquired
|
||||
* \note This function will not block
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
void
|
||||
vmk_SpinlockUnlockIRQ(vmk_Lock lock,
|
||||
vmk_LockIRQL irql);
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockUnlockIRQOutOfOrder -- */ /**
|
||||
*
|
||||
* \brief Out of order release of a IRQ spinlock previously acquired via
|
||||
* vmk_SpinlockLockIRQ
|
||||
*
|
||||
* \deprecated
|
||||
*
|
||||
* \param[in,out] lock IRQ Spinlock to be released
|
||||
* \param[in] irql IRQ level of spinlock prior to locking
|
||||
*
|
||||
* \note Callers are normally required to release spinlocks in the reverse
|
||||
* order in which they were acquired. This function allows for out
|
||||
* of order releases but this should only be done when it is known to
|
||||
* be safe. This function should only be used for out of order releases;
|
||||
* in all other cases vmk_SpinlockUnlockIRQ should be used.
|
||||
* \note This function will not block
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
void
|
||||
vmk_SpinlockUnlockIRQOutOfOrder(vmk_Lock lock,
|
||||
vmk_LockIRQL irql);
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockAssertHeldOnPCPUInt --
|
||||
*
|
||||
* This is used by vmk_SpinlockAssertHeldOnPCPU(). VMKAPI clients should not
|
||||
* call this function directly.
|
||||
*
|
||||
* \deprecated
|
||||
*
|
||||
* \note This function will not block
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** \cond nodoc */
|
||||
void
|
||||
vmk_SpinlockAssertHeldOnPCPUInt(vmk_Lock lock);
|
||||
/** \endcond */
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_SpinlockAssertHeldOnPCPU -- */ /**
|
||||
*
|
||||
* \brief Asserts that a lock is held on the current PCPU
|
||||
*
|
||||
* \deprecated
|
||||
*
|
||||
* \param[in] lock Lock to check
|
||||
*
|
||||
* \note Checks are only executed on debug builds.
|
||||
* \note This function should only be called with a lock of lock type
|
||||
* VMK_SPINLOCK_IRQ
|
||||
* \note This function will not block
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
static VMK_ALWAYS_INLINE void
|
||||
vmk_SpinlockAssertHeldOnPCPU(
|
||||
vmk_Lock lock)
|
||||
{
|
||||
#ifdef VMX86_DEBUG
|
||||
vmk_SpinlockAssertHeldOnPCPUInt(lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
/** @} */
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -1,5 +1,5 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2010 VMware, Inc. All rights reserved.
|
||||
* Copyright 2010-2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
|
@ -26,6 +26,171 @@
|
|||
#endif
|
||||
/** \endcond never */
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_UserMapCallback -- */ /**
|
||||
*
|
||||
* \brief Callback function invoked when user mapping is released.
|
||||
*
|
||||
* \param[in] callbackParam Opaque parameter for callback function.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef void (*vmk_UserMapCallback)(void *);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Properties of a vmk_UserMap() map request.
|
||||
*/
|
||||
typedef struct vmk_UserMapProps {
|
||||
/** \brief Module ID of module requesting mapping. */
|
||||
vmk_ModuleID moduleID;
|
||||
/** \brief Function to call when mapping is released. */
|
||||
vmk_UserMapCallback callbackFunction;
|
||||
/** \brief Opaque parameter for callbackFunction. */
|
||||
vmk_AddrCookie callbackParam;
|
||||
/**
|
||||
* \brief Pointer to map request structure.
|
||||
*
|
||||
* \note See Mapping section for description
|
||||
* of map request structure.
|
||||
*/
|
||||
vmk_MapRequest *mapRequest;
|
||||
} vmk_UserMapProps;
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_UserMap -- */ /**
|
||||
*
|
||||
* \brief Map the provided request into a contiguous virtual address
|
||||
* space of current user world.
|
||||
*
|
||||
* \note The only supported mapping attributes are READONLY, READWRITE,
|
||||
* WRITECOMBINE, and UNCACHED. Any other attribute will cause
|
||||
* mapping to fail with return status VMK_BAD_PARAM.
|
||||
*
|
||||
* \param[in] props Properties of this mapping request.
|
||||
* \param[in,out] vaddr Pointer to virtual address of mapping
|
||||
* (non-zero to specify a virtual address,
|
||||
* or zero for default address).
|
||||
*
|
||||
* \retval VMK_OK Map is successful.
|
||||
* \retval VMK_BAD_PARAM Input parameter is invalid.
|
||||
* \retval VMK_NO_MEMORY Unable to allocate mapping request.
|
||||
* \retval VMK_NO_RESOURCES Unable to allocate mapping request.
|
||||
* \retval VMK_INVALID_ADDRESS Requested address not in map range.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_UserMap(
|
||||
vmk_UserMapProps *props,
|
||||
vmk_VA *vaddr);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_UserUnmap -- */ /**
|
||||
*
|
||||
* \brief Unmap user world virtual address space mapped by vmk_UserMap().
|
||||
*
|
||||
* \param[in] vaddr Virtual address to unmap.
|
||||
* \param[in] length Length of address space in bytes.
|
||||
*
|
||||
* \retval VMK_OK Unmap is successful.
|
||||
* \retval VMK_NOT_FOUND Virtual address and length not mapped.
|
||||
* \retval VMK_INVALID_ADDRESS Requested address is not page aligned.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_UserUnmap(
|
||||
vmk_VA vaddr,
|
||||
vmk_ByteCount length);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_UserAddValidMPNRange -- */ /**
|
||||
*
|
||||
* \brief Indicate a range of consecutive MPNs can be referenced by
|
||||
* user worlds.
|
||||
*
|
||||
* \param[in] mpn First MPN in range.
|
||||
* \param[in] numPages Number of machine pages in range.
|
||||
*
|
||||
* \retval VMK_OK MPNs added to user worlds.
|
||||
* \retval VMK_BAD_PARAM Input parameter is invalid.
|
||||
* \retval VMK_NO_MEMORY Unable to allocate memory for request.
|
||||
* \retval VMK_INVALID_PAGE_NUMBER MPN range intersects with existing
|
||||
* MPN range.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_UserAddValidMPNRange(
|
||||
vmk_MPN mpn,
|
||||
vmk_uint32 numPages);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_UserRemoveValidMPNRange -- */ /**
|
||||
*
|
||||
* \brief Remove a range of consecutive MPNs from user worlds.
|
||||
*
|
||||
* \param[in] mpn First MPN in range.
|
||||
* \param[in] numPages Number of machine pages in range.
|
||||
*
|
||||
* \retval VMK_OK MPNs removed from user worlds.
|
||||
* \retval VMK_NOT_FOUND MPN range not found.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_UserRemoveValidMPNRange(
|
||||
vmk_MPN mpn,
|
||||
vmk_uint32 numPages);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_UserPinPage -- */ /**
|
||||
*
|
||||
* \brief Marks the VPN in the specified world as not swappable.
|
||||
*
|
||||
* \param[in] worldID ID of world whose mapping will be pinned.
|
||||
* \param[in] vpn VPN to pin.
|
||||
* \param[out] mpn MPN backing this pinned VPN.
|
||||
*
|
||||
* \retval VMK_OK VPNs was pinned successfully.
|
||||
* \retval VMK_BAD_PARAM An invalid argument was provided.
|
||||
* \retval VMK_INVALID_WORLD An invalid worldID was provided.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_UserPinPage(
|
||||
vmk_WorldID worldID,
|
||||
vmk_VPN vpn,
|
||||
vmk_MPN *mpn);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_UserUnpinPage -- */ /**
|
||||
*
|
||||
* \brief Marks the specified VPN in the specified world as swappable.
|
||||
*
|
||||
* \note This VPN must have been pinned by a call to vmk_UserPinPage().
|
||||
*
|
||||
* \param[in] worldID ID of world whose mapping will be
|
||||
* unpinned.
|
||||
* \param[in] vpn VPN to unpin.
|
||||
*
|
||||
* \retval VMK_OK VPNs was unpinned successfully.
|
||||
* \retval VMK_BAD_PARAM An invalid argument was provided.
|
||||
* \retval VMK_INVALID_WORLD An invalid worldID was provided.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_UserUnpinPage(
|
||||
vmk_WorldID worldID,
|
||||
vmk_VPN vpn);
|
||||
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_CopyFromUser -- */ /**
|
||||
|
|
|
@ -0,0 +1,701 @@
|
|||
/* **********************************************************
|
||||
* Copyright 1998 - 2013 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Please consult with the VMKernel hardware and core teams before making any
|
||||
* binary incompatible changes to this file!
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* PCI */ /**
|
||||
* \addtogroup Device
|
||||
* @{
|
||||
* \defgroup PCI PCI
|
||||
* @{
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _VMKAPI_PCI_H_
|
||||
#define _VMKAPI_PCI_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 "device/vmkapi_vector.h"
|
||||
|
||||
#define VMK_PCI_BUS_NAME "pci"
|
||||
|
||||
/** \brief Maximum number of characters in a PCI device name. */
|
||||
#define VMK_PCI_DEVICE_NAME_LENGTH 32
|
||||
|
||||
/** \brief Per-system max for segments */
|
||||
#define VMK_PCI_NUM_SEGS 256
|
||||
/** \brief Per-system max for busses */
|
||||
#define VMK_PCI_NUM_BUSES 256
|
||||
/** \brief Per-bus max for slots */
|
||||
#define VMK_PCI_NUM_SLOTS 32
|
||||
/** \brief Per-slot max for functions */
|
||||
#define VMK_PCI_NUM_FUNCS 8
|
||||
/** \brief Per-device max for BARs */
|
||||
#define VMK_PCI_NUM_BARS 6
|
||||
/** \brief Per-device max for BARs on a bridge */
|
||||
#define VMK_PCI_NUM_BARS_BRIDGE 2
|
||||
|
||||
/**
|
||||
* \brief PCI BAR flags.
|
||||
*/
|
||||
typedef enum vmk_PCIBARFlags {
|
||||
VMK_PCI_BAR_FLAGS_IO = 0x1,
|
||||
VMK_PCI_BAR_FLAGS_MEM_64_BITS = 0x4,
|
||||
VMK_PCI_BAR_FLAGS_MEM_PREFETCHABLE = 0x8,
|
||||
VMK_PCI_BAR_FLAGS_IO_MASK = 0x3,
|
||||
VMK_PCI_BAR_FLAGS_MEM_MASK = 0xF,
|
||||
} vmk_PCIBARFlags;
|
||||
|
||||
/**
|
||||
* \brief PCI device identifier.
|
||||
*
|
||||
*/
|
||||
typedef struct vmk_PCIDeviceID {
|
||||
vmk_uint16 vendorID;
|
||||
vmk_uint16 deviceID;
|
||||
vmk_uint16 subVendorID;
|
||||
vmk_uint16 subDeviceID;
|
||||
vmk_uint16 classCode;
|
||||
vmk_uint16 progIFRevID;
|
||||
} vmk_PCIDeviceID;
|
||||
|
||||
/**
|
||||
* \brief PCI device Address (SBDF).
|
||||
*
|
||||
*/
|
||||
typedef struct vmk_PCIDeviceAddr {
|
||||
vmk_uint16 seg;
|
||||
vmk_uint8 bus;
|
||||
vmk_uint8 dev:5;
|
||||
vmk_uint8 fn:3;
|
||||
} vmk_PCIDeviceAddr;
|
||||
|
||||
/**
|
||||
* \brief PCI device resource.
|
||||
*
|
||||
*/
|
||||
typedef struct vmk_PCIResource {
|
||||
/** \brief Resource's physical address. */
|
||||
vmk_MA start;
|
||||
/** \brief Resource size in bytes. */
|
||||
vmk_ByteCount size;
|
||||
/** \brief Resource flags. */
|
||||
vmk_uint64 flags;
|
||||
} vmk_PCIResource;
|
||||
|
||||
/**
|
||||
* \brief Configuration space access types
|
||||
*/
|
||||
typedef enum vmk_PCIConfigAccess {
|
||||
VMK_PCI_CONFIG_ACCESS_8 = 1,
|
||||
VMK_PCI_CONFIG_ACCESS_16 = 2,
|
||||
VMK_PCI_CONFIG_ACCESS_32 = 4
|
||||
} vmk_PCIConfigAccess;
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PCIRemoveVF -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Remove a PCI virtual function (VF) device.
|
||||
*
|
||||
* Physical function (PF) driver should carry out any operations
|
||||
* required for the removal of a virtual function device, and
|
||||
* unregister the virtual function device using vmk_PCIUnregisterVF().
|
||||
*
|
||||
* \param[in] vf Handle to PCI VF to be removed.
|
||||
*
|
||||
* \retval VMK_OK Success
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
typedef VMK_ReturnStatus (*vmk_PCIRemoveVF)(vmk_PCIDevice vf);
|
||||
|
||||
/**
|
||||
* \brief PCI virtual function (VF) device operations.
|
||||
*/
|
||||
typedef struct {
|
||||
/** \brief Remove a PCI virtual function from the system. */
|
||||
vmk_PCIRemoveVF removeVF;
|
||||
} vmk_PCIVFDeviceOps;
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_PCIQueryDeviceID -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Query PCI Device's identifier information.
|
||||
*
|
||||
* Upon successful completion, devID structure is filled with the
|
||||
* identifier information.
|
||||
*
|
||||
* \param[in] pciDevice Pointer to PCI device handle.
|
||||
* \param[out] devID Pointer to PCI Device ID struct.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM pciDevice or devID is invalid.
|
||||
* \retval VMK_OK Query successfully processed.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_PCIQueryDeviceID(vmk_PCIDevice pciDevice,
|
||||
vmk_PCIDeviceID *devID);
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_PCIQueryDeviceAddr -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Query PCI Device's Address (SBDF) information.
|
||||
*
|
||||
* Upon successful operation, sbdf struct is filled with device's
|
||||
* seg, bus, dev, fn information.
|
||||
*
|
||||
* \param[in] pciDevice Pointer to PCI device handle.
|
||||
* \param[out] sbdf Pointer to PCI Device Addr struct.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM pciDevice or sbdf is invalid.
|
||||
* \retval VMK_OK Query successfully processed.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_PCIQueryDeviceAddr(vmk_PCIDevice pciDevice,
|
||||
vmk_PCIDeviceAddr *sbdf);
|
||||
|
||||
/**
|
||||
***********************************************************************
|
||||
* vmk_PCIQueryIOResources -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Query PCI Device's BAR resources information.
|
||||
*
|
||||
* Upon successful completion, resources array is filled with device's
|
||||
* first numBars BARs [0 - numBars) information. The resources array
|
||||
* passed in should be able to hold numBars resources.
|
||||
*
|
||||
* \param[in] pciDevice Pointer to PCI device handle.
|
||||
* \param[in] numBars Number of resources queried.
|
||||
* \param[out] resources Pointer to PCI resources array.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM pciDevice or resources is invalid.
|
||||
* \retval VMK_BAD_PARAM numBars is greater than VMK_PCI_NUM_BARS
|
||||
* \retval VMK_OK Query successfully processed.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_PCIQueryIOResources(vmk_PCIDevice pciDevice,
|
||||
vmk_uint8 numBars,
|
||||
vmk_PCIResource resources[]);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PCIFindCapability -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Returns the offset of the capability in device's config space.
|
||||
*
|
||||
* \param[in] device PCI device handle
|
||||
* \param[in] capID Capability ID of interest
|
||||
* \param[out] capOffset Pointer to the capability offset
|
||||
*
|
||||
* \retval VMK_BAD_PARAM If capOffset is NULL or device handle is invalid
|
||||
* \retval VMK_NOT_FOUND capability is not found
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_PCIFindCapability(vmk_PCIDevice device,
|
||||
vmk_uint8 capID,
|
||||
vmk_uint16 *capOffset);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PCIReadConfig -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Read config space of device at offset.
|
||||
*
|
||||
* \param[in] moduleID Module performing the config read.
|
||||
* \param[in] device PCI device handle.
|
||||
* \param[in] accessType Access 1, 2 or 4 bytes.
|
||||
* \param[in] offset Offset to read.
|
||||
* \param[out] data Pointer to the data read.
|
||||
*
|
||||
* \note Offset is expected to meet the alignment requirements of the
|
||||
* specified access type.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM Device handle is NULL/invalid.
|
||||
* \retval VMK_BAD_PARAM Data pointer is NULL.
|
||||
* \retval VMK_BAD_PARAM Offset is not aligned for the access type.
|
||||
* \retval VMK_BAD_PARAM AccessType is not a valid access type.
|
||||
* \retval VMK_NO_PERMISSION Device is not owned by module.
|
||||
* \retval VMK_LIMIT_EXCEEDED Offset is beyond available config space.
|
||||
* \retval VMK_FAILURE Failure to access config space.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_PCIReadConfig(vmk_ModuleID moduleID,
|
||||
vmk_PCIDevice device,
|
||||
vmk_PCIConfigAccess accessType,
|
||||
vmk_uint16 offset,
|
||||
vmk_uint32 *data);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PCIWriteConfig -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Write data to config space of device at offset.
|
||||
*
|
||||
* \param[in] moduleID Module performing the config write.
|
||||
* \param[in] device PCI device handle.
|
||||
* \param[in] accessType Access 1, 2 or 4 bytes.
|
||||
* \param[in] offset Offset to write at.
|
||||
* \param[in] data Data to write.
|
||||
*
|
||||
* \note Offset is expected to meet the alignment requirements of the
|
||||
* specified access type.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM Device handle is NULL/invalid.
|
||||
* \retval VMK_BAD_PARAM Offset is not aligned for the access type.
|
||||
* \retval VMK_BAD_PARAM AccessType is not a valid access type.
|
||||
* \retval VMK_NO_PERMISSION Device is not owned by module.
|
||||
* \retval VMK_LIMIT_EXCEEDED Offset is beyond available config space.
|
||||
* \retval VMK_FAILURE Failure to access config space.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_PCIWriteConfig(vmk_ModuleID moduleID,
|
||||
vmk_PCIDevice device,
|
||||
vmk_PCIConfigAccess accessType,
|
||||
vmk_uint16 offset,
|
||||
vmk_uint32 data);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PCIMapIOResource -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Reserve and map PCI IO/Memory space described by pciBar.
|
||||
*
|
||||
* Reserves the specified BAR with resource manager and maps the memory
|
||||
* described by pciBar to a virtual address.
|
||||
*
|
||||
* \param[in] moduleID Module requesting the resource.
|
||||
* \param[in] device PCI device handle.
|
||||
* \param[in] pciBar PCI bar to map, must be [0 - 5].
|
||||
* \param[out] reservation IOReservation handle. Only necessary for
|
||||
* VMK_PCI_BAR_FLAGS_IO type BARs.
|
||||
* \param[out] mappedAddress Pointer to hold the virtual address of
|
||||
* the mapping.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM Device handle is NULL/invalid
|
||||
* \retval VMK_BAD_PARAM PciBar is invalid
|
||||
* \retval VMK_BAD_PARAM reservation is NULL for PIO BAR
|
||||
* \retval VMK_BAD_PARAM MappedAddres is NULL
|
||||
* \retval VMK_NO_RESOURCES Resource is not owned by device
|
||||
* \retval VMK_NO_PERMISSION Device is not owned by module
|
||||
* \retval VMK_BAD_PARAM PciBar is 2nd half of 64-bit MMIO BAR
|
||||
* \retval VMK_BAD_PARAM PciBar addr/size too big for 32-bit MPN
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_PCIMapIOResource(vmk_ModuleID moduleID,
|
||||
vmk_PCIDevice device,
|
||||
vmk_uint8 pciBar,
|
||||
vmk_IOReservation *reservation,
|
||||
vmk_VA *mappedAddress);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PCIUnmapIOResource -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Unmap and release the established PCI IO/Memory mapping.
|
||||
*
|
||||
* Upon successful return from the call, the mapping is no longer valid.
|
||||
*
|
||||
* \param[in] moduleID Module requested the resource.
|
||||
* \param[in] device PCI device handle.
|
||||
* \param[in] pciBar PCI bar to unmap.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM Device handle is NULL/invalid
|
||||
* \retval VMK_BAD_PARAM PciBar is invalid
|
||||
* \retval VMK_BAD_PARAM Resource is not mapped
|
||||
* \retval VMK_NO_PERMISSION Device is not owned by module
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_PCIUnmapIOResource(vmk_ModuleID moduleID,
|
||||
vmk_PCIDevice device,
|
||||
vmk_uint8 pciBar);
|
||||
|
||||
/**
|
||||
* Interrupt related functions.
|
||||
*
|
||||
* Driver should first allocate interrupt(s), register and enable the
|
||||
* interrupt(s).
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PCIAllocIntrCookie -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Allocate interrupt resources for the specified device.
|
||||
*
|
||||
* On successful return, intrArray will contain the vmk_IntrCookie(s)
|
||||
* representing the allocated interrupt resources. numIntrsAlloced
|
||||
* will contain the number of interrupts actually allocated.
|
||||
*
|
||||
* \note If type is VMK_PCI_INTERRUPT_TYPE_LEGACY or type is
|
||||
* VMK_PCI_INTERRUPT_TYPE_MSI then numIntrsDesired and
|
||||
* numIntrsRequired must both be set to 1.
|
||||
* \note The caller must provide memory for numIntrsDesired
|
||||
* vmk_IntrCookie(s) in the space referenced by intrArray.
|
||||
* \note The caller can specify the index into MSIX table for the
|
||||
* desired interrupts using indexAarray. indexArray can be NULL
|
||||
* if the caller does not care. If non-NULL, it should specify
|
||||
* index for numIntrDesired entries, and intrArray is filled
|
||||
* with allocated interrupt for requested index values.
|
||||
*
|
||||
* \param[in] moduleID Module allocating the interrupts.
|
||||
* \param[in] device PCI device handle.
|
||||
* \param[in] type Interrupt type.
|
||||
* \param[in] numIntrsDesired Number of interrupts desired.
|
||||
* \param[in] numIntrsRequired Number of interrupts required.
|
||||
* \param[in] indexArray Array of MSIX table index.
|
||||
* \param[out] intrArray Array of interrupts allocated.
|
||||
* \param[out] numIntrsAlloced Number of interrupts allocated.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM props argument is NULL.
|
||||
* \retval VMK_BAD_PARAM Device handle is invalid/NULL.
|
||||
* \retval VMK_BAD_PARAM Device is not interruptive.
|
||||
* \retval VMK_BAD_PARAM type is VMK_INTERRUPT_TYPE_PCI_LEGACY
|
||||
* the ioapic pin the device is connected
|
||||
* to is not described in interrupt
|
||||
* routing tables.
|
||||
* \retval VMK_BAD_PARAM type is VMK_INTERRUPT_TYPE_PCI_LEGACY
|
||||
* or VMK_INTERRUPT_TYPE_PCI_MSI and
|
||||
* numIntrsDesired or numIntrsRequired
|
||||
* is not equal to 1.
|
||||
* \retval VMK_BAD_PARAM type is VMK_INTERRUPT_TYPE_PCI_MSIX and
|
||||
* numIntrsAlloced is NULL.
|
||||
* \retval VMK_BAD_PARAM type is VMK_INTERRUPT_TYPE_PCI_MSIX and
|
||||
* numIntrsRequired > numIntrsDesired
|
||||
* \retval VMK_BAD_PARAM All other mal-formed props.
|
||||
* \retval VMK_NO_MEMORY Internal memory allocation failure
|
||||
* \retval VMK_NOT_SUPPORTED Device/platform doesn't support MSI or
|
||||
* MSIX if request is for MSI or MSIX type
|
||||
* \retval VMK_NO_PERMISSION Device is not owned by module
|
||||
* \retval VMK_IO_ERROR PCI Bus error, probably device is
|
||||
* broken or unplugged
|
||||
* \retval VMK_NO_RESOURCES For MSIX type, the number of interrupts
|
||||
* available is less than numIntrsRequired.
|
||||
* \retval VMK_FAILIURE All other errors.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_PCIAllocIntrCookie(vmk_ModuleID moduleID,
|
||||
vmk_PCIDevice device,
|
||||
vmk_PCIInterruptType type,
|
||||
vmk_uint32 numIntrsDesired,
|
||||
vmk_uint32 numIntrsRequired,
|
||||
vmk_uint16 *indexArray,
|
||||
vmk_IntrCookie *intrArray,
|
||||
vmk_uint32 *numIntrsAlloced);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PCIFreeIntrCookie -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Free all interrupts that were previously allocated by a call
|
||||
* to vmk_PCIAllocIntrCookie().
|
||||
*
|
||||
* \param[in] moduleID Module that allocated the interrupts
|
||||
* \param[in] device PCI device handle
|
||||
*
|
||||
* \retval VMK_BAD_PARAM Module ID is invalid.
|
||||
* \retval VMK_BAD_PARAM Device handle is invalid/NULL.
|
||||
* \retval VMK_NO_PERMISSION Device is not owned by module.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_PCIFreeIntrCookie(vmk_ModuleID moduleID,
|
||||
vmk_PCIDevice device);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PCIEnableVFs -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Enable virtual functions in an SR-IOV physical function.
|
||||
*
|
||||
* numVFs is the number of virtual functions to be enabled. Setting it to
|
||||
* zero requests that all virtual functions (VFs) under the given physical
|
||||
* function (PF) be enabled. The actual number of VFs successfully enabled
|
||||
* is returned in numVFs upon success.
|
||||
*
|
||||
* \note For a native PF driver, this function must be called from the
|
||||
* driver's vmk_DriverAttachDevice() callback. This will ensure VFs are
|
||||
* enabled before the driver receives the vmk_DriverScanDevice() callback,
|
||||
* and also prevent VFs from being re-enabled if the PF is quiesced
|
||||
* and re-started.
|
||||
*
|
||||
* \note This function creates a vmk_PCIDevice handle for each VF. The
|
||||
* handle of each VF can be retrieved via the function
|
||||
* vmk_PCIGetVFPCIDevice().
|
||||
*
|
||||
* \param[in] pf PCI device handle of the SR-IOV PF.
|
||||
* \param[in,out] numVFs Number of VFs to enable/enabled.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM Device handle is invalid or device does not exist.
|
||||
* \retval VMK_FAILURE Cannot enable virtual functions.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PCIEnableVFs(vmk_PCIDevice pf,
|
||||
vmk_uint16 *numVFs);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PCIDisableVFs -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Disable all virtual functions in an SR-IOV physical function.
|
||||
*
|
||||
* \note For a native PF driver, this function must be called from the
|
||||
* driver's vmk_DriverDetachDevice() callback. This will ensure that
|
||||
* all virtual functions (VFs) being disabled have been un-registered
|
||||
* with the vmkkernel's device layer (i.e., unregistration occurs in the
|
||||
* PF driver's VF remove callback which occurs prior to
|
||||
* vmkDriverDetachDevice()). In addition, this will also prevent VFs from
|
||||
* being disabled if the PF is quiesced.
|
||||
*
|
||||
* \param[in] pf PCI device handle of physical function (PF).
|
||||
*
|
||||
* \retval VMK_BAD_PARAM Device handle is invalid or device does not exist.
|
||||
* \retval VMK_FAILURE Device is not in SR-IOV mode.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PCIDisableVFs(vmk_PCIDevice pf);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PCIGetVFPCIDevice -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Retrieves the PCI device handle of a virtual function (VF).
|
||||
*
|
||||
* \note This function should only be called on enabled VFs (see
|
||||
* vmk_PCIEnableVF()).
|
||||
*
|
||||
* \param[in] pf PCI device handle of the parent physical function.
|
||||
* \param[in] vfIndex Index of the virtual function.
|
||||
* \param[out] vf PCI device handle of the requested virtual function.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM PF device handle is invalid or device does not exist.
|
||||
* \retval VMK_BAD_PARAM VF device handle argument is NULL.
|
||||
* \retval VMK_NOT_FOUND VF doesn't exist.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PCIGetVFPCIDevice(vmk_PCIDevice pf,
|
||||
vmk_uint16 vfIndex,
|
||||
vmk_PCIDevice *vf);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PCIGetPFPCIDevice -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Retrieve the PCI device handle of a PF, given the VF handle.
|
||||
*
|
||||
* \param[in] vf PCI device handle of the virtual function.
|
||||
* \param[out] pf PCI device handle of the parent physical function.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM VF device handle is invalid or device does not exist.
|
||||
* \retval VMK_BAD_PARAM PF device handle argument is NULL.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PCIGetPFPCIDevice(vmk_PCIDevice vf, vmk_PCIDevice *pf);
|
||||
|
||||
/*
|
||||
************************************************************************
|
||||
* vmk_PCIRegisterVF -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Register virtual functions with the vmkernel's device layer.
|
||||
*
|
||||
* The devOps parameter is the vmk_DeviceOps structure associated with the
|
||||
* registered virtual function (VF).
|
||||
*
|
||||
* \note This function is meant to be used by native PF drivers only.
|
||||
* Since this function registers a VF with the vmkernel's device layer,
|
||||
* all restrictions associated with device registration apply.
|
||||
*
|
||||
* \note Before this call returns, the vmkernel's device layer may attach
|
||||
* the VF to a driver.
|
||||
*
|
||||
* \param[in] vf PCI device handle of the VF to be registered.
|
||||
* \param[in] pf PCI device handle of the parent PF.
|
||||
* \param[in] pfDriverHandle PF driver handle.
|
||||
* \param[in] vfDevOps Device operations associated with a registered VF.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM VF device handle is invalid.
|
||||
* \retval VMK_BAD_PARAM PF device handle is invalid.
|
||||
* \retval VMK_FAILURE VF registration failed.
|
||||
*
|
||||
************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PCIRegisterVF(vmk_PCIDevice vf,
|
||||
vmk_PCIDevice pf,
|
||||
vmk_Driver pfDriverHandle,
|
||||
vmk_PCIVFDeviceOps *vfDevOps);
|
||||
|
||||
/*
|
||||
************************************************************************
|
||||
* vmk_PCIUnregisterVF -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Unregister a virtual function from the vmkernel's device layer.
|
||||
*
|
||||
* \note Since this function unregisters a virtual function (VF) with the
|
||||
* vmkernel's device layer, all restrictions associated with device
|
||||
* unregistration apply (unregistration of the VF must be done
|
||||
* by the physical function driver from the vmk_DeviceRemove function in the
|
||||
* vmk_DeviceOps passed during VF registration).
|
||||
*
|
||||
* \param[in] vf PCI device handle of the VF to be unregistered.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM VF device handle is invalid.
|
||||
* \retval VMK_FAILURE VF unregistration failed.
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PCIUnregisterVF(vmk_PCIDevice vf);
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
* vmk_PCISetVFPrivateData -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Associate private data with a virtual function.
|
||||
*
|
||||
* Associates a pointer to the given user-defined private data with the
|
||||
* given virtual function (VF). The pointer may retrieved via the
|
||||
* function vmk_PCIGetVFPrivateData(). This provides a mechanism by which
|
||||
* vmkernel components, typically a PF driver and a VF driver, can exchange
|
||||
* private data.
|
||||
*
|
||||
* \param[in] vf PCI device handle of the VF.
|
||||
* \param[in] privateData User-defined private data.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM VF device handle is invalid.
|
||||
*
|
||||
************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PCISetVFPrivateData(vmk_PCIDevice vf,
|
||||
vmk_AddrCookie privateData);
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
* vmk_PCIGetVFPrivateData -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Retrieve private data associated with a virtual function.
|
||||
*
|
||||
* Retrieves a pointer to the user-defined private data associated with
|
||||
* the given virtual function (VF). See the description of
|
||||
* vmk_PCISetVFPrivateData() for further details.
|
||||
*
|
||||
* \param[in] vf PCI device handle of the VF.
|
||||
* \param[out] privateData User-defined private data.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM VF device handle is invalid.
|
||||
* \retval VMK_BAD_PARAM privateData pointer is NULL.
|
||||
*
|
||||
************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PCIGetVFPrivateData(vmk_PCIDevice vf,
|
||||
vmk_AddrCookie *privateData);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PCIEnablePME -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Enable PME# generation.
|
||||
*
|
||||
* Enable PME# generation if the device is capable of asserting
|
||||
* the PME# signal from any of the power states.
|
||||
*
|
||||
* \param[in] moduleID Module requesting the operation.
|
||||
* \param[in] device PCI device handle.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM Module ID is invalid.
|
||||
* \retval VMK_BAD_PARAM Device handle is NULL/invalid.
|
||||
* \retval VMK_NO_PERMISSION Device is not owned by module.
|
||||
* \retval VMK_NOT_SUPPORTED Device has no PM capability.
|
||||
* \retval VMK_NOT_SUPPORTED Device doesn't support PME# generation
|
||||
* from any power state.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PCIEnablePME(vmk_ModuleID moduleID,
|
||||
vmk_PCIDevice device);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_PCIDisablePME -- */ /**
|
||||
*
|
||||
* \ingroup PCI
|
||||
* \brief Disable PME# generation.
|
||||
*
|
||||
* Disable PME# generation if the device is capable of asserting
|
||||
* the PME# signal from any of the power states.
|
||||
*
|
||||
* \param[in] moduleID Module requesting the operation.
|
||||
* \param[in] device PCI device handle.
|
||||
*
|
||||
* \retval VMK_BAD_PARAM Module ID is invalid.
|
||||
* \retval VMK_BAD_PARAM Device handle is NULL/invalid.
|
||||
* \retval VMK_NO_PERMISSION Device is not owned by module.
|
||||
* \retval VMK_NOT_SUPPORTED Device has no PM capability.
|
||||
* \retval VMK_NOT_SUPPORTED Device doesn't support PME# generation
|
||||
* from any power state.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PCIDisablePME(vmk_ModuleID moduleID,
|
||||
vmk_PCIDevice device);
|
||||
|
||||
#endif /* _VMKAPI_PCI_H_ */
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -42,7 +42,7 @@ typedef enum vmk_PCIInterruptType {
|
|||
/**
|
||||
* \brief Opaque PCI device handle
|
||||
*/
|
||||
typedef struct vmk_PCIDeviceInt *vmk_PCIDevice;
|
||||
typedef struct vmkPCIDevice *vmk_PCIDevice;
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* PSA */ /**
|
||||
* \addtogroup Device
|
||||
* @{
|
||||
* \defgroup PSA PSA Driver Interfaces
|
||||
* @{
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _VMKAPI_PSA_H_
|
||||
#define _VMKAPI_PSA_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 */
|
||||
|
||||
|
||||
/** \brief PSA Device Identifier */
|
||||
#define VMK_SCSI_PSA_DRIVER_BUS_ID "com.vmware.HBAPort"
|
||||
/** \brief PSA VPORT Device Identifier */
|
||||
#define VMK_SCSI_PSA_DRIVER_VPORT_BUS_ID "com.vmware.Virtual_HBAPort"
|
||||
|
||||
#endif /* _VMKAPI_PSA_H_ */
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -0,0 +1,191 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2008 - 2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
* Please consult with the VMKernel hardware and core teams before making any
|
||||
* binary incompatible changes to this file!
|
||||
*/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* Vector */ /**
|
||||
* \addtogroup Device
|
||||
* @{
|
||||
* \defgroup Vector Interrupt Interfaces
|
||||
* @{
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _VMKAPI_VECTOR_H_
|
||||
#define _VMKAPI_VECTOR_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 */
|
||||
|
||||
/** \brief Interrupt is an entropy source.
|
||||
*
|
||||
* Set this if device interrupts contributes to entropy pool.
|
||||
*/
|
||||
#define VMK_INTR_ATTRS_ENTROPY_SOURCE (1 << 0)
|
||||
|
||||
/**
|
||||
* \brief Properties for registering the interrupt.
|
||||
*/
|
||||
typedef struct vmk_IntrProps {
|
||||
/** \brief Device registering the interrupt. */
|
||||
vmk_Device device;
|
||||
/** \brief Name of the device registering the interrupt. */
|
||||
vmk_Name deviceName;
|
||||
/** \brief Interrupt acknowledging function */
|
||||
vmk_IntrAcknowledge acknowledgeInterrupt;
|
||||
/** \brief Interrupt handler function. */
|
||||
vmk_IntrHandler handler;
|
||||
/** \brief Interrupt handler client data. */
|
||||
void *handlerData;
|
||||
/** \brief Interrupt attributes.
|
||||
*
|
||||
* Interrupt attributes can be used to specify special attributes
|
||||
* for a interrupt.
|
||||
*/
|
||||
vmk_uint64 attrs;
|
||||
} vmk_IntrProps;
|
||||
|
||||
/** \brief Function to invoke with interrupts disabled. */
|
||||
typedef void (*vmk_IntrDisabledFunc)(vmk_AddrCookie data);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_IntrRegister -- */ /**
|
||||
*
|
||||
* \ingroup Vector
|
||||
* \brief Register the interrupt with the system.
|
||||
*
|
||||
* \note Interrupt sharing is implicitly allowed for level-triggered
|
||||
* interrupts.
|
||||
*
|
||||
* \param[in] moduleID Module registering the interrupt
|
||||
* \param[in] intrCookie Interrupt cookie to register
|
||||
* \param[in] props Properties of the interrupt being registered
|
||||
*
|
||||
* \retval VMK_BAD_PARAM props is NULL or mal-formed props
|
||||
* \retval VMK_BAD_PARAM intrCookie is not valid
|
||||
* \retval VMK_BAD_PARAM Null props->handlerData is specified for
|
||||
* shared interrupt.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_IntrRegister(vmk_ModuleID moduleID,
|
||||
vmk_IntrCookie intrCookie,
|
||||
vmk_IntrProps *props);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_IntrUnregister -- */ /**
|
||||
*
|
||||
* \ingroup Vector
|
||||
* \brief Unregister a previously registered interrupt.
|
||||
*
|
||||
* \param[in] moduleID Module that registered interrupt before
|
||||
* \param[in] intrCookie Interrupt to unregister
|
||||
* \param[in] handlerData Interrupt handler data that was used while
|
||||
* registering the interrupt
|
||||
*
|
||||
* \retval VMK_BAD_PARAM moduleID is not valid.
|
||||
* \retval VMK_BAD_PARAM intrCookie is not valid.
|
||||
* \retval VMK_BAD_PARAM If handlerData is NULL and the interrupt is
|
||||
* shared.
|
||||
* \retval VMK_FAILURE handlerData doesn't match with what's
|
||||
* provided with vmk_IntrRegister().
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_IntrUnregister(vmk_ModuleID moduleID,
|
||||
vmk_IntrCookie intrCookie,
|
||||
void *handlerData);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_IntrEnable -- */ /**
|
||||
*
|
||||
* \ingroup Vector
|
||||
* \brief Start interrupt delivery. Kernel starts calling interrupt
|
||||
* handlers registered for this interrupt.
|
||||
*
|
||||
* \note The interrupt is unmasked if needed.
|
||||
*
|
||||
* \param[in] intrCookie Interrupt that has to be started.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_IntrEnable(vmk_IntrCookie intrCookie);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_IntrDisable -- */ /**
|
||||
*
|
||||
* \ingroup Vector
|
||||
* \brief Stops interrupt delivery.
|
||||
*
|
||||
* \note The interrupt is masked if there are no registered handlers
|
||||
* for this interrupt.
|
||||
*
|
||||
* \warning This API should not be used for indefinite periods for
|
||||
* shared interrupts as this will block interrupts for other
|
||||
* devices that may share the same interrupt line.
|
||||
*
|
||||
* \param[in] intrCookie Interrupt that has to be stopped.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_IntrDisable(vmk_IntrCookie intrCookie);
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_IntrSync -- */ /**
|
||||
*
|
||||
* \ingroup Vector
|
||||
* \brief Blocks, waiting till interrupt is inactive on all CPUs.
|
||||
*
|
||||
* \param[in] intrCookie Interrupt to synchronize.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus vmk_IntrSync(vmk_IntrCookie intrCookie);
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* vmk_IntrWithAllDisabledInvoke -- */ /**
|
||||
*
|
||||
* \ingroup Vector
|
||||
* \brief Invokes a function with all interrupts disabled.
|
||||
*
|
||||
* \warning The function invoked is not allowed to take more than 5us.
|
||||
*
|
||||
* \param[in] moduleID Module implementing function to invoke.
|
||||
* \param[in] func Function to invoke
|
||||
* \param[in] data Data to pass to function
|
||||
*
|
||||
* \retval VMK_BAD_PARAM moduleID is invalid
|
||||
* \retval VMK_BAD_PARAM func is invalid
|
||||
* \retval VMK_OK func was invoked
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
VMK_ReturnStatus vmk_IntrWithAllDisabledInvoke(vmk_ModuleID moduleID,
|
||||
vmk_IntrDisabledFunc func,
|
||||
vmk_AddrCookie data);
|
||||
|
||||
#endif /* _VMKAPI_VECTOR_H_ */
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2010 VMware, Inc. All rights reserved.
|
||||
* Copyright 2010 - 2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
|
@ -26,6 +26,15 @@
|
|||
#endif
|
||||
/** \endcond never */
|
||||
|
||||
/**
|
||||
* \brief Opaque handle to Interrupt.
|
||||
*/
|
||||
typedef vmk_uint32 vmk_IntrCookie;
|
||||
|
||||
/**
|
||||
* \brief Invalid interrupt.
|
||||
*/
|
||||
#define VMK_INVALID_INTRCOOKIE ((vmk_IntrCookie)~0)
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
|
@ -45,7 +54,61 @@
|
|||
*/
|
||||
|
||||
typedef void (*vmk_InterruptHandler)(void *clientData,
|
||||
vmk_uint32 vector);
|
||||
vmk_IntrCookie intrCookie);
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_IntrHandler -- */ /**
|
||||
*
|
||||
* \brief Interrupt callback function.
|
||||
*
|
||||
* \note Callback is allowed to block
|
||||
*
|
||||
* \param[in] handlerData Callback argument specified while adding
|
||||
* the handler.
|
||||
* \param[in] intrCookie Interrupt cookie associated with the interrupt.
|
||||
*
|
||||
* \retval None
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
typedef void (*vmk_IntrHandler)(void *handlerData,
|
||||
vmk_IntrCookie intrCookie);
|
||||
|
||||
/*
|
||||
******************************************************************************
|
||||
* vmk_IntrAcknowledge -- */ /**
|
||||
*
|
||||
* \brief Callback function for device drivers to acknowledge an interrupt
|
||||
*
|
||||
* This callback is called synchronously when an interrupt fires to do device
|
||||
* specific interrupt acknowledgement. The handler is expected to acknowledge
|
||||
* the interrupt with the device for example through device register writes but
|
||||
* nothing more. All other interrupt work should be done in the interrupt
|
||||
* handler which will be called in a world context. The vmkernel will enforce a
|
||||
* very short execution time of 5us for this callback.
|
||||
*
|
||||
* \note Callback is not allowed to block
|
||||
*
|
||||
* \param[in] handlerData Callback argument specified while adding
|
||||
* the handler.
|
||||
* \param[in] intrCookie Interrupt cookie associated with the interrupt.
|
||||
*
|
||||
* \retval VMK_OK Interrupt has been acknowledged and handler
|
||||
* should be called.
|
||||
* \retval VMK_IGNORE Interrupt was for this device and has been
|
||||
* acknowledged, but handler is not needed and
|
||||
* should not be called.
|
||||
* \retval VMK_NOT_THIS_DEVICE Interrupt was not for this device and has not
|
||||
* been acknowledged; handler should not be called.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
typedef VMK_ReturnStatus (*vmk_IntrAcknowledge)(void *handlerData,
|
||||
vmk_IntrCookie intrCookie);
|
||||
|
||||
|
||||
#endif
|
||||
/** @} */
|
||||
|
|
|
@ -738,12 +738,17 @@ typedef enum vmk_DVFilterPropertyOpsFlags {
|
|||
* \param[in] filter Handle to DVFilter instance data
|
||||
* \param[in] propName Property name
|
||||
* \param[in] propVal Property value
|
||||
* \param[in] propLen Length of the property value in bytes
|
||||
* \param[in] propLen Length of the property value in bytes
|
||||
* \param[in] flags Must be VMK_DVFILTER_CLIENT_OPS_NONE
|
||||
* Reserved for future use
|
||||
*
|
||||
* \retval VMK_OK DVFilter accepts value change of the
|
||||
* property on the instance
|
||||
* \retval VMK_NOT_READY DVFilter cannot accept value change of the
|
||||
* property on the instance. Likely due to
|
||||
* temporarily invalid filter. Write will be
|
||||
* called again with same data after filter
|
||||
* is established.
|
||||
* \retval VMK_FAILURE DVFilter does not accept the value change
|
||||
* of the property on the instance
|
||||
***********************************************************************
|
||||
|
@ -875,6 +880,8 @@ typedef struct vmk_DVFilterPropertyOps {
|
|||
* \ingroup DVFilter
|
||||
* \brief Register a DVFilter fast path agent with the network stack.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function may block.
|
||||
*
|
||||
* \param[in] name Human readable name of the agent.
|
||||
|
@ -920,6 +927,8 @@ VMK_ReturnStatus vmk_DVFilterRegisterFastPath(
|
|||
* \brief Unregister a DVFilter fast path agent previously registered
|
||||
* by vmk_DVFilterRegisterFastPath.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function may block.
|
||||
*
|
||||
* \param[in] fastPathHandle Handle to the VMkernel fast path agent.
|
||||
|
@ -940,6 +949,8 @@ VMK_ReturnStatus vmk_DVFilterUnregisterFastPath(
|
|||
* \ingroup DVFilter
|
||||
* \brief Associate a filter with the specified slow path agent.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* Once the association is established, packets can be forwarded to
|
||||
|
@ -992,6 +1003,8 @@ vmk_DVFilterSetSlowPath(
|
|||
* \ingroup DVFilter
|
||||
* \brief Dissociate a filter from its slow path agent.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* This function has no effect if the filter has no associated slow
|
||||
|
@ -1028,6 +1041,8 @@ vmk_DVFilterClearSlowPath(
|
|||
* \ingroup DVFilter
|
||||
* \brief Allocate metadata for this packet.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* The allocated metadata buffer can be used to store data
|
||||
|
@ -1074,6 +1089,8 @@ VMK_ReturnStatus vmk_DVFilterPktAllocMetadata(
|
|||
* \ingroup DVFilter
|
||||
* \brief Release metadata for this packet.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* Releases the metadata of this packet. Afterwards, the scope of
|
||||
|
@ -1096,6 +1113,8 @@ void vmk_DVFilterPktReleaseMetadata(
|
|||
* \ingroup DVFilter
|
||||
* \brief Get pointer to metadata of this packet.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* Gets the address of the metadata associated with this packet,
|
||||
|
@ -1123,6 +1142,8 @@ vmk_VA vmk_DVFilterPktGetMetadata(
|
|||
* \brief Fault specified packets to the slow path agent associated
|
||||
* with the filter.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \note Unless the VMK_DVFILTER_FAULTING_COPY flag is used, the
|
||||
|
@ -1157,6 +1178,8 @@ VMK_ReturnStatus vmk_DVFilterFaultPackets(
|
|||
* \ingroup DVFilter
|
||||
* \brief Inject packets in a filter.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* Used to inject new packets, or resume processing of packets
|
||||
|
@ -1215,6 +1238,8 @@ VMK_ReturnStatus vmk_DVFilterIssuePackets(
|
|||
* \ingroup DVFilter
|
||||
* \brief Query the human readable name of the DVFilter.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] filter Handle to the VMkernel filter object
|
||||
|
@ -1240,6 +1265,8 @@ VMK_ReturnStatus vmk_DVFilterGetName(
|
|||
* \ingroup DVFilter
|
||||
* \brief Query the VM UUID of the VM the DVFilter is attached to.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \note This function may fail with VMK_INVALID_WORLD in the
|
||||
|
@ -1273,6 +1300,8 @@ VMK_ReturnStatus vmk_DVFilterGetVMUUID(
|
|||
* \ingroup DVFilter
|
||||
* \brief Query a configuration parameter value of the DVFilter.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* These parameters may change at any time if the fastpath op
|
||||
|
@ -1309,6 +1338,8 @@ VMK_ReturnStatus vmk_DVFilterGetConfigParameter(
|
|||
* \ingroup DVFilter
|
||||
* \brief Get the failure policy the user configured for this filter.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] filter Handle to the VMkernel filter object.
|
||||
|
@ -1332,6 +1363,8 @@ VMK_ReturnStatus vmk_DVFilterGetFailurePolicy(
|
|||
* \ingroup DVFilter
|
||||
* \brief Get the MTU the switch has configured for this filter
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* Value of *mtu is not defined in case the function was not successful.
|
||||
|
@ -1366,6 +1399,8 @@ VMK_ReturnStatus vmk_DVFilterGetSwitchMTU(
|
|||
* \ingroup DVFilter
|
||||
* \brief Get the type of the filter's end-point.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* The filter end-point might be a virtual nic of a VM, a VMkernel
|
||||
|
@ -1394,6 +1429,8 @@ VMK_ReturnStatus vmk_DVFilterGetEndPointType(
|
|||
* \ingroup DVFilter
|
||||
* \brief Get the portID that the filter is attached to.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \param[in] filter Handle to the VMkernel filter object.
|
||||
|
@ -1416,6 +1453,8 @@ VMK_ReturnStatus vmk_DVFilterGetPortID(
|
|||
* \ingroup DVFilter
|
||||
* \brief Get the index of the vNic this filter is attached to.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* This function is only supported for VM endpoints.
|
||||
|
@ -1442,6 +1481,8 @@ VMK_ReturnStatus vmk_DVFilterGetVnicIndex(
|
|||
* \ingroup DVFilter
|
||||
* \brief Set the minimum mapped packet length required by this filter.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* The function requests new packets to have a specific
|
||||
|
@ -1480,6 +1521,8 @@ vmk_DVFilterSetMinPktMappedLen(
|
|||
* \brief Send an ioctl request associated with a particular filter to
|
||||
* the slow path.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* Send an ioctl request to the slow path agent associated with the
|
||||
|
@ -1537,6 +1580,8 @@ VMK_ReturnStatus vmk_DVFilterSendFilterIoctlRequest(
|
|||
* \ingroup DVFilter
|
||||
* \brief Send an ioctl reply in filter context to the guest appliance.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* Send an ioctl reply to the slow path agent associated with the
|
||||
|
@ -1575,6 +1620,8 @@ VMK_ReturnStatus vmk_DVFilterSendFilterIoctlReply(
|
|||
* \ingroup DVFilter
|
||||
* \brief Send an ioctl request to a slow path agent.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* Send an ioctl request to the slow path agent. The provided
|
||||
|
@ -1630,6 +1677,8 @@ VMK_ReturnStatus vmk_DVFilterSendSlowPathIoctlRequest(
|
|||
* \ingroup DVFilter
|
||||
* \brief Send an ioctl reply to a slow path agent.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* It is acceptable to send a slow path reply with a zero length.
|
||||
|
@ -1667,6 +1716,8 @@ VMK_ReturnStatus vmk_DVFilterSendSlowPathIoctlReply(
|
|||
* \ingroup DVFilter
|
||||
* \brief Restore slow path state in the guest appliance
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* The slow path's state is sent to the slow path agent. The provided
|
||||
|
@ -1717,6 +1768,8 @@ VMK_ReturnStatus vmk_DVFilterRestoreSlowPathState(
|
|||
* \ingroup DVFilter
|
||||
* \brief Retrieve slow path state from the guest appliance.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* The slow path agent is asked to provide its state. The provided
|
||||
|
@ -1763,6 +1816,8 @@ VMK_ReturnStatus vmk_DVFilterRetrieveSlowPathState(
|
|||
* \ingroup DVFilter
|
||||
* \brief Set the src port to the port this filter is installed on.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* Set the packet source port identification field to the port
|
||||
|
@ -1811,6 +1866,8 @@ VMK_ReturnStatus vmk_DVFilterPktSetSourcePort(
|
|||
* \ingroup DVFilter
|
||||
* \brief Allocate a packet tag for the indicated fast path agent.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* DVFilter provides for tagging pkts as an aid in
|
||||
|
@ -1843,6 +1900,8 @@ VMK_ReturnStatus vmk_DVFilterAllocPktTag(
|
|||
* \ingroup DVFilter
|
||||
* \brief Free all the packet tags allocated by the supplied agent.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* One or more pkt tags, each one bit, acquired from
|
||||
|
@ -1863,6 +1922,8 @@ void vmk_DVFilterFreePktTags(
|
|||
* \ingroup DVFilter
|
||||
* \brief Tag the packet with the specified tag.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* \pre The tag must belong to the supplied fast path agent.
|
||||
|
@ -1913,6 +1974,8 @@ VMK_ReturnStatus vmk_DVFilterPktSetTags(
|
|||
* \ingroup DVFilter
|
||||
* \brief Clear a fast path's tags from a packet.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* Clear the tag or tag bits of the pkt with respect to the
|
||||
|
@ -1958,6 +2021,8 @@ VMK_ReturnStatus vmk_DVFilterPktClearTags(
|
|||
* \ingroup DVFilter
|
||||
* \brief Query the values of one or more bits from the pkt tag.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* \note This function will not block.
|
||||
*
|
||||
* Query the tag bits set on a packet.
|
||||
|
@ -1978,6 +2043,7 @@ VMK_ReturnStatus vmk_DVFilterPktClearTags(
|
|||
* \retval VMK_NOT_FOUND fastPathHandle parameter invalid.
|
||||
* \retval VMK_FAILURE getMask contains a bit not allocated for
|
||||
* this agent.
|
||||
* \retval VMK_BAD_PARAM setMask is NULL
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
@ -1994,6 +2060,8 @@ VMK_ReturnStatus vmk_DVFilterGetPktTags(
|
|||
*
|
||||
* \brief Register property operations for a DVFilter
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* DVFilter implementation calls this interface to register a property
|
||||
* handler for a property of a given name. The property name must
|
||||
* start with the agent name pass to vmk_DVFilterRegisterFastPath().
|
||||
|
@ -2026,6 +2094,8 @@ VMK_ReturnStatus vmk_DVFilterPropertyRegister(
|
|||
*
|
||||
* \brief Unregister a DVFilter Client
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* The handle is the token obtained from vmk_DVFilterPropertyRegister().
|
||||
*
|
||||
* \param[in] handle Handle for DVFilter property registration
|
||||
|
@ -2045,6 +2115,8 @@ VMK_ReturnStatus vmk_DVFilterPropertyUnregister(
|
|||
*
|
||||
* \brief Increment a DVFilter client stat.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* Updates the DVFilter's client stat of the specified type in the
|
||||
* specified direction.
|
||||
*
|
||||
|
@ -2073,6 +2145,8 @@ VMK_ReturnStatus vmk_DVFilterStatInc(
|
|||
*
|
||||
* \brief Get the current value of a DVFilter client stat.
|
||||
*
|
||||
* \nativedriversdisallowed
|
||||
*
|
||||
* Fetches the DVFilter's client stat of the specified type in the
|
||||
* specified direction.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,653 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* BitVector */ /**
|
||||
*
|
||||
* \addtogroup Lib
|
||||
* @{
|
||||
* \defgroup vmk_BitVector Bit Vector Manipulation
|
||||
*
|
||||
* Utility interfaces for managing a Bit Vector.
|
||||
|
||||
* \par Example - Using VMK_BITVECTOR_ITERATE or VMK_BITVECTOR_ITERATE_AND_CLEAR
|
||||
* and VMK_BITVECTOR_ENDITERATE
|
||||
*
|
||||
* \code
|
||||
* {
|
||||
* vmk_uint32 n;
|
||||
* VMK_BITVECTOR_ITERATE(_bv,n) {
|
||||
* printf("%d is in set\n",n);
|
||||
* }
|
||||
* VMK_BITVECTOR_ENDITERATE()
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* @{
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _VMKAPI_BITVECTOR_H_
|
||||
#define _VMKAPI_BITVECTOR_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 */
|
||||
|
||||
|
||||
/**
|
||||
* \brief Incomplete Abstract Data type allocated to be larger than
|
||||
* sizeof(vmk_BitVector). Should only be allocated by
|
||||
* vmk_BitVectorAlloc.
|
||||
* Clients should only use the returned pointer.
|
||||
*/
|
||||
typedef struct vmk_BitVector {
|
||||
vmk_uint32 n;
|
||||
vmk_uint32 nwords;
|
||||
vmk_uint32 vector[1];
|
||||
} vmk_BitVector;
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorSize -- */ /**
|
||||
*
|
||||
* \brief Size of vmk_BitVector for a given number of bits
|
||||
*
|
||||
* \param[in] n Number of bits to size for
|
||||
*
|
||||
* \retval size calculation of a vmk_BitVector
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
#define vmk_BitVectorSize(n) \
|
||||
(sizeof(vmk_uint32) /* n */ + \
|
||||
sizeof(vmk_uint32) /* nwords */ + \
|
||||
((n + 31) / 32) * sizeof(vmk_uint32)) /* n bits rounded up to words */
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorAllocWithTimeout -- */ /**
|
||||
*
|
||||
* \brief Allocate a bitvector with timeout
|
||||
*
|
||||
* \param[in] heap vmk_HeapID to allocate the vmk_BitVector from
|
||||
* \param[in] n Total number of bits to allocate for
|
||||
* \param[in] timeoutMs vmk_BitVector to set a bit
|
||||
*
|
||||
* \note If timeoutMS is not 0 then the allocation may block if the
|
||||
* heap needs to expand to accomodate the request.
|
||||
*
|
||||
* \retval vmk_BitVector pointer or NULL.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
vmk_BitVector* vmk_BitVectorAllocWithTimeout(vmk_HeapID heap,
|
||||
vmk_uint32 n,
|
||||
vmk_uint32 timeoutMs);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorAlloc -- */ /**
|
||||
*
|
||||
* \brief Allocate a bitvector
|
||||
*
|
||||
* \param[in] heap vmk_HeapID to allocate the vmk_BitVector from
|
||||
* \param[in] n Total number of bits to allocate for
|
||||
*
|
||||
* \retval vmk_BitVector pointer or NULL.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
vmk_BitVector* vmk_BitVectorAlloc(vmk_HeapID heap,
|
||||
vmk_uint32 n);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorDuplicate -- */ /**
|
||||
*
|
||||
* \brief Allocate a vmk_BitVector and initialise it from another vmk_BitVector
|
||||
*
|
||||
* \param[in] heap vmk_HeapID to allocate the vmk_BitVector from
|
||||
* \param[in] src Source vmk_BitVector to copy into the new vmk_BitVector
|
||||
*
|
||||
* \retval new vmk_BitVector pointer
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
vmk_BitVector* vmk_BitVectorDuplicate(vmk_HeapID heap,
|
||||
const vmk_BitVector *src);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorFree -- */ /**
|
||||
*
|
||||
* \brief Free a vmk_BitVector
|
||||
*
|
||||
* \param[in] heap vmk_HeapID to free the vmk_BitVector to
|
||||
* \param[in] bv vmk_BitVector to free
|
||||
*
|
||||
* \retval If the previous value of this bit was zero then zero is returned
|
||||
* otherwise non-zero is returned.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
void vmk_BitVectorFree(vmk_HeapID heap,
|
||||
vmk_BitVector *bv);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorSet -- */ /**
|
||||
*
|
||||
* \brief Set a bit in a vmk_BitVector
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to set a bit
|
||||
* \param[in] n Bit to set
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
static inline void
|
||||
vmk_BitVectorSet(vmk_BitVector *bv,
|
||||
vmk_uint32 n)
|
||||
{
|
||||
VMK_ASSERT(n < bv->n);
|
||||
asm volatile("btsl %1, (%0)"
|
||||
:: "r" (bv->vector), "r" (n)
|
||||
: "cc", "memory");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorClear -- */ /**
|
||||
*
|
||||
* \brief Clear a bit in a vmk_BitVector
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to clear a bit
|
||||
* \param[in] n Bit to set
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
static inline void
|
||||
vmk_BitVectorClear(vmk_BitVector *bv,
|
||||
vmk_uint32 n)
|
||||
{
|
||||
VMK_ASSERT(n < bv->n);
|
||||
asm volatile("btrl %1, (%0)"
|
||||
:: "r" (bv->vector), "r" (n)
|
||||
: "cc", "memory");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorTest -- */ /**
|
||||
*
|
||||
* \brief Test if a bit in a vmk_BitVector is set
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to check
|
||||
* \param[in] n Bit to check
|
||||
*
|
||||
* \retval If this bit is set, non-zero is returned.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
static inline int
|
||||
vmk_BitVectorTest(const vmk_BitVector *bv,
|
||||
vmk_uint32 n)
|
||||
{
|
||||
VMK_ASSERT(n < bv->n);
|
||||
{
|
||||
vmk_uint32 tmp;
|
||||
|
||||
asm("btl %2, (%1); "
|
||||
"sbbl %0, %0"
|
||||
: "=r" (tmp)
|
||||
: "r" (bv->vector), "r" (n)
|
||||
: "cc");
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorAtomicTestAndSet -- */ /**
|
||||
*
|
||||
* \brief Atomically read bit n and set it
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to set a bit
|
||||
* \param[in] n Bit to set
|
||||
*
|
||||
* \retval If the previous value of this bit was zero then zero is returned
|
||||
* otherwise non-zero is returned.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
static inline int
|
||||
vmk_BitVectorAtomicTestAndSet(const vmk_BitVector *bv,
|
||||
vmk_uint32 n)
|
||||
{
|
||||
VMK_ASSERT(n < bv->n);
|
||||
{
|
||||
vmk_uint32 tmp;
|
||||
|
||||
asm volatile("lock; btsl %2, (%1); "
|
||||
"sbbl %0, %0"
|
||||
: "=r" (tmp)
|
||||
: "r" (bv->vector), "r" (n)
|
||||
: "cc", "memory");
|
||||
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorAtomicTestAndClear -- */ /**
|
||||
*
|
||||
* \brief Atomically read bit n and clear it
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to operate on
|
||||
* \param[in] n Bit to clear
|
||||
*
|
||||
* \retval If the previous value of this bit was zero then zero is returned
|
||||
* otherwise non-zero is returned.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
static inline int
|
||||
vmk_BitVectorAtomicTestAndClear(const vmk_BitVector *bv,
|
||||
vmk_uint32 n)
|
||||
{
|
||||
VMK_ASSERT(n < bv->n);
|
||||
{
|
||||
vmk_uint32 tmp;
|
||||
|
||||
asm volatile("lock; btrl %2, (%1); "
|
||||
"sbbl %0, %0"
|
||||
: "=r" (tmp)
|
||||
: "r" (bv->vector), "r" (n)
|
||||
: "cc", "memory");
|
||||
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorZap -- */ /**
|
||||
*
|
||||
* \brief Removes all entries from the set
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to zap
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
static inline void
|
||||
vmk_BitVectorZap(vmk_BitVector *bv)
|
||||
{
|
||||
vmk_Memset(bv->vector, 0, bv->nwords * sizeof(bv->vector[0]));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorFill -- */ /**
|
||||
*
|
||||
* \brief Set all bits in a vmk_BitVector
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to operate on
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
static inline void
|
||||
vmk_BitVectorFill(vmk_BitVector *bv)
|
||||
{
|
||||
vmk_Memset(bv->vector, 0xff, bv->nwords * sizeof(bv->vector[0]));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorGetRef -- */ /**
|
||||
*
|
||||
* \brief Get a pointer to a particular byte in vmk_BitVector
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to look inside
|
||||
* \param[in] start Starting byte return
|
||||
* \param[in] nbytes Number of bytes expected to be used
|
||||
*
|
||||
* \note nbytes is only checked in debug builds
|
||||
*
|
||||
* \retval Pointer to a vmk_unit8.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
static inline vmk_uint8 *
|
||||
vmk_BitVectorGetRef(const vmk_BitVector *bv,
|
||||
vmk_uint32 start,
|
||||
vmk_uint32 nbytes)
|
||||
{
|
||||
vmk_uint8 *ptr = (vmk_uint8 *)bv->vector;
|
||||
(void)nbytes;
|
||||
VMK_ASSERT((start + nbytes) <= bv->nwords * sizeof(bv->vector[0]));
|
||||
return &ptr[start];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorNumBitsSet -- */ /**
|
||||
*
|
||||
* \brief Return the number of set bits in this vmk_BitVector
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to count
|
||||
*
|
||||
* \retval number of bits set in this vmk_BitVector
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
vmk_uint32 vmk_BitVectorNumBitsSet(const vmk_BitVector *bv);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorIsZero -- */ /**
|
||||
*
|
||||
* \brief Check if a vmk_BitVector has no bits set
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to check
|
||||
*
|
||||
* \retval non-zero if any bit is set in the vmk_BitVector
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
vmk_uint32 vmk_BitVectorIsZero(const vmk_BitVector *bv);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorNextBit -- */ /**
|
||||
*
|
||||
* \brief Find next bit set in a vmk_BitVector
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to check
|
||||
* \param[in] start Bit to start searching from
|
||||
* \param[in] state VMK_TRUE if looking for set bits
|
||||
* \param[out] pos Filled in with index of the next bit
|
||||
*
|
||||
* \retval VMK_TRUE if a bit was found
|
||||
*
|
||||
* \note The value of "pos" must not be used if VMK_FALSE is returned.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
vmk_Bool vmk_BitVectorNextBit(const vmk_BitVector *bv,
|
||||
vmk_uint32 start,
|
||||
vmk_Bool state,
|
||||
vmk_uint32 *pos);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorPrevBit -- */ /**
|
||||
*
|
||||
* \brief Find previous bit set in a vmk_BitVector, searching backwards
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to check
|
||||
* \param[in] start Bit to start searching from
|
||||
* \param[in] state VMK_TRUE if looking for set bits
|
||||
* \param[out] pos Filled in with index of the next bit
|
||||
*
|
||||
* \retval VMK_TRUE if a bit was found
|
||||
*
|
||||
* \note BitVectors are implemented as an array of vmk_uint32 which affects
|
||||
* byte ordering on little endian architectures, such as x86.
|
||||
*
|
||||
* \note The value of "pos" must not be used if VMK_FALSE is returned.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
vmk_Bool vmk_BitVectorPrevBit(const vmk_BitVector *bv,
|
||||
vmk_uint32 start,
|
||||
vmk_Bool state,
|
||||
vmk_uint32 *pos);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorGetExtent -- */ /**
|
||||
*
|
||||
* \brief Find sequence of bits in a vmk_BitVector
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to check
|
||||
* \param[in] start Bit to start searching from
|
||||
* \param[out] set Is start bit set or not
|
||||
* \param[out] length Filled in with index of the next bit
|
||||
*
|
||||
* \note BitVectors are implemented as an array of vmk_uint32 which affects
|
||||
* byte ordering on little endian architectures, such as x86.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
void vmk_BitVectorGetExtent(const vmk_BitVector *bv,
|
||||
vmk_uint32 start,
|
||||
vmk_Bool *set,
|
||||
vmk_uint32 *length);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorNextExtent -- */ /**
|
||||
*
|
||||
* \brief Find next sequence of bits in a vmk_BitVector
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to check
|
||||
* \param[in] startSearch Bit to start searching from
|
||||
* \param[in] set VMK_TRUE if looking for set bits
|
||||
* \param[out] startRun Start index of extend found
|
||||
* \param[out] length Length of extent found
|
||||
*
|
||||
* \retval VMK_TRUE if a bit was found
|
||||
*
|
||||
* \note BitVectors are implemented as an array of vmk_uint32 which affects
|
||||
* byte ordering on little endian architectures, such as x86.
|
||||
*
|
||||
* \note The values of "startRun" and "length" must not be used if VMK_FALSE
|
||||
* is returned.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
vmk_Bool vmk_BitVectorNextExtent(const vmk_BitVector *bv,
|
||||
vmk_uint32 startSearch,
|
||||
vmk_Bool set,
|
||||
vmk_uint32 *startRun,
|
||||
vmk_uint32 *length);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorSetExtent -- */ /**
|
||||
*
|
||||
* \brief Set an extent of a bitvector to a particular state
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to set a bit
|
||||
* \param[in] startRun Bit to start setting from
|
||||
* \param[in] length Number of bits to set
|
||||
* \param[in] state VMK_TRUE if setting to 1
|
||||
*
|
||||
* \retval If setting to 1, returns a positive count number of bits set,
|
||||
* otherwise returns a negative count of the number of bits set.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
int vmk_BitVectorSetExtent(vmk_BitVector *bv,
|
||||
vmk_uint32 startRun,
|
||||
vmk_uint32 length,
|
||||
vmk_Bool state);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorSetExtentFast -- */ /**
|
||||
*
|
||||
* \brief Set an extent of a bitvector to 1
|
||||
*
|
||||
* \param[in] bv vmk_BitVector to set a bit
|
||||
* \param[in] startRun Bit to start setting from
|
||||
* \param[in] length Number of bits to set
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
void vmk_BitVectorSetExtentFast(vmk_BitVector *bv,
|
||||
vmk_uint32 startRun,
|
||||
vmk_uint32 length);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorMerge -- */ /**
|
||||
*
|
||||
* \brief Merge two sets of vmk_BitVector
|
||||
*
|
||||
* \param[in] src vmk_BitVector merged into dest
|
||||
* \param[in,out] dest vmk_BitVector modified by src
|
||||
*
|
||||
* \retval number of bits merged from src to dest that were not previously set.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
vmk_uint32 vmk_BitVectorMerge(vmk_BitVector *src,
|
||||
vmk_BitVector *dest);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorMergeAtOffset -- */ /**
|
||||
*
|
||||
* \brief Merge two sets of vmk_BitVector from specific offset
|
||||
*
|
||||
* This function merges bits from the start of one vmk_BitVector into another,
|
||||
* starting the merge at a specific offset in the destination vector. Bits set
|
||||
* in the source vector that would go beyond the size of dest are ignored.
|
||||
*
|
||||
* \param[in] src vmk_BitVector merged into dest
|
||||
* \param[in,out] dest vmk_BitVector modified by src
|
||||
* \param[in] offset Bit position to write bits from src into
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
void vmk_BitVectorMergeAtOffset(vmk_BitVector *src,
|
||||
vmk_BitVector *dest,
|
||||
vmk_uint32 offset);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_BitVectorMaxSize -- */ /**
|
||||
*
|
||||
* \brief Returns the maximum number of bits that can be held in a vmk_BitVector
|
||||
*
|
||||
* \retval maximum number of bits that can be held in a vmk_BitVector
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
vmk_uint32 vmk_BitVectorMaxSize(void);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* VMK_BITVECTOR_ITERATE -- */ /**
|
||||
*
|
||||
* \brief Macro to iterate a vmk_BitVector
|
||||
*
|
||||
* \param[in] _bv vmk_BitVector to iterate across
|
||||
* \param[in] _n Variable set to each valid bit each iteration
|
||||
*
|
||||
* \retval If the previous value of this bit was zero then zero is returned
|
||||
* otherwise non-zero is returned.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#define VMK_BITVECTOR_ITERATE(_bv,_n) { \
|
||||
vmk_uint32 _index; \
|
||||
for (_index=0;_index <(_bv)->nwords;_index++) { \
|
||||
vmk_uint32 _off,_vals; \
|
||||
_vals = (_bv)->vector[_index]; \
|
||||
while(_vals) { \
|
||||
__asm ("bsfl %1,%0\n\t" \
|
||||
"btrl %0,%1" \
|
||||
: "=r" (_off), "+g" (_vals) \
|
||||
: : "cc" ); \
|
||||
_n = (_index * 32) + _off; \
|
||||
if (_n >= (_bv)->n) { \
|
||||
break; \
|
||||
} \
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* VMK_BITVECTOR_ITERATE_AND_CLEAR -- */ /**
|
||||
*
|
||||
* \brief Macro to iterate a vmk_BitVector, clearing it as well
|
||||
*
|
||||
* \param[in] _bv vmk_BitVector to iterate across
|
||||
* \param[in] _n Variable set to each valid bit each iteration
|
||||
*
|
||||
* \retval If the previous value of this bit was zero then zero is returned
|
||||
* otherwise non-zero is returned.
|
||||
*
|
||||
* \note The state of the vmk_BitVector during the iteration is undefined
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#define VMK_BITVECTOR_ITERATE_AND_CLEAR(_bv,_n) { \
|
||||
vmk_uint32 _index; \
|
||||
for (_index=0;_index <(_bv)->nwords;_index++) { \
|
||||
vmk_uint32 _off,_vals; \
|
||||
_vals = (_bv)->vector[_index]; \
|
||||
(_bv)->vector[_index] = 0; \
|
||||
while(_vals) { \
|
||||
__asm ("bsfl %1,%0\n\t" \
|
||||
"btrl %0,%1" \
|
||||
: "=r" (_off), "+g" (_vals) \
|
||||
: : "cc"); \
|
||||
_n = (_index * 32) + _off; \
|
||||
if (_n >= (_bv)->n) { \
|
||||
break; \
|
||||
} \
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* VMK_BITVECTOR_ENDITERATE -- */ /**
|
||||
*
|
||||
* \brief Macro to end a iteration zone
|
||||
*
|
||||
* Can be used with either VMK_BITVECTOR_ITERATE() or
|
||||
* VMK_BITVECTOR_ITERATE_AND_CLEAR()
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#define VMK_BITVECTOR_ENDITERATE() }}}
|
||||
|
||||
#endif /* _VMKAPI_BITVECTOR_H_ */
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -192,6 +192,22 @@
|
|||
#define VMK_UNLIKELY(_exp) (_exp)
|
||||
#endif
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* VMK_IS_COMPILE_TIME -- */ /**
|
||||
*
|
||||
* \brief If a given expression is known to be constant at compile-time.
|
||||
*
|
||||
* \note This is used to enable some optimizations when an expression is
|
||||
* known to be constant at compile time, and fall back to a more
|
||||
* generic method when it is not.
|
||||
*
|
||||
* \param[in] _exp Expression that is tested.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
#define VMK_IS_COMPILE_TIME(_exp) __builtin_constant_p(_exp)
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* VMK_PADDED_STRUCT -- */ /**
|
||||
|
|
|
@ -101,6 +101,14 @@
|
|||
#define VMK_UINT64_MAX ((vmk_uint64)VMK_CONST64U(0xffffffffffffffff))
|
||||
|
||||
|
||||
/**
|
||||
* \brief Bits per byte.
|
||||
*/
|
||||
#ifndef VMK_BITS_PER_BYTE
|
||||
#define VMK_BITS_PER_BYTE (8)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _VMKAPI_CONST_H_ */
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
|
|
@ -56,7 +56,7 @@ typedef vmk_uint64 vmk_HashKeyFlags;
|
|||
/** No flags. */
|
||||
#define VMK_HASH_KEY_FLAGS_NONE 0x0
|
||||
|
||||
/**
|
||||
/**
|
||||
* Hash implementation should do a local copy of the key on insertion
|
||||
* and do not assume the memory backing up the key will be persistent.
|
||||
*/
|
||||
|
@ -115,7 +115,7 @@ vmk_HashGetAllocSize(vmk_uint32 nbEntries);
|
|||
*
|
||||
* \note The hash table returned does not come with locking, it is the
|
||||
* caller's responsibility to provide such mechanism.
|
||||
*
|
||||
*
|
||||
* \param[in] moduleID Module ID requesting the hash table.
|
||||
* \param[in] heapID The heap used for hash table internal allocation
|
||||
* related to hash structure and hash entries
|
||||
|
@ -228,7 +228,7 @@ vmk_HashAllocWithOpaqueKeys(vmk_ModuleID moduleID,
|
|||
*
|
||||
* \brief Release a hash table.
|
||||
*
|
||||
* \param[in] hdl Hash handle.
|
||||
* \param[in] hdl Hash handle.
|
||||
*
|
||||
* \retval VMK_OK Hash table was released successful.
|
||||
* \retval VMK_BUSY If the hash table is not empty.
|
||||
|
@ -240,6 +240,30 @@ VMK_ReturnStatus
|
|||
vmk_HashRelease(vmk_HashTable hdl);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_HashDeleteAll -- */ /**
|
||||
*
|
||||
* \brief Delete every entry in a hash table.
|
||||
*
|
||||
* \note This won't actually release the values passed as part of the hash
|
||||
* table insertion. Client should make sure the right clean up is done
|
||||
* beforehand.
|
||||
*
|
||||
* \note A subsequent call to vmk_HashIsEmpty() on the given hash table should
|
||||
* return VMK_TRUE.
|
||||
*
|
||||
* \param[in] hdl Hash handle.
|
||||
*
|
||||
* \retval VMK_OK Every single entry of the hash table was deleted.
|
||||
* \retval VMK_BAD_PARAM If hdl equals to VMK_INVALID_HASH_HANDLE.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_HashDeleteAll(vmk_HashTable hdl);
|
||||
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_HashIsEmpty -- */ /**
|
||||
|
@ -264,7 +288,7 @@ vmk_HashIsEmpty(vmk_HashTable hdl);
|
|||
* \brief Iterator used to iterate the key-value pairs on a given hash table.
|
||||
*
|
||||
* \note The return value is a command set given back to the iterator engine to
|
||||
* let it know what to do next. It can be a binary union of any of the
|
||||
* let it know what to do next. It can be a binary union of any of the
|
||||
* vmk_HashKeyIteratorCmd defined above.
|
||||
*
|
||||
* \param[in] hdl Hash handle.
|
||||
|
@ -314,7 +338,7 @@ vmk_HashKeyIterate(vmk_HashTable hdl,
|
|||
*
|
||||
* \brief Insert a key-value pair into a given hash table.
|
||||
*
|
||||
* \note The key passed will be copied locally only if the flag
|
||||
* \note The key passed will be copied locally only if the flag
|
||||
* VMK_HASH_KEY_FLAGS_LOCAL_COPY was passed while creating the hash.
|
||||
*
|
||||
* \note The value passed won't be copied so the reference needs to be persistent
|
||||
|
@ -332,7 +356,7 @@ vmk_HashKeyIterate(vmk_HashTable hdl,
|
|||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_HashKeyInsert(vmk_HashTable hdl,
|
||||
vmk_HashKeyInsert(vmk_HashTable hdl,
|
||||
vmk_HashKey key,
|
||||
vmk_HashValue value);
|
||||
|
||||
|
@ -421,6 +445,30 @@ vmk_HashKeyFind(vmk_HashTable hdl,
|
|||
vmk_HashKey key,
|
||||
vmk_HashValue *value);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_HashBytes -- */ /**
|
||||
*
|
||||
* \brief Calculate 64 bit hash for an array of bytes.
|
||||
*
|
||||
* \note This API is not used as part of a hash table allocated with the
|
||||
* vmk_HashAlloc() function. It is provided as a helper routine for
|
||||
* callers that need to calculate hashes for their own purpose.
|
||||
*
|
||||
* \param[in] key Byte array pointer.
|
||||
* \param[in] keySize Array Size in byte.
|
||||
* \param[out] hash The calculated hash value.
|
||||
*
|
||||
* \retval VMK_OK Hash calculated successfully.
|
||||
* \retval VMK_BAD_PARAM If key or hash is NULL, or keySize equal zero.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
VMK_ReturnStatus
|
||||
vmk_HashBytes(const vmk_uint8 *key,
|
||||
vmk_uint32 keySize,
|
||||
vmk_uint64 *hash);
|
||||
|
||||
#endif /* _VMKAPI_HASH_H_ */
|
||||
/** @} */
|
||||
|
|
|
@ -0,0 +1,395 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2006 - 2012 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
* @VMKAPIMOD_LICENSE@
|
||||
*/
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* PriQ */ /**
|
||||
* \addtogroup Lib
|
||||
* @{
|
||||
* \defgroup PriQ Priority Queue
|
||||
*
|
||||
* These are interfaces for priority queues.
|
||||
*
|
||||
* The keys can be duplicated, the ordering will be kept accross the elements,
|
||||
* but the values are expected to be unique. The only reason for that is
|
||||
* because the vmk_PriQRekey uses the value as an unique identifier to update
|
||||
* the key of an element. If two elements with the same value are stored in the
|
||||
* queue and the vmk_PriQRekey is used on this element, then the behavior is
|
||||
* undefined.
|
||||
*
|
||||
* @{
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _VMKAPI_PRIQ_H_
|
||||
#define _VMKAPI_PRIQ_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 */
|
||||
|
||||
/**
|
||||
* \brief Type of the priority queue.
|
||||
*
|
||||
* \details A priority queue can have elements with the smallest or the biggest
|
||||
* key on front. This enum is used to select the type of priority
|
||||
* queue we use.
|
||||
*/
|
||||
typedef enum vmk_PriQType {
|
||||
/**
|
||||
* \brief The queue will be a "min priority queue", meaning that the elements
|
||||
* with the lowest priority will be on the front.
|
||||
*/
|
||||
VMK_PRIQ_TYPE_MIN,
|
||||
/**
|
||||
* \brief The queue will be a "max priority queue", meaning that the elements
|
||||
* with the highest priority will be on the front.
|
||||
*/
|
||||
VMK_PRIQ_TYPE_MAX,
|
||||
} vmk_PriQType;
|
||||
|
||||
/**
|
||||
* \brief Key used to insert an element into the priority queue.
|
||||
*/
|
||||
typedef vmk_uint64 vmk_PriQKey;
|
||||
|
||||
/**
|
||||
* \brief Opaque data structure for the priority queue.
|
||||
*/
|
||||
typedef struct vmk_PriQInternal *vmk_PriQHandle;
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_PriQCreate -- */ /**
|
||||
*
|
||||
* \brief Create a new priority queue.
|
||||
*
|
||||
* \note vmk_PriQDestroy() needs to be called once done with the priority queue.
|
||||
*
|
||||
* \note The priority queue returned does not come with locking, it is the
|
||||
* caller's responsibility to provide such mechanism if needed.
|
||||
*
|
||||
* \param[in] moduleID Module ID requesting the priority queue.
|
||||
* \param[in] heapID The heap used for priority queue internal allocation.
|
||||
* \param[in] type Type of the priority queue.
|
||||
* \param[in] numElems Number of elements in the priority queue. The queue
|
||||
* can be later resized if needed.
|
||||
* \param[out] priQ Handle on the priority queue.
|
||||
*
|
||||
* \retval VMK_OK Priority queue initialization and allocation was
|
||||
* successful.
|
||||
* \retval VMK_NO_MEMORY Memory allocation failure.
|
||||
* \retval VMK_BAD_PARAM An invalid parameter was provided.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PriQCreate(vmk_ModuleID moduleID,
|
||||
vmk_HeapID heapID,
|
||||
vmk_PriQType type,
|
||||
vmk_uint64 numElems,
|
||||
vmk_PriQHandle *priQ);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_PriQDestroy -- */ /**
|
||||
*
|
||||
* \brief Destroy a priority queue and its associated resources.
|
||||
*
|
||||
* \param[in] priQ Handle on the priority queue.
|
||||
*
|
||||
* \retval VMK_OK Everything went fine, the priority queue is released.
|
||||
* \retval VMK_BUSY The priority queue was not empty. Unable to release it.
|
||||
* \retval VMK_BAD_PARAM An invalid parameter was provided.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PriQDestroy(vmk_PriQHandle priQ);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_PriQClear -- */ /**
|
||||
*
|
||||
* \brief Clear the contents of a priority queue.
|
||||
*
|
||||
* \param[in] priQ Handle on the priority queue.
|
||||
*
|
||||
* \retval VMK_OK Everything went fine, the priority queue was emptied.
|
||||
* \retval VMK_BAD_PARAM An invalid parameter was provided.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PriQClear(vmk_PriQHandle priQ);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_PriQTotalElems -- */ /**
|
||||
*
|
||||
* \brief Get the total number of slots in the priority queue.
|
||||
*
|
||||
* \param[in] priQ Handle on the priority queue.
|
||||
* \param[out] totalElems Pointer to the output data.
|
||||
*
|
||||
* \retval VMK_OK The operation was successful.
|
||||
* \retval VMK_BAD_PARAM An invalid parameter was provided.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PriQTotalElems(vmk_PriQHandle priQ,
|
||||
vmk_uint64 *totalElems);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_PriQUsedElems -- */ /**
|
||||
*
|
||||
* \brief Get the number of used slots in the priority queue.
|
||||
*
|
||||
* \param[in] priQ Handle on the priority queue.
|
||||
* \param[out] usedElems Pointer to the output data.
|
||||
*
|
||||
* \retval VMK_OK The operation was successful.
|
||||
* \retval VMK_BAD_PARAM An invalid parameter was provided.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PriQUsedElems(vmk_PriQHandle priQ,
|
||||
vmk_uint64 *usedElems);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_PriQIsEmpty -- */ /**
|
||||
*
|
||||
* \brief Check whether or not a priority queue is empty.
|
||||
*
|
||||
* \param[in] priQ Handle on the priority queue.
|
||||
*
|
||||
* \retval VMK_TRUE The priority queue is empty.
|
||||
* \retval VMK_FALSE The priority queue still contains some elements.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
static inline vmk_Bool
|
||||
vmk_PriQIsEmpty(vmk_PriQHandle priQ)
|
||||
{
|
||||
VMK_ReturnStatus status;
|
||||
vmk_uint64 usedElems;
|
||||
|
||||
status = vmk_PriQUsedElems(priQ, &usedElems);
|
||||
VMK_ASSERT(status == VMK_OK);
|
||||
|
||||
return (usedElems == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_PriQResize -- */ /**
|
||||
*
|
||||
* \brief Resize a previously allocated priority queue.
|
||||
*
|
||||
* \param[in] priQ Handle on the priority queue.
|
||||
* \param[in] numElems New number of elements of the priority queue.
|
||||
*
|
||||
* \retval VMK_OK Resize operation was successful.
|
||||
* \retval VMK_BUSY Trying to shrink the queue to a size too small for the
|
||||
* elements that are already in there.
|
||||
* \retval VMK_NO_MEMORY Memory allocation failure. The priority queue is left
|
||||
* unchanged.
|
||||
* \retval VMK_BAD_PARAM An invalid parameter was provided.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PriQResize(vmk_PriQHandle priQ,
|
||||
vmk_uint64 numElems);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_PriQInsert -- */ /**
|
||||
*
|
||||
* \brief Insert an element in the priority queue.
|
||||
*
|
||||
* \param[in] priQ Handle on the priority queue.
|
||||
* \param[in] key Key of the new element. This is the actual "priority"
|
||||
* that is used to sort elements in the queue.
|
||||
* \param[in] value Opaque value to store with the key.
|
||||
*
|
||||
* \retval VMK_OK Insertion was successful.
|
||||
* \retval VMK_LIMIT_EXCEEDED The priority queue is already full. The element
|
||||
* was not inserted. The user needs to resize the queue.
|
||||
* \retval VMK_BAD_PARAM An invalid parameter was provided.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PriQInsert(vmk_PriQHandle priQ,
|
||||
vmk_PriQKey key,
|
||||
void *value);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_PriQFirst -- */ /**
|
||||
*
|
||||
* \brief Get the first element of the priority queue and/or its associated key.
|
||||
*
|
||||
* \note This does not remove the first element from the priority queue. One
|
||||
* needs to use vmk_PriQExtractFirst() for that purpose.
|
||||
*
|
||||
* \param[in] priQ Handle on the priority queue.
|
||||
* \param[out] key Pointer to the output key. If this parameter is NULL,
|
||||
* then it is ignored.
|
||||
* \param[out] value Pointer to the output value. If this parameter is
|
||||
* NULL, then it is ignored.
|
||||
*
|
||||
* \retval VMK_OK The first element of the queue has been "found" and
|
||||
* stored in the output parameters.
|
||||
* \retval VMK_BAD_PARAM An invalid parameter was provided.
|
||||
* \retval VMK_NOT_FOUND The queue was empty.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PriQFirst(vmk_PriQHandle priQ,
|
||||
vmk_PriQKey *key,
|
||||
void **value);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_PriQExtractFirst -- */ /**
|
||||
*
|
||||
* \brief Returns and deletes the first element of the priority queue.
|
||||
*
|
||||
* \param[in] priQ Handle on the priority queue.
|
||||
* \param[out] key Pointer to the output key. If this parameter is NULL,
|
||||
* then it is ignored.
|
||||
* \param[out] value Pointer to the output value. If this parameter is
|
||||
* NULL, then it is ignored.
|
||||
*
|
||||
* \retval VMK_OK The first element of the queue has been stored in
|
||||
* output parameters and deleted from the queue.
|
||||
* \retval VMK_BAD_PARAM An invalid parameter was provided.
|
||||
* \retval VMK_NOT_FOUND The queue was empty.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PriQExtractFirst(vmk_PriQHandle priQ,
|
||||
vmk_PriQKey *key,
|
||||
void **value);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_PriQExtract -- */ /**
|
||||
*
|
||||
* \brief Returns and deletes the element whose value is passed as argument.
|
||||
*
|
||||
* \note As keys in a priority queue can be duplicated, the only way to
|
||||
* uniquely identify an element is to use the pointer referencing it.
|
||||
*
|
||||
* \param[in] priQ Handle on the priority queue.
|
||||
* \param[in] value Value that was initially stored in the queue and that
|
||||
* we want to extract.
|
||||
* \param[out] key Pointer to the output key. If this parameter is NULL,
|
||||
* then it is ignored.
|
||||
*
|
||||
* \retval VMK_OK The element of the queue has been stored in output
|
||||
* parameters and deleted from the queue.
|
||||
* \retval VMK_BAD_PARAM An invalid parameter was provided.
|
||||
* \retval VMK_NOT_FOUND The element was not found in the queue.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PriQExtract(vmk_PriQHandle priQ,
|
||||
void *value,
|
||||
vmk_PriQKey *key);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_PriQFind -- */ /**
|
||||
*
|
||||
* \brief Returns the element whose value is passed as argument.
|
||||
*
|
||||
* \note As keys in a priority queue can be duplicated, the only way to
|
||||
* uniquely identify an element is to use the pointer referencing it.
|
||||
*
|
||||
* \param[in] priQ Handle on the priority queue.
|
||||
* \param[in] value Value that was initially stored in the queue and that
|
||||
* we want to find.
|
||||
* \param[out] key Pointer to the output key. If this parameter is NULL,
|
||||
* then it is ignored.
|
||||
*
|
||||
* \retval VMK_OK The element of the queue has been stored in output
|
||||
* parameters and deleted from the queue.
|
||||
* \retval VMK_BAD_PARAM An invalid parameter was provided.
|
||||
* \retval VMK_NOT_FOUND The element was not found in the queue.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PriQFind(vmk_PriQHandle priQ,
|
||||
void *value,
|
||||
vmk_PriQKey *key);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_PriQRekeyFirst -- */ /**
|
||||
*
|
||||
* \brief Update the key of the first element in the queue.
|
||||
*
|
||||
* \details This will lead to the first element beeing moved in the queue if
|
||||
* needed.
|
||||
*
|
||||
* \param[in] priQ Handle on the priority queue.
|
||||
* \param[in] newKey New key to apply to the first element in the queue.
|
||||
*
|
||||
* \retval VMK_OK The first element of the queue has been updated.
|
||||
* \retval VMK_BAD_PARAM An invalid parameter was provided.
|
||||
* \retval VMK_NOT_FOUND The queue was empty.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PriQRekeyFirst(vmk_PriQHandle priQ,
|
||||
vmk_PriQKey newKey);
|
||||
|
||||
/*
|
||||
*******************************************************************************
|
||||
* vmk_PriQRekey -- */ /**
|
||||
*
|
||||
* \brief Update the key of the entry whose value is passed as argument.
|
||||
*
|
||||
* \details This will lead to the element being moved in the queue if needed.
|
||||
*
|
||||
* \note As keys in a priority queue can be duplicated, the only way to
|
||||
* uniquely identify an element is to use the pointer referencing it.
|
||||
*
|
||||
* \param[in] priQ Handle on the priority queue.
|
||||
* \param[in] value Value that was initially stored in the queue, for
|
||||
* which we will update the key.
|
||||
* \param[in] newKey New key to apply to the value.
|
||||
*
|
||||
* \retval VMK_OK The element's key has been updated.
|
||||
* \retval VMK_BAD_PARAM An invalid parameter was provided.
|
||||
* \retval VMK_NOT_FOUND The element was not found in the queue.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
VMK_ReturnStatus
|
||||
vmk_PriQRekey(vmk_PriQHandle priQ,
|
||||
void *value,
|
||||
vmk_PriQKey newKey);
|
||||
|
||||
#endif /* _PRIQ_MINMAXHEAP_H_ */
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -1,5 +1,5 @@
|
|||
/* **********************************************************
|
||||
* Copyright 2008 - 2009 VMware, Inc. All rights reserved.
|
||||
* Copyright 2008 - 2009, 2013 VMware, Inc. All rights reserved.
|
||||
* **********************************************************/
|
||||
|
||||
/*
|
||||
|
@ -58,6 +58,134 @@
|
|||
*/
|
||||
#define VMK_UTIL_ROUNDUP(x, y) ((((x)+(y)-1) / (y)) * (y))
|
||||
|
||||
/**
|
||||
* \brief A series of macros used to count parameters in a varargs list
|
||||
*/
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* __VMK_UTIL_MASK_ARGS_INT__ -- */ /**
|
||||
*
|
||||
* \brief Internal macro to ignore the first 128 varargs parameters and
|
||||
* evaluate as 129th.
|
||||
*
|
||||
* This is used as part of VMK_UTIL_NUM_ARGS(). VMKAPI clients should
|
||||
* not call this macro directly.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/** \cond nodoc */
|
||||
#define __VMK_UTIL_MASK_ARGS_INT__( \
|
||||
_ARG1, _ARG2, _ARG3, _ARG4, _ARG5, \
|
||||
_ARG6, _ARG7, _ARG8, _ARG9, _ARG10, \
|
||||
_ARG11, _ARG12, _ARG13, _ARG14, _ARG15, \
|
||||
_ARG16, _ARG17, _ARG18, _ARG19, _ARG20, \
|
||||
_ARG21, _ARG22, _ARG23, _ARG24, _ARG25, \
|
||||
_ARG26, _ARG27, _ARG28, _ARG29, _ARG30, \
|
||||
_ARG31, _ARG32, _ARG33, _ARG34, _ARG35, \
|
||||
_ARG36, _ARG37, _ARG38, _ARG39, _ARG40, \
|
||||
_ARG41, _ARG42, _ARG43, _ARG44, _ARG45, \
|
||||
_ARG46, _ARG47, _ARG48, _ARG49, _ARG50, \
|
||||
_ARG51, _ARG52, _ARG53, _ARG54, _ARG55, \
|
||||
_ARG56, _ARG57, _ARG58, _ARG59, _ARG60, \
|
||||
_ARG61, _ARG62, _ARG63, _ARG64, _ARG65, \
|
||||
_ARG66, _ARG67, _ARG68, _ARG69, _ARG70, \
|
||||
_ARG71, _ARG72, _ARG73, _ARG74, _ARG75, \
|
||||
_ARG76, _ARG77, _ARG78, _ARG79, _ARG80, \
|
||||
_ARG81, _ARG82, _ARG83, _ARG84, _ARG85, \
|
||||
_ARG86, _ARG87, _ARG88, _ARG89, _ARG90, \
|
||||
_ARG91, _ARG92, _ARG93, _ARG94, _ARG95, \
|
||||
_ARG96, _ARG97, _ARG98, _ARG99, _ARG100, \
|
||||
_ARG101, _ARG102, _ARG103, _ARG104, _ARG105, \
|
||||
_ARG106, _ARG107, _ARG108, _ARG109, _ARG110, \
|
||||
_ARG111, _ARG112, _ARG113, _ARG114, _ARG115, \
|
||||
_ARG116, _ARG117, _ARG118, _ARG119, _ARG120, \
|
||||
_ARG121, _ARG122, _ARG123, _ARG124, _ARG125, \
|
||||
_ARG126, _ARG127, _ARG128, _ARG129, ...) _ARG129
|
||||
/** \endcond */
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* __VMK_UTIL_ARG_COUNTS__ -- */ /**
|
||||
*
|
||||
* \brief A series of argument counts, used with VMK_UTIL_NUM_ARGS.
|
||||
*
|
||||
* This is used as part of VMK_UTIL_NUM_ARGS(). VMKAPI clients should
|
||||
* no call this macro directly.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
/** \cond nodoc */
|
||||
#define __VMK_UTIL_ARG_COUNTS__() \
|
||||
128, 127, 126, 125, 124, 123, 122, 121, 120, \
|
||||
119, 118, 117, 116, 115, 114, 113, 112, 111, 110, \
|
||||
109, 108, 107, 106, 105, 104, 103, 102, 101, 100, \
|
||||
99, 98, 97, 96, 95, 94, 93, 92, 91, 90, \
|
||||
89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \
|
||||
79, 78, 77, 76, 75, 74, 73, 72, 71, 70, \
|
||||
69, 68, 67, 66, 65, 64, 63, 62, 61, 60, \
|
||||
59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \
|
||||
49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \
|
||||
39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \
|
||||
29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \
|
||||
19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \
|
||||
9, 8, 7, 6, 5, 4, 3, 2, 1, 0
|
||||
/** \endcond */
|
||||
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* __VMK_UTIL_MASK_ARGS__ -- */ /**
|
||||
*
|
||||
* \brief Variadic macro that masks the first 128 arguments, evaluating
|
||||
* the 129th.
|
||||
*
|
||||
* This is used as part of VMK_UTIL_NUM_ARGS(). VMKAPI clients should
|
||||
* no call this macro directly.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
/** \cond nodoc */
|
||||
#define __VMK_UTIL_MASK_ARGS__(...) \
|
||||
__VMK_UTIL_MASK_ARGS_INT__(__VA_ARGS__)
|
||||
/** \endcond */
|
||||
|
||||
/*
|
||||
***********************************************************************
|
||||
* VMK_UTIL_NUM_ARGS -- */ /**
|
||||
*
|
||||
* \brief Macro to count the number of varargs parameters.
|
||||
*
|
||||
* \param[in] ... varargs parameters. There can be 0 to 127
|
||||
* parameters. More than 127 produces an
|
||||
* undefined result.
|
||||
*
|
||||
* \note This works by creating a larger varargs series of parameters
|
||||
* around the passed series and using internal macros. The
|
||||
* larger series is a dummy parameter (to support if the passed
|
||||
* series has no parameters), the passed series, and then a
|
||||
* decreasing series of numbers representing the parameter count.
|
||||
* The internal macros effectively ignore the first 128
|
||||
* parameters of this larger series and evaluates as the 129th,
|
||||
* thus effectively evaluating as one plus the count of passed
|
||||
* parameters. (The one is offset by subtraction in this
|
||||
* macro).
|
||||
* \note This macro relies on the special behavior of ##__VA_ARGS__,
|
||||
* as described here:
|
||||
* http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
|
||||
* In the case that the passed varargs series has no elements,
|
||||
* ##__VA_ARGS__ will also consume the comma preceding it,
|
||||
* allowing this macro (VMK_UTIL_NUM_ARGS) to compile correctly
|
||||
* and evaluate as 0.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
/** \cond nodoc */
|
||||
#define VMK_UTIL_NUM_ARGS(...) \
|
||||
(__VMK_UTIL_MASK_ARGS__(_DUMMY, ##__VA_ARGS__, __VMK_UTIL_ARG_COUNTS__()) - 1)
|
||||
/** \endcond */
|
||||
|
||||
#endif /* _VMKAPI_UTIL_H_ */
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue