iorw.c 15 KB

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