Passing data from Userland to Kernel
Passing data from Userland to Kernel
- Subject: Passing data from Userland to Kernel
- From: pratik <email@hidden>
- Date: Thu, 21 Apr 2005 11:07:40 +0530
Hi All,
I am working on MAC OS 10.3.3. I want to pass the data from User space
to the kernel space. For that i am using
IOConnectMethodStructureIStructureO.
I want to pass the SCSITaskData structure to the user-client from
user-space.
My SCSITaskData Structure is as follows:
typedef struct SCSITaskData {
unsigned char CDB[16];
SCSITaskAttribute taskAttribute;
unsigned int transfercount;
UInt32 scatterGatherEntries;
struct iovec scatterGatherList[1];
}SCSITaskData;
struct iovec {
char *iov_base; /* Base address. */
size_t iov_len; /* Length. */
};
Here in the User-Client i am able to print the data by following code
snippet:
IOReturn
com_SPSOFT_driver_iSCSITargetUserClient::MyDo_Write(void *vIn, void
*vOut, void *vInCnt, void * /* vOutCnt */, void *, void *)
{
IOLog("\n####################################IN
USER-CLIENT############################################################\n");
IOReturn ret = kIOReturnSuccess;
SCSITaskData * scsitask =(SCSITaskData *) vIn;
void *pData;
IOMemoryDescriptor* memP;
IOLog("\n %x %x %x %x %x %x %x %x %x
%x",scsitask->CDB[0],scsitask->CDB[1],scsitask->CDB[2],scsitask->CDB[3],scsitask->CDB[4],scsitask->CDB[5],
scsitask->CDB[6],scsitask->CDB[7],scsitask->CDB[8],scsitask->CDB[9]);
IOLog("\n\n****************DATA IN
USER_CLIENT*************************\n\n");
IOMemoryMap *mMap = NULL;
IOReturn retWrite = kIOReturnSuccess;
IOMemoryDescriptor* mem = IOMemoryDescriptor::withRanges((IOVirtualRange
*)&scsitask->scatterGatherList,(UInt32)scsitask->scatterGatherEntries,
kIODirectionOut,fTask,true);
IOLog("\n*******************************AFTER
IOMemoryDescriptor*******************************\n");
if(!mem )
{
IOLog("\ncom_SPSOFT_driver_iSCSITargetUserClient::SPSOFT_readWrite
Unable to Map memory \n");
mem->release();
ret= kIOReturnNoMemory;
}
else
{
IOLog("\n*******************************Calling Write in
driver*******************************\n");
mem->prepare();
IOLog("\n Prepare for mem Succeded....\n");
//mMap =
mem->map(kernel_task,0,kIOMapAnywhere,0,scsitask->scatterGatherList[0].iov_len);
mMap = mem->map();
if(mMap == NULL)
{
IOLog("\n Failed to map buffer......\n");
return kIOReturnError;
}
else
{
IOLog("\n mMap = %p\n", mMap);
IOLog("\n Mapped memory block for buff successfully....\n");
void *pData = mMap->getVirtualAddress();
IOLog("\n *******************************PRINITING
PDATA=%s*******************************\n",pData);
if(pData == NULL)
{
IOLog("\n Failed to get Virtual address.....\n");
return kIOReturnError;
}
}
ret =
fProvider->SPSOFT_Write(scsitask,mem,&((SCSITaskResult*)vOut)->so,&((SCSITaskResult*)vOut)->taskResult);
IOLog("\n*******************************After Write in
driver*******************************\n");
mMap->unmap();
mMap->release();
mem->complete();
mem->release();
}
if (kIOReturnSuccess != ret) {
DEBUG_LOG("%s[%p]::%s - returning err 0xx", getName(), this,
__FUNCTION__, ret);
}
else
{
IOLog("\n Write Completed Successfully !!!!!!!! \n");
}
return ret;
}
Here i am getting the data in the User-Client. Even i am getting the
success for WRITE_10 SCSI command. But no data is get written on the
disk.
My Driver code snippet is as follows :
IOReturn
com_SPSOFT_driver_iscsitarget::MyDo_Write(SCSITaskData *task
,IOMemoryDescriptor* mem,SCSI_Sense_Data *senseBuffer,SCSITaskResults
*taskResult)
{
SCSIServiceResponse serviceResponse =
kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
SCSI_Sense_Data senseBuffer_temp = { 0 };
SCSITaskIdentifier request = NULL;
IOLog("\n*******************************CALL INSIDE
DRIVER*******************************\n");
IOReturn ret = kIOReturnSuccess;
request = GetSCSITask();
IOLog("\n*****************************AFTER
GetSCSITask*****************************\n");
for(int j=0;j<10;j++)
{
IOLog(" %x",task->CDB[j]);
}
if (request == NULL)
{
IOLog("%s[%p]::%s: could not get a SCSITask.\n", getName(), this,
__FUNCTION__);
mem->release();
return kIOReturnError;
}
else
{
if (isInactive() == false)
{
ResetForNewTask(request);
bool result = false;
if(IsParameterValid(0x2a, kSCSICmdFieldMask21Bit) &&
IsParameterValid(8, kSCSICmdFieldMask1Byte) &&
IsParameterValid(0, kSCSICmdFieldMask1Byte) &&
IsMemoryDescriptorValid(mem, 8))
{
IOLog("\n*****************************IsParameterValid*****************************\n");
if(SetCommandDescriptorBlock(request,0x2a,task->CDB[1],task->CDB[2],task->CDB[3],task->CDB[4],task->CDB[5],task->CDB[6],task->CDB[7],task->CDB[8],task->CDB[9])) // ???:root:20040503// byte 5
{
if (SetDataTransferDirection(request,
kSCSIDataTransfer_FromInitiatorToTarget) &&
SetDataBuffer(request, mem) && SetRequestedDataTransferCount(request,
task->transfercount * 512))
{
IOLog("\n****************************result =
true******************************\n");
result = true;
}
if(result == true)
{
serviceResponse =
kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
IOLog("\n B4 Write \n");
IOLog("\n****************************B4
Write******************************\n");
serviceResponse= SendCommand(request, 0 );
IOLog("\n After Write \n");
IOLog("\n****************************After
Write******************************\n");
taskResult->serviceResponse = GetServiceResponse (request );
taskResult->taskStatus = GetTaskStatus ( request);
if (serviceResponse == kSCSIServiceResponse_TASK_COMPLETE)
{
bool validSense = false;
senseBuffer->SENSE_KEY=0;
senseBuffer->ADDITIONAL_SENSE_CODE=0;
senseBuffer->ADDITIONAL_SENSE_CODE_QUALIFIER=0;
if (taskResult->taskStatus == kSCSITaskStatus_CHECK_CONDITION)
{
validSense = GetAutoSenseData(request, &senseBuffer_temp,
sizeof(senseBuffer_temp));
if (validSense == false)
{
ResetForNewTask(request);
IOMemoryDescriptor* senseBufferDesc =
IOMemoryDescriptor::withAddress(&senseBuffer_temp, kSenseDefaultSize,
kIODirectionIn);
if (REQUEST_SENSE(request,senseBufferDesc,kSenseDefaultSize,0))
{
serviceResponse = SendCommand(request, 0);
}
senseBufferDesc->release();
}
}
else
{
/// NO CHECK CONDITION
}
senseBuffer->SENSE_KEY=senseBuffer_temp.SENSE_KEY;
senseBuffer->ADDITIONAL_SENSE_CODE=senseBuffer_temp.ADDITIONAL_SENSE_CODE;
senseBuffer->ADDITIONAL_SENSE_CODE_QUALIFIER=senseBuffer_temp.ADDITIONAL_SENSE_CODE_QUALIFIER;
}
else
{
// Request has a responce other than kSCSIServiceResponse_TASK_COMPLETE
}
}
else
{
mem->release();
return kIOReturnError;
}
}
else
{
mem->release();
return kIOReturnError;
}
}
else
{
mem->release();
return kIOReturnError;
}
}
ReleaseSCSITask(request);
request = NULL;
}
return kIOReturnSuccess;
}
I am writting on the specified LBA, and reading those contents using dd.
But no data is get written.
Do i need to do some other things like vm_allocate(),
mach_make_memory_entry() etc?
Please help me out. It would be a great Help.
Thank You
Kaushik
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden