
On 1/26/07, Wolfgang Denk wd@denx.de wrote:
In message 528646bc0701261111i6f0dcb0i96f81259b3a4311d@mail.gmail.com you wrote:
My vote is to treat DataFlash like a block device, and make sure that it supports byte-wide access.
Treat DataFlash like a block device? That sounds wrong to me.
I've been thinking about this some more, and I'm not sure I agree.
Just for the moment; forget the term 'block device' and forget about the current implementation of u-boot. How significant are the difference between the following devices? mmc, CF, IDE HD, SCSI HD, DataFlash, memmapped flash, NAND flash, i2c eeprom, USB storage. Here's my short list: - different block sizes; DataFlash can be written byte at a time; while other devices have minimum write sizes. Some devices need blocks to be specifically erased before rewriting. - memmapped flash can be be read directly on the memory bus; but writing requires a special routine - Large variation of size, from a few kbytes up to thousands of gigabytes. - Some devices are typically partitioned for convenience - speed differences - large number of
The technology varies wildly, but they are all storage devices which store of an ordered sequence of bytes. In every device, the address of a single item of data can be boiled down to a single integer.
Take a look at the following interface. For *most* commands; how well does this is this api encapsulate those differences for common commands? Assume that device specific commands still exist for things that don't fit well into the model. ie. block erase and protect commands.
open(device) # Prepare for read/write operation seek(distance, abs_flag) # Relative or absolute seek read(buffer, count) write(buffer, count) close() # Operation finished; sync any pending buffers back to disk. Notes: - assume device can only be opened once. ie. it's a bug to call open() twice - this could be used by commands like mm, md, bootm, etc. I'm not trying to design a full control interface (protect, erase, etc). - common commands would typically call open(), seek(), read/write(), read/write(), ..., close() before returning to user. ie. device would *not* be left open after command completes. - should be suitable for partition access too - read/write commands are expected to transparently handle block boundaries. ie. if one byte is written to the middle of a block; the write hook should read the block, modify the byte, and keep it buffered until it either a read/write/seek() moves to another sector, or close() is called. - and yes, I'm just using the each device as a file perspective. It's a well established abstraction, so why not here too?
I think this is a reasonable approach to provide a common interface without making device specific side cases too complex to deal with. Adding new device support to all commands becomes pretty trivial this way.
Thoughts? Feel free to tell me if I'm flying too high in the stratosphere on this one. g.