aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/mei/amthif.c11
-rw-r--r--drivers/misc/mei/hw-me.c3
-rw-r--r--drivers/misc/mei/hw-me.h6
-rw-r--r--drivers/misc/mei/interrupt.c50
-rw-r--r--drivers/misc/mei/mei_dev.h11
5 files changed, 47 insertions, 34 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index c86d7e3839a4..9a5e8c72628b 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -449,7 +449,7 @@ int mei_amthif_irq_write_complete(struct mei_device *dev, s32 *slots,
449 struct mei_msg_hdr mei_hdr; 449 struct mei_msg_hdr mei_hdr;
450 struct mei_cl *cl = cb->cl; 450 struct mei_cl *cl = cb->cl;
451 size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index; 451 size_t len = dev->iamthif_msg_buf_size - dev->iamthif_msg_buf_index;
452 size_t msg_slots = mei_data2slots(len); 452 u32 msg_slots = mei_data2slots(len);
453 453
454 mei_hdr.host_addr = cl->host_client_id; 454 mei_hdr.host_addr = cl->host_client_id;
455 mei_hdr.me_addr = cl->me_client_id; 455 mei_hdr.me_addr = cl->me_client_id;
@@ -566,12 +566,13 @@ int mei_amthif_irq_read_message(struct mei_cl_cb *complete_list,
566 */ 566 */
567int mei_amthif_irq_read(struct mei_device *dev, s32 *slots) 567int mei_amthif_irq_read(struct mei_device *dev, s32 *slots)
568{ 568{
569 u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control));
569 570
570 if (((*slots) * sizeof(u32)) < (sizeof(struct mei_msg_hdr) 571 if (*slots < msg_slots)
571 + sizeof(struct hbm_flow_control))) {
572 return -EMSGSIZE; 572 return -EMSGSIZE;
573 } 573
574 *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); 574 *slots -= msg_slots;
575
575 if (mei_hbm_cl_flow_control_req(dev, &dev->iamthif_cl)) { 576 if (mei_hbm_cl_flow_control_req(dev, &dev->iamthif_cl)) {
576 dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n"); 577 dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n");
577 return -EIO; 578 return -EIO;
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 45ea7185c003..d21e5a761f2c 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -295,10 +295,11 @@ static int mei_me_write_message(struct mei_device *dev,
295 unsigned char *buf) 295 unsigned char *buf)
296{ 296{
297 struct mei_me_hw *hw = to_me_hw(dev); 297 struct mei_me_hw *hw = to_me_hw(dev);
298 unsigned long rem, dw_cnt; 298 unsigned long rem;
299 unsigned long length = header->length; 299 unsigned long length = header->length;
300 u32 *reg_buf = (u32 *)buf; 300 u32 *reg_buf = (u32 *)buf;
301 u32 hcsr; 301 u32 hcsr;
302 u32 dw_cnt;
302 int i; 303 int i;
303 int empty_slots; 304 int empty_slots;
304 305
diff --git a/drivers/misc/mei/hw-me.h b/drivers/misc/mei/hw-me.h
index 8518d3eeb838..80bd829fbd9a 100644
--- a/drivers/misc/mei/hw-me.h
+++ b/drivers/misc/mei/hw-me.h
@@ -36,12 +36,6 @@ struct mei_me_hw {
36 36
37struct mei_device *mei_me_dev_init(struct pci_dev *pdev); 37struct mei_device *mei_me_dev_init(struct pci_dev *pdev);
38 38
39/* get slots (dwords) from a message length + header (bytes) */
40static inline unsigned char mei_data2slots(size_t length)
41{
42 return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4);
43}
44
45irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id); 39irqreturn_t mei_me_irq_quick_handler(int irq, void *dev_id);
46irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id); 40irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id);
47 41
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 3535b2676c97..14c70b8815d8 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -153,25 +153,27 @@ static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
153 struct mei_cl *cl, 153 struct mei_cl *cl,
154 struct mei_cl_cb *cmpl_list) 154 struct mei_cl_cb *cmpl_list)
155{ 155{
156 if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + 156 u32 msg_slots =
157 sizeof(struct hbm_client_connect_request))) 157 mei_data2slots(sizeof(struct hbm_client_connect_request));
158 return -EBADMSG;
159 158
160 *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); 159 if (*slots < msg_slots)
160 return -EMSGSIZE;
161
162 *slots -= msg_slots;
161 163
162 if (mei_hbm_cl_disconnect_req(dev, cl)) { 164 if (mei_hbm_cl_disconnect_req(dev, cl)) {
163 cl->status = 0; 165 cl->status = 0;
164 cb_pos->buf_idx = 0; 166 cb_pos->buf_idx = 0;
165 list_move_tail(&cb_pos->list, &cmpl_list->list); 167 list_move_tail(&cb_pos->list, &cmpl_list->list);
166 return -EMSGSIZE; 168 return -EIO;
167 } else {
168 cl->state = MEI_FILE_DISCONNECTING;
169 cl->status = 0;
170 cb_pos->buf_idx = 0;
171 list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list);
172 cl->timer_count = MEI_CONNECT_TIMEOUT;
173 } 169 }
174 170
171 cl->state = MEI_FILE_DISCONNECTING;
172 cl->status = 0;
173 cb_pos->buf_idx = 0;
174 list_move_tail(&cb_pos->list, &dev->ctrl_rd_list.list);
175 cl->timer_count = MEI_CONNECT_TIMEOUT;
176
175 return 0; 177 return 0;
176} 178}
177 179
@@ -192,14 +194,15 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots,
192 struct mei_cl *cl, 194 struct mei_cl *cl,
193 struct mei_cl_cb *cmpl_list) 195 struct mei_cl_cb *cmpl_list)
194{ 196{
195 if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + 197 u32 msg_slots = mei_data2slots(sizeof(struct hbm_flow_control));
196 sizeof(struct hbm_flow_control))) { 198
199 if (*slots < msg_slots) {
197 /* return the cancel routine */ 200 /* return the cancel routine */
198 list_del(&cb_pos->list); 201 list_del(&cb_pos->list);
199 return -EBADMSG; 202 return -EMSGSIZE;
200 } 203 }
201 204
202 *slots -= mei_data2slots(sizeof(struct hbm_flow_control)); 205 *slots -= msg_slots;
203 206
204 if (mei_hbm_cl_flow_control_req(dev, cl)) { 207 if (mei_hbm_cl_flow_control_req(dev, cl)) {
205 cl->status = -ENODEV; 208 cl->status = -ENODEV;
@@ -229,15 +232,19 @@ static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
229 struct mei_cl *cl, 232 struct mei_cl *cl,
230 struct mei_cl_cb *cmpl_list) 233 struct mei_cl_cb *cmpl_list)
231{ 234{
232 if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + 235 u32 msg_slots =
233 sizeof(struct hbm_client_connect_request))) { 236 mei_data2slots(sizeof(struct hbm_client_connect_request));
237
238 if (*slots < msg_slots) {
234 /* return the cancel routine */ 239 /* return the cancel routine */
235 list_del(&cb_pos->list); 240 list_del(&cb_pos->list);
236 return -EBADMSG; 241 return -EMSGSIZE;
237 } 242 }
238 243
244 *slots -= msg_slots;
245
239 cl->state = MEI_FILE_CONNECTING; 246 cl->state = MEI_FILE_CONNECTING;
240 *slots -= mei_data2slots(sizeof(struct hbm_client_connect_request)); 247
241 if (mei_hbm_cl_connect_req(dev, cl)) { 248 if (mei_hbm_cl_connect_req(dev, cl)) {
242 cl->status = -ENODEV; 249 cl->status = -ENODEV;
243 cb_pos->buf_idx = 0; 250 cb_pos->buf_idx = 0;
@@ -266,7 +273,7 @@ static int mei_irq_thread_write_complete(struct mei_device *dev, s32 *slots,
266 struct mei_msg_hdr mei_hdr; 273 struct mei_msg_hdr mei_hdr;
267 struct mei_cl *cl = cb->cl; 274 struct mei_cl *cl = cb->cl;
268 size_t len = cb->request_buffer.size - cb->buf_idx; 275 size_t len = cb->request_buffer.size - cb->buf_idx;
269 size_t msg_slots = mei_data2slots(len); 276 u32 msg_slots = mei_data2slots(len);
270 277
271 mei_hdr.host_addr = cl->host_client_id; 278 mei_hdr.host_addr = cl->host_client_id;
272 mei_hdr.me_addr = cl->me_client_id; 279 mei_hdr.me_addr = cl->me_client_id;
@@ -419,8 +426,7 @@ end:
419 * 426 *
420 * returns 0 on success, <0 on failure. 427 * returns 0 on success, <0 on failure.
421 */ 428 */
422int mei_irq_write_handler(struct mei_device *dev, 429int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
423 struct mei_cl_cb *cmpl_list)
424{ 430{
425 431
426 struct mei_cl *cl; 432 struct mei_cl *cl;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index cb80166161f0..09a2af4294a6 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -374,6 +374,17 @@ static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
374 return msecs_to_jiffies(sec * MSEC_PER_SEC); 374 return msecs_to_jiffies(sec * MSEC_PER_SEC);
375} 375}
376 376
377/**
378 * mei_data2slots - get slots - number of (dwords) from a message length
379 * + size of the mei header
380 * @length - size of the messages in bytes
381 * returns - number of slots
382 */
383static inline u32 mei_data2slots(size_t length)
384{
385 return DIV_ROUND_UP(sizeof(struct mei_msg_hdr) + length, 4);
386}
387
377 388
378/* 389/*
379 * mei init function prototypes 390 * mei init function prototypes