diff options
Diffstat (limited to 'drivers/misc/mei/interrupt.c')
-rw-r--r-- | drivers/misc/mei/interrupt.c | 61 |
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 | */ | ||
173 | static 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 | */ |
257 | static int mei_cl_irq_ioctl(struct mei_cl *cl, struct mei_cl_cb *cb, | 291 | static 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 | } |