dm: mei: add native io handlers
Add read write and connect handler, that perform io peration on SOS /dev/meiX device. Tracked-On: #1536 Signed-off-by: Vitaly Lubart <vitaly.lubart@intel.com> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Acked-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
parent
3abbf10e55
commit
98c6b7a692
|
@ -974,6 +974,159 @@ static int vmei_add_reset_event(struct virtio_mei *vmei)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint8_t
|
||||||
|
errno_to_hbm_conn_status(int err)
|
||||||
|
{
|
||||||
|
switch (err) {
|
||||||
|
case 0: return MEI_CL_CONN_SUCCESS;
|
||||||
|
case ENOTTY: return MEI_CL_CONN_NOT_FOUND;
|
||||||
|
case EBUSY: return MEI_CL_CONN_ALREADY_STARTED;
|
||||||
|
case EINVAL: return MEI_HBM_INVALID_PARAMETER;
|
||||||
|
default: return MEI_HBM_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* vmei_host_client_native_connect() connect host client
|
||||||
|
* to the native driver and register with mevent.
|
||||||
|
*
|
||||||
|
* @hclient: host client instance
|
||||||
|
* Return: HBM status cot_client
|
||||||
|
*/
|
||||||
|
static uint8_t
|
||||||
|
vmei_host_client_native_connect(struct vmei_host_client *hclient)
|
||||||
|
{
|
||||||
|
struct virtio_mei *vmei = vmei_host_client_to_vmei(hclient);
|
||||||
|
struct vmei_me_client *mclient;
|
||||||
|
struct mei_connect_client_data_vtag connection_data;
|
||||||
|
|
||||||
|
mclient = hclient->mclient;
|
||||||
|
|
||||||
|
/* open mei node */
|
||||||
|
hclient->client_fd = open(vmei->devnode, O_RDWR | O_NONBLOCK);
|
||||||
|
if (hclient->client_fd < 0) {
|
||||||
|
HCL_WARN(hclient, "open %s failed %d\n", vmei->devnode, errno);
|
||||||
|
return MEI_HBM_REJECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&connection_data, 0, sizeof(connection_data));
|
||||||
|
memcpy(&connection_data.connect.in_client_uuid,
|
||||||
|
&mclient->props.protocol_name,
|
||||||
|
sizeof(connection_data.connect.in_client_uuid));
|
||||||
|
connection_data.connect.vtag = vmei->vtag;
|
||||||
|
|
||||||
|
if (ioctl(hclient->client_fd, IOCTL_MEI_CONNECT_CLIENT_VTAG,
|
||||||
|
&connection_data) == -1) {
|
||||||
|
HCL_DBG(hclient, "connect failed %d!\n", errno);
|
||||||
|
return errno_to_hbm_conn_status(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add READ event into mevent */
|
||||||
|
hclient->rx_mevp = mevent_add(hclient->client_fd, EVF_READ,
|
||||||
|
vmei_rx_callback, hclient);
|
||||||
|
if (!hclient->rx_mevp)
|
||||||
|
return MEI_HBM_REJECTED;
|
||||||
|
|
||||||
|
if (!hclient->recv_creds)
|
||||||
|
mevent_disable(hclient->rx_mevp);
|
||||||
|
|
||||||
|
HCL_DBG(hclient, "connect succeeded!\n");
|
||||||
|
|
||||||
|
return MEI_HBM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
vmei_host_client_native_write(struct vmei_host_client *hclient)
|
||||||
|
{
|
||||||
|
struct virtio_mei *vmei = vmei_host_client_to_vmei(hclient);
|
||||||
|
ssize_t len, lencnt = 0;
|
||||||
|
int err;
|
||||||
|
unsigned int iovcnt, i;
|
||||||
|
struct vmei_circular_iobufs *bufs = &hclient->send_bufs;
|
||||||
|
|
||||||
|
if (!vmei)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (hclient->client_fd < 0) {
|
||||||
|
HCL_WARN(hclient, "invalid client fd [%d]\n",
|
||||||
|
hclient->client_fd);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bufs->i_idx == bufs->r_idx) {
|
||||||
|
/* nothing to send actually */
|
||||||
|
WPRINTF("no buffer to send\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (bufs->i_idx != bufs->r_idx) {
|
||||||
|
/*
|
||||||
|
* calculate number of entries
|
||||||
|
* while taking care of wraparound
|
||||||
|
*/
|
||||||
|
iovcnt = (bufs->i_idx > bufs->r_idx) ?
|
||||||
|
(bufs->i_idx - bufs->r_idx) :
|
||||||
|
(VMEI_IOBUFS_MAX - bufs->r_idx);
|
||||||
|
|
||||||
|
for (i = 0; i < iovcnt; i++) {
|
||||||
|
len = writev(hclient->client_fd,
|
||||||
|
&bufs->bufs[bufs->r_idx + i],
|
||||||
|
1);
|
||||||
|
if (len < 0) {
|
||||||
|
err = -errno;
|
||||||
|
if (err != -EAGAIN)
|
||||||
|
WPRINTF("write failed! error[%d]\n",
|
||||||
|
errno);
|
||||||
|
if (err == -ENODEV)
|
||||||
|
vmei_set_status(vmei,
|
||||||
|
VMEI_STS_PENDING_RESET);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
lencnt += len;
|
||||||
|
|
||||||
|
bufs->bufs[bufs->r_idx + i].iov_len = 0;
|
||||||
|
bufs->complete[bufs->r_idx + i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufs->r_idx = (bufs->i_idx > bufs->r_idx) ? bufs->i_idx : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lencnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A completed read guarantees that a client message is completed,
|
||||||
|
* transmission of client message is started by a flow control message of HBM
|
||||||
|
*/
|
||||||
|
static ssize_t
|
||||||
|
vmei_host_client_native_read(struct vmei_host_client *hclient)
|
||||||
|
{
|
||||||
|
struct virtio_mei *vmei = vmei_host_client_to_vmei(hclient);
|
||||||
|
ssize_t len;
|
||||||
|
|
||||||
|
if (hclient->client_fd < 0) {
|
||||||
|
HCL_WARN(hclient, "RX: invalid client fd\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read with max_message_length */
|
||||||
|
len = read(hclient->client_fd, hclient->recv_buf, hclient->recv_buf_sz);
|
||||||
|
if (len < 0) {
|
||||||
|
HCL_WARN(hclient, "RX: read failed! read error[%d]\n", errno);
|
||||||
|
if (errno == ENODEV)
|
||||||
|
vmei_set_status(vmei, VMEI_STS_PENDING_RESET);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
HCL_DBG(hclient, "RX: append data len=%zd at off=%d\n",
|
||||||
|
len, hclient->recv_offset);
|
||||||
|
|
||||||
|
hclient->recv_offset = len;
|
||||||
|
|
||||||
|
return hclient->recv_offset;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vmei_cfgread(void *vsc, int offset, int size, uint32_t *retval)
|
vmei_cfgread(void *vsc, int offset, int size, uint32_t *retval)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue