RE: how to use the function copyout()

From: Norbert Koch (NKoch_at_demig.de)
Date: 07/25/05

  • Next message: Felix-KM: "RE: how to use the function copyout()"
    To: <Felix-KM@yandex.ru>, <freebsd-hackers@freebsd.org>
    Date: Mon, 25 Jul 2005 15:18:44 +0200
    
    

    > #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
    _______________________________________________
    freebsd-hackers@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
    To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"


  • Next message: Felix-KM: "RE: how to use the function copyout()"

    Relevant Pages