aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/interrupt.c
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/interrupt.c
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/interrupt.c')
-rw-r--r--drivers/misc/mei/interrupt.c50
1 files changed, 28 insertions, 22 deletions
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;