Hello,
I am implementing Fault Management (FMA) for my kernel driver. I modified
bofi.conf to enable the FMA test.
I noticed that, when allocating large dma memory, for example 8192 bytes on Sun
x4270 x86 server running Solaris10 u9, the ddi_dma_addr_bind_handle() always
fails and return DDI_DMA_TOOBIG.
However, when freeing previously allocated dma handle and access handle, the
ddi_dma_free_handle function always crashes with "driver freeing bound
dma_handle". Does this mean that the dma handle is still being used? however,
if I call ddi_dma_unbind_handle, I got "driver unbinding unbound dma_handle"
panic which indicates that it is not bounded.
I am very puzzled. Can someone help me?
Tom
WARNING: Could not bind dummy dma resource: fffffffd, size: 9632
Jul 7 16:54:15 fourier unix: [ID 836849 kern.notice]
Jul 7 16:54:15 fourier ^Mpanic[cpu13]/thread=ffffffffa1c5a820:
Jul 7 16:54:15 fourier genunix: [ID 195494 kern.notice] driver freeing bound
dma_handle
Jul 7 16:54:15 fourier unix: [ID 100000 kern.notice]
Jul 7 16:54:15 fourier genunix: [ID 655072 kern.notice] fffffe8001ef7610
bofi:bofi_error_chan+2f78a1e6 ()
Jul 7 16:54:15 fourier genunix: [ID 655072 kern.notice] fffffe8001ef7640
genunix:ddi_dma_freehdl+42 ()
Jul 7 16:54:15 fourier genunix: [ID 655072 kern.notice] fffffe8001ef7680
bofi:bofi_dma_freehdl+9c ()
Jul 7 16:54:15 fourier genunix: [ID 655072 kern.notice] fffffe8001ef76b0
genunix:ddi_dma_freehdl+42 ()
Jul 7 16:54:15 fourier genunix: [ID 655072 kern.notice] fffffe8001ef76c0
genunix:ddi_dma_free_handle+13 ()
Jul 7 16:54:15 fourier genunix: [ID 655072 kern.notice] fffffe8001ef7750
qlcnic:alloc_dummy_dma+1b8 ()
Below is my sample code which is used to allocate 8k+ dma memory:
static ddi_dma_attr_t qlcnic_dma_attr_rxbuf = {
DMA_ATTR_V0, /* dma_attr_version */
0, /* dma_attr_addr_lo */
0x7ffffffffULL, /* dma_attr_addr_hi */
0xffffull, /* dma_attr_count_max */
4096, /* dma_attr_align */
0xfff8ull, /* dma_attr_burstsizes */
1, /* dma_attr_minxfer */
0xffffffffull, /* dma_attr_maxxfer */
0xffffull, /* dma_attr_seg */
1, /* dma_attr_sgllen */
1, /* dma_attr_granular */
0 /* dma_attr_flags */
};
static struct ddi_device_acc_attr qlcnic_buf_acc_attr = {
DDI_DEVICE_ATTR_V0,
DDI_NEVERSWAP_ACC,
DDI_STRICTORDER_ACC,
};
static int
alloc_dummy_dma(qlcnic_t *adapter, size_t size)
{
int ret;
size_t len;
uint_t cookie_num;
dev_info_t *devinfo;
ddi_dma_cookie_t cookie;
ddi_acc_handle_t acc_hdl = NULL;
ddi_dma_handle_t dma_hdl = NULL;
uint32_t ncookies = NULL;
uint64_t dma_addr = 0;
void *vaddr = NULL;
devinfo = adapter->dip;
/*
* Allocate a new DMA handle for the receive descriptor
* memory area.
*/
ret = ddi_dma_alloc_handle(devinfo,
&qlcnic_dma_attr_rxbuf/*&ixgbe_desc_dma_attr*/,
DDI_DMA_DONTWAIT, NULL,
&dma_hdl);
if (ret != DDI_SUCCESS) {
cmn_err(CE_WARN,
"Could not allocate dummy dma handle: %x", ret);
dma_hdl = NULL;
return (DDI_FAILURE);
}
/*
* Allocate memory to DMA data to and from the receive
* descriptors.
*/
ret = ddi_dma_mem_alloc(dma_hdl,
size, &qlcnic_buf_acc_attr/* &ixgbe_desc_acc_attr*/,
DDI_DMA_CONSISTENT,
DDI_DMA_DONTWAIT, NULL,
(caddr_t *)&vaddr,
&len, &acc_hdl);
if (ret != DDI_SUCCESS) {
cmn_err(CE_WARN,
"Could not allocate dummy dma memory: %x", ret);
acc_hdl = NULL;
vaddr = NULL;
if (dma_hdl != NULL) {
ddi_dma_free_handle(&dma_hdl);
dma_hdl = NULL;
}
return (DDI_FAILURE);
}
/*
* Initialize the entire transmit buffer descriptor area to zero
*/
bzero(vaddr, len);
/*
* Allocates DMA resources for the memory that was allocated by
* the ddi_dma_mem_alloc call.
*/
ret = ddi_dma_addr_bind_handle(dma_hdl,
NULL, (caddr_t)vaddr,
len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
DDI_DMA_DONTWAIT, NULL, &cookie, &cookie_num);
if (ret != DDI_DMA_MAPPED) {
cmn_err(CE_WARN,
"Could not bind dummy dma resource: %x, size: %d", ret,
size);
dma_addr = NULL;
if (acc_hdl != NULL) {
ddi_dma_mem_free(&acc_hdl);
acc_hdl = NULL;
vaddr = NULL;
}
if (dma_hdl != NULL) {
/* ddi_dma_unbind_handle(dma_hdl); */
ddi_dma_free_handle(&dma_hdl);
dma_hdl = NULL;
}
return (DDI_FAILURE);
}
ASSERT(cookie_num == 1);
dma_addr = cookie.dmac_laddress;
cmn_err(CE_NOTE, "alloc_dummy_dma done\n");
return (DDI_SUCCESS);
}
--
This message posted from opensolaris.org
_______________________________________________
driver-discuss mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/driver-discuss