diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2016-07-25 18:06:05 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-08-30 08:39:42 -0400 |
commit | 3030dc056459439d756d81a920e135893076a348 (patch) | |
tree | fde7911d5d9b3893c17e9f71227e2ec57ba7fc86 | |
parent | 4034b81ba38967ad0056781572a9d9a95d39f02e (diff) |
mei: add wrapper for queuing control commands.
Enclose the boiler plate code of allocating a control/hbm command cb
and enqueueing it onto ctrl_wr.list in a convenient wrapper
mei_cl_enqueue_ctrl_wr_cb().
This is a preparatory patch for enabling consecutive reads.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/misc/mei/amthif.c | 7 | ||||
-rw-r--r-- | drivers/misc/mei/bus.c | 4 | ||||
-rw-r--r-- | drivers/misc/mei/client.c | 78 | ||||
-rw-r--r-- | drivers/misc/mei/client.h | 5 | ||||
-rw-r--r-- | drivers/misc/mei/hbm.c | 4 | ||||
-rw-r--r-- | drivers/misc/mei/main.c | 2 |
6 files changed, 61 insertions, 39 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 227fd5a816a6..e8029235504d 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c | |||
@@ -188,20 +188,19 @@ out: | |||
188 | * mei_amthif_read_start - queue message for sending read credential | 188 | * mei_amthif_read_start - queue message for sending read credential |
189 | * | 189 | * |
190 | * @cl: host client | 190 | * @cl: host client |
191 | * @file: file pointer of message recipient | 191 | * @fp: file pointer of message recipient |
192 | * | 192 | * |
193 | * Return: 0 on success, <0 on failure. | 193 | * Return: 0 on success, <0 on failure. |
194 | */ | 194 | */ |
195 | static int mei_amthif_read_start(struct mei_cl *cl, const struct file *file) | 195 | static int mei_amthif_read_start(struct mei_cl *cl, const struct file *fp) |
196 | { | 196 | { |
197 | struct mei_device *dev = cl->dev; | 197 | struct mei_device *dev = cl->dev; |
198 | struct mei_cl_cb *cb; | 198 | struct mei_cl_cb *cb; |
199 | 199 | ||
200 | cb = mei_cl_alloc_cb(cl, mei_cl_mtu(cl), MEI_FOP_READ, file); | 200 | cb = mei_cl_enqueue_ctrl_wr_cb(cl, mei_cl_mtu(cl), MEI_FOP_READ, fp); |
201 | if (!cb) | 201 | if (!cb) |
202 | return -ENOMEM; | 202 | return -ENOMEM; |
203 | 203 | ||
204 | list_add_tail(&cb->list, &dev->ctrl_wr_list.list); | ||
205 | cl->rx_flow_ctrl_creds++; | 204 | cl->rx_flow_ctrl_creds++; |
206 | 205 | ||
207 | dev->iamthif_state = MEI_IAMTHIF_READING; | 206 | dev->iamthif_state = MEI_IAMTHIF_READING; |
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 9c404dc8eada..cdf13f6d2697 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c | |||
@@ -235,7 +235,7 @@ static void mei_cl_bus_event_work(struct work_struct *work) | |||
235 | /* Prepare for the next read */ | 235 | /* Prepare for the next read */ |
236 | if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) { | 236 | if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) { |
237 | mutex_lock(&bus->device_lock); | 237 | mutex_lock(&bus->device_lock); |
238 | mei_cl_read_start(cldev->cl, 0, NULL); | 238 | mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL); |
239 | mutex_unlock(&bus->device_lock); | 239 | mutex_unlock(&bus->device_lock); |
240 | } | 240 | } |
241 | } | 241 | } |
@@ -325,7 +325,7 @@ int mei_cldev_register_event_cb(struct mei_cl_device *cldev, | |||
325 | 325 | ||
326 | if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) { | 326 | if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) { |
327 | mutex_lock(&bus->device_lock); | 327 | mutex_lock(&bus->device_lock); |
328 | ret = mei_cl_read_start(cldev->cl, 0, NULL); | 328 | ret = mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL); |
329 | mutex_unlock(&bus->device_lock); | 329 | mutex_unlock(&bus->device_lock); |
330 | if (ret && ret != -EBUSY) | 330 | if (ret && ret != -EBUSY) |
331 | return ret; | 331 | return ret; |
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 89425a8795a8..c924ba92c834 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c | |||
@@ -358,8 +358,9 @@ void mei_io_cb_free(struct mei_cl_cb *cb) | |||
358 | * | 358 | * |
359 | * Return: mei_cl_cb pointer or NULL; | 359 | * Return: mei_cl_cb pointer or NULL; |
360 | */ | 360 | */ |
361 | struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type, | 361 | static struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, |
362 | const struct file *fp) | 362 | enum mei_cb_file_ops type, |
363 | const struct file *fp) | ||
363 | { | 364 | { |
364 | struct mei_cl_cb *cb; | 365 | struct mei_cl_cb *cb; |
365 | 366 | ||
@@ -430,12 +431,12 @@ static inline void mei_io_list_free(struct mei_cl_cb *list, struct mei_cl *cl) | |||
430 | * Return: cb on success and NULL on failure | 431 | * Return: cb on success and NULL on failure |
431 | */ | 432 | */ |
432 | struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length, | 433 | struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length, |
433 | enum mei_cb_file_ops type, | 434 | enum mei_cb_file_ops fop_type, |
434 | const struct file *fp) | 435 | const struct file *fp) |
435 | { | 436 | { |
436 | struct mei_cl_cb *cb; | 437 | struct mei_cl_cb *cb; |
437 | 438 | ||
438 | cb = mei_io_cb_init(cl, type, fp); | 439 | cb = mei_io_cb_init(cl, fop_type, fp); |
439 | if (!cb) | 440 | if (!cb) |
440 | return NULL; | 441 | return NULL; |
441 | 442 | ||
@@ -453,6 +454,36 @@ struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length, | |||
453 | } | 454 | } |
454 | 455 | ||
455 | /** | 456 | /** |
457 | * mei_cl_enqueue_ctrl_wr_cb - a convenient wrapper for allocating | ||
458 | * and enqueuing of the control commands cb | ||
459 | * | ||
460 | * @cl: host client | ||
461 | * @length: size of the buffer | ||
462 | * @type: operation type | ||
463 | * @fp: associated file pointer (might be NULL) | ||
464 | * | ||
465 | * Return: cb on success and NULL on failure | ||
466 | * Locking: called under "dev->device_lock" lock | ||
467 | */ | ||
468 | struct mei_cl_cb *mei_cl_enqueue_ctrl_wr_cb(struct mei_cl *cl, size_t length, | ||
469 | enum mei_cb_file_ops fop_type, | ||
470 | const struct file *fp) | ||
471 | { | ||
472 | struct mei_cl_cb *cb; | ||
473 | |||
474 | /* for RX always allocate at least client's mtu */ | ||
475 | if (length) | ||
476 | length = max_t(size_t, length, mei_cl_mtu(cl)); | ||
477 | |||
478 | cb = mei_cl_alloc_cb(cl, length, fop_type, fp); | ||
479 | if (!cb) | ||
480 | return NULL; | ||
481 | |||
482 | list_add_tail(&cb->list, &cl->dev->ctrl_wr_list.list); | ||
483 | return cb; | ||
484 | } | ||
485 | |||
486 | /** | ||
456 | * mei_cl_read_cb - find this cl's callback in the read list | 487 | * mei_cl_read_cb - find this cl's callback in the read list |
457 | * for a specific file | 488 | * for a specific file |
458 | * | 489 | * |
@@ -848,13 +879,11 @@ static int __mei_cl_disconnect(struct mei_cl *cl) | |||
848 | 879 | ||
849 | cl->state = MEI_FILE_DISCONNECTING; | 880 | cl->state = MEI_FILE_DISCONNECTING; |
850 | 881 | ||
851 | cb = mei_io_cb_init(cl, MEI_FOP_DISCONNECT, NULL); | 882 | cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, MEI_FOP_DISCONNECT, NULL); |
852 | rets = cb ? 0 : -ENOMEM; | 883 | if (!cb) { |
853 | if (rets) | 884 | rets = -ENOMEM; |
854 | goto out; | 885 | goto out; |
855 | 886 | } | |
856 | cl_dbg(dev, cl, "add disconnect cb to control write list\n"); | ||
857 | list_add_tail(&cb->list, &dev->ctrl_wr_list.list); | ||
858 | 887 | ||
859 | if (mei_hbuf_acquire(dev)) { | 888 | if (mei_hbuf_acquire(dev)) { |
860 | rets = mei_cl_send_disconnect(cl, cb); | 889 | rets = mei_cl_send_disconnect(cl, cb); |
@@ -1023,14 +1052,14 @@ int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, | |||
1023 | * | 1052 | * |
1024 | * @cl: host client | 1053 | * @cl: host client |
1025 | * @me_cl: me client | 1054 | * @me_cl: me client |
1026 | * @file: pointer to file structure | 1055 | * @fp: pointer to file structure |
1027 | * | 1056 | * |
1028 | * Locking: called under "dev->device_lock" lock | 1057 | * Locking: called under "dev->device_lock" lock |
1029 | * | 1058 | * |
1030 | * Return: 0 on success, <0 on failure. | 1059 | * Return: 0 on success, <0 on failure. |
1031 | */ | 1060 | */ |
1032 | int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl, | 1061 | int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl, |
1033 | const struct file *file) | 1062 | const struct file *fp) |
1034 | { | 1063 | { |
1035 | struct mei_device *dev; | 1064 | struct mei_device *dev; |
1036 | struct mei_cl_cb *cb; | 1065 | struct mei_cl_cb *cb; |
@@ -1057,12 +1086,11 @@ int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl, | |||
1057 | goto nortpm; | 1086 | goto nortpm; |
1058 | } | 1087 | } |
1059 | 1088 | ||
1060 | cb = mei_io_cb_init(cl, MEI_FOP_CONNECT, file); | 1089 | cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, MEI_FOP_CONNECT, fp); |
1061 | rets = cb ? 0 : -ENOMEM; | 1090 | if (!cb) { |
1062 | if (rets) | 1091 | rets = -ENOMEM; |
1063 | goto out; | 1092 | goto out; |
1064 | 1093 | } | |
1065 | list_add_tail(&cb->list, &dev->ctrl_wr_list.list); | ||
1066 | 1094 | ||
1067 | /* run hbuf acquire last so we don't have to undo */ | 1095 | /* run hbuf acquire last so we don't have to undo */ |
1068 | if (!mei_cl_is_other_connecting(cl) && mei_hbuf_acquire(dev)) { | 1096 | if (!mei_cl_is_other_connecting(cl) && mei_hbuf_acquire(dev)) { |
@@ -1265,7 +1293,7 @@ int mei_cl_irq_notify(struct mei_cl *cl, struct mei_cl_cb *cb, | |||
1265 | * mei_cl_notify_request - send notification stop/start request | 1293 | * mei_cl_notify_request - send notification stop/start request |
1266 | * | 1294 | * |
1267 | * @cl: host client | 1295 | * @cl: host client |
1268 | * @file: associate request with file | 1296 | * @fp: associate request with file |
1269 | * @request: 1 for start or 0 for stop | 1297 | * @request: 1 for start or 0 for stop |
1270 | * | 1298 | * |
1271 | * Locking: called under "dev->device_lock" lock | 1299 | * Locking: called under "dev->device_lock" lock |
@@ -1273,7 +1301,7 @@ int mei_cl_irq_notify(struct mei_cl *cl, struct mei_cl_cb *cb, | |||
1273 | * Return: 0 on such and error otherwise. | 1301 | * Return: 0 on such and error otherwise. |
1274 | */ | 1302 | */ |
1275 | int mei_cl_notify_request(struct mei_cl *cl, | 1303 | int mei_cl_notify_request(struct mei_cl *cl, |
1276 | const struct file *file, u8 request) | 1304 | const struct file *fp, u8 request) |
1277 | { | 1305 | { |
1278 | struct mei_device *dev; | 1306 | struct mei_device *dev; |
1279 | struct mei_cl_cb *cb; | 1307 | struct mei_cl_cb *cb; |
@@ -1298,7 +1326,7 @@ int mei_cl_notify_request(struct mei_cl *cl, | |||
1298 | } | 1326 | } |
1299 | 1327 | ||
1300 | fop_type = mei_cl_notify_req2fop(request); | 1328 | fop_type = mei_cl_notify_req2fop(request); |
1301 | cb = mei_io_cb_init(cl, fop_type, file); | 1329 | cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, fop_type, fp); |
1302 | if (!cb) { | 1330 | if (!cb) { |
1303 | rets = -ENOMEM; | 1331 | rets = -ENOMEM; |
1304 | goto out; | 1332 | goto out; |
@@ -1309,9 +1337,7 @@ int mei_cl_notify_request(struct mei_cl *cl, | |||
1309 | rets = -ENODEV; | 1337 | rets = -ENODEV; |
1310 | goto out; | 1338 | goto out; |
1311 | } | 1339 | } |
1312 | list_add_tail(&cb->list, &dev->ctrl_rd_list.list); | 1340 | list_move_tail(&cb->list, &dev->ctrl_rd_list.list); |
1313 | } else { | ||
1314 | list_add_tail(&cb->list, &dev->ctrl_wr_list.list); | ||
1315 | } | 1341 | } |
1316 | 1342 | ||
1317 | mutex_unlock(&dev->device_lock); | 1343 | mutex_unlock(&dev->device_lock); |
@@ -1443,14 +1469,10 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length, const struct file *fp) | |||
1443 | if (cl->rx_flow_ctrl_creds) | 1469 | if (cl->rx_flow_ctrl_creds) |
1444 | return -EBUSY; | 1470 | return -EBUSY; |
1445 | 1471 | ||
1446 | /* always allocate at least client max message */ | 1472 | cb = mei_cl_enqueue_ctrl_wr_cb(cl, length, MEI_FOP_READ, fp); |
1447 | length = max_t(size_t, length, mei_cl_mtu(cl)); | ||
1448 | cb = mei_cl_alloc_cb(cl, length, MEI_FOP_READ, fp); | ||
1449 | if (!cb) | 1473 | if (!cb) |
1450 | return -ENOMEM; | 1474 | return -ENOMEM; |
1451 | 1475 | ||
1452 | list_add_tail(&cb->list, &dev->ctrl_wr_list.list); | ||
1453 | |||
1454 | rets = pm_runtime_get(dev->dev); | 1476 | rets = pm_runtime_get(dev->dev); |
1455 | if (rets < 0 && rets != -EINPROGRESS) { | 1477 | if (rets < 0 && rets != -EINPROGRESS) { |
1456 | pm_runtime_put_noidle(dev->dev); | 1478 | pm_runtime_put_noidle(dev->dev); |
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index 16466aa40cbd..d2bfabecd882 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h | |||
@@ -82,8 +82,6 @@ static inline u8 mei_me_cl_ver(const struct mei_me_client *me_cl) | |||
82 | /* | 82 | /* |
83 | * MEI IO Functions | 83 | * MEI IO Functions |
84 | */ | 84 | */ |
85 | struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type, | ||
86 | const struct file *fp); | ||
87 | void mei_io_cb_free(struct mei_cl_cb *priv_cb); | 85 | void mei_io_cb_free(struct mei_cl_cb *priv_cb); |
88 | 86 | ||
89 | /** | 87 | /** |
@@ -116,6 +114,9 @@ void mei_cl_read_cb_flush(const struct mei_cl *cl, const struct file *fp); | |||
116 | struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length, | 114 | struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length, |
117 | enum mei_cb_file_ops type, | 115 | enum mei_cb_file_ops type, |
118 | const struct file *fp); | 116 | const struct file *fp); |
117 | struct mei_cl_cb *mei_cl_enqueue_ctrl_wr_cb(struct mei_cl *cl, size_t length, | ||
118 | enum mei_cb_file_ops type, | ||
119 | const struct file *fp); | ||
119 | int mei_cl_flush_queues(struct mei_cl *cl, const struct file *fp); | 120 | int mei_cl_flush_queues(struct mei_cl *cl, const struct file *fp); |
120 | 121 | ||
121 | /* | 122 | /* |
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index c8e8a8d22019..4b9495f0394c 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c | |||
@@ -871,10 +871,10 @@ static int mei_hbm_fw_disconnect_req(struct mei_device *dev, | |||
871 | cl->state = MEI_FILE_DISCONNECTING; | 871 | cl->state = MEI_FILE_DISCONNECTING; |
872 | cl->timer_count = 0; | 872 | cl->timer_count = 0; |
873 | 873 | ||
874 | cb = mei_io_cb_init(cl, MEI_FOP_DISCONNECT_RSP, NULL); | 874 | cb = mei_cl_enqueue_ctrl_wr_cb(cl, 0, MEI_FOP_DISCONNECT_RSP, |
875 | NULL); | ||
875 | if (!cb) | 876 | if (!cb) |
876 | return -ENOMEM; | 877 | return -ENOMEM; |
877 | list_add_tail(&cb->list, &dev->ctrl_wr_list.list); | ||
878 | } | 878 | } |
879 | return 0; | 879 | return 0; |
880 | } | 880 | } |
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index d7ef5edf044a..d698ba32357c 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c | |||
@@ -628,7 +628,7 @@ static unsigned int mei_poll(struct file *file, poll_table *wait) | |||
628 | if (!list_empty(&cl->rd_completed)) | 628 | if (!list_empty(&cl->rd_completed)) |
629 | mask |= POLLIN | POLLRDNORM; | 629 | mask |= POLLIN | POLLRDNORM; |
630 | else | 630 | else |
631 | mei_cl_read_start(cl, 0, file); | 631 | mei_cl_read_start(cl, mei_cl_mtu(cl), file); |
632 | } | 632 | } |
633 | 633 | ||
634 | out: | 634 | out: |