passing buffer from User Client to Driver
site_archiver@lists.apple.com Delivered-To: darwin-kernel@lists.apple.com Thread-index: AcVEGxoJVgfw+VMTQAqOSW9qBKV4FA== 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 (Darwin-kernel@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-kernel/site_archiver%40lists.a... This email sent to site_archiver@lists.apple.com
participants (1)
-
Imran