how to use the function copyout()
Felix-KM
Felix-KM at yandex.ru
Mon Jul 25 14:14:13 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.
So if I get it right, it's impossible in FreeBSD to gain access to 64KB of user's program memory with ioctl?
My situation is this - I have a device driver for Linux. My task is port it as it is (1:1) into FreeBSD.
In the Linux driver Ioctl is realized with the macroses _put_user _get_user all over it. As I understand in FreeBSD their analogues are functions described in store(9), copy(9) and fetch(9).
So the problem is that in my user program an array short unsigned int Data[32768] is defined. I need to gain access to the array(to each element of it) from device driver with Ioctl handler.
Is it possible to do? If yes, then how it can be done?
>
>Norbert
>_______________________________________________
>freebsd-hackers at freebsd.org mailing list
>http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>To unsubscribe, send any mail to "freebsd-hackers-unsubscribe at freebsd.org"
--
Где Яндекс.Деньги - там хорошие скидки http://money.yandex.ru/discount/
More information about the freebsd-hackers
mailing list