#ifndef _DEV_PV_HYPERVVAR_H_
#define _DEV_PV_HYPERVVAR_H_
#ifdef HYPERV_DEBUG
#define DPRINTF(x...) printf(x)
#else
#define DPRINTF(x...)
#endif
struct hv_softc;
struct hv_msg {
uint64_t msg_flags;
#define MSGF_NOSLEEP 0x0001
#define MSGF_NOQUEUE 0x0002
#define MSGF_ORPHANED 0x0004
struct hypercall_postmsg_in msg_req;
void *msg_rsp;
size_t msg_rsplen;
TAILQ_ENTRY(hv_msg) msg_entry;
};
TAILQ_HEAD(hv_queue, hv_msg);
struct hv_offer {
struct vmbus_chanmsg_choffer co_chan;
SIMPLEQ_ENTRY(hv_offer) co_entry;
};
SIMPLEQ_HEAD(hv_offers, hv_offer);
struct hv_ring_data {
struct vmbus_bufring *rd_ring;
uint32_t rd_size;
struct mutex rd_lock;
uint32_t rd_prod;
uint32_t rd_cons;
uint32_t rd_dsize;
};
struct hv_channel {
struct hv_softc *ch_sc;
int ch_state;
#define HV_CHANSTATE_OFFERED 1
#define HV_CHANSTATE_OPENED 2
#define HV_CHANSTATE_CLOSING 3
#define HV_CHANSTATE_CLOSED 4
uint32_t ch_id;
struct hv_guid ch_type;
struct hv_guid ch_inst;
char ch_ident[38];
void *ch_ring;
uint32_t ch_ring_gpadl;
u_long ch_ring_size;
struct hv_ring_data ch_wrd;
struct hv_ring_data ch_rrd;
uint32_t ch_vcpu;
void (*ch_handler)(void *);
void *ch_ctx;
struct evcount ch_evcnt;
struct taskq *ch_taskq;
struct task ch_task;
uint32_t ch_flags;
#define CHF_BATCHED 0x0001
#define CHF_MONITOR 0x0002
uint8_t ch_mgroup;
uint8_t ch_mindex;
struct hv_mon_param ch_monprm __attribute__((aligned(8)));
TAILQ_ENTRY(hv_channel) ch_entry;
};
TAILQ_HEAD(hv_channels, hv_channel);
struct hv_attach_args {
void *aa_parent;
bus_dma_tag_t aa_dmat;
struct hv_guid *aa_type;
struct hv_guid *aa_inst;
char *aa_ident;
struct hv_channel *aa_chan;
};
struct hv_dev {
struct hv_attach_args dv_aa;
SLIST_ENTRY(hv_dev) dv_entry;
};
SLIST_HEAD(hv_devices, hv_dev);
struct hv_softc {
struct device sc_dev;
struct pvbus_hv *sc_pvbus;
struct bus_dma_tag *sc_dmat;
void *sc_hc;
uint32_t sc_features;
uint32_t sc_flags;
#define HSF_CONNECTED 0x0001
#define HSF_OFFERS_DELIVERED 0x0002
int sc_idtvec;
int sc_proto;
uint32_t sc_vcpus[1];
void *sc_simp[1];
void *sc_siep[1];
void *sc_events;
u_long *sc_wevents;
u_long *sc_revents;
struct vmbus_mnf *sc_monitor[2];
struct hv_queue sc_reqs;
struct mutex sc_reqlck;
struct hv_queue sc_rsps;
struct mutex sc_rsplck;
struct hv_offers sc_offers;
struct mutex sc_offerlck;
struct hv_channels sc_channels;
struct mutex sc_channelck;
volatile uint32_t sc_handle;
struct hv_devices sc_devs;
struct mutex sc_devlck;
struct task sc_sdtask;
struct ksensordev sc_sensordev;
struct ksensor sc_sensor;
};
static __inline void
clear_bit(u_int b, volatile void *p)
{
atomic_clearbits_int(((volatile u_int *)p) + (b >> 5), 1 << (b & 0x1f));
}
static __inline void
set_bit(u_int b, volatile void *p)
{
atomic_setbits_int(((volatile u_int *)p) + (b >> 5), 1 << (b & 0x1f));
}
static __inline int
test_bit(u_int b, volatile void *p)
{
return !!(((volatile u_int *)p)[b >> 5] & (1 << (b & 0x1f)));
}
extern const struct hv_guid hv_guid_network;
extern const struct hv_guid hv_guid_ide;
extern const struct hv_guid hv_guid_scsi;
extern const struct hv_guid hv_guid_shutdown;
extern const struct hv_guid hv_guid_timesync;
extern const struct hv_guid hv_guid_heartbeat;
extern const struct hv_guid hv_guid_kvp;
#ifdef HYPERV_DEBUG
extern const struct hv_guid hv_guid_vss;
extern const struct hv_guid hv_guid_dynmem;
extern const struct hv_guid hv_guid_mouse;
extern const struct hv_guid hv_guid_kbd;
extern const struct hv_guid hv_guid_video;
extern const struct hv_guid hv_guid_fc;
extern const struct hv_guid hv_guid_fcopy;
extern const struct hv_guid hv_guid_pcie;
extern const struct hv_guid hv_guid_netdir;
extern const struct hv_guid hv_guid_rdesktop;
extern const struct hv_guid hv_guid_avma1;
extern const struct hv_guid hv_guid_avma2;
extern const struct hv_guid hv_guid_avma3;
extern const struct hv_guid hv_guid_avma4;
#endif
int hv_handle_alloc(struct hv_channel *, void *, uint32_t, uint32_t *);
void hv_handle_free(struct hv_channel *, uint32_t);
int hv_channel_open(struct hv_channel *, size_t, void *, size_t,
void (*)(void *), void *);
int hv_channel_close(struct hv_channel *);
int hv_channel_setdeferred(struct hv_channel *, const char *);
void hv_channel_schedule(struct hv_channel *);
void hv_evcount_attach(struct hv_channel *, const char *);
int hv_channel_send(struct hv_channel *, void *, uint32_t, uint64_t,
int, uint32_t);
int hv_channel_send_sgl(struct hv_channel *, struct vmbus_gpa *,
uint32_t, void *, uint32_t, uint64_t);
int hv_channel_send_prpl(struct hv_channel *, struct vmbus_gpa_range *,
uint32_t, void *, uint32_t, uint64_t);
int hv_channel_recv(struct hv_channel *, void *, uint32_t, uint32_t *,
uint64_t *, int);
#endif