mei: allow read concurrency

Replace clunky read state machine with read stack
implemented as per client read list, this is important
mostly for mei drivers with unsolicited reads

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Tomas Winkler
2015-02-10 10:39:46 +02:00
committed by Greg Kroah-Hartman
parent 928fa6664b
commit a9bed61053
8 changed files with 98 additions and 119 deletions

View File

@@ -68,18 +68,6 @@ static inline int mei_cl_hbm_equal(struct mei_cl *cl,
return cl->host_client_id == mei_hdr->host_addr &&
cl->me_client_id == mei_hdr->me_addr;
}
/**
* mei_cl_is_reading - checks if the client is in reading state
*
* @cl: mei client
*
* Return: true if the client is reading
*/
static bool mei_cl_is_reading(struct mei_cl *cl)
{
return cl->state == MEI_FILE_CONNECTED &&
cl->reading_state != MEI_READ_COMPLETE;
}
/**
* mei_irq_discard_msg - discard received message
@@ -116,24 +104,18 @@ int mei_cl_irq_read_msg(struct mei_cl *cl,
struct mei_cl_cb *cb;
unsigned char *buffer = NULL;
list_for_each_entry(cb, &dev->read_list.list, list) {
if (cl == cb->cl)
break;
}
if (&cb->list == &dev->read_list.list) {
dev_err(dev->dev, "no reader found\n");
cb = list_first_entry_or_null(&cl->rd_pending, struct mei_cl_cb, list);
if (!cb) {
cl_err(dev, cl, "pending read cb not found\n");
goto out;
}
if (!mei_cl_is_reading(cl)) {
cl_err(dev, cl, "cl is not reading state=%d reading state=%d\n",
cl->state, cl->reading_state);
if (cl->state != MEI_FILE_CONNECTED) {
cl_dbg(dev, cl, "not connected\n");
cb->status = -ENODEV;
goto out;
}
cl->reading_state = MEI_READING;
if (cb->buf.size == 0 || cb->buf.data == NULL) {
cl_err(dev, cl, "response buffer is not allocated.\n");
list_move_tail(&cb->list, &complete_list->list);
@@ -163,8 +145,7 @@ int mei_cl_irq_read_msg(struct mei_cl *cl,
if (mei_hdr->msg_complete) {
cb->read_time = jiffies;
cl_dbg(dev, cl, "completed read length = %lu\n",
cb->buf_idx);
cl_dbg(dev, cl, "completed read length = %lu\n", cb->buf_idx);
list_move_tail(&cb->list, &complete_list->list);
}
@@ -281,7 +262,7 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
return ret;
}
list_move_tail(&cb->list, &dev->read_list.list);
list_move_tail(&cb->list, &cl->rd_pending);
return 0;
}