mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 17:52:52 +00:00
dde_linux: update usb_net driver to Linux 6.1.20
Driver for network-interface cards and LTE modems with MBIM support connected via USB. issue #4958
This commit is contained in:
parent
f668aea42a
commit
d5cf77539a
11
repos/dde_linux/recipes/src/usb_net_drv/content.mk
Normal file
11
repos/dde_linux/recipes/src/usb_net_drv/content.mk
Normal file
@ -0,0 +1,11 @@
|
||||
MIRROR_FROM_REP_DIR := src/drivers/usb_net
|
||||
|
||||
content: $(MIRROR_FROM_REP_DIR)
|
||||
$(MIRROR_FROM_REP_DIR):
|
||||
$(mirror_from_rep_dir)
|
||||
|
||||
PORT_DIR := $(call port_dir,$(GENODE_DIR)/repos/dde_linux/ports/linux)
|
||||
|
||||
content: LICENSE
|
||||
LICENSE:
|
||||
cp $(PORT_DIR)/src/linux/COPYING $@
|
1
repos/dde_linux/recipes/src/usb_net_drv/hash
Normal file
1
repos/dde_linux/recipes/src/usb_net_drv/hash
Normal file
@ -0,0 +1 @@
|
||||
2023-07-11-p 9df48e239f9ca1d4233a198e4ec39a4ed571b366
|
10
repos/dde_linux/recipes/src/usb_net_drv/used_apis
Normal file
10
repos/dde_linux/recipes/src/usb_net_drv/used_apis
Normal file
@ -0,0 +1,10 @@
|
||||
base
|
||||
genode_c_api
|
||||
jitterentropy
|
||||
nic_session
|
||||
os
|
||||
report_session
|
||||
terminal_session
|
||||
uplink_session
|
||||
usb_session
|
||||
virt_linux
|
70
repos/dde_linux/src/drivers/usb_net/README
Normal file
70
repos/dde_linux/src/drivers/usb_net/README
Normal file
@ -0,0 +1,70 @@
|
||||
USB NIC driver
|
||||
|
||||
|
||||
Driver for network-interface cards and LTE modems with MBIM support connected via USB.
|
||||
|
||||
|
||||
Current supported devices
|
||||
=========================
|
||||
|
||||
* NICs containing an AX88179A chip
|
||||
* NICs that support the NCM profile (e.g., RTL8156)
|
||||
* NICs that the ECM profile
|
||||
* LTE modems that support the MBIM configuration
|
||||
|
||||
|
||||
NIC configuration
|
||||
=================
|
||||
|
||||
Configuration snippet:
|
||||
|
||||
!<start name="usb_net_drv">
|
||||
! <resource name="RAM" quantum="10M"/>
|
||||
! <config mac="2e:60:90:0c:4e:01 configuration="2" />
|
||||
! <route>
|
||||
! <service name="Uplink"><child name="nic_router"/></service/>
|
||||
! ....
|
||||
! </route>
|
||||
!</start>
|
||||
|
||||
The driver connects as an Uplink client to Genode's network infrastructure.
|
||||
|
||||
The 'mac' can be used to configure the hardware address on devices that support
|
||||
setting it and for devices that do not offer a hardware address (a random
|
||||
address will be used otherwise).
|
||||
|
||||
The 'configuration' attribute allows for setting the desired configuration
|
||||
profile of the USB device in case there is more than one profile. In case it is
|
||||
omitted or 0, the driver will choose a profile (first non-vendor specific).
|
||||
|
||||
|
||||
LTE modem configuration
|
||||
========================
|
||||
|
||||
Currently there is support for MBIM (Mobile Broadband Interface Model) devices.
|
||||
|
||||
Tested devices:
|
||||
Huawai ME906s (P/V: 12d1:15c1) - "configuration=3" for 'usb_net_drv'
|
||||
Fibocom L830-EB-00 (P/V: 2cb7:0210) - automatically detected
|
||||
|
||||
|
||||
!<start name="usb_nic_drv">
|
||||
! <resource name="RAM" quantum="10M"/>
|
||||
! <provides>
|
||||
! <service name="Terminal"/>
|
||||
! </provides>
|
||||
! <config mac="02:00:00:00:01:01" configuration="3"/>
|
||||
! <route>
|
||||
! <service name="Uplink"><child name="nic_router"/></service/>
|
||||
! ....
|
||||
! </route>
|
||||
!</start>
|
||||
|
||||
|
||||
In case the driver finds a MBIM capable device it will announce a terminal
|
||||
session which is used as the control channel (wireless communication device
|
||||
class - CDC WDM).
|
||||
|
||||
An example scenario can be found in Genode World
|
||||
(_src/app/mbimcli_). Once a data connection is established via the Terminal
|
||||
session, the Uplink session is used to transfer Ethernet frames.
|
1299
repos/dde_linux/src/drivers/usb_net/dep.list
Normal file
1299
repos/dde_linux/src/drivers/usb_net/dep.list
Normal file
File diff suppressed because it is too large
Load Diff
418
repos/dde_linux/src/drivers/usb_net/dummies.c
Normal file
418
repos/dde_linux/src/drivers/usb_net/dummies.c
Normal file
@ -0,0 +1,418 @@
|
||||
/*
|
||||
* \brief Dummy definitions of Linux Kernel functions
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2023-07-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <lx_emul.h>
|
||||
|
||||
|
||||
DEFINE_STATIC_KEY_FALSE(force_irqthreads_key);
|
||||
DEFINE_STATIC_KEY_FALSE(bpf_stats_enabled_key);
|
||||
DEFINE_STATIC_KEY_FALSE(bpf_master_redirect_enabled_key);
|
||||
DEFINE_STATIC_KEY_FALSE(memalloc_socks_key);
|
||||
|
||||
unsigned long __FIXADDR_TOP = 0xfffff000;
|
||||
|
||||
bool arm64_use_ng_mappings = false;
|
||||
|
||||
const struct ipv6_stub *ipv6_stub;
|
||||
|
||||
|
||||
#ifdef __i386__
|
||||
asmlinkage __wsum csum_partial(const void * buff,int len,__wsum sum)
|
||||
#else
|
||||
__wsum csum_partial(const void * buff,int len,__wsum sum)
|
||||
#endif
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __arm__
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
unsigned long arm_copy_to_user(void *to, const void *from, unsigned long n)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
asmlinkage void __div0(void);
|
||||
asmlinkage void __div0(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/dma-map-ops.h>
|
||||
|
||||
void arch_teardown_dma_ops(struct device * dev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void arm_heavy_mb(void);
|
||||
void arm_heavy_mb(void)
|
||||
{
|
||||
// FIXME: on Cortex A9 we potentially need to flush L2-cache
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <linux/timekeeper_internal.h>
|
||||
void update_vsyscall(struct timekeeper * tk)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include <linux/filter.h>
|
||||
#include <linux/jump_label.h> /* for DEFINE_STATIC_KEY_FALSE */
|
||||
|
||||
void bpf_prog_change_xdp(struct bpf_prog *prev_prog, struct bpf_prog *prog)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rcutree.h>
|
||||
|
||||
void synchronize_rcu_expedited(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rcupdate.h>
|
||||
|
||||
void synchronize_rcu(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/net_namespace.h>
|
||||
|
||||
void __init net_ns_init(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/kobject.h>
|
||||
|
||||
int kobject_uevent(struct kobject * kobj,enum kobject_action action)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb/hcd.h>
|
||||
|
||||
void __init usb_init_pool_max(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern int usb_major_init(void);
|
||||
int usb_major_init(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern int __init usb_devio_init(void);
|
||||
int __init usb_devio_init(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb/hcd.h>
|
||||
|
||||
void usb_hcd_synchronize_unlinks(struct usb_device * udev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb.h>
|
||||
|
||||
struct urb * usb_get_from_anchor(struct usb_anchor * anchor)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
extern char * usb_cache_string(struct usb_device * udev,int index);
|
||||
char * usb_cache_string(struct usb_device * udev,int index)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void usb_kill_urb(struct urb * urb)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
int usb_unlink_urb(struct urb * urb)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void usb_poison_urb(struct urb * urb)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb/hcd.h>
|
||||
|
||||
struct usb_hcd * usb_get_hcd(struct usb_hcd * hcd)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return hcd;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb/hcd.h>
|
||||
|
||||
void usb_put_hcd(struct usb_hcd * hcd)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern int __init netdev_kobject_init(void);
|
||||
int __init netdev_kobject_init(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
void dev_add_offload(struct packet_offload * po)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/syscore_ops.h>
|
||||
|
||||
void register_syscore_ops(struct syscore_ops * ops)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
bool parse_option_str(const char * str,const char * option)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
int rtnl_lock_killable(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
void rtnl_lock(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
int rtnl_is_locked(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
struct sk_buff * rtmsg_ifinfo_build_skb(int type,struct net_device * dev,unsigned int change,u32 event,gfp_t flags,int * new_nsid,int new_ifindex)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/stringhash.h>
|
||||
|
||||
unsigned int full_name_hash(const void * salt,const char * name,unsigned int len)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <linux/random.h>
|
||||
|
||||
void add_device_randomness(const void * buf,size_t len)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
void rtnl_unlock(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/gen_stats.h>
|
||||
|
||||
void gnet_stats_basic_sync_init(struct gnet_stats_basic_sync * b)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/gen_stats.h>
|
||||
|
||||
void gen_kill_estimator(struct net_rate_estimator __rcu ** rate_est)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <asm-generic/softirq_stack.h>
|
||||
|
||||
void do_softirq_own_stack(void)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/of_net.h>
|
||||
#if defined(CONFIG_OF) && defined(CONFIG_NET)
|
||||
int of_get_mac_address(struct device_node * np,u8 * addr)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
extern void software_node_notify(struct device * dev);
|
||||
void software_node_notify(struct device * dev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void software_node_notify_remove(struct device * dev);
|
||||
void software_node_notify_remove(struct device * dev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern int usb_create_sysfs_dev_files(struct usb_device * udev);
|
||||
int usb_create_sysfs_dev_files(struct usb_device * udev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern void usb_remove_sysfs_dev_files(struct usb_device * udev);
|
||||
void usb_remove_sysfs_dev_files(struct usb_device * udev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void usb_remove_sysfs_intf_files(struct usb_interface * intf);
|
||||
void usb_remove_sysfs_intf_files(struct usb_interface * intf)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void usb_create_sysfs_intf_files(struct usb_interface * intf);
|
||||
void usb_create_sysfs_intf_files(struct usb_interface * intf)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void usb_notify_add_device(struct usb_device * udev);
|
||||
void usb_notify_add_device(struct usb_device * udev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void usb_notify_remove_device(struct usb_device * udev);
|
||||
void usb_notify_remove_device(struct usb_device * udev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern int usb_create_ep_devs(struct device * parent,struct usb_host_endpoint * endpoint,struct usb_device * udev);
|
||||
int usb_create_ep_devs(struct device * parent,struct usb_host_endpoint * endpoint,struct usb_device * udev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern void usb_remove_ep_devs(struct usb_host_endpoint * endpoint);
|
||||
void usb_remove_ep_devs(struct usb_host_endpoint * endpoint)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void usb_disable_interface(struct usb_device * dev,struct usb_interface * intf,bool reset_hardware);
|
||||
void usb_disable_interface(struct usb_device * dev,struct usb_interface * intf,bool reset_hardware)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void netdev_unregister_kobject(struct net_device * ndev);
|
||||
void netdev_unregister_kobject(struct net_device * ndev)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
513
repos/dde_linux/src/drivers/usb_net/lx_emul.c
Normal file
513
repos/dde_linux/src/drivers/usb_net/lx_emul.c
Normal file
@ -0,0 +1,513 @@
|
||||
/*
|
||||
* \brief Implementation of driver specific Linux functions
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2023-06-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <lx_emul.h>
|
||||
|
||||
|
||||
pteval_t __default_kernel_pte_mask __read_mostly = ~0;
|
||||
|
||||
|
||||
struct device_type usb_if_device_type = {
|
||||
.name = "usb_interface"
|
||||
};
|
||||
|
||||
|
||||
struct usb_driver usbfs_driver = {
|
||||
.name = "usbfs"
|
||||
};
|
||||
|
||||
const struct attribute_group *usb_device_groups[] = { };
|
||||
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
struct kmem_cache * kmem_cache_create_usercopy(const char * name,
|
||||
unsigned int size,
|
||||
unsigned int align,
|
||||
slab_flags_t flags,
|
||||
unsigned int useroffset,
|
||||
unsigned int usersize,
|
||||
void (* ctor)(void *))
|
||||
{
|
||||
return kmem_cache_create(name, size, align, flags, ctor);
|
||||
}
|
||||
|
||||
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
|
||||
struct net init_net;
|
||||
|
||||
|
||||
#include <net/net_namespace.h>
|
||||
|
||||
int register_pernet_subsys(struct pernet_operations *ops)
|
||||
{
|
||||
if (ops->init)
|
||||
ops->init(&init_net);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int register_pernet_device(struct pernet_operations *ops)
|
||||
{
|
||||
return register_pernet_subsys(ops);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rcutree.h>
|
||||
|
||||
/*
|
||||
* taken from src/lib/wifi/lx_emul.c
|
||||
*/
|
||||
void kvfree_call_rcu(struct rcu_head * head, rcu_callback_t func)
|
||||
{
|
||||
void *ptr = (void *) head - (unsigned long) func;
|
||||
kvfree(ptr);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/gfp.h>
|
||||
|
||||
unsigned long get_zeroed_page(gfp_t gfp_mask)
|
||||
{
|
||||
return (unsigned long)kzalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
}
|
||||
|
||||
|
||||
void free_pages(unsigned long addr,unsigned int order)
|
||||
{
|
||||
kfree((void *)addr);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/gfp.h>
|
||||
|
||||
void * page_frag_alloc_align(struct page_frag_cache * nc, unsigned int fragsz,
|
||||
gfp_t gfp_mask, unsigned int align_mask)
|
||||
{
|
||||
if (align_mask != ~0U) {
|
||||
printk("page_frag_alloc_align: unsupported align_mask=%x\n", align_mask);
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
return lx_emul_mem_alloc_aligned(fragsz, ARCH_KMALLOC_MINALIGN);
|
||||
}
|
||||
|
||||
|
||||
void page_frag_free(void * addr)
|
||||
{
|
||||
lx_emul_mem_free(addr);
|
||||
}
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#ifndef INLINE_COPY_TO_USER
|
||||
unsigned long _copy_from_user(void * to,const void __user * from,unsigned long n)
|
||||
{
|
||||
memcpy(to, from, n);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
unsigned long __must_check __arch_copy_from_user(void *to, const void __user *from, unsigned long n);
|
||||
unsigned long __must_check __arch_copy_from_user(void *to, const void __user *from, unsigned long n)
|
||||
{
|
||||
memcpy(to, from, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef INLINE_COPY_FROM_USER
|
||||
unsigned long _copy_to_user(void __user * to,const void * from,unsigned long n)
|
||||
{
|
||||
memcpy(to, from, n);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
unsigned long __must_check __arch_copy_to_user(void __user *to, const void *from, unsigned long n);
|
||||
unsigned long __must_check __arch_copy_to_user(void __user *to, const void *from, unsigned long n)
|
||||
{
|
||||
memcpy(to, from, n);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
unsigned long arm_copy_from_user(void *to, const void *from, unsigned long n)
|
||||
{
|
||||
memcpy(to, from, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* custom MAC address
|
||||
*/
|
||||
|
||||
bool use_mac_address;
|
||||
unsigned char mac_address[6];
|
||||
|
||||
int netdev_register_kobject(struct net_device * ndev)
|
||||
{
|
||||
if (use_mac_address) eth_hw_addr_set(ndev, mac_address);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* core/message.c
|
||||
*/
|
||||
#include <linux/nls.h>
|
||||
#include <linux/usb/quirks.h>
|
||||
#include <linux/usb/cdc.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr,
|
||||
struct usb_interface *intf,
|
||||
u8 *buffer,
|
||||
int buflen)
|
||||
{
|
||||
/* duplicates are ignored */
|
||||
struct usb_cdc_union_desc *union_header = NULL;
|
||||
|
||||
/* duplicates are not tolerated */
|
||||
struct usb_cdc_header_desc *header = NULL;
|
||||
struct usb_cdc_ether_desc *ether = NULL;
|
||||
struct usb_cdc_mdlm_detail_desc *detail = NULL;
|
||||
struct usb_cdc_mdlm_desc *desc = NULL;
|
||||
|
||||
unsigned int elength;
|
||||
int cnt = 0;
|
||||
|
||||
memset(hdr, 0x00, sizeof(struct usb_cdc_parsed_header));
|
||||
hdr->phonet_magic_present = false;
|
||||
while (buflen > 0) {
|
||||
elength = buffer[0];
|
||||
if (!elength) {
|
||||
dev_err(&intf->dev, "skipping garbage byte\n");
|
||||
elength = 1;
|
||||
goto next_desc;
|
||||
}
|
||||
if ((buflen < elength) || (elength < 3)) {
|
||||
dev_err(&intf->dev, "invalid descriptor buffer length\n");
|
||||
break;
|
||||
}
|
||||
if (buffer[1] != USB_DT_CS_INTERFACE) {
|
||||
dev_err(&intf->dev, "skipping garbage\n");
|
||||
goto next_desc;
|
||||
}
|
||||
|
||||
switch (buffer[2]) {
|
||||
case USB_CDC_UNION_TYPE: /* we've found it */
|
||||
if (elength < sizeof(struct usb_cdc_union_desc))
|
||||
goto next_desc;
|
||||
if (union_header) {
|
||||
dev_err(&intf->dev, "More than one union descriptor, skipping ...\n");
|
||||
goto next_desc;
|
||||
}
|
||||
union_header = (struct usb_cdc_union_desc *)buffer;
|
||||
break;
|
||||
case USB_CDC_COUNTRY_TYPE:
|
||||
if (elength < sizeof(struct usb_cdc_country_functional_desc))
|
||||
goto next_desc;
|
||||
hdr->usb_cdc_country_functional_desc =
|
||||
(struct usb_cdc_country_functional_desc *)buffer;
|
||||
break;
|
||||
case USB_CDC_HEADER_TYPE:
|
||||
if (elength != sizeof(struct usb_cdc_header_desc))
|
||||
goto next_desc;
|
||||
if (header)
|
||||
return -EINVAL;
|
||||
header = (struct usb_cdc_header_desc *)buffer;
|
||||
break;
|
||||
case USB_CDC_ACM_TYPE:
|
||||
if (elength < sizeof(struct usb_cdc_acm_descriptor))
|
||||
goto next_desc;
|
||||
hdr->usb_cdc_acm_descriptor =
|
||||
(struct usb_cdc_acm_descriptor *)buffer;
|
||||
break;
|
||||
case USB_CDC_ETHERNET_TYPE:
|
||||
if (elength != sizeof(struct usb_cdc_ether_desc))
|
||||
goto next_desc;
|
||||
if (ether)
|
||||
return -EINVAL;
|
||||
ether = (struct usb_cdc_ether_desc *)buffer;
|
||||
break;
|
||||
case USB_CDC_CALL_MANAGEMENT_TYPE:
|
||||
if (elength < sizeof(struct usb_cdc_call_mgmt_descriptor))
|
||||
goto next_desc;
|
||||
hdr->usb_cdc_call_mgmt_descriptor =
|
||||
(struct usb_cdc_call_mgmt_descriptor *)buffer;
|
||||
break;
|
||||
case USB_CDC_DMM_TYPE:
|
||||
if (elength < sizeof(struct usb_cdc_dmm_desc))
|
||||
goto next_desc;
|
||||
hdr->usb_cdc_dmm_desc =
|
||||
(struct usb_cdc_dmm_desc *)buffer;
|
||||
break;
|
||||
case USB_CDC_MDLM_TYPE:
|
||||
if (elength < sizeof(struct usb_cdc_mdlm_desc))
|
||||
goto next_desc;
|
||||
if (desc)
|
||||
return -EINVAL;
|
||||
desc = (struct usb_cdc_mdlm_desc *)buffer;
|
||||
break;
|
||||
case USB_CDC_MDLM_DETAIL_TYPE:
|
||||
if (elength < sizeof(struct usb_cdc_mdlm_detail_desc))
|
||||
goto next_desc;
|
||||
if (detail)
|
||||
return -EINVAL;
|
||||
detail = (struct usb_cdc_mdlm_detail_desc *)buffer;
|
||||
break;
|
||||
case USB_CDC_NCM_TYPE:
|
||||
if (elength < sizeof(struct usb_cdc_ncm_desc))
|
||||
goto next_desc;
|
||||
hdr->usb_cdc_ncm_desc = (struct usb_cdc_ncm_desc *)buffer;
|
||||
break;
|
||||
case USB_CDC_MBIM_TYPE:
|
||||
if (elength < sizeof(struct usb_cdc_mbim_desc))
|
||||
goto next_desc;
|
||||
|
||||
hdr->usb_cdc_mbim_desc = (struct usb_cdc_mbim_desc *)buffer;
|
||||
break;
|
||||
case USB_CDC_MBIM_EXTENDED_TYPE:
|
||||
if (elength < sizeof(struct usb_cdc_mbim_extended_desc))
|
||||
break;
|
||||
hdr->usb_cdc_mbim_extended_desc =
|
||||
(struct usb_cdc_mbim_extended_desc *)buffer;
|
||||
break;
|
||||
case CDC_PHONET_MAGIC_NUMBER:
|
||||
hdr->phonet_magic_present = true;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* there are LOTS more CDC descriptors that
|
||||
* could legitimately be found here.
|
||||
*/
|
||||
dev_dbg(&intf->dev, "Ignoring descriptor: type %02x, length %ud\n",
|
||||
buffer[2], elength);
|
||||
goto next_desc;
|
||||
}
|
||||
cnt++;
|
||||
next_desc:
|
||||
buflen -= elength;
|
||||
buffer += elength;
|
||||
}
|
||||
hdr->usb_cdc_union_desc = union_header;
|
||||
hdr->usb_cdc_header_desc = header;
|
||||
hdr->usb_cdc_mdlm_detail_desc = detail;
|
||||
hdr->usb_cdc_mdlm_desc = desc;
|
||||
hdr->usb_cdc_ether_desc = ether;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* usb_get_string - gets a string descriptor
|
||||
* @dev: the device whose string descriptor is being retrieved
|
||||
* @langid: code for language chosen (from string descriptor zero)
|
||||
* @index: the number of the descriptor
|
||||
* @buf: where to put the string
|
||||
* @size: how big is "buf"?
|
||||
*
|
||||
* Context: task context, might sleep.
|
||||
*
|
||||
* Retrieves a string, encoded using UTF-16LE (Unicode, 16 bits per character,
|
||||
* in little-endian byte order).
|
||||
* The usb_string() function will often be a convenient way to turn
|
||||
* these strings into kernel-printable form.
|
||||
*
|
||||
* Strings may be referenced in device, configuration, interface, or other
|
||||
* descriptors, and could also be used in vendor-specific ways.
|
||||
*
|
||||
* This call is synchronous, and may not be used in an interrupt context.
|
||||
*
|
||||
* Return: The number of bytes received on success, or else the status code
|
||||
* returned by the underlying usb_control_msg() call.
|
||||
*/
|
||||
static int usb_get_string(struct usb_device *dev, unsigned short langid,
|
||||
unsigned char index, void *buf, int size)
|
||||
{
|
||||
int i;
|
||||
int result;
|
||||
|
||||
if (size <= 0) /* No point in asking for no data */
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
/* retry on length 0 or stall; some devices are flakey */
|
||||
result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
|
||||
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
|
||||
(USB_DT_STRING << 8) + index, langid, buf, size,
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
if (result == 0 || result == -EPIPE)
|
||||
continue;
|
||||
if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) {
|
||||
result = -ENODATA;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void usb_try_string_workarounds(unsigned char *buf, int *length)
|
||||
{
|
||||
int newlength, oldlength = *length;
|
||||
|
||||
for (newlength = 2; newlength + 1 < oldlength; newlength += 2)
|
||||
if (!isprint(buf[newlength]) || buf[newlength + 1])
|
||||
break;
|
||||
|
||||
if (newlength > 2) {
|
||||
buf[0] = newlength;
|
||||
*length = newlength;
|
||||
}
|
||||
}
|
||||
|
||||
static int usb_string_sub(struct usb_device *dev, unsigned int langid,
|
||||
unsigned int index, unsigned char *buf)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Try to read the string descriptor by asking for the maximum
|
||||
* possible number of bytes */
|
||||
if (dev->quirks & USB_QUIRK_STRING_FETCH_255)
|
||||
rc = -EIO;
|
||||
else
|
||||
rc = usb_get_string(dev, langid, index, buf, 255);
|
||||
|
||||
/* If that failed try to read the descriptor length, then
|
||||
* ask for just that many bytes */
|
||||
if (rc < 2) {
|
||||
rc = usb_get_string(dev, langid, index, buf, 2);
|
||||
if (rc == 2)
|
||||
rc = usb_get_string(dev, langid, index, buf, buf[0]);
|
||||
}
|
||||
|
||||
if (rc >= 2) {
|
||||
if (!buf[0] && !buf[1])
|
||||
usb_try_string_workarounds(buf, &rc);
|
||||
|
||||
/* There might be extra junk at the end of the descriptor */
|
||||
if (buf[0] < rc)
|
||||
rc = buf[0];
|
||||
|
||||
rc = rc - (rc & 1); /* force a multiple of two */
|
||||
}
|
||||
|
||||
if (rc < 2)
|
||||
rc = (rc < 0 ? rc : -EINVAL);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int usb_get_langid(struct usb_device *dev, unsigned char *tbuf)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (dev->have_langid)
|
||||
return 0;
|
||||
|
||||
if (dev->string_langid < 0)
|
||||
return -EPIPE;
|
||||
|
||||
err = usb_string_sub(dev, 0, 0, tbuf);
|
||||
|
||||
/* If the string was reported but is malformed, default to english
|
||||
* (0x0409) */
|
||||
if (err == -ENODATA || (err > 0 && err < 4)) {
|
||||
dev->string_langid = 0x0409;
|
||||
dev->have_langid = 1;
|
||||
dev_err(&dev->dev,
|
||||
"language id specifier not provided by device, defaulting to English\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* In case of all other errors, we assume the device is not able to
|
||||
* deal with strings at all. Set string_langid to -1 in order to
|
||||
* prevent any string to be retrieved from the device */
|
||||
if (err < 0) {
|
||||
dev_info(&dev->dev, "string descriptor 0 read error: %d\n",
|
||||
err);
|
||||
dev->string_langid = -1;
|
||||
return -EPIPE;
|
||||
}
|
||||
|
||||
/* always use the first langid listed */
|
||||
dev->string_langid = tbuf[2] | (tbuf[3] << 8);
|
||||
dev->have_langid = 1;
|
||||
dev_dbg(&dev->dev, "default language 0x%04x\n",
|
||||
dev->string_langid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_string - returns UTF-8 version of a string descriptor
|
||||
* @dev: the device whose string descriptor is being retrieved
|
||||
* @index: the number of the descriptor
|
||||
* @buf: where to put the string
|
||||
* @size: how big is "buf"?
|
||||
*
|
||||
* Context: task context, might sleep.
|
||||
*
|
||||
* This converts the UTF-16LE encoded strings returned by devices, from
|
||||
* usb_get_string_descriptor(), to null-terminated UTF-8 encoded ones
|
||||
* that are more usable in most kernel contexts. Note that this function
|
||||
* chooses strings in the first language supported by the device.
|
||||
*
|
||||
* This call is synchronous, and may not be used in an interrupt context.
|
||||
*
|
||||
* Return: length of the string (>= 0) or usb_control_msg status (< 0).
|
||||
*/
|
||||
int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
|
||||
{
|
||||
unsigned char *tbuf;
|
||||
int err;
|
||||
|
||||
if (dev->state == USB_STATE_SUSPENDED)
|
||||
return -EHOSTUNREACH;
|
||||
if (size <= 0 || !buf)
|
||||
return -EINVAL;
|
||||
buf[0] = 0;
|
||||
if (index <= 0 || index >= 256)
|
||||
return -EINVAL;
|
||||
tbuf = kmalloc(256, GFP_NOIO);
|
||||
if (!tbuf)
|
||||
return -ENOMEM;
|
||||
|
||||
err = usb_get_langid(dev, tbuf);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
err = usb_string_sub(dev, dev->string_langid, index, tbuf);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
size--; /* leave room for trailing NULL char in output buffer */
|
||||
err = utf16s_to_utf8s((wchar_t *) &tbuf[2], (err - 2) / 2,
|
||||
UTF16_LITTLE_ENDIAN, buf, size);
|
||||
buf[err] = 0;
|
||||
|
||||
if (tbuf[1] != USB_DT_STRING)
|
||||
dev_dbg(&dev->dev,
|
||||
"wrong descriptor type %02x for string %d (\"%s\")\n",
|
||||
tbuf[1], index, buf);
|
||||
|
||||
errout:
|
||||
kfree(tbuf);
|
||||
return err;
|
||||
}
|
19
repos/dde_linux/src/drivers/usb_net/lx_emul.h
Normal file
19
repos/dde_linux/src/drivers/usb_net/lx_emul.h
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* \brief Dummy definitions of Linux Kernel functions
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2023-07-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <lx_emul/debug.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sched/debug.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
struct usb_hub;
|
353
repos/dde_linux/src/drivers/usb_net/lx_user.c
Normal file
353
repos/dde_linux/src/drivers/usb_net/lx_user.c
Normal file
@ -0,0 +1,353 @@
|
||||
/*
|
||||
* \brief Post kernel activity
|
||||
* \author Christian Helmuth
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2023-06-29
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/sched/task.h>
|
||||
#include <linux/usb.h>
|
||||
#include <lx_user/init.h>
|
||||
#include <genode_c_api/uplink.h>
|
||||
#include <genode_c_api/mac_address_reporter.h>
|
||||
#include <usb_net.h>
|
||||
|
||||
|
||||
struct task_struct *lx_user_new_usb_task(int (*func)(void*), void *args)
|
||||
{
|
||||
int pid = kernel_thread(func, args, CLONE_FS | CLONE_FILES);
|
||||
return find_task_by_pid_ns(pid, NULL);
|
||||
}
|
||||
|
||||
|
||||
static struct genode_uplink *dev_genode_uplink(struct net_device *dev)
|
||||
{
|
||||
return (struct genode_uplink *)dev->ifalias;
|
||||
}
|
||||
|
||||
|
||||
struct genode_uplink_rx_context
|
||||
{
|
||||
struct net_device *dev;
|
||||
};
|
||||
|
||||
|
||||
struct genode_uplink_tx_packet_context
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
};
|
||||
|
||||
|
||||
static unsigned long uplink_tx_packet_content(struct genode_uplink_tx_packet_context *ctx,
|
||||
char *dst, unsigned long dst_len)
|
||||
{
|
||||
struct sk_buff * const skb = ctx->skb;
|
||||
|
||||
skb_push(skb, ETH_HLEN);
|
||||
|
||||
if (dst_len < skb->len) {
|
||||
printk("uplink_tx_packet_content: packet exceeds uplink packet size\n");
|
||||
memset(dst, 0, dst_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
skb_copy_from_linear_data(skb, dst, skb->len);
|
||||
|
||||
/* clear unused part of the destination buffer */
|
||||
memset(dst + skb->len, 0, dst_len - skb->len);
|
||||
|
||||
return skb->len;
|
||||
}
|
||||
|
||||
|
||||
static rx_handler_result_t handle_rx(struct sk_buff **pskb)
|
||||
{
|
||||
struct sk_buff *skb = *pskb;
|
||||
struct net_device *dev = skb->dev;
|
||||
struct genode_uplink_tx_packet_context ctx = { .skb = skb };
|
||||
|
||||
/* if uplink still exists */
|
||||
if (dev->ifalias) {
|
||||
bool progress = genode_uplink_tx_packet(dev_genode_uplink(dev),
|
||||
uplink_tx_packet_content,
|
||||
&ctx);
|
||||
if (!progress)
|
||||
printk("handle_rx: uplink saturated, dropping packet\n");
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
return RX_HANDLER_CONSUMED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create Genode uplink for given net device
|
||||
*
|
||||
* The uplink is registered at the dev->ifalias pointer.
|
||||
*/
|
||||
static void handle_create_uplink(struct net_device *dev)
|
||||
{
|
||||
struct genode_uplink_args args;
|
||||
|
||||
if (dev_genode_uplink(dev))
|
||||
return;
|
||||
|
||||
if (!netif_carrier_ok(dev))
|
||||
return;
|
||||
|
||||
printk("create uplink for net device %s\n", &dev->name[0]);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
if (dev->addr_len != sizeof(args.mac_address)) {
|
||||
printk("error: net device has unexpected addr_len %u\n", dev->addr_len);
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < dev->addr_len; i++)
|
||||
args.mac_address[i] = dev->dev_addr[i];
|
||||
}
|
||||
|
||||
args.label = &dev->name[0];
|
||||
|
||||
dev->ifalias = (struct dev_ifalias *)genode_uplink_create(&args);
|
||||
}
|
||||
|
||||
|
||||
static void handle_destroy_uplink(struct net_device *dev)
|
||||
{
|
||||
struct genode_uplink *uplink = dev_genode_uplink(dev);
|
||||
|
||||
if (!uplink)
|
||||
return;
|
||||
|
||||
if (netif_carrier_ok(dev))
|
||||
return;
|
||||
|
||||
printk("destroy uplink for net device %s\n", &dev->name[0]);
|
||||
genode_uplink_destroy(uplink);
|
||||
|
||||
dev->ifalias = NULL;
|
||||
}
|
||||
|
||||
|
||||
static genode_uplink_rx_result_t uplink_rx_one_packet(struct genode_uplink_rx_context *ctx,
|
||||
char const *ptr, unsigned long len)
|
||||
{
|
||||
struct sk_buff *skb = alloc_skb(len, GFP_KERNEL);
|
||||
|
||||
if (!skb) {
|
||||
printk("alloc_skb failed\n");
|
||||
return GENODE_UPLINK_RX_RETRY;
|
||||
}
|
||||
|
||||
skb_copy_to_linear_data(skb, ptr, len);
|
||||
skb_put(skb, len);
|
||||
skb->dev = ctx->dev;
|
||||
|
||||
if (dev_queue_xmit(skb) < 0) {
|
||||
printk("lx_user: failed to xmit packet\n");
|
||||
return GENODE_UPLINK_RX_REJECTED;
|
||||
}
|
||||
|
||||
return GENODE_UPLINK_RX_ACCEPTED;
|
||||
}
|
||||
|
||||
|
||||
static int user_task_function(void *arg)
|
||||
{
|
||||
for (;;) {
|
||||
|
||||
struct net_device *dev;
|
||||
|
||||
for_each_netdev(&init_net, dev) {
|
||||
struct genode_mac_address dev_addr;
|
||||
|
||||
/* enable link sensing, repeated calls are handled by testing IFF_UP */
|
||||
dev_open(dev, 0);
|
||||
|
||||
memcpy(dev_addr.addr, dev->dev_addr, sizeof(dev_addr));
|
||||
genode_mac_address_register(dev->name, dev_addr);
|
||||
|
||||
/* install rx handler once */
|
||||
if (!netdev_is_rx_handler_busy(dev))
|
||||
netdev_rx_handler_register(dev, handle_rx, NULL);
|
||||
|
||||
/* respond to cable plug/unplug */
|
||||
handle_create_uplink(dev);
|
||||
handle_destroy_uplink(dev);
|
||||
|
||||
/* transmit packets received from the uplink session */
|
||||
if (netif_carrier_ok(dev)) {
|
||||
|
||||
struct genode_uplink_rx_context ctx = { .dev = dev };
|
||||
|
||||
while (genode_uplink_rx(dev_genode_uplink(dev),
|
||||
uplink_rx_one_packet,
|
||||
&ctx));
|
||||
}
|
||||
};
|
||||
|
||||
/* block until lx_emul_task_unblock */
|
||||
lx_emul_task_schedule(true);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct task_struct *user_task_struct_ptr; /* used by 'Device' for lx_emul_task_unblock */
|
||||
|
||||
void lx_user_init(void)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
lx_user_main_task(NULL);
|
||||
|
||||
pid = kernel_thread(user_task_function, NULL, CLONE_FS | CLONE_FILES);
|
||||
|
||||
user_task_struct_ptr = find_task_by_pid_ns(pid, NULL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
/*
|
||||
* Called whenever the link state changes
|
||||
*/
|
||||
|
||||
bool force_uplink_destroy = false;
|
||||
|
||||
void rtmsg_ifinfo(int type, struct net_device * dev, unsigned int change, gfp_t flags)
|
||||
{
|
||||
/* trigger handle_create_uplink / handle_destroy_uplink */
|
||||
if (user_task_struct_ptr)
|
||||
lx_emul_task_unblock(user_task_struct_ptr);
|
||||
|
||||
if (force_uplink_destroy) {
|
||||
struct genode_uplink *uplink = dev_genode_uplink(dev);
|
||||
printk("force destroy uplink for net device %s\n", &dev->name[0]);
|
||||
genode_uplink_destroy(uplink);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle WDM device class for MBIM-modems
|
||||
*/
|
||||
|
||||
struct usb_class_driver *wdm_driver;
|
||||
struct file wdm_file;
|
||||
|
||||
enum { WDM_MINOR = 8 };
|
||||
|
||||
int usb_register_dev(struct usb_interface *intf, struct usb_class_driver *class_driver)
|
||||
{
|
||||
if (strncmp(class_driver->name, "cdc-wdm", 7) == 0) {
|
||||
wdm_driver = class_driver;
|
||||
|
||||
intf->usb_dev = &intf->dev;
|
||||
intf->minor = WDM_MINOR;
|
||||
|
||||
lx_wdm_create_root();
|
||||
return 0;
|
||||
}
|
||||
|
||||
printk("%s:%d error: no device class for driver %s\n", __func__, __LINE__,
|
||||
class_driver->name);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void usb_deregister_dev(struct usb_interface * intf,struct usb_class_driver * class_driver)
|
||||
{
|
||||
lx_emul_trace(__func__);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int lx_wdm_read(void *args)
|
||||
{
|
||||
ssize_t length;
|
||||
struct lx_wdm *wdm_data = (struct lx_wdm *)args;
|
||||
|
||||
lx_emul_task_schedule(true);
|
||||
|
||||
if (!wdm_driver) {
|
||||
printk("%s:%d error: no WDM class driver\n", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (wdm_data->active) {
|
||||
length = wdm_driver->fops->read(&wdm_file, wdm_data->buffer, 0x1000, NULL);
|
||||
if (length > 0) {
|
||||
*wdm_data->data_avail = length;
|
||||
lx_wdm_signal_data_avail(wdm_data->handle);
|
||||
}
|
||||
lx_emul_task_schedule(true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int lx_wdm_write(void *args)
|
||||
{
|
||||
ssize_t length;
|
||||
struct lx_wdm *wdm_data = (struct lx_wdm *)args;
|
||||
|
||||
lx_emul_task_schedule(true);
|
||||
|
||||
if (!wdm_driver) {
|
||||
printk("%s:%d error: no WDM class driver\n", __func__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (wdm_data->active) {
|
||||
length = wdm_driver->fops->write(&wdm_file, wdm_data->buffer,
|
||||
*wdm_data->data_avail, NULL);
|
||||
if (length < 0) {
|
||||
printk("WDM write error: %ld", (long)length);
|
||||
}
|
||||
|
||||
lx_wdm_schedule_read(wdm_data->handle);
|
||||
lx_emul_task_schedule(true);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int lx_wdm_device(void *args)
|
||||
{
|
||||
int err = -1;
|
||||
|
||||
/* minor number for inode is 1 (see: ubs_register_dev above) */
|
||||
struct inode inode;
|
||||
inode.i_rdev = MKDEV(USB_DEVICE_MAJOR, WDM_MINOR);
|
||||
|
||||
if (!wdm_driver) {
|
||||
printk("%s:%d error: no WDM class driver\n", __func__, __LINE__);
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = wdm_driver->fops->open(&inode, &wdm_file))) {
|
||||
printk("Could not open WDM device: %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
lx_emul_task_schedule(true);
|
||||
//XXX: close
|
||||
return 0;
|
||||
}
|
234
repos/dde_linux/src/drivers/usb_net/main.cc
Normal file
234
repos/dde_linux/src/drivers/usb_net/main.cc
Normal file
@ -0,0 +1,234 @@
|
||||
/*
|
||||
* \brief C++ initialization, session, and client handling
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2023-07-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/component.h>
|
||||
#include <base/env.h>
|
||||
|
||||
#include <genode_c_api/uplink.h>
|
||||
#include <genode_c_api/mac_address_reporter.h>
|
||||
|
||||
#include <nic_session/nic_session.h>
|
||||
|
||||
#include <lx_kit/env.h>
|
||||
#include <lx_emul/task.h>
|
||||
#include <lx_emul/init.h>
|
||||
|
||||
/* C-interface */
|
||||
#include <usb_net.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern task_struct *user_task_struct_ptr;
|
||||
extern bool force_uplink_destroy;
|
||||
extern bool use_mac_address;
|
||||
extern unsigned char mac_address[6];
|
||||
|
||||
struct Device
|
||||
{
|
||||
Env &env;
|
||||
|
||||
Attached_rom_dataspace config_rom { env, "config" };
|
||||
unsigned long usb_config { 0 };
|
||||
|
||||
/*
|
||||
* Dedicated allocator per device to notice dangling
|
||||
* allocations on device destruction.
|
||||
*/
|
||||
Allocator_avl alloc { &Lx_kit::env().heap };
|
||||
|
||||
task_struct *state_task { lx_user_new_usb_task(state_task_entry, this) };
|
||||
task_struct *urb_task { lx_user_new_usb_task(urb_task_entry, this) };
|
||||
|
||||
Signal_handler<Device> task_state_handler { env.ep(), *this, &Device::handle_task_state };
|
||||
Signal_handler<Device> urb_handler { env.ep(), *this, &Device::handle_urb };
|
||||
|
||||
genode_usb_client_handle_t usb_handle {
|
||||
genode_usb_client_create(genode_env_ptr(env),
|
||||
genode_allocator_ptr(Lx_kit::env().heap),
|
||||
genode_range_allocator_ptr(alloc),
|
||||
"",
|
||||
genode_signal_handler_ptr(task_state_handler)) };
|
||||
|
||||
Signal_handler<Device> nic_handler { env.ep(), *this, &Device::handle_nic };
|
||||
Signal_handler<Device> config_handler { env.ep(), *this, &Device::handle_config };
|
||||
|
||||
bool registered { false };
|
||||
|
||||
void *lx_device_handle { nullptr };
|
||||
|
||||
Device(Env &env)
|
||||
:
|
||||
env(env)
|
||||
{
|
||||
genode_usb_client_sigh_ack_avail(usb_handle,
|
||||
genode_signal_handler_ptr(urb_handler));
|
||||
|
||||
genode_mac_address_reporter_init(env, Lx_kit::env().heap);
|
||||
|
||||
genode_uplink_init(genode_env_ptr(env),
|
||||
genode_allocator_ptr(Lx_kit::env().heap),
|
||||
genode_signal_handler_ptr(nic_handler));
|
||||
|
||||
config_rom.sigh(config_handler);
|
||||
handle_config();
|
||||
}
|
||||
|
||||
/* non-copyable */
|
||||
Device(const Device&) = delete;
|
||||
Device & operator=(const Device&) = delete;
|
||||
|
||||
void register_device()
|
||||
{
|
||||
registered = true;
|
||||
lx_device_handle = lx_emul_usb_client_register_device(usb_handle, "usb_nic");
|
||||
if (!lx_device_handle) {
|
||||
registered = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (usb_config != 0)
|
||||
lx_emul_usb_client_set_configuration(usb_handle, lx_device_handle, usb_config);
|
||||
|
||||
}
|
||||
|
||||
void unregister_device()
|
||||
{
|
||||
force_uplink_destroy = true;
|
||||
lx_emul_usb_client_unregister_device(usb_handle, lx_device_handle);
|
||||
registered = false;
|
||||
force_uplink_destroy = false;
|
||||
}
|
||||
|
||||
void handle_task_state()
|
||||
{
|
||||
lx_emul_task_unblock(state_task);
|
||||
Lx_kit::env().scheduler.execute();
|
||||
}
|
||||
|
||||
void handle_urb()
|
||||
{
|
||||
lx_emul_task_unblock(urb_task);
|
||||
Lx_kit::env().scheduler.execute();
|
||||
genode_uplink_notify_peers();
|
||||
}
|
||||
|
||||
void handle_nic()
|
||||
{
|
||||
if (!user_task_struct_ptr)
|
||||
return;
|
||||
|
||||
lx_emul_task_unblock(user_task_struct_ptr);
|
||||
Lx_kit::env().scheduler.execute();
|
||||
}
|
||||
|
||||
void handle_config()
|
||||
{
|
||||
config_rom.update();
|
||||
genode_mac_address_reporter_config(config_rom.xml());
|
||||
|
||||
/* read USB configuration setting */
|
||||
unsigned long config = config_rom.xml().attribute_value("configuration", 0ul);
|
||||
if (registered && config != 0 && config != usb_config)
|
||||
lx_emul_usb_client_set_configuration(usb_handle, lx_device_handle, config);
|
||||
|
||||
usb_config = config;
|
||||
|
||||
/* retrieve possible MAC */
|
||||
Nic::Mac_address mac;
|
||||
try {
|
||||
Xml_node::Attribute mac_node = config_rom.xml().attribute("mac");
|
||||
mac_node.value(mac);
|
||||
mac.copy(mac_address);
|
||||
use_mac_address = true;
|
||||
log("Trying to use configured mac: ", mac);
|
||||
} catch (...) {
|
||||
use_mac_address = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********
|
||||
** Task **
|
||||
**********/
|
||||
|
||||
static int state_task_entry(void *arg)
|
||||
{
|
||||
Device &device = *reinterpret_cast<Device *>(arg);
|
||||
|
||||
while (true) {
|
||||
if (genode_usb_client_plugged(device.usb_handle) && !device.registered)
|
||||
device.register_device();
|
||||
|
||||
if (!genode_usb_client_plugged(device.usb_handle) && device.registered)
|
||||
device.unregister_device();
|
||||
lx_emul_task_schedule(true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int urb_task_entry(void *arg)
|
||||
{
|
||||
Device &device = *reinterpret_cast<Device *>(arg);
|
||||
|
||||
while (true) {
|
||||
if (device.registered) {
|
||||
genode_usb_client_execute_completions(device.usb_handle);
|
||||
}
|
||||
|
||||
lx_emul_task_schedule(true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Main
|
||||
{
|
||||
Env &env;
|
||||
|
||||
Signal_handler<Main> signal_handler { env.ep(), *this, &Main::handle_signal };
|
||||
|
||||
Main(Env &env) : env(env) { }
|
||||
|
||||
void handle_signal()
|
||||
{
|
||||
Lx_kit::env().scheduler.execute();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Component::construct(Env & env)
|
||||
{
|
||||
static Main main { env };
|
||||
Lx_kit::initialize(env, main.signal_handler);
|
||||
|
||||
env.exec_static_constructors();
|
||||
|
||||
lx_emul_start_kernel(nullptr);
|
||||
}
|
||||
|
||||
|
||||
/**********
|
||||
** Task **
|
||||
**********/
|
||||
|
||||
int lx_user_main_task(void *)
|
||||
{
|
||||
/* one device only */
|
||||
static Device dev(Lx_kit::env().env);
|
||||
|
||||
return 0;
|
||||
}
|
1066
repos/dde_linux/src/drivers/usb_net/spec/arm/generated_dummies.c
Normal file
1066
repos/dde_linux/src/drivers/usb_net/spec/arm/generated_dummies.c
Normal file
File diff suppressed because it is too large
Load Diff
87
repos/dde_linux/src/drivers/usb_net/spec/arm/source.list
Normal file
87
repos/dde_linux/src/drivers/usb_net/spec/arm/source.list
Normal file
@ -0,0 +1,87 @@
|
||||
arch/arm/lib/clearbit.S
|
||||
arch/arm/lib/div64.S
|
||||
arch/arm/lib/findbit.S
|
||||
arch/arm/lib/setbit.S
|
||||
arch/arm/lib/strchr.S
|
||||
arch/arm/lib/testclearbit.S
|
||||
arch/arm/lib/testsetbit.S
|
||||
drivers/base/bus.c
|
||||
drivers/base/core.c
|
||||
drivers/base/class.c
|
||||
drivers/base/devres.c
|
||||
drivers/base/driver.c
|
||||
drivers/base/dd.c
|
||||
drivers/base/property.c
|
||||
drivers/net/mii.c
|
||||
drivers/net/usb/asix_common.c
|
||||
drivers/net/usb/asix_devices.c
|
||||
drivers/net/usb/asix.h
|
||||
drivers/net/usb/ax88172a.c
|
||||
drivers/net/usb/ax88179_178a.c
|
||||
drivers/net/usb/cdc_ether.c
|
||||
drivers/net/usb/cdc_mbim.c
|
||||
drivers/net/usb/cdc_ncm.c
|
||||
drivers/net/usb/usbnet.c
|
||||
drivers/usb/class/cdc-wdm.c
|
||||
drivers/usb/core/config.c
|
||||
drivers/usb/core/driver.c
|
||||
drivers/usb/core/generic.c
|
||||
drivers/usb/core/hub.c
|
||||
drivers/usb/core/quirks.c
|
||||
drivers/usb/core/usb.c
|
||||
fs/nls/nls_base.c
|
||||
kernel/kthread.c
|
||||
kernel/locking/mutex.c
|
||||
kernel/locking/osq_lock.c
|
||||
kernel/locking/rwsem.c
|
||||
kernel/notifier.c
|
||||
kernel/sched/build_utility.c
|
||||
kernel/smpboot.c
|
||||
kernel/softirq.c
|
||||
kernel/time/clockevents.c
|
||||
kernel/time/clocksource.c
|
||||
kernel/time/hrtimer.c
|
||||
kernel/time/jiffies.c
|
||||
kernel/time/ntp.c
|
||||
kernel/time/tick-broadcast.c
|
||||
kernel/time/tick-broadcast-hrtimer.c
|
||||
kernel/time/tick-common.c
|
||||
kernel/time/tick-oneshot.c
|
||||
kernel/time/tick-sched.c
|
||||
kernel/time/time.c
|
||||
kernel/time/timeconv.c
|
||||
kernel/time/timecounter.c
|
||||
kernel/time/timekeeping.c
|
||||
kernel/time/timer.c
|
||||
kernel/time/timer_list.c
|
||||
kernel/workqueue.c
|
||||
lib/bitmap.c
|
||||
lib/crc16.c
|
||||
lib/crc32.c
|
||||
lib/ctype.c
|
||||
lib/find_bit.c
|
||||
lib/hexdump.c
|
||||
lib/hweight.c
|
||||
lib/idr.c
|
||||
lib/kasprintf.c
|
||||
lib/klist.c
|
||||
lib/kobject.c
|
||||
lib/kstrtox.c
|
||||
lib/radix-tree.c
|
||||
lib/rhashtable.c
|
||||
lib/rbtree.c
|
||||
lib/xarray.c
|
||||
lib/siphash.c
|
||||
lib/string.c
|
||||
lib/string_helpers.c
|
||||
lib/timerqueue.c
|
||||
lib/vsprintf.c
|
||||
mm/util.c
|
||||
net/core/dev.c
|
||||
net/core/dev_addr_lists.c
|
||||
net/core/link_watch.c
|
||||
net/core/skbuff.c
|
||||
net/core/xdp.c
|
||||
net/ethernet/eth.c
|
||||
net/ethtool/common.c
|
||||
net/sched/sch_generic.c
|
3
repos/dde_linux/src/drivers/usb_net/spec/arm/target.mk
Normal file
3
repos/dde_linux/src/drivers/usb_net/spec/arm/target.mk
Normal file
@ -0,0 +1,3 @@
|
||||
REQUIRES := arm
|
||||
|
||||
include $(PRG_DIR)/../../target.inc
|
1047
repos/dde_linux/src/drivers/usb_net/spec/arm_64/generated_dummies.c
Normal file
1047
repos/dde_linux/src/drivers/usb_net/spec/arm_64/generated_dummies.c
Normal file
File diff suppressed because it is too large
Load Diff
86
repos/dde_linux/src/drivers/usb_net/spec/arm_64/source.list
Normal file
86
repos/dde_linux/src/drivers/usb_net/spec/arm_64/source.list
Normal file
@ -0,0 +1,86 @@
|
||||
arch/arm64/lib/memcmp.S
|
||||
arch/arm64/lib/strchr.S
|
||||
arch/arm64/lib/strcmp.S
|
||||
arch/arm64/lib/strlen.S
|
||||
arch/arm64/lib/strncmp.S
|
||||
arch/arm64/lib/strnlen.S
|
||||
drivers/base/bus.c
|
||||
drivers/base/core.c
|
||||
drivers/base/class.c
|
||||
drivers/base/devres.c
|
||||
drivers/base/driver.c
|
||||
drivers/base/dd.c
|
||||
drivers/base/property.c
|
||||
drivers/net/mii.c
|
||||
drivers/net/usb/asix_common.c
|
||||
drivers/net/usb/asix_devices.c
|
||||
drivers/net/usb/asix.h
|
||||
drivers/net/usb/ax88172a.c
|
||||
drivers/net/usb/ax88179_178a.c
|
||||
drivers/net/usb/cdc_ether.c
|
||||
drivers/net/usb/cdc_mbim.c
|
||||
drivers/net/usb/cdc_ncm.c
|
||||
drivers/net/usb/usbnet.c
|
||||
drivers/usb/class/cdc-wdm.c
|
||||
drivers/usb/core/config.c
|
||||
drivers/usb/core/driver.c
|
||||
drivers/usb/core/generic.c
|
||||
drivers/usb/core/hub.c
|
||||
drivers/usb/core/quirks.c
|
||||
drivers/usb/core/usb.c
|
||||
fs/nls/nls_base.c
|
||||
kernel/kthread.c
|
||||
kernel/locking/mutex.c
|
||||
kernel/locking/osq_lock.c
|
||||
kernel/locking/rwsem.c
|
||||
kernel/notifier.c
|
||||
kernel/sched/build_utility.c
|
||||
kernel/smpboot.c
|
||||
kernel/softirq.c
|
||||
kernel/time/clockevents.c
|
||||
kernel/time/clocksource.c
|
||||
kernel/time/hrtimer.c
|
||||
kernel/time/jiffies.c
|
||||
kernel/time/ntp.c
|
||||
kernel/time/tick-broadcast.c
|
||||
kernel/time/tick-broadcast-hrtimer.c
|
||||
kernel/time/tick-common.c
|
||||
kernel/time/tick-oneshot.c
|
||||
kernel/time/tick-sched.c
|
||||
kernel/time/time.c
|
||||
kernel/time/timeconv.c
|
||||
kernel/time/timecounter.c
|
||||
kernel/time/timekeeping.c
|
||||
kernel/time/timer.c
|
||||
kernel/time/timer_list.c
|
||||
kernel/workqueue.c
|
||||
lib/bitmap.c
|
||||
lib/crc16.c
|
||||
lib/crc32.c
|
||||
lib/ctype.c
|
||||
lib/find_bit.c
|
||||
lib/hexdump.c
|
||||
lib/hweight.c
|
||||
lib/idr.c
|
||||
lib/kasprintf.c
|
||||
lib/klist.c
|
||||
lib/kobject.c
|
||||
lib/kstrtox.c
|
||||
lib/radix-tree.c
|
||||
lib/rhashtable.c
|
||||
lib/rbtree.c
|
||||
lib/xarray.c
|
||||
lib/siphash.c
|
||||
lib/string.c
|
||||
lib/string_helpers.c
|
||||
lib/timerqueue.c
|
||||
lib/vsprintf.c
|
||||
mm/util.c
|
||||
net/core/dev.c
|
||||
net/core/dev_addr_lists.c
|
||||
net/core/link_watch.c
|
||||
net/core/skbuff.c
|
||||
net/core/xdp.c
|
||||
net/ethernet/eth.c
|
||||
net/ethtool/common.c
|
||||
net/sched/sch_generic.c
|
@ -0,0 +1,5 @@
|
||||
REQUIRES := arm_64
|
||||
|
||||
SRC_C += lx_emul/shadow/arch/arm64/kernel/smp.c
|
||||
|
||||
include $(PRG_DIR)/../../target.inc
|
@ -0,0 +1,948 @@
|
||||
/*
|
||||
* \brief Dummy definitions of Linux Kernel functions
|
||||
* \author Automatically generated file - do no edit
|
||||
* \date 2023-08-18
|
||||
*/
|
||||
|
||||
#include <lx_emul.h>
|
||||
|
||||
|
||||
#include <linux/gfp.h>
|
||||
|
||||
struct page * __alloc_pages(gfp_t gfp,unsigned int order,int preferred_nid,nodemask_t * nodemask)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/cpumask.h>
|
||||
|
||||
struct cpumask __cpu_active_mask;
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int __devm_mdiobus_register(struct device * dev,struct mii_bus * bus,struct module * owner)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/mm.h>
|
||||
|
||||
void __folio_put(struct folio * folio)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/ipv6.h>
|
||||
|
||||
int __ipv6_addr_type(const struct in6_addr * addr)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int __mdiobus_register(struct mii_bus * bus,struct module * owner)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/printk.h>
|
||||
|
||||
int __printk_ratelimit(const char * func)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/printk.h>
|
||||
|
||||
void __printk_safe_enter(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/printk.h>
|
||||
|
||||
void __printk_safe_exit(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sched/task.h>
|
||||
|
||||
void __put_task_struct(struct task_struct * tsk)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
void __skb_get_hash(struct sk_buff * skb)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
void * __vmalloc_node_range(unsigned long size,unsigned long align,unsigned long start,unsigned long end,gfp_t gfp_mask,pgprot_t prot,unsigned long vm_flags,int node,const void * caller)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/printk.h>
|
||||
|
||||
int _printk_deferred(const char * fmt,...)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void ack_bad_irq(unsigned int irq);
|
||||
void ack_bad_irq(unsigned int irq)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/kobject.h>
|
||||
|
||||
int add_uevent_var(struct kobj_uevent_env * env,const char * format,...)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/async.h>
|
||||
|
||||
async_cookie_t async_schedule_node(async_func_t func,void * data,int node)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/async.h>
|
||||
|
||||
void async_synchronize_full(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/filter.h>
|
||||
|
||||
void bpf_warn_invalid_xdp_action(struct net_device * dev,struct bpf_prog * prog,u32 act)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/bitrev.h>
|
||||
|
||||
u8 const byte_rev_table[256] = {};
|
||||
|
||||
|
||||
#include <linux/context_tracking_irq.h>
|
||||
|
||||
noinstr void ct_irq_enter(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/context_tracking_irq.h>
|
||||
|
||||
noinstr void ct_irq_exit(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
struct mii_bus * devm_mdiobus_alloc_size(struct device * dev,int sizeof_priv)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/math64.h>
|
||||
|
||||
u64 div64_u64(u64 dividend,u64 divisor)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/math64.h>
|
||||
|
||||
u64 div64_u64_rem(u64 dividend,u64 divisor,u64 * remainder)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/math64.h>
|
||||
|
||||
s64 div_s64_rem(s64 dividend,s32 divisor,s32 * remainder)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/netlink.h>
|
||||
|
||||
void do_trace_netlink_extack(const char * msg)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/dst.h>
|
||||
|
||||
void dst_release(struct dst_entry * dst)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/printk.h>
|
||||
|
||||
asmlinkage __visible void dump_stack(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
void ethtool_convert_legacy_u32_to_link_mode(unsigned long * dst,u32 legacy_u32)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
bool ethtool_convert_link_mode_to_legacy_u32(u32 * legacy_u32,const unsigned long * src)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
u32 ethtool_op_get_link(struct net_device * dev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
int ethtool_op_get_ts_info(struct net_device * dev,struct ethtool_ts_info * info)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/capability.h>
|
||||
|
||||
bool file_ns_capable(const struct file * file,struct user_namespace * ns,int cap)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rcuwait.h>
|
||||
|
||||
void finish_rcuwait(struct rcuwait * w)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int genphy_resume(struct phy_device * phydev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/gfp.h>
|
||||
|
||||
bool gfp_pfmemalloc_allowed(gfp_t gfp_mask)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
struct packet_offload * gro_find_complete_by_type(__be16 type)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
struct packet_offload * gro_find_receive_by_type(__be16 type)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/uuid.h>
|
||||
|
||||
const u8 guid_index[16] = {};
|
||||
|
||||
|
||||
#include <linux/mm.h>
|
||||
|
||||
void * high_memory;
|
||||
|
||||
|
||||
#include <net/addrconf.h>
|
||||
|
||||
void in6_dev_finish_destroy(struct inet6_dev * idev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
unsigned long init_stack[THREAD_SIZE / sizeof(unsigned long)] = {};
|
||||
|
||||
|
||||
#include <linux/utsname.h>
|
||||
|
||||
struct user_namespace init_user_ns;
|
||||
|
||||
|
||||
#include <linux/init.h>
|
||||
|
||||
bool initcall_debug;
|
||||
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
void __sched io_schedule(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
void io_schedule_finish(int token)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
int io_schedule_prepare(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
long __sched io_schedule_timeout(long timeout)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
int irq_can_set_affinity(unsigned int irq)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
int irq_set_affinity(unsigned int irq,const struct cpumask * cpumask)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/irq_work.h>
|
||||
|
||||
void irq_work_tick(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
int kmem_cache_alloc_bulk(struct kmem_cache * s,gfp_t flags,size_t nr,void ** p)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
void * kmem_cache_alloc_lru(struct kmem_cache * cachep,struct list_lru * lru,gfp_t flags)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
void kmem_cache_free_bulk(struct kmem_cache * s,size_t nr,void ** p)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/kobject.h>
|
||||
|
||||
int kobject_synth_uevent(struct kobject * kobj,const char * buf,size_t count)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/kobject.h>
|
||||
|
||||
int kobject_uevent_env(struct kobject * kobj,enum kobject_action action,char * envp_ext[])
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
struct pernet_operations __net_initdata loopback_net_ops;
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
struct mii_bus * mdiobus_alloc_size(size_t size)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
void mdiobus_free(struct mii_bus * bus)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/mdio.h>
|
||||
|
||||
struct phy_device * mdiobus_get_phy(struct mii_bus * bus,int addr)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
void mdiobus_unregister(struct mii_bus * bus)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/preempt.h>
|
||||
|
||||
void migrate_disable(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/preempt.h>
|
||||
|
||||
void migrate_enable(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/sch_generic.h>
|
||||
|
||||
struct Qdisc_ops mq_qdisc_ops;
|
||||
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
void napi_gro_flush(struct napi_struct * napi,bool flush_old)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/net.h>
|
||||
|
||||
int net_ratelimit(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/selftests.h>
|
||||
|
||||
void net_selftest(struct net_device * ndev,struct ethtool_test * etest,u64 * buf)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/selftests.h>
|
||||
|
||||
int net_selftest_get_count(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/selftests.h>
|
||||
|
||||
void net_selftest_get_strings(u8 * data)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/netlink.h>
|
||||
|
||||
int nla_put(struct sk_buff * skb,int attrtype,int attrlen,const void * data)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/fs.h>
|
||||
|
||||
loff_t noop_llseek(struct file * file,loff_t offset,int whence)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
int param_set_copystring(const char * val,const struct kernel_param * kp)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
void phy_attached_info(struct phy_device * phydev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
struct phy_device * phy_connect(struct net_device * dev,const char * bus_id,void (* handler)(struct net_device *),phy_interface_t interface)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
void phy_disconnect(struct phy_device * phydev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int phy_do_ioctl_running(struct net_device * dev,struct ifreq * ifr,int cmd)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int phy_ethtool_get_link_ksettings(struct net_device * ndev,struct ethtool_link_ksettings * cmd)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int phy_ethtool_nway_reset(struct net_device * ndev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int phy_ethtool_set_link_ksettings(struct net_device * ndev,const struct ethtool_link_ksettings * cmd)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
void phy_print_status(struct phy_device * phydev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
void phy_start(struct phy_device * phydev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
void phy_stop(struct phy_device * phydev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int phy_suspend(struct phy_device * phydev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
int phylink_connect_phy(struct phylink * pl,struct phy_device * phy)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
struct phylink * phylink_create(struct phylink_config * config,struct fwnode_handle * fwnode,phy_interface_t iface,const struct phylink_mac_ops * mac_ops)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_destroy(struct phylink * pl)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_disconnect_phy(struct phylink * pl)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_ethtool_get_pauseparam(struct phylink * pl,struct ethtool_pauseparam * pause)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
int phylink_ethtool_set_pauseparam(struct phylink * pl,struct ethtool_pauseparam * pause)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_generic_validate(struct phylink_config * config,unsigned long * supported,struct phylink_link_state * state)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_resume(struct phylink * pl)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_start(struct phylink * pl)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_stop(struct phylink * pl)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_suspend(struct phylink * pl,bool mac_wol)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/refcount.h>
|
||||
|
||||
void refcount_warn_saturate(refcount_t * r,enum refcount_saturation_type t)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
void rtmsg_ifinfo_send(struct sk_buff * skb,struct net_device * dev,gfp_t flags)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/scatterlist.h>
|
||||
|
||||
void sg_init_table(struct scatterlist * sgl,unsigned int nents)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/sock.h>
|
||||
|
||||
void sk_error_report(struct sock * sk)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
struct sk_buff * skb_mac_gso_segment(struct sk_buff * skb,netdev_features_t features)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/smp.h>
|
||||
|
||||
void smp_call_function_many(const struct cpumask * mask,smp_call_func_t func,void * info,bool wait)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/smp.h>
|
||||
|
||||
int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/sock.h>
|
||||
|
||||
void sock_edemux(struct sk_buff * skb)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/jump_label.h>
|
||||
|
||||
bool static_key_initialized;
|
||||
|
||||
|
||||
#include <net/sock.h>
|
||||
|
||||
int sysctl_tstamp_allow_data;
|
||||
|
||||
|
||||
#include <linux/tcp.h>
|
||||
|
||||
struct sk_buff * tcp_get_timestamping_opt_stats(const struct sock * sk,const struct sk_buff * orig_skb,const struct sk_buff * ack_skb)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb.h>
|
||||
|
||||
int usb_clear_halt(struct usb_device * dev,int pipe)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void usb_devio_cleanup(void);
|
||||
void usb_devio_cleanup(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void usb_disable_endpoint(struct usb_device * dev,unsigned int epaddr,bool reset_hardware);
|
||||
void usb_disable_endpoint(struct usb_device * dev,unsigned int epaddr,bool reset_hardware)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb.h>
|
||||
|
||||
int usb_free_streams(struct usb_interface * interface,struct usb_host_endpoint ** eps,unsigned int num_eps,gfp_t mem_flags)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern int usb_get_device_descriptor(struct usb_device * dev,unsigned int size);
|
||||
int usb_get_device_descriptor(struct usb_device * dev,unsigned int size)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb.h>
|
||||
|
||||
int usb_get_status(struct usb_device * dev,int recip,int type,int target,void * data)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb/hcd.h>
|
||||
|
||||
int usb_hcd_alloc_bandwidth(struct usb_device * udev,struct usb_host_config * new_config,struct usb_host_interface * cur_alt,struct usb_host_interface * new_alt)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb/hcd.h>
|
||||
|
||||
int usb_hcd_find_raw_port_number(struct usb_hcd * hcd,int port1)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern int usb_hub_create_port_device(struct usb_hub * hub,int port1);
|
||||
int usb_hub_create_port_device(struct usb_hub * hub,int port1)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void usb_hub_remove_port_device(struct usb_hub * hub,int port1);
|
||||
void usb_hub_remove_port_device(struct usb_hub * hub,int port1)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void usb_major_cleanup(void);
|
||||
void usb_major_cleanup(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern int usb_set_isoch_delay(struct usb_device * dev);
|
||||
int usb_set_isoch_delay(struct usb_device * dev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb/ch9.h>
|
||||
|
||||
const char * usb_speed_string(enum usb_device_speed speed)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb.h>
|
||||
|
||||
void usb_unpoison_urb(struct urb * urb)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/uuid.h>
|
||||
|
||||
const u8 uuid_index[16] = {};
|
||||
|
||||
|
||||
#include <linux/sched/wake_q.h>
|
||||
|
||||
void wake_q_add_safe(struct wake_q_head * head,struct task_struct * task)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/filter.h>
|
||||
|
||||
int xdp_do_generic_redirect(struct net_device * dev,struct sk_buff * skb,struct xdp_buff * xdp,struct bpf_prog * xdp_prog)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/filter.h>
|
||||
|
||||
u32 xdp_master_redirect(struct xdp_buff * xdp)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
79
repos/dde_linux/src/drivers/usb_net/spec/x86_32/source.list
Normal file
79
repos/dde_linux/src/drivers/usb_net/spec/x86_32/source.list
Normal file
@ -0,0 +1,79 @@
|
||||
arch/x86/lib/hweight.S
|
||||
drivers/base/bus.c
|
||||
drivers/base/core.c
|
||||
drivers/base/class.c
|
||||
drivers/base/devres.c
|
||||
drivers/base/driver.c
|
||||
drivers/base/dd.c
|
||||
drivers/base/property.c
|
||||
drivers/net/mii.c
|
||||
drivers/net/usb/asix_common.c
|
||||
drivers/net/usb/asix_devices.c
|
||||
drivers/net/usb/asix.h
|
||||
drivers/net/usb/ax88172a.c
|
||||
drivers/net/usb/ax88179_178a.c
|
||||
drivers/net/usb/cdc_ether.c
|
||||
drivers/net/usb/cdc_mbim.c
|
||||
drivers/net/usb/cdc_ncm.c
|
||||
drivers/net/usb/usbnet.c
|
||||
drivers/usb/class/cdc-wdm.c
|
||||
drivers/usb/core/config.c
|
||||
drivers/usb/core/driver.c
|
||||
drivers/usb/core/generic.c
|
||||
drivers/usb/core/hub.c
|
||||
drivers/usb/core/quirks.c
|
||||
drivers/usb/core/usb.c
|
||||
fs/nls/nls_base.c
|
||||
kernel/kthread.c
|
||||
kernel/locking/mutex.c
|
||||
kernel/locking/osq_lock.c
|
||||
kernel/locking/rwsem.c
|
||||
kernel/notifier.c
|
||||
kernel/sched/build_utility.c
|
||||
kernel/smpboot.c
|
||||
kernel/softirq.c
|
||||
kernel/time/clockevents.c
|
||||
kernel/time/clocksource.c
|
||||
kernel/time/hrtimer.c
|
||||
kernel/time/jiffies.c
|
||||
kernel/time/ntp.c
|
||||
kernel/time/tick-broadcast.c
|
||||
kernel/time/tick-common.c
|
||||
kernel/time/tick-oneshot.c
|
||||
kernel/time/tick-sched.c
|
||||
kernel/time/time.c
|
||||
kernel/time/timeconv.c
|
||||
kernel/time/timecounter.c
|
||||
kernel/time/timekeeping.c
|
||||
kernel/time/timer.c
|
||||
kernel/time/timer_list.c
|
||||
kernel/workqueue.c
|
||||
lib/bitmap.c
|
||||
lib/crc16.c
|
||||
lib/crc32.c
|
||||
lib/ctype.c
|
||||
lib/find_bit.c
|
||||
lib/hexdump.c
|
||||
lib/idr.c
|
||||
lib/kasprintf.c
|
||||
lib/klist.c
|
||||
lib/kobject.c
|
||||
lib/kstrtox.c
|
||||
lib/radix-tree.c
|
||||
lib/rhashtable.c
|
||||
lib/rbtree.c
|
||||
lib/xarray.c
|
||||
lib/siphash.c
|
||||
lib/string.c
|
||||
lib/string_helpers.c
|
||||
lib/timerqueue.c
|
||||
lib/vsprintf.c
|
||||
mm/util.c
|
||||
net/core/dev.c
|
||||
net/core/dev_addr_lists.c
|
||||
net/core/link_watch.c
|
||||
net/core/skbuff.c
|
||||
net/core/xdp.c
|
||||
net/ethernet/eth.c
|
||||
net/ethtool/common.c
|
||||
net/sched/sch_generic.c
|
@ -0,0 +1,3 @@
|
||||
REQUIRES := x86_32
|
||||
|
||||
include $(PRG_DIR)/../../target.inc
|
@ -0,0 +1,921 @@
|
||||
/*
|
||||
* \brief Dummy definitions of Linux Kernel functions
|
||||
* \author Automatically generated file - do no edit
|
||||
* \date 2023-07-17
|
||||
*/
|
||||
|
||||
#include <lx_emul.h>
|
||||
|
||||
|
||||
#include <linux/gfp.h>
|
||||
|
||||
struct page * __alloc_pages(gfp_t gfp,unsigned int order,int preferred_nid,nodemask_t * nodemask)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/cpumask.h>
|
||||
|
||||
struct cpumask __cpu_active_mask;
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int __devm_mdiobus_register(struct device * dev,struct mii_bus * bus,struct module * owner)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/mm.h>
|
||||
|
||||
void __folio_put(struct folio * folio)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/ipv6.h>
|
||||
|
||||
int __ipv6_addr_type(const struct in6_addr * addr)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int __mdiobus_register(struct mii_bus * bus,struct module * owner)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/printk.h>
|
||||
|
||||
int __printk_ratelimit(const char * func)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/printk.h>
|
||||
|
||||
void __printk_safe_enter(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/printk.h>
|
||||
|
||||
void __printk_safe_exit(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sched/task.h>
|
||||
|
||||
void __put_task_struct(struct task_struct * tsk)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
void __skb_get_hash(struct sk_buff * skb)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
void * __vmalloc_node_range(unsigned long size,unsigned long align,unsigned long start,unsigned long end,gfp_t gfp_mask,pgprot_t prot,unsigned long vm_flags,int node,const void * caller)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/printk.h>
|
||||
|
||||
int _printk_deferred(const char * fmt,...)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void ack_bad_irq(unsigned int irq);
|
||||
void ack_bad_irq(unsigned int irq)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/kobject.h>
|
||||
|
||||
int add_uevent_var(struct kobj_uevent_env * env,const char * format,...)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/async.h>
|
||||
|
||||
async_cookie_t async_schedule_node(async_func_t func,void * data,int node)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/async.h>
|
||||
|
||||
void async_synchronize_full(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/filter.h>
|
||||
|
||||
void bpf_warn_invalid_xdp_action(struct net_device * dev,struct bpf_prog * prog,u32 act)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/bitrev.h>
|
||||
|
||||
u8 const byte_rev_table[256] = {};
|
||||
|
||||
|
||||
#include <linux/context_tracking_irq.h>
|
||||
|
||||
noinstr void ct_irq_enter(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/context_tracking_irq.h>
|
||||
|
||||
noinstr void ct_irq_exit(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
struct mii_bus * devm_mdiobus_alloc_size(struct device * dev,int sizeof_priv)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/netlink.h>
|
||||
|
||||
void do_trace_netlink_extack(const char * msg)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/dst.h>
|
||||
|
||||
void dst_release(struct dst_entry * dst)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/printk.h>
|
||||
|
||||
asmlinkage __visible void dump_stack(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
void ethtool_convert_legacy_u32_to_link_mode(unsigned long * dst,u32 legacy_u32)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
bool ethtool_convert_link_mode_to_legacy_u32(u32 * legacy_u32,const unsigned long * src)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
u32 ethtool_op_get_link(struct net_device * dev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
int ethtool_op_get_ts_info(struct net_device * dev,struct ethtool_ts_info * info)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/capability.h>
|
||||
|
||||
bool file_ns_capable(const struct file * file,struct user_namespace * ns,int cap)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rcuwait.h>
|
||||
|
||||
void finish_rcuwait(struct rcuwait * w)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int genphy_resume(struct phy_device * phydev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/gfp.h>
|
||||
|
||||
bool gfp_pfmemalloc_allowed(gfp_t gfp_mask)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
struct packet_offload * gro_find_complete_by_type(__be16 type)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
struct packet_offload * gro_find_receive_by_type(__be16 type)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/uuid.h>
|
||||
|
||||
const u8 guid_index[16] = {};
|
||||
|
||||
|
||||
#include <net/addrconf.h>
|
||||
|
||||
void in6_dev_finish_destroy(struct inet6_dev * idev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/utsname.h>
|
||||
|
||||
struct user_namespace init_user_ns;
|
||||
|
||||
|
||||
#include <linux/init.h>
|
||||
|
||||
bool initcall_debug;
|
||||
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
void __sched io_schedule(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
void io_schedule_finish(int token)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
int io_schedule_prepare(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
long __sched io_schedule_timeout(long timeout)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/swiotlb.h>
|
||||
|
||||
struct io_tlb_mem io_tlb_default_mem;
|
||||
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
int irq_can_set_affinity(unsigned int irq)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
int irq_set_affinity(unsigned int irq,const struct cpumask * cpumask)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/irq_work.h>
|
||||
|
||||
void irq_work_tick(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
int kmem_cache_alloc_bulk(struct kmem_cache * s,gfp_t flags,size_t nr,void ** p)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
void * kmem_cache_alloc_lru(struct kmem_cache * cachep,struct list_lru * lru,gfp_t flags)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
void kmem_cache_free_bulk(struct kmem_cache * s,size_t nr,void ** p)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/kobject.h>
|
||||
|
||||
int kobject_synth_uevent(struct kobject * kobj,const char * buf,size_t count)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/kobject.h>
|
||||
|
||||
int kobject_uevent_env(struct kobject * kobj,enum kobject_action action,char * envp_ext[])
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
struct pernet_operations __net_initdata loopback_net_ops;
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
struct mii_bus * mdiobus_alloc_size(size_t size)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
void mdiobus_free(struct mii_bus * bus)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/mdio.h>
|
||||
|
||||
struct phy_device * mdiobus_get_phy(struct mii_bus * bus,int addr)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
void mdiobus_unregister(struct mii_bus * bus)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/preempt.h>
|
||||
|
||||
void migrate_disable(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/preempt.h>
|
||||
|
||||
void migrate_enable(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/sch_generic.h>
|
||||
|
||||
struct Qdisc_ops mq_qdisc_ops;
|
||||
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
void napi_gro_flush(struct napi_struct * napi,bool flush_old)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/net.h>
|
||||
|
||||
int net_ratelimit(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/selftests.h>
|
||||
|
||||
void net_selftest(struct net_device * ndev,struct ethtool_test * etest,u64 * buf)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/selftests.h>
|
||||
|
||||
int net_selftest_get_count(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/selftests.h>
|
||||
|
||||
void net_selftest_get_strings(u8 * data)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/netlink.h>
|
||||
|
||||
int nla_put(struct sk_buff * skb,int attrtype,int attrlen,const void * data)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/fs.h>
|
||||
|
||||
loff_t noop_llseek(struct file * file,loff_t offset,int whence)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
int param_set_copystring(const char * val,const struct kernel_param * kp)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
void phy_attached_info(struct phy_device * phydev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
struct phy_device * phy_connect(struct net_device * dev,const char * bus_id,void (* handler)(struct net_device *),phy_interface_t interface)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
void phy_disconnect(struct phy_device * phydev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int phy_do_ioctl_running(struct net_device * dev,struct ifreq * ifr,int cmd)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int phy_ethtool_get_link_ksettings(struct net_device * ndev,struct ethtool_link_ksettings * cmd)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int phy_ethtool_nway_reset(struct net_device * ndev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int phy_ethtool_set_link_ksettings(struct net_device * ndev,const struct ethtool_link_ksettings * cmd)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
void phy_print_status(struct phy_device * phydev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
void phy_start(struct phy_device * phydev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
void phy_stop(struct phy_device * phydev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phy.h>
|
||||
|
||||
int phy_suspend(struct phy_device * phydev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
int phylink_connect_phy(struct phylink * pl,struct phy_device * phy)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
struct phylink * phylink_create(struct phylink_config * config,struct fwnode_handle * fwnode,phy_interface_t iface,const struct phylink_mac_ops * mac_ops)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_destroy(struct phylink * pl)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_disconnect_phy(struct phylink * pl)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_ethtool_get_pauseparam(struct phylink * pl,struct ethtool_pauseparam * pause)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
int phylink_ethtool_set_pauseparam(struct phylink * pl,struct ethtool_pauseparam * pause)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_generic_validate(struct phylink_config * config,unsigned long * supported,struct phylink_link_state * state)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_resume(struct phylink * pl)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_start(struct phylink * pl)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_stop(struct phylink * pl)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/phylink.h>
|
||||
|
||||
void phylink_suspend(struct phylink * pl,bool mac_wol)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/refcount.h>
|
||||
|
||||
void refcount_warn_saturate(refcount_t * r,enum refcount_saturation_type t)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
void rtmsg_ifinfo_send(struct sk_buff * skb,struct net_device * dev,gfp_t flags)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/scatterlist.h>
|
||||
|
||||
void sg_init_table(struct scatterlist * sgl,unsigned int nents)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/sock.h>
|
||||
|
||||
void sk_error_report(struct sock * sk)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
struct sk_buff * skb_mac_gso_segment(struct sk_buff * skb,netdev_features_t features)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/smp.h>
|
||||
|
||||
void smp_call_function_many(const struct cpumask * mask,smp_call_func_t func,void * info,bool wait)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/smp.h>
|
||||
|
||||
int smp_call_function_single(int cpu,smp_call_func_t func,void * info,int wait)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <net/sock.h>
|
||||
|
||||
void sock_edemux(struct sk_buff * skb)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/jump_label.h>
|
||||
|
||||
bool static_key_initialized;
|
||||
|
||||
|
||||
#include <net/sock.h>
|
||||
|
||||
int sysctl_tstamp_allow_data;
|
||||
|
||||
|
||||
#include <linux/tcp.h>
|
||||
|
||||
struct sk_buff * tcp_get_timestamping_opt_stats(const struct sock * sk,const struct sk_buff * orig_skb,const struct sk_buff * ack_skb)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb.h>
|
||||
|
||||
int usb_clear_halt(struct usb_device * dev,int pipe)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb.h>
|
||||
|
||||
extern void usb_devio_cleanup(void);
|
||||
void usb_devio_cleanup(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void usb_disable_endpoint(struct usb_device * dev,unsigned int epaddr,bool reset_hardware);
|
||||
void usb_disable_endpoint(struct usb_device * dev,unsigned int epaddr,bool reset_hardware)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb.h>
|
||||
|
||||
int usb_free_streams(struct usb_interface * interface,struct usb_host_endpoint ** eps,unsigned int num_eps,gfp_t mem_flags)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern int usb_get_device_descriptor(struct usb_device * dev,unsigned int size);
|
||||
int usb_get_device_descriptor(struct usb_device * dev,unsigned int size)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb.h>
|
||||
|
||||
int usb_get_status(struct usb_device * dev,int recip,int type,int target,void * data)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb/hcd.h>
|
||||
|
||||
int usb_hcd_alloc_bandwidth(struct usb_device * udev,struct usb_host_config * new_config,struct usb_host_interface * cur_alt,struct usb_host_interface * new_alt)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb/hcd.h>
|
||||
|
||||
int usb_hcd_find_raw_port_number(struct usb_hcd * hcd,int port1)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern int usb_hub_create_port_device(struct usb_hub * hub,int port1);
|
||||
int usb_hub_create_port_device(struct usb_hub * hub,int port1)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void usb_hub_remove_port_device(struct usb_hub * hub,int port1);
|
||||
void usb_hub_remove_port_device(struct usb_hub * hub,int port1)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern void usb_major_cleanup(void);
|
||||
void usb_major_cleanup(void)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
extern int usb_set_isoch_delay(struct usb_device * dev);
|
||||
int usb_set_isoch_delay(struct usb_device * dev)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb/ch9.h>
|
||||
|
||||
const char * usb_speed_string(enum usb_device_speed speed)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/usb.h>
|
||||
|
||||
void usb_unpoison_urb(struct urb * urb)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/uuid.h>
|
||||
|
||||
const u8 uuid_index[16] = {};
|
||||
|
||||
|
||||
#include <linux/sched/wake_q.h>
|
||||
|
||||
void wake_q_add_safe(struct wake_q_head * head,struct task_struct * task)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/filter.h>
|
||||
|
||||
int xdp_do_generic_redirect(struct net_device * dev,struct sk_buff * skb,struct xdp_buff * xdp,struct bpf_prog * xdp_prog)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
||||
|
||||
#include <linux/filter.h>
|
||||
|
||||
u32 xdp_master_redirect(struct xdp_buff * xdp)
|
||||
{
|
||||
lx_emul_trace_and_stop(__func__);
|
||||
}
|
||||
|
79
repos/dde_linux/src/drivers/usb_net/spec/x86_64/source.list
Normal file
79
repos/dde_linux/src/drivers/usb_net/spec/x86_64/source.list
Normal file
@ -0,0 +1,79 @@
|
||||
arch/x86/lib/hweight.S
|
||||
drivers/base/bus.c
|
||||
drivers/base/core.c
|
||||
drivers/base/class.c
|
||||
drivers/base/devres.c
|
||||
drivers/base/driver.c
|
||||
drivers/base/dd.c
|
||||
drivers/base/property.c
|
||||
drivers/net/mii.c
|
||||
drivers/net/usb/asix_common.c
|
||||
drivers/net/usb/asix_devices.c
|
||||
drivers/net/usb/asix.h
|
||||
drivers/net/usb/ax88172a.c
|
||||
drivers/net/usb/ax88179_178a.c
|
||||
drivers/net/usb/cdc_ether.c
|
||||
drivers/net/usb/cdc_mbim.c
|
||||
drivers/net/usb/cdc_ncm.c
|
||||
drivers/net/usb/usbnet.c
|
||||
drivers/usb/class/cdc-wdm.c
|
||||
drivers/usb/core/config.c
|
||||
drivers/usb/core/driver.c
|
||||
drivers/usb/core/generic.c
|
||||
drivers/usb/core/hub.c
|
||||
drivers/usb/core/quirks.c
|
||||
drivers/usb/core/usb.c
|
||||
fs/nls/nls_base.c
|
||||
kernel/kthread.c
|
||||
kernel/locking/mutex.c
|
||||
kernel/locking/osq_lock.c
|
||||
kernel/locking/rwsem.c
|
||||
kernel/notifier.c
|
||||
kernel/sched/build_utility.c
|
||||
kernel/smpboot.c
|
||||
kernel/softirq.c
|
||||
kernel/time/clockevents.c
|
||||
kernel/time/clocksource.c
|
||||
kernel/time/hrtimer.c
|
||||
kernel/time/jiffies.c
|
||||
kernel/time/ntp.c
|
||||
kernel/time/tick-broadcast.c
|
||||
kernel/time/tick-common.c
|
||||
kernel/time/tick-oneshot.c
|
||||
kernel/time/tick-sched.c
|
||||
kernel/time/time.c
|
||||
kernel/time/timeconv.c
|
||||
kernel/time/timecounter.c
|
||||
kernel/time/timekeeping.c
|
||||
kernel/time/timer.c
|
||||
kernel/time/timer_list.c
|
||||
kernel/workqueue.c
|
||||
lib/bitmap.c
|
||||
lib/crc16.c
|
||||
lib/crc32.c
|
||||
lib/ctype.c
|
||||
lib/find_bit.c
|
||||
lib/hexdump.c
|
||||
lib/idr.c
|
||||
lib/kasprintf.c
|
||||
lib/klist.c
|
||||
lib/kobject.c
|
||||
lib/kstrtox.c
|
||||
lib/radix-tree.c
|
||||
lib/rhashtable.c
|
||||
lib/rbtree.c
|
||||
lib/xarray.c
|
||||
lib/siphash.c
|
||||
lib/string.c
|
||||
lib/string_helpers.c
|
||||
lib/timerqueue.c
|
||||
lib/vsprintf.c
|
||||
mm/util.c
|
||||
net/core/dev.c
|
||||
net/core/dev_addr_lists.c
|
||||
net/core/link_watch.c
|
||||
net/core/skbuff.c
|
||||
net/core/xdp.c
|
||||
net/ethernet/eth.c
|
||||
net/ethtool/common.c
|
||||
net/sched/sch_generic.c
|
@ -0,0 +1,3 @@
|
||||
REQUIRES := x86_64
|
||||
|
||||
include $(PRG_DIR)/../../target.inc
|
36
repos/dde_linux/src/drivers/usb_net/target.inc
Normal file
36
repos/dde_linux/src/drivers/usb_net/target.inc
Normal file
@ -0,0 +1,36 @@
|
||||
TARGET = usb_net_drv
|
||||
LIBS = base jitterentropy virt_lx_emul
|
||||
|
||||
INC_DIR = $(PRG_DIR)/../..
|
||||
|
||||
SRC_C += dummies.c \
|
||||
generated_dummies.c \
|
||||
lx_emul.c \
|
||||
lx_user.c
|
||||
|
||||
SRC_C += lx_emul/virt/shadow/drivers/usb/core/message.c \
|
||||
lx_emul/virt/shadow/drivers/usb/core/urb.c \
|
||||
lx_emul/virt/usb_client.c
|
||||
|
||||
SRC_CC = main.cc \
|
||||
wdm_terminal.cc
|
||||
|
||||
SRC_CC += lx_emul/random.cc
|
||||
|
||||
SRC_CC += genode_c_api/mac_address_reporter.cc \
|
||||
genode_c_api/usb_client.cc \
|
||||
genode_c_api/uplink.cc
|
||||
|
||||
|
||||
vpath %.c $(PRG_DIR)
|
||||
vpath %.c $(PRG_DIR)/../..
|
||||
vpath %.cc $(PRG_DIR)/../..
|
||||
vpath %.c $(REP_DIR)/src/lib
|
||||
|
||||
C_API = $(dir $(call select_from_repositories,src/lib/genode_c_api))
|
||||
|
||||
vpath genode_c_api/mac_address_reporter.cc $(C_API)
|
||||
vpath genode_c_api/uplink.cc $(C_API)
|
||||
vpath genode_c_api/usb_client.cc $(C_API)
|
||||
|
||||
# vim: set ft=make :
|
45
repos/dde_linux/src/drivers/usb_net/usb_net.h
Normal file
45
repos/dde_linux/src/drivers/usb_net/usb_net.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* \brief C/C++ interface for this driver
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2023-07-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <lx_emul/usb_client.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct task_struct;
|
||||
|
||||
int lx_user_main_task(void *);
|
||||
struct task_struct *lx_user_new_usb_task(int (*func)(void*), void *args);
|
||||
|
||||
struct lx_wdm
|
||||
{
|
||||
unsigned long *data_avail;
|
||||
void *buffer;
|
||||
void *handle;
|
||||
unsigned active;
|
||||
};
|
||||
|
||||
int lx_wdm_read(void *args);
|
||||
int lx_wdm_write(void *args);
|
||||
int lx_wdm_device(void *args);
|
||||
|
||||
void lx_wdm_create_root(void);
|
||||
void lx_wdm_schedule_read(void *handle);
|
||||
void lx_wdm_signal_data_avail(void *handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
214
repos/dde_linux/src/drivers/usb_net/wdm_terminal.cc
Normal file
214
repos/dde_linux/src/drivers/usb_net/wdm_terminal.cc
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* \brief Service providing the 'Terminal_session' interface for cdc-wdm file
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2023-08-16
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#include <base/attached_ram_dataspace.h>
|
||||
#include <base/log.h>
|
||||
#include <os/session_policy.h>
|
||||
#include <root/component.h>
|
||||
#include <terminal_session/terminal_session.h>
|
||||
|
||||
#include <lx_emul/task.h>
|
||||
#include <lx_kit/env.h>
|
||||
#include <usb_net.h>
|
||||
|
||||
namespace Terminal {
|
||||
class Session_component;
|
||||
class Root;
|
||||
}
|
||||
|
||||
|
||||
class Terminal::Session_component : public Genode::Rpc_object<Session, Session_component>
|
||||
{
|
||||
using size_t = Genode::size_t;
|
||||
|
||||
private:
|
||||
|
||||
enum State { WRITE, READ };
|
||||
|
||||
Genode::Attached_ram_dataspace _io_buffer;
|
||||
Genode::Signal_context_capability _read_avail_sigh { };
|
||||
|
||||
State _state { WRITE };
|
||||
size_t _data_avail { 0 };
|
||||
|
||||
struct lx_wdm _wdm_data { &_data_avail, buffer(), this, 1 };
|
||||
|
||||
task_struct *_write_task { lx_user_new_usb_task(lx_wdm_write, &_wdm_data) };
|
||||
task_struct *_read_task { lx_user_new_usb_task(lx_wdm_read, &_wdm_data) };
|
||||
task_struct *_device_task { lx_user_new_usb_task(lx_wdm_device, nullptr) };
|
||||
|
||||
/* non-copyable */
|
||||
Session_component(const Session_component&) = delete;
|
||||
Session_component & operator=(const Session_component&) = delete;
|
||||
|
||||
public:
|
||||
|
||||
Session_component(Genode::Env &env,
|
||||
Genode::size_t io_buffer_size)
|
||||
:
|
||||
_io_buffer(env.ram(), env.rm(), io_buffer_size)
|
||||
{ }
|
||||
|
||||
void schedule_read()
|
||||
{
|
||||
lx_emul_task_unblock(_read_task);
|
||||
}
|
||||
|
||||
void schedule_write()
|
||||
{
|
||||
lx_emul_task_unblock(_write_task);
|
||||
}
|
||||
|
||||
/********************************
|
||||
** Terminal session interface **
|
||||
********************************/
|
||||
|
||||
Size size() override { return Size(0, 0); }
|
||||
|
||||
bool avail() override
|
||||
{
|
||||
return _data_avail > 0;
|
||||
}
|
||||
|
||||
Genode::size_t _read(Genode::size_t dst_len)
|
||||
{
|
||||
if (_state != READ) return 0;
|
||||
|
||||
size_t length = Genode::min(dst_len, _data_avail);
|
||||
if (dst_len < _data_avail)
|
||||
Genode::warning("dst_len < data_avail (", dst_len, " < ", _data_avail, ") not supported");
|
||||
|
||||
_data_avail -= length;
|
||||
|
||||
if (_data_avail == 0) {
|
||||
_state = WRITE;
|
||||
schedule_read();
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
Genode::size_t _write(Genode::size_t num_bytes)
|
||||
{
|
||||
if (_state == READ) return 0;
|
||||
|
||||
_data_avail = num_bytes;
|
||||
_state = WRITE;
|
||||
|
||||
schedule_write();
|
||||
Lx_kit::env().scheduler.execute();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Genode::Dataspace_capability _dataspace()
|
||||
{
|
||||
return _io_buffer.cap();
|
||||
}
|
||||
|
||||
void read_avail_sigh(Genode::Signal_context_capability sigh) override
|
||||
{
|
||||
_read_avail_sigh = sigh;
|
||||
}
|
||||
|
||||
void connected_sigh(Genode::Signal_context_capability sigh) override
|
||||
{
|
||||
Genode::Signal_transmitter(sigh).submit();
|
||||
}
|
||||
|
||||
void size_changed_sigh(Genode::Signal_context_capability) override { }
|
||||
|
||||
size_t read(void *, size_t) override { return 0; }
|
||||
size_t write(void const *, size_t) override { return 0; }
|
||||
|
||||
void *buffer() { return _io_buffer.local_addr<void>(); }
|
||||
|
||||
void signal_data_avail()
|
||||
{
|
||||
if (_read_avail_sigh.valid() == false) return;
|
||||
_state = READ;
|
||||
Genode::Signal_transmitter(_read_avail_sigh).submit();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Terminal::Root : public Genode::Root_component<Session_component, Genode::Single_client>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
|
||||
task_struct *_create_task { lx_user_new_usb_task(_create_session, this) };
|
||||
|
||||
Genode::Constructible<Session_component> _session { };
|
||||
|
||||
static int _create_session(void *arg)
|
||||
{
|
||||
Root *root = static_cast<Root *>(arg);
|
||||
Genode::size_t const io_buffer_size = 4096ul;
|
||||
|
||||
while (true) {
|
||||
lx_emul_task_schedule(true);
|
||||
if (!root->_session.constructed())
|
||||
root->_session.construct(root->_env, io_buffer_size);
|
||||
}
|
||||
}
|
||||
|
||||
/* non-copyable */
|
||||
Root(const Root&) = delete;
|
||||
Root & operator=(const Root&) = delete;
|
||||
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(const char *) override
|
||||
{
|
||||
if (!_session.constructed()) {
|
||||
lx_emul_task_unblock(_create_task);
|
||||
Lx_kit::env().scheduler.execute();
|
||||
}
|
||||
return &*_session;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Root(Genode::Env &env,
|
||||
Genode::Allocator &md_alloc)
|
||||
:
|
||||
Genode::Root_component<Session_component, Genode::Single_client>(&env.ep().rpc_ep(), &md_alloc),
|
||||
_env(env)
|
||||
{
|
||||
_env.parent().announce(_env.ep().manage(*this));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void lx_wdm_schedule_read(void *handle)
|
||||
{
|
||||
using namespace Terminal;
|
||||
Session_component *session = static_cast<Session_component *>(handle);
|
||||
session->schedule_read();
|
||||
}
|
||||
|
||||
|
||||
void lx_wdm_signal_data_avail(void *handle)
|
||||
{
|
||||
using namespace Terminal;
|
||||
Session_component *session = static_cast<Session_component *>(handle);
|
||||
session->signal_data_avail();
|
||||
}
|
||||
|
||||
|
||||
void lx_wdm_create_root(void)
|
||||
{
|
||||
new (Lx_kit::env().heap) Terminal::Root(Lx_kit::env().env, Lx_kit::env().heap);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user