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