aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2013-03-11 12:27:02 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-03-15 14:10:48 -0400
commitc8c8d080ed94cea6757f2d781b6e360a74b256fd (patch)
tree5fa9937912d66e7d6633c3109fdce1b344c8728f /drivers/misc/mei
parent388f7bd24d2ffc945ad08be3a592672c1e32156e (diff)
mei: revamp mei_data2slots
1. Move the mei_data2slots to mei_dev.h as it will be used by the all supported HW. 2. Change return value from u8 to u32 to catch possible overflows 3. Eliminate computing the slots number twice in the same function Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei')
-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