summaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/extcon/extcon-gpio.h (renamed from include/linux/extcon/extcon_gpio.h)0
-rw-r--r--include/linux/hyperv.h248
-rw-r--r--include/linux/mfd/arizona/core.h4
-rw-r--r--include/linux/mfd/arizona/pdata.h21
-rw-r--r--include/linux/mfd/arizona/registers.h56
-rw-r--r--include/linux/mfd/max77693-private.h86
-rw-r--r--include/linux/mfd/max77693.h9
-rw-r--r--include/linux/mfd/max8997-private.h64
-rw-r--r--include/linux/mfd/max8997.h25
-rw-r--r--include/linux/ntb.h83
-rw-r--r--include/linux/vmw_vmci_api.h82
-rw-r--r--include/linux/vmw_vmci_defs.h880
12 files changed, 1524 insertions, 34 deletions
diff --git a/include/linux/extcon/extcon_gpio.h b/include/linux/extcon/extcon-gpio.h
index 2d8307f7d67d..2d8307f7d67d 100644
--- a/include/linux/extcon/extcon_gpio.h
+++ b/include/linux/extcon/extcon-gpio.h
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index e73b852156b1..df77ba9a8166 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -325,14 +325,28 @@ struct hv_ring_buffer {
u32 interrupt_mask;
- /* Pad it to PAGE_SIZE so that data starts on page boundary */
- u8 reserved[4084];
-
- /* NOTE:
- * The interrupt_mask field is used only for channels but since our
- * vmbus connection also uses this data structure and its data starts
- * here, we commented out this field.
+ /*
+ * Win8 uses some of the reserved bits to implement
+ * interrupt driven flow management. On the send side
+ * we can request that the receiver interrupt the sender
+ * when the ring transitions from being full to being able
+ * to handle a message of size "pending_send_sz".
+ *
+ * Add necessary state for this enhancement.
*/
+ u32 pending_send_sz;
+
+ u32 reserved1[12];
+
+ union {
+ struct {
+ u32 feat_pending_send_sz:1;
+ };
+ u32 value;
+ } feature_bits;
+
+ /* Pad it to PAGE_SIZE so that data starts on page boundary */
+ u8 reserved2[4028];
/*
* Ring data starts here + RingDataStartOffset
@@ -405,12 +419,22 @@ hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi,
*/
#define HV_DRV_VERSION "3.1"
-
/*
- * A revision number of vmbus that is used for ensuring both ends on a
- * partition are using compatible versions.
+ * VMBUS version is 32 bit entity broken up into
+ * two 16 bit quantities: major_number. minor_number.
+ *
+ * 0 . 13 (Windows Server 2008)
+ * 1 . 1 (Windows 7)
+ * 2 . 4 (Windows 8)
*/
-#define VMBUS_REVISION_NUMBER 13
+
+#define VERSION_WS2008 ((0 << 16) | (13))
+#define VERSION_WIN7 ((1 << 16) | (1))
+#define VERSION_WIN8 ((2 << 16) | (4))
+
+#define VERSION_INVAL -1
+
+#define VERSION_CURRENT VERSION_WIN8
/* Make maximum size of pipe payload of 16K */
#define MAX_PIPE_DATA_PAYLOAD (sizeof(u8) * 16384)
@@ -432,9 +456,13 @@ hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi,
struct vmbus_channel_offer {
uuid_le if_type;
uuid_le if_instance;
- u64 int_latency; /* in 100ns units */
- u32 if_revision;
- u32 server_ctx_size; /* in bytes */
+
+ /*
+ * These two fields are not currently used.
+ */
+ u64 reserved1;
+ u64 reserved2;
+
u16 chn_flags;
u16 mmio_megabytes; /* in bytes * 1024 * 1024 */
@@ -456,7 +484,11 @@ struct vmbus_channel_offer {
unsigned char user_def[MAX_PIPE_USER_DEFINED_BYTES];
} pipe;
} u;
- u32 padding;
+ /*
+ * The sub_channel_index is defined in win8.
+ */
+ u16 sub_channel_index;
+ u16 reserved3;
} __packed;
/* Server Flags */
@@ -652,7 +684,25 @@ struct vmbus_channel_offer_channel {
struct vmbus_channel_offer offer;
u32 child_relid;
u8 monitorid;
- u8 monitor_allocated;
+ /*
+ * win7 and beyond splits this field into a bit field.
+ */
+ u8 monitor_allocated:1;
+ u8 reserved:7;
+ /*
+ * These are new fields added in win7 and later.
+ * Do not access these fields without checking the
+ * negotiated protocol.
+ *
+ * If "is_dedicated_interrupt" is set, we must not set the
+ * associated bit in the channel bitmap while sending the
+ * interrupt to the host.
+ *
+ * connection_id is to be used in signaling the host.
+ */
+ u16 is_dedicated_interrupt:1;
+ u16 reserved1:15;
+ u32 connection_id;
} __packed;
/* Rescind Offer parameters */
@@ -683,8 +733,15 @@ struct vmbus_channel_open_channel {
/* GPADL for the channel's ring buffer. */
u32 ringbuffer_gpadlhandle;
- /* GPADL for the channel's server context save area. */
- u32 server_contextarea_gpadlhandle;
+ /*
+ * Starting with win8, this field will be used to specify
+ * the target virtual processor on which to deliver the interrupt for
+ * the host to guest communication.
+ * Prior to win8, incoming channel interrupts would only
+ * be delivered on cpu 0. Setting this value to 0 would
+ * preserve the earlier behavior.
+ */
+ u32 target_vp;
/*
* The upstream ring buffer begins at offset zero in the memory
@@ -848,6 +905,27 @@ struct vmbus_close_msg {
struct vmbus_channel_close_channel msg;
};
+/* Define connection identifier type. */
+union hv_connection_id {
+ u32 asu32;
+ struct {
+ u32 id:24;
+ u32 reserved:8;
+ } u;
+};
+
+/* Definition of the hv_signal_event hypercall input structure. */
+struct hv_input_signal_event {
+ union hv_connection_id connectionid;
+ u16 flag_number;
+ u16 rsvdz;
+};
+
+struct hv_input_signal_event_buffer {
+ u64 align8;
+ struct hv_input_signal_event event;
+};
+
struct vmbus_channel {
struct list_head listentry;
@@ -882,8 +960,42 @@ struct vmbus_channel {
void (*onchannel_callback)(void *context);
void *channel_callback_context;
+
+ /*
+ * A channel can be marked for efficient (batched)
+ * reading:
+ * If batched_reading is set to "true", we read until the
+ * channel is empty and hold off interrupts from the host
+ * during the entire read process.
+ * If batched_reading is set to "false", the client is not
+ * going to perform batched reading.
+ *
+ * By default we will enable batched reading; specific
+ * drivers that don't want this behavior can turn it off.
+ */
+
+ bool batched_reading;
+
+ bool is_dedicated_interrupt;
+ struct hv_input_signal_event_buffer sig_buf;
+ struct hv_input_signal_event *sig_event;
+
+ /*
+ * Starting with win8, this field will be used to specify
+ * the target virtual processor on which to deliver the interrupt for
+ * the host to guest communication.
+ * Prior to win8, incoming channel interrupts would only
+ * be delivered on cpu 0. Setting this value to 0 would
+ * preserve the earlier behavior.
+ */
+ u32 target_vp;
};
+static inline void set_channel_read_state(struct vmbus_channel *c, bool state)
+{
+ c->batched_reading = state;
+}
+
void vmbus_onmessage(void *context);
int vmbus_request_offers(void);
@@ -1047,6 +1159,100 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver);
g8, g9, ga, gb, gc, gd, ge, gf },
/*
+ * GUID definitions of various offer types - services offered to the guest.
+ */
+
+/*
+ * Network GUID
+ * {f8615163-df3e-46c5-913f-f2d2f965ed0e}
+ */
+#define HV_NIC_GUID \
+ .guid = { \
+ 0x63, 0x51, 0x61, 0xf8, 0x3e, 0xdf, 0xc5, 0x46, \
+ 0x91, 0x3f, 0xf2, 0xd2, 0xf9, 0x65, 0xed, 0x0e \
+ }
+
+/*
+ * IDE GUID
+ * {32412632-86cb-44a2-9b5c-50d1417354f5}
+ */
+#define HV_IDE_GUID \
+ .guid = { \
+ 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, \
+ 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 \
+ }
+
+/*
+ * SCSI GUID
+ * {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}
+ */
+#define HV_SCSI_GUID \
+ .guid = { \
+ 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, \
+ 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f \
+ }
+
+/*
+ * Shutdown GUID
+ * {0e0b6031-5213-4934-818b-38d90ced39db}
+ */
+#define HV_SHUTDOWN_GUID \
+ .guid = { \
+ 0x31, 0x60, 0x0b, 0x0e, 0x13, 0x52, 0x34, 0x49, \
+ 0x81, 0x8b, 0x38, 0xd9, 0x0c, 0xed, 0x39, 0xdb \
+ }
+
+/*
+ * Time Synch GUID
+ * {9527E630-D0AE-497b-ADCE-E80AB0175CAF}
+ */
+#define HV_TS_GUID \
+ .guid = { \
+ 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, \
+ 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf \
+ }
+
+/*
+ * Heartbeat GUID
+ * {57164f39-9115-4e78-ab55-382f3bd5422d}
+ */
+#define HV_HEART_BEAT_GUID \
+ .guid = { \
+ 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, \
+ 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d \
+ }
+
+/*
+ * KVP GUID
+ * {a9a0f4e7-5a45-4d96-b827-8a841e8c03e6}
+ */
+#define HV_KVP_GUID \
+ .guid = { \
+ 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, \
+ 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 \
+ }
+
+/*
+ * Dynamic memory GUID
+ * {525074dc-8985-46e2-8057-a307dc18a502}
+ */
+#define HV_DM_GUID \
+ .guid = { \
+ 0xdc, 0x74, 0x50, 0X52, 0x85, 0x89, 0xe2, 0x46, \
+ 0x80, 0x57, 0xa3, 0x07, 0xdc, 0x18, 0xa5, 0x02 \
+ }
+
+/*
+ * Mouse GUID
+ * {cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a}
+ */
+#define HV_MOUSE_GUID \
+ .guid = { \
+ 0x9e, 0xb6, 0xa8, 0xcf, 0x4a, 0x5b, 0xc0, 0x4c, \
+ 0xb9, 0x8b, 0x8b, 0xa1, 0xa1, 0xf3, 0xf9, 0x5a \
+ }
+
+/*
* Common header for Hyper-V ICs
*/
@@ -1150,5 +1356,11 @@ int hv_kvp_init(struct hv_util_service *);
void hv_kvp_deinit(void);
void hv_kvp_onchannelcallback(void *);
+/*
+ * Negotiated version with the Host.
+ */
+
+extern __u32 vmbus_proto_version;
+
#endif /* __KERNEL__ */
#endif /* _HYPERV_H */
diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h
index a580363a7d29..a710255528d7 100644
--- a/include/linux/mfd/arizona/core.h
+++ b/include/linux/mfd/arizona/core.h
@@ -75,8 +75,10 @@ enum arizona_type {
#define ARIZONA_IRQ_DCS_HP_DONE 47
#define ARIZONA_IRQ_FLL2_CLOCK_OK 48
#define ARIZONA_IRQ_FLL1_CLOCK_OK 49
+#define ARIZONA_IRQ_MICD_CLAMP_RISE 50
+#define ARIZONA_IRQ_MICD_CLAMP_FALL 51
-#define ARIZONA_NUM_IRQ 50
+#define ARIZONA_NUM_IRQ 52
struct snd_soc_dapm_context;
diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h
index ec3e2a2a6d77..96d64f2b8d78 100644
--- a/include/linux/mfd/arizona/pdata.h
+++ b/include/linux/mfd/arizona/pdata.h
@@ -105,9 +105,30 @@ struct arizona_pdata {
*/
int max_channels_clocked[ARIZONA_MAX_AIF];
+ /** GPIO5 is used for jack detection */
+ bool jd_gpio5;
+
+ /** Use the headphone detect circuit to identify the accessory */
+ bool hpdet_acc_id;
+
+ /** GPIO used for mic isolation with HPDET */
+ int hpdet_id_gpio;
+
/** GPIO for mic detection polarity */
int micd_pol_gpio;
+ /** Mic detect ramp rate */
+ int micd_bias_start_time;
+
+ /** Mic detect sample rate */
+ int micd_rate;
+
+ /** Mic detect debounce level */
+ int micd_dbtime;
+
+ /** Force MICBIAS on for mic detect */
+ bool micd_force_micbias;
+
/** Headset polarity configurations */
struct arizona_micd_config *micd_configs;
int num_micd_configs;
diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h
index 1f6fe31a4d5c..188d89abd963 100644
--- a/include/linux/mfd/arizona/registers.h
+++ b/include/linux/mfd/arizona/registers.h
@@ -119,6 +119,8 @@
#define ARIZONA_ACCESSORY_DETECT_MODE_1 0x293
#define ARIZONA_HEADPHONE_DETECT_1 0x29B
#define ARIZONA_HEADPHONE_DETECT_2 0x29C
+#define ARIZONA_HP_DACVAL 0x29F
+#define ARIZONA_MICD_CLAMP_CONTROL 0x2A2
#define ARIZONA_MIC_DETECT_1 0x2A3
#define ARIZONA_MIC_DETECT_2 0x2A4
#define ARIZONA_MIC_DETECT_3 0x2A5
@@ -1194,6 +1196,14 @@
/*
* R64 (0x40) - Wake control
*/
+#define ARIZONA_WKUP_MICD_CLAMP_FALL 0x0080 /* WKUP_MICD_CLAMP_FALL */
+#define ARIZONA_WKUP_MICD_CLAMP_FALL_MASK 0x0080 /* WKUP_MICD_CLAMP_FALL */
+#define ARIZONA_WKUP_MICD_CLAMP_FALL_SHIFT 7 /* WKUP_MICD_CLAMP_FALL */
+#define ARIZONA_WKUP_MICD_CLAMP_FALL_WIDTH 1 /* WKUP_MICD_CLAMP_FALL */
+#define ARIZONA_WKUP_MICD_CLAMP_RISE 0x0040 /* WKUP_MICD_CLAMP_RISE */
+#define ARIZONA_WKUP_MICD_CLAMP_RISE_MASK 0x0040 /* WKUP_MICD_CLAMP_RISE */
+#define ARIZONA_WKUP_MICD_CLAMP_RISE_SHIFT 6 /* WKUP_MICD_CLAMP_RISE */
+#define ARIZONA_WKUP_MICD_CLAMP_RISE_WIDTH 1 /* WKUP_MICD_CLAMP_RISE */
#define ARIZONA_WKUP_GP5_FALL 0x0020 /* WKUP_GP5_FALL */
#define ARIZONA_WKUP_GP5_FALL_MASK 0x0020 /* WKUP_GP5_FALL */
#define ARIZONA_WKUP_GP5_FALL_SHIFT 5 /* WKUP_GP5_FALL */
@@ -2035,6 +2045,9 @@
/*
* R667 (0x29B) - Headphone Detect 1
*/
+#define ARIZONA_HP_IMPEDANCE_RANGE_MASK 0x0600 /* HP_IMPEDANCE_RANGE - [10:9] */
+#define ARIZONA_HP_IMPEDANCE_RANGE_SHIFT 9 /* HP_IMPEDANCE_RANGE - [10:9] */
+#define ARIZONA_HP_IMPEDANCE_RANGE_WIDTH 2 /* HP_IMPEDANCE_RANGE - [10:9] */
#define ARIZONA_HP_STEP_SIZE 0x0100 /* HP_STEP_SIZE */
#define ARIZONA_HP_STEP_SIZE_MASK 0x0100 /* HP_STEP_SIZE */
#define ARIZONA_HP_STEP_SIZE_SHIFT 8 /* HP_STEP_SIZE */
@@ -2069,6 +2082,21 @@
#define ARIZONA_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
#define ARIZONA_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
+#define ARIZONA_HP_DONE_B 0x8000 /* HP_DONE */
+#define ARIZONA_HP_DONE_B_MASK 0x8000 /* HP_DONE */
+#define ARIZONA_HP_DONE_B_SHIFT 15 /* HP_DONE */
+#define ARIZONA_HP_DONE_B_WIDTH 1 /* HP_DONE */
+#define ARIZONA_HP_LVL_B_MASK 0x7FFF /* HP_LVL - [14:0] */
+#define ARIZONA_HP_LVL_B_SHIFT 0 /* HP_LVL - [14:0] */
+#define ARIZONA_HP_LVL_B_WIDTH 15 /* HP_LVL - [14:0] */
+
+/*
+ * R674 (0x2A2) - MICD clamp control
+ */
+#define ARIZONA_MICD_CLAMP_MODE_MASK 0x000F /* MICD_CLAMP_MODE - [3:0] */
+#define ARIZONA_MICD_CLAMP_MODE_SHIFT 0 /* MICD_CLAMP_MODE - [3:0] */
+#define ARIZONA_MICD_CLAMP_MODE_WIDTH 4 /* MICD_CLAMP_MODE - [3:0] */
+
/*
* R675 (0x2A3) - Mic Detect 1
*/
@@ -5239,6 +5267,14 @@
/*
* R3408 (0xD50) - AOD wkup and trig
*/
+#define ARIZONA_MICD_CLAMP_FALL_TRIG_STS 0x0080 /* MICD_CLAMP_FALL_TRIG_STS */
+#define ARIZONA_MICD_CLAMP_FALL_TRIG_STS_MASK 0x0080 /* MICD_CLAMP_FALL_TRIG_STS */
+#define ARIZONA_MICD_CLAMP_FALL_TRIG_STS_SHIFT 7 /* MICD_CLAMP_FALL_TRIG_STS */
+#define ARIZONA_MICD_CLAMP_FALL_TRIG_STS_WIDTH 1 /* MICD_CLAMP_FALL_TRIG_STS */
+#define ARIZONA_MICD_CLAMP_RISE_TRIG_STS 0x0040 /* MICD_CLAMP_RISE_TRIG_STS */
+#define ARIZONA_MICD_CLAMP_RISE_TRIG_STS_MASK 0x0040 /* MICD_CLAMP_RISE_TRIG_STS */
+#define ARIZONA_MICD_CLAMP_RISE_TRIG_STS_SHIFT 6 /* MICD_CLAMP_RISE_TRIG_STS */
+#define ARIZONA_MICD_CLAMP_RISE_TRIG_STS_WIDTH 1 /* MICD_CLAMP_RISE_TRIG_STS */
#define ARIZONA_GP5_FALL_TRIG_STS 0x0020 /* GP5_FALL_TRIG_STS */
#define ARIZONA_GP5_FALL_TRIG_STS_MASK 0x0020 /* GP5_FALL_TRIG_STS */
#define ARIZONA_GP5_FALL_TRIG_STS_SHIFT 5 /* GP5_FALL_TRIG_STS */
@@ -5267,6 +5303,12 @@
/*
* R3409 (0xD51) - AOD IRQ1
*/
+#define ARIZONA_MICD_CLAMP_FALL_EINT1 0x0080 /* MICD_CLAMP_FALL_EINT1 */
+#define ARIZONA_MICD_CLAMP_FALL_EINT1_MASK 0x0080 /* MICD_CLAMP_FALL_EINT1 */
+#define ARIZONA_MICD_CLAMP_FALL_EINT1_SHIFT 7 /* MICD_CLAMP_FALL_EINT1 */
+#define ARIZONA_MICD_CLAMP_RISE_EINT1 0x0040 /* MICD_CLAMP_RISE_EINT1 */
+#define ARIZONA_MICD_CLAMP_RISE_EINT1_MASK 0x0040 /* MICD_CLAMP_RISE_EINT1 */
+#define ARIZONA_MICD_CLAMP_RISE_EINT1_SHIFT 6 /* MICD_CLAMP_RISE_EINT1 */
#define ARIZONA_GP5_FALL_EINT1 0x0020 /* GP5_FALL_EINT1 */
#define ARIZONA_GP5_FALL_EINT1_MASK 0x0020 /* GP5_FALL_EINT1 */
#define ARIZONA_GP5_FALL_EINT1_SHIFT 5 /* GP5_FALL_EINT1 */
@@ -5295,6 +5337,12 @@
/*
* R3410 (0xD52) - AOD IRQ2
*/
+#define ARIZONA_MICD_CLAMP_FALL_EINT2 0x0080 /* MICD_CLAMP_FALL_EINT2 */
+#define ARIZONA_MICD_CLAMP_FALL_EINT2_MASK 0x0080 /* MICD_CLAMP_FALL_EINT2 */
+#define ARIZONA_MICD_CLAMP_FALL_EINT2_SHIFT 7 /* MICD_CLAMP_FALL_EINT2 */
+#define ARIZONA_MICD_CLAMP_RISE_EINT2 0x0040 /* MICD_CLAMP_RISE_EINT2 */
+#define ARIZONA_MICD_CLAMP_RISE_EINT2_MASK 0x0040 /* MICD_CLAMP_RISE_EINT2 */
+#define ARIZONA_MICD_CLAMP_RISE_EINT2_SHIFT 6 /* MICD_CLAMP_RISE_EINT2 */
#define ARIZONA_GP5_FALL_EINT2 0x0020 /* GP5_FALL_EINT2 */
#define ARIZONA_GP5_FALL_EINT2_MASK 0x0020 /* GP5_FALL_EINT2 */
#define ARIZONA_GP5_FALL_EINT2_SHIFT 5 /* GP5_FALL_EINT2 */
@@ -5379,6 +5427,10 @@
/*
* R3413 (0xD55) - AOD IRQ Raw Status
*/
+#define ARIZONA_MICD_CLAMP_STS 0x0008 /* MICD_CLAMP_STS */
+#define ARIZONA_MICD_CLAMP_STS_MASK 0x0008 /* MICD_CLAMP_STS */
+#define ARIZONA_MICD_CLAMP_STS_SHIFT 3 /* MICD_CLAMP_STS */
+#define ARIZONA_MICD_CLAMP_STS_WIDTH 1 /* MICD_CLAMP_STS */
#define ARIZONA_GP5_STS 0x0004 /* GP5_STS */
#define ARIZONA_GP5_STS_MASK 0x0004 /* GP5_STS */
#define ARIZONA_GP5_STS_SHIFT 2 /* GP5_STS */
@@ -5395,6 +5447,10 @@
/*
* R3414 (0xD56) - Jack detect debounce
*/
+#define ARIZONA_MICD_CLAMP_DB 0x0008 /* MICD_CLAMP_DB */
+#define ARIZONA_MICD_CLAMP_DB_MASK 0x0008 /* MICD_CLAMP_DB */
+#define ARIZONA_MICD_CLAMP_DB_SHIFT 3 /* MICD_CLAMP_DB */
+#define ARIZONA_MICD_CLAMP_DB_WIDTH 1 /* MICD_CLAMP_DB */
#define ARIZONA_JD2_DB 0x0002 /* JD2_DB */
#define ARIZONA_JD2_DB_MASK 0x0002 /* JD2_DB */
#define ARIZONA_JD2_DB_SHIFT 1 /* JD2_DB */
diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h
index 1eeae5c07915..5b18ecde69b5 100644
--- a/include/linux/mfd/max77693-private.h
+++ b/include/linux/mfd/max77693-private.h
@@ -106,6 +106,92 @@ enum max77693_muic_reg {
MAX77693_MUIC_REG_END,
};
+/* MAX77693 MUIC - STATUS1~3 Register */
+#define STATUS1_ADC_SHIFT (0)
+#define STATUS1_ADCLOW_SHIFT (5)
+#define STATUS1_ADCERR_SHIFT (6)
+#define STATUS1_ADC1K_SHIFT (7)
+#define STATUS1_ADC_MASK (0x1f << STATUS1_ADC_SHIFT)
+#define STATUS1_ADCLOW_MASK (0x1 << STATUS1_ADCLOW_SHIFT)
+#define STATUS1_ADCERR_MASK (0x1 << STATUS1_ADCERR_SHIFT)
+#define STATUS1_ADC1K_MASK (0x1 << STATUS1_ADC1K_SHIFT)
+
+#define STATUS2_CHGTYP_SHIFT (0)
+#define STATUS2_CHGDETRUN_SHIFT (3)
+#define STATUS2_DCDTMR_SHIFT (4)
+#define STATUS2_DXOVP_SHIFT (5)
+#define STATUS2_VBVOLT_SHIFT (6)
+#define STATUS2_VIDRM_SHIFT (7)
+#define STATUS2_CHGTYP_MASK (0x7 << STATUS2_CHGTYP_SHIFT)
+#define STATUS2_CHGDETRUN_MASK (0x1 << STATUS2_CHGDETRUN_SHIFT)
+#define STATUS2_DCDTMR_MASK (0x1 << STATUS2_DCDTMR_SHIFT)
+#define STATUS2_DXOVP_MASK (0x1 << STATUS2_DXOVP_SHIFT)
+#define STATUS2_VBVOLT_MASK (0x1 << STATUS2_VBVOLT_SHIFT)
+#define STATUS2_VIDRM_MASK (0x1 << STATUS2_VIDRM_SHIFT)
+
+#define STATUS3_OVP_SHIFT (2)
+#define STATUS3_OVP_MASK (0x1 << STATUS3_OVP_SHIFT)
+
+/* MAX77693 CDETCTRL1~2 register */
+#define CDETCTRL1_CHGDETEN_SHIFT (0)
+#define CDETCTRL1_CHGTYPMAN_SHIFT (1)
+#define CDETCTRL1_DCDEN_SHIFT (2)
+#define CDETCTRL1_DCD2SCT_SHIFT (3)
+#define CDETCTRL1_CDDELAY_SHIFT (4)
+#define CDETCTRL1_DCDCPL_SHIFT (5)
+#define CDETCTRL1_CDPDET_SHIFT (7)
+#define CDETCTRL1_CHGDETEN_MASK (0x1 << CDETCTRL1_CHGDETEN_SHIFT)
+#define CDETCTRL1_CHGTYPMAN_MASK (0x1 << CDETCTRL1_CHGTYPMAN_SHIFT)
+#define CDETCTRL1_DCDEN_MASK (0x1 << CDETCTRL1_DCDEN_SHIFT)
+#define CDETCTRL1_DCD2SCT_MASK (0x1 << CDETCTRL1_DCD2SCT_SHIFT)
+#define CDETCTRL1_CDDELAY_MASK (0x1 << CDETCTRL1_CDDELAY_SHIFT)
+#define CDETCTRL1_DCDCPL_MASK (0x1 << CDETCTRL1_DCDCPL_SHIFT)
+#define CDETCTRL1_CDPDET_MASK (0x1 << CDETCTRL1_CDPDET_SHIFT)
+
+#define CDETCTRL2_VIDRMEN_SHIFT (1)
+#define CDETCTRL2_DXOVPEN_SHIFT (3)
+#define CDETCTRL2_VIDRMEN_MASK (0x1 << CDETCTRL2_VIDRMEN_SHIFT)
+#define CDETCTRL2_DXOVPEN_MASK (0x1 << CDETCTRL2_DXOVPEN_SHIFT)
+
+/* MAX77693 MUIC - CONTROL1~3 register */
+#define COMN1SW_SHIFT (0)
+#define COMP2SW_SHIFT (3)
+#define COMN1SW_MASK (0x7 << COMN1SW_SHIFT)
+#define COMP2SW_MASK (0x7 << COMP2SW_SHIFT)
+#define COMP_SW_MASK (COMP2SW_MASK | COMN1SW_MASK)
+#define CONTROL1_SW_USB ((1 << COMP2SW_SHIFT) \
+ | (1 << COMN1SW_SHIFT))
+#define CONTROL1_SW_AUDIO ((2 << COMP2SW_SHIFT) \
+ | (2 << COMN1SW_SHIFT))
+#define CONTROL1_SW_UART ((3 << COMP2SW_SHIFT) \
+ | (3 << COMN1SW_SHIFT))
+#define CONTROL1_SW_OPEN ((0 << COMP2SW_SHIFT) \
+ | (0 << COMN1SW_SHIFT))
+
+#define CONTROL2_LOWPWR_SHIFT (0)
+#define CONTROL2_ADCEN_SHIFT (1)
+#define CONTROL2_CPEN_SHIFT (2)
+#define CONTROL2_SFOUTASRT_SHIFT (3)
+#define CONTROL2_SFOUTORD_SHIFT (4)
+#define CONTROL2_ACCDET_SHIFT (5)
+#define CONTROL2_USBCPINT_SHIFT (6)
+#define CONTROL2_RCPS_SHIFT (7)
+#define CONTROL2_LOWPWR_MASK (0x1 << CONTROL2_LOWPWR_SHIFT)
+#define CONTROL2_ADCEN_MASK (0x1 << CONTROL2_ADCEN_SHIFT)
+#define CONTROL2_CPEN_MASK (0x1 << CONTROL2_CPEN_SHIFT)
+#define CONTROL2_SFOUTASRT_MASK (0x1 << CONTROL2_SFOUTASRT_SHIFT)
+#define CONTROL2_SFOUTORD_MASK (0x1 << CONTROL2_SFOUTORD_SHIFT)
+#define CONTROL2_ACCDET_MASK (0x1 << CONTROL2_ACCDET_SHIFT)
+#define CONTROL2_USBCPINT_MASK (0x1 << CONTROL2_USBCPINT_SHIFT)
+#define CONTROL2_RCPS_MASK (0x1 << CONTROL2_RCPS_SHIFT)
+
+#define CONTROL3_JIGSET_SHIFT (0)
+#define CONTROL3_BTLDSET_SHIFT (2)
+#define CONTROL3_ADCDBSET_SHIFT (4)
+#define CONTROL3_JIGSET_MASK (0x3 << CONTROL3_JIGSET_SHIFT)
+#define CONTROL3_BTLDSET_MASK (0x3 << CONTROL3_BTLDSET_SHIFT)
+#define CONTROL3_ADCDBSET_MASK (0x3 << CONTROL3_ADCDBSET_SHIFT)
+
/* Slave addr = 0x90: Haptic */
enum max77693_haptic_reg {
MAX77693_HAPTIC_REG_STATUS = 0x00,
diff --git a/include/linux/mfd/max77693.h b/include/linux/mfd/max77693.h
index fe03b2d35d4f..3109a6c5c948 100644
--- a/include/linux/mfd/max77693.h
+++ b/include/linux/mfd/max77693.h
@@ -38,6 +38,15 @@ struct max77693_reg_data {
struct max77693_muic_platform_data {
struct max77693_reg_data *init_data;
int num_init_data;
+
+ int detcable_delay_ms;
+
+ /*
+ * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
+ * h/w path of COMP2/COMN1 on CONTROL1 register.
+ */
+ int path_usb;
+ int path_uart;
};
struct max77693_platform_data {
diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
index 6ae21bf47d64..fb465dfbb59e 100644
--- a/include/linux/mfd/max8997-private.h
+++ b/include/linux/mfd/max8997-private.h
@@ -194,6 +194,70 @@ enum max8997_muic_reg {
MAX8997_MUIC_REG_END = 0xf,
};
+/* MAX8997-MUIC STATUS1 register */
+#define STATUS1_ADC_SHIFT 0
+#define STATUS1_ADCLOW_SHIFT 5
+#define STATUS1_ADCERR_SHIFT 6
+#define STATUS1_ADC_MASK (0x1f << STATUS1_ADC_SHIFT)
+#define STATUS1_ADCLOW_MASK (0x1 << STATUS1_ADCLOW_SHIFT)
+#define STATUS1_ADCERR_MASK (0x1 << STATUS1_ADCERR_SHIFT)
+
+/* MAX8997-MUIC STATUS2 register */
+#define STATUS2_CHGTYP_SHIFT 0
+#define STATUS2_CHGDETRUN_SHIFT 3
+#define STATUS2_DCDTMR_SHIFT 4
+#define STATUS2_DBCHG_SHIFT 5
+#define STATUS2_VBVOLT_SHIFT 6
+#define STATUS2_CHGTYP_MASK (0x7 << STATUS2_CHGTYP_SHIFT)
+#define STATUS2_CHGDETRUN_MASK (0x1 << STATUS2_CHGDETRUN_SHIFT)
+#define STATUS2_DCDTMR_MASK (0x1 << STATUS2_DCDTMR_SHIFT)
+#define STATUS2_DBCHG_MASK (0x1 << STATUS2_DBCHG_SHIFT)
+#define STATUS2_VBVOLT_MASK (0x1 << STATUS2_VBVOLT_SHIFT)
+
+/* MAX8997-MUIC STATUS3 register */
+#define STATUS3_OVP_SHIFT 2
+#define STATUS3_OVP_MASK (0x1 << STATUS3_OVP_SHIFT)
+
+/* MAX8997-MUIC CONTROL1 register */
+#define COMN1SW_SHIFT 0
+#define COMP2SW_SHIFT 3
+#define COMN1SW_MASK (0x7 << COMN1SW_SHIFT)
+#define COMP2SW_MASK (0x7 << COMP2SW_SHIFT)
+#define COMP_SW_MASK (COMP2SW_MASK | COMN1SW_MASK)
+
+#define CONTROL1_SW_USB ((1 << COMP2SW_SHIFT) \
+ | (1 << COMN1SW_SHIFT))
+#define CONTROL1_SW_AUDIO ((2 << COMP2SW_SHIFT) \
+ | (2 << COMN1SW_SHIFT))
+#define CONTROL1_SW_UART ((3 << COMP2SW_SHIFT) \
+ | (3 << COMN1SW_SHIFT))
+#define CONTROL1_SW_OPEN ((0 << COMP2SW_SHIFT) \
+ | (0 << COMN1SW_SHIFT))
+
+#define CONTROL2_LOWPWR_SHIFT (0)
+#define CONTROL2_ADCEN_SHIFT (1)
+#define CONTROL2_CPEN_SHIFT (2)
+#define CONTROL2_SFOUTASRT_SHIFT (3)
+#define CONTROL2_SFOUTORD_SHIFT (4)
+#define CONTROL2_ACCDET_SHIFT (5)
+#define CONTROL2_USBCPINT_SHIFT (6)
+#define CONTROL2_RCPS_SHIFT (7)
+#define CONTROL2_LOWPWR_MASK (0x1 << CONTROL2_LOWPWR_SHIFT)
+#define CONTROL2_ADCEN_MASK (0x1 << CONTROL2_ADCEN_SHIFT)
+#define CONTROL2_CPEN_MASK (0x1 << CONTROL2_CPEN_SHIFT)
+#define CONTROL2_SFOUTASRT_MASK (0x1 << CONTROL2_SFOUTASRT_SHIFT)
+#define CONTROL2_SFOUTORD_MASK (0x1 << CONTROL2_SFOUTORD_SHIFT)
+#define CONTROL2_ACCDET_MASK (0x1 << CONTROL2_ACCDET_SHIFT)
+#define CONTROL2_USBCPINT_MASK (0x1 << CONTROL2_USBCPINT_SHIFT)
+#define CONTROL2_RCPS_MASK (0x1 << CONTROL2_RCPS_SHIFT)
+
+#define CONTROL3_JIGSET_SHIFT (0)
+#define CONTROL3_BTLDSET_SHIFT (2)
+#define CONTROL3_ADCDBSET_SHIFT (4)
+#define CONTROL3_JIGSET_MASK (0x3 << CONTROL3_JIGSET_SHIFT)
+#define CONTROL3_BTLDSET_MASK (0x3 << CONTROL3_BTLDSET_SHIFT)
+#define CONTROL3_ADCDBSET_MASK (0x3 << CONTROL3_ADCDBSET_SHIFT)
+
enum max8997_haptic_reg {
MAX8997_HAPTIC_REG_GENERAL = 0x00,
MAX8997_HAPTIC_REG_CONF1 = 0x01,
diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
index 1d4a4fe6ac33..cf815577bd68 100644
--- a/include/linux/mfd/max8997.h
+++ b/include/linux/mfd/max8997.h
@@ -78,21 +78,6 @@ struct max8997_regulator_data {
struct device_node *reg_node;
};
-enum max8997_muic_usb_type {
- MAX8997_USB_HOST,
- MAX8997_USB_DEVICE,
-};
-
-enum max8997_muic_charger_type {
- MAX8997_CHARGER_TYPE_NONE = 0,
- MAX8997_CHARGER_TYPE_USB,
- MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT,
- MAX8997_CHARGER_TYPE_DEDICATED_CHG,
- MAX8997_CHARGER_TYPE_500MA,
- MAX8997_CHARGER_TYPE_1A,
- MAX8997_CHARGER_TYPE_DEAD_BATTERY = 7,
-};
-
struct max8997_muic_reg_data {
u8 addr;
u8 data;
@@ -107,6 +92,16 @@ struct max8997_muic_reg_data {
struct max8997_muic_platform_data {
struct max8997_muic_reg_data *init_data;
int num_init_data;
+
+ /* Check cable state after certain delay */
+ int detcable_delay_ms;
+
+ /*
+ * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
+ * h/w path of COMP2/COMN1 on CONTROL1 register.
+ */
+ int path_usb;
+ int path_uart;
};
enum max8997_haptic_motor_type {
diff --git a/include/linux/ntb.h b/include/linux/ntb.h
new file mode 100644
index 000000000000..f6a15205853b
--- /dev/null
+++ b/include/linux/ntb.h
@@ -0,0 +1,83 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2012 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copy
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Intel PCIe NTB Linux driver
+ *
+ * Contact Information:
+ * Jon Mason <jon.mason@intel.com>
+ */
+
+struct ntb_transport_qp;
+
+struct ntb_client {
+ struct device_driver driver;
+ int (*probe) (struct pci_dev *pdev);
+ void (*remove) (struct pci_dev *pdev);
+};
+
+int ntb_register_client(struct ntb_client *drvr);
+void ntb_unregister_client(struct ntb_client *drvr);
+int ntb_register_client_dev(char *device_name);
+void ntb_unregister_client_dev(char *device_name);
+
+struct ntb_queue_handlers {
+ void (*rx_handler) (struct ntb_transport_qp *qp, void *qp_data,
+ void *data, int len);
+ void (*tx_handler) (struct ntb_transport_qp *qp, void *qp_data,
+ void *data, int len);
+ void (*event_handler) (void *data, int status);
+};
+
+unsigned char ntb_transport_qp_num(struct ntb_transport_qp *qp);
+unsigned int ntb_transport_max_size(struct ntb_transport_qp *qp);
+struct ntb_transport_qp *
+ntb_transport_create_queue(void *data, struct pci_dev *pdev,
+ const struct ntb_queue_handlers *handlers);
+void ntb_transport_free_queue(struct ntb_transport_qp *qp);
+int ntb_transport_rx_enqueue(struct ntb_transport_qp *qp, void *cb, void *data,
+ unsigned int len);
+int ntb_transport_tx_enqueue(struct ntb_transport_qp *qp, void *cb, void *data,
+ unsigned int len);
+void *ntb_transport_rx_remove(struct ntb_transport_qp *qp, unsigned int *len);
+void ntb_transport_link_up(struct ntb_transport_qp *qp);
+void ntb_transport_link_down(struct ntb_transport_qp *qp);
+bool ntb_transport_link_query(struct ntb_transport_qp *qp);
diff --git a/include/linux/vmw_vmci_api.h b/include/linux/vmw_vmci_api.h
new file mode 100644
index 000000000000..023430e265fe
--- /dev/null
+++ b/include/linux/vmw_vmci_api.h
@@ -0,0 +1,82 @@
+/*
+ * VMware VMCI Driver
+ *
+ * Copyright (C) 2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef __VMW_VMCI_API_H__
+#define __VMW_VMCI_API_H__
+
+#include <linux/uidgid.h>
+#include <linux/vmw_vmci_defs.h>
+
+#undef VMCI_KERNEL_API_VERSION
+#define VMCI_KERNEL_API_VERSION_1 1
+#define VMCI_KERNEL_API_VERSION_2 2
+#define VMCI_KERNEL_API_VERSION VMCI_KERNEL_API_VERSION_2
+
+typedef void (vmci_device_shutdown_fn) (void *device_registration,
+ void *user_data);
+
+int vmci_datagram_create_handle(u32 resource_id, u32 flags,
+ vmci_datagram_recv_cb recv_cb,
+ void *client_data,
+ struct vmci_handle *out_handle);
+int vmci_datagram_create_handle_priv(u32 resource_id, u32 flags, u32 priv_flags,
+ vmci_datagram_recv_cb recv_cb,
+ void *client_data,
+ struct vmci_handle *out_handle);
+int vmci_datagram_destroy_handle(struct vmci_handle handle);
+int vmci_datagram_send(struct vmci_datagram *msg);
+int vmci_doorbell_create(struct vmci_handle *handle, u32 flags,
+ u32 priv_flags,
+ vmci_callback notify_cb, void *client_data);
+int vmci_doorbell_destroy(struct vmci_handle handle);
+int vmci_doorbell_notify(struct vmci_handle handle, u32 priv_flags);
+u32 vmci_get_context_id(void);
+bool vmci_is_context_owner(u32 context_id, kuid_t uid);
+
+int vmci_event_subscribe(u32 event,
+ vmci_event_cb callback, void *callback_data,
+ u32 *subid);
+int vmci_event_unsubscribe(u32 subid);
+u32 vmci_context_get_priv_flags(u32 context_id);
+int vmci_qpair_alloc(struct vmci_qp **qpair,
+ struct vmci_handle *handle,
+ u64 produce_qsize,
+ u64 consume_qsize,
+ u32 peer, u32 flags, u32 priv_flags);
+int vmci_qpair_detach(struct vmci_qp **qpair);
+int vmci_qpair_get_produce_indexes(const struct vmci_qp *qpair,
+ u64 *producer_tail,
+ u64 *consumer_head);
+int vmci_qpair_get_consume_indexes(const struct vmci_qp *qpair,
+ u64 *consumer_tail,
+ u64 *producer_head);
+s64 vmci_qpair_produce_free_space(const struct vmci_qp *qpair);
+s64 vmci_qpair_produce_buf_ready(const struct vmci_qp *qpair);
+s64 vmci_qpair_consume_free_space(const struct vmci_qp *qpair);
+s64 vmci_qpair_consume_buf_ready(const struct vmci_qp *qpair);
+ssize_t vmci_qpair_enqueue(struct vmci_qp *qpair,
+ const void *buf, size_t buf_size, int mode);
+ssize_t vmci_qpair_dequeue(struct vmci_qp *qpair,
+ void *buf, size_t buf_size, int mode);
+ssize_t vmci_qpair_peek(struct vmci_qp *qpair, void *buf, size_t buf_size,
+ int mode);
+ssize_t vmci_qpair_enquev(struct vmci_qp *qpair,
+ void *iov, size_t iov_size, int mode);
+ssize_t vmci_qpair_dequev(struct vmci_qp *qpair,
+ void *iov, size_t iov_size, int mode);
+ssize_t vmci_qpair_peekv(struct vmci_qp *qpair, void *iov, size_t iov_size,
+ int mode);
+
+#endif /* !__VMW_VMCI_API_H__ */
diff --git a/include/linux/vmw_vmci_defs.h b/include/linux/vmw_vmci_defs.h
new file mode 100644
index 000000000000..65ac54c61c18
--- /dev/null
+++ b/include/linux/vmw_vmci_defs.h
@@ -0,0 +1,880 @@
+/*
+ * VMware VMCI Driver
+ *
+ * Copyright (C) 2012 VMware, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2 and no later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _VMW_VMCI_DEF_H_
+#define _VMW_VMCI_DEF_H_
+
+#include <linux/atomic.h>
+
+/* Register offsets. */
+#define VMCI_STATUS_ADDR 0x00
+#define VMCI_CONTROL_ADDR 0x04
+#define VMCI_ICR_ADDR 0x08
+#define VMCI_IMR_ADDR 0x0c
+#define VMCI_DATA_OUT_ADDR 0x10
+#define VMCI_DATA_IN_ADDR 0x14
+#define VMCI_CAPS_ADDR 0x18
+#define VMCI_RESULT_LOW_ADDR 0x1c
+#define VMCI_RESULT_HIGH_ADDR 0x20
+
+/* Max number of devices. */
+#define VMCI_MAX_DEVICES 1
+
+/* Status register bits. */
+#define VMCI_STATUS_INT_ON 0x1
+
+/* Control register bits. */
+#define VMCI_CONTROL_RESET 0x1
+#define VMCI_CONTROL_INT_ENABLE 0x2
+#define VMCI_CONTROL_INT_DISABLE 0x4
+
+/* Capabilities register bits. */
+#define VMCI_CAPS_HYPERCALL 0x1
+#define VMCI_CAPS_GUESTCALL 0x2
+#define VMCI_CAPS_DATAGRAM 0x4
+#define VMCI_CAPS_NOTIFICATIONS 0x8
+
+/* Interrupt Cause register bits. */
+#define VMCI_ICR_DATAGRAM 0x1
+#define VMCI_ICR_NOTIFICATION 0x2
+
+/* Interrupt Mask register bits. */
+#define VMCI_IMR_DATAGRAM 0x1
+#define VMCI_IMR_NOTIFICATION 0x2
+
+/* Interrupt type. */
+enum {
+ VMCI_INTR_TYPE_INTX = 0,
+ VMCI_INTR_TYPE_MSI = 1,
+ VMCI_INTR_TYPE_MSIX = 2,
+};
+
+/* Maximum MSI/MSI-X interrupt vectors in the device. */
+#define VMCI_MAX_INTRS 2
+
+/*
+ * Supported interrupt vectors. There is one for each ICR value above,
+ * but here they indicate the position in the vector array/message ID.
+ */
+enum {
+ VMCI_INTR_DATAGRAM = 0,
+ VMCI_INTR_NOTIFICATION = 1,
+};
+
+/*
+ * A single VMCI device has an upper limit of 128MB on the amount of
+ * memory that can be used for queue pairs.
+ */
+#define VMCI_MAX_GUEST_QP_MEMORY (128 * 1024 * 1024)
+
+/*
+ * Queues with pre-mapped data pages must be small, so that we don't pin
+ * too much kernel memory (especially on vmkernel). We limit a queuepair to
+ * 32 KB, or 16 KB per queue for symmetrical pairs.
+ */
+#define VMCI_MAX_PINNED_QP_MEMORY (32 * 1024)
+
+/*
+ * We have a fixed set of resource IDs available in the VMX.
+ * This allows us to have a very simple implementation since we statically
+ * know how many will create datagram handles. If a new caller arrives and
+ * we have run out of slots we can manually increment the maximum size of
+ * available resource IDs.
+ *
+ * VMCI reserved hypervisor datagram resource IDs.
+ */
+enum {
+ VMCI_RESOURCES_QUERY = 0,
+ VMCI_GET_CONTEXT_ID = 1,
+ VMCI_SET_NOTIFY_BITMAP = 2,
+ VMCI_DOORBELL_LINK = 3,
+ VMCI_DOORBELL_UNLINK = 4,
+ VMCI_DOORBELL_NOTIFY = 5,
+ /*
+ * VMCI_DATAGRAM_REQUEST_MAP and VMCI_DATAGRAM_REMOVE_MAP are
+ * obsoleted by the removal of VM to VM communication.
+ */
+ VMCI_DATAGRAM_REQUEST_MAP = 6,
+ VMCI_DATAGRAM_REMOVE_MAP = 7,
+ VMCI_EVENT_SUBSCRIBE = 8,
+ VMCI_EVENT_UNSUBSCRIBE = 9,
+ VMCI_QUEUEPAIR_ALLOC = 10,
+ VMCI_QUEUEPAIR_DETACH = 11,
+
+ /*
+ * VMCI_VSOCK_VMX_LOOKUP was assigned to 12 for Fusion 3.0/3.1,
+ * WS 7.0/7.1 and ESX 4.1
+ */
+ VMCI_HGFS_TRANSPORT = 13,
+ VMCI_UNITY_PBRPC_REGISTER = 14,
+ VMCI_RPC_PRIVILEGED = 15,
+ VMCI_RPC_UNPRIVILEGED = 16,
+ VMCI_RESOURCE_MAX = 17,
+};
+
+/*
+ * struct vmci_handle - Ownership information structure
+ * @context: The VMX context ID.
+ * @resource: The resource ID (used for locating in resource hash).
+ *
+ * The vmci_handle structure is used to track resources used within
+ * vmw_vmci.
+ */
+struct vmci_handle {
+ u32 context;
+ u32 resource;
+};
+
+#define vmci_make_handle(_cid, _rid) \
+ (struct vmci_handle){ .context = _cid, .resource = _rid }
+
+static inline bool vmci_handle_is_equal(struct vmci_handle h1,
+ struct vmci_handle h2)
+{
+ return h1.context == h2.context && h1.resource == h2.resource;
+}
+
+#define VMCI_INVALID_ID ~0
+static const struct vmci_handle VMCI_INVALID_HANDLE = {
+ .context = VMCI_INVALID_ID,
+ .resource = VMCI_INVALID_ID
+};
+
+static inline bool vmci_handle_is_invalid(struct vmci_handle h)
+{
+ return vmci_handle_is_equal(h, VMCI_INVALID_HANDLE);
+}
+
+/*
+ * The below defines can be used to send anonymous requests.
+ * This also indicates that no response is expected.
+ */
+#define VMCI_ANON_SRC_CONTEXT_ID VMCI_INVALID_ID
+#define VMCI_ANON_SRC_RESOURCE_ID VMCI_INVALID_ID
+static const struct vmci_handle VMCI_ANON_SRC_HANDLE = {
+ .context = VMCI_ANON_SRC_CONTEXT_ID,
+ .resource = VMCI_ANON_SRC_RESOURCE_ID
+};
+
+/* The lowest 16 context ids are reserved for internal use. */
+#define VMCI_RESERVED_CID_LIMIT ((u32) 16)
+
+/*
+ * Hypervisor context id, used for calling into hypervisor
+ * supplied services from the VM.
+ */
+#define VMCI_HYPERVISOR_CONTEXT_ID 0
+
+/*
+ * Well-known context id, a logical context that contains a set of
+ * well-known services. This context ID is now obsolete.
+ */
+#define VMCI_WELL_KNOWN_CONTEXT_ID 1
+
+/*
+ * Context ID used by host endpoints.
+ */
+#define VMCI_HOST_CONTEXT_ID 2
+
+#define VMCI_CONTEXT_IS_VM(_cid) (VMCI_INVALID_ID != (_cid) && \
+ (_cid) > VMCI_HOST_CONTEXT_ID)
+
+/*
+ * The VMCI_CONTEXT_RESOURCE_ID is used together with vmci_make_handle to make
+ * handles that refer to a specific context.
+ */
+#define VMCI_CONTEXT_RESOURCE_ID 0
+
+/*
+ * VMCI error codes.
+ */
+enum {
+ VMCI_SUCCESS_QUEUEPAIR_ATTACH = 5,
+ VMCI_SUCCESS_QUEUEPAIR_CREATE = 4,
+ VMCI_SUCCESS_LAST_DETACH = 3,
+ VMCI_SUCCESS_ACCESS_GRANTED = 2,
+ VMCI_SUCCESS_ENTRY_DEAD = 1,
+ VMCI_SUCCESS = 0,
+ VMCI_ERROR_INVALID_RESOURCE = (-1),
+ VMCI_ERROR_INVALID_ARGS = (-2),
+ VMCI_ERROR_NO_MEM = (-3),
+ VMCI_ERROR_DATAGRAM_FAILED = (-4),
+ VMCI_ERROR_MORE_DATA = (-5),
+ VMCI_ERROR_NO_MORE_DATAGRAMS = (-6),
+ VMCI_ERROR_NO_ACCESS = (-7),
+ VMCI_ERROR_NO_HANDLE = (-8),
+ VMCI_ERROR_DUPLICATE_ENTRY = (-9),
+ VMCI_ERROR_DST_UNREACHABLE = (-10),
+ VMCI_ERROR_PAYLOAD_TOO_LARGE = (-11),
+ VMCI_ERROR_INVALID_PRIV = (-12),
+ VMCI_ERROR_GENERIC = (-13),
+ VMCI_ERROR_PAGE_ALREADY_SHARED = (-14),
+ VMCI_ERROR_CANNOT_SHARE_PAGE = (-15),
+ VMCI_ERROR_CANNOT_UNSHARE_PAGE = (-16),
+ VMCI_ERROR_NO_PROCESS = (-17),
+ VMCI_ERROR_NO_DATAGRAM = (-18),
+ VMCI_ERROR_NO_RESOURCES = (-19),
+ VMCI_ERROR_UNAVAILABLE = (-20),
+ VMCI_ERROR_NOT_FOUND = (-21),
+ VMCI_ERROR_ALREADY_EXISTS = (-22),
+ VMCI_ERROR_NOT_PAGE_ALIGNED = (-23),
+ VMCI_ERROR_INVALID_SIZE = (-24),
+ VMCI_ERROR_REGION_ALREADY_SHARED = (-25),
+ VMCI_ERROR_TIMEOUT = (-26),
+ VMCI_ERROR_DATAGRAM_INCOMPLETE = (-27),
+ VMCI_ERROR_INCORRECT_IRQL = (-28),
+ VMCI_ERROR_EVENT_UNKNOWN = (-29),
+ VMCI_ERROR_OBSOLETE = (-30),
+ VMCI_ERROR_QUEUEPAIR_MISMATCH = (-31),
+ VMCI_ERROR_QUEUEPAIR_NOTSET = (-32),
+ VMCI_ERROR_QUEUEPAIR_NOTOWNER = (-33),
+ VMCI_ERROR_QUEUEPAIR_NOTATTACHED = (-34),
+ VMCI_ERROR_QUEUEPAIR_NOSPACE = (-35),
+ VMCI_ERROR_QUEUEPAIR_NODATA = (-36),
+ VMCI_ERROR_BUSMEM_INVALIDATION = (-37),
+ VMCI_ERROR_MODULE_NOT_LOADED = (-38),
+ VMCI_ERROR_DEVICE_NOT_FOUND = (-39),
+ VMCI_ERROR_QUEUEPAIR_NOT_READY = (-40),
+ VMCI_ERROR_WOULD_BLOCK = (-41),
+
+ /* VMCI clients should return error code within this range */
+ VMCI_ERROR_CLIENT_MIN = (-500),
+ VMCI_ERROR_CLIENT_MAX = (-550),
+
+ /* Internal error codes. */
+ VMCI_SHAREDMEM_ERROR_BAD_CONTEXT = (-1000),
+};
+
+/* VMCI reserved events. */
+enum {
+ /* Only applicable to guest endpoints */
+ VMCI_EVENT_CTX_ID_UPDATE = 0,
+
+ /* Applicable to guest and host */
+ VMCI_EVENT_CTX_REMOVED = 1,
+
+ /* Only applicable to guest endpoints */
+ VMCI_EVENT_QP_RESUMED = 2,
+
+ /* Applicable to guest and host */
+ VMCI_EVENT_QP_PEER_ATTACH = 3,
+
+ /* Applicable to guest and host */
+ VMCI_EVENT_QP_PEER_DETACH = 4,
+
+ /*
+ * Applicable to VMX and vmk. On vmk,
+ * this event has the Context payload type.
+ */
+ VMCI_EVENT_MEM_ACCESS_ON = 5,
+
+ /*
+ * Applicable to VMX and vmk. Same as
+ * above for the payload type.
+ */
+ VMCI_EVENT_MEM_ACCESS_OFF = 6,
+ VMCI_EVENT_MAX = 7,
+};
+
+/*
+ * Of the above events, a few are reserved for use in the VMX, and
+ * other endpoints (guest and host kernel) should not use them. For
+ * the rest of the events, we allow both host and guest endpoints to
+ * subscribe to them, to maintain the same API for host and guest
+ * endpoints.
+ */
+#define VMCI_EVENT_VALID_VMX(_event) ((_event) == VMCI_EVENT_MEM_ACCESS_ON || \
+ (_event) == VMCI_EVENT_MEM_ACCESS_OFF)
+
+#define VMCI_EVENT_VALID(_event) ((_event) < VMCI_EVENT_MAX && \
+ !VMCI_EVENT_VALID_VMX(_event))
+
+/* Reserved guest datagram resource ids. */
+#define VMCI_EVENT_HANDLER 0
+
+/*
+ * VMCI coarse-grained privileges (per context or host
+ * process/endpoint. An entity with the restricted flag is only
+ * allowed to interact with the hypervisor and trusted entities.
+ */
+enum {
+ VMCI_NO_PRIVILEGE_FLAGS = 0,
+ VMCI_PRIVILEGE_FLAG_RESTRICTED = 1,
+ VMCI_PRIVILEGE_FLAG_TRUSTED = 2,
+ VMCI_PRIVILEGE_ALL_FLAGS = (VMCI_PRIVILEGE_FLAG_RESTRICTED |
+ VMCI_PRIVILEGE_FLAG_TRUSTED),
+ VMCI_DEFAULT_PROC_PRIVILEGE_FLAGS = VMCI_NO_PRIVILEGE_FLAGS,
+ VMCI_LEAST_PRIVILEGE_FLAGS = VMCI_PRIVILEGE_FLAG_RESTRICTED,
+ VMCI_MAX_PRIVILEGE_FLAGS = VMCI_PRIVILEGE_FLAG_TRUSTED,
+};
+
+/* 0 through VMCI_RESERVED_RESOURCE_ID_MAX are reserved. */
+#define VMCI_RESERVED_RESOURCE_ID_MAX 1023
+
+/*
+ * Driver version.
+ *
+ * Increment major version when you make an incompatible change.
+ * Compatibility goes both ways (old driver with new executable
+ * as well as new driver with old executable).
+ */
+
+/* Never change VMCI_VERSION_SHIFT_WIDTH */
+#define VMCI_VERSION_SHIFT_WIDTH 16
+#define VMCI_MAKE_VERSION(_major, _minor) \
+ ((_major) << VMCI_VERSION_SHIFT_WIDTH | (u16) (_minor))
+
+#define VMCI_VERSION_MAJOR(v) ((u32) (v) >> VMCI_VERSION_SHIFT_WIDTH)
+#define VMCI_VERSION_MINOR(v) ((u16) (v))
+
+/*
+ * VMCI_VERSION is always the current version. Subsequently listed
+ * versions are ways of detecting previous versions of the connecting
+ * application (i.e., VMX).
+ *
+ * VMCI_VERSION_NOVMVM: This version removed support for VM to VM
+ * communication.
+ *
+ * VMCI_VERSION_NOTIFY: This version introduced doorbell notification
+ * support.
+ *
+ * VMCI_VERSION_HOSTQP: This version introduced host end point support
+ * for hosted products.
+ *
+ * VMCI_VERSION_PREHOSTQP: This is the version prior to the adoption of
+ * support for host end-points.
+ *
+ * VMCI_VERSION_PREVERS2: This fictional version number is intended to
+ * represent the version of a VMX which doesn't call into the driver
+ * with ioctl VERSION2 and thus doesn't establish its version with the
+ * driver.
+ */
+
+#define VMCI_VERSION VMCI_VERSION_NOVMVM
+#define VMCI_VERSION_NOVMVM VMCI_MAKE_VERSION(11, 0)
+#define VMCI_VERSION_NOTIFY VMCI_MAKE_VERSION(10, 0)
+#define VMCI_VERSION_HOSTQP VMCI_MAKE_VERSION(9, 0)
+#define VMCI_VERSION_PREHOSTQP VMCI_MAKE_VERSION(8, 0)
+#define VMCI_VERSION_PREVERS2 VMCI_MAKE_VERSION(1, 0)
+
+#define VMCI_SOCKETS_MAKE_VERSION(_p) \
+ ((((_p)[0] & 0xFF) << 24) | (((_p)[1] & 0xFF) << 16) | ((_p)[2]))
+
+/*
+ * The VMCI IOCTLs. We use identity code 7, as noted in ioctl-number.h, and
+ * we start at sequence 9f. This gives us the same values that our shipping
+ * products use, starting at 1951, provided we leave out the direction and
+ * structure size. Note that VMMon occupies the block following us, starting
+ * at 2001.
+ */
+#define IOCTL_VMCI_VERSION _IO(7, 0x9f) /* 1951 */
+#define IOCTL_VMCI_INIT_CONTEXT _IO(7, 0xa0)
+#define IOCTL_VMCI_QUEUEPAIR_SETVA _IO(7, 0xa4)
+#define IOCTL_VMCI_NOTIFY_RESOURCE _IO(7, 0xa5)
+#define IOCTL_VMCI_NOTIFICATIONS_RECEIVE _IO(7, 0xa6)
+#define IOCTL_VMCI_VERSION2 _IO(7, 0xa7)
+#define IOCTL_VMCI_QUEUEPAIR_ALLOC _IO(7, 0xa8)
+#define IOCTL_VMCI_QUEUEPAIR_SETPAGEFILE _IO(7, 0xa9)
+#define IOCTL_VMCI_QUEUEPAIR_DETACH _IO(7, 0xaa)
+#define IOCTL_VMCI_DATAGRAM_SEND _IO(7, 0xab)
+#define IOCTL_VMCI_DATAGRAM_RECEIVE _IO(7, 0xac)
+#define IOCTL_VMCI_CTX_ADD_NOTIFICATION _IO(7, 0xaf)
+#define IOCTL_VMCI_CTX_REMOVE_NOTIFICATION _IO(7, 0xb0)
+#define IOCTL_VMCI_CTX_GET_CPT_STATE _IO(7, 0xb1)
+#define IOCTL_VMCI_CTX_SET_CPT_STATE _IO(7, 0xb2)
+#define IOCTL_VMCI_GET_CONTEXT_ID _IO(7, 0xb3)
+#define IOCTL_VMCI_SOCKETS_VERSION _IO(7, 0xb4)
+#define IOCTL_VMCI_SOCKETS_GET_AF_VALUE _IO(7, 0xb8)
+#define IOCTL_VMCI_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9)
+#define IOCTL_VMCI_SET_NOTIFY _IO(7, 0xcb) /* 1995 */
+/*IOCTL_VMMON_START _IO(7, 0xd1)*/ /* 2001 */
+
+/*
+ * struct vmci_queue_header - VMCI Queue Header information.
+ *
+ * A Queue cannot stand by itself as designed. Each Queue's header
+ * contains a pointer into itself (the producer_tail) and into its peer
+ * (consumer_head). The reason for the separation is one of
+ * accessibility: Each end-point can modify two things: where the next
+ * location to enqueue is within its produce_q (producer_tail); and
+ * where the next dequeue location is in its consume_q (consumer_head).
+ *
+ * An end-point cannot modify the pointers of its peer (guest to
+ * guest; NOTE that in the host both queue headers are mapped r/w).
+ * But, each end-point needs read access to both Queue header
+ * structures in order to determine how much space is used (or left)
+ * in the Queue. This is because for an end-point to know how full
+ * its produce_q is, it needs to use the consumer_head that points into
+ * the produce_q but -that- consumer_head is in the Queue header for
+ * that end-points consume_q.
+ *
+ * Thoroughly confused? Sorry.
+ *
+ * producer_tail: the point to enqueue new entrants. When you approach
+ * a line in a store, for example, you walk up to the tail.
+ *
+ * consumer_head: the point in the queue from which the next element is
+ * dequeued. In other words, who is next in line is he who is at the
+ * head of the line.
+ *
+ * Also, producer_tail points to an empty byte in the Queue, whereas
+ * consumer_head points to a valid byte of data (unless producer_tail ==
+ * consumer_head in which case consumer_head does not point to a valid
+ * byte of data).
+ *
+ * For a queue of buffer 'size' bytes, the tail and head pointers will be in
+ * the range [0, size-1].
+ *
+ * If produce_q_header->producer_tail == consume_q_header->consumer_head
+ * then the produce_q is empty.
+ */
+struct vmci_queue_header {
+ /* All fields are 64bit and aligned. */
+ struct vmci_handle handle; /* Identifier. */
+ atomic64_t producer_tail; /* Offset in this queue. */
+ atomic64_t consumer_head; /* Offset in peer queue. */
+};
+
+/*
+ * struct vmci_datagram - Base struct for vmci datagrams.
+ * @dst: A vmci_handle that tracks the destination of the datagram.
+ * @src: A vmci_handle that tracks the source of the datagram.
+ * @payload_size: The size of the payload.
+ *
+ * vmci_datagram structs are used when sending vmci datagrams. They include
+ * the necessary source and destination information to properly route
+ * the information along with the size of the package.
+ */
+struct vmci_datagram {
+ struct vmci_handle dst;
+ struct vmci_handle src;
+ u64 payload_size;
+};
+
+/*
+ * Second flag is for creating a well-known handle instead of a per context
+ * handle. Next flag is for deferring datagram delivery, so that the
+ * datagram callback is invoked in a delayed context (not interrupt context).
+ */
+#define VMCI_FLAG_DG_NONE 0
+#define VMCI_FLAG_WELLKNOWN_DG_HND 0x1
+#define VMCI_FLAG_ANYCID_DG_HND 0x2
+#define VMCI_FLAG_DG_DELAYED_CB 0x4
+
+/*
+ * Maximum supported size of a VMCI datagram for routable datagrams.
+ * Datagrams going to the hypervisor are allowed to be larger.
+ */
+#define VMCI_MAX_DG_SIZE (17 * 4096)
+#define VMCI_MAX_DG_PAYLOAD_SIZE (VMCI_MAX_DG_SIZE - \
+ sizeof(struct vmci_datagram))
+#define VMCI_DG_PAYLOAD(_dg) (void *)((char *)(_dg) + \
+ sizeof(struct vmci_datagram))
+#define VMCI_DG_HEADERSIZE sizeof(struct vmci_datagram)
+#define VMCI_DG_SIZE(_dg) (VMCI_DG_HEADERSIZE + (size_t)(_dg)->payload_size)
+#define VMCI_DG_SIZE_ALIGNED(_dg) ((VMCI_DG_SIZE(_dg) + 7) & (~((size_t) 0x7)))
+#define VMCI_MAX_DATAGRAM_QUEUE_SIZE (VMCI_MAX_DG_SIZE * 2)
+
+struct vmci_event_payload_qp {
+ struct vmci_handle handle; /* queue_pair handle. */
+ u32 peer_id; /* Context id of attaching/detaching VM. */
+ u32 _pad;
+};
+
+/* Flags for VMCI queue_pair API. */
+enum {
+ /* Fail alloc if QP not created by peer. */
+ VMCI_QPFLAG_ATTACH_ONLY = 1 << 0,
+
+ /* Only allow attaches from local context. */
+ VMCI_QPFLAG_LOCAL = 1 << 1,
+
+ /* Host won't block when guest is quiesced. */
+ VMCI_QPFLAG_NONBLOCK = 1 << 2,
+
+ /* Pin data pages in ESX. Used with NONBLOCK */
+ VMCI_QPFLAG_PINNED = 1 << 3,
+
+ /* Update the following flag when adding new flags. */
+ VMCI_QP_ALL_FLAGS = (VMCI_QPFLAG_ATTACH_ONLY | VMCI_QPFLAG_LOCAL |
+ VMCI_QPFLAG_NONBLOCK | VMCI_QPFLAG_PINNED),
+
+ /* Convenience flags */
+ VMCI_QP_ASYMM = (VMCI_QPFLAG_NONBLOCK | VMCI_QPFLAG_PINNED),
+ VMCI_QP_ASYMM_PEER = (VMCI_QPFLAG_ATTACH_ONLY | VMCI_QP_ASYMM),
+};
+
+/*
+ * We allow at least 1024 more event datagrams from the hypervisor past the
+ * normally allowed datagrams pending for a given context. We define this
+ * limit on event datagrams from the hypervisor to guard against DoS attack
+ * from a malicious VM which could repeatedly attach to and detach from a queue
+ * pair, causing events to be queued at the destination VM. However, the rate
+ * at which such events can be generated is small since it requires a VM exit
+ * and handling of queue pair attach/detach call at the hypervisor. Event
+ * datagrams may be queued up at the destination VM if it has interrupts
+ * disabled or if it is not draining events for some other reason. 1024
+ * datagrams is a grossly conservative estimate of the time for which
+ * interrupts may be disabled in the destination VM, but at the same time does
+ * not exacerbate the memory pressure problem on the host by much (size of each
+ * event datagram is small).
+ */
+#define VMCI_MAX_DATAGRAM_AND_EVENT_QUEUE_SIZE \
+ (VMCI_MAX_DATAGRAM_QUEUE_SIZE + \
+ 1024 * (sizeof(struct vmci_datagram) + \
+ sizeof(struct vmci_event_data_max)))
+
+/*
+ * Struct used for querying, via VMCI_RESOURCES_QUERY, the availability of
+ * hypervisor resources. Struct size is 16 bytes. All fields in struct are
+ * aligned to their natural alignment.
+ */
+struct vmci_resource_query_hdr {
+ struct vmci_datagram hdr;
+ u32 num_resources;
+ u32 _padding;
+};
+
+/*
+ * Convenience struct for negotiating vectors. Must match layout of
+ * VMCIResourceQueryHdr minus the struct vmci_datagram header.
+ */
+struct vmci_resource_query_msg {
+ u32 num_resources;
+ u32 _padding;
+ u32 resources[1];
+};
+
+/*
+ * The maximum number of resources that can be queried using
+ * VMCI_RESOURCE_QUERY is 31, as the result is encoded in the lower 31
+ * bits of a positive return value. Negative values are reserved for
+ * errors.
+ */
+#define VMCI_RESOURCE_QUERY_MAX_NUM 31
+
+/* Maximum size for the VMCI_RESOURCE_QUERY request. */
+#define VMCI_RESOURCE_QUERY_MAX_SIZE \
+ (sizeof(struct vmci_resource_query_hdr) + \
+ sizeof(u32) * VMCI_RESOURCE_QUERY_MAX_NUM)
+
+/*
+ * Struct used for setting the notification bitmap. All fields in
+ * struct are aligned to their natural alignment.
+ */
+struct vmci_notify_bm_set_msg {
+ struct vmci_datagram hdr;
+ u32 bitmap_ppn;
+ u32 _pad;
+};
+
+/*
+ * Struct used for linking a doorbell handle with an index in the
+ * notify bitmap. All fields in struct are aligned to their natural
+ * alignment.
+ */
+struct vmci_doorbell_link_msg {
+ struct vmci_datagram hdr;
+ struct vmci_handle handle;
+ u64 notify_idx;
+};
+
+/*
+ * Struct used for unlinking a doorbell handle from an index in the
+ * notify bitmap. All fields in struct are aligned to their natural
+ * alignment.
+ */
+struct vmci_doorbell_unlink_msg {
+ struct vmci_datagram hdr;
+ struct vmci_handle handle;
+};
+
+/*
+ * Struct used for generating a notification on a doorbell handle. All
+ * fields in struct are aligned to their natural alignment.
+ */
+struct vmci_doorbell_notify_msg {
+ struct vmci_datagram hdr;
+ struct vmci_handle handle;
+};
+
+/*
+ * This struct is used to contain data for events. Size of this struct is a
+ * multiple of 8 bytes, and all fields are aligned to their natural alignment.
+ */
+struct vmci_event_data {
+ u32 event; /* 4 bytes. */
+ u32 _pad;
+ /* Event payload is put here. */
+};
+
+/*
+ * Define the different VMCI_EVENT payload data types here. All structs must
+ * be a multiple of 8 bytes, and fields must be aligned to their natural
+ * alignment.
+ */
+struct vmci_event_payld_ctx {
+ u32 context_id; /* 4 bytes. */
+ u32 _pad;
+};
+
+struct vmci_event_payld_qp {
+ struct vmci_handle handle; /* queue_pair handle. */
+ u32 peer_id; /* Context id of attaching/detaching VM. */
+ u32 _pad;
+};
+
+/*
+ * We define the following struct to get the size of the maximum event
+ * data the hypervisor may send to the guest. If adding a new event
+ * payload type above, add it to the following struct too (inside the
+ * union).
+ */
+struct vmci_event_data_max {
+ struct vmci_event_data event_data;
+ union {
+ struct vmci_event_payld_ctx context_payload;
+ struct vmci_event_payld_qp qp_payload;
+ } ev_data_payload;
+};
+
+/*
+ * Struct used for VMCI_EVENT_SUBSCRIBE/UNSUBSCRIBE and
+ * VMCI_EVENT_HANDLER messages. Struct size is 32 bytes. All fields
+ * in struct are aligned to their natural alignment.
+ */
+struct vmci_event_msg {
+ struct vmci_datagram hdr;
+
+ /* Has event type and payload. */
+ struct vmci_event_data event_data;
+
+ /* Payload gets put here. */
+};
+
+/* Event with context payload. */
+struct vmci_event_ctx {
+ struct vmci_event_msg msg;
+ struct vmci_event_payld_ctx payload;
+};
+
+/* Event with QP payload. */
+struct vmci_event_qp {
+ struct vmci_event_msg msg;
+ struct vmci_event_payld_qp payload;
+};
+
+/*
+ * Structs used for queue_pair alloc and detach messages. We align fields of
+ * these structs to 64bit boundaries.
+ */
+struct vmci_qp_alloc_msg {
+ struct vmci_datagram hdr;
+ struct vmci_handle handle;
+ u32 peer;
+ u32 flags;
+ u64 produce_size;
+ u64 consume_size;
+ u64 num_ppns;
+
+ /* List of PPNs placed here. */
+};
+
+struct vmci_qp_detach_msg {
+ struct vmci_datagram hdr;
+ struct vmci_handle handle;
+};
+
+/* VMCI Doorbell API. */
+#define VMCI_FLAG_DELAYED_CB 0x01
+
+typedef void (*vmci_callback) (void *client_data);
+
+/*
+ * struct vmci_qp - A vmw_vmci queue pair handle.
+ *
+ * This structure is used as a handle to a queue pair created by
+ * VMCI. It is intentionally left opaque to clients.
+ */
+struct vmci_qp;
+
+/* Callback needed for correctly waiting on events. */
+typedef int (*vmci_datagram_recv_cb) (void *client_data,
+ struct vmci_datagram *msg);
+
+/* VMCI Event API. */
+typedef void (*vmci_event_cb) (u32 sub_id, const struct vmci_event_data *ed,
+ void *client_data);
+
+/*
+ * We use the following inline function to access the payload data
+ * associated with an event data.
+ */
+static inline const void *
+vmci_event_data_const_payload(const struct vmci_event_data *ev_data)
+{
+ return (const char *)ev_data + sizeof(*ev_data);
+}
+
+static inline void *vmci_event_data_payload(struct vmci_event_data *ev_data)
+{
+ return (void *)vmci_event_data_const_payload(ev_data);
+}
+
+/*
+ * Helper to add a given offset to a head or tail pointer. Wraps the
+ * value of the pointer around the max size of the queue.
+ */
+static inline void vmci_qp_add_pointer(atomic64_t *var,
+ size_t add,
+ u64 size)
+{
+ u64 new_val = atomic64_read(var);
+
+ if (new_val >= size - add)
+ new_val -= size;
+
+ new_val += add;
+
+ atomic64_set(var, new_val);
+}
+
+/*
+ * Helper routine to get the Producer Tail from the supplied queue.
+ */
+static inline u64
+vmci_q_header_producer_tail(const struct vmci_queue_header *q_header)
+{
+ struct vmci_queue_header *qh = (struct vmci_queue_header *)q_header;
+ return atomic64_read(&qh->producer_tail);
+}
+
+/*
+ * Helper routine to get the Consumer Head from the supplied queue.
+ */
+static inline u64
+vmci_q_header_consumer_head(const struct vmci_queue_header *q_header)
+{
+ struct vmci_queue_header *qh = (struct vmci_queue_header *)q_header;
+ return atomic64_read(&qh->consumer_head);
+}
+
+/*
+ * Helper routine to increment the Producer Tail. Fundamentally,
+ * vmci_qp_add_pointer() is used to manipulate the tail itself.
+ */
+static inline void
+vmci_q_header_add_producer_tail(struct vmci_queue_header *q_header,
+ size_t add,
+ u64 queue_size)
+{
+ vmci_qp_add_pointer(&q_header->producer_tail, add, queue_size);
+}
+
+/*
+ * Helper routine to increment the Consumer Head. Fundamentally,
+ * vmci_qp_add_pointer() is used to manipulate the head itself.
+ */
+static inline void
+vmci_q_header_add_consumer_head(struct vmci_queue_header *q_header,
+ size_t add,
+ u64 queue_size)
+{
+ vmci_qp_add_pointer(&q_header->consumer_head, add, queue_size);
+}
+
+/*
+ * Helper routine for getting the head and the tail pointer for a queue.
+ * Both the VMCIQueues are needed to get both the pointers for one queue.
+ */
+static inline void
+vmci_q_header_get_pointers(const struct vmci_queue_header *produce_q_header,
+ const struct vmci_queue_header *consume_q_header,
+ u64 *producer_tail,
+ u64 *consumer_head)
+{
+ if (producer_tail)
+ *producer_tail = vmci_q_header_producer_tail(produce_q_header);
+
+ if (consumer_head)
+ *consumer_head = vmci_q_header_consumer_head(consume_q_header);
+}
+
+static inline void vmci_q_header_init(struct vmci_queue_header *q_header,
+ const struct vmci_handle handle)
+{
+ q_header->handle = handle;
+ atomic64_set(&q_header->producer_tail, 0);
+ atomic64_set(&q_header->consumer_head, 0);
+}
+
+/*
+ * Finds available free space in a produce queue to enqueue more
+ * data or reports an error if queue pair corruption is detected.
+ */
+static s64
+vmci_q_header_free_space(const struct vmci_queue_header *produce_q_header,
+ const struct vmci_queue_header *consume_q_header,
+ const u64 produce_q_size)
+{
+ u64 tail;
+ u64 head;
+ u64 free_space;
+
+ tail = vmci_q_header_producer_tail(produce_q_header);
+ head = vmci_q_header_consumer_head(consume_q_header);
+
+ if (tail >= produce_q_size || head >= produce_q_size)
+ return VMCI_ERROR_INVALID_SIZE;
+
+ /*
+ * Deduct 1 to avoid tail becoming equal to head which causes
+ * ambiguity. If head and tail are equal it means that the
+ * queue is empty.
+ */
+ if (tail >= head)
+ free_space = produce_q_size - (tail - head) - 1;
+ else
+ free_space = head - tail - 1;
+
+ return free_space;
+}
+
+/*
+ * vmci_q_header_free_space() does all the heavy lifting of
+ * determing the number of free bytes in a Queue. This routine,
+ * then subtracts that size from the full size of the Queue so
+ * the caller knows how many bytes are ready to be dequeued.
+ * Results:
+ * On success, available data size in bytes (up to MAX_INT64).
+ * On failure, appropriate error code.
+ */
+static inline s64
+vmci_q_header_buf_ready(const struct vmci_queue_header *consume_q_header,
+ const struct vmci_queue_header *produce_q_header,
+ const u64 consume_q_size)
+{
+ s64 free_space;
+
+ free_space = vmci_q_header_free_space(consume_q_header,
+ produce_q_header, consume_q_size);
+ if (free_space < VMCI_SUCCESS)
+ return free_space;
+
+ return consume_q_size - free_space - 1;
+}
+
+
+#endif /* _VMW_VMCI_DEF_H_ */
OpenPOWER on IntegriCloud