UDM-block.txt 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. The U-Boot Driver Model Project
  2. ===============================
  3. Block device subsystem analysis
  4. ===============================
  5. Pavel Herrmann <morpheus.ibis@gmail.com>
  6. 2012-03-08
  7. I) Overview
  8. -----------
  9. U-Boot currently implements several distinct APIs for block devices - some
  10. drivers use the SATA API, some drivers use the IDE API, sym53c8xx and
  11. AHCI use the SCSI API, mg_disk has a separate API, and systemace also has a
  12. separate API. There are also MMC and USB APIs used outside of drivers/block,
  13. those will be detailed in their specific documents.
  14. Block devices are described by block_dev_desc structure, that holds, among
  15. other things, the read/write/erase callbacks. Block device structures are
  16. stored in any way depending on the API, but can be accessed by
  17. block_dev_desc_t * $api_get_dev(int dev)
  18. function, as seen in disk/part.c.
  19. 1) SATA interface
  20. -----------------
  21. The SATA interface drivers implement the following functions:
  22. int init_sata(int dev)
  23. int scan_sata(int dev)
  24. ulong sata_read(int dev, ulong blknr, ulong blkcnt, void *buffer)
  25. ulong sata_write(int dev, ulong blknr, ulong blkcnt, const void *buffer)
  26. Block devices are kept in sata_dev_desc[], which is prefilled with values
  27. common to all SATA devices in cmd_sata.c, and then modified in init_sata
  28. function in the drivers. Callbacks of the block device use SATA API
  29. directly. The sata_get_dev function is defined in cmd_sata.c.
  30. 2) SCSI interface
  31. -----------------
  32. The SCSI interface drivers implement the following functions:
  33. void scsi_print_error(ccb *pccb)
  34. int scsi_exec(ccb *pccb)
  35. void scsi_bus_reset(void)
  36. void scsi_low_level_init(int busdevfunc)
  37. The SCSI API works through the scsi_exec function, the actual operation
  38. requested is found in the ccb structure.
  39. Block devices are kept in scsi_dev_desc[], which lives only in cmd_scsi.c.
  40. Callbacks of the block device use functions from cmd_scsi.c, which in turn
  41. call scsi_exec of the controller. The scsi_get_dev function is also defined
  42. in cmd_scsi.c.
  43. 3) mg_disk interface
  44. --------------------
  45. The mg_disk interface drivers implement the following functions:
  46. struct mg_drv_data* mg_get_drv_data (void)
  47. uint mg_disk_init (void)
  48. uint mg_disk_read (u32 addr, u8 *buff, u32 len)
  49. uint mg_disk_write(u32 addr, u8 *buff, u32 len)
  50. uint mg_disk_write_sects(void *buff, u32 sect_num, u32 sect_cnt)
  51. uint mg_disk_read_sects(void *buff, u32 sect_num, u32 sect_cnt)
  52. The mg_get_drv_data function is to be overridden per-board, but there are no
  53. board in-tree that do this.
  54. Only one driver for this API exists, and it only supports one block device.
  55. Callbacks for this device are implemented in mg_disk.c and call the mg_disk
  56. API. The mg_disk_get_dev function is defined in mg_disk.c and ignores the
  57. device number, always returning the same device.
  58. 4) systemace interface
  59. ----------------------
  60. The systemace interface does not define any driver API, and has no command
  61. itself. The single defined function is systemace_get_devs() from
  62. systemace.c, which returns a single static structure for the only supported
  63. block device. Callbacks for this device are also implemented in systemace.c.
  64. 5) IDE interface
  65. ----------------
  66. The IDE interface drivers implement the following functions, but only if
  67. CONFIG_IDE_AHB is set:
  68. uchar ide_read_register(int dev, unsigned int port);
  69. void ide_write_register(int dev, unsigned int port, unsigned char val);
  70. void ide_read_data(int dev, ulong *sect_buf, int words);
  71. void ide_write_data(int dev, ulong *sect_buf, int words);
  72. The first two functions are called from ide_inb()/ide_outb(), and will
  73. default to direct memory access if CONFIG_IDE_AHB is not set, or
  74. ide_inb()/ide_outb() functions will get overridden by the board altogether.
  75. The second two functions are called from input_data()/output_data()
  76. functions, and also default to direct memory access, but cannot be
  77. overridden by the board.
  78. One function shared by IDE drivers (but not defined in ide.h) is
  79. int ide_preinit(void)
  80. This function gets called from ide_init in cmd_ide.c if CONFIG_IDE_PREINIT
  81. is defined, and will do the driver-specific initialization of the device.
  82. Block devices are kept in ide_dev_desc[], which is filled in cmd_ide.c.
  83. Callbacks of the block device are defined in cmd_ide.c, and use the
  84. ide_inb()/ide_outb()/input_data()/output_data() functions mentioned above.
  85. The ide_get_dev function is defined in cmd_ide.c.
  86. II) Approach
  87. ------------
  88. A new block controller core and an associated API will be created to mimic the
  89. current SATA API, its drivers will have the following ops:
  90. struct block_ctrl_ops {
  91. int scan(instance *i);
  92. int reset(instance *i, int port);
  93. lbaint_t read(instance *i, int port, lbaint_t start, lbatin_t length,
  94. void *buffer);
  95. lbaint_t write(instance *i, int port, lbaint_t start, lbatin_t length,
  96. void*buffer);
  97. }
  98. The current sata_init() function will be changed into the driver probe()
  99. function. The read() and write() functions should never be called directly,
  100. instead they should be called by block device driver for disks.
  101. Other block APIs would either be transformed into this API, or be kept as
  102. legacy for old drivers, or be dropped altogether.
  103. Legacy driver APIs will each have its own driver core that will contain the
  104. shared logic, which is currently located mostly in cmd_* files. Callbacks for
  105. block device drivers will then probably be implemented as a part of the core
  106. logic, and will use the driver ops (which will copy current state of
  107. respective APIs) to do the work.
  108. All drivers will be cleaned up, most ifdefs should be converted into
  109. platform_data, to enable support for multiple devices with different settings.
  110. A new block device core will also be created, and will keep track of all
  111. block devices on all interfaces.
  112. Current block_dev_desc structure will be changed to fit the driver model, all
  113. identification and configuration will be placed in private data, and
  114. a single accessor and modifier will be defined, to accommodate the need for
  115. different sets of options for different interfaces, while keeping the
  116. structure small. The new block device drivers will have the following ops
  117. structure (lbaint_t is either 32bit or 64bit unsigned, depending on
  118. CONFIG_LBA48):
  119. struct blockdev_ops {
  120. lbaint_t (*block_read)(struct instance *i, lbaint_t start, lbaint_t blkcnt,
  121. void *buffer);
  122. lbaint_t (*block_write)(struct instance *i, lbaint_t start, lbaint_t blkcnt,
  123. void *buffer);
  124. lbaint_t (*block_erase)(struct instance *i, lbaint_t start, lbaint_t blkcnt
  125. );
  126. int (*get_option)(struct instance *i, enum blockdev_option_code op,
  127. struct option *res);
  128. int (*set_option)(struct instance *i, enum blockdev_option_code op,
  129. struct option *val);
  130. }
  131. struct option {
  132. uint32_t flags
  133. union data {
  134. uint64_t data_u;
  135. char* data_s;
  136. void* data_p;
  137. }
  138. }
  139. enum blockdev_option_code {
  140. BLKD_OPT_IFTYPE=0,
  141. BLKD_OPT_TYPE,
  142. BLKD_OPT_BLOCKSIZE,
  143. BLKD_OPT_BLOCKCOUNT,
  144. BLKD_OPT_REMOVABLE,
  145. BLKD_OPT_LBA48,
  146. BLKD_OPT_VENDOR,
  147. BLKD_OPT_PRODICT,
  148. BLKD_OPT_REVISION,
  149. BLKD_OPT_SCSILUN,
  150. BLKD_OPT_SCSITARGET,
  151. BLKD_OPT_OFFSET
  152. }
  153. Flags in option above will contain the type of returned data (which should be
  154. checked against what is expected, even though the option requested should
  155. specify it), and a flag to indicate whether the returned pointer needs to be
  156. free()'d.
  157. The block device core will contain the logic now located in disk/part.c and
  158. related files, and will be used to forward requests to block devices. The API
  159. for the block device core will copy the ops of a block device (with a string
  160. identifier instead of instance pointer). This means that partitions will also
  161. be handled by the block device core, and exported as block devices, making
  162. them transparent to the rest of the code.
  163. Sadly, this will change how file systems can access the devices, and thus will
  164. affect a lot of places. However, these changes should be localized and easy to
  165. implement.
  166. AHCI driver will be rewritten to fit the new unified block controller API,
  167. making SCSI API easy to merge with sym53c8xx, or remove it once the device
  168. driver has died.
  169. Optionally, IDE core may be changed into one driver with unified block
  170. controller API, as most of it is already in one place and device drivers are
  171. just sets of hooks. Additionally, mg_disk driver is unused and may be removed
  172. in near future.
  173. III) Analysis of in-tree drivers
  174. --------------------------------
  175. 1) ahci.c
  176. ---------
  177. SCSI API, will be rewritten for a different API.
  178. 2) ata_piix.c
  179. -------------
  180. SATA API, easy to port.
  181. 3) fsl_sata.c
  182. -------------
  183. SATA API, few CONFIG macros, easy to port.
  184. 4) ftide020.c
  185. -------------
  186. IDE API, defines CONFIG_IDE_AHB and ide_preinit hook functions.
  187. 5) mg_disk.c
  188. ------------
  189. Single driver with mg_disk API, not much to change, easy to port.
  190. 6) mvsata_ide.c
  191. ---------------
  192. IDE API, only defines ide_preinit hook function.
  193. 7) mxc_ata.c
  194. ------------
  195. IDE API, only defines ide_preinit hook function.
  196. 8) pata_bfin.c
  197. --------------
  198. SATA API, easy to port.
  199. 9) sata_dwc.c
  200. -------------
  201. SATA API, easy to port.
  202. 10) sata_sil3114.c
  203. ------------------
  204. SATA API, easy to port.
  205. 11) sata_sil.c
  206. --------------
  207. SATA API, easy to port.
  208. 12) sil680.c
  209. ------------
  210. IDE API, only defines ide_preinit hook function.
  211. 13) sym53c8xx.c
  212. ---------------
  213. SCSI API, may be merged with code from cmd_scsi.
  214. 14) systemace.c
  215. ---------------
  216. Single driver with systemace API, not much to change, easy to port.