Project Home
Project Home
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - ioctl operations: (9 Items)
   
ioctl operations  
Hi,

 I m using application to read data from driver.

myapp.c
=====

char buf[10];
struct ifreq ifr;
s = socket();
strcpy(ifr.ifr_name,"sam0");
ifr.ifr_data = &buf;

ioctl(s,MY_CMD,&ifr);

printf(" [%s]\n",buf);

----

my driver
=====
sam_ioctl(ifp,cmd,caddr_t data)
{
    struct ifreq *ifr;
    ifr = (ifreq*)data;

case MY_CMD:
   memcpy(data,"driver",5);
   break;

  return 0;

}

But i m not able to update the buffer value from driver to applicatio.
How can i do that..
please help on this.

Thanks and Regards
K.Senthil



 

Re: ioctl operations  
On Fri, Oct 30, 2009 at 10:11:49AM -0400, Senthil K wrote:
> Hi,
> 
>  I m using application to read data from driver.
> 
> myapp.c
> =====
> 
> char buf[10];
> struct ifreq ifr;
> s = socket();
> strcpy(ifr.ifr_name,"sam0");
> ifr.ifr_data = &buf;
> 
> ioctl(s,MY_CMD,&ifr);
> 
> printf(" [%s]\n",buf);
> 
> ----
> 
> my driver
> =====
> sam_ioctl(ifp,cmd,caddr_t data)
> {
>     struct ifreq *ifr;
>     ifr = (ifreq*)data;
> 
> case MY_CMD:
>    memcpy(data,"driver",5);
>    break;
> 
>   return 0;
> 
> }
> 
> But i m not able to update the buffer value from driver to applicatio.
> How can i do that..
> please help on this.
> 

Check out lib/socket/ioctlsocket.c for examples on
how to pass ioctls with embedded pointers in them.

-seanb
Re: ioctl operations  
Hi Sean,

i reffered that file.they using SETIOV waht it will do.

i used the copyin and copyout it  also not working.
my version QNX 6.4.1

Thanks and Regards
K.Senthil
Re: ioctl operations  
Try ioctl_socket() and you've also got to put your response in 
ifr.ifr_data not directly in ifr.
/P
Re: ioctl operations  
To be clear, like Sean pointed out, you've got to make sure your 
embedded pointer is packaged right in the message - see ioctl_socket() 
implementation how to do that. Remember, the ifr_data is a pointer in 
myapp's address space, but the stack operates in a different address space.

/P
Re: ioctl operations  
Hi,

i refered ioctl_socket functio n in which they using SETIOV function.
But that also not working for me.

Any permission i want to want to enable for copying data from network driver to application.

Thanks and Regards
K.Senthil
RE: ioctl operations  
> copying data from network driver to application

http://en.wikipedia.org/wiki/Virtual_address_space

In QNX, copying data between separate processes is 
usually performed with the message-passing kernel calls.  

In your case, to copy data from a server's virtual 
address space to a client's virtual address space, you 
would probably want to use:

http://www.qnx.com/developers/docs/6.3.2/neutrino/lib_ref/m/msgwrite.htm
l


--
aboyd
Re: RE: ioctl operations  
Hi,

How to copy the data using ioctl function.

In the ioctl function they updating the buf in ifr->ifr_data pointer and get the data via the same.

Thanks and Regards
K.Senthil
Re: ioctl operations  
Hi,

> How to copy the data using ioctl function.
You can't.

Because you use #define MY_CMD _IOWR('i',1,struct ifreq) the ioctl API 
will copy sizeof(struct ifreq) bytes from the data pointer in the app to 
the stack. Once in your driver code, it has only the struct ifreq. The 
data which ifr_data points to needs to also be copied to the stack.

You can do this by using MsgSend APIs like ioctl_socket() does. This 
will mean that inside your driver code, the data pointer points to a 
block of memory which first has the struct ifreq and directly after 
follows whatever ifr_data pointed to.

As you see, ioctl_socket() will use IOVs and MsgSendv(). It does so 
because the ifr and the ifr_data pointers are scattered so IOVs are 
convenient. It puts the data pointer of sizeof(struct ifreq) in the 
first IOV, and puts the ifr_data pointer and its length, which depends 
on what type of ioctl command is being processed, in the second IOV. 
E.g. in the case of SIOCGETVLAN ifr_data points to a struct vlanreq and 
so the size of the second IOV is sizeof(struct vlanreq).

In the MsgSendv() API, the two IOVs gets copied and "gathered" so that 
they are linear (one after the other) when they arrive at the stack. 
Following the example of SIOCGETVLAN, it means data points to a place in 
memory where there is first a struct ifreq AND a struct vlanreq follows 
right after it.

In your code you have a string in ifr_data. You've therefore got to 
change your app to use MsgSend like ioctl_socket() does and put the 
length of the string in the second IOV.

The only alternative is to change your app code to always pass a 
concatenated ifr and ifr_data buffer to ioctl() and change the define of 
MY_CMD to use a type which represent that concatenation, but that's not 
advisable and really not customary.

In addition, as I pointed out earlier, there is a bug in your driver 
code here:
 > memcpy(data,"driver",5);
You're copying "driver" straight into data, ie. into where the struct 
ifreq is, not where the ifr_data is. And the length of the copy is wrong.

You want to copy into the place where ifr_data is:
 > memcpy(ifr+1,"driver",strlen("driver") + 1);

Hope this helps!
/P