mei: iamthif: use regular client read functions
Reduce code duplication in amthif by reusing regular client read functions. The change also removes the need for amthif own buffering Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
8660172e1d
commit
331e418701
@ -49,8 +49,6 @@ void mei_amthif_reset_params(struct mei_device *dev)
|
|||||||
{
|
{
|
||||||
/* reset iamthif parameters. */
|
/* reset iamthif parameters. */
|
||||||
dev->iamthif_current_cb = NULL;
|
dev->iamthif_current_cb = NULL;
|
||||||
dev->iamthif_msg_buf_size = 0;
|
|
||||||
dev->iamthif_msg_buf_index = 0;
|
|
||||||
dev->iamthif_canceled = false;
|
dev->iamthif_canceled = false;
|
||||||
dev->iamthif_state = MEI_IAMTHIF_IDLE;
|
dev->iamthif_state = MEI_IAMTHIF_IDLE;
|
||||||
dev->iamthif_timer = 0;
|
dev->iamthif_timer = 0;
|
||||||
@ -69,7 +67,6 @@ int mei_amthif_host_init(struct mei_device *dev)
|
|||||||
{
|
{
|
||||||
struct mei_cl *cl = &dev->iamthif_cl;
|
struct mei_cl *cl = &dev->iamthif_cl;
|
||||||
struct mei_me_client *me_cl;
|
struct mei_me_client *me_cl;
|
||||||
unsigned char *msg_buf;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
dev->iamthif_state = MEI_IAMTHIF_IDLE;
|
dev->iamthif_state = MEI_IAMTHIF_IDLE;
|
||||||
@ -90,18 +87,6 @@ int mei_amthif_host_init(struct mei_device *dev)
|
|||||||
dev->iamthif_mtu = me_cl->props.max_msg_length;
|
dev->iamthif_mtu = me_cl->props.max_msg_length;
|
||||||
dev_dbg(dev->dev, "IAMTHIF_MTU = %d\n", dev->iamthif_mtu);
|
dev_dbg(dev->dev, "IAMTHIF_MTU = %d\n", dev->iamthif_mtu);
|
||||||
|
|
||||||
kfree(dev->iamthif_msg_buf);
|
|
||||||
dev->iamthif_msg_buf = NULL;
|
|
||||||
|
|
||||||
/* allocate storage for ME message buffer */
|
|
||||||
msg_buf = kcalloc(dev->iamthif_mtu,
|
|
||||||
sizeof(unsigned char), GFP_KERNEL);
|
|
||||||
if (!msg_buf) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev->iamthif_msg_buf = msg_buf;
|
|
||||||
|
|
||||||
ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID);
|
ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -282,9 +267,6 @@ static int mei_amthif_read_start(struct mei_cl *cl, struct file *file)
|
|||||||
cb->fop_type = MEI_FOP_READ;
|
cb->fop_type = MEI_FOP_READ;
|
||||||
list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
|
list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
|
||||||
|
|
||||||
dev->iamthif_msg_buf_index = 0;
|
|
||||||
dev->iamthif_msg_buf_size = 0;
|
|
||||||
|
|
||||||
dev->iamthif_state = MEI_IAMTHIF_READING;
|
dev->iamthif_state = MEI_IAMTHIF_READING;
|
||||||
dev->iamthif_file_object = cb->file_object;
|
dev->iamthif_file_object = cb->file_object;
|
||||||
dev->iamthif_current_cb = cb;
|
dev->iamthif_current_cb = cb;
|
||||||
@ -340,8 +322,6 @@ int mei_amthif_run_next_cmd(struct mei_device *dev)
|
|||||||
struct mei_cl *cl = &dev->iamthif_cl;
|
struct mei_cl *cl = &dev->iamthif_cl;
|
||||||
struct mei_cl_cb *cb;
|
struct mei_cl_cb *cb;
|
||||||
|
|
||||||
dev->iamthif_msg_buf_size = 0;
|
|
||||||
dev->iamthif_msg_buf_index = 0;
|
|
||||||
dev->iamthif_canceled = false;
|
dev->iamthif_canceled = false;
|
||||||
dev->iamthif_state = MEI_IAMTHIF_IDLE;
|
dev->iamthif_state = MEI_IAMTHIF_IDLE;
|
||||||
dev->iamthif_timer = 0;
|
dev->iamthif_timer = 0;
|
||||||
@ -440,66 +420,33 @@ int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
|
|||||||
*
|
*
|
||||||
* @cl: mei client
|
* @cl: mei client
|
||||||
* @mei_hdr: header of amthif message
|
* @mei_hdr: header of amthif message
|
||||||
* @complete_list: completed callbacks list
|
* @cmpl_list: completed callbacks list
|
||||||
*
|
*
|
||||||
* Return: Always 0; error message is in cb->status
|
* Return: -ENODEV if cb is NULL 0 otherwise; error message is in cb->status
|
||||||
*/
|
*/
|
||||||
int mei_amthif_irq_read_msg(struct mei_cl *cl,
|
int mei_amthif_irq_read_msg(struct mei_cl *cl,
|
||||||
struct mei_msg_hdr *mei_hdr,
|
struct mei_msg_hdr *mei_hdr,
|
||||||
struct mei_cl_cb *complete_list)
|
struct mei_cl_cb *cmpl_list)
|
||||||
{
|
{
|
||||||
struct mei_device *dev;
|
struct mei_device *dev;
|
||||||
struct mei_cl_cb *cb;
|
int ret;
|
||||||
unsigned char *buffer;
|
|
||||||
|
|
||||||
dev = cl->dev;
|
dev = cl->dev;
|
||||||
|
|
||||||
if (cl->state != MEI_FILE_CONNECTED)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (dev->iamthif_state != MEI_IAMTHIF_READING)
|
if (dev->iamthif_state != MEI_IAMTHIF_READING)
|
||||||
goto err;
|
return 0;
|
||||||
|
|
||||||
list_for_each_entry(cb, &dev->read_list.list, list) {
|
ret = mei_cl_irq_read_msg(cl, mei_hdr, cmpl_list);
|
||||||
if (cl == cb->cl)
|
if (ret)
|
||||||
break;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
if (&cb->list == &dev->read_list.list) {
|
|
||||||
dev_err(dev->dev, "no reader found\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length) {
|
|
||||||
cb->status = -ERANGE;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer = dev->iamthif_msg_buf + dev->iamthif_msg_buf_index;
|
|
||||||
mei_read_slots(dev, buffer, mei_hdr->length);
|
|
||||||
|
|
||||||
dev->iamthif_msg_buf_index += mei_hdr->length;
|
|
||||||
|
|
||||||
if (!mei_hdr->msg_complete)
|
if (!mei_hdr->msg_complete)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dev_dbg(dev->dev, "completed amthif read.\n ");
|
dev_dbg(dev->dev, "completed amthif read.\n ");
|
||||||
|
|
||||||
dev->iamthif_current_cb = NULL;
|
dev->iamthif_current_cb = NULL;
|
||||||
|
|
||||||
dev->iamthif_stall_timer = 0;
|
dev->iamthif_stall_timer = 0;
|
||||||
cb->buf_idx = dev->iamthif_msg_buf_index;
|
|
||||||
cb->read_time = jiffies;
|
|
||||||
|
|
||||||
dev_dbg(dev->dev, "complete the amthif read cb.\n ");
|
|
||||||
list_move_tail(&cb->list, &complete_list->list);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err:
|
|
||||||
mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
|
|
||||||
dev_dbg(dev->dev, "discarding message " MEI_HDR_FMT "\n",
|
|
||||||
MEI_HDR_PRM(mei_hdr));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,8 +477,6 @@ void mei_amthif_complete(struct mei_device *dev, struct mei_cl_cb *cb)
|
|||||||
if (dev->iamthif_canceled != 1) {
|
if (dev->iamthif_canceled != 1) {
|
||||||
dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE;
|
dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE;
|
||||||
dev->iamthif_stall_timer = 0;
|
dev->iamthif_stall_timer = 0;
|
||||||
memcpy(cb->response_buffer.data,
|
|
||||||
dev->iamthif_msg_buf, dev->iamthif_msg_buf_index);
|
|
||||||
list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list);
|
list_add_tail(&cb->list, &dev->amthif_rd_complete_list.list);
|
||||||
dev_dbg(dev->dev, "amthif read completed\n");
|
dev_dbg(dev->dev, "amthif read completed\n");
|
||||||
dev->iamthif_timer = jiffies;
|
dev->iamthif_timer = jiffies;
|
||||||
|
@ -102,6 +102,8 @@ bool mei_cl_is_other_connecting(struct mei_cl *cl);
|
|||||||
int mei_cl_disconnect(struct mei_cl *cl);
|
int mei_cl_disconnect(struct mei_cl *cl);
|
||||||
int mei_cl_connect(struct mei_cl *cl, struct file *file);
|
int mei_cl_connect(struct mei_cl *cl, struct file *file);
|
||||||
int mei_cl_read_start(struct mei_cl *cl, size_t length);
|
int mei_cl_read_start(struct mei_cl *cl, size_t length);
|
||||||
|
int mei_cl_irq_read_msg(struct mei_cl *cl, struct mei_msg_hdr *hdr,
|
||||||
|
struct mei_cl_cb *cmpl_list);
|
||||||
int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking);
|
int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking);
|
||||||
int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
|
int mei_cl_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
|
||||||
struct mei_cl_cb *cmpl_list);
|
struct mei_cl_cb *cmpl_list);
|
||||||
|
@ -81,6 +81,24 @@ static bool mei_cl_is_reading(struct mei_cl *cl)
|
|||||||
cl->reading_state != MEI_READ_COMPLETE;
|
cl->reading_state != MEI_READ_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mei_irq_discard_msg - discard received message
|
||||||
|
*
|
||||||
|
* @dev: mei device
|
||||||
|
* @hdr: message header
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
void mei_irq_discard_msg(struct mei_device *dev, struct mei_msg_hdr *hdr)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* no need to check for size as it is guarantied
|
||||||
|
* that length fits into rd_msg_buf
|
||||||
|
*/
|
||||||
|
mei_read_slots(dev, dev->rd_msg_buf, hdr->length);
|
||||||
|
dev_dbg(dev->dev, "discarding message " MEI_HDR_FMT "\n",
|
||||||
|
MEI_HDR_PRM(hdr));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mei_cl_irq_read_msg - process client message
|
* mei_cl_irq_read_msg - process client message
|
||||||
*
|
*
|
||||||
@ -90,9 +108,9 @@ static bool mei_cl_is_reading(struct mei_cl *cl)
|
|||||||
*
|
*
|
||||||
* Return: always 0
|
* Return: always 0
|
||||||
*/
|
*/
|
||||||
static int mei_cl_irq_read_msg(struct mei_cl *cl,
|
int mei_cl_irq_read_msg(struct mei_cl *cl,
|
||||||
struct mei_msg_hdr *mei_hdr,
|
struct mei_msg_hdr *mei_hdr,
|
||||||
struct mei_cl_cb *complete_list)
|
struct mei_cl_cb *complete_list)
|
||||||
{
|
{
|
||||||
struct mei_device *dev = cl->dev;
|
struct mei_device *dev = cl->dev;
|
||||||
struct mei_cl_cb *cb;
|
struct mei_cl_cb *cb;
|
||||||
@ -144,20 +162,17 @@ static int mei_cl_irq_read_msg(struct mei_cl *cl,
|
|||||||
mei_read_slots(dev, buffer, mei_hdr->length);
|
mei_read_slots(dev, buffer, mei_hdr->length);
|
||||||
|
|
||||||
cb->buf_idx += mei_hdr->length;
|
cb->buf_idx += mei_hdr->length;
|
||||||
|
|
||||||
if (mei_hdr->msg_complete) {
|
if (mei_hdr->msg_complete) {
|
||||||
|
cb->read_time = jiffies;
|
||||||
cl_dbg(dev, cl, "completed read length = %lu\n",
|
cl_dbg(dev, cl, "completed read length = %lu\n",
|
||||||
cb->buf_idx);
|
cb->buf_idx);
|
||||||
list_move_tail(&cb->list, &complete_list->list);
|
list_move_tail(&cb->list, &complete_list->list);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (!buffer) {
|
if (!buffer)
|
||||||
/* assume that mei_hdr->length <= MEI_RD_MSG_BUF_SIZE */
|
mei_irq_discard_msg(dev, mei_hdr);
|
||||||
BUG_ON(mei_hdr->length > MEI_RD_MSG_BUF_SIZE);
|
|
||||||
mei_read_slots(dev, dev->rd_msg_buf, mei_hdr->length);
|
|
||||||
dev_dbg(dev->dev, "discarding message " MEI_HDR_FMT "\n",
|
|
||||||
MEI_HDR_PRM(mei_hdr));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -569,8 +584,6 @@ void mei_timer(struct work_struct *work)
|
|||||||
if (--dev->iamthif_stall_timer == 0) {
|
if (--dev->iamthif_stall_timer == 0) {
|
||||||
dev_err(dev->dev, "timer: amthif hanged.\n");
|
dev_err(dev->dev, "timer: amthif hanged.\n");
|
||||||
mei_reset(dev);
|
mei_reset(dev);
|
||||||
dev->iamthif_msg_buf_size = 0;
|
|
||||||
dev->iamthif_msg_buf_index = 0;
|
|
||||||
dev->iamthif_canceled = false;
|
dev->iamthif_canceled = false;
|
||||||
dev->iamthif_state = MEI_IAMTHIF_IDLE;
|
dev->iamthif_state = MEI_IAMTHIF_IDLE;
|
||||||
dev->iamthif_timer = 0;
|
dev->iamthif_timer = 0;
|
||||||
|
@ -485,9 +485,6 @@ const char *mei_pg_state_str(enum mei_pg_state state);
|
|||||||
* @iamthif_mtu : amthif client max message length
|
* @iamthif_mtu : amthif client max message length
|
||||||
* @iamthif_timer : time stamp of current amthif command completion
|
* @iamthif_timer : time stamp of current amthif command completion
|
||||||
* @iamthif_stall_timer : timer to detect amthif hang
|
* @iamthif_stall_timer : timer to detect amthif hang
|
||||||
* @iamthif_msg_buf : amthif current message buffer
|
|
||||||
* @iamthif_msg_buf_size : size of current amthif message request buffer
|
|
||||||
* @iamthif_msg_buf_index : current index in amthif message request buffer
|
|
||||||
* @iamthif_state : amthif processor state
|
* @iamthif_state : amthif processor state
|
||||||
* @iamthif_canceled : current amthif command is canceled
|
* @iamthif_canceled : current amthif command is canceled
|
||||||
*
|
*
|
||||||
@ -583,9 +580,6 @@ struct mei_device {
|
|||||||
int iamthif_mtu;
|
int iamthif_mtu;
|
||||||
unsigned long iamthif_timer;
|
unsigned long iamthif_timer;
|
||||||
u32 iamthif_stall_timer;
|
u32 iamthif_stall_timer;
|
||||||
unsigned char *iamthif_msg_buf; /* Note: memory has to be allocated */
|
|
||||||
u32 iamthif_msg_buf_size;
|
|
||||||
u32 iamthif_msg_buf_index;
|
|
||||||
enum iamthif_states iamthif_state;
|
enum iamthif_states iamthif_state;
|
||||||
bool iamthif_canceled;
|
bool iamthif_canceled;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user