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