0
votes

I have some trouble with write IOCTL operations on my Raspberry Pi.

My driver:

static struct file_operations st7735_syahniuk_device_fops =
{
    .owner          = THIS_MODULE,
    .open           = st7735_syahniuk_device_open,
    .release        = st7735_syahniuk_device_release,
    .unlocked_ioctl = st7735_syahniuk_device_ioctl,
    .read           = st7735_syahniuk_device_read,
    .write          = st7735_syahniuk_device_write
};

static long st7735_syahniuk_device_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
...
    case ST7735_SYAHNIUK_IOCTL_READ_DISPLAY_DELAY_MS:
        printk(KERN_INFO "ST7735 IOCTL: Reading display delay\n");
        uldata = g_display.display_thread_sleep_ms;
        err = copy_to_user((void *)arg, &uldata, sizeof(uldata));
        if(err) {
            printk(KERN_ERR "ST7735 IOCTL: Error\n");
            err = -EIO;
        }
        break;

    case ST7735_SYAHNIUK_IOCTL_WRITE_DISPLAY_DELAY_MS:
        printk(KERN_INFO "ST7735 IOCTL: Writing display delay\n");
        err = copy_from_user(&uldata, (void *)arg, sizeof(uldata));
        if(err) {
            printk(KERN_ERR "ST7735 IOCTL: Error\n");
            err = -EIO;
            break;
        }
        g_display.display_thread_sleep_ms = uldata;
        break;
}

...
}

There are IOCTL commands definitions:

#define MAJIC_NUM 'k'
#define ST7735_SYAHNIUK_IOCTL_READ_DISPLAY_DELAY_MS  _IOR(MAJIC_NUM, 10, unsigned long)
#define ST7735_SYAHNIUK_IOCTL_WRITE_DISPLAY_DELAY_MS _IOW(MAJIC_NUM, 11, unsigned long)

There is test userland application:

...
    if(ioctl(fd, ST7735_SYAHNIUK_IOCTL_READ_DISPLAY_DELAY_MS, &display_delay_ms) < 0) {
        perror("Failed to read Display Delay (ms) register");
        goto finish;
    }
...
if(ioctl(fd, ST7735_SYAHNIUK_IOCTL_WRITE_DISPLAY_DELAY_MS, &display_delay_ms) < 0) {
        perror("Failed to write Display Delay (ms) register");
        goto finish;
    }

When I launch read command is working well but write command gives an error ENOTTY - Inappropriate ioctl for device.

I already tried different magic numbers but all read commands work well but write commands don't.

Addition

I checked userland application with strace and noticed something strange. When I open my device file it return me file descriptor number (for example '3'). When I call ioctl with read command strace shows me that the function is called with fd=3. But for some reason, the fd=1 is transmitted with the write command. Why it called with 1 (stdout) instead of fd of my device file?

1
Have you checked that st7735_syahniuk_device_ioctl is ever called with ST7735_SYAHNIUK_IOCTL_WRITE_DISPLAY_DELAY_MS ioctl request? - Tsyvarev
@Tsyvarev yes I checked with printk. It never called. - Yahniukov Stanislav
May I ask why you are not using upstream driver? - 0andriy

1 Answers

0
votes

The reason was that after one of the read commands, my file descriptor had a different value than when I opened the device file. Possible cause memory leak.