efi_uclass.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Uclass for EFI drivers
  4. *
  5. * Copyright (c) 2017 Heinrich Schuchardt
  6. *
  7. * For each EFI driver the uclass
  8. * - creates a handle
  9. * - installs the driver binding protocol
  10. *
  11. * The uclass provides the bind, start, and stop entry points for the driver
  12. * binding protocol.
  13. *
  14. * In supported() and bind() it checks if the controller implements the protocol
  15. * supported by the EFI driver. In the start() function it calls the bind()
  16. * function of the EFI driver. In the stop() function it destroys the child
  17. * controllers.
  18. */
  19. #include <common.h>
  20. #include <dm.h>
  21. #include <efi_driver.h>
  22. #include <log.h>
  23. #include <malloc.h>
  24. /**
  25. * check_node_type() - check node type
  26. *
  27. * We do not support partitions as controller handles.
  28. *
  29. * @handle: handle to be checked
  30. * Return: status code
  31. */
  32. static efi_status_t check_node_type(efi_handle_t handle)
  33. {
  34. efi_status_t r, ret = EFI_SUCCESS;
  35. const struct efi_device_path *dp;
  36. /* Open the device path protocol */
  37. r = EFI_CALL(systab.boottime->open_protocol(
  38. handle, &efi_guid_device_path, (void **)&dp,
  39. NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL));
  40. if (r == EFI_SUCCESS && dp) {
  41. /* Get the last node */
  42. const struct efi_device_path *node = efi_dp_last_node(dp);
  43. /* We do not support partitions as controller */
  44. if (!node || node->type == DEVICE_PATH_TYPE_MEDIA_DEVICE)
  45. ret = EFI_UNSUPPORTED;
  46. }
  47. return ret;
  48. }
  49. /**
  50. * efi_uc_supported() - check if the driver supports the controller
  51. *
  52. * @this: driver binding protocol
  53. * @controller_handle: handle of the controller
  54. * @remaining_device_path: path specifying the child controller
  55. * Return: status code
  56. */
  57. static efi_status_t EFIAPI efi_uc_supported(
  58. struct efi_driver_binding_protocol *this,
  59. efi_handle_t controller_handle,
  60. struct efi_device_path *remaining_device_path)
  61. {
  62. efi_status_t r, ret;
  63. void *interface;
  64. struct efi_driver_binding_extended_protocol *bp =
  65. (struct efi_driver_binding_extended_protocol *)this;
  66. EFI_ENTRY("%p, %p, %ls", this, controller_handle,
  67. efi_dp_str(remaining_device_path));
  68. /*
  69. * U-Boot internal devices install protocols interfaces without calling
  70. * ConnectController(). Hence we should not bind an extra driver.
  71. */
  72. if (controller_handle->dev) {
  73. ret = EFI_UNSUPPORTED;
  74. goto out;
  75. }
  76. ret = EFI_CALL(systab.boottime->open_protocol(
  77. controller_handle, bp->ops->protocol,
  78. &interface, this->driver_binding_handle,
  79. controller_handle, EFI_OPEN_PROTOCOL_BY_DRIVER));
  80. switch (ret) {
  81. case EFI_ACCESS_DENIED:
  82. case EFI_ALREADY_STARTED:
  83. goto out;
  84. case EFI_SUCCESS:
  85. break;
  86. default:
  87. ret = EFI_UNSUPPORTED;
  88. goto out;
  89. }
  90. ret = check_node_type(controller_handle);
  91. r = efi_close_protocol(controller_handle, bp->ops->protocol,
  92. this->driver_binding_handle,
  93. controller_handle);
  94. if (r != EFI_SUCCESS)
  95. ret = EFI_UNSUPPORTED;
  96. out:
  97. return EFI_EXIT(ret);
  98. }
  99. /**
  100. * efi_uc_start() - create child controllers and attach driver
  101. *
  102. * @this: driver binding protocol
  103. * @controller_handle: handle of the controller
  104. * @remaining_device_path: path specifying the child controller
  105. * Return: status code
  106. */
  107. static efi_status_t EFIAPI efi_uc_start(
  108. struct efi_driver_binding_protocol *this,
  109. efi_handle_t controller_handle,
  110. struct efi_device_path *remaining_device_path)
  111. {
  112. efi_status_t r, ret;
  113. void *interface = NULL;
  114. struct efi_driver_binding_extended_protocol *bp =
  115. (struct efi_driver_binding_extended_protocol *)this;
  116. EFI_ENTRY("%p, %p, %ls", this, controller_handle,
  117. efi_dp_str(remaining_device_path));
  118. /* Attach driver to controller */
  119. ret = EFI_CALL(systab.boottime->open_protocol(
  120. controller_handle, bp->ops->protocol,
  121. &interface, this->driver_binding_handle,
  122. controller_handle, EFI_OPEN_PROTOCOL_BY_DRIVER));
  123. switch (ret) {
  124. case EFI_ACCESS_DENIED:
  125. case EFI_ALREADY_STARTED:
  126. goto out;
  127. case EFI_SUCCESS:
  128. break;
  129. default:
  130. ret = EFI_UNSUPPORTED;
  131. goto out;
  132. }
  133. ret = check_node_type(controller_handle);
  134. if (ret != EFI_SUCCESS)
  135. goto err;
  136. ret = bp->ops->bind(bp, controller_handle, interface);
  137. if (ret == EFI_SUCCESS)
  138. goto out;
  139. err:
  140. r = efi_close_protocol(controller_handle, bp->ops->protocol,
  141. this->driver_binding_handle,
  142. controller_handle);
  143. if (r != EFI_SUCCESS)
  144. EFI_PRINT("Failure to close handle\n");
  145. out:
  146. return EFI_EXIT(ret);
  147. }
  148. /**
  149. * disconnect_child() - remove a single child controller from the parent
  150. * controller
  151. *
  152. * @controller_handle: parent controller
  153. * @child_handle: child controller
  154. * Return: status code
  155. */
  156. static efi_status_t disconnect_child(efi_handle_t controller_handle,
  157. efi_handle_t child_handle)
  158. {
  159. efi_status_t ret;
  160. efi_guid_t *guid_controller = NULL;
  161. efi_guid_t *guid_child_controller = NULL;
  162. ret = efi_close_protocol(controller_handle, guid_controller,
  163. child_handle, child_handle);
  164. if (ret != EFI_SUCCESS) {
  165. EFI_PRINT("Cannot close protocol\n");
  166. return ret;
  167. }
  168. ret = EFI_CALL(systab.boottime->uninstall_protocol_interface(
  169. child_handle, guid_child_controller, NULL));
  170. if (ret != EFI_SUCCESS) {
  171. EFI_PRINT("Cannot uninstall protocol interface\n");
  172. return ret;
  173. }
  174. return ret;
  175. }
  176. /**
  177. * efi_uc_stop() - Remove child controllers and disconnect the controller
  178. *
  179. * @this: driver binding protocol
  180. * @controller_handle: handle of the controller
  181. * @number_of_children: number of child controllers to remove
  182. * @child_handle_buffer: handles of the child controllers to remove
  183. * Return: status code
  184. */
  185. static efi_status_t EFIAPI efi_uc_stop(
  186. struct efi_driver_binding_protocol *this,
  187. efi_handle_t controller_handle,
  188. size_t number_of_children,
  189. efi_handle_t *child_handle_buffer)
  190. {
  191. efi_status_t ret;
  192. efi_uintn_t count;
  193. struct efi_open_protocol_info_entry *entry_buffer;
  194. struct efi_driver_binding_extended_protocol *bp =
  195. (struct efi_driver_binding_extended_protocol *)this;
  196. EFI_ENTRY("%p, %p, %zu, %p", this, controller_handle,
  197. number_of_children, child_handle_buffer);
  198. /* Destroy provided child controllers */
  199. if (number_of_children) {
  200. efi_uintn_t i;
  201. for (i = 0; i < number_of_children; ++i) {
  202. ret = disconnect_child(controller_handle,
  203. child_handle_buffer[i]);
  204. if (ret != EFI_SUCCESS)
  205. goto out;
  206. }
  207. ret = EFI_SUCCESS;
  208. goto out;
  209. }
  210. /* Destroy all children */
  211. ret = EFI_CALL(systab.boottime->open_protocol_information(
  212. controller_handle, bp->ops->protocol,
  213. &entry_buffer, &count));
  214. if (ret != EFI_SUCCESS)
  215. goto out;
  216. while (count) {
  217. if (entry_buffer[--count].attributes &
  218. EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
  219. ret = disconnect_child(
  220. controller_handle,
  221. entry_buffer[count].agent_handle);
  222. if (ret != EFI_SUCCESS)
  223. goto out;
  224. }
  225. }
  226. ret = efi_free_pool(entry_buffer);
  227. if (ret != EFI_SUCCESS)
  228. log_err("Cannot free EFI memory pool\n");
  229. /* Detach driver from controller */
  230. ret = efi_close_protocol(controller_handle, bp->ops->protocol,
  231. this->driver_binding_handle,
  232. controller_handle);
  233. out:
  234. return EFI_EXIT(ret);
  235. }
  236. /**
  237. * efi_add_driver() - add driver
  238. *
  239. * @drv: driver to add
  240. * Return: status code
  241. */
  242. static efi_status_t efi_add_driver(struct driver *drv)
  243. {
  244. efi_status_t ret;
  245. const struct efi_driver_ops *ops = drv->ops;
  246. struct efi_driver_binding_extended_protocol *bp;
  247. log_debug("Adding EFI driver '%s'\n", drv->name);
  248. if (!ops->protocol) {
  249. log_err("EFI protocol GUID missing for driver '%s'\n",
  250. drv->name);
  251. return EFI_INVALID_PARAMETER;
  252. }
  253. bp = calloc(1, sizeof(struct efi_driver_binding_extended_protocol));
  254. if (!bp)
  255. return EFI_OUT_OF_RESOURCES;
  256. bp->bp.supported = efi_uc_supported;
  257. bp->bp.start = efi_uc_start;
  258. bp->bp.stop = efi_uc_stop;
  259. bp->bp.version = 0xffffffff;
  260. bp->ops = ops;
  261. ret = efi_create_handle(&bp->bp.driver_binding_handle);
  262. if (ret != EFI_SUCCESS)
  263. goto err;
  264. bp->bp.image_handle = bp->bp.driver_binding_handle;
  265. ret = efi_add_protocol(bp->bp.driver_binding_handle,
  266. &efi_guid_driver_binding_protocol, bp);
  267. if (ret != EFI_SUCCESS)
  268. goto err;
  269. if (ops->init) {
  270. ret = ops->init(bp);
  271. if (ret != EFI_SUCCESS)
  272. goto err;
  273. }
  274. return ret;
  275. err:
  276. if (bp->bp.driver_binding_handle)
  277. efi_delete_handle(bp->bp.driver_binding_handle);
  278. free(bp);
  279. return ret;
  280. }
  281. /**
  282. * efi_driver_init() - initialize the EFI drivers
  283. *
  284. * Called by efi_init_obj_list().
  285. *
  286. * Return: 0 = success, any other value will stop further execution
  287. */
  288. efi_status_t efi_driver_init(void)
  289. {
  290. struct driver *drv;
  291. efi_status_t ret = EFI_SUCCESS;
  292. log_debug("Initializing EFI driver framework\n");
  293. for (drv = ll_entry_start(struct driver, driver);
  294. drv < ll_entry_end(struct driver, driver); ++drv) {
  295. if (drv->id == UCLASS_EFI_LOADER) {
  296. ret = efi_add_driver(drv);
  297. if (ret != EFI_SUCCESS) {
  298. log_err("Failed to add EFI driver %s\n",
  299. drv->name);
  300. break;
  301. }
  302. }
  303. }
  304. return ret;
  305. }
  306. /**
  307. * efi_uc_init() - initialize the EFI uclass
  308. *
  309. * @class: the EFI uclass
  310. * Return: 0 = success
  311. */
  312. static int efi_uc_init(struct uclass *class)
  313. {
  314. log_debug("Initializing UCLASS_EFI_LOADER\n");
  315. return 0;
  316. }
  317. /**
  318. * efi_uc_destroy() - destroy the EFI uclass
  319. *
  320. * @class: the EFI uclass
  321. * Return: 0 = success
  322. */
  323. static int efi_uc_destroy(struct uclass *class)
  324. {
  325. log_debug("Destroying UCLASS_EFI_LOADER\n");
  326. return 0;
  327. }
  328. UCLASS_DRIVER(efi) = {
  329. .name = "efi",
  330. .id = UCLASS_EFI_LOADER,
  331. .init = efi_uc_init,
  332. .destroy = efi_uc_destroy,
  333. };