pcibr_get_dmatrans_node(D3)pcibr_get_dmatrans_node(D3)NAMEpcibr_get_dmatrans_node - get 32-bit Direct Mapping node id
SYNOPSIS
#include <sys/PCI/pciio.h>
cnodeid_t
pcibr_get_dmatrans_node(
vertex_hdl_t vhdl)
Arguments
vhdl The connection point of the PCI device, as passed to the driver's
attach() entry point.
DESCRIPTION
Most drivers will not need to make use of this function; it exists for
drivers of 32-bit devices, running on multi-node systems.
When making use of 32-bit Direct Mapping, the PCI Bridge's Direct Mapping
Register can be setup to map PCI address space to memory on any node in
the system. Any driver that wishes to use 32-bit Direct Mapping via
pciio_dmatrans_addr() or pciio_dmatrans_list() needs to know what this
node is, and ensure that memory addresses passed to these functions
reside on that node. pcibr_get_dmatrans_node() provides the means for a
driver to obtain this node id.
A typical scenario would have a driver calling pcibr_get_dmatrans_node(),
and then using the returned node id to allocate DMA buffers on that node
via calls to a function such as kmem_zalloc_node().
By default, 32-bit Direct Mapping will use node zero. However, the
administrator can change the default by adding a DEVICE_ADMIN statement
with the PCIBUS_DMATRANS_NODE attribute in the configuration file:
/var/sysgen/system/irix.sm. For this change to take affect, the kernel
must be rebuilt and the system rebooted.
EXAMPLES
Here is an example of how a driver might make use of
pcibr_get_dmatrans_node().
#define BUFFER_POOL_SIZE 256
struct pcifoo_pool buffer_pool;
pcifoo_attach(vertex_hdl_t pconn_vhdl)
{
int buffer_size = 4096;
cnodeid_t dmatrans_node;
struct pcifoo_buffer *buffer;
buffer_pool.first = NULL;
...
/*
Page 1
pcibr_get_dmatrans_node(D3)pcibr_get_dmatrans_node(D3)
* Allocate buffer pool on node that will allow
* use of 32-bit Direct Mapping.
*/
dmatrans_node = pcibr_get_dmatrans_node(pconn_vhdl);
for (i = 0; i < BUFFER_POOL_SIZE; i++) {
buffer = kmem_zalloc_node(buffer_size,
KM_NOSLEEP | KM_CACHEALIGN,
dmatrans_node);
if (buffer == NULL) {
cmn_err(CE_ALERT,
"pcifoo_attach: kmem_zalloc_node failed");
return(-1);
}
buffer->next = buffer_pool.first;
buffer_pool.first = buffer;
}
...
}
void
pcifoo_get_dma_addr(vertex_hdl_t vhdl,
device_desc_t dev_desc,
paddr_t paddr,
size_t size,
unsigned dma_flags,
pciio_dmamap_t *dma_mapp,
iopaddr_t *dma_addrp)
{
*dma_addrp = pciio_dmatrans_addr(vhdl, dev_desc, paddr,
size, flags);
/*
* Even though we've allocated our buffers on the node returned
* by pcibr_get_dmatrans_node(), it is still possible that we
* cannot use direct mapping.
*/
if (*dma_addrp == NULL) {
*dma_mapp = pciio_dmamap_alloc(vhdl, dev_desc, size,
flags);
if (*dma_mapp != NULL) {
*dma_addrp = pciio_dmamap_addr(*dma_mapp,
paddr, size);
if (*dma_addrp == NULL) {
pciio_dmamap_free(*dma_mapp);
}
}
}
}
SEE ALSOpciio(D3), pciio_dma(D3), system(4).
Page 2