This is a discussion on dma'able user memory within the comp.unix.solaris forums, part of the Solaris Operating System category; --> i am running on an ultra sparc IIe, solaris 10. i want to allocate user memory which is dma'able ...
| |||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| i am running on an ultra sparc IIe, solaris 10. i want to allocate user memory which is dma'able (ie has a physical address). it doesn't need to be contiguous, b/c i am only running it on a sparc system. i have tried 2 methods, here is the first: ddi_dma_alloc_handle - success ddi_dma_mem_alloc - success ddi_dma_addr_bind_handle - success ddi_umem_lock - EFAULT can you tell me why this might be. The reason i am using umem_lock, is that i need a umem cookie to handle devmap requests. I have also tried to allocate memory first in user mode, and then to umem_lock it in kernel mode, and then to run ddi_dma_addr_bind_handle - but there the bind handle is failing due to DDI_DMA_NOMAPPING. here is the code for my first attempt. any ideas would be really helpful. nachum attr.dma_attr_version = DMA_ATTR_V0; attr.dma_attr_addr_lo = 0x00000000; attr.dma_attr_addr_hi = 0xffffffff; attr.dma_attr_count_max = 0xffffffff; attr.dma_attr_align = 1; attr.dma_attr_burstsizes = 0xffffffff; attr.dma_attr_minxfer = 1; attr.dma_attr_maxxfer = 0xffffffff; attr.dma_attr_seg = 0xffffffff; attr.dma_attr_sgllen = 1; attr.dma_attr_granular = 1; attr.dma_attr_flags = 0; error = ddi_dma_alloc_handle(softc->dip, &attr, DDI_DMA_SLEEP, 0, &memunit->hdma); if(error != DDI_SUCCESS){ cmn_err(CE_NOTE, "%s: attach: could not allocate dma handle %d", "mangomem", error); memunit->hdma = NULL; break; } dev_acc_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; dev_acc_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; dev_acc_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; error = ddi_dma_mem_alloc(memunit->hdma, alloct.size, &dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, 0, &memunit->ka, &memunit->size, &memunit->hacc); if(error != DDI_SUCCESS){ cmn_err(CE_NOTE, "ddi_dma_mem_alloc failed\n"); } if(alloct.size < memunit->size){ cmn_err(CE_NOTE, "size less than necessary wanted %x, got %x\n", alloct.size, memunit->size); ddi_dma_free_handle(&memunit->hdma); memunit->hdma = NULL; error = ENXIO; break; } alloct.size = memunit->size; error = ddi_dma_addr_bind_handle(memunit->hdma, NULL, memunit->ka, memunit->size, DDI_DMA_RDWR, DDI_DMA_SLEEP, 0, &memunit->cdma, &count); if(error != DDI_SUCCESS){ cmn_err(CE_NOTE, "ddi_dma_addr_bind_handle failed %d\n", error); ddi_dma_mem_free(&memunit->hacc); ddi_dma_free_handle(&memunit->hdma); memunit->hdma = NULL; error = ENXIO; break; } *(int*)memunit->ka = 0xfacedead; cmn_err(CE_NOTE, "count %d\n", count); alloct.pa = memunit->cdma.dmac_address; error = ddi_umem_lock(memunit->ka, memunit->size, DDI_UMEMLOCK_READ | DDI_UMEMLOCK_WRITE, &memunit->cumem); if(error != 0){ cmn_err(CE_NOTE, "ddi_umem_lock failed %d\n", error); ddi_dma_unbind_handle(memunit->hdma); ddi_dma_mem_free(&memunit->hacc); ddi_dma_free_handle(&memunit->hdma); memunit->hdma = NULL; error = ENXIO; break; } |