diff options
Diffstat (limited to 'doc/driver-model/UDM-block.txt')
-rw-r--r-- | doc/driver-model/UDM-block.txt | 278 |
1 files changed, 0 insertions, 278 deletions
diff --git a/doc/driver-model/UDM-block.txt b/doc/driver-model/UDM-block.txt deleted file mode 100644 index 0437d9b..0000000 --- a/doc/driver-model/UDM-block.txt +++ /dev/null @@ -1,278 +0,0 @@ -The U-Boot Driver Model Project -=============================== -Block device subsystem analysis -=============================== - -Pavel Herrmann <morpheus.ibis@gmail.com> -2012-03-08 - -I) Overview ------------ - - U-Boot currently implements several distinct APIs for block devices - some - drivers use the SATA API, some drivers use the IDE API, sym53c8xx and - AHCI use the SCSI API, mg_disk has a separate API, and systemace also has a - separate API. There are also MMC and USB APIs used outside of drivers/block, - those will be detailed in their specific documents. - - Block devices are described by block_dev_desc structure, that holds, among - other things, the read/write/erase callbacks. Block device structures are - stored in any way depending on the API, but can be accessed by - - block_dev_desc_t * $api_get_dev(int dev) - - function, as seen in disk/part.c. - - 1) SATA interface - ----------------- - - The SATA interface drivers implement the following functions: - - int init_sata(int dev) - int scan_sata(int dev) - ulong sata_read(int dev, ulong blknr, ulong blkcnt, void *buffer) - ulong sata_write(int dev, ulong blknr, ulong blkcnt, const void *buffer) - - Block devices are kept in sata_dev_desc[], which is prefilled with values - common to all SATA devices in cmd_sata.c, and then modified in init_sata - function in the drivers. Callbacks of the block device use SATA API - directly. The sata_get_dev function is defined in cmd_sata.c. - - 2) SCSI interface - ----------------- - - The SCSI interface drivers implement the following functions: - - void scsi_print_error(ccb *pccb) - int scsi_exec(ccb *pccb) - void scsi_bus_reset(void) - void scsi_low_level_init(int busdevfunc) - - The SCSI API works through the scsi_exec function, the actual operation - requested is found in the ccb structure. - - Block devices are kept in scsi_dev_desc[], which lives only in cmd_scsi.c. - Callbacks of the block device use functions from cmd_scsi.c, which in turn - call scsi_exec of the controller. The scsi_get_dev function is also defined - in cmd_scsi.c. - - 3) mg_disk interface - -------------------- - - The mg_disk interface drivers implement the following functions: - - struct mg_drv_data* mg_get_drv_data (void) - uint mg_disk_init (void) - uint mg_disk_read (u32 addr, u8 *buff, u32 len) - uint mg_disk_write(u32 addr, u8 *buff, u32 len) - uint mg_disk_write_sects(void *buff, u32 sect_num, u32 sect_cnt) - uint mg_disk_read_sects(void *buff, u32 sect_num, u32 sect_cnt) - - The mg_get_drv_data function is to be overridden per-board, but there are no - board in-tree that do this. - - Only one driver for this API exists, and it only supports one block device. - Callbacks for this device are implemented in mg_disk.c and call the mg_disk - API. The mg_disk_get_dev function is defined in mg_disk.c and ignores the - device number, always returning the same device. - - 4) systemace interface - ---------------------- - - The systemace interface does not define any driver API, and has no command - itself. The single defined function is systemace_get_devs() from - systemace.c, which returns a single static structure for the only supported - block device. Callbacks for this device are also implemented in systemace.c. - - 5) IDE interface - ---------------- - - The IDE interface drivers implement the following functions, but only if - CONFIG_IDE_AHB is set: - - uchar ide_read_register(int dev, unsigned int port); - void ide_write_register(int dev, unsigned int port, unsigned char val); - void ide_read_data(int dev, ulong *sect_buf, int words); - void ide_write_data(int dev, const ulong *sect_buf, int words); - - The first two functions are called from ide_inb()/ide_outb(), and will - default to direct memory access if CONFIG_IDE_AHB is not set, or - ide_inb()/ide_outb() functions will get overridden by the board altogether. - - The second two functions are called from input_data()/output_data() - functions, and also default to direct memory access, but cannot be - overridden by the board. - - One function shared by IDE drivers (but not defined in ide.h) is - int ide_preinit(void) - This function gets called from ide_init in cmd_ide.c if CONFIG_IDE_PREINIT - is defined, and will do the driver-specific initialization of the device. - - Block devices are kept in ide_dev_desc[], which is filled in cmd_ide.c. - Callbacks of the block device are defined in cmd_ide.c, and use the - ide_inb()/ide_outb()/input_data()/output_data() functions mentioned above. - The ide_get_dev function is defined in cmd_ide.c. - -II) Approach ------------- - - A new block controller core and an associated API will be created to mimic the - current SATA API, its drivers will have the following ops: - - struct block_ctrl_ops { - int scan(instance *i); - int reset(instance *i, int port); - lbaint_t read(instance *i, int port, lbaint_t start, lbatin_t length, - void *buffer); - lbaint_t write(instance *i, int port, lbaint_t start, lbatin_t length, - void*buffer); - } - - The current sata_init() function will be changed into the driver probe() - function. The read() and write() functions should never be called directly, - instead they should be called by block device driver for disks. - - Other block APIs would either be transformed into this API, or be kept as - legacy for old drivers, or be dropped altogether. - - Legacy driver APIs will each have its own driver core that will contain the - shared logic, which is currently located mostly in cmd_* files. Callbacks for - block device drivers will then probably be implemented as a part of the core - logic, and will use the driver ops (which will copy current state of - respective APIs) to do the work. - - All drivers will be cleaned up, most ifdefs should be converted into - platform_data, to enable support for multiple devices with different settings. - - A new block device core will also be created, and will keep track of all - block devices on all interfaces. - - Current block_dev_desc structure will be changed to fit the driver model, all - identification and configuration will be placed in private data, and - a single accessor and modifier will be defined, to accommodate the need for - different sets of options for different interfaces, while keeping the - structure small. The new block device drivers will have the following ops - structure (lbaint_t is either 32bit or 64bit unsigned, depending on - CONFIG_LBA48): - - struct blockdev_ops { - lbaint_t (*block_read)(struct instance *i, lbaint_t start, lbaint_t blkcnt, - void *buffer); - lbaint_t (*block_write)(struct instance *i, lbaint_t start, lbaint_t blkcnt, - void *buffer); - lbaint_t (*block_erase)(struct instance *i, lbaint_t start, lbaint_t blkcnt - ); - int (*get_option)(struct instance *i, enum blockdev_option_code op, - struct option *res); - int (*set_option)(struct instance *i, enum blockdev_option_code op, - struct option *val); - } - - struct option { - uint32_t flags - union data { - uint64_t data_u; - char* data_s; - void* data_p; - } - } - - enum blockdev_option_code { - BLKD_OPT_IFTYPE=0, - BLKD_OPT_TYPE, - BLKD_OPT_BLOCKSIZE, - BLKD_OPT_BLOCKCOUNT, - BLKD_OPT_REMOVABLE, - BLKD_OPT_LBA48, - BLKD_OPT_VENDOR, - BLKD_OPT_PRODICT, - BLKD_OPT_REVISION, - BLKD_OPT_SCSILUN, - BLKD_OPT_SCSITARGET, - BLKD_OPT_OFFSET - } - - Flags in option above will contain the type of returned data (which should be - checked against what is expected, even though the option requested should - specify it), and a flag to indicate whether the returned pointer needs to be - free()'d. - - The block device core will contain the logic now located in disk/part.c and - related files, and will be used to forward requests to block devices. The API - for the block device core will copy the ops of a block device (with a string - identifier instead of instance pointer). This means that partitions will also - be handled by the block device core, and exported as block devices, making - them transparent to the rest of the code. - - Sadly, this will change how file systems can access the devices, and thus will - affect a lot of places. However, these changes should be localized and easy to - implement. - - AHCI driver will be rewritten to fit the new unified block controller API, - making SCSI API easy to merge with sym53c8xx, or remove it once the device - driver has died. - - Optionally, IDE core may be changed into one driver with unified block - controller API, as most of it is already in one place and device drivers are - just sets of hooks. Additionally, mg_disk driver is unused and may be removed - in near future. - - -III) Analysis of in-tree drivers --------------------------------- - - ahci.c - ------ - SCSI API, will be rewritten for a different API. - - ata_piix.c - ---------- - SATA API, easy to port. - - fsl_sata.c - ---------- - SATA API, few CONFIG macros, easy to port. - - ftide020.c - ---------- - IDE API, defines CONFIG_IDE_AHB and ide_preinit hook functions. - - mg_disk.c - --------- - Single driver with mg_disk API, not much to change, easy to port. - - mvsata_ide.c - ------------ - IDE API, only defines ide_preinit hook function. - - mxc_ata.c - --------- - IDE API, only defines ide_preinit hook function. - - pata_bfin.c - ----------- - SATA API, easy to port. - - sata_dwc.c - ---------- - SATA API, easy to port. - - sata_sil3114.c - -------------- - SATA API, easy to port. - - sata_sil.c - ---------- - SATA API, easy to port. - - sil680.c - -------- - IDE API, only defines ide_preinit hook function. - - sym53c8xx.c - ----------- - SCSI API, may be merged with code from cmd_scsi. - - systemace.c - ----------- - Single driver with systemace API, not much to change, easy to port. |