how to use the function copyout()

Norbert Koch NKoch at demig.de
Mon Jul 25 13:21:43 GMT 2005


> #define IOCTL_GET_B    _IOWR("F", 127, 0x4)

I think the third parameter to _IOWR should directly specify a type,
e.g. _IOWR("F", 127, int) or _IOWR("F", 127, struct MyStruct).

> 
> ---- driver ----
> 
> struct my_softc {
>  ...
>  short unsigned int B;
> };
> 
> ...
> 
> static int
> my_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
>                                                struct thread *td)
> {
>  struct my_softc *my_sc;
>  int unit, error;
>  unit = minor(dev);
>       my_sc = (struct my_softc *)devclass_get_softc(my_devclass, unit);
>  if (my_sc == NULL)
>    return (ENXIO);
>     switch(cmd)
>  {
>    ...
>    case IOCTL_GET_B:
>      error = copyout(&my_sc->B, data, sizeof(my_sc->B));
>      switch (error)
>      {
>    case 0:
>      printf(" IOCTL_GET_B: %d\n", my_sc->B);
>      break;
>    case EFAULT:
>      printf("EFAULT\n");
>      break;
>    case EIO:
>      printf("EIO\n");
>      break;
>    case ENOMEM:
>      printf("ENOMEM\n");
>      break;
>        case ENOSPC:
>      printf("ENOSPC\n");
>      break;
>      }
>      break;
>       default:
>      break;
>  }
>     return 0;
> }
> 
> ---user program ----------------------
> 
> ...
> 
> short unsigned int Data[32768];
> 
> int
> main(int argc, char *argv[])
> {     ...
> 
>  if (ioctl(fd0, IOCTL_GET_B, Data) == -1)
>    err(1, "IOCTL_GET_B");
> 
>  ...
> }
> 
> -------
> 
> Here I get EFAULT.
> 
> What have I done wrong? How can I do it correctly?

The caddr_t data in your ioctl is already mapped into kernel
memory. Look into the source of other device drivers. You'll
find a lot of *(int *) data = ...
So your copyout() has to fail because it tries to address
memory which is not a part of your application's
memory.
>From errno(2): EFAULT: Bad address...

I have no idea if it is possible for ioctls to have mapped more
than a few 100 bytes for data exchange.
You should use read and uiomove() instead.

Norbert


More information about the freebsd-hackers mailing list