• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
passing buffer from User Client to Driver
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

passing buffer from User Client to Driver


  • Subject: passing buffer from User Client to Driver
  • From: "Imran" <email@hidden>
  • Date: Mon, 18 Apr 2005 19:02:44 +0530

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

  • Follow-Ups:
    • Re: passing buffer from User Client to Driver
      • From: Godfrey van der Linden <email@hidden>
  • Prev by Date: Re: Two sessions of ISO 9660
  • Next by Date: Re: Cann't make connection to a graphics IOService "IOFramebuffer"
  • Previous by thread: Re: Two sessions of ISO 9660
  • Next by thread: Re: passing buffer from User Client to Driver
  • Index(es):
    • Date
    • Thread