Hi,
I`ve written some ioctl`s to my simple char device. I created inside
the device some number called "secretTreasure" and programs using
ioctl function would set and get this number (manipulate it). So i
have two ioctl commands: IO_SET_TREASURE and IO_GET_TREASURE. First
one works very well, but second has some bugs. In my "demo
application" I just want to get this treasure to some output value not
as return value from function. This way works as well but I can`t
manage with output values. Here is the source code. At the beginning
my "first.h" file:

#ifndef FIRST_H
#define FIRST_H

/* header`s files */
#include <linux/ioctl.h>

/* some constants for my device drivers */
#define    FIRST_MAJOR    250
#define    FIRST_MAGIC    'E'
#define    DEV_LICENSE    "GPL"
#define    SUCCESS        0
#define    DEVICE_NAME    "MyFirstDevice"
#define    BUF_LEN        128

/* there is, our ioctls */
#define IO_SET_TREASURE _IOW(FIRST_MAGIC, 0, unsigned long)
#define IO_GET_TREASURE _IOR(FIRST_MAGIC, 1, unsigned long)

/* and name of device */
#define DEVICE_FILE_NAME        "MyFirstDevice"
#endif

I think whole *.c file with code of device driver will be too big and
unnecessary, so I will paste only ioctl function:
static int      FirstModule_Ioctl(struct inode* inode, struct file* file,
unsigned int number, unsigned long param)
{
 int   err = 0;
        
        /* checking numbes to decode */
        if (_IOC_TYPE(number) != FIRST_MAGIC) return -ENOTTY;
        if (_IOC_NR(number) > 2) return -ENOTTY;

        /* checking access mode */
        if (_IOC_DIR(number) & _IOC_READ)
                err = !access_ok(VERIFY_WRITE, (void __user *)param, 
_IOC_SIZE(number));
        else if (_IOC_DIR(number) & _IOC_WRITE)
                err = !access_ok(VERIFY_READ, (void __user *)param, 
_IOC_SIZE(number));
        if (err)
                return -EFAULT;

        switch(number){
          case IO_SET_TREASURE:
                secretTreasure = param;
                printk(KERN_INFO "New Secret Treasure has been set up as: %d\n",
secretTreasure);
                break;

          case IO_GET_TREASURE:
                put_user(secretTreasure, (unsigned long *)param);
                printk(KERN_INFO "Secret Treasure is: %d\n and param is: %d",
secretTreasure, param);
                //return secretTreasure;
                break;
        }
        return SUCCESS;
}
As You can see I commented "return secretTreasure". It works but i
don`t want solve my trouble in that way. Return value must be for
error-checking not for secret number. I was trying to use some
put_user() macro. Of course it didn`t help me. Here is my demo
program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include "first.h"

void ioctl_set_trs(int fd, unsigned long new_number)
{
        int ret;
        if((ret = ioctl(fd, IO_SET_TREASURE, new_number)) < 0)
        {
                printf("IOCTL (set_trs) failed: %d\n", ret);
                perror("ioctl");
                exit(-1);
        }
}

void ioctl_get_trs(int fd)
{
 int ret;
 unsigned treasure;

        if( (ret = ioctl(fd, IO_GET_TREASURE, treasure)) < 0)
        {
                printf("IOCTL failed: %d\n", ret);
                perror("ioctl");
                exit(-1);
        }
        printf("Here is secret number for You: %d and ret: %d\n", treasure,ret);
}
int main()
{
        int fd, ret;
        unsigned long new_treasure = 47;

        fd = open("/dev/MyFirstDevice",0);
        if(fd < 0){
                printf("I can`t open %s\n", DEVICE_FILE_NAME);
                perror("open");
                exit(-1);
        }
        ioctl_set_trs(fd, new_treasure);
        ioctl_get_trs(fd);
        return 0;
}
When i fire up this application I can see this message: <<Here is
secret number for You: 0 and ret: 0>> Of course ret == 0 but why does
my param value equal to zero ? When i look at dmesg output there is
something like this:
"New Secret Treasure has been set up as: 47
Secret Treasure is: 47"
And this comes from IO_GET_TREASURE, so everything in kernel mode is
set properly but not in userspace. Thanks for any help
-- 
-----BEGIN GEEK CODE BLOCK-----
GCS d- s:- a--- C+++ P L+++>+++++ E---- W+ N+ o? K- w--- O- M- V? PS++
PE++ Y PGP++ t--- 5? X R tv-- b+ DI+ D- G++ e- h! !r(--) !z+
------END GEEK CODE BLOCK------

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to [EMAIL PROTECTED]
Please read the FAQ at http://kernelnewbies.org/FAQ

Reply via email to