/drivers/staging/mei/iorw.c

https://bitbucket.org/cyanogenmod/android_kernel_asus_tf300t · C · 604 lines · 428 code · 77 blank · 99 comment · 98 complexity · ab343b3257cdb394af4b4f36b3b7677c MD5 · raw file

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