使用 usbfs 在 USB 设备上调用 ioctl() 不起作用

Posted

技术标签:

【中文标题】使用 usbfs 在 USB 设备上调用 ioctl() 不起作用【英文标题】:Call to ioctl() on a usb device using usbfs does not work 【发布时间】:2013-03-20 16:40:17 【问题描述】:

我现在正在尝试为我的游戏手柄创建自己的驱动程序,我发现我想要创建它的最初原因不存在,但我仍然想为体验而这样做。 所以请不要告诉我有比自己编写驱动程序更好的方法。

内核空间中应该调用ioctl函数的部分是:

static int xpad_ioctl (struct usb_interface *intf, unsigned int code,void *buf) 
    //struct usb_xpad *xpad = usb_get_intfdata(intf);
    printk(KERN_INFO"(Ongy)IOCTL called\n");

    //if (_IOC_TYPE(code) != XPAD_IOMAGIC) return -ENOTTY;
    //if (_IOC_NR(code) > XPAD_IOMAX) return -ENOTTY;
    switch(code)
        case XPAD_IORMAP:
            printk(KERN_INFO"(Ongy)IORMAP called\n");
            break;
        default:
           return -EINVAL;
    
    return 0;


static struct usb_driver xpad_driver =

    .name = "Cyborg-V5-driver",
    .probe = xpad_probe,
    .disconnect = xpad_disconnect,
    .unlocked_ioctl = xpad_ioctl,
    .id_table = xpad_table,
;

在用户空间中调用它的部分是(这是 Qt 应用程序的一部分):

int openfile() 
    char *device = "/dev/bus/usb/005/009";
    printf("Opening device %s\n", device);
    return open(device, /*O_RDONLY*/O_WRONLY | O_NONBLOCK );

[...] 这里缺少 closefile(int file_desc),this 和 openfile 函数存在是因为我不知道当 Qt 覆盖函数调用时可以调用“::open()”。

void MainContainer::callioctl() 
    int file_desc, ret_val;
    errno = 0;
    file_desc = openfile();
    if (file_desc==-1)
        printf("Ioctl notcalled because of: error %s\n", strerror(errno));
    
    else
    
        errno = 0;
        //struct usbdevfs_getdriver* driver = (usbdevfs_getdriver*)malloc(sizeof(struct usbdevfs_getdriver));
        struct mappingpair* pair = (mappingpair*)malloc(sizeof(struct mappingpair));
        ret_val = ioctl(file_desc, XPAD_IORMAP, pair);
        //printf("Drivername %s\n", driver->driver);
        closefile(file_desc);
        if (ret_val==-1) printf("Ioctl failed with error %s\n", strerror(errno));
        else printf("Ioctl call successfull\n");
    

好的,我打开文件的字符串是通过调用 lsusb 并在代码中手动更改的,这仅用于调试,直到我让 ioctl 调用正常工作

当我调用 callioctl() 时,它会打印:

Ioctl failed with error Unpassender IOCTL (I/O-Control) für das Gerät

德语部分的意思是“设备的 ioctl (I/O-Control) 错误”,dmesg 中没有出现任何内容,这就是为什么我认为驱动程序中的 ioctl 函数没有被调用。

【问题讨论】:

有人叫过xpad_probe吗? 是的,我通过为按钮分配不同的输入事件来测试我的驱动程序是否被使用,并查看我用来在 dmesg 中识别我的驱动程序的打印 【参考方案1】:

如果您查看http://www.hep.by/gnu/kernel/usb/usbfs.html,它表示要将ioctl 发送到usb_driver 设备,您需要这样做:

struct usbdevfs_ioctl 
    int     ifno;
    int     ioctl_code;
    void    *data;
;

/* user mode call looks like this.
 * 'request' becomes the driver->ioctl() 'code' parameter.
 * the size of 'param' is encoded in 'request', and that data
 * is copied to or from the driver->ioctl() 'buf' parameter.
 */
static int
usbdev_ioctl (int fd, int ifno, unsigned request, void *param)

        struct usbdevfs_ioctl   wrapper;

        wrapper.ifno = ifno;
        wrapper.ioctl_code = request;
        wrapper.data = param;

        return ioctl (fd, USBDEVFS_IOCTL, &wrapper);

文档在/proc/bus 下列出了 USB 设备,因此不可否认,这可能已经改变。

【讨论】:

以上是关于使用 usbfs 在 USB 设备上调用 ioctl() 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

virtualbox下不能分配U盘到虚拟机

将 Linux /dev/USB 作为标准文件访问以与 USB 设备通信

Ubuntu 16.04中VirtualBox 5.1使用U盘/USB设备的方法

STM32F7 发现 - USB FS 主机/设备模式检测

宿主机系统 Deepin 15.4,解决 Virtualbox 5.1 中 XP虚拟机无法使用 USB设备(如:U盘罗技优联接收器等)的问题

在 QT 中使用 libusb 检测 MAC 上的 USB 设备