1

Now I am trying to write an IOUserSCSIParallelInterfaceController driver which uses neither DMA nor PCI and emulates a SCSI target.

I realized that fBufferIOVMAddr ( https://developer.apple.com/documentation/scsicontrollerdriverkit/scsiuserparalleltask/3555105-fbufferiovmaddr ) in SCSIUserParallelTask struct given via UserProcessParallelTask method indicates a physical address and it couldn't be used as a memory address in the driver's memory space.

I need my driver to write something to the buffer and read something from the buffer because I want to make a SCSI Communication by my driver codes.

Is there any way to access memory in physical address from a DriverKit driver?

asked Jul 11, 2021 at 3:23
1

2 Answers 2

0
#if ARCMSR_DEBUG_UserGetDataBuffer
 if(pCCB->arcmsr_request.Cdb[0]==0xA0)/*SCSI_CMD_REPORT_LUN*/
 {
 IOBufferMemoryDescriptor *osdatabuffer = nullptr;
 uint64_t address, len, length=pCCB->request_transfer_count; /* parallelTask.fRequestedTransferCount */
 /*
 ******************************************************************************************************************************************
 **
 ** virtual kern_return_t UserGetDataBuffer(SCSIDeviceIdentifier fTargetID, uint64_t fControllerTaskIdentifier, IOBufferMemoryDescriptor **osdatabuffer);
 **
 ******************************************************************************************************************************************
 */
 if((UserGetDataBuffer(fTargetID, pCCB->fControllerTaskIdentifier, &osdatabuffer) != kIOReturnSuccess) || (osdatabuffer == NULL))
 {
 arcmsr_debug_print("ArcMSRUserSpaceDriver %d: ************************************************************************************ \n",ivars->adapter_index);
 arcmsr_debug_print("ArcMSRUserSpaceDriver %d: ** Get task data buffer error, ftargetID=%d fControllerTaskIdentifier=%d \n",ivars->adapter_index,(int)fTargetID,(int)pCCB->fControllerTaskIdentifier);
 arcmsr_debug_print("ArcMSRUserSpaceDriver %d: ************************************************************************************ \n",ivars->adapter_index); 
 goto command_completion;
 }
 if((osdatabuffer->Map(0, 0, 0, 0, &address, &len) != kIOReturnSuccess) || (length != len))
 {
 arcmsr_debug_print("ArcMSRUserSpaceDriver %d: ************************************************************************************ \n",ivars->adapter_index);
 arcmsr_debug_print("ArcMSRUserSpaceDriver %d: ** Map task data buffer error, ftargetID=%d fControllerTaskIdentifier=%d \n",ivars->adapter_index,(int)fTargetID,(int)pCCB->fControllerTaskIdentifier);
 arcmsr_debug_print("ArcMSRUserSpaceDriver %d: ************************************************************************************ \n",ivars->adapter_index); 
 goto command_completion;
 }
 /*
 *******************************************************************************************************************
 ** The LUN LIST LENGTH field shall contain the length in bytes of the LUN list that is available to be transferred.
 ** The LUN list length is the number of logical unit numbers in the logical unit inventory multiplied by eight.
 *******************************************************************************************************************
 */
 memset((void *)(address+3),8,1); /* report_lun_data */
 memset((void *)(address+8),0,8); /* first lun */
 response.fBytesTransferred = 16;
 }
#endif
answered Nov 4, 2021 at 3:08
Sign up to request clarification or add additional context in comments.

3 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
This function is released in DriverKit 21.0 sdk, You can see it in Xcode 13.04 beta
MacOSX 12.0 has added this function
0
kern_return_t ArcNVMeUserSpaceDriver::arcnvme_parallelTask_remap_os_data_buffer(SCSIUserParallelTask *pParallelTask, PCCB pCCB)
{
 IOBufferMemoryDescriptor* data_buffer_memory_descriptor = nullptr;
 if ((UserGetDataBuffer(pParallelTask->fTargetID, pParallelTask->fControllerTaskIdentifier, &data_buffer_memory_descriptor) == kIOReturnSuccess) && (data_buffer_memory_descriptor != NULL))
 {
 IOAddressSegment data_buffer_virtual_address_segment = { 0 };
 if (data_buffer_memory_descriptor->GetAddressRange(&data_buffer_virtual_address_segment) == kIOReturnSuccess)
 {
 IOAddressSegment data_buffer_physical_address_segment = { 0 };
 IODMACommandSpecification dmaSpecification;
 IODMACommand* data_buffer_iodmacommand = { 0 };
 bzero(&dmaSpecification, sizeof(dmaSpecification));
 dmaSpecification.options = kIODMACommandSpecificationNoOptions;
 dmaSpecification.maxAddressBits = 64;
 if (IODMACommand::Create(ivars->pciDevice, kIODMACommandCreateNoOptions, &dmaSpecification, &data_buffer_iodmacommand) == kIOReturnSuccess)
 {
 uint64_t dmaFlags = kIOMemoryDirectionInOut;
 uint32_t dmaSegmentCount = 1;
 pCCB->data_buffer_iodmacommand = data_buffer_iodmacommand;
 if (data_buffer_iodmacommand->PrepareForDMA(kIODMACommandPrepareForDMANoOptions, data_buffer_memory_descriptor, 0/*offset*/, pParallelTask->fRequestedTransferCount/*length*/, &dmaFlags, &dmaSegmentCount, &data_buffer_physical_address_segment) == kIOReturnSuccess)
 {
 pParallelTask->fBufferIOVMAddr = (uint64_t)data_buffer_physical_address_segment.address; /* data_buffer_physical_address: overwrite original fBufferIOVMAddr */
 pCCB->OSDataBuffer = reinterpret_cast <uint8_t*> (data_buffer_virtual_address_segment.address);/* data_buffer_virtual_address */
 }
 else
 {
 return (kIOReturnError);
 }
 }
 else
 {
 return (kIOReturnError);
 }
 }
 else
 {
 return (kIOReturnError);
 }
 }
 else
 {
 return (kIOReturnError);
 }
 return(kIOReturnSuccess);
}
answered Mar 27, 2025 at 8:29

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.