mei: don't query HCSR for host buffer depth
1. We record host (write) buffer depth during reset
so we don't need to query HCSR register later on.
The host buffer depth doesn't change after the reset
2. Use mei_hbuf_max_data function to compute payload size in bytes
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index a7d0bb0..d39b277 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -162,6 +162,9 @@
if ((dev->host_hw_state & H_IS) == H_IS)
mei_reg_write(dev, H_CSR, dev->host_hw_state);
+ /* Doesn't change in runtime */
+ dev->hbuf_depth = (dev->host_hw_state & H_CBD) >> 24;
+
dev->recvd_msg = false;
dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n");
diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c
index 6c05691..784a606 100644
--- a/drivers/misc/mei/interface.c
+++ b/drivers/misc/mei/interface.c
@@ -103,15 +103,14 @@
*/
int mei_count_empty_write_slots(struct mei_device *dev)
{
- unsigned char buffer_depth, filled_slots, empty_slots;
+ unsigned char filled_slots, empty_slots;
dev->host_hw_state = mei_hcsr_read(dev);
- buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24);
filled_slots = _host_get_filled_slots(dev);
- empty_slots = buffer_depth - filled_slots;
+ empty_slots = dev->hbuf_depth - filled_slots;
/* check for overflow */
- if (filled_slots > buffer_depth)
+ if (filled_slots > dev->hbuf_depth)
return -EOVERFLOW;
return empty_slots;
diff --git a/drivers/misc/mei/interface.h b/drivers/misc/mei/interface.h
index ddff5d1..8723d88 100644
--- a/drivers/misc/mei/interface.h
+++ b/drivers/misc/mei/interface.h
@@ -49,6 +49,12 @@
int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl);
+static inline size_t mei_hbuf_max_data(const struct mei_device *dev)
+{
+ return dev->hbuf_depth * sizeof(u32) - sizeof(struct mei_msg_hdr);
+}
+
+
int mei_wd_send(struct mei_device *dev);
int mei_wd_stop(struct mei_device *dev, bool preserve);
int mei_wd_host_init(struct mei_device *dev);
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 8e4dd74..4ad6a6b 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -951,7 +951,7 @@
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;
@@ -1046,8 +1046,8 @@
&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;
diff --git a/drivers/misc/mei/iorw.c b/drivers/misc/mei/iorw.c
index f9cced6..50f52e2 100644
--- a/drivers/misc/mei/iorw.c
+++ b/drivers/misc/mei/iorw.c
@@ -481,12 +481,8 @@
if (ret && dev->mei_host_buffer_is_empty) {
ret = 0;
dev->mei_host_buffer_is_empty = false;
- if (cb->request_buffer.size >
- (((dev->host_hw_state & H_CBD) >> 24) * sizeof(u32))
- -sizeof(struct mei_msg_hdr)) {
- mei_hdr.length =
- (((dev->host_hw_state & H_CBD) >> 24) *
- sizeof(u32)) - sizeof(struct mei_msg_hdr);
+ if (cb->request_buffer.size > mei_hbuf_max_data(dev)) {
+ mei_hdr.length = mei_hbuf_max_data(dev);
mei_hdr.msg_complete = 0;
} else {
mei_hdr.length = cb->request_buffer.size;
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index c703332..aaf2683 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -714,13 +714,8 @@
if (rets && dev->mei_host_buffer_is_empty) {
rets = 0;
dev->mei_host_buffer_is_empty = false;
- if (length > ((((dev->host_hw_state & H_CBD) >> 24) *
- sizeof(u32)) - sizeof(struct mei_msg_hdr))) {
-
- mei_hdr.length =
- (((dev->host_hw_state & H_CBD) >> 24) *
- sizeof(u32)) -
- sizeof(struct mei_msg_hdr);
+ if (length > mei_hbuf_max_data(dev)) {
+ mei_hdr.length = mei_hbuf_max_data(dev);
mei_hdr.msg_complete = 0;
} else {
mei_hdr.length = length;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 4fe6533..d60250d 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -167,7 +167,10 @@
struct mei_cl_cb mei_cb;
};
-/* MEI private device struct */
+/**
+ * struct mei_deive - MEI private device struct
+ * @hbuf_depth - depth of host(write) buffer
+ */
struct mei_device {
struct pci_dev *pdev; /* pointer to pci device struct */
/*
@@ -205,6 +208,7 @@
*/
u32 host_hw_state;
u32 me_hw_state;
+ u8 hbuf_depth;
/*
* waiting queue for receive message from FW
*/