summaryrefslogtreecommitdiff
path: root/doc/driver-model/UDM-block.txt
diff options
context:
space:
mode:
Diffstat (limited to 'doc/driver-model/UDM-block.txt')
-rw-r--r--doc/driver-model/UDM-block.txt278
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.