mei: kill usless struct mei_io_list
[firefly-linux-kernel-4.4.55.git] / drivers / misc / mei / iorw.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
18 #include <linux/kernel.h>
19 #include <linux/fs.h>
20 #include <linux/errno.h>
21 #include <linux/types.h>
22 #include <linux/fcntl.h>
23 #include <linux/aio.h>
24 #include <linux/pci.h>
25 #include <linux/init.h>
26 #include <linux/ioctl.h>
27 #include <linux/cdev.h>
28 #include <linux/list.h>
29 #include <linux/delay.h>
30 #include <linux/sched.h>
31 #include <linux/uuid.h>
32 #include <linux/jiffies.h>
33 #include <linux/uaccess.h>
34
35
36 #include "mei_dev.h"
37 #include "hw.h"
38 #include <linux/mei.h>
39 #include "interface.h"
40
41 /**
42  * mei_me_cl_by_id return index to me_clients for client_id
43  *
44  * @dev: the device structure
45  * @client_id: me client id
46  *
47  * Locking: called under "dev->device_lock" lock
48  *
49  * returns index on success, -ENOENT on failure.
50  */
51
52 int mei_me_cl_by_id(struct mei_device *dev, u8 client_id)
53 {
54         int i;
55         for (i = 0; i < dev->me_clients_num; i++)
56                 if (dev->me_clients[i].client_id == client_id)
57                         break;
58         if (WARN_ON(dev->me_clients[i].client_id != client_id))
59                 return -ENOENT;
60
61         if (i == dev->me_clients_num)
62                 return -ENOENT;
63
64         return i;
65 }
66
67 /**
68  * mei_ioctl_connect_client - the connect to fw client IOCTL function
69  *
70  * @dev: the device structure
71  * @data: IOCTL connect data, input and output parameters
72  * @file: private data of the file object
73  *
74  * Locking: called under "dev->device_lock" lock
75  *
76  * returns 0 on success, <0 on failure.
77  */
78 int mei_ioctl_connect_client(struct file *file,
79                         struct mei_connect_client_data *data)
80 {
81         struct mei_device *dev;
82         struct mei_cl_cb *cb;
83         struct mei_client *client;
84         struct mei_cl *cl;
85         struct mei_cl *cl_pos = NULL;
86         struct mei_cl *cl_next = NULL;
87         long timeout = CONNECT_TIMEOUT;
88         int i;
89         int err;
90         int rets;
91
92         cl = file->private_data;
93         if (WARN_ON(!cl || !cl->dev))
94                 return -ENODEV;
95
96         dev = cl->dev;
97
98         dev_dbg(&dev->pdev->dev, "mei_ioctl_connect_client() Entry\n");
99
100
101         /* buffered ioctl cb */
102         cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
103         if (!cb) {
104                 rets = -ENOMEM;
105                 goto end;
106         }
107         mei_io_list_init(cb);
108
109         cb->major_file_operations = MEI_IOCTL;
110
111         if (dev->dev_state != MEI_DEV_ENABLED) {
112                 rets = -ENODEV;
113                 goto end;
114         }
115         if (cl->state != MEI_FILE_INITIALIZING &&
116             cl->state != MEI_FILE_DISCONNECTED) {
117                 rets = -EBUSY;
118                 goto end;
119         }
120
121         /* find ME client we're trying to connect to */
122         i = mei_me_cl_by_uuid(dev, &data->in_client_uuid);
123         if (i >= 0 && !dev->me_clients[i].props.fixed_address) {
124                 cl->me_client_id = dev->me_clients[i].client_id;
125                 cl->state = MEI_FILE_CONNECTING;
126         }
127
128         dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n",
129                         cl->me_client_id);
130         dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n",
131                         dev->me_clients[i].props.protocol_version);
132         dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n",
133                         dev->me_clients[i].props.max_msg_length);
134
135         /* if we're connecting to amthi client then we will use the
136          * existing connection
137          */
138         if (uuid_le_cmp(data->in_client_uuid, mei_amthi_guid) == 0) {
139                 dev_dbg(&dev->pdev->dev, "FW Client is amthi\n");
140                 if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) {
141                         rets = -ENODEV;
142                         goto end;
143                 }
144                 clear_bit(cl->host_client_id, dev->host_clients_map);
145                 list_for_each_entry_safe(cl_pos, cl_next,
146                                          &dev->file_list, link) {
147                         if (mei_cl_cmp_id(cl, cl_pos)) {
148                                 dev_dbg(&dev->pdev->dev,
149                                         "remove file private data node host"
150                                     " client = %d, ME client = %d.\n",
151                                     cl_pos->host_client_id,
152                                     cl_pos->me_client_id);
153                                 list_del(&cl_pos->link);
154                         }
155
156                 }
157                 dev_dbg(&dev->pdev->dev, "free file private data memory.\n");
158                 kfree(cl);
159
160                 cl = NULL;
161                 file->private_data = &dev->iamthif_cl;
162
163                 client = &data->out_client_properties;
164                 client->max_msg_length =
165                         dev->me_clients[i].props.max_msg_length;
166                 client->protocol_version =
167                         dev->me_clients[i].props.protocol_version;
168                 rets = dev->iamthif_cl.status;
169
170                 goto end;
171         }
172
173         if (cl->state != MEI_FILE_CONNECTING) {
174                 rets = -ENODEV;
175                 goto end;
176         }
177
178
179         /* prepare the output buffer */
180         client = &data->out_client_properties;
181         client->max_msg_length = dev->me_clients[i].props.max_msg_length;
182         client->protocol_version = dev->me_clients[i].props.protocol_version;
183         dev_dbg(&dev->pdev->dev, "Can connect?\n");
184         if (dev->mei_host_buffer_is_empty
185             && !mei_other_client_is_connecting(dev, cl)) {
186                 dev_dbg(&dev->pdev->dev, "Sending Connect Message\n");
187                 dev->mei_host_buffer_is_empty = false;
188                 if (mei_connect(dev, cl)) {
189                         dev_dbg(&dev->pdev->dev, "Sending connect message - failed\n");
190                         rets = -ENODEV;
191                         goto end;
192                 } else {
193                         dev_dbg(&dev->pdev->dev, "Sending connect message - succeeded\n");
194                         cl->timer_count = MEI_CONNECT_TIMEOUT;
195                         cb->file_private = cl;
196                         list_add_tail(&cb->list, &dev->ctrl_rd_list.list);
197                 }
198
199
200         } else {
201                 dev_dbg(&dev->pdev->dev, "Queuing the connect request due to device busy\n");
202                 cb->file_private = cl;
203                 dev_dbg(&dev->pdev->dev, "add connect cb to control write list.\n");
204                 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
205         }
206         mutex_unlock(&dev->device_lock);
207         err = wait_event_timeout(dev->wait_recvd_msg,
208                         (MEI_FILE_CONNECTED == cl->state ||
209                          MEI_FILE_DISCONNECTED == cl->state),
210                         timeout * HZ);
211
212         mutex_lock(&dev->device_lock);
213         if (MEI_FILE_CONNECTED == cl->state) {
214                 dev_dbg(&dev->pdev->dev, "successfully connected to FW client.\n");
215                 rets = cl->status;
216                 goto end;
217         } else {
218                 dev_dbg(&dev->pdev->dev, "failed to connect to FW client.cl->state = %d.\n",
219                     cl->state);
220                 if (!err) {
221                         dev_dbg(&dev->pdev->dev,
222                                 "wait_event_interruptible_timeout failed on client"
223                                 " connect message fw response message.\n");
224                 }
225                 rets = -EFAULT;
226
227                 mei_io_list_flush(&dev->ctrl_rd_list, cl);
228                 mei_io_list_flush(&dev->ctrl_wr_list, cl);
229                 goto end;
230         }
231         rets = 0;
232 end:
233         dev_dbg(&dev->pdev->dev, "free connect cb memory.");
234         kfree(cb);
235         return rets;
236 }
237
238 /**
239  * find_amthi_read_list_entry - finds a amthilist entry for current file
240  *
241  * @dev: the device structure
242  * @file: pointer to file object
243  *
244  * returns   returned a list entry on success, NULL on failure.
245  */
246 struct mei_cl_cb *find_amthi_read_list_entry(
247                 struct mei_device *dev,
248                 struct file *file)
249 {
250         struct mei_cl *cl_temp;
251         struct mei_cl_cb *pos = NULL;
252         struct mei_cl_cb *next = NULL;
253
254         list_for_each_entry_safe(pos, next,
255             &dev->amthi_read_complete_list.list, list) {
256                 cl_temp = (struct mei_cl *)pos->file_private;
257                 if (cl_temp && cl_temp == &dev->iamthif_cl &&
258                         pos->file_object == file)
259                         return pos;
260         }
261         return NULL;
262 }
263
264 /**
265  * amthi_read - read data from AMTHI client
266  *
267  * @dev: the device structure
268  * @if_num:  minor number
269  * @file: pointer to file object
270  * @*ubuf: pointer to user data in user space
271  * @length: data length to read
272  * @offset: data read offset
273  *
274  * Locking: called under "dev->device_lock" lock
275  *
276  * returns
277  *  returned data length on success,
278  *  zero if no data to read,
279  *  negative on failure.
280  */
281 int amthi_read(struct mei_device *dev, struct file *file,
282                char __user *ubuf, size_t length, loff_t *offset)
283 {
284         int rets;
285         int wait_ret;
286         struct mei_cl_cb *cb = NULL;
287         struct mei_cl *cl = file->private_data;
288         unsigned long timeout;
289         int i;
290
291         /* Only Posible if we are in timeout */
292         if (!cl || cl != &dev->iamthif_cl) {
293                 dev_dbg(&dev->pdev->dev, "bad file ext.\n");
294                 return -ETIMEDOUT;
295         }
296
297         i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id);
298
299         if (i < 0) {
300                 dev_dbg(&dev->pdev->dev, "amthi client not found.\n");
301                 return -ENODEV;
302         }
303         dev_dbg(&dev->pdev->dev, "checking amthi data\n");
304         cb = find_amthi_read_list_entry(dev, file);
305
306         /* Check for if we can block or not*/
307         if (cb == NULL && file->f_flags & O_NONBLOCK)
308                 return -EAGAIN;
309
310
311         dev_dbg(&dev->pdev->dev, "waiting for amthi data\n");
312         while (cb == NULL) {
313                 /* unlock the Mutex */
314                 mutex_unlock(&dev->device_lock);
315
316                 wait_ret = wait_event_interruptible(dev->iamthif_cl.wait,
317                         (cb = find_amthi_read_list_entry(dev, file)));
318
319                 if (wait_ret)
320                         return -ERESTARTSYS;
321
322                 dev_dbg(&dev->pdev->dev, "woke up from sleep\n");
323
324                 /* Locking again the Mutex */
325                 mutex_lock(&dev->device_lock);
326         }
327
328
329         dev_dbg(&dev->pdev->dev, "Got amthi data\n");
330         dev->iamthif_timer = 0;
331
332         if (cb) {
333                 timeout = cb->read_time + msecs_to_jiffies(IAMTHIF_READ_TIMER);
334                 dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n",
335                                 timeout);
336
337                 if  (time_after(jiffies, timeout)) {
338                         dev_dbg(&dev->pdev->dev, "amthi Time out\n");
339                         /* 15 sec for the message has expired */
340                         list_del(&cb->list);
341                         rets = -ETIMEDOUT;
342                         goto free;
343                 }
344         }
345         /* if the whole message will fit remove it from the list */
346         if (cb->buf_idx >= *offset && length >= (cb->buf_idx - *offset))
347                 list_del(&cb->list);
348         else if (cb->buf_idx > 0 && cb->buf_idx <= *offset) {
349                 /* end of the message has been reached */
350                 list_del(&cb->list);
351                 rets = 0;
352                 goto free;
353         }
354                 /* else means that not full buffer will be read and do not
355                  * remove message from deletion list
356                  */
357
358         dev_dbg(&dev->pdev->dev, "amthi cb->response_buffer size - %d\n",
359             cb->response_buffer.size);
360         dev_dbg(&dev->pdev->dev, "amthi cb->buf_idx - %lu\n", cb->buf_idx);
361
362         /* length is being turncated to PAGE_SIZE, however,
363          * the buf_idx may point beyond */
364         length = min_t(size_t, length, (cb->buf_idx - *offset));
365
366         if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length))
367                 rets = -EFAULT;
368         else {
369                 rets = length;
370                 if ((*offset + length) < cb->buf_idx) {
371                         *offset += length;
372                         goto out;
373                 }
374         }
375 free:
376         dev_dbg(&dev->pdev->dev, "free amthi cb memory.\n");
377         *offset = 0;
378         mei_free_cb_private(cb);
379 out:
380         return rets;
381 }
382
383 /**
384  * mei_start_read - the start read client message function.
385  *
386  * @dev: the device structure
387  * @if_num:  minor number
388  * @cl: private data of the file object
389  *
390  * returns 0 on success, <0 on failure.
391  */
392 int mei_start_read(struct mei_device *dev, struct mei_cl *cl)
393 {
394         struct mei_cl_cb *cb;
395         int rets = 0;
396         int i;
397
398         if (cl->state != MEI_FILE_CONNECTED)
399                 return -ENODEV;
400
401         if (dev->dev_state != MEI_DEV_ENABLED)
402                 return -ENODEV;
403
404         dev_dbg(&dev->pdev->dev, "check if read is pending.\n");
405         if (cl->read_pending || cl->read_cb) {
406                 dev_dbg(&dev->pdev->dev, "read is pending.\n");
407                 return -EBUSY;
408         }
409
410         cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
411         if (!cb)
412                 return -ENOMEM;
413
414         dev_dbg(&dev->pdev->dev, "allocation call back successful. host client = %d, ME client = %d\n",
415                 cl->host_client_id, cl->me_client_id);
416         i = mei_me_cl_by_id(dev, cl->me_client_id);
417         if (i < 0) {
418                 rets = -ENODEV;
419                 goto unlock;
420         }
421
422         cb->response_buffer.size = dev->me_clients[i].props.max_msg_length;
423         cb->response_buffer.data =
424                         kmalloc(cb->response_buffer.size, GFP_KERNEL);
425         if (!cb->response_buffer.data) {
426                 rets = -ENOMEM;
427                 goto unlock;
428         }
429         dev_dbg(&dev->pdev->dev, "allocation call back data success.\n");
430         cb->major_file_operations = MEI_READ;
431         /* make sure buffer index is zero before we start */
432         cb->buf_idx = 0;
433         cb->file_private = (void *) cl;
434         cl->read_cb = cb;
435         if (dev->mei_host_buffer_is_empty) {
436                 dev->mei_host_buffer_is_empty = false;
437                 if (mei_send_flow_control(dev, cl)) {
438                         rets = -ENODEV;
439                         goto unlock;
440                 }
441                 list_add_tail(&cb->list, &dev->read_list.list);
442         } else {
443                 list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
444         }
445         return rets;
446 unlock:
447         mei_free_cb_private(cb);
448         return rets;
449 }
450
451 /**
452  * amthi_write - write iamthif data to amthi client
453  *
454  * @dev: the device structure
455  * @cb: mei call back struct
456  *
457  * returns 0 on success, <0 on failure.
458  */
459 int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb)
460 {
461         struct mei_msg_hdr mei_hdr;
462         int ret;
463
464         if (!dev || !cb)
465                 return -ENODEV;
466
467         dev_dbg(&dev->pdev->dev, "write data to amthi client.\n");
468
469         dev->iamthif_state = MEI_IAMTHIF_WRITING;
470         dev->iamthif_current_cb = cb;
471         dev->iamthif_file_object = cb->file_object;
472         dev->iamthif_canceled = false;
473         dev->iamthif_ioctl = true;
474         dev->iamthif_msg_buf_size = cb->request_buffer.size;
475         memcpy(dev->iamthif_msg_buf, cb->request_buffer.data,
476                cb->request_buffer.size);
477
478         ret = mei_flow_ctrl_creds(dev, &dev->iamthif_cl);
479         if (ret < 0)
480                 return ret;
481
482         if (ret && dev->mei_host_buffer_is_empty) {
483                 ret = 0;
484                 dev->mei_host_buffer_is_empty = false;
485                 if (cb->request_buffer.size > mei_hbuf_max_data(dev)) {
486                         mei_hdr.length = mei_hbuf_max_data(dev);
487                         mei_hdr.msg_complete = 0;
488                 } else {
489                         mei_hdr.length = cb->request_buffer.size;
490                         mei_hdr.msg_complete = 1;
491                 }
492
493                 mei_hdr.host_addr = dev->iamthif_cl.host_client_id;
494                 mei_hdr.me_addr = dev->iamthif_cl.me_client_id;
495                 mei_hdr.reserved = 0;
496                 dev->iamthif_msg_buf_index += mei_hdr.length;
497                 if (mei_write_message(dev, &mei_hdr,
498                                         (unsigned char *)(dev->iamthif_msg_buf),
499                                         mei_hdr.length))
500                         return -ENODEV;
501
502                 if (mei_hdr.msg_complete) {
503                         if (mei_flow_ctrl_reduce(dev, &dev->iamthif_cl))
504                                 return -ENODEV;
505                         dev->iamthif_flow_control_pending = true;
506                         dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
507                         dev_dbg(&dev->pdev->dev, "add amthi cb to write waiting list\n");
508                         dev->iamthif_current_cb = cb;
509                         dev->iamthif_file_object = cb->file_object;
510                         list_add_tail(&cb->list, &dev->write_waiting_list.list);
511                 } else {
512                         dev_dbg(&dev->pdev->dev, "message does not complete, "
513                                         "so add amthi cb to write list.\n");
514                         list_add_tail(&cb->list, &dev->write_list.list);
515                 }
516         } else {
517                 if (!(dev->mei_host_buffer_is_empty))
518                         dev_dbg(&dev->pdev->dev, "host buffer is not empty");
519
520                 dev_dbg(&dev->pdev->dev, "No flow control credentials, "
521                                 "so add iamthif cb to write list.\n");
522                 list_add_tail(&cb->list, &dev->write_list.list);
523         }
524         return 0;
525 }
526
527 /**
528  * iamthif_ioctl_send_msg - send cmd data to amthi client
529  *
530  * @dev: the device structure
531  *
532  * returns 0 on success, <0 on failure.
533  */
534 void mei_run_next_iamthif_cmd(struct mei_device *dev)
535 {
536         struct mei_cl *cl_tmp;
537         struct mei_cl_cb *pos = NULL;
538         struct mei_cl_cb *next = NULL;
539         int status;
540
541         if (!dev)
542                 return;
543
544         dev->iamthif_msg_buf_size = 0;
545         dev->iamthif_msg_buf_index = 0;
546         dev->iamthif_canceled = false;
547         dev->iamthif_ioctl = true;
548         dev->iamthif_state = MEI_IAMTHIF_IDLE;
549         dev->iamthif_timer = 0;
550         dev->iamthif_file_object = NULL;
551
552         dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n");
553
554         list_for_each_entry_safe(pos, next, &dev->amthi_cmd_list.list, list) {
555                 list_del(&pos->list);
556                 cl_tmp = (struct mei_cl *)pos->file_private;
557
558                 if (cl_tmp && cl_tmp == &dev->iamthif_cl) {
559                         status = amthi_write(dev, pos);
560                         if (status) {
561                                 dev_dbg(&dev->pdev->dev,
562                                         "amthi write failed status = %d\n",
563                                                 status);
564                                 return;
565                         }
566                         break;
567                 }
568         }
569 }
570
571 /**
572  * mei_free_cb_private - free mei_cb_private related memory
573  *
574  * @cb: mei callback struct
575  */
576 void mei_free_cb_private(struct mei_cl_cb *cb)
577 {
578         if (cb == NULL)
579                 return;
580
581         kfree(cb->request_buffer.data);
582         kfree(cb->response_buffer.data);
583         kfree(cb);
584 }