Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Jul 2005 18:14:05 +0400 (MSD)
From:      "Felix-KM" <Felix-KM@yandex.ru>
To:        NKoch@demig.de
Cc:        freebsd-hackers@freebsd.org
Subject:   RE: how to use the function copyout()
Message-ID:  <42E4F3AD.000001.28235@colgate.yandex.ru>
In-Reply-To: <000101c5911b$62441260$4801a8c0@ws-ew-3.W2KDEMIG>
References:  <000101c5911b$62441260$4801a8c0@ws-ew-3.W2KDEMIG>

next in thread | previous in thread | raw e-mail | index | archive | help
>> #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@freebsd.org mailing list
>http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
>To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"


-- 
Где Яндекс.Деньги - там хорошие скидки http://money.yandex.ru/discount/



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?42E4F3AD.000001.28235>