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>