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