summaryrefslogtreecommitdiff
path: root/drivers/misc/mei/interface.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-26 23:15:41 +0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-26 23:15:41 +0400
commitb84382f5141875230b7c55eb29443596fd2d8d53 (patch)
tree87c66fcec04a0851c0a8c732b115e246541898b5 /drivers/misc/mei/interface.c
parentfa93669a1917f93b09142d4b2298329b82d7d36d (diff)
parent6078188e2ba1d61a2119ddb2289e88c2c2a015ab (diff)
downloadlinux-b84382f5141875230b7c55eb29443596fd2d8d53.tar.xz
Merge tag 'char-misc-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc patches from Greg Kroah-Hartman: "Here's the "big" pull request for 3.6-rc1 for the char/misc drivers. It's really just a few updates to the mei driver, plus 4 other tiny patches, nothing big at all. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'char-misc-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: mei: use module_pci_driver powerpc/BSR: cleanup the error path of bsr_init mei: mei_irq_thread_write_handler - line break fix mei: streamline the _mei_irq_thread_close/ioctol functions mei: introduce mei_data2slots wrapper mei: mei_wd_host_init: update the comment mei: remove write only wariable wd_due_counter mei: mei_device can be const for mei register access functions mei: revamp host buffer interface function mei: don't query HCSR for host buffer depth mei: group wd_interface_reg with watchdog variables within struct mei_device mei: mei_irq_thread_write_handler check for overflow mei: make mei_write_message more readable mei: check for error codes that mei_flow_ctrl_creds retuns misc: at25: Parse dt settings misc: hpilo: increase number of max supported channels mei: mei.txt: minor grammar fixes
Diffstat (limited to 'drivers/misc/mei/interface.c')
-rw-r--r--drivers/misc/mei/interface.c85
1 files changed, 32 insertions, 53 deletions
diff --git a/drivers/misc/mei/interface.c b/drivers/misc/mei/interface.c
index 428d21e36416..509c3957ff45 100644
--- a/drivers/misc/mei/interface.c
+++ b/drivers/misc/mei/interface.c
@@ -58,16 +58,18 @@ void mei_disable_interrupts(struct mei_device *dev)
}
/**
- * _host_get_filled_slots - gets number of device filled buffer slots
+ * mei_hbuf_filled_slots - gets number of device filled buffer slots
*
* @device: the device structure
*
* returns number of filled slots
*/
-static unsigned char _host_get_filled_slots(const struct mei_device *dev)
+static unsigned char mei_hbuf_filled_slots(struct mei_device *dev)
{
char read_ptr, write_ptr;
+ dev->host_hw_state = mei_hcsr_read(dev);
+
read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8);
write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16);
@@ -75,43 +77,33 @@ static unsigned char _host_get_filled_slots(const struct mei_device *dev)
}
/**
- * mei_host_buffer_is_empty - checks if host buffer is empty.
+ * mei_hbuf_is_empty - checks if host buffer is empty.
*
* @dev: the device structure
*
- * returns 1 if empty, 0 - otherwise.
+ * returns true if empty, false - otherwise.
*/
-int mei_host_buffer_is_empty(struct mei_device *dev)
+bool mei_hbuf_is_empty(struct mei_device *dev)
{
- unsigned char filled_slots;
-
- dev->host_hw_state = mei_hcsr_read(dev);
- filled_slots = _host_get_filled_slots(dev);
-
- if (filled_slots == 0)
- return 1;
-
- return 0;
+ return mei_hbuf_filled_slots(dev) == 0;
}
/**
- * mei_count_empty_write_slots - counts write empty slots.
+ * mei_hbuf_empty_slots - counts write empty slots.
*
* @dev: the device structure
*
* returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count
*/
-int mei_count_empty_write_slots(struct mei_device *dev)
+int mei_hbuf_empty_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;
+ filled_slots = mei_hbuf_filled_slots(dev);
+ 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;
@@ -127,52 +119,39 @@ int mei_count_empty_write_slots(struct mei_device *dev)
*
* This function returns -EIO if write has failed
*/
-int mei_write_message(struct mei_device *dev,
- struct mei_msg_hdr *header,
- unsigned char *write_buffer,
- unsigned long write_length)
+int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header,
+ unsigned char *buf, unsigned long length)
{
- u32 temp_msg = 0;
- unsigned long bytes_written = 0;
- unsigned char buffer_depth, filled_slots, empty_slots;
- unsigned long dw_to_write;
-
- dev->host_hw_state = mei_hcsr_read(dev);
+ unsigned long rem, dw_cnt;
+ u32 *reg_buf = (u32 *)buf;
+ int i;
+ int empty_slots;
- dev_dbg(&dev->pdev->dev,
- "host_hw_state = 0x%08x.\n",
- dev->host_hw_state);
dev_dbg(&dev->pdev->dev,
"mei_write_message header=%08x.\n",
*((u32 *) header));
- buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24);
- filled_slots = _host_get_filled_slots(dev);
- empty_slots = buffer_depth - filled_slots;
- dev_dbg(&dev->pdev->dev,
- "filled = %hu, empty = %hu.\n",
- filled_slots, empty_slots);
-
- dw_to_write = ((write_length + 3) / 4);
+ empty_slots = mei_hbuf_empty_slots(dev);
+ dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots);
- if (dw_to_write > empty_slots)
+ dw_cnt = mei_data2slots(length);
+ if (empty_slots < 0 || dw_cnt > empty_slots)
return -EIO;
mei_reg_write(dev, H_CB_WW, *((u32 *) header));
- while (write_length >= 4) {
- mei_reg_write(dev, H_CB_WW,
- *(u32 *) (write_buffer + bytes_written));
- bytes_written += 4;
- write_length -= 4;
- }
+ for (i = 0; i < length / 4; i++)
+ mei_reg_write(dev, H_CB_WW, reg_buf[i]);
- if (write_length > 0) {
- memcpy(&temp_msg, &write_buffer[bytes_written], write_length);
- mei_reg_write(dev, H_CB_WW, temp_msg);
+ rem = length & 0x3;
+ if (rem > 0) {
+ u32 reg = 0;
+ memcpy(&reg, &buf[length - rem], rem);
+ mei_reg_write(dev, H_CB_WW, reg);
}
+ dev->host_hw_state = mei_hcsr_read(dev);
dev->host_hw_state |= H_IG;
mei_hcsr_set(dev);
dev->me_hw_state = mei_mecsr_read(dev);