]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/misc/mei/client.c
mei: fix client functions names
[karo-tx-linux.git] / drivers / misc / mei / client.c
1 /*
2  *
3  * Intel Management Engine Interface (Intel MEI) Linux driver
4  * Copyright (c) 2003-2012, Intel Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  */
16
17 #include <linux/pci.h>
18 #include <linux/sched.h>
19 #include <linux/wait.h>
20 #include <linux/delay.h>
21
22 #include <linux/mei.h>
23
24 #include "mei_dev.h"
25 #include "hbm.h"
26 #include "interface.h"
27 #include "client.h"
28
29 /**
30  * mei_me_cl_by_uuid - locate index of me client
31  *
32  * @dev: mei device
33  * returns me client index or -ENOENT if not found
34  */
35 int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *uuid)
36 {
37         int i, res = -ENOENT;
38
39         for (i = 0; i < dev->me_clients_num; ++i)
40                 if (uuid_le_cmp(*uuid,
41                                 dev->me_clients[i].props.protocol_name) == 0) {
42                         res = i;
43                         break;
44                 }
45
46         return res;
47 }
48
49
50 /**
51  * mei_me_cl_by_id return index to me_clients for client_id
52  *
53  * @dev: the device structure
54  * @client_id: me client id
55  *
56  * Locking: called under "dev->device_lock" lock
57  *
58  * returns index on success, -ENOENT on failure.
59  */
60
61 int mei_me_cl_by_id(struct mei_device *dev, u8 client_id)
62 {
63         int i;
64         for (i = 0; i < dev->me_clients_num; i++)
65                 if (dev->me_clients[i].client_id == client_id)
66                         break;
67         if (WARN_ON(dev->me_clients[i].client_id != client_id))
68                 return -ENOENT;
69
70         if (i == dev->me_clients_num)
71                 return -ENOENT;
72
73         return i;
74 }
75
76
77 /**
78  * mei_io_list_flush - removes list entry belonging to cl.
79  *
80  * @list:  An instance of our list structure
81  * @cl: host client
82  */
83 void mei_io_list_flush(struct mei_cl_cb *list, struct mei_cl *cl)
84 {
85         struct mei_cl_cb *cb;
86         struct mei_cl_cb *next;
87
88         list_for_each_entry_safe(cb, next, &list->list, list) {
89                 if (cb->cl && mei_cl_cmp_id(cl, cb->cl))
90                         list_del(&cb->list);
91         }
92 }
93
94 /**
95  * mei_io_cb_free - free mei_cb_private related memory
96  *
97  * @cb: mei callback struct
98  */
99 void mei_io_cb_free(struct mei_cl_cb *cb)
100 {
101         if (cb == NULL)
102                 return;
103
104         kfree(cb->request_buffer.data);
105         kfree(cb->response_buffer.data);
106         kfree(cb);
107 }
108
109 /**
110  * mei_io_cb_init - allocate and initialize io callback
111  *
112  * @cl - mei client
113  * @file: pointer to file structure
114  *
115  * returns mei_cl_cb pointer or NULL;
116  */
117 struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp)
118 {
119         struct mei_cl_cb *cb;
120
121         cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
122         if (!cb)
123                 return NULL;
124
125         mei_io_list_init(cb);
126
127         cb->file_object = fp;
128         cb->cl = cl;
129         cb->buf_idx = 0;
130         return cb;
131 }
132
133 /**
134  * mei_io_cb_alloc_req_buf - allocate request buffer
135  *
136  * @cb -  io callback structure
137  * @size: size of the buffer
138  *
139  * returns 0 on success
140  *         -EINVAL if cb is NULL
141  *         -ENOMEM if allocation failed
142  */
143 int mei_io_cb_alloc_req_buf(struct mei_cl_cb *cb, size_t length)
144 {
145         if (!cb)
146                 return -EINVAL;
147
148         if (length == 0)
149                 return 0;
150
151         cb->request_buffer.data = kmalloc(length, GFP_KERNEL);
152         if (!cb->request_buffer.data)
153                 return -ENOMEM;
154         cb->request_buffer.size = length;
155         return 0;
156 }
157 /**
158  * mei_io_cb_alloc_req_buf - allocate respose buffer
159  *
160  * @cb -  io callback structure
161  * @size: size of the buffer
162  *
163  * returns 0 on success
164  *         -EINVAL if cb is NULL
165  *         -ENOMEM if allocation failed
166  */
167 int mei_io_cb_alloc_resp_buf(struct mei_cl_cb *cb, size_t length)
168 {
169         if (!cb)
170                 return -EINVAL;
171
172         if (length == 0)
173                 return 0;
174
175         cb->response_buffer.data = kmalloc(length, GFP_KERNEL);
176         if (!cb->response_buffer.data)
177                 return -ENOMEM;
178         cb->response_buffer.size = length;
179         return 0;
180 }
181
182
183
184 /**
185  * mei_cl_flush_queues - flushes queue lists belonging to cl.
186  *
187  * @dev: the device structure
188  * @cl: host client
189  */
190 int mei_cl_flush_queues(struct mei_cl *cl)
191 {
192         if (WARN_ON(!cl || !cl->dev))
193                 return -EINVAL;
194
195         dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n");
196         mei_io_list_flush(&cl->dev->read_list, cl);
197         mei_io_list_flush(&cl->dev->write_list, cl);
198         mei_io_list_flush(&cl->dev->write_waiting_list, cl);
199         mei_io_list_flush(&cl->dev->ctrl_wr_list, cl);
200         mei_io_list_flush(&cl->dev->ctrl_rd_list, cl);
201         mei_io_list_flush(&cl->dev->amthif_cmd_list, cl);
202         mei_io_list_flush(&cl->dev->amthif_rd_complete_list, cl);
203         return 0;
204 }
205
206
207 /**
208  * mei_cl_init - initializes intialize cl.
209  *
210  * @cl: host client to be initialized
211  * @dev: mei device
212  */
213 void mei_cl_init(struct mei_cl *cl, struct mei_device *dev)
214 {
215         memset(cl, 0, sizeof(struct mei_cl));
216         init_waitqueue_head(&cl->wait);
217         init_waitqueue_head(&cl->rx_wait);
218         init_waitqueue_head(&cl->tx_wait);
219         INIT_LIST_HEAD(&cl->link);
220         cl->reading_state = MEI_IDLE;
221         cl->writing_state = MEI_IDLE;
222         cl->dev = dev;
223 }
224
225 /**
226  * mei_cl_allocate - allocates cl  structure and sets it up.
227  *
228  * @dev: mei device
229  * returns  The allocated file or NULL on failure
230  */
231 struct mei_cl *mei_cl_allocate(struct mei_device *dev)
232 {
233         struct mei_cl *cl;
234
235         cl = kmalloc(sizeof(struct mei_cl), GFP_KERNEL);
236         if (!cl)
237                 return NULL;
238
239         mei_cl_init(cl, dev);
240
241         return cl;
242 }
243
244 /**
245  * mei_cl_find_read_cb - find this cl's callback in the read list
246  *
247  * @dev: device structure
248  * returns cb on success, NULL on error
249  */
250 struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl)
251 {
252         struct mei_device *dev = cl->dev;
253         struct mei_cl_cb *cb = NULL;
254         struct mei_cl_cb *next = NULL;
255
256         list_for_each_entry_safe(cb, next, &dev->read_list.list, list)
257                 if (mei_cl_cmp_id(cl, cb->cl))
258                         return cb;
259         return NULL;
260 }
261
262
263 /**
264  * mei_me_cl_link - create link between host and me clinet and add
265  *   me_cl to the list
266  *
267  * @cl: link between me and host client assocated with opened file descriptor
268  * @uuid: uuid of ME client
269  * @client_id: id of the host client
270  *
271  * returns ME client index if ME client
272  *      -EINVAL on incorrect values
273  *      -ENONET if client not found
274  */
275 int mei_cl_link_me(struct mei_cl *cl, const uuid_le *uuid, u8 host_cl_id)
276 {
277         struct mei_device *dev;
278         int i;
279
280         if (WARN_ON(!cl || !cl->dev || !uuid))
281                 return -EINVAL;
282
283         dev = cl->dev;
284
285         /* check for valid client id */
286         i = mei_me_cl_by_uuid(dev, uuid);
287         if (i >= 0) {
288                 cl->me_client_id = dev->me_clients[i].client_id;
289                 cl->state = MEI_FILE_CONNECTING;
290                 cl->host_client_id = host_cl_id;
291
292                 list_add_tail(&cl->link, &dev->file_list);
293                 return (u8)i;
294         }
295
296         return -ENOENT;
297 }
298 /**
299  * mei_cl_unlink - remove me_cl from the list
300  *
301  * @dev: the device structure
302  * @host_client_id: host client id to be removed
303  */
304 int mei_cl_unlink(struct mei_cl *cl)
305 {
306         struct mei_device *dev;
307         struct mei_cl *pos, *next;
308
309         if (WARN_ON(!cl || !cl->dev))
310                 return -EINVAL;
311
312         dev = cl->dev;
313
314         list_for_each_entry_safe(pos, next, &dev->file_list, link) {
315                 if (cl->host_client_id == pos->host_client_id) {
316                         dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n",
317                                 pos->host_client_id, pos->me_client_id);
318                         list_del_init(&pos->link);
319                         break;
320                 }
321         }
322         return 0;
323 }
324
325
326 void mei_host_client_init(struct work_struct *work)
327 {
328         struct mei_device *dev = container_of(work,
329                                               struct mei_device, init_work);
330         struct mei_client_properties *client_props;
331         int i;
332
333         mutex_lock(&dev->device_lock);
334
335         bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
336         dev->open_handle_count = 0;
337
338         /*
339          * Reserving the first three client IDs
340          * 0: Reserved for MEI Bus Message communications
341          * 1: Reserved for Watchdog
342          * 2: Reserved for AMTHI
343          */
344         bitmap_set(dev->host_clients_map, 0, 3);
345
346         for (i = 0; i < dev->me_clients_num; i++) {
347                 client_props = &dev->me_clients[i].props;
348
349                 if (!uuid_le_cmp(client_props->protocol_name, mei_amthi_guid))
350                         mei_amthif_host_init(dev);
351                 else if (!uuid_le_cmp(client_props->protocol_name, mei_wd_guid))
352                         mei_wd_host_init(dev);
353         }
354
355         dev->dev_state = MEI_DEV_ENABLED;
356
357         mutex_unlock(&dev->device_lock);
358 }
359
360
361 /**
362  * mei_cl_disconnect - disconnect host clinet form the me one
363  *
364  * @cl: host client
365  *
366  * Locking: called under "dev->device_lock" lock
367  *
368  * returns 0 on success, <0 on failure.
369  */
370 int mei_cl_disconnect(struct mei_cl *cl)
371 {
372         struct mei_device *dev;
373         struct mei_cl_cb *cb;
374         int rets, err;
375
376         if (WARN_ON(!cl || !cl->dev))
377                 return -ENODEV;
378
379         dev = cl->dev;
380
381         if (cl->state != MEI_FILE_DISCONNECTING)
382                 return 0;
383
384         cb = mei_io_cb_init(cl, NULL);
385         if (!cb)
386                 return -ENOMEM;
387
388         cb->fop_type = MEI_FOP_CLOSE;
389         if (dev->mei_host_buffer_is_empty) {
390                 dev->mei_host_buffer_is_empty = false;
391                 if (mei_hbm_cl_disconnect_req(dev, cl)) {
392                         rets = -ENODEV;
393                         dev_err(&dev->pdev->dev, "failed to disconnect.\n");
394                         goto free;
395                 }
396                 mdelay(10); /* Wait for hardware disconnection ready */
397                 list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
398         } else {
399                 dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n");
400                 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
401
402         }
403         mutex_unlock(&dev->device_lock);
404
405         err = wait_event_timeout(dev->wait_recvd_msg,
406                         MEI_FILE_DISCONNECTED == cl->state,
407                         mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
408
409         mutex_lock(&dev->device_lock);
410         if (MEI_FILE_DISCONNECTED == cl->state) {
411                 rets = 0;
412                 dev_dbg(&dev->pdev->dev, "successfully disconnected from FW client.\n");
413         } else {
414                 rets = -ENODEV;
415                 if (MEI_FILE_DISCONNECTED != cl->state)
416                         dev_dbg(&dev->pdev->dev, "wrong status client disconnect.\n");
417
418                 if (err)
419                         dev_dbg(&dev->pdev->dev,
420                                         "wait failed disconnect err=%08x\n",
421                                         err);
422
423                 dev_dbg(&dev->pdev->dev, "failed to disconnect from FW client.\n");
424         }
425
426         mei_io_list_flush(&dev->ctrl_rd_list, cl);
427         mei_io_list_flush(&dev->ctrl_wr_list, cl);
428 free:
429         mei_io_cb_free(cb);
430         return rets;
431 }
432
433
434 /**
435  * mei_cl_is_other_connecting - checks if other
436  *    client with the same me client id is connecting
437  *
438  * @cl: private data of the file object
439  *
440  * returns ture if other client is connected, 0 - otherwise.
441  */
442 bool mei_cl_is_other_connecting(struct mei_cl *cl)
443 {
444         struct mei_device *dev;
445         struct mei_cl *pos;
446         struct mei_cl *next;
447
448         if (WARN_ON(!cl || !cl->dev))
449                 return false;
450
451         dev = cl->dev;
452
453         list_for_each_entry_safe(pos, next, &dev->file_list, link) {
454                 if ((pos->state == MEI_FILE_CONNECTING) &&
455                     (pos != cl) && cl->me_client_id == pos->me_client_id)
456                         return true;
457
458         }
459
460         return false;
461 }
462
463 /**
464  * mei_cl_flow_ctrl_creds - checks flow_control credits for cl.
465  *
466  * @dev: the device structure
467  * @cl: private data of the file object
468  *
469  * returns 1 if mei_flow_ctrl_creds >0, 0 - otherwise.
470  *      -ENOENT if mei_cl is not present
471  *      -EINVAL if single_recv_buf == 0
472  */
473 int mei_cl_flow_ctrl_creds(struct mei_cl *cl)
474 {
475         struct mei_device *dev;
476         int i;
477
478         if (WARN_ON(!cl || !cl->dev))
479                 return -EINVAL;
480
481         dev = cl->dev;
482
483         if (!dev->me_clients_num)
484                 return 0;
485
486         if (cl->mei_flow_ctrl_creds > 0)
487                 return 1;
488
489         for (i = 0; i < dev->me_clients_num; i++) {
490                 struct mei_me_client  *me_cl = &dev->me_clients[i];
491                 if (me_cl->client_id == cl->me_client_id) {
492                         if (me_cl->mei_flow_ctrl_creds) {
493                                 if (WARN_ON(me_cl->props.single_recv_buf == 0))
494                                         return -EINVAL;
495                                 return 1;
496                         } else {
497                                 return 0;
498                         }
499                 }
500         }
501         return -ENOENT;
502 }
503
504 /**
505  * mei_cl_flow_ctrl_reduce - reduces flow_control.
506  *
507  * @dev: the device structure
508  * @cl: private data of the file object
509  * @returns
510  *      0 on success
511  *      -ENOENT when me client is not found
512  *      -EINVAL when ctrl credits are <= 0
513  */
514 int mei_cl_flow_ctrl_reduce(struct mei_cl *cl)
515 {
516         struct mei_device *dev;
517         int i;
518
519         if (WARN_ON(!cl || !cl->dev))
520                 return -EINVAL;
521
522         dev = cl->dev;
523
524         if (!dev->me_clients_num)
525                 return -ENOENT;
526
527         for (i = 0; i < dev->me_clients_num; i++) {
528                 struct mei_me_client  *me_cl = &dev->me_clients[i];
529                 if (me_cl->client_id == cl->me_client_id) {
530                         if (me_cl->props.single_recv_buf != 0) {
531                                 if (WARN_ON(me_cl->mei_flow_ctrl_creds <= 0))
532                                         return -EINVAL;
533                                 dev->me_clients[i].mei_flow_ctrl_creds--;
534                         } else {
535                                 if (WARN_ON(cl->mei_flow_ctrl_creds <= 0))
536                                         return -EINVAL;
537                                 cl->mei_flow_ctrl_creds--;
538                         }
539                         return 0;
540                 }
541         }
542         return -ENOENT;
543 }
544
545
546
547 /**
548  * mei_ioctl_connect_client - the connect to fw client IOCTL function
549  *
550  * @dev: the device structure
551  * @data: IOCTL connect data, input and output parameters
552  * @file: private data of the file object
553  *
554  * Locking: called under "dev->device_lock" lock
555  *
556  * returns 0 on success, <0 on failure.
557  */
558 int mei_ioctl_connect_client(struct file *file,
559                         struct mei_connect_client_data *data)
560 {
561         struct mei_device *dev;
562         struct mei_cl_cb *cb;
563         struct mei_client *client;
564         struct mei_cl *cl;
565         long timeout = mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT);
566         int i;
567         int err;
568         int rets;
569
570         cl = file->private_data;
571         if (WARN_ON(!cl || !cl->dev))
572                 return -ENODEV;
573
574         dev = cl->dev;
575
576         dev_dbg(&dev->pdev->dev, "mei_ioctl_connect_client() Entry\n");
577
578         /* buffered ioctl cb */
579         cb = mei_io_cb_init(cl, file);
580         if (!cb) {
581                 rets = -ENOMEM;
582                 goto end;
583         }
584
585         cb->fop_type = MEI_FOP_IOCTL;
586
587         if (dev->dev_state != MEI_DEV_ENABLED) {
588                 rets = -ENODEV;
589                 goto end;
590         }
591         if (cl->state != MEI_FILE_INITIALIZING &&
592             cl->state != MEI_FILE_DISCONNECTED) {
593                 rets = -EBUSY;
594                 goto end;
595         }
596
597         /* find ME client we're trying to connect to */
598         i = mei_me_cl_by_uuid(dev, &data->in_client_uuid);
599         if (i >= 0 && !dev->me_clients[i].props.fixed_address) {
600                 cl->me_client_id = dev->me_clients[i].client_id;
601                 cl->state = MEI_FILE_CONNECTING;
602         }
603
604         dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n",
605                         cl->me_client_id);
606         dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n",
607                         dev->me_clients[i].props.protocol_version);
608         dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n",
609                         dev->me_clients[i].props.max_msg_length);
610
611         /* if we're connecting to amthi client then we will use the
612          * existing connection
613          */
614         if (uuid_le_cmp(data->in_client_uuid, mei_amthi_guid) == 0) {
615                 dev_dbg(&dev->pdev->dev, "FW Client is amthi\n");
616                 if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) {
617                         rets = -ENODEV;
618                         goto end;
619                 }
620                 clear_bit(cl->host_client_id, dev->host_clients_map);
621                 mei_cl_unlink(cl);
622
623                 kfree(cl);
624                 cl = NULL;
625                 file->private_data = &dev->iamthif_cl;
626
627                 client = &data->out_client_properties;
628                 client->max_msg_length =
629                         dev->me_clients[i].props.max_msg_length;
630                 client->protocol_version =
631                         dev->me_clients[i].props.protocol_version;
632                 rets = dev->iamthif_cl.status;
633
634                 goto end;
635         }
636
637         if (cl->state != MEI_FILE_CONNECTING) {
638                 rets = -ENODEV;
639                 goto end;
640         }
641
642
643         /* prepare the output buffer */
644         client = &data->out_client_properties;
645         client->max_msg_length = dev->me_clients[i].props.max_msg_length;
646         client->protocol_version = dev->me_clients[i].props.protocol_version;
647         dev_dbg(&dev->pdev->dev, "Can connect?\n");
648         if (dev->mei_host_buffer_is_empty &&
649             !mei_cl_is_other_connecting(cl)) {
650                 dev_dbg(&dev->pdev->dev, "Sending Connect Message\n");
651                 dev->mei_host_buffer_is_empty = false;
652                 if (mei_hbm_cl_connect_req(dev, cl)) {
653                         dev_dbg(&dev->pdev->dev, "Sending connect message - failed\n");
654                         rets = -ENODEV;
655                         goto end;
656                 } else {
657                         dev_dbg(&dev->pdev->dev, "Sending connect message - succeeded\n");
658                         cl->timer_count = MEI_CONNECT_TIMEOUT;
659                         list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
660                 }
661
662
663         } else {
664                 dev_dbg(&dev->pdev->dev, "Queuing the connect request due to device busy\n");
665                 dev_dbg(&dev->pdev->dev, "add connect cb to control write list.\n");
666                 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
667         }
668         mutex_unlock(&dev->device_lock);
669         err = wait_event_timeout(dev->wait_recvd_msg,
670                         (MEI_FILE_CONNECTED == cl->state ||
671                          MEI_FILE_DISCONNECTED == cl->state), timeout);
672
673         mutex_lock(&dev->device_lock);
674         if (MEI_FILE_CONNECTED == cl->state) {
675                 dev_dbg(&dev->pdev->dev, "successfully connected to FW client.\n");
676                 rets = cl->status;
677                 goto end;
678         } else {
679                 dev_dbg(&dev->pdev->dev, "failed to connect to FW client.cl->state = %d.\n",
680                     cl->state);
681                 if (!err) {
682                         dev_dbg(&dev->pdev->dev,
683                                 "wait_event_interruptible_timeout failed on client"
684                                 " connect message fw response message.\n");
685                 }
686                 rets = -EFAULT;
687
688                 mei_io_list_flush(&dev->ctrl_rd_list, cl);
689                 mei_io_list_flush(&dev->ctrl_wr_list, cl);
690                 goto end;
691         }
692         rets = 0;
693 end:
694         dev_dbg(&dev->pdev->dev, "free connect cb memory.");
695         mei_io_cb_free(cb);
696         return rets;
697 }
698
699 /**
700  * mei_cl_start_read - the start read client message function.
701  *
702  * @cl: host client
703  *
704  * returns 0 on success, <0 on failure.
705  */
706 int mei_cl_read_start(struct mei_cl *cl)
707 {
708         struct mei_device *dev;
709         struct mei_cl_cb *cb;
710         int rets;
711         int i;
712
713         if (WARN_ON(!cl || !cl->dev))
714                 return -ENODEV;
715
716         dev = cl->dev;
717
718         if (cl->state != MEI_FILE_CONNECTED)
719                 return -ENODEV;
720
721         if (dev->dev_state != MEI_DEV_ENABLED)
722                 return -ENODEV;
723
724         if (cl->read_pending || cl->read_cb) {
725                 dev_dbg(&dev->pdev->dev, "read is pending.\n");
726                 return -EBUSY;
727         }
728         i = mei_me_cl_by_id(dev, cl->me_client_id);
729         if (i < 0) {
730                 dev_err(&dev->pdev->dev, "no such me client %d\n",
731                         cl->me_client_id);
732                 return  -ENODEV;
733         }
734
735         cb = mei_io_cb_init(cl, NULL);
736         if (!cb)
737                 return -ENOMEM;
738
739         rets = mei_io_cb_alloc_resp_buf(cb,
740                         dev->me_clients[i].props.max_msg_length);
741         if (rets)
742                 goto err;
743
744         cb->fop_type = MEI_FOP_READ;
745         cl->read_cb = cb;
746         if (dev->mei_host_buffer_is_empty) {
747                 dev->mei_host_buffer_is_empty = false;
748                 if (mei_hbm_cl_flow_control_req(dev, cl)) {
749                         rets = -ENODEV;
750                         goto err;
751                 }
752                 list_add_tail(&cb->list, &dev->read_list.list);
753         } else {
754                 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
755         }
756         return rets;
757 err:
758         mei_io_cb_free(cb);
759         return rets;
760 }
761