PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/staging/greybus/fw-download.c

https://github.com/kvaneesh/linux
C | 466 lines | 322 code | 89 blank | 55 comment | 29 complexity | 63323de4cd4607910fc7ba0945b622f1 MD5 | raw file
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Greybus Firmware Download Protocol Driver.
  4. *
  5. * Copyright 2016 Google Inc.
  6. * Copyright 2016 Linaro Ltd.
  7. */
  8. #include <linux/firmware.h>
  9. #include <linux/jiffies.h>
  10. #include <linux/mutex.h>
  11. #include <linux/workqueue.h>
  12. #include <linux/greybus.h>
  13. #include "firmware.h"
  14. /* Estimated minimum buffer size, actual size can be smaller than this */
  15. #define MIN_FETCH_SIZE 512
  16. /* Timeout, in jiffies, within which fetch or release firmware must be called */
  17. #define NEXT_REQ_TIMEOUT_J msecs_to_jiffies(1000)
  18. struct fw_request {
  19. u8 firmware_id;
  20. bool disabled;
  21. bool timedout;
  22. char name[FW_NAME_SIZE];
  23. const struct firmware *fw;
  24. struct list_head node;
  25. struct delayed_work dwork;
  26. /* Timeout, in jiffies, within which the firmware shall download */
  27. unsigned long release_timeout_j;
  28. struct kref kref;
  29. struct fw_download *fw_download;
  30. };
  31. struct fw_download {
  32. struct device *parent;
  33. struct gb_connection *connection;
  34. struct list_head fw_requests;
  35. struct ida id_map;
  36. struct mutex mutex;
  37. };
  38. static void fw_req_release(struct kref *kref)
  39. {
  40. struct fw_request *fw_req = container_of(kref, struct fw_request, kref);
  41. dev_dbg(fw_req->fw_download->parent, "firmware %s released\n",
  42. fw_req->name);
  43. release_firmware(fw_req->fw);
  44. /*
  45. * The request timed out and the module may send a fetch-fw or
  46. * release-fw request later. Lets block the id we allocated for this
  47. * request, so that the AP doesn't refer to a later fw-request (with
  48. * same firmware_id) for the old timedout fw-request.
  49. *
  50. * NOTE:
  51. *
  52. * This also means that after 255 timeouts we will fail to service new
  53. * firmware downloads. But what else can we do in that case anyway? Lets
  54. * just hope that it never happens.
  55. */
  56. if (!fw_req->timedout)
  57. ida_simple_remove(&fw_req->fw_download->id_map,
  58. fw_req->firmware_id);
  59. kfree(fw_req);
  60. }
  61. /*
  62. * Incoming requests are serialized for a connection, and the only race possible
  63. * is between the timeout handler freeing this and an incoming request.
  64. *
  65. * The operations on the fw-request list are protected by the mutex and
  66. * get_fw_req() increments the reference count before returning a fw_req pointer
  67. * to the users.
  68. *
  69. * free_firmware() also takes the mutex while removing an entry from the list,
  70. * it guarantees that every user of fw_req has taken a kref-reference by now and
  71. * we wouldn't have any new users.
  72. *
  73. * Once the last user drops the reference, the fw_req structure is freed.
  74. */
  75. static void put_fw_req(struct fw_request *fw_req)
  76. {
  77. kref_put(&fw_req->kref, fw_req_release);
  78. }
  79. /* Caller must call put_fw_req() after using struct fw_request */
  80. static struct fw_request *get_fw_req(struct fw_download *fw_download,
  81. u8 firmware_id)
  82. {
  83. struct fw_request *fw_req;
  84. mutex_lock(&fw_download->mutex);
  85. list_for_each_entry(fw_req, &fw_download->fw_requests, node) {
  86. if (fw_req->firmware_id == firmware_id) {
  87. kref_get(&fw_req->kref);
  88. goto unlock;
  89. }
  90. }
  91. fw_req = NULL;
  92. unlock:
  93. mutex_unlock(&fw_download->mutex);
  94. return fw_req;
  95. }
  96. static void free_firmware(struct fw_download *fw_download,
  97. struct fw_request *fw_req)
  98. {
  99. /* Already disabled from timeout handlers */
  100. if (fw_req->disabled)
  101. return;
  102. mutex_lock(&fw_download->mutex);
  103. list_del(&fw_req->node);
  104. mutex_unlock(&fw_download->mutex);
  105. fw_req->disabled = true;
  106. put_fw_req(fw_req);
  107. }
  108. static void fw_request_timedout(struct work_struct *work)
  109. {
  110. struct delayed_work *dwork = to_delayed_work(work);
  111. struct fw_request *fw_req = container_of(dwork,
  112. struct fw_request, dwork);
  113. struct fw_download *fw_download = fw_req->fw_download;
  114. dev_err(fw_download->parent,
  115. "Timed out waiting for fetch / release firmware requests: %u\n",
  116. fw_req->firmware_id);
  117. fw_req->timedout = true;
  118. free_firmware(fw_download, fw_req);
  119. }
  120. static int exceeds_release_timeout(struct fw_request *fw_req)
  121. {
  122. struct fw_download *fw_download = fw_req->fw_download;
  123. if (time_before(jiffies, fw_req->release_timeout_j))
  124. return 0;
  125. dev_err(fw_download->parent,
  126. "Firmware download didn't finish in time, abort: %d\n",
  127. fw_req->firmware_id);
  128. fw_req->timedout = true;
  129. free_firmware(fw_download, fw_req);
  130. return -ETIMEDOUT;
  131. }
  132. /* This returns path of the firmware blob on the disk */
  133. static struct fw_request *find_firmware(struct fw_download *fw_download,
  134. const char *tag)
  135. {
  136. struct gb_interface *intf = fw_download->connection->bundle->intf;
  137. struct fw_request *fw_req;
  138. int ret, req_count;
  139. fw_req = kzalloc(sizeof(*fw_req), GFP_KERNEL);
  140. if (!fw_req)
  141. return ERR_PTR(-ENOMEM);
  142. /* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */
  143. ret = ida_simple_get(&fw_download->id_map, 1, 256, GFP_KERNEL);
  144. if (ret < 0) {
  145. dev_err(fw_download->parent,
  146. "failed to allocate firmware id (%d)\n", ret);
  147. goto err_free_req;
  148. }
  149. fw_req->firmware_id = ret;
  150. snprintf(fw_req->name, sizeof(fw_req->name),
  151. FW_NAME_PREFIX "%08x_%08x_%08x_%08x_%s.tftf",
  152. intf->ddbl1_manufacturer_id, intf->ddbl1_product_id,
  153. intf->vendor_id, intf->product_id, tag);
  154. dev_info(fw_download->parent, "Requested firmware package '%s'\n",
  155. fw_req->name);
  156. ret = request_firmware(&fw_req->fw, fw_req->name, fw_download->parent);
  157. if (ret) {
  158. dev_err(fw_download->parent,
  159. "firmware request failed for %s (%d)\n", fw_req->name,
  160. ret);
  161. goto err_free_id;
  162. }
  163. fw_req->fw_download = fw_download;
  164. kref_init(&fw_req->kref);
  165. mutex_lock(&fw_download->mutex);
  166. list_add(&fw_req->node, &fw_download->fw_requests);
  167. mutex_unlock(&fw_download->mutex);
  168. /* Timeout, in jiffies, within which firmware should get loaded */
  169. req_count = DIV_ROUND_UP(fw_req->fw->size, MIN_FETCH_SIZE);
  170. fw_req->release_timeout_j = jiffies + req_count * NEXT_REQ_TIMEOUT_J;
  171. INIT_DELAYED_WORK(&fw_req->dwork, fw_request_timedout);
  172. schedule_delayed_work(&fw_req->dwork, NEXT_REQ_TIMEOUT_J);
  173. return fw_req;
  174. err_free_id:
  175. ida_simple_remove(&fw_download->id_map, fw_req->firmware_id);
  176. err_free_req:
  177. kfree(fw_req);
  178. return ERR_PTR(ret);
  179. }
  180. static int fw_download_find_firmware(struct gb_operation *op)
  181. {
  182. struct gb_connection *connection = op->connection;
  183. struct fw_download *fw_download = gb_connection_get_data(connection);
  184. struct gb_fw_download_find_firmware_request *request;
  185. struct gb_fw_download_find_firmware_response *response;
  186. struct fw_request *fw_req;
  187. const char *tag;
  188. if (op->request->payload_size != sizeof(*request)) {
  189. dev_err(fw_download->parent,
  190. "illegal size of find firmware request (%zu != %zu)\n",
  191. op->request->payload_size, sizeof(*request));
  192. return -EINVAL;
  193. }
  194. request = op->request->payload;
  195. tag = (const char *)request->firmware_tag;
  196. /* firmware_tag must be null-terminated */
  197. if (strnlen(tag, GB_FIRMWARE_TAG_MAX_SIZE) ==
  198. GB_FIRMWARE_TAG_MAX_SIZE) {
  199. dev_err(fw_download->parent,
  200. "firmware-tag is not null-terminated\n");
  201. return -EINVAL;
  202. }
  203. fw_req = find_firmware(fw_download, tag);
  204. if (IS_ERR(fw_req))
  205. return PTR_ERR(fw_req);
  206. if (!gb_operation_response_alloc(op, sizeof(*response), GFP_KERNEL)) {
  207. dev_err(fw_download->parent, "error allocating response\n");
  208. free_firmware(fw_download, fw_req);
  209. return -ENOMEM;
  210. }
  211. response = op->response->payload;
  212. response->firmware_id = fw_req->firmware_id;
  213. response->size = cpu_to_le32(fw_req->fw->size);
  214. dev_dbg(fw_download->parent,
  215. "firmware size is %zu bytes\n", fw_req->fw->size);
  216. return 0;
  217. }
  218. static int fw_download_fetch_firmware(struct gb_operation *op)
  219. {
  220. struct gb_connection *connection = op->connection;
  221. struct fw_download *fw_download = gb_connection_get_data(connection);
  222. struct gb_fw_download_fetch_firmware_request *request;
  223. struct gb_fw_download_fetch_firmware_response *response;
  224. struct fw_request *fw_req;
  225. const struct firmware *fw;
  226. unsigned int offset, size;
  227. u8 firmware_id;
  228. int ret = 0;
  229. if (op->request->payload_size != sizeof(*request)) {
  230. dev_err(fw_download->parent,
  231. "Illegal size of fetch firmware request (%zu %zu)\n",
  232. op->request->payload_size, sizeof(*request));
  233. return -EINVAL;
  234. }
  235. request = op->request->payload;
  236. offset = le32_to_cpu(request->offset);
  237. size = le32_to_cpu(request->size);
  238. firmware_id = request->firmware_id;
  239. fw_req = get_fw_req(fw_download, firmware_id);
  240. if (!fw_req) {
  241. dev_err(fw_download->parent,
  242. "firmware not available for id: %02u\n", firmware_id);
  243. return -EINVAL;
  244. }
  245. /* Make sure work handler isn't running in parallel */
  246. cancel_delayed_work_sync(&fw_req->dwork);
  247. /* We timed-out before reaching here ? */
  248. if (fw_req->disabled) {
  249. ret = -ETIMEDOUT;
  250. goto put_fw;
  251. }
  252. /*
  253. * Firmware download must finish within a limited time interval. If it
  254. * doesn't, then we might have a buggy Module on the other side. Abort
  255. * download.
  256. */
  257. ret = exceeds_release_timeout(fw_req);
  258. if (ret)
  259. goto put_fw;
  260. fw = fw_req->fw;
  261. if (offset >= fw->size || size > fw->size - offset) {
  262. dev_err(fw_download->parent,
  263. "bad fetch firmware request (offs = %u, size = %u)\n",
  264. offset, size);
  265. ret = -EINVAL;
  266. goto put_fw;
  267. }
  268. if (!gb_operation_response_alloc(op, sizeof(*response) + size,
  269. GFP_KERNEL)) {
  270. dev_err(fw_download->parent,
  271. "error allocating fetch firmware response\n");
  272. ret = -ENOMEM;
  273. goto put_fw;
  274. }
  275. response = op->response->payload;
  276. memcpy(response->data, fw->data + offset, size);
  277. dev_dbg(fw_download->parent,
  278. "responding with firmware (offs = %u, size = %u)\n", offset,
  279. size);
  280. /* Refresh timeout */
  281. schedule_delayed_work(&fw_req->dwork, NEXT_REQ_TIMEOUT_J);
  282. put_fw:
  283. put_fw_req(fw_req);
  284. return ret;
  285. }
  286. static int fw_download_release_firmware(struct gb_operation *op)
  287. {
  288. struct gb_connection *connection = op->connection;
  289. struct fw_download *fw_download = gb_connection_get_data(connection);
  290. struct gb_fw_download_release_firmware_request *request;
  291. struct fw_request *fw_req;
  292. u8 firmware_id;
  293. if (op->request->payload_size != sizeof(*request)) {
  294. dev_err(fw_download->parent,
  295. "Illegal size of release firmware request (%zu %zu)\n",
  296. op->request->payload_size, sizeof(*request));
  297. return -EINVAL;
  298. }
  299. request = op->request->payload;
  300. firmware_id = request->firmware_id;
  301. fw_req = get_fw_req(fw_download, firmware_id);
  302. if (!fw_req) {
  303. dev_err(fw_download->parent,
  304. "firmware not available for id: %02u\n", firmware_id);
  305. return -EINVAL;
  306. }
  307. cancel_delayed_work_sync(&fw_req->dwork);
  308. free_firmware(fw_download, fw_req);
  309. put_fw_req(fw_req);
  310. dev_dbg(fw_download->parent, "release firmware\n");
  311. return 0;
  312. }
  313. int gb_fw_download_request_handler(struct gb_operation *op)
  314. {
  315. u8 type = op->type;
  316. switch (type) {
  317. case GB_FW_DOWNLOAD_TYPE_FIND_FIRMWARE:
  318. return fw_download_find_firmware(op);
  319. case GB_FW_DOWNLOAD_TYPE_FETCH_FIRMWARE:
  320. return fw_download_fetch_firmware(op);
  321. case GB_FW_DOWNLOAD_TYPE_RELEASE_FIRMWARE:
  322. return fw_download_release_firmware(op);
  323. default:
  324. dev_err(&op->connection->bundle->dev,
  325. "unsupported request: %u\n", type);
  326. return -EINVAL;
  327. }
  328. }
  329. int gb_fw_download_connection_init(struct gb_connection *connection)
  330. {
  331. struct fw_download *fw_download;
  332. int ret;
  333. if (!connection)
  334. return 0;
  335. fw_download = kzalloc(sizeof(*fw_download), GFP_KERNEL);
  336. if (!fw_download)
  337. return -ENOMEM;
  338. fw_download->parent = &connection->bundle->dev;
  339. INIT_LIST_HEAD(&fw_download->fw_requests);
  340. ida_init(&fw_download->id_map);
  341. gb_connection_set_data(connection, fw_download);
  342. fw_download->connection = connection;
  343. mutex_init(&fw_download->mutex);
  344. ret = gb_connection_enable(connection);
  345. if (ret)
  346. goto err_destroy_id_map;
  347. return 0;
  348. err_destroy_id_map:
  349. ida_destroy(&fw_download->id_map);
  350. kfree(fw_download);
  351. return ret;
  352. }
  353. void gb_fw_download_connection_exit(struct gb_connection *connection)
  354. {
  355. struct fw_download *fw_download;
  356. struct fw_request *fw_req, *tmp;
  357. if (!connection)
  358. return;
  359. fw_download = gb_connection_get_data(connection);
  360. gb_connection_disable(fw_download->connection);
  361. /*
  362. * Make sure we have a reference to the pending requests, before they
  363. * are freed from the timeout handler.
  364. */
  365. mutex_lock(&fw_download->mutex);
  366. list_for_each_entry(fw_req, &fw_download->fw_requests, node)
  367. kref_get(&fw_req->kref);
  368. mutex_unlock(&fw_download->mutex);
  369. /* Release pending firmware packages */
  370. list_for_each_entry_safe(fw_req, tmp, &fw_download->fw_requests, node) {
  371. cancel_delayed_work_sync(&fw_req->dwork);
  372. free_firmware(fw_download, fw_req);
  373. put_fw_req(fw_req);
  374. }
  375. ida_destroy(&fw_download->id_map);
  376. kfree(fw_download);
  377. }