pointer passing from devctl to resource manager

Hi all,
I need to send a pointer (which holds application local variable address) to resource manager through “devctl” call.In devctl handler function,pointer is dereferenced(*pointer done) & updated with non-zero value.But in application it is showing the value of (*p) is 0.

    someone suggested that use shared memory but it is somehow difficult to manage and other option is use "devctlv".
    
    I don't know how to use devctlv & what is the difference between devctl and devctlv. can anybody tell me how to solve this problem.

It would really help if you would post your code. Both your application code and the resource manager code (assuming you wrote the resource manager. If it’s a QNX/3rd party one we have to assume it works).

Tim

Resource manager code:

typedef struct _DevDetails
{
	unsigned int * puiversion;
}SDevDetails,*pSDevDetails;

#define MY_DEVCTL_DEVDETAILS __DIOTF(_DCMD_MISC, 1, struct _DevDetails)

int main(int argc, char **argv)   
{ 
int fd, ret, val;     
SDevDetails Sdetails;

if ((fd = open("/dev/sample0", O_RDONLY)) == -1) 
{ 
     return(1); 
}          

ret = devctl(fd, MY_DEVCTL_DEVDETAILS , &Sdetails, sizeof (Sdetails) , NULL); 
if(ret == -1)
{
	printf("devctl error\n");
	return -1;
}
printf("Version is:%d\n",*Sdetails.puiversion);		
                    
return(0); 
}

Sorry to say previously posted code is Application code not resource manager code.
Here I am posting resource manager code

int io_devctl(resmgr_context_t *ctp, io_devctl_t *msg, RESMGR_OCB_T *ocb) { 
 int nbytes, status;      
 void *data; 
 
  if ((status = iofunc_devctl_default(ctp, msg, ocb)) != _RESMGR_DEFAULT) { 
    return(status); 
   } 
  status = nbytes = 0; 
 
  data = _DEVCTL_DATA(msg->i); 
 
  switch (msg->i.dcmd) { 
      case    MY_DEVCTL_DEVDETAILS: 
					*((pSDevDetails)data)->puiversion = 2;
       break;
       
      default: 
           printf ("command unknown \n" );     
   return(ENOSYS); 
   } 
 
/* Clear the return message ... note we saved our data after this */ 
  memset(&msg->o, 0, sizeof(msg->o)); 
/* 
If you wanted to pass something different to the return 
field of the devctl() you could do it through this member. 
*/ 
  msg->o.ret_val = status; 
/* Indicate the number of bytes and return the message */ 
  msg->o.nbytes = nbytes; 
  
 return( _RESMGR_PTR(ctp, &msg->o, sizeof(msg->o) + nbytes)); 
}

It should print 2 but it is printing 0 only

I don’t know what this devctl is supposed to do but I can see the call looks pretty darn wrong.
You are passing the address of Sdetails. But Sdetails is a pointer. This might work with a monolithic kernel, but Not with QNX. Whatever address the resource manager might return to your pointer would be meaningless to the application because it wouldn’t be an address in the application’s address space.

Thanks for your reply.

–>devctl is similar to ioctl call in linux.

—>Sdetails is a structure variable not a pointer.

—>My requirement is passing a pointer and it gets updated in driver(resource manager in Qnx case). I understood that both Application & resource manager processes are different,so one process variable address not updated in another process.To fullfill my requirement is there any way.

Please tell me.

How would the resource manager know how to update the address? The address is just data, so if for example the driver just needed to increment it, it could. That is if it just needs to adjust it arithmetically it is possible. But if it is supposed to re-point it at some other place in memory in the applications address space, how does it know how to do this without access to that address space?

Note that puiversion is defined as a pointer, not an integer.

Here in your resource manager you are assigning a value to it as if it’s an integer.

As Maschoen already mentioned, there is no way for the resource manager to write to pointer data within a structure. Your SDevDetails structure can’t contain pointers.

Try changing puiversion to an integer.

Tim

Thanks to tim & maschoen.
I will change “puiversion” variable to integer data type.I have another problem,it’s somewhat silly but i didn’t find the solution.
–>Actually In my resource manager i created thread pool( by using “thread_pool_create”) i.e it will cretae pool of threads,initially it will block and waiting for client request after receiving request thread is unblocked and process the request and once again it go to blocked state.
–>My resource manager executable name is “Sample_Drv”,application executable name is “Sample_App”.
–>In one terminal i executed driver “./Sample_Drv” (till application not executed).
–>In another terminal i opened “/dev” folder and given “ls -l” command.
–>Suddenly “Open handler”(resmgr_connect_funcs_t.open = Sample_Open) function got executing i.e “Sample_Open” and all prints in that function are displaying.
It’s very shocking to me because in application i am calling “open”,there is no request coming from application.
–>Still open handler is calling.

Please give me the solution.

Let’s start with some vocabulary. The QNX file system doesn’t have folders, it has directories. You can call them folders if you like. You do not open directories. Well not from a terminal. You can cd to a directory, or you can read the directory with ls. Actually ls will open the directory using opendir(). If you ls /dev is will need to contact your resource manager when it gets to your name space under /dev. This is normal.

What are you trying to open() in your application? What name space did you attach to your resource manager? If you do not see any activity in your resource manager, the name you use might be the problem.

Thanks to maschoen.

–>I opened “/dev” folder by giving cd and after with “ls” i am checking devices.

–>I didn’t understand one of your sentence listed below

" If you ls /dev is will need to contact your resource manager when it gets to your name space under /dev. This is normal."

Please give some details about the mentioned statement.

What you may think of as the file system, things like “/” for the root directory, and “/dev” the directory where devices names usually go is part of what QNX calls the “Name Space”.

Resource managers when they start up claim a piece of the name space. For example the disk driver for the file system mounted at “/” claims “/”. The serial driver will claim “/dev/ser”.

When an application does an open() call, the kernel looks at the name of what is being opened and knows which resource manager is responsible for that piece of name space so it redirects the open() call message to that resource manager’s process.

So when you do an ls on /dev/some-device, ls does a opendir() call which calls open() on “/dev/some-device”. The open call becomes an open message to the resource manager responsible for that name space. The resource manager receives that message and processes it, and replies. The application gets an fd. Thereafter all I/O calls, eg read() write() devctl() to that fd become messages that go directly to the resource manager.

Since you are writing a resource manager, you see these messages being received in your resource manager. In previous versions of QNX you had to support every such I/O message. With QNX 6 there are default message handlers, so you only need to write handlers for messages you support.

This structure is equivalent to what a monolithic kernel does, but it works very differently. If you are going to write a resource manager for QNX you need to understand this structure. QNX provides a manual/document that describes this.

Thanks to maschoen for reply