Dear All,
I got success in all the function required to call for passing
buffer from
User Application to Driver through User Client.
I have use IOMemoryDescriptor for mapping the user space buffer in
kernel
address space.
Still my problem is I am not able to get the buffer in the driver
though I
am able to pass it from user application to User Client successfully.
My code snippet is as follows:
My UserKernelShared.h contains following structure -
typedef struct MySampleStruct
{
UInt32 size;
char buff [kBufSize];
} MySampleStruct;
// these are the User Client method names
enum
{
kMyUserClientOpen,
kMyUserClientClose,
kMyDoWrite,
kMyDoRead
kMyDoReadWrite,
kMyNumberOfMethods
};
My UserSpace.c includes following call -
In main()
{
kernResult = MyDoWrite(dataPort); /*declaration*/
if (kernResult != KERN_SUCCESS)
{
printf("\n kMyDoWrite returned %d\n", kernResult);
fflush(stdout);
}
}
/*Definition for MyDoWrite() in userspace application*/
static kern_return_t
MyDoWrite(io_connect_t connect)
{
kern_return_t kernResult;
MySampleStruct sampleStructIn;
MySampleStruct sampleStructOut;
strcpy(sampleStructIn.buff,"MACOSX Write Call");
UInt32 size;
size = kBufSize;
sampleStructIn.size = size;
IOByteCount structSizeIn = sizeof(MySampleStruct);
IOByteCount structSizeOut = sizeof(MySampleStruct);
if (!connect) {
printf("\n Unable to make connection in MyDoWrite of userspace
app.....\n");
return kIOReturnNoDevice;
}
else {
kernResult = IOConnectMethodStructureIStructureO(connect,
kMyDoWrite,
structSizeIn, &structSizeOut,
&sampleStructIn, &sampleStructOut);
}
if(kernResult == kIOReturnSuccess){
printf("\n kMyDoWrite was successful..........\n");
}
return kernResult;
}
My UserClient.h includes -
class com_MySoftwareCompany_MyUserClient : public IOUserClient
{
OSDeclareDefaultStructors(com_MySoftwareCompany_MyUserClient)
protected:
IOService* fProvider;
com_MySoftwareCompany_driver_MyFilterScheme* UCProvider;
task_t fTask;
bool fDead;
public:
//Note - Also includes all IOUserClient Methods
virtual IOReturn myDoWrite(MySampleStruct *vInStruct, IOByteCount
vInStructSize, MySampleStruct *vOutStruct, IOByteCount
*vOutStructSize);
};
My UserClient.cpp includes -
IOExternalMethod *
com_MySoftwareCompany_MyUserClient::getTargetAndMethodForIndex
(IOService **
target, UInt32 index)
{
static const IOExternalMethod sMethods[kMyNumberOfMethods] =
{
{ // kMyDoWrite
NULL, IOMethod)
&com_MySoftwareCompany_MyUserClient::myDoWrite,
kIOUCStructIStructO,
sizeof(MySampleStruct), sizeof(MySampleStruct)},
};
if (index < (UInt32)kMyNumberOfMethods)
{
if(index == kMyUserClientOpen || index == kMyUserClientClose ||
index == kMyDoWrite){
*target = this;
}
else {
*target = UCProvider;
}
return (IOExternalMethod *) &sMethods[index];
}
return NULL;
}
IOReturn com_MySoftwareCompany_MyUserClient::myDoWrite(MySampleStruct
*vInStruct, IOByteCount vInStructSize, MySampleStruct *vOutStruct,
IOByteCount * vOutStructSize)
{
IOReturn retWrite = kIOReturnSuccess;
char* buf = new char[kBufSize];
UInt32 Size;
buf = vInStruct->buff;
Size = vInStruct->size;
IOMemoryDescriptor *WriteBuffer = NULL;
IOMemoryMap *memMap = NULL;
WriteBuffer = IOMemoryDescriptor::withAddress((vm_address_t)
vInStruct->buff, (IOByteCount) vInStruct->size, kIODirectionOut,
fTask);
IOByteCount bufLength = WriteBuffer->getLength();
if (!WriteBuffer){
return kIOReturnNoMemory;
}
else {
// wire it and make sure we can read it
retWrite = WriteBuffer->prepare();
if(retWrite == kIOReturnSuccess) {
memMap = WriteBuffer->map();
if(!memMap) {
return kIOReturnNoMemory;
}
else {
void* pData = (void*)(memMap->getVirtualAddress());
if(pData == NULL) {
return kIOReturnError;
}
else {
UCProvider =
OSDynamicCast(com_MySoftwareCompany_driver_MyFilterScheme, fProvider);
retWrite =
UCProvider->DoDriverWrite(WriteBuffer); // Calling Driver
DoDriverWrite
Routine
}
}
}
memMap->unmap();
memMap->release();
WriteBuffer->complete();
WriteBuffer->release();
WriteBuffer = NULL;
delete[] buf;
return retWrite;
}
My Driver.cpp includes -
// kMyDoWrite
IOReturn
com_MySoftwareCompany_driver_MyFilterScheme::DoDriverWrite
(IOMemoryDescripto
r * inBuffer)
{
IOReturn retDrWrite = kIOReturnSuccess;
IOStorageCompletion completion;
// If the user client's 'open' method was never called, return
kIOReturnNotOpen.
if (!isOpen()) {
return kIOReturnNotOpen;
}
else {
IOLog("\n Userclient is open for the driver....\n");
}
IOByteCount readBytes;
UInt64 byteStart = 0;
IOByteCount bufLength = inBuffer->getLength();
IOLog("\n bufLength = %lu\n", bufLength);
char myBuff[512];
readBytes = inBuffer->readBytes(0, myBuff, bufLength);
getProvider()->write(this, 512,inBuffer, completion);
return retDrWrite;
}
The problem I am facing is that all my IOMemoryDescriptor calls
such as
prepare(), map(), complete() are getting succeeded but the
WriteBuffer which
is a IOMemoryDescriptor pointer I am passing to the DoDriverWrite()
driver
routine
is not getting passed from userclient to driver.
When I print the IOMemoryDescriptor addresses in userclient and
driver it
gives me the same address but when I print the buffer in driver it
shows
nothing but the blank.
Is there anything I am missing for mapping the user space buffer in
kernel
address space???
Thanks
Imran
_______________________________________________
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