efi_block_device.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * EFI block driver
  4. *
  5. * Copyright (c) 2017 Heinrich Schuchardt
  6. *
  7. * The EFI uclass creates a handle for this driver and installs the
  8. * driver binding protocol on it.
  9. *
  10. * The EFI block driver binds to controllers implementing the block io
  11. * protocol.
  12. *
  13. * When the bind function of the EFI block driver is called it creates a
  14. * new U-Boot block device. It installs child handles for all partitions and
  15. * installs the simple file protocol on these.
  16. *
  17. * The read and write functions of the EFI block driver delegate calls to the
  18. * controller that it is bound to.
  19. *
  20. * A usage example is as following:
  21. *
  22. * U-Boot loads the iPXE snp.efi executable. iPXE connects an iSCSI drive and
  23. * exposes a handle with the block IO protocol. It calls ConnectController.
  24. *
  25. * Now the EFI block driver installs the partitions with the simple file
  26. * protocol.
  27. *
  28. * iPXE uses the simple file protocol to load Grub or the Linux Kernel.
  29. */
  30. #include <common.h>
  31. #include <blk.h>
  32. #include <dm.h>
  33. #include <efi_driver.h>
  34. #include <malloc.h>
  35. #include <dm/device-internal.h>
  36. #include <dm/root.h>
  37. #include <dm/tag.h>
  38. /**
  39. * struct efi_blk_plat - attributes of a block device
  40. *
  41. * @handle: handle of the controller on which this driver is installed
  42. * @io: block io protocol proxied by this driver
  43. */
  44. struct efi_blk_plat {
  45. efi_handle_t handle;
  46. struct efi_block_io *io;
  47. };
  48. /**
  49. * efi_bl_read() - read from block device
  50. *
  51. * @dev: device
  52. * @blknr: first block to be read
  53. * @blkcnt: number of blocks to read
  54. * @buffer: output buffer
  55. * Return: number of blocks transferred
  56. */
  57. static ulong efi_bl_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
  58. void *buffer)
  59. {
  60. struct efi_blk_plat *plat = dev_get_plat(dev);
  61. struct efi_block_io *io = plat->io;
  62. efi_status_t ret;
  63. EFI_PRINT("%s: read '%s', from block " LBAFU ", " LBAFU " blocks\n",
  64. __func__, dev->name, blknr, blkcnt);
  65. ret = EFI_CALL(io->read_blocks(
  66. io, io->media->media_id, (u64)blknr,
  67. (efi_uintn_t)blkcnt *
  68. (efi_uintn_t)io->media->block_size, buffer));
  69. EFI_PRINT("%s: r = %u\n", __func__,
  70. (unsigned int)(ret & ~EFI_ERROR_MASK));
  71. if (ret != EFI_SUCCESS)
  72. return 0;
  73. return blkcnt;
  74. }
  75. /**
  76. * efi_bl_write() - write to block device
  77. *
  78. * @dev: device
  79. * @blknr: first block to be write
  80. * @blkcnt: number of blocks to write
  81. * @buffer: input buffer
  82. * Return: number of blocks transferred
  83. */
  84. static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
  85. const void *buffer)
  86. {
  87. struct efi_blk_plat *plat = dev_get_plat(dev);
  88. struct efi_block_io *io = plat->io;
  89. efi_status_t ret;
  90. EFI_PRINT("%s: write '%s', from block " LBAFU ", " LBAFU " blocks\n",
  91. __func__, dev->name, blknr, blkcnt);
  92. ret = EFI_CALL(io->write_blocks(
  93. io, io->media->media_id, (u64)blknr,
  94. (efi_uintn_t)blkcnt *
  95. (efi_uintn_t)io->media->block_size,
  96. (void *)buffer));
  97. EFI_PRINT("%s: r = %u\n", __func__,
  98. (unsigned int)(ret & ~EFI_ERROR_MASK));
  99. if (ret != EFI_SUCCESS)
  100. return 0;
  101. return blkcnt;
  102. }
  103. /**
  104. * efi_bl_create_block_device() - create a block device for a handle
  105. *
  106. * @handle: handle
  107. * @interface: block io protocol
  108. * Return: status code
  109. */
  110. static efi_status_t
  111. efi_bl_create_block_device(efi_handle_t handle, void *interface)
  112. {
  113. struct udevice *bdev = NULL, *parent = dm_root();
  114. efi_status_t ret;
  115. int devnum;
  116. char *name;
  117. struct efi_block_io *io = interface;
  118. struct efi_blk_plat *plat;
  119. devnum = blk_next_free_devnum(UCLASS_EFI_LOADER);
  120. if (devnum < 0)
  121. return EFI_OUT_OF_RESOURCES;
  122. name = calloc(1, 18); /* strlen("efiblk#2147483648") + 1 */
  123. if (!name)
  124. return EFI_OUT_OF_RESOURCES;
  125. sprintf(name, "efiblk#%d", devnum);
  126. /* Create driver model udevice for the EFI block io device */
  127. if (blk_create_device(parent, "efi_blk", name, UCLASS_EFI_LOADER,
  128. devnum, io->media->block_size,
  129. (lbaint_t)io->media->last_block, &bdev)) {
  130. ret = EFI_OUT_OF_RESOURCES;
  131. free(name);
  132. goto err;
  133. }
  134. /* Set the DM_FLAG_NAME_ALLOCED flag to avoid a memory leak */
  135. device_set_name_alloced(bdev);
  136. plat = dev_get_plat(bdev);
  137. plat->handle = handle;
  138. plat->io = interface;
  139. if (efi_link_dev(handle, bdev)) {
  140. ret = EFI_OUT_OF_RESOURCES;
  141. goto err;
  142. }
  143. if (device_probe(bdev)) {
  144. ret = EFI_DEVICE_ERROR;
  145. goto err;
  146. }
  147. EFI_PRINT("%s: block device '%s' created\n", __func__, bdev->name);
  148. return EFI_SUCCESS;
  149. err:
  150. efi_unlink_dev(handle);
  151. if (bdev)
  152. device_unbind(bdev);
  153. return ret;
  154. }
  155. /**
  156. * efi_bl_bind() - bind to a block io protocol
  157. *
  158. * @this: driver binding protocol
  159. * @handle: handle
  160. * @interface: block io protocol
  161. * Return: status code
  162. */
  163. static efi_status_t efi_bl_bind(
  164. struct efi_driver_binding_extended_protocol *this,
  165. efi_handle_t handle, void *interface)
  166. {
  167. efi_status_t ret = EFI_SUCCESS;
  168. struct efi_object *obj = efi_search_obj(handle);
  169. EFI_PRINT("%s: handle %p, interface %p\n", __func__, handle, interface);
  170. if (!obj || !interface)
  171. return EFI_INVALID_PARAMETER;
  172. if (!handle->dev)
  173. ret = efi_bl_create_block_device(handle, interface);
  174. return ret;
  175. }
  176. /**
  177. * efi_bl_init() - initialize block device driver
  178. *
  179. * @this: extended driver binding protocol
  180. */
  181. static efi_status_t
  182. efi_bl_init(struct efi_driver_binding_extended_protocol *this)
  183. {
  184. int ret;
  185. ret = event_register("efi_disk add", EVT_DM_POST_PROBE,
  186. efi_disk_probe, this);
  187. if (ret) {
  188. log_err("Event registration for efi_disk add failed\n");
  189. return EFI_OUT_OF_RESOURCES;
  190. }
  191. ret = event_register("efi_disk del", EVT_DM_PRE_REMOVE,
  192. efi_disk_remove, this);
  193. if (ret) {
  194. log_err("Event registration for efi_disk del failed\n");
  195. return EFI_OUT_OF_RESOURCES;
  196. }
  197. return EFI_SUCCESS;
  198. }
  199. /* Block device driver operators */
  200. static const struct blk_ops efi_blk_ops = {
  201. .read = efi_bl_read,
  202. .write = efi_bl_write,
  203. };
  204. /* Identify as block device driver */
  205. U_BOOT_DRIVER(efi_blk) = {
  206. .name = "efi_blk",
  207. .id = UCLASS_BLK,
  208. .ops = &efi_blk_ops,
  209. .plat_auto = sizeof(struct efi_blk_plat),
  210. };
  211. /* EFI driver operators */
  212. static const struct efi_driver_ops driver_ops = {
  213. .protocol = &efi_block_io_guid,
  214. .child_protocol = &efi_block_io_guid,
  215. .init = efi_bl_init,
  216. .bind = efi_bl_bind,
  217. };
  218. /* Identify as EFI driver */
  219. U_BOOT_DRIVER(efi_block) = {
  220. .name = "EFI block driver",
  221. .id = UCLASS_EFI_LOADER,
  222. .ops = &driver_ops,
  223. };