efi_uclass.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  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 bind() and stop() 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. ret = EFI_CALL(systab.boottime->open_protocol(
  69. controller_handle, bp->ops->protocol,
  70. &interface, this->driver_binding_handle,
  71. controller_handle, EFI_OPEN_PROTOCOL_BY_DRIVER));
  72. switch (ret) {
  73. case EFI_ACCESS_DENIED:
  74. case EFI_ALREADY_STARTED:
  75. goto out;
  76. case EFI_SUCCESS:
  77. break;
  78. default:
  79. ret = EFI_UNSUPPORTED;
  80. goto out;
  81. }
  82. ret = check_node_type(controller_handle);
  83. r = EFI_CALL(systab.boottime->close_protocol(
  84. controller_handle, bp->ops->protocol,
  85. this->driver_binding_handle,
  86. controller_handle));
  87. if (r != EFI_SUCCESS)
  88. ret = EFI_UNSUPPORTED;
  89. out:
  90. return EFI_EXIT(ret);
  91. }
  92. /**
  93. * efi_uc_start() - create child controllers and attach driver
  94. *
  95. * @this: driver binding protocol
  96. * @controller_handle: handle of the controller
  97. * @remaining_device_path: path specifying the child controller
  98. * Return: status code
  99. */
  100. static efi_status_t EFIAPI efi_uc_start(
  101. struct efi_driver_binding_protocol *this,
  102. efi_handle_t controller_handle,
  103. struct efi_device_path *remaining_device_path)
  104. {
  105. efi_status_t r, ret;
  106. void *interface = NULL;
  107. struct efi_driver_binding_extended_protocol *bp =
  108. (struct efi_driver_binding_extended_protocol *)this;
  109. EFI_ENTRY("%p, %p, %ls", this, controller_handle,
  110. efi_dp_str(remaining_device_path));
  111. /* Attach driver to controller */
  112. ret = EFI_CALL(systab.boottime->open_protocol(
  113. controller_handle, bp->ops->protocol,
  114. &interface, this->driver_binding_handle,
  115. controller_handle, EFI_OPEN_PROTOCOL_BY_DRIVER));
  116. switch (ret) {
  117. case EFI_ACCESS_DENIED:
  118. case EFI_ALREADY_STARTED:
  119. goto out;
  120. case EFI_SUCCESS:
  121. break;
  122. default:
  123. ret = EFI_UNSUPPORTED;
  124. goto out;
  125. }
  126. ret = check_node_type(controller_handle);
  127. if (ret != EFI_SUCCESS) {
  128. r = EFI_CALL(systab.boottime->close_protocol(
  129. controller_handle, bp->ops->protocol,
  130. this->driver_binding_handle,
  131. controller_handle));
  132. if (r != EFI_SUCCESS)
  133. EFI_PRINT("Failure to close handle\n");
  134. goto out;
  135. }
  136. /* TODO: driver specific stuff */
  137. bp->ops->bind(controller_handle, interface);
  138. out:
  139. return EFI_EXIT(ret);
  140. }
  141. /**
  142. * disconnect_child() - remove a single child controller from the parent
  143. * controller
  144. *
  145. * @controller_handle: parent controller
  146. * @child_handle: child controller
  147. * Return: status code
  148. */
  149. static efi_status_t disconnect_child(efi_handle_t controller_handle,
  150. efi_handle_t child_handle)
  151. {
  152. efi_status_t ret;
  153. efi_guid_t *guid_controller = NULL;
  154. efi_guid_t *guid_child_controller = NULL;
  155. ret = EFI_CALL(systab.boottime->close_protocol(
  156. controller_handle, guid_controller,
  157. child_handle, child_handle));
  158. if (ret != EFI_SUCCESS) {
  159. EFI_PRINT("Cannot close protocol\n");
  160. return ret;
  161. }
  162. ret = EFI_CALL(systab.boottime->uninstall_protocol_interface(
  163. child_handle, guid_child_controller, NULL));
  164. if (ret != EFI_SUCCESS) {
  165. EFI_PRINT("Cannot uninstall protocol interface\n");
  166. return ret;
  167. }
  168. return ret;
  169. }
  170. /**
  171. * efi_uc_stop() - Remove child controllers and disconnect the controller
  172. *
  173. * @this: driver binding protocol
  174. * @controller_handle: handle of the controller
  175. * @number_of_children: number of child controllers to remove
  176. * @child_handle_buffer: handles of the child controllers to remove
  177. * Return: status code
  178. */
  179. static efi_status_t EFIAPI efi_uc_stop(
  180. struct efi_driver_binding_protocol *this,
  181. efi_handle_t controller_handle,
  182. size_t number_of_children,
  183. efi_handle_t *child_handle_buffer)
  184. {
  185. efi_status_t ret;
  186. efi_uintn_t count;
  187. struct efi_open_protocol_info_entry *entry_buffer;
  188. struct efi_driver_binding_extended_protocol *bp =
  189. (struct efi_driver_binding_extended_protocol *)this;
  190. EFI_ENTRY("%p, %p, %zu, %p", this, controller_handle,
  191. number_of_children, child_handle_buffer);
  192. /* Destroy provided child controllers */
  193. if (number_of_children) {
  194. efi_uintn_t i;
  195. for (i = 0; i < number_of_children; ++i) {
  196. ret = disconnect_child(controller_handle,
  197. child_handle_buffer[i]);
  198. if (ret != EFI_SUCCESS)
  199. return ret;
  200. }
  201. return EFI_SUCCESS;
  202. }
  203. /* Destroy all children */
  204. ret = EFI_CALL(systab.boottime->open_protocol_information(
  205. controller_handle, bp->ops->protocol,
  206. &entry_buffer, &count));
  207. if (ret != EFI_SUCCESS)
  208. goto out;
  209. while (count) {
  210. if (entry_buffer[--count].attributes &
  211. EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
  212. ret = disconnect_child(
  213. controller_handle,
  214. entry_buffer[count].agent_handle);
  215. if (ret != EFI_SUCCESS)
  216. goto out;
  217. }
  218. }
  219. ret = EFI_CALL(systab.boottime->free_pool(entry_buffer));
  220. if (ret != EFI_SUCCESS)
  221. log_err("Cannot free EFI memory pool\n");
  222. /* Detach driver from controller */
  223. ret = EFI_CALL(systab.boottime->close_protocol(
  224. controller_handle, bp->ops->protocol,
  225. this->driver_binding_handle, controller_handle));
  226. out:
  227. return EFI_EXIT(ret);
  228. }
  229. /**
  230. * efi_add_driver() - add driver
  231. *
  232. * @drv: driver to add
  233. * Return: status code
  234. */
  235. static efi_status_t efi_add_driver(struct driver *drv)
  236. {
  237. efi_status_t ret;
  238. const struct efi_driver_ops *ops = drv->ops;
  239. struct efi_driver_binding_extended_protocol *bp;
  240. log_debug("Adding EFI driver '%s'\n", drv->name);
  241. if (!ops->protocol) {
  242. log_err("EFI protocol GUID missing for driver '%s'\n",
  243. drv->name);
  244. return EFI_INVALID_PARAMETER;
  245. }
  246. bp = calloc(1, sizeof(struct efi_driver_binding_extended_protocol));
  247. if (!bp)
  248. return EFI_OUT_OF_RESOURCES;
  249. bp->bp.supported = efi_uc_supported;
  250. bp->bp.start = efi_uc_start;
  251. bp->bp.stop = efi_uc_stop;
  252. bp->bp.version = 0xffffffff;
  253. bp->ops = drv->ops;
  254. ret = efi_create_handle(&bp->bp.driver_binding_handle);
  255. if (ret != EFI_SUCCESS) {
  256. free(bp);
  257. goto out;
  258. }
  259. bp->bp.image_handle = bp->bp.driver_binding_handle;
  260. ret = efi_add_protocol(bp->bp.driver_binding_handle,
  261. &efi_guid_driver_binding_protocol, bp);
  262. if (ret != EFI_SUCCESS) {
  263. efi_delete_handle(bp->bp.driver_binding_handle);
  264. free(bp);
  265. goto out;
  266. }
  267. out:
  268. return ret;
  269. }
  270. /**
  271. * efi_driver_init() - initialize the EFI drivers
  272. *
  273. * Called by efi_init_obj_list().
  274. *
  275. * Return: 0 = success, any other value will stop further execution
  276. */
  277. efi_status_t efi_driver_init(void)
  278. {
  279. struct driver *drv;
  280. efi_status_t ret = EFI_SUCCESS;
  281. log_debug("Initializing EFI driver framework\n");
  282. for (drv = ll_entry_start(struct driver, driver);
  283. drv < ll_entry_end(struct driver, driver); ++drv) {
  284. if (drv->id == UCLASS_EFI) {
  285. ret = efi_add_driver(drv);
  286. if (ret != EFI_SUCCESS) {
  287. log_err("Failed to add EFI driver %s\n",
  288. drv->name);
  289. break;
  290. }
  291. }
  292. }
  293. return ret;
  294. }
  295. /**
  296. * efi_uc_init() - initialize the EFI uclass
  297. *
  298. * @class: the EFI uclass
  299. * Return: 0 = success
  300. */
  301. static int efi_uc_init(struct uclass *class)
  302. {
  303. log_debug("Initializing UCLASS_EFI\n");
  304. return 0;
  305. }
  306. /**
  307. * efi_uc_destroy() - destroy the EFI uclass
  308. *
  309. * @class: the EFI uclass
  310. * Return: 0 = success
  311. */
  312. static int efi_uc_destroy(struct uclass *class)
  313. {
  314. log_debug("Destroying UCLASS_EFI\n");
  315. return 0;
  316. }
  317. UCLASS_DRIVER(efi) = {
  318. .name = "efi",
  319. .id = UCLASS_EFI,
  320. .init = efi_uc_init,
  321. .destroy = efi_uc_destroy,
  322. };