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

Reply via email to