site_archiver@lists.apple.com Delivered-To: darwin-kernel@lists.apple.com A few points, Godfrey On 04/18/2005, at 6:32 , Imran wrote: Dear All, 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); 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 }; My UserClient.cpp includes - 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; 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()); delete[] buf; return retWrite; } // 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; } 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/gvdl%40apple.com This email sent to gvdl@apple.com _______________________________________________ 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... 1> Could you change all occurrences of "MySoftwareCompany" to "spsoftindia", or something else more meaningful. The problem is that your driver will fail to load for obscure reasons in the future if you continue using a generic came like this. 2> The use of the 'v' prefix in arguments is to indicate that the input type is a void *. This is immediately cast to the appropriate type. I use this idiom to get clean, warning free compiles. I suggest changing variables like (vInStruct) to inStruct if you don't care about the void * cast. 3> You probably don't need to create a map on the memory descriptor. In fact it is better well more efficient if you don't. 4> Does the 'readBytes' call return the data that you expect to be there? Are you call in the 'synchronous' write on your provider? 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. 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; } virtual IOReturn myDoWrite(MySampleStruct *vInStruct, IOByteCount vInStructSize, MySampleStruct *vOutStruct, IOByteCount *vOutStructSize); 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)}, }; IOMemoryDescriptor *WriteBuffer = NULL; IOMemoryMap *memMap = NULL; WriteBuffer = IOMemoryDescriptor::withAddress((vm_address_t) vInStruct->buff, (IOByteCount) vInStruct->size, kIODirectionOut, fTask); 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; My Driver.cpp includes - // kMyDoWrite IOReturn com_MySoftwareCompany_driver_MyFilterScheme::DoDriverWrite (IOMemoryDescripto r * inBuffer) { IOReturn retDrWrite = kIOReturnSuccess; IOStorageCompletion completion; 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??? This email sent to site_archiver@lists.apple.com