aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/interrupt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mei/interrupt.c')
-rw-r--r--drivers/misc/mei/interrupt.c61
1 files changed, 47 insertions, 14 deletions
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index f0fbb5179f80..75ff4092953e 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -161,6 +161,41 @@ static int mei_cl_irq_read_msg(struct mei_device *dev,
161} 161}
162 162
163/** 163/**
164 * mei_cl_irq_disconnect_rsp - send disconnection response message
165 *
166 * @cl: client
167 * @cb: callback block.
168 * @slots: free slots.
169 * @cmpl_list: complete list.
170 *
171 * returns 0, OK; otherwise, error.
172 */
173static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb,
174 s32 *slots, struct mei_cl_cb *cmpl_list)
175{
176 struct mei_device *dev = cl->dev;
177 int ret;
178
179 u32 msg_slots =
180 mei_data2slots(sizeof(struct hbm_client_connect_response));
181
182 if (*slots < msg_slots)
183 return -EMSGSIZE;
184
185 *slots -= msg_slots;
186
187 ret = mei_hbm_cl_disconnect_rsp(dev, cl);
188
189 cl->state = MEI_FILE_DISCONNECTED;
190 cl->status = 0;
191 mei_io_cb_free(cb);
192
193 return ret;
194}
195
196
197
198/**
164 * mei_cl_irq_close - processes close related operation from 199 * mei_cl_irq_close - processes close related operation from
165 * interrupt thread context - send disconnect request 200 * interrupt thread context - send disconnect request
166 * 201 *
@@ -244,8 +279,7 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
244 279
245 280
246/** 281/**
247 * mei_cl_irq_ioctl - processes client ioctl related operation from the 282 * mei_cl_irq_connect - send connect request in irq_thread context
248 * interrupt thread context - send connection request
249 * 283 *
250 * @cl: client 284 * @cl: client
251 * @cb: callback block. 285 * @cb: callback block.
@@ -254,7 +288,7 @@ static int mei_cl_irq_read(struct mei_cl *cl, struct mei_cl_cb *cb,
254 * 288 *
255 * returns 0, OK; otherwise, error. 289 * returns 0, OK; otherwise, error.
256 */ 290 */
257static int mei_cl_irq_ioctl(struct mei_cl *cl, struct mei_cl_cb *cb, 291static int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb,
258 s32 *slots, struct mei_cl_cb *cmpl_list) 292 s32 *slots, struct mei_cl_cb *cmpl_list)
259{ 293{
260 struct mei_device *dev = cl->dev; 294 struct mei_device *dev = cl->dev;
@@ -263,6 +297,9 @@ static int mei_cl_irq_ioctl(struct mei_cl *cl, struct mei_cl_cb *cb,
263 u32 msg_slots = 297 u32 msg_slots =
264 mei_data2slots(sizeof(struct hbm_client_connect_request)); 298 mei_data2slots(sizeof(struct hbm_client_connect_request));
265 299
300 if (mei_cl_is_other_connecting(cl))
301 return 0;
302
266 if (*slots < msg_slots) { 303 if (*slots < msg_slots) {
267 /* return the cancel routine */ 304 /* return the cancel routine */
268 list_del(&cb->list); 305 list_del(&cb->list);
@@ -450,12 +487,6 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
450 wake_up_interruptible(&dev->wait_stop_wd); 487 wake_up_interruptible(&dev->wait_stop_wd);
451 } 488 }
452 489
453 if (dev->wr_ext_msg.hdr.length) {
454 mei_write_message(dev, &dev->wr_ext_msg.hdr,
455 dev->wr_ext_msg.data);
456 slots -= mei_data2slots(dev->wr_ext_msg.hdr.length);
457 dev->wr_ext_msg.hdr.length = 0;
458 }
459 if (dev->dev_state == MEI_DEV_ENABLED) { 490 if (dev->dev_state == MEI_DEV_ENABLED) {
460 if (dev->wd_pending && 491 if (dev->wd_pending &&
461 mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) { 492 mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) {
@@ -496,16 +527,18 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
496 return ret; 527 return ret;
497 528
498 break; 529 break;
499 case MEI_FOP_IOCTL: 530 case MEI_FOP_CONNECT:
500 /* connect message */ 531 /* connect message */
501 if (mei_cl_is_other_connecting(cl)) 532 ret = mei_cl_irq_connect(cl, cb, &slots, cmpl_list);
502 continue;
503 ret = mei_cl_irq_ioctl(cl, cb, &slots, cmpl_list);
504 if (ret) 533 if (ret)
505 return ret; 534 return ret;
506 535
507 break; 536 break;
508 537 case MEI_FOP_DISCONNECT_RSP:
538 /* send disconnect resp */
539 ret = mei_cl_irq_disconnect_rsp(cl, cb, &slots, cmpl_list);
540 if (ret)
541 return ret;
509 default: 542 default:
510 BUG(); 543 BUG();
511 } 544 }