diff mbox

[U-Boot,01/11] DM: add block device core

Message ID 1348169867-2917-2-git-send-email-morpheus.ibis@gmail.com
State Superseded
Delegated to: Marek Vasut
Headers show

Commit Message

Pavel Herrmann Sept. 20, 2012, 7:37 p.m. UTC
This core will register all block devices (disk, cards, partitons) and provide
unfied access to them, instead of current method with device + partition offset

Signed-off-by: Pavel Herrmann <morpheus.ibis@gmail.com>
---
 Makefile                  |   1 +
 drivers/blockdev/Makefile |  42 ++++++++++++++++
 include/dm/blockdev.h     | 121 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 164 insertions(+)
 create mode 100644 drivers/blockdev/Makefile
 create mode 100644 include/dm/blockdev.h

Comments

Marek Vasut Sept. 20, 2012, 7:58 p.m. UTC | #1
Dear Pavel Herrmann,

> This core will register all block devices (disk, cards, partitons) and
> provide unfied access to them, instead of current method with device +
> partition offset
> 
> Signed-off-by: Pavel Herrmann <morpheus.ibis@gmail.com>
> ---
>  Makefile                  |   1 +
>  drivers/blockdev/Makefile |  42 ++++++++++++++++
>  include/dm/blockdev.h     | 121
> ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 164
> insertions(+)
>  create mode 100644 drivers/blockdev/Makefile
>  create mode 100644 include/dm/blockdev.h


Why not use drivers/block/ ?

[...]

Best regards,
Marek Vasut
Vikram Narayanan Sept. 20, 2012, 8:49 p.m. UTC | #2
On Fri, Sep 21, 2012 at 1:07 AM, Pavel Herrmann <morpheus.ibis@gmail.com> wrote:
> This core will register all block devices (disk, cards, partitons) and provide
> unfied access to them, instead of current method with device + partition offset
>
> Signed-off-by: Pavel Herrmann <morpheus.ibis@gmail.com>
> ---
>  Makefile                  |   1 +
>  drivers/blockdev/Makefile |  42 ++++++++++++++++
>  include/dm/blockdev.h     | 121 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 164 insertions(+)
>  create mode 100644 drivers/blockdev/Makefile
>  create mode 100644 include/dm/blockdev.h
>
<snip>
> +struct blockdev_ops {
> +       lbaint_t        (*read)(struct instance *inst, lbaint_t start,
> +                               lbaint_t blkcnt, void *buffer);
> +       lbaint_t        (*write)(struct instance *inst, lbaint_t start,
> +                               lbaint_t blkcnt, void *buffer);
> +       lbaint_t        (*erase)(struct instance *inst, lbaint_t start,
> +                               lbaint_t blkcnt);

lbaint_t is little "cryptic". Any better name suggestions?

Regards,
Vikram
Pavel Herrmann Sept. 21, 2012, 7:09 a.m. UTC | #3
Hi

On Friday 21 of September 2012 02:19:00 Vikram Narayanan wrote:
> On Fri, Sep 21, 2012 at 1:07 AM, Pavel Herrmann <morpheus.ibis@gmail.com> 
wrote:
> > This core will register all block devices (disk, cards, partitons) and
> > provide unfied access to them, instead of current method with device +
> > partition offset
> > 
> > Signed-off-by: Pavel Herrmann <morpheus.ibis@gmail.com>
> > ---
> > 
> >  Makefile                  |   1 +
> >  drivers/blockdev/Makefile |  42 ++++++++++++++++
> >  include/dm/blockdev.h     | 121
> >  ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 164
> >  insertions(+)
> >  create mode 100644 drivers/blockdev/Makefile
> >  create mode 100644 include/dm/blockdev.h
> 
> <snip>
> 
> > +struct blockdev_ops {
> > +       lbaint_t        (*read)(struct instance *inst, lbaint_t start,
> > +                               lbaint_t blkcnt, void *buffer);
> > +       lbaint_t        (*write)(struct instance *inst, lbaint_t start,
> > +                               lbaint_t blkcnt, void *buffer);
> > +       lbaint_t        (*erase)(struct instance *inst, lbaint_t start,
> > +                               lbaint_t blkcnt);
> 
> lbaint_t is little "cryptic". Any better name suggestions?

lbaint_t is an unsigned 32bit or 64bit number, depending on state of 
CONFIG_LBA48.

It was chosen because some parts of current block code use it as well, but we 
can pretty much replace it with size_t (and assume CONFIG_LBA48 is always on)

Pavel Herrmann
Pavel Herrmann Sept. 21, 2012, 7:11 a.m. UTC | #4
On Thursday 20 of September 2012 21:58:17 Marek Vasut wrote:
> Dear Pavel Herrmann,
> 
> > This core will register all block devices (disk, cards, partitons) and
> > provide unfied access to them, instead of current method with device +
> > partition offset
> > 
> > Signed-off-by: Pavel Herrmann <morpheus.ibis@gmail.com>
> > ---
> > 
> >  Makefile                  |   1 +
> >  drivers/blockdev/Makefile |  42 ++++++++++++++++
> >  include/dm/blockdev.h     | 121
> > 
> > ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 164
> > insertions(+)
> > 
> >  create mode 100644 drivers/blockdev/Makefile
> >  create mode 100644 include/dm/blockdev.h
> 
> Why not use drivers/block/ ?

Because the drivers in drivers/block have a different purpose than blockdev. I 
would expect this question for blockctrl, there i just try to avoid confusion 
about being completely compatible

Pavel Herrmann
Marek Vasut Sept. 21, 2012, 12:39 p.m. UTC | #5
Dear Pavel Herrmann,

> On Thursday 20 of September 2012 21:58:17 Marek Vasut wrote:
> > Dear Pavel Herrmann,
> > 
> > > This core will register all block devices (disk, cards, partitons) and
> > > provide unfied access to them, instead of current method with device +
> > > partition offset
> > > 
> > > Signed-off-by: Pavel Herrmann <morpheus.ibis@gmail.com>
> > > ---
> > > 
> > >  Makefile                  |   1 +
> > >  drivers/blockdev/Makefile |  42 ++++++++++++++++
> > >  include/dm/blockdev.h     | 121
> > > 
> > > ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 164
> > > insertions(+)
> > > 
> > >  create mode 100644 drivers/blockdev/Makefile
> > >  create mode 100644 include/dm/blockdev.h
> > 
> > Why not use drivers/block/ ?
> 
> Because the drivers in drivers/block have a different purpose than
> blockdev.

Different, ok. Can you elaborate how is it different?

> I would expect this question for blockctrl, there i just try to
> avoid confusion about being completely compatible
> 
> Pavel Herrmann

Best regards,
Marek Vasut
Marek Vasut Sept. 21, 2012, 12:39 p.m. UTC | #6
Dear Pavel Herrmann,

> Hi
> 
> On Friday 21 of September 2012 02:19:00 Vikram Narayanan wrote:
> > On Fri, Sep 21, 2012 at 1:07 AM, Pavel Herrmann <morpheus.ibis@gmail.com>
> 
> wrote:
> > > This core will register all block devices (disk, cards, partitons) and
> > > provide unfied access to them, instead of current method with device +
> > > partition offset
> > > 
> > > Signed-off-by: Pavel Herrmann <morpheus.ibis@gmail.com>
> > > ---
> > > 
> > >  Makefile                  |   1 +
> > >  drivers/blockdev/Makefile |  42 ++++++++++++++++
> > >  include/dm/blockdev.h     | 121
> > >  ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 164
> > >  insertions(+)
> > >  create mode 100644 drivers/blockdev/Makefile
> > >  create mode 100644 include/dm/blockdev.h
> > 
> > <snip>
> > 
> > > +struct blockdev_ops {
> > > +       lbaint_t        (*read)(struct instance *inst, lbaint_t start,
> > > +                               lbaint_t blkcnt, void *buffer);
> > > +       lbaint_t        (*write)(struct instance *inst, lbaint_t start,
> > > +                               lbaint_t blkcnt, void *buffer);
> > > +       lbaint_t        (*erase)(struct instance *inst, lbaint_t start,
> > > +                               lbaint_t blkcnt);
> > 
> > lbaint_t is little "cryptic". Any better name suggestions?
> 
> lbaint_t is an unsigned 32bit or 64bit number, depending on state of
> CONFIG_LBA48.
> 
> It was chosen because some parts of current block code use it as well, but
> we can pretty much replace it with size_t (and assume CONFIG_LBA48 is
> always on)

lbaint_t seems ok indeed.

> Pavel Herrmann

Best regards,
Marek Vasut
Pavel Herrmann Sept. 21, 2012, 1:27 p.m. UTC | #7
On Friday 21 of September 2012 14:39:14 Marek Vasut wrote:
> Dear Pavel Herrmann,
> 
> > On Thursday 20 of September 2012 21:58:17 Marek Vasut wrote:
> > > Dear Pavel Herrmann,
> > > 
> > > > This core will register all block devices (disk, cards, partitons) and
> > > > provide unfied access to them, instead of current method with device +
> > > > partition offset
> > > > 
> > > > Signed-off-by: Pavel Herrmann <morpheus.ibis@gmail.com>
> > > > ---
> > > > 
> > > >  Makefile                  |   1 +
> > > >  drivers/blockdev/Makefile |  42 ++++++++++++++++
> > > >  include/dm/blockdev.h     | 121
> > > > 
> > > > ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 164
> > > > insertions(+)
> > > > 
> > > >  create mode 100644 drivers/blockdev/Makefile
> > > >  create mode 100644 include/dm/blockdev.h
> > > 
> > > Why not use drivers/block/ ?
> > 
> > Because the drivers in drivers/block have a different purpose than
> > blockdev.
> 
> Different, ok. Can you elaborate how is it different?

blockctrl is equivalent in purpose to drivers/block, just a new approach

blockctrl = AHCI, PIIX... whichever chip you have between SATA and PCI (or 
generally disk-bus and board-bus)

blockdev = disk, partition, SD card - something that does basic checks (range, 
possibility of operation) and submits operations to correct parent (blockctrl, 
MMC controller, whatnot).
Also this gets rid of all partition-related code in filesystems, because the 
access to a partition and to the whole disk is the same, no need to manually 
compute offsets every time (and you can support discontinuous partitions, if 
you chose to do so)

Pavel Herrmann
Marek Vasut Sept. 21, 2012, 1:53 p.m. UTC | #8
Dear Pavel Herrmann,

> On Friday 21 of September 2012 14:39:14 Marek Vasut wrote:
> > Dear Pavel Herrmann,
> > 
> > > On Thursday 20 of September 2012 21:58:17 Marek Vasut wrote:
> > > > Dear Pavel Herrmann,
> > > > 
> > > > > This core will register all block devices (disk, cards, partitons)
> > > > > and provide unfied access to them, instead of current method with
> > > > > device + partition offset
> > > > > 
> > > > > Signed-off-by: Pavel Herrmann <morpheus.ibis@gmail.com>
> > > > > ---
> > > > > 
> > > > >  Makefile                  |   1 +
> > > > >  drivers/blockdev/Makefile |  42 ++++++++++++++++
> > > > >  include/dm/blockdev.h     | 121
> > > > > 
> > > > > ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 164
> > > > > insertions(+)
> > > > > 
> > > > >  create mode 100644 drivers/blockdev/Makefile
> > > > >  create mode 100644 include/dm/blockdev.h
> > > > 
> > > > Why not use drivers/block/ ?
> > > 
> > > Because the drivers in drivers/block have a different purpose than
> > > blockdev.
> > 
> > Different, ok. Can you elaborate how is it different?
> 
> blockctrl is equivalent in purpose to drivers/block, just a new approach
> 
> blockctrl = AHCI, PIIX... whichever chip you have between SATA and PCI (or
> generally disk-bus and board-bus)

So this is for sata ? Or will it also by used for SD/USB flash discs?

> blockdev = disk, partition, SD card

Uh, let's say I understand (even if I don't see the correlation between 
partition and SD card)

> - something that does basic checks
> (range, possibility of operation) and submits operations to correct parent
> (blockctrl, MMC controller, whatnot).

Ascii art might help here greatly (how these pieces fall together). I think I do 
understand it though.

> Also this gets rid of all partition-related code in filesystems, because
> the access to a partition and to the whole disk is the same, no need to
> manually compute offsets every time (and you can support discontinuous
> partitions, if you chose to do so)
> 
> Pavel Herrmann

Best regards,
Marek Vasut
Pavel Herrmann Sept. 21, 2012, 2:57 p.m. UTC | #9
On Friday 21 of September 2012 15:53:26 Marek Vasut wrote:
> Dear Pavel Herrmann,
> 
> > On Friday 21 of September 2012 14:39:14 Marek Vasut wrote:
> > > Dear Pavel Herrmann,
> > > 
> > > > On Thursday 20 of September 2012 21:58:17 Marek Vasut wrote:
> > > > > Dear Pavel Herrmann,
> > > > > 
> > > > > > This core will register all block devices (disk, cards, partitons)
> > > > > > and provide unfied access to them, instead of current method with
> > > > > > device + partition offset
> > > > > > 
> > > > > > Signed-off-by: Pavel Herrmann <morpheus.ibis@gmail.com>
> > > > > > ---
> > > > > > 
> > > > > >  Makefile                  |   1 +
> > > > > >  drivers/blockdev/Makefile |  42 ++++++++++++++++
> > > > > >  include/dm/blockdev.h     | 121
> > > > > > 
> > > > > > ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed,
> > > > > > 164
> > > > > > insertions(+)
> > > > > > 
> > > > > >  create mode 100644 drivers/blockdev/Makefile
> > > > > >  create mode 100644 include/dm/blockdev.h
> > > > > 
> > > > > Why not use drivers/block/ ?
> > > > 
> > > > Because the drivers in drivers/block have a different purpose than
> > > > blockdev.
> > > 
> > > Different, ok. Can you elaborate how is it different?
> > 
> > blockctrl is equivalent in purpose to drivers/block, just a new approach
> > 
> > blockctrl = AHCI, PIIX... whichever chip you have between SATA and PCI (or
> > generally disk-bus and board-bus)
> 
> So this is for sata ? Or will it also by used for SD/USB flash discs?

no, blockctrl will be used for SATA, PATA, SCSI, and anything of the sort 
(device with several ports, block devices on said ports, ability to send 
read/write/query commands to devices on ports - definitely not USB, possibly 
also SD, but you probably want more operations from SD)

> > blockdev = disk, partition, SD card
> 
> Uh, let's say I understand (even if I don't see the correlation between
> partition and SD card)

they are an ordered bunch of blocks with a "conventional" filesystem on them

> > - something that does basic checks
> > (range, possibility of operation) and submits operations to correct parent
> > (blockctrl, MMC controller, whatnot).
> 
> Ascii art might help here greatly (how these pieces fall together). I think
> I do understand it though.

current code
user -> FS -> offset calculation from partition info -> drivers/disk

new code
user -> FS -> blockdev -> blockctrl (or USB or SD controller)

partition blockdev does all the offset calculation and range check that FSs do 
now, and then submits the operation to the parent blockdev, which in turn 
submits it to blockctrl (or an SD controller in case of a SD card, or USB 
controller in case of a USB flash)

Pavel Herrmann
Marek Vasut Sept. 21, 2012, 3:34 p.m. UTC | #10
Dear Pavel Herrmann,

[...]

> > > blockctrl = AHCI, PIIX... whichever chip you have between SATA and PCI
> > > (or generally disk-bus and board-bus)
> > 
> > So this is for sata ? Or will it also by used for SD/USB flash discs?
> 
> no, blockctrl will be used for SATA, PATA, SCSI, and anything of the sort
> (device with several ports, block devices on said ports, ability to send
> read/write/query commands to devices on ports - definitely not USB,
> possibly also SD, but you probably want more operations from SD)

Why not USB flash ? Why not SD, what other stuff do you need for that? Is the 
API not misdesigned then?

> > > blockdev = disk, partition, SD card
> > 
> > Uh, let's say I understand (even if I don't see the correlation between
> > partition and SD card)
> 
> they are an ordered bunch of blocks with a "conventional" filesystem on
> them

You might want to do RAW reads, so why do you put filesystem into this context?

> > > - something that does basic checks
> > > (range, possibility of operation) and submits operations to correct
> > > parent (blockctrl, MMC controller, whatnot).
> > 
> > Ascii art might help here greatly (how these pieces fall together). I
> > think I do understand it though.
> 
> current code
> user -> FS -> offset calculation from partition info -> drivers/disk
> 
> new code
> user -> FS -> blockdev -> blockctrl (or USB or SD controller)

So your "blockctrl" should do the USB/SD/whatever muxing.

> partition blockdev does all the offset calculation and range check that FSs
> do now, and then submits the operation to the parent blockdev, which in
> turn submits it to blockctrl (or an SD controller in case of a SD card, or
> USB controller in case of a USB flash)

Make sure you document this in the next series.

> Pavel Herrmann

Best regards,
Marek Vasut
Pavel Herrmann Sept. 21, 2012, 3:48 p.m. UTC | #11
On Friday 21 of September 2012 17:34:27 Marek Vasut wrote:
> Dear Pavel Herrmann,
> 
> [...]
> 
> > > > blockctrl = AHCI, PIIX... whichever chip you have between SATA and PCI
> > > > (or generally disk-bus and board-bus)
> > > 
> > > So this is for sata ? Or will it also by used for SD/USB flash discs?
> > 
> > no, blockctrl will be used for SATA, PATA, SCSI, and anything of the sort
> > (device with several ports, block devices on said ports, ability to send
> > read/write/query commands to devices on ports - definitely not USB,
> > possibly also SD, but you probably want more operations from SD)
> 
> Why not USB flash ? Why not SD, what other stuff do you need for that? Is
> the API not misdesigned then?

you should have a blockdev driver for USB flash and SD, but not blockctrl

> > > > blockdev = disk, partition, SD card
> > > 
> > > Uh, let's say I understand (even if I don't see the correlation between
> > > partition and SD card)
> > 
> > they are an ordered bunch of blocks with a "conventional" filesystem on
> > them
> 
> You might want to do RAW reads, so why do you put filesystem into this
> context?

yes, you can do raw reads, but in most cases you are using a filesystem. i put 
filesystem there to differentiate from nand devices (which have a special flash-
based filesystems in most cases).

> > > > - something that does basic checks
> > > > (range, possibility of operation) and submits operations to correct
> > > > parent (blockctrl, MMC controller, whatnot).
> > > 
> > > Ascii art might help here greatly (how these pieces fall together). I
> > > think I do understand it though.
> > 
> > current code
> > user -> FS -> offset calculation from partition info -> drivers/disk
> > 
> > new code
> > user -> FS -> blockdev -> blockctrl (or USB or SD controller)
> 
> So your "blockctrl" should do the USB/SD/whatever muxing.

no, blockdev shoud be the last common part, for SD/USB, you should have a 
different blockdev driver, that uses USB/SD API for the actual works

blockctrl is just an unified look at whatever now resides in drivers/block

> > partition blockdev does all the offset calculation and range check that
> > FSs
> > do now, and then submits the operation to the parent blockdev, which in
> > turn submits it to blockctrl (or an SD controller in case of a SD card, or
> > USB controller in case of a USB flash)
> 
> Make sure you document this in the next series.
> 
> > Pavel Herrmann
> 
> Best regards,
> Marek Vasut
Marek Vasut Sept. 21, 2012, 3:55 p.m. UTC | #12
Dear Pavel Herrmann,

> On Friday 21 of September 2012 17:34:27 Marek Vasut wrote:
> > Dear Pavel Herrmann,
> > 
> > [...]
> > 
> > > > > blockctrl = AHCI, PIIX... whichever chip you have between SATA and
> > > > > PCI (or generally disk-bus and board-bus)
> > > > 
> > > > So this is for sata ? Or will it also by used for SD/USB flash discs?
> > > 
> > > no, blockctrl will be used for SATA, PATA, SCSI, and anything of the
> > > sort (device with several ports, block devices on said ports, ability
> > > to send read/write/query commands to devices on ports - definitely not
> > > USB, possibly also SD, but you probably want more operations from SD)
> > 
> > Why not USB flash ? Why not SD, what other stuff do you need for that? Is
> > the API not misdesigned then?
> 
> you should have a blockdev driver for USB flash and SD, but not blockctrl

I'm lost again. Do I also need a blockdev driver for SATA controller now that I 
need a blockdev driver for SD card controller ?

> > > > > blockdev = disk, partition, SD card
> > > > 
> > > > Uh, let's say I understand (even if I don't see the correlation
> > > > between partition and SD card)
> > > 
> > > they are an ordered bunch of blocks with a "conventional" filesystem on
> > > them
> > 
> > You might want to do RAW reads, so why do you put filesystem into this
> > context?
> 
> yes, you can do raw reads, but in most cases you are using a filesystem.

Not true, see how env is stored to these media.

> i
> put filesystem there to differentiate from nand devices (which have a
> special flash- based filesystems in most cases).

Not true, raw IO on flash media is often used too.

> > > > > - something that does basic checks
> > > > > (range, possibility of operation) and submits operations to correct
> > > > > parent (blockctrl, MMC controller, whatnot).
> > > > 
> > > > Ascii art might help here greatly (how these pieces fall together). I
> > > > think I do understand it though.
> > > 
> > > current code
> > > user -> FS -> offset calculation from partition info -> drivers/disk
> > > 
> > > new code
> > > user -> FS -> blockdev -> blockctrl (or USB or SD controller)
> > 
> > So your "blockctrl" should do the USB/SD/whatever muxing.
> 
> no, blockdev shoud be the last common part, for SD/USB, you should have a
> different blockdev driver, that uses USB/SD API for the actual works
> 
> blockctrl is just an unified look at whatever now resides in drivers/block

Answer my question, you are contradicting yourself in your answer. So again, 
does "blockctrl" do the muxing between the downstream drivers (SD blockdev, USB 
blockdev, SATA blockdev, IDE blockdev ... ) ?

> > > partition blockdev does all the offset calculation and range check that
> > > FSs
> > > do now, and then submits the operation to the parent blockdev, which in
> > > turn submits it to blockctrl (or an SD controller in case of a SD card,
> > > or USB controller in case of a USB flash)
> > 
> > Make sure you document this in the next series.
> > 
> > > Pavel Herrmann
> > 
> > Best regards,
> > Marek Vasut

Best regards,
Marek Vasut
Pavel Herrmann Sept. 21, 2012, 5:19 p.m. UTC | #13
On Friday 21 of September 2012 17:55:10 Marek Vasut wrote:
> Dear Pavel Herrmann,
> 
> > On Friday 21 of September 2012 17:34:27 Marek Vasut wrote:
> > > Dear Pavel Herrmann,
> > > 
> > > [...]
> > > 
> > > > > > blockctrl = AHCI, PIIX... whichever chip you have between SATA and
> > > > > > PCI (or generally disk-bus and board-bus)
> > > > > 
> > > > > So this is for sata ? Or will it also by used for SD/USB flash
> > > > > discs?
> > > > 
> > > > no, blockctrl will be used for SATA, PATA, SCSI, and anything of the
> > > > sort (device with several ports, block devices on said ports, ability
> > > > to send read/write/query commands to devices on ports - definitely not
> > > > USB, possibly also SD, but you probably want more operations from SD)
> > > 
> > > Why not USB flash ? Why not SD, what other stuff do you need for that?
> > > Is
> > > the API not misdesigned then?
> > 
> > you should have a blockdev driver for USB flash and SD, but not blockctrl
> 
> I'm lost again. Do I also need a blockdev driver for SATA controller now
> that I need a blockdev driver for SD card controller ?

you need a blockdev for a blockctrl (see [5/11]), and you need a blockctrl 
driver for your SATA controller

you can either implement your SD as a blockctrl and use that blockdev, or 
implement a separate blockdev for your SD card (this is the original 
intention)

I have not looked at current SD API, but i do recall seeing some non-memory 
SDIO cards (wifi for example, not sure u-boot supports this though), so i dont 
think SD should be implemented as a blockctrl

> > > > > > blockdev = disk, partition, SD card
> > > > > 
> > > > > Uh, let's say I understand (even if I don't see the correlation
> > > > > between partition and SD card)
> > > > 
> > > > they are an ordered bunch of blocks with a "conventional" filesystem
> > > > on
> > > > them
> > > 
> > > You might want to do RAW reads, so why do you put filesystem into this
> > > context?
> > 
> > yes, you can do raw reads, but in most cases you are using a filesystem.
> 
> Not true, see how env is stored to these media.
> 
> > i
> > put filesystem there to differentiate from nand devices (which have a
> > special flash- based filesystems in most cases).
> 
> Not true, raw IO on flash media is often used too.
> 
> > > > > > - something that does basic checks
> > > > > > (range, possibility of operation) and submits operations to
> > > > > > correct
> > > > > > parent (blockctrl, MMC controller, whatnot).
> > > > > 
> > > > > Ascii art might help here greatly (how these pieces fall together).
> > > > > I
> > > > > think I do understand it though.
> > > > 
> > > > current code
> > > > user -> FS -> offset calculation from partition info -> drivers/disk
> > > > 
> > > > new code
> > > > user -> FS -> blockdev -> blockctrl (or USB or SD controller)
> > > 
> > > So your "blockctrl" should do the USB/SD/whatever muxing.
> > 
> > no, blockdev shoud be the last common part, for SD/USB, you should have a
> > different blockdev driver, that uses USB/SD API for the actual works
> > 
> > blockctrl is just an unified look at whatever now resides in drivers/block
> 
> Answer my question, you are contradicting yourself in your answer. So again,
> does "blockctrl" do the muxing between the downstream drivers (SD blockdev,
> USB blockdev, SATA blockdev, IDE blockdev ... ) ?

again, no

blockctrl is a common API primarily for SATA/PATA/SCSI controllers, blockdev 
is an abstraction of any block device, therefore you should have a AHCI 
blockctrl, piix blockctrl, bfin blockctrl, sil3114 blockctrl (add anything from 
drivers/block) but a USB blockdev and SD blockdev.

see the difference?

the idea is that there would be no difference when working with SATA/PATA/SCSI 
(as the commands are almost the same currently), but working with USB drives 
and SD cards would be a little different (that is from their own separate 
commands, but not through the blockdev layer)

Pavel Herrmann
Marek Vasut Sept. 21, 2012, 6 p.m. UTC | #14
Dear Pavel Herrmann,

[...]

> > > you should have a blockdev driver for USB flash and SD, but not
> > > blockctrl
> > 
> > I'm lost again. Do I also need a blockdev driver for SATA controller now
> > that I need a blockdev driver for SD card controller ?
> 
> you need a blockdev for a blockctrl (see [5/11]), and you need a blockctrl
> driver for your SATA controller

So "blockctrl" == The controller driver? Viva abbrevs. Rename it to 
block_controller_driver .

> you can either implement your SD as a blockctrl and use that blockdev

SD as in ... SD card or SD host controller ? Use what blockdev ?

> , or
> implement a separate blockdev for your SD card (this is the original
> intention)

Ok, so the general abstration is to have a block_controller_driver (blockctrl in 
your parlance) for each and every driver in drivers/block _and_ which provides 
only basic read/write block for the downstream drivers (block_device) attached 
to it _and_ proxifies them for particular device type handlers?

Now block_device (blockdev) is either a whole disc, partition, or subpartition. 
It exports read/write block operations, but to complete them, it uses upcalls 
into it's parent, yes? These upcalls stop at first block_controller_driver, 
correct?

The user only ever uses the read/write block operations of the block_device, 
yes?

> I have not looked at current SD API, but i do recall seeing some non-memory
> SDIO cards (wifi for example, not sure u-boot supports this though), so i
> dont think SD should be implemented as a blockctrl

They are not. But you should have looked at them since if you don't, that means 
you ignored fundamental part of the block interface.

But anyway, in case of SD card, the upcalls stop at block_controller_driver, 
which handles the block IO the specific SD controller way?

> > > > > > > blockdev = disk, partition, SD card
> > > > > > 
> > > > > > Uh, let's say I understand (even if I don't see the correlation
> > > > > > between partition and SD card)
> > > > > 
> > > > > they are an ordered bunch of blocks with a "conventional"
> > > > > filesystem on
> > > > > them
> > > > 
> > > > You might want to do RAW reads, so why do you put filesystem into
> > > > this context?
> > > 
> > > yes, you can do raw reads, but in most cases you are using a
> > > filesystem.
> > 
> > Not true, see how env is stored to these media.
> > 
> > > i
> > > put filesystem there to differentiate from nand devices (which have a
> > > special flash- based filesystems in most cases).
> > 
> > Not true, raw IO on flash media is often used too.
> > 
> > > > > > > - something that does basic checks
> > > > > > > (range, possibility of operation) and submits operations to
> > > > > > > correct
> > > > > > > parent (blockctrl, MMC controller, whatnot).
> > > > > > 
> > > > > > Ascii art might help here greatly (how these pieces fall
> > > > > > together). I
> > > > > > think I do understand it though.
> > > > > 
> > > > > current code
> > > > > user -> FS -> offset calculation from partition info ->
> > > > > drivers/disk
> > > > > 
> > > > > new code
> > > > > user -> FS -> blockdev -> blockctrl (or USB or SD controller)
> > > > 
> > > > So your "blockctrl" should do the USB/SD/whatever muxing.
> > > 
> > > no, blockdev shoud be the last common part, for SD/USB, you should have
> > > a different blockdev driver, that uses USB/SD API for the actual works
> > > 
> > > blockctrl is just an unified look at whatever now resides in
> > > drivers/block
> > 
> > Answer my question, you are contradicting yourself in your answer. So
> > again, does "blockctrl" do the muxing between the downstream drivers (SD
> > blockdev, USB blockdev, SATA blockdev, IDE blockdev ... ) ?
> 
> again, no
> 
> blockctrl is a common API primarily for SATA/PATA/SCSI controllers,
> blockdev is an abstraction of any block device, therefore you should have
> a AHCI blockctrl, piix blockctrl, bfin blockctrl, sil3114 blockctrl (add
> anything from drivers/block) but a USB blockdev and SD blockdev.
> 
> see the difference?

I assume I do, confirm above.

> the idea is that there would be no difference when working with
> SATA/PATA/SCSI (as the commands are almost the same currently), but
> working with USB drives and SD cards would be a little different (that is
> from their own separate commands, but not through the blockdev layer)

I see

> Pavel Herrmann

Best regards,
Marek Vasut
Pavel Herrmann Sept. 21, 2012, 6:53 p.m. UTC | #15
On Friday 21 of September 2012 20:00:10 Marek Vasut wrote:
> Dear Pavel Herrmann,
> 
> [...]
> 
> > > > you should have a blockdev driver for USB flash and SD, but not
> > > > blockctrl
> > > 
> > > I'm lost again. Do I also need a blockdev driver for SATA controller now
> > > that I need a blockdev driver for SD card controller ?
> > 
> > you need a blockdev for a blockctrl (see [5/11]), and you need a blockctrl
> > driver for your SATA controller
> 
> So "blockctrl" == The controller driver? Viva abbrevs. Rename it to
> block_controller_driver .

thats far too long, dont you think? we only have 80 cols in code...

> > you can either implement your SD as a blockctrl and use that blockdev
> 
> SD as in ... SD card or SD host controller ? Use what blockdev ?

either we say we only have SD memory (and will never ever have other SDIO 
cards), implement SD controller with blockctrl API (and change it slightly, 
because SD is inherently flash and therefore has an erase operation)

on the other hand, we could have a separate API for SD controllers (richer 
than the blockctrl, to eventually suport non-memory SD cards), and then have a 
device that provides blockdev API on one end, and uses this SD API on the 
other (much like blockdev_ata in [5/11] does for blockctrl API).
this is the original idea; for this reason, blockdev API already has an erase 
operation, even though blockctrl does not support it.

> > , or
> > implement a separate blockdev for your SD card (this is the original
> > intention)
> 
> Ok, so the general abstration is to have a block_controller_driver
> (blockctrl in your parlance) for each and every driver in drivers/block

yes

> _and_ which provides only basic read/write block for the downstream drivers
> (block_device) attached to it

yes

> _and_ proxifies them for particular device type handlers?

not sure what you mean there. what device type handlers? is that 
SATA/SCSI/PATA? that should disappear, only reason i have it in code is 
because i am wrapping old APIs into the new one.

> Now block_device (blockdev) is either a whole disc, partition, or
> subpartition. It exports read/write block operations, but to complete them,
> it uses upcalls into it's parent, yes?

yes

> These upcalls stop at first block_controller_driver, correct?

in case of a hard disk, yes. in case of a USB flash, it uses USB calls to its 
parent (USB hub or whatever) to complete the task at hand

> The user only ever uses the read/write block operations of the block_device,
> yes?

yes

> > I have not looked at current SD API, but i do recall seeing some
> > non-memory
> > SDIO cards (wifi for example, not sure u-boot supports this though), so i
> > dont think SD should be implemented as a blockctrl
> 
> They are not. But you should have looked at them since if you don't, that
> means you ignored fundamental part of the block interface.
> 
> But anyway, in case of SD card, the upcalls stop at block_controller_driver,
> which handles the block IO the specific SD controller way?

see above for the options. original idea is no, but it should be possible to 
implement it that way

> > > > > > > > blockdev = disk, partition, SD card
> > > > > > > 
> > > > > > > Uh, let's say I understand (even if I don't see the correlation
> > > > > > > between partition and SD card)
> > > > > > 
> > > > > > they are an ordered bunch of blocks with a "conventional"
> > > > > > filesystem on
> > > > > > them
> > > > > 
> > > > > You might want to do RAW reads, so why do you put filesystem into
> > > > > this context?
> > > > 
> > > > yes, you can do raw reads, but in most cases you are using a
> > > > filesystem.
> > > 
> > > Not true, see how env is stored to these media.
> > > 
> > > > i
> > > > put filesystem there to differentiate from nand devices (which have a
> > > > special flash- based filesystems in most cases).
> > > 
> > > Not true, raw IO on flash media is often used too.
> > > 
> > > > > > > > - something that does basic checks
> > > > > > > > (range, possibility of operation) and submits operations to
> > > > > > > > correct
> > > > > > > > parent (blockctrl, MMC controller, whatnot).
> > > > > > > 
> > > > > > > Ascii art might help here greatly (how these pieces fall
> > > > > > > together). I
> > > > > > > think I do understand it though.
> > > > > > 
> > > > > > current code
> > > > > > user -> FS -> offset calculation from partition info ->
> > > > > > drivers/disk
> > > > > > 
> > > > > > new code
> > > > > > user -> FS -> blockdev -> blockctrl (or USB or SD controller)
> > > > > 
> > > > > So your "blockctrl" should do the USB/SD/whatever muxing.
> > > > 
> > > > no, blockdev shoud be the last common part, for SD/USB, you should
> > > > have
> > > > a different blockdev driver, that uses USB/SD API for the actual works
> > > > 
> > > > blockctrl is just an unified look at whatever now resides in
> > > > drivers/block
> > > 
> > > Answer my question, you are contradicting yourself in your answer. So
> > > again, does "blockctrl" do the muxing between the downstream drivers (SD
> > > blockdev, USB blockdev, SATA blockdev, IDE blockdev ... ) ?
> > 
> > again, no
> > 
> > blockctrl is a common API primarily for SATA/PATA/SCSI controllers,
> > blockdev is an abstraction of any block device, therefore you should have
> > a AHCI blockctrl, piix blockctrl, bfin blockctrl, sil3114 blockctrl (add
> > anything from drivers/block) but a USB blockdev and SD blockdev.
> > 
> > see the difference?
> 
> I assume I do, confirm above.
> 
> > the idea is that there would be no difference when working with
> > SATA/PATA/SCSI (as the commands are almost the same currently), but
> > working with USB drives and SD cards would be a little different (that is
> > from their own separate commands, but not through the blockdev layer)
> 
> I see

Pavel Herrmann
Marek Vasut Sept. 21, 2012, 7:17 p.m. UTC | #16
Dear Pavel Herrmann,

> On Friday 21 of September 2012 20:00:10 Marek Vasut wrote:
> > Dear Pavel Herrmann,
> > 
> > [...]
> > 
> > > > > you should have a blockdev driver for USB flash and SD, but not
> > > > > blockctrl
> > > > 
> > > > I'm lost again. Do I also need a blockdev driver for SATA controller
> > > > now that I need a blockdev driver for SD card controller ?
> > > 
> > > you need a blockdev for a blockctrl (see [5/11]), and you need a
> > > blockctrl driver for your SATA controller
> > 
> > So "blockctrl" == The controller driver? Viva abbrevs. Rename it to
> > block_controller_driver .
> 
> thats far too long, dont you think? we only have 80 cols in code...

So what? You can abbrev. the variable name, so it won't get in the way. As you 
can see, I was confused by the name, do you expect others not to be?

> > > you can either implement your SD as a blockctrl and use that blockdev
> > 
> > SD as in ... SD card or SD host controller ? Use what blockdev ?
> 
> either we say we only have SD memory (and will never ever have other SDIO
> cards), implement SD controller with blockctrl API (and change it slightly,
> because SD is inherently flash and therefore has an erase operation)
> 
> on the other hand, we could have a separate API for SD controllers (richer
> than the blockctrl, to eventually suport non-memory SD cards), and then
> have a device that provides blockdev API on one end, and uses this SD API
> on the other (much like blockdev_ata in [5/11] does for blockctrl API).
> this is the original idea; for this reason, blockdev API already has an
> erase operation, even though blockctrl does not support it.
> 
> > > , or
> > > implement a separate blockdev for your SD card (this is the original
> > > intention)
> > 
> > Ok, so the general abstration is to have a block_controller_driver
> > (blockctrl in your parlance) for each and every driver in drivers/block
> 
> yes
> 
> > _and_ which provides only basic read/write block for the downstream
> > drivers (block_device) attached to it
> 
> yes
> 
> > _and_ proxifies them for particular device type handlers?
> 
> not sure what you mean there. what device type handlers? is that
> SATA/SCSI/PATA? that should disappear, only reason i have it in code is
> because i am wrapping old APIs into the new one.

I mean the particular block_controller_driver instance routes the "read/write 
block" request from downstream block_device through SATA/SD/SCSI/whatever 
"library" or "layer" back into itself. But the later "itself" is the 
implementation of the "library" or "layer" API. Once the library call returns, 
the "read/write block" operation is complete and the result can be passed back 
to the downstream "block_device". Yes?

> > Now block_device (blockdev) is either a whole disc, partition, or
> > subpartition. It exports read/write block operations, but to complete
> > them, it uses upcalls into it's parent, yes?
> 
> yes
> 
> > These upcalls stop at first block_controller_driver, correct?
> 
> in case of a hard disk, yes. in case of a USB flash, it uses USB calls to
> its parent (USB hub or whatever) to complete the task at hand

Let me reformulate -- there is only single block_controller_driver instance the 
request crosses on it's way up the driver tree. Yes?

[...]

Best regards,
Marek Vasut
Pavel Herrmann Sept. 21, 2012, 7:29 p.m. UTC | #17
On Friday 21 of September 2012 21:17:43 Marek Vasut wrote:
> Dear Pavel Herrmann,
> 
> > On Friday 21 of September 2012 20:00:10 Marek Vasut wrote:
> > > Dear Pavel Herrmann,
> > > 
> > > [...]
> > > 
> > > > > > you should have a blockdev driver for USB flash and SD, but not
> > > > > > blockctrl
> > > > > 
> > > > > I'm lost again. Do I also need a blockdev driver for SATA controller
> > > > > now that I need a blockdev driver for SD card controller ?
> > > > 
> > > > you need a blockdev for a blockctrl (see [5/11]), and you need a
> > > > blockctrl driver for your SATA controller
> > > 
> > > So "blockctrl" == The controller driver? Viva abbrevs. Rename it to
> > > block_controller_driver .
> > 
> > thats far too long, dont you think? we only have 80 cols in code...
> 
> So what? You can abbrev. the variable name, so it won't get in the way. As
> you can see, I was confused by the name, do you expect others not to be?
> > > > you can either implement your SD as a blockctrl and use that blockdev
> > > 
> > > SD as in ... SD card or SD host controller ? Use what blockdev ?
> > 
> > either we say we only have SD memory (and will never ever have other SDIO
> > cards), implement SD controller with blockctrl API (and change it
> > slightly,
> > because SD is inherently flash and therefore has an erase operation)
> > 
> > on the other hand, we could have a separate API for SD controllers (richer
> > than the blockctrl, to eventually suport non-memory SD cards), and then
> > have a device that provides blockdev API on one end, and uses this SD API
> > on the other (much like blockdev_ata in [5/11] does for blockctrl API).
> > this is the original idea; for this reason, blockdev API already has an
> > erase operation, even though blockctrl does not support it.
> > 
> > > > , or
> > > > implement a separate blockdev for your SD card (this is the original
> > > > intention)
> > > 
> > > Ok, so the general abstration is to have a block_controller_driver
> > > (blockctrl in your parlance) for each and every driver in drivers/block
> > 
> > yes
> > 
> > > _and_ which provides only basic read/write block for the downstream
> > > drivers (block_device) attached to it
> > 
> > yes
> > 
> > > _and_ proxifies them for particular device type handlers?
> > 
> > not sure what you mean there. what device type handlers? is that
> > SATA/SCSI/PATA? that should disappear, only reason i have it in code is
> > because i am wrapping old APIs into the new one.
> 
> I mean the particular block_controller_driver instance routes the
> "read/write block" request from downstream block_device through
> SATA/SD/SCSI/whatever "library" or "layer" back into itself. But the later
> "itself" is the implementation of the "library" or "layer" API. Once the
> library call returns, the "read/write block" operation is complete and the
> result can be passed back to the downstream "block_device". Yes?

in that case no, the block controller should directly take care of the call, 
without it being translated into some form it likes better for its particular 
interface.

the translation is udes as a mechanism to support old code, but eventually 
there should be none, and the drivers should take a request from block_device 
and take care of it (probably by using memory-mapped access, or however you 
communicate with that chip).

there might be a shared library for old IDE drivers though, as they are more 
like a shared code with driver (and board)-specific hooks.

> > > Now block_device (blockdev) is either a whole disc, partition, or
> > > subpartition. It exports read/write block operations, but to complete
> > > them, it uses upcalls into it's parent, yes?
> > 
> > yes
> > 
> > > These upcalls stop at first block_controller_driver, correct?
> > 
> > in case of a hard disk, yes. in case of a USB flash, it uses USB calls to
> > its parent (USB hub or whatever) to complete the task at hand
> 
> Let me reformulate -- there is only single block_controller_driver instance
> the request crosses on it's way up the driver tree. Yes?

one or none - requests on USB flashes should not pass through 
block_controller_driver.

every child of block_controller should be a block_device (not necessarily the 
other way around), so there is no way you pass more instances block_controller 
on your way up.
Marek Vasut Sept. 21, 2012, 9:11 p.m. UTC | #18
Dear Pavel Herrmann,

[...]

> > I mean the particular block_controller_driver instance routes the
> > "read/write block" request from downstream block_device through
> > SATA/SD/SCSI/whatever "library" or "layer" back into itself. But the
> > later "itself" is the implementation of the "library" or "layer" API.
> > Once the library call returns, the "read/write block" operation is
> > complete and the result can be passed back to the downstream
> > "block_device". Yes?
> 
> in that case no, the block controller should directly take care of the
> call, without it being translated into some form it likes better for its
> particular interface.

This is entirely wrong. This would mean for example for SD drivers, to implement 
whole SD stack.

> the translation is udes as a mechanism to support old code, but eventually
> there should be none, and the drivers should take a request from
> block_device and take care of it (probably by using memory-mapped access,
> or however you communicate with that chip).
> 
> there might be a shared library for old IDE drivers though, as they are
> more like a shared code with driver (and board)-specific hooks.
> 
> > > > Now block_device (blockdev) is either a whole disc, partition, or
> > > > subpartition. It exports read/write block operations, but to complete
> > > > them, it uses upcalls into it's parent, yes?
> > > 
> > > yes
> > > 
> > > > These upcalls stop at first block_controller_driver, correct?
> > > 
> > > in case of a hard disk, yes. in case of a USB flash, it uses USB calls
> > > to its parent (USB hub or whatever) to complete the task at hand
> > 
> > Let me reformulate -- there is only single block_controller_driver
> > instance the request crosses on it's way up the driver tree. Yes?
> 
> one or none - requests on USB flashes should not pass through
> block_controller_driver.

Uh, what do they pass into then ?

> every child of block_controller should be a block_device (not necessarily
> the other way around

I doubt it's even possible to be the other way around.

> ), so there is no way you pass more instances
> block_controller on your way up.

Ok, let me explain again. Let's look at the USB case to make it more real-world-
ish. Imagine you have a thumb drive with 2 partitions. Thus you have two 
instances of struct block_device [denote BDp] for the partitions and one more 
for the whole disc [denote BDd]. When you read from partition, you end up poking 
BDp, which pushes the request up into BDd. This in turn calls USB-flashdisc-
block_controller_driver [call it UFc]. For flash disc to read data, it needs to 
do some USB transfers. These are provided by USB host controller [UHC]. Thus you 
need some glue between UHC and UFc ... this is what I'm talking about.

Ok, I see the issue at hand. In case of a "regular drive", this implements the 
IO directly. In case of SD, this is a proxy object which interfaces with some 
SD-library and prepares the SD commands and then pushes that up into the 
controller to do the job? Same thing for USB flashes ?

Best regards,
Marek Vasut
Pavel Herrmann Sept. 21, 2012, 11:43 p.m. UTC | #19
On Friday 21 of September 2012 23:11:57 Marek Vasut wrote:
> Dear Pavel Herrmann,
> 
> [...]
> 
> > > I mean the particular block_controller_driver instance routes the
> > > "read/write block" request from downstream block_device through
> > > SATA/SD/SCSI/whatever "library" or "layer" back into itself. But the
> > > later "itself" is the implementation of the "library" or "layer" API.
> > > Once the library call returns, the "read/write block" operation is
> > > complete and the result can be passed back to the downstream
> > > "block_device". Yes?
> > 
> > in that case no, the block controller should directly take care of the
> > call, without it being translated into some form it likes better for its
> > particular interface.
> 
> This is entirely wrong. This would mean for example for SD drivers, to
> implement whole SD stack.

no one is forbiding you from having a shared library of common routines, but 
you should not force anyone to use it.

> > the translation is udes as a mechanism to support old code, but eventually
> > there should be none, and the drivers should take a request from
> > block_device and take care of it (probably by using memory-mapped access,
> > or however you communicate with that chip).
> > 
> > there might be a shared library for old IDE drivers though, as they are
> > more like a shared code with driver (and board)-specific hooks.
> > 
> > > > > Now block_device (blockdev) is either a whole disc, partition, or
> > > > > subpartition. It exports read/write block operations, but to
> > > > > complete
> > > > > them, it uses upcalls into it's parent, yes?
> > > > 
> > > > yes
> > > > 
> > > > > These upcalls stop at first block_controller_driver, correct?
> > > > 
> > > > in case of a hard disk, yes. in case of a USB flash, it uses USB calls
> > > > to its parent (USB hub or whatever) to complete the task at hand
> > > 
> > > Let me reformulate -- there is only single block_controller_driver
> > > instance the request crosses on it's way up the driver tree. Yes?
> > 
> > one or none - requests on USB flashes should not pass through
> > block_controller_driver.
> 
> Uh, what do they pass into then ?

their parent (an USB hub)

> > every child of block_controller should be a block_device (not necessarily
> > the other way around
> 
> I doubt it's even possible to be the other way around.
> 
> > ), so there is no way you pass more instances
> > block_controller on your way up.
> 
> Ok, let me explain again. Let's look at the USB case to make it more
> real-world- ish. Imagine you have a thumb drive with 2 partitions. Thus you
> have two instances of struct block_device [denote BDp] for the partitions
> and one more for the whole disc [denote BDd]. When you read from partition,
> you end up poking BDp, which pushes the request up into BDd. This in turn
> calls USB-flashdisc- block_controller_driver [call it UFc]. For flash disc
> to read data, it needs to do some USB transfers. These are provided by USB
> host controller [UHC]. Thus you need some glue between UHC and UFc ... this
> is what I'm talking about.

there should be no "UFc", your "BDd" driver should talk directly to your "UHC" 
(a driver that has blockdev API on one end, USB on the other)

> Ok, I see the issue at hand. In case of a "regular drive", this implements
> the IO directly. In case of SD, this is a proxy object which interfaces
> with some SD-library and prepares the SD commands and then pushes that up
> into the controller to do the job? Same thing for USB flashes ?

not every block device will have a block controller as a parent (or parent-of-
parent in case of a partition). there would be a blockdev-usb that has a USB 
hub as a parent, and a blockdev-mmc, that has a mmc/sdio controller as a 
parent.

so basically what you mean, without the block_controller in the middle - 
please note that the block_device API is actually richer than the 
block_controller API (has erase) for exactly this reason.

Pavel Herrmann
Marek Vasut Sept. 22, 2012, 12:09 a.m. UTC | #20
Dear Pavel Herrmann,

[...]

> > > one or none - requests on USB flashes should not pass through
> > > block_controller_driver.
> > 
> > Uh, what do they pass into then ?
> 
> their parent (an USB hub)

block_device instance (aka. partition/disk) directly connected to USB hub 
instance does not seem right.

> > > every child of block_controller should be a block_device (not
> > > necessarily the other way around
> > 
> > I doubt it's even possible to be the other way around.
> > 
> > > ), so there is no way you pass more instances
> > > block_controller on your way up.
> > 
> > Ok, let me explain again. Let's look at the USB case to make it more
> > real-world- ish. Imagine you have a thumb drive with 2 partitions. Thus
> > you have two instances of struct block_device [denote BDp] for the
> > partitions and one more for the whole disc [denote BDd]. When you read
> > from partition, you end up poking BDp, which pushes the request up into
> > BDd. This in turn calls USB-flashdisc- block_controller_driver [call it
> > UFc]. For flash disc to read data, it needs to do some USB transfers.
> > These are provided by USB host controller [UHC]. Thus you need some glue
> > between UHC and UFc ... this is what I'm talking about.
> 
> there should be no "UFc", your "BDd" driver should talk directly to your
> "UHC"

So my generic partition implementation (BDd) would have to implement USB 
flashdisc stuff, correct? This makes no sense.

> (a driver that has blockdev API on one end, USB on the other)

Ok, so how would this work, every partition implementation implements upcalls 
for all USB, SCSI, SATA, IDE, SD, ... and gazilion other types of drive it can 
sit on?

> > Ok, I see the issue at hand. In case of a "regular drive", this
> > implements the IO directly. In case of SD, this is a proxy object which
> > interfaces with some SD-library and prepares the SD commands and then
> > pushes that up into the controller to do the job? Same thing for USB
> > flashes ?
> 
> not every block device will have a block controller as a parent (or
> parent-of- parent in case of a partition). there would be a blockdev-usb
> that has a USB hub as a parent, and a blockdev-mmc, that has a mmc/sdio
> controller as a parent.

So you would have a specific partition implementation for SD, SATA, IDE, SCSI, 
USB ... ? This is flawed.

The partition should be a generic "thing" which knows nothing about where it's 
sitting at. So is the whole drive, same thing, it just has partitions hooked 
under it.

I'd expect a "block_controller" to be the proxy object under which the 
block_device representing the disc is connected. And this "block_controller" to 
be proxifying the requests to the respective drivers (be it SD, SATA, whatever).

> so basically what you mean, without the block_controller in the middle -
> please note that the block_device API is actually richer than the
> block_controller API (has erase) for exactly this reason.
> 
> Pavel Herrmann

Best regards,
Marek Vasut
Pavel Herrmann Sept. 22, 2012, 9:39 a.m. UTC | #21
On Saturday 22 of September 2012 02:09:15 Marek Vasut wrote:
> Dear Pavel Herrmann,
> 
> [...]
> 
> > > > one or none - requests on USB flashes should not pass through
> > > > block_controller_driver.
> > > 
> > > Uh, what do they pass into then ?
> > 
> > their parent (an USB hub)
> 
> block_device instance (aka. partition/disk) directly connected to USB hub
> instance does not seem right.

why?

> > > > every child of block_controller should be a block_device (not
> > > > necessarily the other way around
> > > 
> > > I doubt it's even possible to be the other way around.
> > > 
> > > > ), so there is no way you pass more instances
> > > > block_controller on your way up.
> > > 
> > > Ok, let me explain again. Let's look at the USB case to make it more
> > > real-world- ish. Imagine you have a thumb drive with 2 partitions. Thus
> > > you have two instances of struct block_device [denote BDp] for the
> > > partitions and one more for the whole disc [denote BDd]. When you read
> > > from partition, you end up poking BDp, which pushes the request up into
> > > BDd. This in turn calls USB-flashdisc- block_controller_driver [call it
> > > UFc]. For flash disc to read data, it needs to do some USB transfers.
> > > These are provided by USB host controller [UHC]. Thus you need some glue
> > > between UHC and UFc ... this is what I'm talking about.
> > 
> > there should be no "UFc", your "BDd" driver should talk directly to your
> > "UHC"
> 
> So my generic partition implementation (BDd) would have to implement USB
> flashdisc stuff, correct? This makes no sense.

no. your generic USB flash would have to implement USB flashdisc stuff, your 
generic partition implements block_device operations on top of other 
block_device (aka diosk, memory card, USB flash)

please read the letters you came up with right. (maybe after getting some 
sleep by the looks of it)

the point you are not getting is that there should be more block_device 
drivers than there is now - one for partitions, one for disk, one for USB 
flash, one for SD and so on, each one using a different parent API

> > (a driver that has blockdev API on one end, USB on the other)
> 
> Ok, so how would this work, every partition implementation implements
> upcalls for all USB, SCSI, SATA, IDE, SD, ... and gazilion other types of
> drive it can sit on?

no, partition only implements call onto another block device

> > > Ok, I see the issue at hand. In case of a "regular drive", this
> > > implements the IO directly. In case of SD, this is a proxy object which
> > > interfaces with some SD-library and prepares the SD commands and then
> > > pushes that up into the controller to do the job? Same thing for USB
> > > flashes ?
> > 
> > not every block device will have a block controller as a parent (or
> > parent-of- parent in case of a partition). there would be a blockdev-usb
> > that has a USB hub as a parent, and a blockdev-mmc, that has a mmc/sdio
> > controller as a parent.
> 
> So you would have a specific partition implementation for SD, SATA, IDE,
> SCSI, USB ... ? This is flawed.

no, read above

> The partition should be a generic "thing" which knows nothing about where
> it's sitting at. So is the whole drive, same thing, it just has partitions
> hooked under it.
> 
> I'd expect a "block_controller" to be the proxy object under which the
> block_device representing the disc is connected. And this "block_controller"
> to be proxifying the requests to the respective drivers (be it SD, SATA,
> whatever).

your idea is wrong - you expect there will always be only one block_device 
representig a "disk", and all the proxy would be done by the block_controller 
above it. this is not true


Pavel Herrmann
Marek Vasut Sept. 22, 2012, 1:33 p.m. UTC | #22
Dear Pavel Herrmann,

> On Saturday 22 of September 2012 02:09:15 Marek Vasut wrote:
> > Dear Pavel Herrmann,
> > 
> > [...]
> > 
> > > > > one or none - requests on USB flashes should not pass through
> > > > > block_controller_driver.
> > > > 
> > > > Uh, what do they pass into then ?
> > > 
> > > their parent (an USB hub)
> > 
> > block_device instance (aka. partition/disk) directly connected to USB hub
> > instance does not seem right.
> 
> why?

It doesn't make sense ... you need some kind of interim controller (like the 
chip between the USB and NAND in the thumbdrive.

> > > > > every child of block_controller should be a block_device (not
> > > > > necessarily the other way around
> > > > 
> > > > I doubt it's even possible to be the other way around.
> > > > 
> > > > > ), so there is no way you pass more instances
> > > > > block_controller on your way up.
> > > > 
> > > > Ok, let me explain again. Let's look at the USB case to make it more
> > > > real-world- ish. Imagine you have a thumb drive with 2 partitions.
> > > > Thus you have two instances of struct block_device [denote BDp] for
> > > > the partitions and one more for the whole disc [denote BDd]. When
> > > > you read from partition, you end up poking BDp, which pushes the
> > > > request up into BDd. This in turn calls USB-flashdisc-
> > > > block_controller_driver [call it UFc]. For flash disc to read data,
> > > > it needs to do some USB transfers. These are provided by USB host
> > > > controller [UHC]. Thus you need some glue between UHC and UFc ...
> > > > this is what I'm talking about.
> > > 
> > > there should be no "UFc", your "BDd" driver should talk directly to
> > > your "UHC"
> > 
> > So my generic partition implementation (BDd) would have to implement USB
> > flashdisc stuff, correct? This makes no sense.
> 
> no. your generic USB flash would have to implement USB flashdisc stuff,
> your generic partition implements block_device operations on top of other
> block_device (aka diosk, memory card, USB flash)

Ok, so in your parlance, the block_device is either "partition/disc" or a "SD 
card controller driver" or "USB flashdisc driver" ? You are mixing these two 
things together?

> please read the letters you came up with right. (maybe after getting some
> sleep by the looks of it)

I'd prefer to read some documented code.

> the point you are not getting is that there should be more block_device
> drivers than there is now - one for partitions, one for disk, one for USB
> flash, one for SD and so on, each one using a different parent API

Ok, now I understand your intention. Split it -- make partitions separate, since 
this is flat out confusing!

Make partitions / whole disc a separate thing ...
Make USB flash driver / SD card driver / etc. another thing ...

You can not mix these two together, it makes no sense.

> > > (a driver that has blockdev API on one end, USB on the other)
> > 
> > Ok, so how would this work, every partition implementation implements
> > upcalls for all USB, SCSI, SATA, IDE, SD, ... and gazilion other types of
> > drive it can sit on?
> 
> no, partition only implements call onto another block device
> 
> > > > Ok, I see the issue at hand. In case of a "regular drive", this
> > > > implements the IO directly. In case of SD, this is a proxy object
> > > > which interfaces with some SD-library and prepares the SD commands
> > > > and then pushes that up into the controller to do the job? Same
> > > > thing for USB flashes ?
> > > 
> > > not every block device will have a block controller as a parent (or
> > > parent-of- parent in case of a partition). there would be a
> > > blockdev-usb that has a USB hub as a parent, and a blockdev-mmc, that
> > > has a mmc/sdio controller as a parent.
> > 
> > So you would have a specific partition implementation for SD, SATA, IDE,
> > SCSI, USB ... ? This is flawed.
> 
> no, read above
> 
> > The partition should be a generic "thing" which knows nothing about where
> > it's sitting at. So is the whole drive, same thing, it just has
> > partitions hooked under it.
> > 
> > I'd expect a "block_controller" to be the proxy object under which the
> > block_device representing the disc is connected. And this
> > "block_controller" to be proxifying the requests to the respective
> > drivers (be it SD, SATA, whatever).
> 
> your idea is wrong - you expect there will always be only one block_device
> representig a "disk", and all the proxy would be done by the
> block_controller above it. this is not true

Any amount of "block_device" can be connected under the "block_controller". 
Given that "block_device" is a partition/disc _only_ and "block_controller" is 
the interface driver ... which is probably not true, so you lost me again.

I stop here, this discussion leads nowhere. Can you please write proper 
documentation from which I can get an idea how this exactly works? Ideally with 
diagrams ... doc/driver-model/UDM-block.txt would be a good place.

> 
> Pavel Herrmann

Best regards,
Marek Vasut
Pavel Herrmann Sept. 22, 2012, 1:59 p.m. UTC | #23
On Saturday 22 of September 2012 15:33:10 Marek Vasut wrote:
> Dear Pavel Herrmann,
> 
> > On Saturday 22 of September 2012 02:09:15 Marek Vasut wrote:
> > > Dear Pavel Herrmann,
> > > 
> > > [...]
> > > 
> > > > > > one or none - requests on USB flashes should not pass through
> > > > > > block_controller_driver.
> > > > > 
> > > > > Uh, what do they pass into then ?
> > > > 
> > > > their parent (an USB hub)
> > > 
> > > block_device instance (aka. partition/disk) directly connected to USB
> > > hub
> > > instance does not seem right.
> > 
> > why?
> 
> It doesn't make sense ... you need some kind of interim controller (like the
> chip between the USB and NAND in the thumbdrive.

yes, but you dont make drivers for every chip there is, instead the chips 
understand a common language, where you describe block operations by USB 
transfers, and that is exactly what saib block_device_usb_flash would do.

> > > > > > every child of block_controller should be a block_device (not
> > > > > > necessarily the other way around
> > > > > 
> > > > > I doubt it's even possible to be the other way around.
> > > > > 
> > > > > > ), so there is no way you pass more instances
> > > > > > block_controller on your way up.
> > > > > 
> > > > > Ok, let me explain again. Let's look at the USB case to make it more
> > > > > real-world- ish. Imagine you have a thumb drive with 2 partitions.
> > > > > Thus you have two instances of struct block_device [denote BDp] for
> > > > > the partitions and one more for the whole disc [denote BDd]. When
> > > > > you read from partition, you end up poking BDp, which pushes the
> > > > > request up into BDd. This in turn calls USB-flashdisc-
> > > > > block_controller_driver [call it UFc]. For flash disc to read data,
> > > > > it needs to do some USB transfers. These are provided by USB host
> > > > > controller [UHC]. Thus you need some glue between UHC and UFc ...
> > > > > this is what I'm talking about.
> > > > 
> > > > there should be no "UFc", your "BDd" driver should talk directly to
> > > > your "UHC"
> > > 
> > > So my generic partition implementation (BDd) would have to implement USB
> > > flashdisc stuff, correct? This makes no sense.
> > 
> > no. your generic USB flash would have to implement USB flashdisc stuff,
> > your generic partition implements block_device operations on top of other
> > block_device (aka diosk, memory card, USB flash)
> 
> Ok, so in your parlance, the block_device is either "partition/disc" or a
> "SD card controller driver" or "USB flashdisc driver" ? You are mixing
> these two things together?
> 
> > please read the letters you came up with right. (maybe after getting some
> > sleep by the looks of it)
> 
> I'd prefer to read some documented code.

im missing the point of this. you stateted that you have a partition "BDp" and 
a disk "BDd". i said your "BDd" will sit above USB API, and you stared ranting 
about partitions implementing USB stuff, which was totaly off.

> > the point you are not getting is that there should be more block_device
> > drivers than there is now - one for partitions, one for disk, one for USB
> > flash, one for SD and so on, each one using a different parent API
> 
> Ok, now I understand your intention. Split it -- make partitions separate,
> since this is flat out confusing!
> 
> Make partitions / whole disc a separate thing ...
> Make USB flash driver / SD card driver / etc. another thing ...
> 
> You can not mix these two together, it makes no sense.

well, disks, SD cards and USB flashes are one thing at the moment (see struct 
block_dev_desc). i am only adding partitions to the mix.

> > > > (a driver that has blockdev API on one end, USB on the other)
> > > 
> > > Ok, so how would this work, every partition implementation implements
> > > upcalls for all USB, SCSI, SATA, IDE, SD, ... and gazilion other types
> > > of
> > > drive it can sit on?
> > 
> > no, partition only implements call onto another block device
> > 
> > > > > Ok, I see the issue at hand. In case of a "regular drive", this
> > > > > implements the IO directly. In case of SD, this is a proxy object
> > > > > which interfaces with some SD-library and prepares the SD commands
> > > > > and then pushes that up into the controller to do the job? Same
> > > > > thing for USB flashes ?
> > > > 
> > > > not every block device will have a block controller as a parent (or
> > > > parent-of- parent in case of a partition). there would be a
> > > > blockdev-usb that has a USB hub as a parent, and a blockdev-mmc, that
> > > > has a mmc/sdio controller as a parent.
> > > 
> > > So you would have a specific partition implementation for SD, SATA, IDE,
> > > SCSI, USB ... ? This is flawed.
> > 
> > no, read above
> > 
> > > The partition should be a generic "thing" which knows nothing about
> > > where
> > > it's sitting at. So is the whole drive, same thing, it just has
> > > partitions hooked under it.
> > > 
> > > I'd expect a "block_controller" to be the proxy object under which the
> > > block_device representing the disc is connected. And this
> > > "block_controller" to be proxifying the requests to the respective
> > > drivers (be it SD, SATA, whatever).
> > 
> > your idea is wrong - you expect there will always be only one block_device
> > representig a "disk", and all the proxy would be done by the
> > block_controller above it. this is not true
> 
> Any amount of "block_device" can be connected under the "block_controller".
> Given that "block_device" is a partition/disc _only_ and "block_controller"
> is the interface driver ... which is probably not true, so you lost me
> again.

block controller muxes several disks onto one device (like a SATA controller 
does). you dont need this on USB drives and MMC cards, because you have a 
controller that can access multiple devices already (like the USB root hub)

if you took a look at the code you might see the point - the only thing you 
add by haveing a block_controller is a "port" parameter to every function, 
which you dont need in SD cards or USB flashes

> I stop here, this discussion leads nowhere. Can you please write proper
> documentation from which I can get an idea how this exactly works? Ideally
> with diagrams ... doc/driver-model/UDM-block.txt would be a good place.
> > Pavel Herrmann
> 
> Best regards,
> Marek Vasut
Pavel Herrmann Sept. 24, 2012, 12:23 p.m. UTC | #24
On Saturday 22 September 2012 15:59:46 Pavel Herrmann wrote:
> On Saturday 22 of September 2012 15:33:10 Marek Vasut wrote:
> > Dear Pavel Herrmann,
> > 
> > > On Saturday 22 of September 2012 02:09:15 Marek Vasut wrote:
> > > > Dear Pavel Herrmann,
> > > > 
> > > > [...]
> > > > 
> > > > > > > one or none - requests on USB flashes should not pass through
> > > > > > > block_controller_driver.
> > > > > > 
> > > > > > Uh, what do they pass into then ?
> > > > > 
> > > > > their parent (an USB hub)
> > > > 
> > > > block_device instance (aka. partition/disk) directly connected to USB
> > > > hub
> > > > instance does not seem right.
> > > 
> > > why?
> > 
> > It doesn't make sense ... you need some kind of interim controller (like
> > the chip between the USB and NAND in the thumbdrive.
> 
> yes, but you dont make drivers for every chip there is, instead the chips
> understand a common language, where you describe block operations by USB
> transfers, and that is exactly what saib block_device_usb_flash would do.
> 
> > > > > > > every child of block_controller should be a block_device (not
> > > > > > > necessarily the other way around
> > > > > > 
> > > > > > I doubt it's even possible to be the other way around.
> > > > > > 
> > > > > > > ), so there is no way you pass more instances
> > > > > > > block_controller on your way up.
> > > > > > 
> > > > > > Ok, let me explain again. Let's look at the USB case to make it
> > > > > > more
> > > > > > real-world- ish. Imagine you have a thumb drive with 2 partitions.
> > > > > > Thus you have two instances of struct block_device [denote BDp]
> > > > > > for
> > > > > > the partitions and one more for the whole disc [denote BDd]. When
> > > > > > you read from partition, you end up poking BDp, which pushes the
> > > > > > request up into BDd. This in turn calls USB-flashdisc-
> > > > > > block_controller_driver [call it UFc]. For flash disc to read
> > > > > > data,
> > > > > > it needs to do some USB transfers. These are provided by USB host
> > > > > > controller [UHC]. Thus you need some glue between UHC and UFc ...
> > > > > > this is what I'm talking about.
> > > > > 
> > > > > there should be no "UFc", your "BDd" driver should talk directly to
> > > > > your "UHC"
> > > > 
> > > > So my generic partition implementation (BDd) would have to implement
> > > > USB
> > > > flashdisc stuff, correct? This makes no sense.
> > > 
> > > no. your generic USB flash would have to implement USB flashdisc stuff,
> > > your generic partition implements block_device operations on top of
> > > other
> > > block_device (aka diosk, memory card, USB flash)
> > 
> > Ok, so in your parlance, the block_device is either "partition/disc" or a
> > "SD card controller driver" or "USB flashdisc driver" ? You are mixing
> > these two things together?
> > 
> > > please read the letters you came up with right. (maybe after getting
> > > some
> > > sleep by the looks of it)
> > 
> > I'd prefer to read some documented code.
> 
> im missing the point of this. you stateted that you have a partition "BDp"
> and a disk "BDd". i said your "BDd" will sit above USB API, and you stared
> ranting about partitions implementing USB stuff, which was totaly off.
> 
> > > the point you are not getting is that there should be more block_device
> > > drivers than there is now - one for partitions, one for disk, one for
> > > USB
> > > flash, one for SD and so on, each one using a different parent API
> > 
> > Ok, now I understand your intention. Split it -- make partitions separate,
> > since this is flat out confusing!
> > 
> > Make partitions / whole disc a separate thing ...
> > Make USB flash driver / SD card driver / etc. another thing ...
> > 
> > You can not mix these two together, it makes no sense.
> 
> well, disks, SD cards and USB flashes are one thing at the moment (see
> struct block_dev_desc). i am only adding partitions to the mix.
> 
> > > > > (a driver that has blockdev API on one end, USB on the other)
> > > > 
> > > > Ok, so how would this work, every partition implementation implements
> > > > upcalls for all USB, SCSI, SATA, IDE, SD, ... and gazilion other types
> > > > of
> > > > drive it can sit on?
> > > 
> > > no, partition only implements call onto another block device
> > > 
> > > > > > Ok, I see the issue at hand. In case of a "regular drive", this
> > > > > > implements the IO directly. In case of SD, this is a proxy object
> > > > > > which interfaces with some SD-library and prepares the SD commands
> > > > > > and then pushes that up into the controller to do the job? Same
> > > > > > thing for USB flashes ?
> > > > > 
> > > > > not every block device will have a block controller as a parent (or
> > > > > parent-of- parent in case of a partition). there would be a
> > > > > blockdev-usb that has a USB hub as a parent, and a blockdev-mmc,
> > > > > that
> > > > > has a mmc/sdio controller as a parent.
> > > > 
> > > > So you would have a specific partition implementation for SD, SATA,
> > > > IDE,
> > > > SCSI, USB ... ? This is flawed.
> > > 
> > > no, read above
> > > 
> > > > The partition should be a generic "thing" which knows nothing about
> > > > where
> > > > it's sitting at. So is the whole drive, same thing, it just has
> > > > partitions hooked under it.
> > > > 
> > > > I'd expect a "block_controller" to be the proxy object under which the
> > > > block_device representing the disc is connected. And this
> > > > "block_controller" to be proxifying the requests to the respective
> > > > drivers (be it SD, SATA, whatever).
> > > 
> > > your idea is wrong - you expect there will always be only one
> > > block_device
> > > representig a "disk", and all the proxy would be done by the
> > > block_controller above it. this is not true
> > 
> > Any amount of "block_device" can be connected under the
> > "block_controller".
> > Given that "block_device" is a partition/disc _only_ and
> > "block_controller"
> > is the interface driver ... which is probably not true, so you lost me
> > again.
> 
> block controller muxes several disks onto one device (like a SATA controller
> does). you dont need this on USB drives and MMC cards, because you have a
> controller that can access multiple devices already (like the USB root hub)
> 
> if you took a look at the code you might see the point - the only thing you
> add by haveing a block_controller is a "port" parameter to every function,
> which you dont need in SD cards or USB flashes

For all who are reading this, I have been enlightened with the knowledge that 
there can be multiple MMC/SD cards on one MMC controller, as there can be 
multiple hard drives behind one USB device. This is something this code was 
indeed not designed for, and i apologize for the misunderstanding.

Pavel Herrmann
diff mbox

Patch

diff --git a/Makefile b/Makefile
index ba74696..e43fd9d 100644
--- a/Makefile
+++ b/Makefile
@@ -303,6 +303,7 @@  LIBS-y += test/libtest.o
 
 LIBS-$(CONFIG_DM) += common/dm/libdm.o
 LIBS-$(CONFIG_DM) += drivers/demo/libdemo.o
+LIBS-${CONFIG_DM_BLOCK} += drivers/blockdev/libblockdev.o
 
 ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
 LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
diff --git a/drivers/blockdev/Makefile b/drivers/blockdev/Makefile
new file mode 100644
index 0000000..693e236
--- /dev/null
+++ b/drivers/blockdev/Makefile
@@ -0,0 +1,42 @@ 
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	:= $(obj)libblockdev.o
+
+COBJS-${CONFIG_DM_BLOCK} := core.o
+
+COBJS	:= $(COBJS-y)
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+
+all:	$(LIB)
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/include/dm/blockdev.h b/include/dm/blockdev.h
new file mode 100644
index 0000000..828eb2b
--- /dev/null
+++ b/include/dm/blockdev.h
@@ -0,0 +1,121 @@ 
+/*
+ * (C) Copyright 2012
+ * Pavel Herrmann <morpheus.ibis@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _DM_BLOCKDEV_H_
+#define _DM_BLOCKDEV_H_ 1
+
+#include <dm/options.h>
+#include <dm/structures.h>
+
+#define BLOCKDEV_IFTYPE_BITS 4
+#define BLOCKDEV_IFTYPE_COUNT (1<<BLOCKDEV_IFTYPE_BITS)
+#define BLOCKDEV_IFTYPE_MAX BLOCKDEV_IFTYPE_COUNT-1
+
+/* core interface structures */
+
+enum blockdev_iftype {
+	BLOCKDEV_IFTYPE_UNKNOWN = 0,
+	BLOCKDEV_IFTYPE_PARTITION,
+	BLOCKDEV_IFTYPE_ATA,
+	BLOCKDEV_IFTYPE_SD,
+	BLOCKDEV_IFTYPE_USB,
+};
+
+/* values from ATA specification */
+#define BLOCKDEV_TYPE_UNKNOWN	0xff
+#define BLOCKDEV_TYPE_HARDDISK	0x00
+#define BLOCKDEV_TYPE_TAPE	0x01
+#define BLOCKDEV_TYPE_CDROM	0x05
+#define BLOCKDEV_TYPE_OPDISK	0x07
+/* this one does not exist in ATA */
+#define BLOCKDEV_TYPE_PARTITION	0xfe
+
+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_PRODUCT,
+	BLKD_OPT_REVISION,
+	BLKD_OPT_SCSILUN,
+	BLKD_OPT_SCSITARGET,
+	BLKD_OPT_OFFSET
+};
+
+struct blockdev_ops {
+	lbaint_t	(*read)(struct instance *inst, lbaint_t start,
+				lbaint_t blkcnt, void *buffer);
+	lbaint_t	(*write)(struct instance *inst, lbaint_t start,
+				lbaint_t blkcnt, void *buffer);
+	lbaint_t	(*erase)(struct instance *inst, lbaint_t start,
+				lbaint_t blkcnt);
+	int		(*get_option)(struct instance *inst,
+				enum blockdev_option_code option,
+				struct option *result);
+	int		(*set_option)(struct instance *inst,
+				enum blockdev_option_code option,
+				struct option *value);
+};
+
+struct blockdev_core_hint {
+	enum blockdev_iftype iftype;
+	unsigned int part_number;
+};
+
+/* platform data for devices */
+
+struct blockdev_ata_platform_data {
+	int port_number;
+};
+
+struct blockdev_partition_platform_data {
+	lbaint_t offset;
+	lbaint_t block_count;
+	unsigned int part_number;
+};
+
+/* core command API */
+
+struct instance *get_blockdev_by_name(char *name);
+int scan_partitions(struct instance *i);
+int add_partition(struct instance *parent, lbaint_t start, lbaint_t length,
+	unsigned int number);
+int print_blockdev_info(struct instance *i);
+int print_blockdev_info_all(void);
+
+/* core driver API */
+
+lbaint_t blockdev_read(struct instance *i, lbaint_t start, lbaint_t blkcnt,
+		void *buffer);
+lbaint_t blockdev_write(struct instance *i, lbaint_t start, lbaint_t blkcnt,
+		void *buffer);
+lbaint_t blockdev_erase(struct instance *i, lbaint_t start, lbaint_t blkcnt);
+int blockdev_get_option(struct instance *i, enum blockdev_option_code op,
+		struct option *result);
+int blockdev_set_option(struct instance *i, enum blockdev_option_code op,
+		struct option *value);
+
+#endif