Dear Mike,
Please go through the code for our Read
problem
/***************User
Space Application **************************/
/*
Purpose: This calls the 'read' method of user client using IOConnectMethodStructureIStructureO
*/
static
kern_return_t MyDoRead(io_connect_t connect)
kern_return_t kernResult;
MySampleStruct
sampleStructIn; // Input structure
MySampleStruct
sampleStructOut; //Output structure
kernResult =
vm_allocate(mach_task_self(), (vm_address_t*) &sampleStructIn.buff,
vm_page_size, TRUE);
if(sampleStructIn.buff)
{
char* buff = (char*) sampleStructOut.buff;
strcpy(buff, "");
}
IOByteCount structSizeIn = sizeof(MySampleStruct);
IOByteCount structSizeOut =
sizeof(MySampleStruct);
if (connect)
{
kernResult =
IOConnectMethodStructureIStructureO(connect, // connection handle returned from IOServiceOpen().
kCoreDoRead, // an
index to the function in the kernel.
structSizeIn, // the
number of scalar parameters.
&structSizeOut,
&sampleStructIn,
&sampleStructOut
);
}
return kernResult;
}
/***************User
client **************************/
getTargetAndMethodForIndex(IOService
** target, UInt32 index)
{
{ // kCoreDoRead
NULL,
(IOMethod)
&com_CoreSnap_UserClient::CoreSnapUserClientDoRead,
kIOUCStructIStructO,
sizeof(MySampleStruct),
sizeof(MySampleStruct)
},
}
IOReturn
com_CoreSnap_UserClient::CoreSnapUserClientDoRead(MySampleStruct *InStruct,
IOByteCount InStructSize, MySampleStruct *OutStruct, IOByteCount
*OutStructSize)
{
IOMemoryDescriptor
*ReadBuffer = NULL;
// Constructing memory
descriptor for out put structure
ReadBuffer =
IOMemoryDescriptor::withAddress((vm_address_t) OutStruct->buff,
(IOByteCount) OutStruct->size, kIODirectionIn, fTask);
if(ReadBuffer) //Created IOMemoryDescriptor for buff Successfully....
{
retRead = ReadBuffer->prepare();
IOLog("\n address of prepare buffer = %p\n",
retRead);
if(retRead == kIOReturnSuccess)
{
IOLog("\n prepare for buff
Succeded....\n");
// mapping the
IOMemoryDescriptr buffer
retRead =
ReadBuffer->map();
if(retRead == kIOReturnSuccess)
{
IOLog("map successful\n");
// get the provider for our userclient and call driver
read routine
UCProvider =
OSDynamicCast(com_CoreSnap_driver, fProvider);
IOLog("\n UCProvider = %p\n",
UCProvider);
IOStorageCompletion
completion;
// calling driver read call by passing IOMemoryDescriptor
buffer
retRead =
UCProvider->CoreSnapDriverDoRead(this, 512, ReadBuffer, completion);
if(retRead == kIOReturnSuccess)
{
IOLog("\n CoreSnapDriverDoRead of
Driver Succeded...\n");
//return retRead;
}
}// end of prepare
}
ReadBuffer->complete();
ReadBuffer->release();
if (kIOReturnSuccess != retRead)
{
IOLog("%s[%p]::%s - returning err 0xx",
getName(), this,
__FUNCTION__, retRead);
}
fProvider->release();
return retRead;
}
/********************************Driver
Read routine ***************************/
//
kCoreDoRead
IOReturn
com_CoreSnap_driver::CoreSnapDriverDoRead(IOService* client, UInt64 byteStart,
IOMemoryDescriptor * OutBuffer, IOStorageCompletion completion)
{
IOReturn retDrRead =
kIOReturnSuccess;
IOByteCount readBytes;
IOByteCount requestByteCount = 0;
IOReturn status = 0;
IOByteCount bufLength =
OutBuffer->getLength();
char *myBuff = new char[bufLength];
readBytes =
OutBuffer->readBytes(0,
myBuff, bufLength);
IOLog("com_CoreSnap_driver::read BEFORE **** readBytes =
%lu byteStart = %lu \
bufLength = %lu buffer = %s ***\n", (long)readBytes, (long)byteStart, (long)bufLength, myBuff);
// Make "filter" changes to the buffer here.
IOLog("\n Calling read routine of driver.....\n");
getProvider()->read(client, 0, OutBuffer, completion);
IOLog("\n Called read routine of driver.....\n");
IOLog("\n Calling readbytes.......in driver\n");
readBytes =
OutBuffer->readBytes(0,
myBuff, bufLength);
IOLog("com_CoreSnap_driver::***AFTER::readBytes = %lu
byteStart = %lu bufLength = %lu buffer = %s \n", (long)readBytes, (long)byteStart, (long)bufLength,
myBuff);
IOLog("\n Calling complete routine of driver......\n");
getProvider()->complete(completion, status, requestByteCount);
IOLog("\n Called complete routine of driver......\n");
delete[] myBuff;
return retDrRead;
}
We are able to prepare() and
map() IOMemoryDescriptor successfully and pass this buffer to driver's read
routine(we also have interchange the prepare and map). My problem is while
debugging it prints all the IOLogs before driver’s standard read() method, but
IOLogs after read() does not get printed in system.logs.
Do we need to call withAddress()
and prepare() and map() the IOMemoryDescriptor before passing it to standard
read() method.
Are we following correct steps
for reading the buffer from disk and passing it to user space application?
Thanks
Imran