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