aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r--drivers/misc/mei/hbm.c64
-rw-r--r--drivers/misc/mei/hbm.h1
-rw-r--r--drivers/misc/mei/hw-me.c3
-rw-r--r--drivers/misc/mei/init.c1
-rw-r--r--drivers/misc/mei/interrupt.c47
-rw-r--r--drivers/misc/mei/mei_dev.h8
6 files changed, 88 insertions, 36 deletions
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index 0c770255bf89..d3fcb23bb081 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -283,17 +283,18 @@ static int mei_hbm_prop_req(struct mei_device *dev)
283} 283}
284 284
285/** 285/**
286 * mei_hbm_stop_req_prepare - prepare stop request message 286 * mei_hbm_stop_req - send stop request message
287 * 287 *
288 * @dev - mei device 288 * @dev - mei device
289 * @mei_hdr - mei message header 289 * @cl: client info
290 * @data - hbm message body buffer 290 *
291 * This function returns -EIO on write failure
291 */ 292 */
292static void mei_hbm_stop_req_prepare(struct mei_device *dev, 293static int mei_hbm_stop_req(struct mei_device *dev)
293 struct mei_msg_hdr *mei_hdr, unsigned char *data)
294{ 294{
295 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
295 struct hbm_host_stop_request *req = 296 struct hbm_host_stop_request *req =
296 (struct hbm_host_stop_request *)data; 297 (struct hbm_host_stop_request *)dev->wr_msg.data;
297 const size_t len = sizeof(struct hbm_host_stop_request); 298 const size_t len = sizeof(struct hbm_host_stop_request);
298 299
299 mei_hbm_hdr(mei_hdr, len); 300 mei_hbm_hdr(mei_hdr, len);
@@ -301,6 +302,8 @@ static void mei_hbm_stop_req_prepare(struct mei_device *dev,
301 memset(req, 0, len); 302 memset(req, 0, len);
302 req->hbm_cmd = HOST_STOP_REQ_CMD; 303 req->hbm_cmd = HOST_STOP_REQ_CMD;
303 req->reason = DRIVER_STOP_REQUEST; 304 req->reason = DRIVER_STOP_REQUEST;
305
306 return mei_write_message(dev, mei_hdr, dev->wr_msg.data);
304} 307}
305 308
306/** 309/**
@@ -405,6 +408,25 @@ int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl)
405} 408}
406 409
407/** 410/**
411 * mei_hbm_cl_disconnect_rsp - sends disconnect respose to the FW
412 *
413 * @dev: the device structure
414 * @cl: a client to disconnect from
415 *
416 * This function returns -EIO on write failure
417 */
418int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl)
419{
420 struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
421 const size_t len = sizeof(struct hbm_client_connect_response);
422
423 mei_hbm_hdr(mei_hdr, len);
424 mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_RES_CMD, dev->wr_msg.data, len);
425
426 return mei_write_message(dev, mei_hdr, dev->wr_msg.data);
427}
428
429/**
408 * mei_hbm_cl_disconnect_res - disconnect response from ME 430 * mei_hbm_cl_disconnect_res - disconnect response from ME
409 * 431 *
410 * @dev: the device structure 432 * @dev: the device structure
@@ -525,12 +547,14 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev,
525 * 547 *
526 * @dev: the device structure. 548 * @dev: the device structure.
527 * @disconnect_req: disconnect request bus message from the me 549 * @disconnect_req: disconnect request bus message from the me
550 *
551 * returns -ENOMEM on allocation failure
528 */ 552 */
529static void mei_hbm_fw_disconnect_req(struct mei_device *dev, 553static int mei_hbm_fw_disconnect_req(struct mei_device *dev,
530 struct hbm_client_connect_request *disconnect_req) 554 struct hbm_client_connect_request *disconnect_req)
531{ 555{
532 struct mei_cl *cl, *next; 556 struct mei_cl *cl, *next;
533 const size_t len = sizeof(struct hbm_client_connect_response); 557 struct mei_cl_cb *cb;
534 558
535 list_for_each_entry_safe(cl, next, &dev->file_list, link) { 559 list_for_each_entry_safe(cl, next, &dev->file_list, link) {
536 if (mei_hbm_cl_addr_equal(cl, disconnect_req)) { 560 if (mei_hbm_cl_addr_equal(cl, disconnect_req)) {
@@ -544,13 +568,17 @@ static void mei_hbm_fw_disconnect_req(struct mei_device *dev,
544 else if (cl == &dev->iamthif_cl) 568 else if (cl == &dev->iamthif_cl)
545 dev->iamthif_timer = 0; 569 dev->iamthif_timer = 0;
546 570
547 /* prepare disconnect response */ 571 cb = mei_io_cb_init(cl, NULL);
548 mei_hbm_hdr(&dev->wr_ext_msg.hdr, len); 572 if (!cb)
549 mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_RES_CMD, 573 return -ENOMEM;
550 dev->wr_ext_msg.data, len); 574 cb->fop_type = MEI_FOP_DISCONNECT_RSP;
575 cl_dbg(dev, cl, "add disconnect response as first\n");
576 list_add(&cb->list, &dev->ctrl_wr_list.list);
577
551 break; 578 break;
552 } 579 }
553 } 580 }
581 return 0;
554} 582}
555 583
556 584
@@ -629,10 +657,7 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
629 dev_warn(&dev->pdev->dev, "hbm: start: version mismatch - stopping the driver.\n"); 657 dev_warn(&dev->pdev->dev, "hbm: start: version mismatch - stopping the driver.\n");
630 658
631 dev->hbm_state = MEI_HBM_STOPPED; 659 dev->hbm_state = MEI_HBM_STOPPED;
632 mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr, 660 if (mei_hbm_stop_req(dev)) {
633 dev->wr_msg.data);
634 if (mei_write_message(dev, &dev->wr_msg.hdr,
635 dev->wr_msg.data)) {
636 dev_err(&dev->pdev->dev, "hbm: start: failed to send stop request\n"); 661 dev_err(&dev->pdev->dev, "hbm: start: failed to send stop request\n");
637 return -EIO; 662 return -EIO;
638 } 663 }
@@ -778,10 +803,11 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
778 803
779 case ME_STOP_REQ_CMD: 804 case ME_STOP_REQ_CMD:
780 dev_dbg(&dev->pdev->dev, "hbm: stop request: message received\n"); 805 dev_dbg(&dev->pdev->dev, "hbm: stop request: message received\n");
781
782 dev->hbm_state = MEI_HBM_STOPPED; 806 dev->hbm_state = MEI_HBM_STOPPED;
783 mei_hbm_stop_req_prepare(dev, &dev->wr_ext_msg.hdr, 807 if (mei_hbm_stop_req(dev)) {
784 dev->wr_ext_msg.data); 808 dev_err(&dev->pdev->dev, "hbm: start: failed to send stop request\n");
809 return -EIO;
810 }
785 break; 811 break;
786 default: 812 default:
787 BUG(); 813 BUG();
diff --git a/drivers/misc/mei/hbm.h b/drivers/misc/mei/hbm.h
index 5f92188a5cd7..20e8782711c0 100644
--- a/drivers/misc/mei/hbm.h
+++ b/drivers/misc/mei/hbm.h
@@ -54,6 +54,7 @@ int mei_hbm_start_req(struct mei_device *dev);
54int mei_hbm_start_wait(struct mei_device *dev); 54int mei_hbm_start_wait(struct mei_device *dev);
55int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl); 55int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl);
56int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl); 56int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl);
57int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl);
57int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl); 58int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl);
58bool mei_hbm_version_is_supported(struct mei_device *dev); 59bool mei_hbm_version_is_supported(struct mei_device *dev);
59 60
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 54286f304939..847c9e5746cb 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -505,9 +505,6 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
505 /* check slots available for reading */ 505 /* check slots available for reading */
506 slots = mei_count_full_read_slots(dev); 506 slots = mei_count_full_read_slots(dev);
507 while (slots > 0) { 507 while (slots > 0) {
508 /* we have urgent data to send so break the read */
509 if (dev->wr_ext_msg.hdr.length)
510 break;
511 dev_dbg(&dev->pdev->dev, "slots to read = %08x\n", slots); 508 dev_dbg(&dev->pdev->dev, "slots to read = %08x\n", slots);
512 rets = mei_irq_read_handler(dev, &complete_list, &slots); 509 rets = mei_irq_read_handler(dev, &complete_list, &slots);
513 if (rets && dev->dev_state != MEI_DEV_RESETTING) { 510 if (rets && dev->dev_state != MEI_DEV_RESETTING) {
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
index 95a7180c75ea..214dcef9750a 100644
--- a/drivers/misc/mei/init.c
+++ b/drivers/misc/mei/init.c
@@ -116,7 +116,6 @@ int mei_reset(struct mei_device *dev)
116 mei_cl_unlink(&dev->wd_cl); 116 mei_cl_unlink(&dev->wd_cl);
117 mei_cl_unlink(&dev->iamthif_cl); 117 mei_cl_unlink(&dev->iamthif_cl);
118 mei_amthif_reset_params(dev); 118 mei_amthif_reset_params(dev);
119 memset(&dev->wr_ext_msg, 0, sizeof(dev->wr_ext_msg));
120 } 119 }
121 120
122 121
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 3f0b0b9ce951..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 *
@@ -452,12 +487,6 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
452 wake_up_interruptible(&dev->wait_stop_wd); 487 wake_up_interruptible(&dev->wait_stop_wd);
453 } 488 }
454 489
455 if (dev->wr_ext_msg.hdr.length) {
456 mei_write_message(dev, &dev->wr_ext_msg.hdr,
457 dev->wr_ext_msg.data);
458 slots -= mei_data2slots(dev->wr_ext_msg.hdr.length);
459 dev->wr_ext_msg.hdr.length = 0;
460 }
461 if (dev->dev_state == MEI_DEV_ENABLED) { 490 if (dev->dev_state == MEI_DEV_ENABLED) {
462 if (dev->wd_pending && 491 if (dev->wd_pending &&
463 mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) { 492 mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) {
@@ -505,7 +534,11 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
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 }
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index f2c949ef3f28..21e52496bc6e 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -133,6 +133,7 @@ enum mei_wd_states {
133 * @MEI_FOP_READ - read 133 * @MEI_FOP_READ - read
134 * @MEI_FOP_WRITE - write 134 * @MEI_FOP_WRITE - write
135 * @MEI_FOP_CONNECT - connect 135 * @MEI_FOP_CONNECT - connect
136 * @MEI_FOP_DISCONNECT_RSP - disconnect response
136 * @MEI_FOP_OPEN - open 137 * @MEI_FOP_OPEN - open
137 * @MEI_FOP_CLOSE - close 138 * @MEI_FOP_CLOSE - close
138 */ 139 */
@@ -140,6 +141,7 @@ enum mei_cb_file_ops {
140 MEI_FOP_READ = 0, 141 MEI_FOP_READ = 0,
141 MEI_FOP_WRITE, 142 MEI_FOP_WRITE,
142 MEI_FOP_CONNECT, 143 MEI_FOP_CONNECT,
144 MEI_FOP_DISCONNECT_RSP,
143 MEI_FOP_OPEN, 145 MEI_FOP_OPEN,
144 MEI_FOP_CLOSE 146 MEI_FOP_CLOSE
145}; 147};
@@ -339,7 +341,6 @@ struct mei_cl_device {
339 * @hbuf_depth - depth of hardware host/write buffer is slots 341 * @hbuf_depth - depth of hardware host/write buffer is slots
340 * @hbuf_is_ready - query if the host host/write buffer is ready 342 * @hbuf_is_ready - query if the host host/write buffer is ready
341 * @wr_msg - the buffer for hbm control messages 343 * @wr_msg - the buffer for hbm control messages
342 * @wr_ext_msg - the buffer for hbm control responses (set in read cycle)
343 */ 344 */
344struct mei_device { 345struct mei_device {
345 struct pci_dev *pdev; /* pointer to pci device struct */ 346 struct pci_dev *pdev; /* pointer to pci device struct */
@@ -394,11 +395,6 @@ struct mei_device {
394 unsigned char data[128]; 395 unsigned char data[128];
395 } wr_msg; 396 } wr_msg;
396 397
397 struct {
398 struct mei_msg_hdr hdr;
399 unsigned char data[4]; /* All HBM messages are 4 bytes */
400 } wr_ext_msg; /* for control responses */
401
402 struct hbm_version version; 398 struct hbm_version version;
403 399
404 struct mei_me_client *me_clients; /* Note: memory has to be allocated */ 400 struct mei_me_client *me_clients; /* Note: memory has to be allocated */