Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 03 Sep 1997 18:35:25 -0700 (PDT)
From:      Simon Shapiro <Shimon@i-Connect.Net>
To:        Mike Smith <mike@smith.net.au>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: IOCTL Commands - Where is my mistake?
Message-ID:  <XFMail.970903183525.Shimon@i-Connect.Net>
In-Reply-To: <199709030821.RAA00286@word.smith.net.au>

next in thread | previous in thread | raw e-mail | index | archive | help
Thax for the help Mike!

Hi Mike Smith;  On 03-Sep-97 you wrote: 
> > I want to pass IOCTL commands to a driver.  This is what I do:
> > 
> >     #define DPT_IOCTL_INTERNAL_METRICS       _IOW('D', 1, dpt_perf_t)
>  
>  You want to pass a pointer to the struct, not the struct itself.

I do.  what gave you the idea I do not?

>  
> >     switch (cmd) {
> >     case DPT_IOCTL_INTERNAL_METRICS:
> >          result = copyout((char *)&dpt->performance, 
> >                          (dpt_softc_t *)(*(caddr_t *)cmdarg),
> >                          sizeof(dpt_perf_t));
>  
>  This is *hideously* bogus.  Try :
>  
>       caddr_t dest;
>  
>               /* get address in userspace */
>       dest = fuword(*(caddr_t *)cmdarg);

This is *hideously* not portable :-)  You assume an integer and a char *
are the same.  Should be dest = (caddr_t)fuword....

>               /* copy out to userspace */
>       return(copyout(&dpt->performance, dest, 
>                       sizeof(dpt->performance))
>  
>  
>  ie. cmdarg is a pointer in kernel space to a *copy* of the value
>  passed as an argument to the ioctl.

This is all fine and dandy, BUT, 
>  
>  You could also define the ioctl :
>  
> #define DPT_IOCTL_INTERNAL_METRICS    _IOR('D', 1, dpt_perf_t)
>  
>  and then in the kernel say :
>  
>       memcpy(cmdarg, &dpt->performance,
>               sizeof(dpt->performance));
>  
>  however this will perform two copies; once as you copy it to the arg
>  area, and another when the ioctl returns the copy to userspace.  This 
>  approach is somewhat discouraged from an efficiency point of view.
>  
>  You would call this as :
>  
>       ioctl(fd, DPT_IOCTL_INTERNAL_METRICS, metrics)
>  
>  ie. pass the structure, not a pointer to it.  Think of an ioctl define 
>  as being like a function prototype.

I did.  I am still getting the SAME result.  Maybe I should re-state that:

If I do:

#define DPT_IOCTL_INTERNAL_METRICS    _IOR('D', 1, dpt_perf_t)

Then copyout fails!

BUT if I do:

#define DPT_IOCTL_INTERNAL_METRICS   (IOC_INOUT | 1)

Then it WORKS.

The fact that the contents of cmd (NOT the identity of cmdarg!) changes
the outcome of copyout, coupled with the fact that your version, although
not nearly as *hideously* bogus as mine, does NOT work, coupled to the
fact that ioctl does work, leads me to belive that I am making a stupid 
mistake, but your solution is not indicating my error.

Can we try again?

Thanx!

>  
>  mike
>  
>  

---


Sincerely Yours,           (Sent on 03-Sep-97, 18:22:33 by XF-Mail)

Simon Shapiro              Atlas Telecom
Senior Architect           14355 SW Allen Blvd., Suite 130 Beaverton OR
97005
Shimon@i-Connect.Net       Voice:  503.643.5559, Emergency: 503.799.2313



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?XFMail.970903183525.Shimon>