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 ecartis@xxxxxxxxxxxx Please read the FAQ at http://kernelnewbies.org/FAQ