aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/interface.c
diff options
context:
space:
mode:
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)
58} 58}
59 59
60/** 60/**
61 * _host_get_filled_slots - gets number of device filled buffer slots 61 * mei_hbuf_filled_slots - gets number of device filled buffer slots
62 * 62 *
63 * @device: the device structure 63 * @device: the device structure
64 * 64 *
65 * returns number of filled slots 65 * returns number of filled slots
66 */ 66 */
67static unsigned char _host_get_filled_slots(const struct mei_device *dev) 67static unsigned char mei_hbuf_filled_slots(struct mei_device *dev)
68{ 68{
69 char read_ptr, write_ptr; 69 char read_ptr, write_ptr;
70 70
71 dev->host_hw_state = mei_hcsr_read(dev);
72
71 read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8); 73 read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8);
72 write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16); 74 write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16);
73 75
@@ -75,43 +77,33 @@ static unsigned char _host_get_filled_slots(const struct mei_device *dev)
75} 77}
76 78
77/** 79/**
78 * mei_host_buffer_is_empty - checks if host buffer is empty. 80 * mei_hbuf_is_empty - checks if host buffer is empty.
79 * 81 *
80 * @dev: the device structure 82 * @dev: the device structure
81 * 83 *
82 * returns 1 if empty, 0 - otherwise. 84 * returns true if empty, false - otherwise.
83 */ 85 */
84int mei_host_buffer_is_empty(struct mei_device *dev) 86bool mei_hbuf_is_empty(struct mei_device *dev)
85{ 87{
86 unsigned char filled_slots; 88 return mei_hbuf_filled_slots(dev) == 0;
87
88 dev->host_hw_state = mei_hcsr_read(dev);
89 filled_slots = _host_get_filled_slots(dev);
90
91 if (filled_slots == 0)
92 return 1;
93
94 return 0;
95} 89}
96 90
97/** 91/**
98 * mei_count_empty_write_slots - counts write empty slots. 92 * mei_hbuf_empty_slots - counts write empty slots.
99 * 93 *
100 * @dev: the device structure 94 * @dev: the device structure
101 * 95 *
102 * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count 96 * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count
103 */ 97 */
104int mei_count_empty_write_slots(struct mei_device *dev) 98int mei_hbuf_empty_slots(struct mei_device *dev)
105{ 99{
106 unsigned char buffer_depth, filled_slots, empty_slots; 100 unsigned char filled_slots, empty_slots;
107 101
108 dev->host_hw_state = mei_hcsr_read(dev); 102 filled_slots = mei_hbuf_filled_slots(dev);
109 buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24); 103 empty_slots = dev->hbuf_depth - filled_slots;
110 filled_slots = _host_get_filled_slots(dev);
111 empty_slots = buffer_depth - filled_slots;
112 104
113 /* check for overflow */ 105 /* check for overflow */
114 if (filled_slots > buffer_depth) 106 if (filled_slots > dev->hbuf_depth)
115 return -EOVERFLOW; 107 return -EOVERFLOW;
116 108
117 return empty_slots; 109 return empty_slots;
@@ -127,52 +119,39 @@ int mei_count_empty_write_slots(struct mei_device *dev)
127 * 119 *
128 * This function returns -EIO if write has failed 120 * This function returns -EIO if write has failed
129 */ 121 */
130int mei_write_message(struct mei_device *dev, 122int mei_write_message(struct mei_device *dev, struct mei_msg_hdr *header,
131 struct mei_msg_hdr *header, 123 unsigned char *buf, unsigned long length)
132 unsigned char *write_buffer,
133 unsigned long write_length)
134{ 124{
135 u32 temp_msg = 0; 125 unsigned long rem, dw_cnt;
136 unsigned long bytes_written = 0; 126 u32 *reg_buf = (u32 *)buf;
137 unsigned char buffer_depth, filled_slots, empty_slots; 127 int i;
138 unsigned long dw_to_write; 128 int empty_slots;
139
140 dev->host_hw_state = mei_hcsr_read(dev);
141 129
142 dev_dbg(&dev->pdev->dev,
143 "host_hw_state = 0x%08x.\n",
144 dev->host_hw_state);
145 130
146 dev_dbg(&dev->pdev->dev, 131 dev_dbg(&dev->pdev->dev,
147 "mei_write_message header=%08x.\n", 132 "mei_write_message header=%08x.\n",
148 *((u32 *) header)); 133 *((u32 *) header));
149 134
150 buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24); 135 empty_slots = mei_hbuf_empty_slots(dev);
151 filled_slots = _host_get_filled_slots(dev); 136 dev_dbg(&dev->pdev->dev, "empty slots = %hu.\n", empty_slots);
152 empty_slots = buffer_depth - filled_slots;
153 dev_dbg(&dev->pdev->dev,
154 "filled = %hu, empty = %hu.\n",
155 filled_slots, empty_slots);
156
157 dw_to_write = ((write_length + 3) / 4);
158 137
159 if (dw_to_write > empty_slots) 138 dw_cnt = mei_data2slots(length);
139 if (empty_slots < 0 || dw_cnt > empty_slots)
160 return -EIO; 140 return -EIO;
161 141
162 mei_reg_write(dev, H_CB_WW, *((u32 *) header)); 142 mei_reg_write(dev, H_CB_WW, *((u32 *) header));
163 143
164 while (write_length >= 4) { 144 for (i = 0; i < length / 4; i++)
165 mei_reg_write(dev, H_CB_WW, 145 mei_reg_write(dev, H_CB_WW, reg_buf[i]);
166 *(u32 *) (write_buffer + bytes_written));
167 bytes_written += 4;
168 write_length -= 4;
169 }
170 146
171 if (write_length > 0) { 147 rem = length & 0x3;
172 memcpy(&temp_msg, &write_buffer[bytes_written], write_length); 148 if (rem > 0) {
173 mei_reg_write(dev, H_CB_WW, temp_msg); 149 u32 reg = 0;
150 memcpy(&reg, &buf[length - rem], rem);
151 mei_reg_write(dev, H_CB_WW, reg);
174 } 152 }
175 153
154 dev->host_hw_state = mei_hcsr_read(dev);
176 dev->host_hw_state |= H_IG; 155 dev->host_hw_state |= H_IG;
177 mei_hcsr_set(dev); 156 mei_hcsr_set(dev);
178 dev->me_hw_state = mei_mecsr_read(dev); 157 dev->me_hw_state = mei_mecsr_read(dev);