626 lines
18 KiB
C
626 lines
18 KiB
C
/*
|
|
* \brief USB HID driver Linux emulation environment
|
|
* \author Stefan Kalkowski
|
|
* \date 2018-06-13
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2018 Genode Labs GmbH
|
|
*
|
|
* This file is distributed under the terms of the GNU General Public License
|
|
* version 2.
|
|
*/
|
|
|
|
#ifndef _SRC__DRIVERS__USB_HID__LX_EMUL_H_
|
|
#define _SRC__DRIVERS__USB_HID__LX_EMUL_H_
|
|
|
|
#include <base/fixed_stdint.h>
|
|
#include <stdarg.h>
|
|
|
|
#include <lx_emul/extern_c_begin.h>
|
|
|
|
#include <lx_emul/compiler.h>
|
|
#include <lx_emul/printf.h>
|
|
#include <lx_emul/types.h>
|
|
#include <lx_emul/kernel.h>
|
|
|
|
enum { HZ = 100UL };
|
|
|
|
#include <lx_emul/jiffies.h>
|
|
#include <lx_emul/time.h>
|
|
#include <lx_emul/bitops.h>
|
|
|
|
typedef int clockid_t;
|
|
|
|
#include <lx_emul/timer.h>
|
|
#include <lx_emul/spinlock.h>
|
|
#include <lx_emul/mutex.h>
|
|
|
|
typedef __u16 __le16;
|
|
typedef __u32 __le32;
|
|
typedef __u64 __le64;
|
|
typedef __u64 __be64;
|
|
|
|
#include <lx_emul/byteorder.h>
|
|
#include <lx_emul/atomic.h>
|
|
#include <lx_emul/work.h>
|
|
#include <lx_emul/bug.h>
|
|
#include <lx_emul/errno.h>
|
|
#include <lx_emul/module.h>
|
|
#include <lx_emul/gfp.h>
|
|
|
|
static inline void barrier() { asm volatile ("": : :"memory"); }
|
|
|
|
#define READ_ONCE(x) x
|
|
|
|
#include <lx_emul/list.h>
|
|
#include <lx_emul/string.h>
|
|
#include <lx_emul/kobject.h>
|
|
#include <lx_emul/completion.h>
|
|
|
|
struct file
|
|
{
|
|
unsigned int f_flags;
|
|
void * private_data;
|
|
};
|
|
|
|
struct device;
|
|
|
|
typedef unsigned long kernel_ulong_t;
|
|
typedef struct { __u8 b[16]; } uuid_le;
|
|
|
|
struct device * get_device(struct device *dev);
|
|
void put_device(struct device *);
|
|
void * dev_get_drvdata(const struct device *dev);
|
|
int dev_set_drvdata(struct device *dev, void *data);
|
|
|
|
#define dev_info(dev, format, arg...) lx_printf("dev_info: " format , ## arg)
|
|
#define dev_warn(dev, format, arg...) lx_printf("dev_warn: " format , ## arg)
|
|
#define dev_err( dev, format, arg...) lx_printf("dev_err: " format , ## arg)
|
|
#define dev_dbg( dev, format, arg...)
|
|
|
|
#define pr_info(fmt, ...) printk(KERN_INFO fmt, ##__VA_ARGS__)
|
|
#define pr_err(fmt, ...) printk(KERN_ERR fmt, ##__VA_ARGS__)
|
|
#define pr_warn(fmt, ...) printk(KERN_WARN fmt, ##__VA_ARGS__)
|
|
|
|
struct semaphore {};
|
|
|
|
struct device_driver
|
|
{
|
|
char const *name;
|
|
struct bus_type *bus;
|
|
struct module *owner;
|
|
const char *mod_name;
|
|
};
|
|
|
|
typedef int devt;
|
|
|
|
struct class
|
|
{
|
|
const char *name;
|
|
char *(*devnode)(struct device *dev, mode_t *mode);
|
|
};
|
|
|
|
struct device
|
|
{
|
|
char const * name;
|
|
struct device * parent;
|
|
struct kobject * kobj;
|
|
struct device_driver * driver;
|
|
struct bus_type * bus;
|
|
dev_t devt;
|
|
struct class * class;
|
|
const struct device_type * type;
|
|
void (*release)(struct device *dev);
|
|
void * driver_data;
|
|
};
|
|
|
|
void down(struct semaphore *sem);
|
|
void up(struct semaphore *sem);
|
|
|
|
#define module_driver(__driver, __register, __unregister, ...) \
|
|
static int __init __driver##_init(void) \
|
|
{ \
|
|
return __register(&(__driver) , ##__VA_ARGS__); \
|
|
} \
|
|
module_init(__driver##_init); \
|
|
static void __exit __driver##_exit(void) \
|
|
{ \
|
|
__unregister(&(__driver) , ##__VA_ARGS__); \
|
|
} \
|
|
module_exit(__driver##_exit);
|
|
|
|
void device_lock(struct device *dev);
|
|
void device_release_driver(struct device *dev);
|
|
|
|
#define KBUILD_MODNAME ""
|
|
|
|
struct attribute
|
|
{
|
|
const char * name;
|
|
mode_t mode;
|
|
};
|
|
|
|
struct device_attribute {
|
|
struct attribute attr;
|
|
ssize_t (*show)(struct device *dev, struct device_attribute *attr,
|
|
char *buf);
|
|
ssize_t (*store)(struct device *dev, struct device_attribute *attr,
|
|
const char *buf, size_t count);
|
|
};
|
|
|
|
#define __ATTR(_name,_mode,_show,_store) { \
|
|
.attr = {.name = #_name, .mode = _mode }, \
|
|
.show = _show, \
|
|
.store = _store, \
|
|
}
|
|
|
|
#define DEVICE_ATTR(_name, _mode, _show, _store) \
|
|
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
|
|
|
|
int sprintf(char *buf, const char *fmt, ...);
|
|
int kstrtoul(const char *s, unsigned int base, unsigned long *res);
|
|
|
|
void device_unlock(struct device *dev);
|
|
|
|
struct kobj_uevent_env;
|
|
|
|
struct bus_type {
|
|
const char * name;
|
|
const struct attribute_group **dev_groups;
|
|
const struct attribute_group **drv_groups;
|
|
int (*match)(struct device *dev, struct device_driver *drv);
|
|
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
|
|
int (*probe)(struct device *dev);
|
|
int (*remove)(struct device *dev);
|
|
};
|
|
|
|
int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data, int (*fn)(struct device *dev, void *data));
|
|
int bus_for_each_drv(struct bus_type *bus, struct device_driver *start, void *data, int (*fn)(struct device_driver *, void *));
|
|
int driver_attach(struct device_driver *drv);
|
|
|
|
struct file_operations;
|
|
struct cdev { const struct file_operations * ops; };
|
|
|
|
typedef __s64 time64_t;
|
|
|
|
struct timespec64 {
|
|
time64_t tv_sec; /* seconds */
|
|
long tv_nsec; /* nanoseconds */
|
|
};
|
|
|
|
struct timespec64 ktime_to_timespec64(const s64 nsec);
|
|
|
|
enum {
|
|
S_IWGRP = 20,
|
|
S_IRGRP = 40,
|
|
S_IRUGO = 444,
|
|
S_IWUSR = 200,
|
|
S_IRUSR = 400,
|
|
};
|
|
|
|
struct attribute_group
|
|
{
|
|
const char *name;
|
|
struct attribute **attrs;
|
|
struct bin_attribute **bin_attrs;
|
|
};
|
|
|
|
void kfree(const void *);
|
|
unsigned int jiffies_to_usecs(const unsigned long j);
|
|
void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp);
|
|
size_t strlen(const char *s);
|
|
|
|
#define from_timer(var, callback_timer, timer_fieldname) \
|
|
container_of(callback_timer, typeof(*var), timer_fieldname)
|
|
|
|
int sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp);
|
|
void sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp);
|
|
static inline void devm_kfree(struct device *dev, void *p) {}
|
|
|
|
#define module_param_array_named(name, array, type, nump, perm)
|
|
|
|
void *kmalloc(size_t size, gfp_t flags);
|
|
void *kzalloc(size_t size, gfp_t flags);
|
|
void *kcalloc(size_t n, size_t size, gfp_t flags);
|
|
|
|
int snprintf(char *buf, size_t size, const char *fmt, ...);
|
|
const char *dev_name(const struct device *dev);
|
|
u16 get_unaligned_le16(const void *p);
|
|
u32 get_unaligned_le32(const void *p);
|
|
|
|
void *vzalloc(unsigned long size);
|
|
void vfree(void *addr);
|
|
|
|
struct pm_message {};
|
|
typedef struct pm_message pm_message_t;
|
|
|
|
struct task_struct
|
|
{
|
|
char comm[16];
|
|
};
|
|
|
|
extern struct task_struct *current;
|
|
|
|
struct completion
|
|
{
|
|
unsigned int done;
|
|
void * task;
|
|
};
|
|
|
|
long __wait_completion(struct completion *work, unsigned long timeout);
|
|
|
|
struct notifier_block;
|
|
|
|
enum {
|
|
EPOLLIN = 0x00000001,
|
|
EPOLLOUT = 0x00000004,
|
|
EPOLLERR = 0x00000008,
|
|
EPOLLHUP = 0x00000010,
|
|
EPOLLRDNORM = 0x00000040,
|
|
EPOLLWRNORM = 0x00000100,
|
|
EPOLLRDHUP = 0x00002000,
|
|
ESHUTDOWN = 58,
|
|
};
|
|
|
|
enum led_brightness { LED_OFF = 0, LED_FULL = 255 };
|
|
|
|
struct led_classdev
|
|
{
|
|
const char * name;
|
|
enum led_brightness max_brightness;
|
|
int flags;
|
|
void (*brightness_set)(struct led_classdev *led_cdev,
|
|
enum led_brightness brightness);
|
|
int (*brightness_set_blocking)(struct led_classdev *led_cdev,
|
|
enum led_brightness brightness);
|
|
enum led_brightness (*brightness_get)(struct led_classdev *led_cdev);
|
|
const char *default_trigger;
|
|
struct led_trigger *trigger;
|
|
};
|
|
|
|
struct led_trigger
|
|
{
|
|
const char * name;
|
|
};
|
|
|
|
int sscanf(const char *, const char *, ...);
|
|
|
|
#define hid_dump_input(a,b,c) do { } while (0)
|
|
#define hid_dump_report(a, b, c, d) do { } while (0)
|
|
#define hid_debug_register(a, b) do { } while (0)
|
|
#define hid_debug_unregister(a) do { } while (0)
|
|
#define hid_debug_init() do { } while (0)
|
|
#define hid_debug_exit() do { } while (0)
|
|
|
|
struct hid_device;
|
|
|
|
static inline int hidraw_report_event(struct hid_device *hid, u8 *data, int len) { return 0; }
|
|
|
|
int down_trylock(struct semaphore *sem);
|
|
|
|
struct bin_attribute {
|
|
struct attribute attr;
|
|
size_t size;
|
|
ssize_t (*read)(struct file *, struct kobject *,
|
|
struct bin_attribute *, char *, loff_t, size_t);
|
|
};
|
|
|
|
struct device *kobj_to_dev(struct kobject *kobj);
|
|
|
|
static inline int hidraw_connect(struct hid_device *hid) { return -1; }
|
|
static inline void hidraw_disconnect(struct hid_device *hid) { }
|
|
|
|
struct hidraw { u32 minor; };
|
|
|
|
int device_create_file(struct device *device, const struct device_attribute *entry);
|
|
void device_remove_file(struct device *dev, const struct device_attribute *attr);
|
|
|
|
int mutex_lock_killable(struct mutex *lock);
|
|
|
|
struct driver_attribute {
|
|
struct attribute attr;
|
|
};
|
|
|
|
#define DRIVER_ATTR_WO(_name) \
|
|
struct driver_attribute driver_attr_##_name = { .attr = { .name = NULL } }
|
|
|
|
void msleep(unsigned int);
|
|
|
|
long find_next_zero_bit_le(const void *addr, unsigned long size, unsigned long offset);
|
|
|
|
int sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp);
|
|
|
|
int down_interruptible(struct semaphore *sem);
|
|
|
|
int scnprintf(char *buf, size_t size, const char *fmt, ...);
|
|
|
|
enum { PAGE_SIZE = 4096, };
|
|
|
|
#define __ATTRIBUTE_GROUPS(_name) \
|
|
static const struct attribute_group *_name##_groups[] = { \
|
|
&_name##_group, \
|
|
NULL, \
|
|
}
|
|
|
|
#define ATTRIBUTE_GROUPS(_name) \
|
|
static const struct attribute_group _name##_group = { \
|
|
.attrs = _name##_attrs, \
|
|
}; \
|
|
__ATTRIBUTE_GROUPS(_name)
|
|
|
|
#define DEVICE_ATTR_RO(_name) \
|
|
struct device_attribute dev_attr_##_name = { .attr = { .name = NULL } }
|
|
|
|
struct kobj_uevent_env;
|
|
|
|
int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...);
|
|
|
|
int dev_set_name(struct device *dev, const char *name, ...);
|
|
int device_add(struct device *dev);
|
|
|
|
void device_initialize(struct device *dev);
|
|
|
|
void device_enable_async_suspend(struct device *dev);
|
|
|
|
void device_del(struct device *dev);
|
|
|
|
void sema_init(struct semaphore *sem, int val);
|
|
|
|
int driver_register(struct device_driver *drv);
|
|
void driver_unregister(struct device_driver *drv);
|
|
int bus_register(struct bus_type *bus);
|
|
void bus_unregister(struct bus_type *bus);
|
|
|
|
enum { CLOCK_BOOTTIME = 7, };
|
|
|
|
struct fasync_struct;
|
|
void kill_fasync(struct fasync_struct **, int, int);
|
|
|
|
enum { SIGIO = 29 };
|
|
|
|
enum {
|
|
POLL_IN = 1,
|
|
POLL_HUP = 6,
|
|
};
|
|
|
|
enum tk_offsets { TK_OFFS_BOOT = 1, };
|
|
|
|
ktime_t ktime_mono_to_real(ktime_t mono);
|
|
ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
|
|
|
|
static inline void rcu_read_lock(void) { }
|
|
static inline void rcu_read_unlock(void) { }
|
|
|
|
#define rcu_dereference(p) p
|
|
#define rcu_assign_pointer(p,v) p = v
|
|
#define rcu_dereference_protected(p, c) p
|
|
|
|
static inline int hidraw_init(void) { return 0; }
|
|
static inline int hidraw_exit(void) { return 0; }
|
|
static inline int hidraw_debug_init(void) { return 0; }
|
|
static inline int hidraw_debug_exit(void) { return 0; }
|
|
|
|
#define list_for_each_entry_rcu(pos, head, member) \
|
|
list_for_each_entry(pos, head, member)
|
|
|
|
int fasync_helper(int, struct file *, int, struct fasync_struct **);
|
|
|
|
typedef unsigned fl_owner_t;
|
|
|
|
struct scatterlist;
|
|
|
|
bool lockdep_is_held(void *);
|
|
|
|
struct power_supply;
|
|
void power_supply_changed(struct power_supply *psy);
|
|
|
|
static inline u16 get_unaligned_be16(const void *p) {
|
|
return be16_to_cpup((__be16 *)p); }
|
|
|
|
static inline void synchronize_rcu(void) { }
|
|
|
|
static inline void list_add_tail_rcu(struct list_head *n,
|
|
struct list_head *head) {
|
|
list_add_tail(n, head); }
|
|
|
|
static inline void list_del_rcu(struct list_head *entry) {
|
|
list_del(entry); }
|
|
|
|
int mutex_lock_interruptible(struct mutex *m);
|
|
|
|
void kvfree(const void *addr);
|
|
|
|
struct inode
|
|
{
|
|
struct cdev * i_cdev;
|
|
};
|
|
|
|
int nonseekable_open(struct inode *inode, struct file *filp);
|
|
|
|
enum { O_NONBLOCK = 0x4000 };
|
|
|
|
typedef unsigned __poll_t;
|
|
|
|
typedef struct poll_table_struct { } poll_table;
|
|
|
|
size_t copy_to_user(void *dst, void const *src, size_t len);
|
|
long copy_from_user(void *to, const void *from, unsigned long n);
|
|
#define put_user(x, ptr) ({ lx_printf("put_user not implemented"); (0);})
|
|
|
|
int devm_add_action(struct device *dev, void (*action)(void *), void *data);
|
|
|
|
void poll_wait(struct file *f, wait_queue_head_t *w, poll_table *p);
|
|
|
|
#define get_user(x, ptr) ({ x = *ptr; 0; })
|
|
|
|
unsigned long clear_user(void *to, unsigned long n);
|
|
|
|
#define _IOC_NRSHIFT 0
|
|
#define _IOC_TYPESHIFT (_IOC_NRSHIFT + 8)
|
|
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT + 8)
|
|
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT + 14)
|
|
|
|
#define _IOC_WRITE 1U
|
|
#define _IOC_READ 2U
|
|
#define _IOC_SIZEMASK ((1 << 14) - 1)
|
|
#define _IOC_DIR(cmd) cmd
|
|
#define _IOC(dir,type,nr,size) (type+nr+sizeof(size))
|
|
#define _IOR(type,nr,size) (type+nr+sizeof(size)+10)
|
|
#define _IOW(type,nr,size) (type+nr+sizeof(size)+20)
|
|
#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
|
|
#define _IOC_TYPE(cmd) cmd
|
|
#define _IOC_NR(cmd) cmd
|
|
|
|
signed long schedule_timeout(signed long timeout);
|
|
|
|
int kstrtouint(const char *s, unsigned int base, unsigned int *res);
|
|
|
|
#define find_next_zero_bit find_next_zero_bit_le
|
|
|
|
int device_set_wakeup_enable(struct device *dev, bool enable);
|
|
|
|
struct ida {};
|
|
#define DEFINE_IDA(name) struct ida name;
|
|
|
|
loff_t no_llseek(struct file *file, loff_t offset, int whence);
|
|
|
|
struct file_operations
|
|
{
|
|
struct module *owner;
|
|
int (*open) (struct inode *, struct file *);
|
|
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
|
|
loff_t (*llseek) (struct file *, loff_t, int);
|
|
unsigned int (*poll) (struct file *, struct poll_table_struct *);
|
|
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
|
|
int (*flush) (struct file *, fl_owner_t id);
|
|
int (*release) (struct inode *, struct file *);
|
|
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
|
|
int (*fasync) (int, struct file *, int);
|
|
};
|
|
|
|
#define MKDEV(major, minor) 0
|
|
|
|
unsigned long int_sqrt(unsigned long x);
|
|
|
|
u64 get_unaligned_le64(const void *p);
|
|
|
|
#define U8_MAX ((u8)~0U)
|
|
#define S8_MAX ((s8)(U8_MAX>>1))
|
|
#define S8_MIN ((s8)(-S8_MAX - 1))
|
|
#define U16_MAX ((u16)~0U)
|
|
#define S16_MAX ((s16)(U16_MAX>>1))
|
|
#define S16_MIN ((s16)(-S16_MAX - 1))
|
|
#define U32_MAX ((u32)~0U)
|
|
#define S32_MAX ((s32)(U32_MAX>>1))
|
|
#define S32_MIN ((s32)(-S32_MAX - 1))
|
|
|
|
typedef void (*dr_release_t)(struct device *dev, void *res);
|
|
void *devres_alloc(dr_release_t release, size_t size, gfp_t gfp);
|
|
void devres_add(struct device *dev, void *res);
|
|
int devres_release_group(struct device *dev, void *id);
|
|
void * devres_open_group(struct device *dev, void *id, gfp_t gfp);
|
|
void devres_close_group(struct device *dev, void *id);
|
|
|
|
static inline void add_input_randomness(unsigned int type, unsigned int code, unsigned int value) { }
|
|
|
|
unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset);
|
|
#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
|
|
|
|
char *devm_kasprintf(struct device *dev, gfp_t gfp, const char *fmt, ...);
|
|
|
|
int devm_led_trigger_register(struct device *dev, struct led_trigger *trigger);
|
|
|
|
int devm_add_action_or_reset(struct device *dev, void (*action)(void *), void *data);
|
|
|
|
int devm_led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
|
|
|
|
enum { LED_HW_PLUGGABLE = 1 << 19 };
|
|
|
|
int kstrtou8(const char *s, unsigned int base, u8 *res);
|
|
|
|
struct kobj_attribute
|
|
{
|
|
struct attribute attr;
|
|
void * show;
|
|
void * store;
|
|
};
|
|
|
|
int bitmap_subset(const unsigned long *src1, const unsigned long *src2, int nbits);
|
|
|
|
struct device_type {
|
|
const char *name;
|
|
const struct attribute_group **groups;
|
|
void (*release)(struct device *dev);
|
|
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
|
|
char *(*devnode)(struct device *dev, mode_t *mode, kuid_t *, kgid_t *);
|
|
};
|
|
|
|
char *kasprintf(gfp_t gfp, const char *fmt, ...);
|
|
|
|
void cdev_init(struct cdev *c, const struct file_operations *fops);
|
|
int cdev_device_add(struct cdev *cdev, struct device *dev);
|
|
void cdev_device_del(struct cdev *cdev, struct device *dev);
|
|
|
|
#define MINOR(dev) ((dev) & 0xff)
|
|
|
|
typedef int (*dr_match_t)(struct device *dev, void *res, void *match_data);
|
|
|
|
void devres_free(void *res);
|
|
int devres_destroy(struct device *dev, dr_release_t release, dr_match_t match, void *match_data);
|
|
|
|
static inline void dump_stack(void) { }
|
|
|
|
int bitmap_weight(const unsigned long *src, unsigned int nbits);
|
|
|
|
#define list_add_rcu list_add
|
|
|
|
int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, gfp_t gfp_mask);
|
|
void ida_simple_remove(struct ida *ida, unsigned int id);
|
|
|
|
int class_register(struct class *cls);
|
|
void class_unregister(struct class *cls);
|
|
int register_chrdev_region(dev_t, unsigned, const char *);
|
|
void unregister_chrdev_region(dev_t, unsigned);
|
|
|
|
int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr);
|
|
|
|
static inline void led_trigger_event(struct led_trigger *trigger,
|
|
enum led_brightness event) {}
|
|
|
|
typedef unsigned slab_flags_t;
|
|
|
|
struct tasklet_struct
|
|
{
|
|
void (*func)(unsigned long);
|
|
unsigned long data;
|
|
};
|
|
|
|
struct __una_u16 { u16 x; } __attribute__((packed));
|
|
struct __una_u32 { u32 x; } __attribute__((packed));
|
|
|
|
void subsys_input_init();
|
|
int module_evdev_init();
|
|
int module_led_init();
|
|
int module_usbhid_init();
|
|
int module_hid_init();
|
|
int module_hid_generic_init();
|
|
int module_ch_driver_init();
|
|
int module_ms_driver_init();
|
|
int module_mt_driver_init();
|
|
int module_wacom_driver_init();
|
|
|
|
struct input_handle;
|
|
void genode_evdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value);
|
|
|
|
struct usb_device;
|
|
extern int usb_get_configuration(struct usb_device *dev);
|
|
|
|
struct usb_hcd { unsigned amd_resume_bug:1; };
|
|
|
|
bool usb_device_is_owned(struct usb_device *udev);
|
|
|
|
#include <lx_emul/extern_c_end.h>
|
|
|
|
#endif /* _SRC__DRIVERS__USB_HID__LX_EMUL_H_ */
|