• 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
Re: passing buffer from User Client to Driver
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: passing buffer from User Client to Driver


  • Subject: Re: passing buffer from User Client to Driver
  • From: Godfrey van der Linden <email@hidden>
  • Date: Mon, 18 Apr 2005 10:55:38 -0700

A few points,

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?

Godfrey

On 04/18/2005, at 6:32 , Imran wrote:

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


_______________________________________________ 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: "Imran" <email@hidden>
References: 
 >passing buffer from User Client to Driver (From: "Imran" <email@hidden>)

  • Prev by Date: Re: Two sessions of ISO 9660
  • Next by Date: Re: xnu-517.12.7
  • Previous by thread: passing buffer from User Client to Driver
  • Next by thread: RE: passing buffer from User Client to Driver
  • Index(es):
    • Date
    • Thread