RFC bus_dma_tag_parent
Matthew Dillon
dillon at apollo.backplane.com
Sat Nov 13 13:17:38 PST 2004
:> > parent_dmat = bus_dma_tag_parent(dev, lowaddr, highaddr, maxsegments);
:>
:> is the intent of the {low,high}addr and maxsegments parameters to
:> define the properties of the parent tag? the object oriented nature of
:> bus_dma would have made me think the bus (PCI, ISA, USB, etc), being
:> the "base class", would define the {low,high}addr and maxsegments
:> values and not burden each driver with knowing the specifics of the
:> bus hierarchy.
:
:It is to define the properties of the device. For example PCI does support
:both 32bit and 64bit cards, meaning that some cards can directly address
:memory above 4 GB and some not. This is import for two parts:
:a) the internal mapping of resource done by "powerful" bridges, again Alpha
: has/had those. It's a wonderful property if you have a MMU in the bridge.
:b) define characteristics for later memory allocation. This is necessary to
: correctly decide where [in system memory] to allocate memory or when to
: use bounce buffers.
I think the issue here is that the parent's dma tag is shared with all of
its children, so it can't be created with different parameters for each
child. That is what the child's own personal dma tag is supposed to be
for, right?
Perhaps this is just a naming convention problem. My take was that
the purpose of bus_dma_tag_parent() was simply to retrieve the parent's
dma tag so it could be used as the first argument in a call to
bus_dma_tag_create().
e.g.
device {
bus_dma_tag_t = bus_dma_tag_create(bus_dma_tag_parent(dev), align,
boundary, lowaddr, highaddr, etc...);
}
Now, there are certainly some restrictions to the current
bus_dma_tag_create() function. It does not give the parent(s) any
ability to modify the parameters to the device's new dma tag other
then through inheritance.
If we want to give the parent(s) more control over how the child's tag
is created we would want to change bus_dma_tag_create() from a fixed
function in i386 to a DEVMETHOD. I still believe we would also need
to have a bus_dma_tag_parent() DEVMETHOD, but the separation of
functionality seems fairly clear to me.
bus_dma_tag_parent(dev)
DEVMETHOD - simply return the (shared) dma tag representing
general requirements imposed by the parent. No modifications
are made to the tag.
bus_dma_tag_create(dev, align, boundary, lowaddr, highaddr, etc...)
DEVMETHOD (note we pass dev instead of parent_tag now), intended
to create a DMA tag suitable for the device (that is, the child)
based on the parent's restrictions plus additional restrictions
provided by the child.
The difference between the current bus_dma_tag_create() and my proposed
bus_dma_tag_create() is that my proposed function is a DEVMETHOD and thus
the parent(s) along the chain are given the opportunity to modify the
the tag directly based on additional information.
For example, If a PCI bus is 64-bit capable then bus_dma_tag_parent()
would provide a 64-bit capable tag. But if a PCI device is only 32 bit
capable that is information the the parent PCI BUS would have and so
the PCI BUS's own bus_dma_tag_create() would take the combination of its
knowlege of the PCI BUS and its knowledge of whether the child device
is a 32 or 64 bit device, and it would modify the address capabilities
AS WELL AS integrate the address restrictions specified by the device
when it called bus_dma_tag_create().
Well, does that make any sense ?
-Matt
More information about the Kernel
mailing list