IODMACommandSpecification dmaSpecification;
IOAddressSegment dma_physical_address_segment = {0};
IOAddressSegment dma_virtual_address_segment;
uint64_t dma_resource_phsical, dmaFlags = kIOMemoryDirectionInOut;
uint32_t dmaSegmentCount = 1;/* for get Physical Address, we need only one large Segment */
.....
bzero(&dmaSpecification, sizeof(dmaSpecification));
dmaSpecification.options = kIODMACommandSpecificationNoOptions;
dmaSpecification.maxAddressBits = 64;
if(IODMACommand::Create(ivars->pciDevice, kIODMACommandCreateNoOptions, &dmaSpecification, &ivars->dma_resource_iodmacommand) != kIOReturnSuccess)
{
arcsas_debug_print("ArcSASUserSpaceDriver %d: ************************************************************* \n", ivars->adapter_index);
arcsas_debug_print("ArcSASUserSpaceDriver %d: ** pciDevice IODMACommand Create Failed \n", ivars->adapter_index);
arcsas_debug_print("ArcSASUserSpaceDriver %d: ************************************************************* \n", ivars->adapter_index);
return false;
}
if(ivars->dma_resource_iodmacommand->PrepareForDMA(kIODMACommandPrepareForDMANoOptions, ivars->dma_resource_descriptor, 0/*offset /, dma_resource_size/length/, &dmaFlags, &dmaSegmentCount, &dma_physical_address_segment) != kIOReturnSuccess)
{
arcsas_debug_print("ArcSASUserSpaceDriver %d: ************************************************************************** \n", ivars->adapter_index);
arcsas_debug_print("ArcSASUserSpaceDriver %d: ** IODMACommand PrepareForDMA try to get Memory Physical Address Failed \n", ivars->adapter_index);
arcsas_debug_print("ArcSASUserSpaceDriver %d: ************************************************************************** \n", ivars->adapter_index);
return false;
}
/ physical /
dma_resource_phsical = (uint64_t)dma_physical_address_segment.address;
dma_resource->Physical_Address.parts.low = (uint32_t)(dma_resource_phsical & 0xFFFFFFFF);
dma_resource->Physical_Address.parts.high = (uint32_t)(dma_resource_phsical>> 32);
/ virtual */
dma_resource->Virtual_Address = reinterpret_cast < uint8_t *> (dma_virtual_address_segment.address);
memset(dma_resource->Virtual_Address, 0, dma_resource_size);