|
@@ -267,8 +267,7 @@ static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots)
|
|
|
+ sizeof(struct hbm_flow_control))) {
|
|
|
return -EMSGSIZE;
|
|
|
}
|
|
|
- *slots -= (sizeof(struct mei_msg_hdr) +
|
|
|
- sizeof(struct hbm_flow_control) + 3) / 4;
|
|
|
+ *slots -= mei_data2slots(sizeof(struct hbm_flow_control));
|
|
|
if (mei_send_flow_control(dev, &dev->iamthif_cl)) {
|
|
|
dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n");
|
|
|
return -EIO;
|
|
@@ -280,7 +279,7 @@ static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots)
|
|
|
dev->iamthif_msg_buf_index = 0;
|
|
|
dev->iamthif_msg_buf_size = 0;
|
|
|
dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER;
|
|
|
- dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev);
|
|
|
+ dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -300,28 +299,25 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
|
|
|
struct mei_cl *cl,
|
|
|
struct mei_io_list *cmpl_list)
|
|
|
{
|
|
|
- if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
|
|
|
- sizeof(struct hbm_client_disconnect_request))) {
|
|
|
- *slots -= (sizeof(struct mei_msg_hdr) +
|
|
|
- sizeof(struct hbm_client_disconnect_request) + 3) / 4;
|
|
|
+ if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
|
|
|
+ sizeof(struct hbm_client_disconnect_request)))
|
|
|
+ return -EBADMSG;
|
|
|
|
|
|
- if (mei_disconnect(dev, cl)) {
|
|
|
- cl->status = 0;
|
|
|
- cb_pos->information = 0;
|
|
|
- list_move_tail(&cb_pos->cb_list,
|
|
|
- &cmpl_list->mei_cb.cb_list);
|
|
|
- return -EMSGSIZE;
|
|
|
- } else {
|
|
|
- cl->state = MEI_FILE_DISCONNECTING;
|
|
|
- cl->status = 0;
|
|
|
- cb_pos->information = 0;
|
|
|
- list_move_tail(&cb_pos->cb_list,
|
|
|
- &dev->ctrl_rd_list.mei_cb.cb_list);
|
|
|
- cl->timer_count = MEI_CONNECT_TIMEOUT;
|
|
|
- }
|
|
|
+ *slots -= mei_data2slots(sizeof(struct hbm_client_disconnect_request));
|
|
|
+
|
|
|
+ if (mei_disconnect(dev, cl)) {
|
|
|
+ cl->status = 0;
|
|
|
+ cb_pos->information = 0;
|
|
|
+ list_move_tail(&cb_pos->cb_list,
|
|
|
+ &cmpl_list->mei_cb.cb_list);
|
|
|
+ return -EMSGSIZE;
|
|
|
} else {
|
|
|
- /* return the cancel routine */
|
|
|
- return -EBADMSG;
|
|
|
+ cl->state = MEI_FILE_DISCONNECTING;
|
|
|
+ cl->status = 0;
|
|
|
+ cb_pos->information = 0;
|
|
|
+ list_move_tail(&cb_pos->cb_list,
|
|
|
+ &dev->ctrl_rd_list.mei_cb.cb_list);
|
|
|
+ cl->timer_count = MEI_CONNECT_TIMEOUT;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -575,10 +571,9 @@ static void mei_client_disconnect_request(struct mei_device *dev,
|
|
|
disconnect_req->me_addr);
|
|
|
cl_pos->state = MEI_FILE_DISCONNECTED;
|
|
|
cl_pos->timer_count = 0;
|
|
|
- if (cl_pos == &dev->wd_cl) {
|
|
|
- dev->wd_due_counter = 0;
|
|
|
+ if (cl_pos == &dev->wd_cl)
|
|
|
dev->wd_pending = false;
|
|
|
- } else if (cl_pos == &dev->iamthif_cl)
|
|
|
+ else if (cl_pos == &dev->iamthif_cl)
|
|
|
dev->iamthif_timer = 0;
|
|
|
|
|
|
/* prepare disconnect response */
|
|
@@ -842,8 +837,8 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots,
|
|
|
return -EBADMSG;
|
|
|
}
|
|
|
|
|
|
- *slots -= (sizeof(struct mei_msg_hdr) +
|
|
|
- sizeof(struct hbm_flow_control) + 3) / 4;
|
|
|
+ *slots -= mei_data2slots(sizeof(struct hbm_flow_control));
|
|
|
+
|
|
|
if (mei_send_flow_control(dev, cl)) {
|
|
|
cl->status = -ENODEV;
|
|
|
cb_pos->information = 0;
|
|
@@ -872,27 +867,25 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
|
|
|
struct mei_cl *cl,
|
|
|
struct mei_io_list *cmpl_list)
|
|
|
{
|
|
|
- if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
|
|
|
+ if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) +
|
|
|
sizeof(struct hbm_client_connect_request))) {
|
|
|
- cl->state = MEI_FILE_CONNECTING;
|
|
|
- *slots -= (sizeof(struct mei_msg_hdr) +
|
|
|
- sizeof(struct hbm_client_connect_request) + 3) / 4;
|
|
|
- if (mei_connect(dev, cl)) {
|
|
|
- cl->status = -ENODEV;
|
|
|
- cb_pos->information = 0;
|
|
|
- list_del(&cb_pos->cb_list);
|
|
|
- return -ENODEV;
|
|
|
- } else {
|
|
|
- list_move_tail(&cb_pos->cb_list,
|
|
|
- &dev->ctrl_rd_list.mei_cb.cb_list);
|
|
|
- cl->timer_count = MEI_CONNECT_TIMEOUT;
|
|
|
- }
|
|
|
- } else {
|
|
|
/* return the cancel routine */
|
|
|
list_del(&cb_pos->cb_list);
|
|
|
return -EBADMSG;
|
|
|
}
|
|
|
|
|
|
+ cl->state = MEI_FILE_CONNECTING;
|
|
|
+ *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request));
|
|
|
+ if (mei_connect(dev, cl)) {
|
|
|
+ cl->status = -ENODEV;
|
|
|
+ cb_pos->information = 0;
|
|
|
+ list_del(&cb_pos->cb_list);
|
|
|
+ return -ENODEV;
|
|
|
+ } else {
|
|
|
+ list_move_tail(&cb_pos->cb_list,
|
|
|
+ &dev->ctrl_rd_list.mei_cb.cb_list);
|
|
|
+ cl->timer_count = MEI_CONNECT_TIMEOUT;
|
|
|
+ }
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -932,8 +925,7 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots,
|
|
|
cb_pos->information);
|
|
|
dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n",
|
|
|
mei_hdr->length);
|
|
|
- *slots -= (sizeof(struct mei_msg_hdr) +
|
|
|
- mei_hdr->length + 3) / 4;
|
|
|
+ *slots -= mei_data2slots(mei_hdr->length);
|
|
|
if (mei_write_message(dev, mei_hdr,
|
|
|
(unsigned char *)
|
|
|
(cb_pos->request_buffer.data +
|
|
@@ -951,7 +943,7 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots,
|
|
|
list_move_tail(&cb_pos->cb_list,
|
|
|
&dev->write_waiting_list.mei_cb.cb_list);
|
|
|
}
|
|
|
- } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) {
|
|
|
+ } else if (*slots == dev->hbuf_depth) {
|
|
|
/* buffer is still empty */
|
|
|
mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
|
|
|
mei_hdr->host_addr = cl->host_client_id;
|
|
@@ -960,9 +952,7 @@ static int _mei_irq_thread_cmpl(struct mei_device *dev, s32 *slots,
|
|
|
(*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
|
|
|
mei_hdr->msg_complete = 0;
|
|
|
mei_hdr->reserved = 0;
|
|
|
-
|
|
|
- (*slots) -= (sizeof(struct mei_msg_hdr) +
|
|
|
- mei_hdr->length + 3) / 4;
|
|
|
+ *slots -= mei_data2slots(mei_hdr->length);
|
|
|
if (mei_write_message(dev, mei_hdr,
|
|
|
(unsigned char *)
|
|
|
(cb_pos->request_buffer.data +
|
|
@@ -1021,8 +1011,7 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots,
|
|
|
mei_hdr->msg_complete = 1;
|
|
|
mei_hdr->reserved = 0;
|
|
|
|
|
|
- *slots -= (sizeof(struct mei_msg_hdr) +
|
|
|
- mei_hdr->length + 3) / 4;
|
|
|
+ *slots -= mei_data2slots(mei_hdr->length);
|
|
|
|
|
|
if (mei_write_message(dev, mei_hdr,
|
|
|
(dev->iamthif_msg_buf +
|
|
@@ -1046,8 +1035,8 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots,
|
|
|
&dev->write_waiting_list.mei_cb.cb_list);
|
|
|
|
|
|
}
|
|
|
- } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) {
|
|
|
- /* buffer is still empty */
|
|
|
+ } else if (*slots == dev->hbuf_depth) {
|
|
|
+ /* buffer is still empty */
|
|
|
mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
|
|
|
mei_hdr->host_addr = cl->host_client_id;
|
|
|
mei_hdr->me_addr = cl->me_client_id;
|
|
@@ -1056,8 +1045,7 @@ static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots,
|
|
|
mei_hdr->msg_complete = 0;
|
|
|
mei_hdr->reserved = 0;
|
|
|
|
|
|
- *slots -= (sizeof(struct mei_msg_hdr) +
|
|
|
- mei_hdr->length + 3) / 4;
|
|
|
+ *slots -= mei_data2slots(mei_hdr->length);
|
|
|
|
|
|
if (mei_write_message(dev, mei_hdr,
|
|
|
(dev->iamthif_msg_buf +
|
|
@@ -1199,17 +1187,19 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
|
|
|
struct mei_io_list *list;
|
|
|
int ret;
|
|
|
|
|
|
- if (!mei_host_buffer_is_empty(dev)) {
|
|
|
+ if (!mei_hbuf_is_empty(dev)) {
|
|
|
dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n");
|
|
|
return 0;
|
|
|
}
|
|
|
- *slots = mei_count_empty_write_slots(dev);
|
|
|
+ *slots = mei_hbuf_empty_slots(dev);
|
|
|
+ if (*slots <= 0)
|
|
|
+ return -EMSGSIZE;
|
|
|
+
|
|
|
/* complete all waiting for write CB */
|
|
|
dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n");
|
|
|
|
|
|
list = &dev->write_waiting_list;
|
|
|
- list_for_each_entry_safe(pos, next,
|
|
|
- &list->mei_cb.cb_list, cb_list) {
|
|
|
+ list_for_each_entry_safe(pos, next, &list->mei_cb.cb_list, cb_list) {
|
|
|
cl = (struct mei_cl *)pos->file_private;
|
|
|
if (cl == NULL)
|
|
|
continue;
|
|
@@ -1219,17 +1209,15 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
|
|
|
if (MEI_WRITING == cl->writing_state &&
|
|
|
(pos->major_file_operations == MEI_WRITE) &&
|
|
|
(cl != &dev->iamthif_cl)) {
|
|
|
- dev_dbg(&dev->pdev->dev,
|
|
|
- "MEI WRITE COMPLETE\n");
|
|
|
+ dev_dbg(&dev->pdev->dev, "MEI WRITE COMPLETE\n");
|
|
|
cl->writing_state = MEI_WRITE_COMPLETE;
|
|
|
list_add_tail(&pos->cb_list,
|
|
|
- &cmpl_list->mei_cb.cb_list);
|
|
|
+ &cmpl_list->mei_cb.cb_list);
|
|
|
}
|
|
|
if (cl == &dev->iamthif_cl) {
|
|
|
dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
|
|
|
if (dev->iamthif_flow_control_pending) {
|
|
|
- ret = _mei_irq_thread_iamthif_read(
|
|
|
- dev, slots);
|
|
|
+ ret = _mei_irq_thread_iamthif_read(dev, slots);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
}
|
|
@@ -1254,25 +1242,18 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
|
|
|
}
|
|
|
if (dev->mei_state == MEI_ENABLED) {
|
|
|
if (dev->wd_pending &&
|
|
|
- mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
|
|
|
+ mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
|
|
|
if (mei_wd_send(dev))
|
|
|
dev_dbg(&dev->pdev->dev, "wd send failed.\n");
|
|
|
- else
|
|
|
- if (mei_flow_ctrl_reduce(dev, &dev->wd_cl))
|
|
|
- return -ENODEV;
|
|
|
+ else if (mei_flow_ctrl_reduce(dev, &dev->wd_cl))
|
|
|
+ return -ENODEV;
|
|
|
|
|
|
dev->wd_pending = false;
|
|
|
|
|
|
- if (dev->wd_timeout) {
|
|
|
- *slots -= (sizeof(struct mei_msg_hdr) +
|
|
|
- MEI_START_WD_DATA_SIZE + 3) / 4;
|
|
|
- dev->wd_due_counter = 2;
|
|
|
- } else {
|
|
|
- *slots -= (sizeof(struct mei_msg_hdr) +
|
|
|
- MEI_WD_PARAMS_SIZE + 3) / 4;
|
|
|
- dev->wd_due_counter = 0;
|
|
|
- }
|
|
|
-
|
|
|
+ if (dev->wd_timeout)
|
|
|
+ *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE);
|
|
|
+ else
|
|
|
+ *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE);
|
|
|
}
|
|
|
}
|
|
|
if (dev->stop)
|
|
@@ -1320,42 +1301,34 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
|
|
|
/* complete write list CB */
|
|
|
dev_dbg(&dev->pdev->dev, "complete write list cb.\n");
|
|
|
list_for_each_entry_safe(pos, next,
|
|
|
- &dev->write_list.mei_cb.cb_list, cb_list) {
|
|
|
+ &dev->write_list.mei_cb.cb_list, cb_list) {
|
|
|
cl = (struct mei_cl *)pos->file_private;
|
|
|
if (cl == NULL)
|
|
|
continue;
|
|
|
|
|
|
if (cl != &dev->iamthif_cl) {
|
|
|
- if (!mei_flow_ctrl_creds(dev, cl)) {
|
|
|
+ if (mei_flow_ctrl_creds(dev, cl) <= 0) {
|
|
|
dev_dbg(&dev->pdev->dev,
|
|
|
- "No flow control"
|
|
|
- " credentials for client"
|
|
|
- " %d, not sending.\n",
|
|
|
- cl->host_client_id);
|
|
|
+ "No flow control credentials for client %d, not sending.\n",
|
|
|
+ cl->host_client_id);
|
|
|
continue;
|
|
|
}
|
|
|
- ret = _mei_irq_thread_cmpl(dev, slots,
|
|
|
- pos,
|
|
|
- cl, cmpl_list);
|
|
|
+ ret = _mei_irq_thread_cmpl(dev, slots, pos,
|
|
|
+ cl, cmpl_list);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
|
} else if (cl == &dev->iamthif_cl) {
|
|
|
/* IAMTHIF IOCTL */
|
|
|
dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n");
|
|
|
- if (!mei_flow_ctrl_creds(dev, cl)) {
|
|
|
+ if (mei_flow_ctrl_creds(dev, cl) <= 0) {
|
|
|
dev_dbg(&dev->pdev->dev,
|
|
|
- "No flow control"
|
|
|
- " credentials for amthi"
|
|
|
- " client %d.\n",
|
|
|
- cl->host_client_id);
|
|
|
+ "No flow control credentials for amthi client %d.\n",
|
|
|
+ cl->host_client_id);
|
|
|
continue;
|
|
|
}
|
|
|
- ret = _mei_irq_thread_cmpl_iamthif(dev,
|
|
|
- slots,
|
|
|
- pos,
|
|
|
- cl,
|
|
|
- cmpl_list);
|
|
|
+ ret = _mei_irq_thread_cmpl_iamthif(dev, slots, pos,
|
|
|
+ cl, cmpl_list);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|
|
@@ -1555,7 +1528,7 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
|
|
|
end:
|
|
|
dev_dbg(&dev->pdev->dev, "end of bottom half function.\n");
|
|
|
dev->host_hw_state = mei_hcsr_read(dev);
|
|
|
- dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev);
|
|
|
+ dev->mei_host_buffer_is_empty = mei_hbuf_is_empty(dev);
|
|
|
|
|
|
bus_message_received = false;
|
|
|
if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) {
|