#ifndef _SYS_IB_CLIENTS_OF_SOL_UMAD_SOL_UMAD_H
#define _SYS_IB_CLIENTS_OF_SOL_UMAD_SOL_UMAD_H
#ifdef __cplusplus
extern "C" {
#endif
#define GET_UMAD_MINOR(node, port) ((node << 4) | port)
#define GET_ISSM_MINOR(node, port) ((node << 4) | port | 0x8000)
#define GET_NODE(minor) ((minor >> 4) & 0xf)
#define GET_PORT(minor) ((minor) & 0xf)
#define ISSM_MINOR(minor) (minor & 0x8000)
#define GET_UCTX(minor) (minor >> 8)
#define GET_NEW_UCTX_MINOR(minor, uctxnum) ((uctxnum << 8) | minor)
#define UMAD_INSTANCE 0
#define MAX_UCTX 16
typedef struct umad_port_info_s umad_port_info_t;
typedef struct umad_uctx_s {
kmutex_t uctx_lock;
umad_port_info_t *uctx_port;
struct pollhead uctx_pollhead;
llist_head_t uctx_agent_list;
kmutex_t uctx_recv_lock;
genlist_t uctx_recv_list;
kcondvar_t uctx_recv_cv;
} umad_uctx_t;
typedef struct umad_agent_s {
llist_head_t agent_list;
struct ib_user_mad_reg_req agent_req;
struct ibmf_reg_info *agent_reg;
umad_uctx_t *agent_uctx;
int agent_outstanding_msgs;
kmutex_t agent_lock;
int agent_flags;
kcondvar_t agent_cv;
} umad_agent_t;
enum umad_agent_flags {
UMAD_AGENT_UNREGISTERING = 1 << 0,
UMAD_HANDLING_ASYNC = 1 << 1
};
typedef struct umad_hca_info_s {
ib_guid_t hca_guid;
ibt_hca_hdl_t hca_handle;
ibt_hca_attr_t hca_attr;
uint8_t hca_nports;
umad_port_info_t *hca_ports;
} umad_hca_info_t;
struct umad_port_info_s {
kmutex_t port_lock;
const umad_hca_info_t *port_hca;
unsigned int port_minor_name;
uint8_t port_num;
ib_guid_t port_guid;
int port_issm_open_cnt;
ib_lid_t port_lid;
bool port_has_umad_minor_node;
bool port_has_issm_minor_node;
llist_head_t port_ibmf_regs;
};
typedef struct umad_info_s {
dev_info_t *info_dip;
kmutex_t info_mutex;
ibt_clnt_hdl_t info_clnt_hdl;
uint32_t info_hca_count;
ib_guid_t *info_hca_guids;
umad_hca_info_t *info_hcas;
umad_uctx_t *info_uctx[MAX_UCTX];
} umad_info_t;
typedef struct ib_umad_msg_s {
struct ib_user_mad_hdr umad_msg_hdr;
ibmf_msg_t *umad_msg_ibmf_msg;
} ib_umad_msg_t;
struct umad_send {
struct umad_agent_s *send_agent;
size_t send_len;
uint8_t send_umad[];
};
struct ibmf_reg_info {
ibmf_handle_t ibmf_reg_handle;
unsigned int ibmf_reg_refcnt;
umad_uctx_t *ibmf_reg_uctx;
kmutex_t ibmf_reg_lock;
kcondvar_t ibmf_cv;
unsigned int ibmf_flags;
enum _ibmf_client_type_t ibmf_class;
};
enum ibmf_flag_values {
UMAD_IBMF_UNREGISTERING = 1 << 0
};
static inline int
is_supported_mad_method(int nr, void *addr)
{
return (1 & (((uint32_t *)addr)[nr >> 5] >> (nr & 31)));
}
static int umad_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
static int umad_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
static int umad_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg,
void **resultp);
static int umad_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
int flags, char *name, caddr_t valuep,
int *lengthp);
static int umad_open(dev_t *devp, int flag, int otyp, cred_t *cred);
static int umad_close(dev_t dev, int flag, int otyp, cred_t *cred);
static int umad_read(dev_t dev, struct uio *uiop, cred_t *credp);
static int umad_write(dev_t dev, struct uio *uiop, cred_t *credp);
static int umad_poll(dev_t dev, short events, int anyyet,
short *reventsp, struct pollhead **phpp);
static int umad_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
cred_t *credp, int *rvalp);
static void umad_async_handler(void *private, ibt_hca_hdl_t hca_hdl,
ibt_async_code_t code,
ibt_async_event_t *event);
static int umad_register(struct ib_user_mad_reg_req *req,
umad_uctx_t *uctx);
static int umad_unregister(struct ib_user_mad_reg_req *agent,
umad_uctx_t *uctx);
static void umad_unsolicited_cb(ibmf_handle_t ibmf_handle,
ibmf_msg_t *msgp, void *args);
#ifdef __cplusplus
}
#endif
#endif