Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Oct 2000 16:07:03 -0700
From:      Mike Smith <msmith@freebsd.org>
To:        "Chris Ptacek" <ptacek@technologist.com>
Cc:        freebsd-hackers@FreeBSD.ORG
Subject:   Re: DMA in drivers? 
Message-ID:  <200010232307.e9NN73h05149@mass.osd.bsdi.com>
In-Reply-To: Your message of "Sun, 22 Oct 2000 21:26:11 PDT." <NEBBKLFHMJGHPAEKCHJJEEHNCCAA.ptacek@technologist.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
> I am in the process of writing a PCI driver for an encryption card.  The
> specifications state that the DMA Destination Address, DMA Dest. Length, DMA
> Source Addr, and DMA Source Length should be loaded into registers in the
> card.  Part of the info states:
> 
> "This register is used to establish the PCI address for data moving from the
> the Host Computer Memory to the card. It consists of a 30 bit counter with
> the low-order 2 bits hardwired as zeros. The address stored may be any
> nonzero byte length that is a multiple of 8, since 8 bytes are required to
> make up a DES encryption block.  The Source Address Register is continually
> updated during the transfer process and will always be pointing to the next
> unwritten location."
> 
> What do I need to do to get a memory address for the source and destination
> data for the DMA transfers? It sounds as if these memory addresses must have
> the last three bits zeros, will this happen automatically?  Right now I am
> stuck on how this DMA stuff is working and any help would be appreciated.
> Oh yeah, I am targeting this driver for a FreeBSD 3.x system.

3.x is obsolete, and should typically not be considered for new drivers 
unless you're doing something specifically to spec.

Having said that, the busdma infrastructure in 3.x probably works well 
enough to do what you want.

The actual process to follow is going to depend largely on how your 
exported interface to the driver works.  The card sounds like it's pretty 
stupid (eg. no scatter/gather DMA, no descriptor ring, etc). so you 
really have two options:

 - manual scatter/gather
 - copy to/from a conforming DMA-able buffer.

The choice between these two depends on the nature of the data; if your 
chunks of contiguous data are relatively large, then manual scatter/
gather will be more efficient.  OTOH, if the chunks are small, then 
it will be more efficient to gather the stream into a single buffer and 
pass that to the adapter instead.

In either case, you will want to look to the busdma code.  At the very 
least, you will need to construct a DMA tag which decsribes the card's 
DMA capabilities and a DMA map for the transaction in progress.

For manual scatter/gather, you then pass the input segment to 
bus_dmamap_load and use the helper function to build a list of physical 
segment addresses and lengths.  Then you feed each of these segments to 
the adapter, and call bus_dmamap_unload when you're done.

To allocate a conforming DMA-able buffer, use bus_dmamem_alloc and then 
pass it to bus_dmamap_load in order to obtain the base address of the 
buffer (note that if you've set the tag up properly, the buffer will be 
physically contiguous).

-- 
... every activity meets with opposition, everyone who acts has his
rivals and unfortunately opponents also.  But not because people want
to be opponents, rather because the tasks and relationships force
people to take different points of view.  [Dr. Fritz Todt]
           V I C T O R Y   N O T   V E N G E A N C E




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200010232307.e9NN73h05149>