def METHOD_NAME(self, fd, request, p_arg):
    self.init()
    p_arg = ctypes.c_void_p(p_arg)
    if request not in self.ioctl_map:
        self.log(f"Unknown ioctl: fd={fd} request={IOCTL(request)} arg={p_arg:#x}")
        return -errno.ENOSYS
    METHOD_NAME, f = self.ioctl_map[request]
    size = METHOD_NAME.SIZE
    if METHOD_NAME.DIR & _IOC_WRITE:
        args = f._arg_cls.parse(self.read_buf(p_arg, size))
        ret = f(fd, args)
    elif METHOD_NAME.DIR & _IOC_READ:
        args = f._arg_cls.parse(bytes(size))
        ret = f(fd, args)
    else:
        ret = f(fd)
    if METHOD_NAME.DIR & _IOC_READ:
        data = args.build()
        assert len(data) == size
        ctypes.memmove(p_arg, data, size)
    sys.stdout.flush()
    return ret