From owner-freebsd-hackers Mon Oct 23 16: 3:30 2000 Delivered-To: freebsd-hackers@freebsd.org Received: from mass.osd.bsdi.com (adsl-63-202-176-145.dsl.snfc21.pacbell.net [63.202.176.145]) by hub.freebsd.org (Postfix) with ESMTP id 6B33337B4C5 for ; Mon, 23 Oct 2000 16:03:27 -0700 (PDT) Received: from mass.osd.bsdi.com (localhost [127.0.0.1]) by mass.osd.bsdi.com (8.11.0/8.9.3) with ESMTP id e9NN73h05149; Mon, 23 Oct 2000 16:07:09 -0700 (PDT) (envelope-from msmith@mass.osd.bsdi.com) Message-Id: <200010232307.e9NN73h05149@mass.osd.bsdi.com> X-Mailer: exmh version 2.1.1 10/15/1999 To: "Chris Ptacek" Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: DMA in drivers? In-reply-to: Your message of "Sun, 22 Oct 2000 21:26:11 PDT." Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Date: Mon, 23 Oct 2000 16:07:03 -0700 From: Mike Smith Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG > 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