3

私は今、自分のゲームパッド用の独自のドライバーを作成しようとしています。作成したかった最初の理由が存在しないことがわかりましたが、それでも経験のために作成したいと思っています。そのため、自分でドライバーを作成するよりも良い方法があるとは言わないでください。

呼び出す必要がある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) がここにありません。これと 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 関数が呼び出されていないと思います。

4

1 に答える 1

0

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);
}

ドキュメントには USB デバイスがリストされ/proc/busているため、変更されている可能性があります。

于 2014-01-27T11:01:44.340 に答える