mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
parent
b09e69a444
commit
27004e1fd5
@ -162,10 +162,6 @@ capture-session and event-session interfaces respectively.
|
||||
:_dde_linux/src/drivers/usb_hid/_:
|
||||
USB Human Interface Device driver using the USB session interface.
|
||||
|
||||
:_os/src/drivers/usb_block/_:
|
||||
USB storage driver that uses the USB session interface and provides
|
||||
a block-session interface.
|
||||
|
||||
|
||||
Timer drivers
|
||||
=============
|
||||
@ -220,11 +216,6 @@ _os/include/block_session/_.
|
||||
:_os/src/drivers/sd_card/spec/rpi/_:
|
||||
Driver for SD-cards connected to the Raspberry Pi.
|
||||
|
||||
:_dde_linux/src/drivers/usb/_:
|
||||
USB driver that makes USB storage devices available as block sessions.
|
||||
For an example of using this driver, refer to the run script at
|
||||
_dde_linux/run/usb_storage.run_.
|
||||
|
||||
:_os/src/drivers/ahci/_:
|
||||
Driver for SATA disks and CD-ROMs on x86 PCs.
|
||||
|
||||
@ -232,7 +223,8 @@ _os/include/block_session/_.
|
||||
Driver for NVMe block devices on x86 PCs.
|
||||
|
||||
:_os/src/drivers/usb_block/_:
|
||||
USB Mass Storage Bulk-Only driver using the USB session interface.
|
||||
USB Mass Storage Bulk-Only driver using the USB session interface and provides
|
||||
a block-session interface.
|
||||
|
||||
|
||||
Network interface drivers
|
||||
@ -257,8 +249,8 @@ defined at _os/include/nic_session/_.
|
||||
The wifi_drv component is a port of the Linux mac802.11 stack, including the
|
||||
iwlwifi driver. It enables the use of Intel Wireless 6xxx and 7xxx cards.
|
||||
|
||||
:_dde_linux/src/drivers/usb/_:
|
||||
For the OMAP4 platform, the USB driver contains the networking driver.
|
||||
:_dde_linux/src/drivers/usb_net/_:
|
||||
USB network driver using the USB session interface.
|
||||
|
||||
:_dde_linux/src/drivers/nic/fec/_:
|
||||
Driver for ethernet NICs of the i.MX SoC family.
|
||||
|
@ -3,174 +3,27 @@ Device drivers ported from the Linux kernel
|
||||
USB
|
||||
###
|
||||
|
||||
Controller configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Host controller
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
The driver can be started using different or all USB controller types a platform
|
||||
offers (USB 1.0/2.0/3.0). Note that not all controllers are supported by all
|
||||
platforms. Controllers can be enabled as attribute in the config node of the
|
||||
driver. Supported attributes are: 'uhci', 'ohci', 'ehci', and 'xhci'.
|
||||
The driver will start all USB controller types a platform offers.
|
||||
|
||||
|
||||
Configuration snippet to enable UHCI and EHCI
|
||||
|
||||
! <config uhci="yes" ehci="yes">
|
||||
|
||||
BIOS Handoff
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Per default the USB driver performs a hand off of the USB controller from the
|
||||
BIOS, since it still may access the controller when booting, for example, from
|
||||
a USB device. The BIOS hand off induces the execution of BIOS/SMM USB driver
|
||||
code and potentially DMA operations. Unfortunately, some ACPI tables report
|
||||
wrong RMRR information, which implicates IOMMU faults on illegal DMA
|
||||
operations and consequently the hand off may fail after noticeably long
|
||||
timeouts. Therefore, the hand off can be disabled in the USB driver
|
||||
configuration like follows.
|
||||
|
||||
! <config bios_handoff="no"/>
|
||||
Please consult repos/dde_linux/drivers/usb_host/README for a description.
|
||||
|
||||
HID
|
||||
~~~
|
||||
|
||||
Supports keyboard and mouse. A run script can be found under 'run/usb_hid.run'.
|
||||
|
||||
Configuration snippet:
|
||||
|
||||
!<start name="usb_drv">
|
||||
! <resource name="RAM" quantum="12M"/>
|
||||
! <config uhci="yes" ohci="yes" ehci="yes" xhci="yes">
|
||||
! <hid/>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
With '<hid>' config node in place, the USB driver requests an "Event" session
|
||||
for reporting input events.
|
||||
|
||||
Note: It has been observed that certain 1.0 versions of Qemu do not generate
|
||||
mouse interrupts. The mouse driver should work correctly on Qemu 1.0.93 and
|
||||
above.
|
||||
|
||||
HID - Touchscreen support
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Touchscreen absolute coordinates must be calibrated (e.g. re-calculated) to
|
||||
screen absolute coordinates. The screen resolution is not determined
|
||||
automatically by the USB driver, but can be configured as sub node of the
|
||||
hid xml tag:
|
||||
|
||||
!...
|
||||
!<hid>
|
||||
! <touchscreen width="1024" height="768" multitouch="no"/>
|
||||
!</hid>
|
||||
!...
|
||||
|
||||
If a touchscreen is multi-touch-capable than the multitouch attribute gears
|
||||
which type of Genode input events are generated. If set to 'no' (default)
|
||||
than absolute events are generated and no multitouch events. If set to 'yes'
|
||||
solely multitouch events are generated.
|
||||
Please consult repos/dde_linux/drivers/usb_hid/README for a description.
|
||||
|
||||
Storage
|
||||
~~~~~~~
|
||||
|
||||
Currently supports one USB storage device. Hot plugging has not been tested. A
|
||||
run script can be found under 'run/usb_storage.run'.
|
||||
|
||||
Configuration snippet:
|
||||
|
||||
!<start name="usb_drv">
|
||||
! <resource name="RAM" quantum="12M"/>
|
||||
! <provides> <service name="Block"/> </provides>
|
||||
! <config><storage /></config>
|
||||
!</start>
|
||||
|
||||
Please consult repos/os/src/drivers/usb_block/README for a description.
|
||||
|
||||
Network (Nic)
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Configuration snippet:
|
||||
|
||||
!<start name="usb_drv">
|
||||
! <resource name="RAM" quantum="12M"/>
|
||||
! <provides>
|
||||
! <service name="Nic"/>
|
||||
! </provides>
|
||||
! <config ehci="yes" xhci="yes">
|
||||
! <nic mac="2e:60:90:0c:4e:01" />
|
||||
! <hid/>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
Please observe that this setup starts the HID and Nic service at the same time.
|
||||
Also there is the 'mac' attribute where one can specify the hardware address of
|
||||
the network interface. This is necessary in case the EEPROM of the network card
|
||||
cannot be accessed via the host controller making it impossible to retrieve the
|
||||
devices hardware address. If this is the case and no 'mac' attribute is given a
|
||||
fallback address will be assigned to the network device. Note that the fallback
|
||||
address will always be the same.
|
||||
|
||||
|
||||
RAW
|
||||
~~~
|
||||
|
||||
Allows raw access to USB devices via the 'Usb' session interface.
|
||||
|
||||
Configuration snippet:
|
||||
|
||||
!<start name="usb_drv">
|
||||
! <resource name="RAM" quantum="12M"/>
|
||||
! <provides><service name="Usb"/></provides>
|
||||
! <config uhci="yes" ohci="yes" ehci="yes" xhci="yes">
|
||||
! <raw>
|
||||
! <report devices="yes"/>
|
||||
! </raw>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
The optional 'devices' report lists the connected devices and gets updated
|
||||
when devices are added or removed.
|
||||
|
||||
Example report:
|
||||
|
||||
!<devices>
|
||||
! <device label="usb-1-7" vendor_id="0x1f75" product_id="0x0917" bus="0x0001" dev="0x0007"/>
|
||||
! <device label="usb-1-6" vendor_id="0x13fe" product_id="0x5200" bus="0x0001" dev="0x0006"/>
|
||||
! <device label="usb-1-4" vendor_id="0x17ef" product_id="0x4816" bus="0x0001" dev="0x0004"/>
|
||||
! <device label="usb-1-3" vendor_id="0x0a5c" product_id="0x217f" bus="0x0001" dev="0x0003"/>
|
||||
! <device label="usb-2-2" vendor_id="0x8087" product_id="0x0020" bus="0x0002" dev="0x0002"/>
|
||||
! <device label="usb-1-2" vendor_id="0x8087" product_id="0x0020" bus="0x0001" dev="0x0002"/>
|
||||
! <device label="usb-2-1" vendor_id="0x1d6b" product_id="0x0002" bus="0x0002" dev="0x0001"/>
|
||||
! <device label="usb-1-1" vendor_id="0x1d6b" product_id="0x0002" bus="0x0001" dev="0x0001"/>
|
||||
!</devices>
|
||||
|
||||
For every device a unique identifier is generated that is used to access the
|
||||
USB device. Only devices that have a valid policy configured at the USB driver
|
||||
can be accessed by a client. The following configuration allows 'comp1' to
|
||||
access the device 'usb-1-6':
|
||||
|
||||
!<start name="usb_drv">
|
||||
! <resource name="RAM" quantum="12M"/>
|
||||
! <provides><service name="Usb"/></provides>
|
||||
! <config uhci="yes" ohci="yes" ehci="yes" xhci="yes">
|
||||
! <raw>
|
||||
! <report devices="yes"/>
|
||||
! <policy label="comp1 -> usb-1-6" vendor_id="0x13fe" product_id="0x5200" bus="0x0001" dev="0x0006"/>
|
||||
! </raw>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
In addition to the mandatory 'label' attribute the policy node also
|
||||
contains optional attribute tuples of which at least one has to be present.
|
||||
The 'vendor_id' and 'product_id' tuple selects a device regardless of its
|
||||
location on the USB bus and is mostly used in static configurations. The
|
||||
'bus' and 'dev' tuple selects a specific device via its bus locations and
|
||||
device address. It is mostly used in dynamic configurations because the device
|
||||
address is not fixed and may change every time the same device is plugged in.
|
||||
|
||||
The configuration of the USB driver can be changed at runtime to satisfy
|
||||
dynamic configurations or rather policies when using the 'Usb' session
|
||||
interface.
|
||||
|
||||
Please consolut repos/dde_linux/src/drivers/usb_net/README for a description.
|
||||
|
||||
LXIP
|
||||
####
|
||||
|
@ -1,16 +0,0 @@
|
||||
USB_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/lib/usb
|
||||
|
||||
LIB_DIR := $(REP_DIR)/src/drivers/usb
|
||||
LIB_INC_DIR := $(LIB_DIR)/include
|
||||
|
||||
include $(call select_from_repositories,lib/import/import-usb_arch_include.mk)
|
||||
|
||||
#
|
||||
# The order of include-search directories is important, we need to look into
|
||||
# 'contrib' before falling back to our custom 'lx_emul.h' header.
|
||||
#
|
||||
INC_DIR += $(LIB_INC_DIR)
|
||||
INC_DIR += $(ARCH_SRC_INC_DIR)
|
||||
INC_DIR += $(USB_CONTRIB_DIR)/include
|
||||
INC_DIR += $(USB_CONTRIB_DIR)/drivers/usb/core
|
||||
INC_DIR += $(LIB_CACHE_DIR)/usb_include/include/include/include
|
@ -1,39 +0,0 @@
|
||||
ifeq ($(called_from_lib_mk),yes)
|
||||
|
||||
USB_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/lib/usb
|
||||
LX_EMUL_H := $(REP_DIR)/src/drivers/usb/include/lx_emul.h
|
||||
|
||||
#
|
||||
# Determine the header files included by the contrib code. For each
|
||||
# of these header files we create a symlink to 'lx_emul.h'.
|
||||
#
|
||||
SCAN_DIRS := $(addprefix $(USB_CONTRIB_DIR)/include/, asm-generic linux scsi uapi) \
|
||||
$(addprefix $(USB_CONTRIB_DIR)/, drivers lib)
|
||||
GEN_INCLUDES := $(shell grep -rIh "^\#include .*\/" $(SCAN_DIRS) |\
|
||||
sed "s/^\#include [^<\"]*[<\"]\([^>\"]*\)[>\"].*/\1/" |\
|
||||
sort | uniq)
|
||||
#
|
||||
# Filter out original Linux headers that exist in the contrib directory
|
||||
#
|
||||
NO_GEN_INCLUDES := $(shell cd $(USB_CONTRIB_DIR)/; find include -name "*.h" |\
|
||||
sed "s/.\///" | sed "s/.*include\///")
|
||||
GEN_INCLUDES := $(filter-out $(NO_GEN_INCLUDES),$(GEN_INCLUDES))
|
||||
|
||||
#
|
||||
# Put Linux headers in 'GEN_INC' dir, since some include use "../../" paths use
|
||||
# three level include hierarchy
|
||||
#
|
||||
GEN_INC := $(shell pwd)/include/include/include
|
||||
GEN_INCLUDES := $(addprefix $(GEN_INC)/,$(GEN_INCLUDES))
|
||||
|
||||
all: $(GEN_INCLUDES)
|
||||
|
||||
$(GEN_INCLUDES):
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)ln -s $(LX_EMUL_H) $@
|
||||
|
||||
endif
|
||||
|
||||
# vi: set ft=make :
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
@ -1,12 +0,0 @@
|
||||
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
|
||||
index e6338c1..b768fc8 100644
|
||||
--- a/drivers/net/usb/ax88179_178a.c
|
||||
+++ b/drivers/net/usb/ax88179_178a.c
|
||||
@@ -1266,6 +1266,7 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||
dev->net->netdev_ops = &ax88179_netdev_ops;
|
||||
dev->net->ethtool_ops = &ax88179_ethtool_ops;
|
||||
dev->net->needed_headroom = 8;
|
||||
+ dev->net->net_ip_align = 1;
|
||||
|
||||
/* Initialize MII structure */
|
||||
dev->mii.dev = dev->net;
|
@ -1,19 +0,0 @@
|
||||
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
|
||||
index 66b3ab9..a17f054 100644
|
||||
--- a/drivers/net/usb/smsc95xx.c
|
||||
+++ b/drivers/net/usb/smsc95xx.c
|
||||
@@ -1730,7 +1730,13 @@ static int smsc95xx_reset_resume(struct usb_interface *intf)
|
||||
|
||||
static void smsc95xx_rx_csum_offload(struct sk_buff *skb)
|
||||
{
|
||||
- skb->csum = *(u16 *)(skb_tail_pointer(skb) - 2);
|
||||
+ /*
|
||||
+ * Use bytewise access to avoid alignment issues on packets that have none
|
||||
+ * aligned sizes
|
||||
+ */
|
||||
+ char *tail = skb_tail_pointer(skb);
|
||||
+ skb->csum = (*(tail - 2) << 8) | *(tail - 1);
|
||||
+
|
||||
skb->ip_summed = CHECKSUM_COMPLETE;
|
||||
skb_trim(skb, skb->len - 2);
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
|
||||
index e9ae3d5..edd0b4f 100644
|
||||
--- a/drivers/input/evdev.c
|
||||
+++ b/drivers/input/evdev.c
|
||||
@@ -1425,6 +1425,9 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
|
||||
if (error)
|
||||
goto err_cleanup_evdev;
|
||||
|
||||
+ evdev_open_device(evdev);
|
||||
+ dev_info(evdev, "%s\n", dev->name);
|
||||
+
|
||||
return 0;
|
||||
|
||||
err_cleanup_evdev:
|
||||
@@ -1457,8 +1460,7 @@ static const struct input_device_id evdev_ids[] = {
|
||||
MODULE_DEVICE_TABLE(input, evdev_ids);
|
||||
|
||||
static struct input_handler evdev_handler = {
|
||||
- .event = evdev_event,
|
||||
- .events = evdev_events,
|
||||
+ .event = genode_evdev_event,
|
||||
.connect = evdev_connect,
|
||||
.disconnect = evdev_disconnect,
|
||||
.legacy_minors = true,
|
@ -1,24 +0,0 @@
|
||||
--- a/drivers/input/input-mt.c
|
||||
+++ b/drivers/input/input-mt.c
|
||||
@@ -217,10 +217,6 @@
|
||||
count++;
|
||||
}
|
||||
|
||||
- input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
|
||||
- if (use_count)
|
||||
- input_mt_report_finger_count(dev, count);
|
||||
-
|
||||
if (oldest) {
|
||||
int x = input_mt_get_value(oldest, ABS_MT_POSITION_X);
|
||||
int y = input_mt_get_value(oldest, ABS_MT_POSITION_Y);
|
||||
@@ -236,6 +232,10 @@
|
||||
if (test_bit(ABS_MT_PRESSURE, dev->absbit))
|
||||
input_event(dev, EV_ABS, ABS_PRESSURE, 0);
|
||||
}
|
||||
+
|
||||
+ input_event(dev, EV_KEY, BTN_TOUCH, count > 0);
|
||||
+ if (use_count)
|
||||
+ input_mt_report_finger_count(dev, count);
|
||||
}
|
||||
EXPORT_SYMBOL(input_mt_report_pointer_emulation);
|
||||
|
@ -1,327 +0,0 @@
|
||||
commit 91eb4a3e68978feca81f6a5bc31cfcd7c683d628
|
||||
Author: Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
Date: Tue Mar 15 09:59:11 2016 +0100
|
||||
|
||||
mem
|
||||
|
||||
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
|
||||
index 5dd426f..6b4294a 100644
|
||||
--- a/drivers/hid/usbhid/hid-core.c
|
||||
+++ b/drivers/hid/usbhid/hid-core.c
|
||||
@@ -841,7 +841,7 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
|
||||
&usbhid->inbuf_dma);
|
||||
usbhid->outbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
|
||||
&usbhid->outbuf_dma);
|
||||
- usbhid->cr = kmalloc(sizeof(*usbhid->cr), GFP_KERNEL);
|
||||
+ usbhid->cr = kmalloc(sizeof(*usbhid->cr), GFP_LX_DMA);
|
||||
usbhid->ctrlbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
|
||||
&usbhid->ctrlbuf_dma);
|
||||
if (!usbhid->inbuf || !usbhid->outbuf || !usbhid->cr ||
|
||||
@@ -1013,7 +1013,7 @@ static int usbhid_parse(struct hid_device *hid)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) {
|
||||
+ if (!(rdesc = kmalloc(rsize, GFP_LX_DMA))) {
|
||||
dbg_hid("couldn't allocate rdesc memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
|
||||
index 0744bf2..6237370 100644
|
||||
--- a/drivers/net/usb/usbnet.c
|
||||
+++ b/drivers/net/usb/usbnet.c
|
||||
@@ -229,7 +229,7 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf)
|
||||
period = max ((int) dev->status->desc.bInterval,
|
||||
(dev->udev->speed == USB_SPEED_HIGH) ? 7 : 3);
|
||||
|
||||
- buf = kmalloc (maxp, GFP_KERNEL);
|
||||
+ buf = kmalloc (maxp, GFP_LX_DMA);
|
||||
if (buf) {
|
||||
dev->interrupt = usb_alloc_urb (0, GFP_KERNEL);
|
||||
if (!dev->interrupt) {
|
||||
@@ -1916,7 +1916,7 @@ static int __usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
|
||||
cmd, reqtype, value, index, size);
|
||||
|
||||
if (data) {
|
||||
- buf = kmalloc(size, GFP_KERNEL);
|
||||
+ buf = kmalloc(size, GFP_LX_DMA);
|
||||
if (!buf)
|
||||
goto out;
|
||||
}
|
||||
@@ -1943,7 +1943,7 @@ static int __usbnet_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
|
||||
cmd, reqtype, value, index, size);
|
||||
|
||||
if (data) {
|
||||
- buf = kmemdup(data, size, GFP_KERNEL);
|
||||
+ buf = kmemdup(data, size, GFP_LX_DMA);
|
||||
if (!buf)
|
||||
goto out;
|
||||
}
|
||||
@@ -2192,7 +2192,7 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
|
||||
}
|
||||
|
||||
if (data) {
|
||||
- buf = kmemdup(data, size, GFP_ATOMIC);
|
||||
+ buf = kmemdup(data, size, GFP_LX_DMA);
|
||||
if (!buf) {
|
||||
netdev_err(dev->net, "Error allocating buffer"
|
||||
" in %s!\n", __func__);
|
||||
@@ -2200,7 +2200,7 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
|
||||
}
|
||||
}
|
||||
|
||||
- req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
|
||||
+ req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_LX_DMA);
|
||||
if (!req)
|
||||
goto fail_free_buf;
|
||||
|
||||
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
|
||||
index 5050760..9ac55f9 100644
|
||||
--- a/drivers/usb/core/config.c
|
||||
+++ b/drivers/usb/core/config.c
|
||||
@@ -695,7 +695,7 @@ int usb_get_configuration(struct usb_device *dev)
|
||||
if (!dev->rawdescriptors)
|
||||
goto err2;
|
||||
|
||||
- desc = kmalloc(USB_DT_CONFIG_SIZE, GFP_KERNEL);
|
||||
+ desc = kmalloc(USB_DT_CONFIG_SIZE, GFP_LX_DMA);
|
||||
if (!desc)
|
||||
goto err2;
|
||||
|
||||
@@ -724,7 +724,7 @@ int usb_get_configuration(struct usb_device *dev)
|
||||
USB_DT_CONFIG_SIZE);
|
||||
|
||||
/* Now that we know the length, get the whole thing */
|
||||
- bigbuffer = kmalloc(length, GFP_KERNEL);
|
||||
+ bigbuffer = kmalloc(length, GFP_LX_DMA);
|
||||
if (!bigbuffer) {
|
||||
result = -ENOMEM;
|
||||
goto err;
|
||||
@@ -786,7 +786,7 @@ int usb_get_bos_descriptor(struct usb_device *dev)
|
||||
int length, total_len, num, i;
|
||||
int ret;
|
||||
|
||||
- bos = kzalloc(sizeof(struct usb_bos_descriptor), GFP_KERNEL);
|
||||
+ bos = kzalloc(sizeof(struct usb_bos_descriptor), GFP_LX_DMA);
|
||||
if (!bos)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -812,7 +812,7 @@ int usb_get_bos_descriptor(struct usb_device *dev)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Now let's get the whole BOS descriptor set */
|
||||
- buffer = kzalloc(total_len, GFP_KERNEL);
|
||||
+ buffer = kzalloc(total_len, GFP_LX_DMA);
|
||||
if (!buffer) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
|
||||
index 1560f3f..54e99b5 100644
|
||||
--- a/drivers/usb/core/hub.c
|
||||
+++ b/drivers/usb/core/hub.c
|
||||
@@ -1365,20 +1365,20 @@ static int hub_configure(struct usb_hub *hub,
|
||||
unsigned full_load;
|
||||
unsigned maxchild;
|
||||
|
||||
- hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL);
|
||||
+ hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_LX_DMA);
|
||||
if (!hub->buffer) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL);
|
||||
+ hub->status = kmalloc(sizeof(*hub->status), GFP_LX_DMA);
|
||||
if (!hub->status) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
mutex_init(&hub->status_mutex);
|
||||
|
||||
- hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
|
||||
+ hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_LX_DMA);
|
||||
if (!hub->descriptor) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
@@ -4586,7 +4586,7 @@ check_highspeed(struct usb_hub *hub, struct usb_device *udev, int port1)
|
||||
if (udev->quirks & USB_QUIRK_DEVICE_QUALIFIER)
|
||||
return;
|
||||
|
||||
- qual = kmalloc(sizeof *qual, GFP_KERNEL);
|
||||
+ qual = kmalloc(sizeof *qual, GFP_LX_DMA);
|
||||
if (qual == NULL)
|
||||
return;
|
||||
|
||||
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
|
||||
index 8e641b5..5807f68 100644
|
||||
--- a/drivers/usb/core/message.c
|
||||
+++ b/drivers/usb/core/message.c
|
||||
@@ -942,7 +942,7 @@ int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)
|
||||
int usb_get_status(struct usb_device *dev, int type, int target, void *data)
|
||||
{
|
||||
int ret;
|
||||
- __le16 *status = kmalloc(sizeof(*status), GFP_KERNEL);
|
||||
+ __le16 *status = kmalloc(sizeof(*status), GFP_LX_DMA);
|
||||
|
||||
if (!status)
|
||||
return -ENOMEM;
|
||||
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
|
||||
index b6205fa..99cae0f 100644
|
||||
--- a/drivers/usb/host/ehci-mem.c
|
||||
+++ b/drivers/usb/host/ehci-mem.c
|
||||
@@ -82,7 +82,7 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
|
||||
struct ehci_qh *qh;
|
||||
dma_addr_t dma;
|
||||
|
||||
- qh = kzalloc(sizeof *qh, GFP_ATOMIC);
|
||||
+ qh = kzalloc(sizeof *qh, GFP_LX_DMA);
|
||||
if (!qh)
|
||||
goto done;
|
||||
qh->hw = (struct ehci_qh_hw *)
|
||||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
|
||||
index 776d59c..e32db7b 100644
|
||||
--- a/drivers/usb/host/xhci.c
|
||||
+++ b/drivers/usb/host/xhci.c
|
||||
@@ -1354,7 +1354,7 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
|
||||
size = 1;
|
||||
|
||||
urb_priv = kzalloc(sizeof(struct urb_priv) +
|
||||
- size * sizeof(struct xhci_td *), mem_flags);
|
||||
+ size * sizeof(struct xhci_td *), GFP_LX_DMA);
|
||||
if (!urb_priv)
|
||||
return -ENOMEM;
|
||||
|
||||
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
|
||||
index 43576ed..2b13b4e 100644
|
||||
--- a/drivers/usb/storage/usb.c
|
||||
+++ b/drivers/usb/storage/usb.c
|
||||
@@ -450,7 +450,7 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf)
|
||||
usb_set_intfdata(intf, us);
|
||||
|
||||
/* Allocate the control/setup and DMA-mapped buffers */
|
||||
- us->cr = kmalloc(sizeof(*us->cr), GFP_KERNEL);
|
||||
+ us->cr = kmalloc(sizeof(*us->cr), GFP_LX_DMA);
|
||||
if (!us->cr)
|
||||
return -ENOMEM;
|
||||
|
||||
--- a/drivers/hid/hid-multitouch.c
|
||||
+++ b/drivers/hid/hid-multitouch.c
|
||||
@@ -325,7 +325,7 @@
|
||||
if (td->mtclass.name != MT_CLS_WIN_8)
|
||||
return;
|
||||
|
||||
- buf = hid_alloc_report_buf(report, GFP_KERNEL);
|
||||
+ buf = hid_alloc_report_buf(report, GFP_LX_DMA);
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
@@ -912,7 +912,7 @@
|
||||
if (r) {
|
||||
if (cls->quirks & MT_QUIRK_FORCE_GET_FEATURE) {
|
||||
report_len = hid_report_len(r);
|
||||
- buf = hid_alloc_report_buf(r, GFP_KERNEL);
|
||||
+ buf = hid_alloc_report_buf(r, GFP_LX_DMA);
|
||||
if (!buf) {
|
||||
hid_err(hdev, "failed to allocate buffer for report\n");
|
||||
return;
|
||||
@@ -1043,7 +1043,7 @@
|
||||
if (suffix) {
|
||||
name = devm_kzalloc(&hi->input->dev,
|
||||
strlen(hdev->name) + strlen(suffix) + 2,
|
||||
- GFP_KERNEL);
|
||||
+ GFP_LX_DMA);
|
||||
if (name) {
|
||||
sprintf(name, "%s %s", hdev->name, suffix);
|
||||
hi->input->name = name;
|
||||
@@ -1096,7 +1096,7 @@
|
||||
*/
|
||||
hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
|
||||
|
||||
- td = devm_kzalloc(&hdev->dev, sizeof(struct mt_device), GFP_KERNEL);
|
||||
+ td = devm_kzalloc(&hdev->dev, sizeof(struct mt_device), GFP_LX_DMA);
|
||||
if (!td) {
|
||||
dev_err(&hdev->dev, "cannot allocate multitouch data\n");
|
||||
return -ENOMEM;
|
||||
@@ -1110,7 +1110,7 @@
|
||||
hid_set_drvdata(hdev, td);
|
||||
|
||||
td->fields = devm_kzalloc(&hdev->dev, sizeof(struct mt_fields),
|
||||
- GFP_KERNEL);
|
||||
+ GFP_LX_DMA);
|
||||
if (!td->fields) {
|
||||
dev_err(&hdev->dev, "cannot allocate multitouch fields data\n");
|
||||
return -ENOMEM;
|
||||
--- a/drivers/hid/wacom_sys.c
|
||||
+++ b/drivers/hid/wacom_sys.c
|
||||
@@ -124,7 +124,7 @@
|
||||
/* leave touch_max as is if predefined */
|
||||
if (!features->touch_max) {
|
||||
/* read manually */
|
||||
- data = kzalloc(2, GFP_KERNEL);
|
||||
+ data = kzalloc(2, GFP_LX_DMA);
|
||||
if (!data)
|
||||
break;
|
||||
data[0] = field->report->id;
|
||||
@@ -328,7 +328,7 @@
|
||||
unsigned char *rep_data;
|
||||
int error = -ENOMEM, limit = 0;
|
||||
|
||||
- rep_data = kzalloc(length, GFP_KERNEL);
|
||||
+ rep_data = kzalloc(length, GFP_LX_DMA);
|
||||
if (!rep_data)
|
||||
return error;
|
||||
|
||||
@@ -530,7 +530,7 @@
|
||||
|
||||
data = wacom_get_hdev_data(hdev);
|
||||
if (!data) {
|
||||
- data = kzalloc(sizeof(struct wacom_hdev_data), GFP_KERNEL);
|
||||
+ data = kzalloc(sizeof(struct wacom_hdev_data), GFP_LX_DMA);
|
||||
if (!data) {
|
||||
retval = -ENOMEM;
|
||||
goto out;
|
||||
@@ -595,7 +595,7 @@
|
||||
report_id = WAC_CMD_WL_LED_CONTROL;
|
||||
buf_size = 13;
|
||||
}
|
||||
- buf = kzalloc(buf_size, GFP_KERNEL);
|
||||
+ buf = kzalloc(buf_size, GFP_LX_DMA);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -648,7 +648,7 @@
|
||||
int i, retval;
|
||||
const unsigned chunk_len = len / 4; /* 4 chunks are needed to be sent */
|
||||
|
||||
- buf = kzalloc(chunk_len + 3 , GFP_KERNEL);
|
||||
+ buf = kzalloc(chunk_len + 3 , GFP_LX_DMA);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1176,7 +1176,7 @@
|
||||
|
||||
wacom_wac->serial[index] = serial;
|
||||
|
||||
- buf = kzalloc(WAC_REMOTE_SERIAL_MAX_STRLEN, GFP_KERNEL);
|
||||
+ buf = kzalloc(WAC_REMOTE_SERIAL_MAX_STRLEN, GFP_LX_DMA);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
snprintf(buf, WAC_REMOTE_SERIAL_MAX_STRLEN, "%d", serial);
|
||||
@@ -1222,7 +1222,7 @@
|
||||
unsigned char *buf;
|
||||
int retval;
|
||||
|
||||
- buf = kzalloc(buf_size, GFP_KERNEL);
|
||||
+ buf = kzalloc(buf_size, GFP_LX_DMA);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1705,7 +1705,7 @@
|
||||
/* hid-core sets this quirk for the boot interface */
|
||||
hdev->quirks &= ~HID_QUIRK_NOGET;
|
||||
|
||||
- wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
|
||||
+ wacom = kzalloc(sizeof(struct wacom), GFP_LX_DMA);
|
||||
if (!wacom)
|
||||
return -ENOMEM;
|
||||
|
@ -1,30 +0,0 @@
|
||||
diff -Nur a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
|
||||
--- a/drivers/net/usb/rndis_host.c
|
||||
+++ b/drivers/net/usb/rndis_host.c
|
||||
@@ -318,7 +318,7 @@
|
||||
unsigned char *bp;
|
||||
|
||||
/* we can't rely on i/o from stack working, or stack allocation */
|
||||
- u.buf = kmalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
|
||||
+ u.buf = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL | GFP_LX_DMA);
|
||||
if (!u.buf)
|
||||
return -ENOMEM;
|
||||
retval = usbnet_generic_cdc_bind(dev, intf);
|
||||
@@ -475,7 +475,7 @@
|
||||
struct rndis_halt *halt;
|
||||
|
||||
/* try to clear any rndis state/activity (no i/o from stack!) */
|
||||
- halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL);
|
||||
+ halt = kzalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL | GFP_LX_DMA);
|
||||
if (halt) {
|
||||
halt->msg_type = cpu_to_le32(RNDIS_MSG_HALT);
|
||||
halt->msg_len = cpu_to_le32(sizeof *halt);
|
||||
@@ -573,7 +573,7 @@
|
||||
* packets; Linux minimizes wasted bandwidth through tx queues.
|
||||
*/
|
||||
fill:
|
||||
- hdr = (void *) __skb_push(skb, sizeof *hdr);
|
||||
+ hdr = (void *) skb_push(skb, sizeof *hdr);
|
||||
memset(hdr, 0, sizeof *hdr);
|
||||
hdr->msg_type = cpu_to_le32(RNDIS_MSG_PACKET);
|
||||
hdr->msg_len = cpu_to_le32(skb->len);
|
@ -1,13 +0,0 @@
|
||||
diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c
|
||||
index 424ac5d..a2afc34 100644
|
||||
--- a/drivers/usb/host/ehci-timer.c
|
||||
+++ b/drivers/usb/host/ehci-timer.c
|
||||
@@ -422,7 +422,7 @@ static enum hrtimer_restart ehci_hrtimer_func(struct hrtimer *t)
|
||||
*/
|
||||
now = ktime_get();
|
||||
for_each_set_bit(e, &events, EHCI_HRTIMER_NUM_EVENTS) {
|
||||
- if (now.tv64 >= ehci->hr_timeouts[e].tv64)
|
||||
+ if (now >= ehci->hr_timeouts[e])
|
||||
event_handlers[e](ehci);
|
||||
else
|
||||
ehci_enable_event(ehci, e, false);
|
@ -1,37 +0,0 @@
|
||||
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
|
||||
index 6237370..8339402 100644
|
||||
--- a/drivers/net/usb/usbnet.c
|
||||
+++ b/drivers/net/usb/usbnet.c
|
||||
@@ -64,8 +64,30 @@
|
||||
* the equation.
|
||||
*/
|
||||
#define MAX_QUEUE_MEMORY (60 * 1518)
|
||||
-#define RX_QLEN(dev) ((dev)->rx_qlen)
|
||||
-#define TX_QLEN(dev) ((dev)->tx_qlen)
|
||||
+
|
||||
+inline unsigned RX_QLEN(struct usbnet *dev)
|
||||
+{
|
||||
+ switch(dev->udev->speed) {
|
||||
+ case USB_SPEED_HIGH:
|
||||
+ return MAX_QUEUE_MEMORY/dev->rx_urb_size;
|
||||
+ case USB_SPEED_SUPER:
|
||||
+ return 16;
|
||||
+ default:
|
||||
+ return 4;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+inline unsigned TX_QLEN(struct usbnet *dev)
|
||||
+{
|
||||
+ switch(dev->udev->speed) {
|
||||
+ case USB_SPEED_HIGH:
|
||||
+ return MAX_QUEUE_MEMORY/dev->hard_mtu;
|
||||
+ case USB_SPEED_SUPER:
|
||||
+ return 16;
|
||||
+ default:
|
||||
+ return 4;
|
||||
+ }
|
||||
+}
|
||||
|
||||
// reawaken network queue this soon after stopping; else watchdog barks
|
||||
#define TX_TIMEOUT_JIFFIES (5*HZ)
|
@ -1 +1 @@
|
||||
6f2e873679a79e8c85bdf62c2f81910b357f8abe
|
||||
c2dc5da56111d6a1734458679176722832b10207
|
||||
|
@ -1,6 +1,6 @@
|
||||
LICENSE := GPLv2
|
||||
VERSION := 2
|
||||
DOWNLOADS := dwc_otg.git usb.archive intel_fb.archive lxip.archive \
|
||||
DOWNLOADS := intel_fb.archive lxip.archive \
|
||||
wifi.archive fec.archive libnl.archive wpa_supplicant.git \
|
||||
fw.archive usb_host.archive dwc_otg_host.git usb_hid.archive \
|
||||
usb_modem.archive usb_net.archive imx8_fb.archive
|
||||
@ -18,21 +18,9 @@ YACC = bison
|
||||
# The git checkout checks for the existence of SRC_DIR, which is created by the
|
||||
# Linux extraction, therefore make sure to checkout the GIT sources first.
|
||||
#
|
||||
usb.archive: dwc_otg.git
|
||||
usb_host.archive: dwc_otg_host.git
|
||||
|
||||
|
||||
#
|
||||
# USB
|
||||
#
|
||||
SRC_DIR_USB := src/lib/usb
|
||||
VERSION_USB := 4.4.3
|
||||
URL(usb) := https://www.kernel.org/pub/linux/kernel/v4.x/linux-$(VERSION_USB).tar.xz
|
||||
SHA(usb) := 0b379cb19bbd7e38fc5a9a000ea927db55cce519a7400ec7fa705c581a6491dd
|
||||
DIR(usb) := $(SRC_DIR_USB)
|
||||
TAR_OPT(usb) := --strip-components=1 --files-from - < <(sed 's/-x.x.x/-$(VERSION_USB)/g' $(REP_DIR)/usb.list)
|
||||
HASH_INPUT += $(REP_DIR)/usb.list
|
||||
|
||||
#
|
||||
# USB host controller
|
||||
#
|
||||
@ -71,10 +59,6 @@ HASH_INPUT += $(REP_DIR)/usb_modem.list
|
||||
#
|
||||
# Raspberry Pi USB controller
|
||||
#
|
||||
URL(dwc_otg) := https://github.com/ssumpf/dwc_otg.git
|
||||
REV(dwc_otg) := r3
|
||||
DIR(dwc_otg) := $(SRC_DIR_USB)/drivers/usb/host/dwc_otg
|
||||
|
||||
URL(dwc_otg_host) := https://github.com/cproc/dwc_otg.git
|
||||
REV(dwc_otg_host) := r5
|
||||
DIR(dwc_otg_host) := $(SRC_DIR_USB_HOST)/drivers/usb/host
|
||||
@ -194,17 +178,6 @@ PATCH_OPT(patches/libnl.patch) := -p1 -d ${DIR(libnl)}
|
||||
# WPA supplicant
|
||||
PATCH_OPT(patches/wpa_supplicant.patch) := -p1 -d ${DIR(wpa_supplicant)}
|
||||
|
||||
# USB
|
||||
USB_OPT = -p1 -d$(SRC_DIR_USB)
|
||||
PATCH_OPT(patches/usb_ax88179.patch) := $(USB_OPT)
|
||||
PATCH_OPT(patches/usb_csum.patch) := $(USB_OPT)
|
||||
PATCH_OPT(patches/usb_evdev.patch) := $(USB_OPT)
|
||||
PATCH_OPT(patches/usb_input_mt.patch) := $(USB_OPT)
|
||||
PATCH_OPT(patches/usb_mem.patch) := $(USB_OPT)
|
||||
PATCH_OPT(patches/usb_usbnet.patch) := $(USB_OPT)
|
||||
PATCH_OPT(patches/usb_rndis.patch) := $(USB_OPT)
|
||||
PATCH_OPT(patches/usb_tv64.patch) := $(USB_OPT)
|
||||
|
||||
# USB HOST
|
||||
USB_HOST_OPT = -p1 -d$(SRC_DIR_USB_HOST)
|
||||
PATCH_OPT(patches/usb_host_mem.patch) := $(USB_HOST_OPT)
|
||||
|
@ -1,26 +0,0 @@
|
||||
LIB_MK := lib/import/import-usb_include.mk lib/mk/usb_include.mk \
|
||||
lib/import/import-usb_arch_include.mk \
|
||||
$(foreach SPEC,x86_32 x86_64 arm,lib/mk/spec/$(SPEC)/lx_kit_setjmp.mk)
|
||||
|
||||
PORT_DIR := $(call port_dir,$(REP_DIR)/ports/dde_linux)
|
||||
|
||||
MIRROR_FROM_REP_DIR := $(LIB_MK) \
|
||||
src/drivers/usb \
|
||||
src/include src/lx_kit
|
||||
|
||||
MIRROR_FROM_PORT_DIR := $(shell cd $(PORT_DIR); find src/lib/usb -type f | grep -v ".git")
|
||||
MIRROR_FROM_PORT_DIR := $(filter-out $(MIRROR_FROM_REP_DIR),$(MIRROR_FROM_PORT_DIR))
|
||||
|
||||
content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_PORT_DIR)
|
||||
|
||||
$(MIRROR_FROM_REP_DIR):
|
||||
$(mirror_from_rep_dir)
|
||||
|
||||
$(MIRROR_FROM_PORT_DIR):
|
||||
mkdir -p $(dir $@)
|
||||
cp $(PORT_DIR)/$@ $@
|
||||
|
||||
content: LICENSE
|
||||
LICENSE:
|
||||
( echo "GNU General Public License version 2, see:"; \
|
||||
echo "https://www.kernel.org/pub/linux/kernel/COPYING" ) > $@
|
@ -1 +0,0 @@
|
||||
2021-05-27 ca37c2f2c35387633aff258015e3bee29ff6109a
|
@ -1,12 +0,0 @@
|
||||
base
|
||||
os
|
||||
nic_session
|
||||
uplink_session
|
||||
nic_driver
|
||||
usb_session
|
||||
gpio_session
|
||||
event_session
|
||||
block_session
|
||||
platform_session
|
||||
timer_session
|
||||
report_session
|
@ -1,235 +0,0 @@
|
||||
#
|
||||
# USB HID test
|
||||
#
|
||||
# By default, the run script runs interactively and reports any received USB
|
||||
# input events to the console.
|
||||
#
|
||||
# When run with the '--autopilot' run option, the run script tests the USB
|
||||
# input events generated by a 'Pro Micro' microcontroller.
|
||||
#
|
||||
# Pro Micro setup instructions
|
||||
# ----------------------------
|
||||
#
|
||||
# Install prerequisites (example for Xubuntu 16.04):
|
||||
#
|
||||
# $ sudo apt-get install gcc-avr avr-libc avrdude
|
||||
#
|
||||
# Checkout and build the microcontroller software:
|
||||
#
|
||||
# $ git clone https://github.com/cproc/lufa.git
|
||||
# $ cd lufa
|
||||
# $ git checkout genode_usb_tests
|
||||
# $ cd Demos/Device/ClassDriver/KeyboardMouseGenode
|
||||
# $ make
|
||||
#
|
||||
# Connect the 'RST' pin with the 'GND' pin to hold the Pro Micro in the reset
|
||||
# state.
|
||||
#
|
||||
# Connect the Pro Micro to the host PC
|
||||
#
|
||||
# Check the device file name with 'dmesg'. If it is not 'ttyACM0', change
|
||||
# 'AVRDUDE_PORT' in 'makefile' accordingly.
|
||||
#
|
||||
# Release the RST/GND pin connection and within the next 8 seconds run:
|
||||
#
|
||||
# $ make avrdude
|
||||
#
|
||||
# Disconnect the Pro Micro or put it into reset state again to avoid unexpected
|
||||
# input events on the host PC.
|
||||
#
|
||||
|
||||
if { [get_cmd_switch --autopilot] && [have_include "power_on/qemu"] } {
|
||||
puts "Run script does not support autopilot mode on Qemu"
|
||||
exit 0
|
||||
}
|
||||
|
||||
if {![have_board rpi] && ![have_board pc]} {
|
||||
puts "Run script does not support autopilot mode on this platform"
|
||||
exit 0
|
||||
}
|
||||
|
||||
proc usb_drv_binary { } {
|
||||
if {[have_board rpi]} { return rpi_usb_drv }
|
||||
if {[have_board pc]} { return usb_drv }
|
||||
return no_usb_drv_available
|
||||
}
|
||||
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
set build_components {
|
||||
core init timer
|
||||
drivers/usb
|
||||
server/event_dump
|
||||
server/dynamic_rom
|
||||
}
|
||||
|
||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
append_platform_drv_build_components
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
|
||||
#
|
||||
# Generate config
|
||||
#
|
||||
|
||||
append config {
|
||||
<config prio_levels="2">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<default caps="100"/>}
|
||||
|
||||
append_platform_drv_config
|
||||
|
||||
append config {
|
||||
<start name="timer" priority="0">
|
||||
<resource name="CPU" quantum="10"/>
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
</start>
|
||||
|
||||
<start name="usb_drv" caps="150" priority="0">
|
||||
<binary name="} [usb_drv_binary] {"/>
|
||||
<resource name="RAM" quantum="12M"/>
|
||||
<resource name="CPU" quantum="80"/>
|
||||
<config uhci="yes" ohci="yes" ehci="yes" xhci="yes"
|
||||
capslock_led="rom" numlock_led="rom" scrlock_led="rom"
|
||||
bios_handoff="yes">
|
||||
<hid/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="ROM" label="capslock"> <child name="dynamic_rom"/> </service>
|
||||
<service name="ROM" label="numlock"> <child name="dynamic_rom"/> </service>
|
||||
<service name="ROM" label="scrlock"> <child name="dynamic_rom"/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="IO_PORT"> <parent/> </service>
|
||||
<service name="IO_MEM"> <parent/> </service>
|
||||
<service name="IRQ"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="RM"> <parent/> </service>
|
||||
<service name="Platform"> <any-child/> </service>
|
||||
<service name="Regulator"> <child name="platform_drv"/> </service>
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
<service name="Event"> <child name="event_dump"/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="dynamic_rom" priority="-1">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<provides> <service name="ROM"/> </provides>
|
||||
<config verbose="no">
|
||||
<rom name="capslock">
|
||||
<inline> <capslock enabled="no"/> </inline>
|
||||
<sleep milliseconds="250" />
|
||||
<inline> <capslock enabled="yes"/> </inline>
|
||||
<sleep milliseconds="250" />
|
||||
</rom>
|
||||
<rom name="numlock">
|
||||
<inline> <numlock enabled="no"/> </inline>
|
||||
<sleep milliseconds="500" />
|
||||
<inline> <numlock enabled="yes"/> </inline>
|
||||
<sleep milliseconds="500" />
|
||||
</rom>
|
||||
<rom name="scrlock">
|
||||
<inline> <scrlock enabled="no"/> </inline>
|
||||
<sleep milliseconds="1000" />
|
||||
<inline> <scrlock enabled="yes"/> </inline>
|
||||
<sleep milliseconds="1000" />
|
||||
</rom>
|
||||
</config>
|
||||
<route>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="event_dump" priority="-1">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Event"/> </provides>
|
||||
<config/>
|
||||
</start>
|
||||
</config>}
|
||||
|
||||
install_config $config
|
||||
|
||||
#
|
||||
# Boot modules
|
||||
#
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core ld.lib.so init timer event_dump dynamic_rom
|
||||
}
|
||||
|
||||
append boot_modules [usb_drv_binary]
|
||||
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
append qemu_args " -usb -usbdevice mouse -usbdevice keyboard"
|
||||
append qemu_args " -device usb-ehci,id=ehci"
|
||||
append xen_args { usbdevice=\["mouse","keyboard"\] }
|
||||
|
||||
if { [have_include "power_on/qemu"] || ![get_cmd_switch --autopilot] } { run_genode_until forever }
|
||||
|
||||
# autopilot test
|
||||
|
||||
run_genode_until {\[init -\> event_dump\] Input event #0\t} 60
|
||||
|
||||
# remove everything before the first interesting line
|
||||
regexp {(\[init -\> event_dump\] Input event #0\t.*)} $output all output
|
||||
|
||||
run_genode_until {\[init -\> event_dump\] Input event #11.*\n} 40 [output_spawn_id]
|
||||
|
||||
# pay only attention to the output of init and its children
|
||||
grep_output {^\[init }
|
||||
|
||||
unify_output { number [0-9]+} ""
|
||||
unify_output {(?n)on usb-.*$} ""
|
||||
unify_output {(?n)using .*$} ""
|
||||
unify_output {(?n)^.*__wait_event.*$} ""
|
||||
unify_output {(?n)^.*Failed to submit URB.*$} ""
|
||||
unify_output {(?n)^.*dev_warn.*$} ""
|
||||
filter_out_color_escape_sequences
|
||||
trim_lines
|
||||
|
||||
compare_output_to {
|
||||
[init -> event_dump] Input event #0 PRESS KEY_X 65534 key count: 1
|
||||
[init -> event_dump] Input event #1 RELEASE KEY_X key count: 0
|
||||
[init -> event_dump] Input event #2 PRESS BTN_LEFT 65534 key count: 1
|
||||
[init -> event_dump] Input event #3 REL_MOTION -1+0 key count: 1
|
||||
[init -> event_dump] Input event #4 REL_MOTION +0+1 key count: 1
|
||||
[init -> event_dump] Input event #5 RELEASE BTN_LEFT key count: 0
|
||||
[init -> usb_drv] dev_info: USB disconnect, device
|
||||
[init -> usb_drv] dev_info: new full-speed USB device
|
||||
[init -> usb_drv] dev_info: D L
|
||||
[init -> usb_drv] dev_info: input: USB HID v1.11 Keyboard [D L]
|
||||
[init -> usb_drv] dev_info: D L
|
||||
[init -> usb_drv] dev_info: input: USB HID v1.11 Mouse [D L]
|
||||
[init -> event_dump] Input event #6 PRESS KEY_X 65534 key count: 1
|
||||
[init -> event_dump] Input event #7 RELEASE KEY_X key count: 0
|
||||
[init -> event_dump] Input event #8 PRESS BTN_LEFT 65534 key count: 1
|
||||
[init -> event_dump] Input event #9 REL_MOTION -1+0 key count: 1
|
||||
[init -> event_dump] Input event #10 REL_MOTION +0+1 key count: 1
|
||||
[init -> event_dump] Input event #11 RELEASE BTN_LEFT key count: 0
|
||||
}
|
@ -201,9 +201,8 @@ append config {
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<start name="usb_drv" caps="150"> }
|
||||
append config "<binary name=\"[usb_host_drv_binary]\"/>"
|
||||
append config {
|
||||
<start name="usb_drv" caps="150">
|
||||
<binary name="} [usb_host_drv_binary] {"/>
|
||||
<resource name="RAM" quantum="12M"/>
|
||||
<provides> <service name="Usb"/> </provides>
|
||||
<config bios_handoff="yes">
|
||||
|
@ -26,7 +26,8 @@ if {[get_cmd_switch --autopilot] && ![have_spec x86_64]} {
|
||||
|
||||
set build_components {
|
||||
core init timer
|
||||
drivers/usb
|
||||
drivers/usb_host
|
||||
drivers/usb_hid
|
||||
server/event_dump
|
||||
server/dynamic_rom
|
||||
}
|
||||
@ -67,17 +68,23 @@ append config {
|
||||
<provides><service name="Timer"/></provides>
|
||||
</start>
|
||||
|
||||
<start name="usb_drv" caps="120">
|
||||
<start name="report_rom">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Report"/> <service name="ROM"/> </provides>
|
||||
<config verbose="no">
|
||||
<default-policy report="usb_drv -> devices"/>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<start name="usb_drv" caps="150">
|
||||
<binary name="} [usb_host_drv_binary] {"/>
|
||||
<resource name="RAM" quantum="12M"/>
|
||||
<config uhci="no" ohci="no" ehci="no" xhci="yes"
|
||||
capslock_led="rom" numlock_led="rom" scrlock_led="rom"
|
||||
bios_handoff="yes">
|
||||
<hid/>
|
||||
<provides> <service name="Usb"/> </provides>
|
||||
<config uhci="no" ohci="no" ehci="no" xhci="yes" bios_handoff="yes">
|
||||
<report devices="yes"/>
|
||||
<policy label_prefix="usb_hid_drv" class="0x3"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="ROM" label="capslock"> <child name="dynamic_rom"/> </service>
|
||||
<service name="ROM" label="numlock"> <child name="dynamic_rom"/> </service>
|
||||
<service name="ROM" label="scrlock"> <child name="dynamic_rom"/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
@ -87,7 +94,20 @@ append config {
|
||||
<service name="RM"> <parent/> </service>
|
||||
<service name="Platform"> <any-child/> </service>
|
||||
<service name="Timer"> <child name="timer"/> </service>
|
||||
<service name="Event"> <child name="event_dump"/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="usb_hid_drv" caps="140">
|
||||
<resource name="RAM" quantum="11M"/>
|
||||
<config use_report="yes" capslock_led="rom" numlock_led="rom" scrlock_led="rom"/>
|
||||
<route>
|
||||
<service name="ROM" label="capslock"> <child name="dynamic_rom"/> </service>
|
||||
<service name="ROM" label="numlock"> <child name="dynamic_rom"/> </service>
|
||||
<service name="ROM" label="scrlock"> <child name="dynamic_rom"/> </service>
|
||||
<service name="ROM" label="report"> <child name="report_rom"/> </service>
|
||||
<service name="Event"> <child name="event_dump"/> </service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
@ -138,8 +158,10 @@ install_config $config
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core ld.lib.so init timer usb_drv event_dump dynamic_rom
|
||||
core ld.lib.so init timer event_dump dynamic_rom
|
||||
usb_hid_drv
|
||||
}
|
||||
append boot_modules [usb_host_drv_binary]
|
||||
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
|
@ -12,10 +12,12 @@ assert_spec x86
|
||||
|
||||
set build_components {
|
||||
core init timer
|
||||
drivers/usb
|
||||
drivers/usb_host
|
||||
drivers/usb_net
|
||||
server/tcp_terminal
|
||||
test/terminal_echo
|
||||
lib/vfs/lwip
|
||||
lib/vfs/pipe
|
||||
server/nic_router
|
||||
}
|
||||
|
||||
@ -30,7 +32,8 @@ create_boot_directory
|
||||
# Generate config
|
||||
#
|
||||
|
||||
set config {
|
||||
set config ""
|
||||
append config {
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
@ -52,13 +55,24 @@ set config {
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="usb_drv">
|
||||
<start name="usb_drv" caps="120">
|
||||
<binary name="} [usb_host_drv_binary] {"/>
|
||||
<resource name="RAM" quantum="24M"/>
|
||||
<config mode="uplink_client" uhci="no" ohci="no" ehci="yes" xhci="yes">
|
||||
<nic mac="02:00:00:00:01:01" />
|
||||
<provides><service name="Usb"/></provides>
|
||||
<config>
|
||||
<policy label_prefix="usb_net_drv" vendor_id="0x0b95" product_id="0x1790"/>
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<start name="usb_net_drv">
|
||||
<resource name="RAM" quantum="20M"/>
|
||||
<config mode="uplink_client" mac="02:00:00:00:01:01" />
|
||||
<route>
|
||||
<service name="Uplink"><child name="nic_router"/></service>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="nic_router" caps="200">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<provides>
|
||||
@ -68,7 +82,7 @@ set config {
|
||||
<config verbose_domain_state="yes">
|
||||
|
||||
<policy label_prefix="tcp_terminal" domain="downlink"/>
|
||||
<policy label_prefix="usb_drv" domain="uplink"/>
|
||||
<policy label_prefix="usb_net_drv" domain="uplink"/>
|
||||
|
||||
<domain name="uplink">
|
||||
|
||||
@ -87,7 +101,7 @@ set config {
|
||||
</start>
|
||||
|
||||
<start name="tcp_terminal" caps="200">
|
||||
<resource name="RAM" quantum="2560K"/>
|
||||
<resource name="RAM" quantum="3M"/>
|
||||
<provides> <service name="Terminal"/> </provides>
|
||||
<config>
|
||||
<policy label_prefix="test-terminal_echo" port="8888"/>
|
||||
@ -105,8 +119,7 @@ set config {
|
||||
</start>
|
||||
<start name="test-terminal_echo">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
</start>
|
||||
}
|
||||
</start>}
|
||||
|
||||
append_platform_drv_config
|
||||
|
||||
@ -122,13 +135,15 @@ install_config $config
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core ld.lib.so init timer usb_drv
|
||||
libc.lib.so vfs.lib.so lwip_legacy.lib.so
|
||||
core ld.lib.so init timer
|
||||
libc.lib.so vfs.lib.so vfs_pipe.lib.so
|
||||
tcp_terminal
|
||||
test-terminal_echo
|
||||
vfs_lwip.lib.so
|
||||
usb_net_drv
|
||||
nic_router
|
||||
}
|
||||
append boot_modules [usb_host_drv_binary]
|
||||
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
|
@ -1,121 +0,0 @@
|
||||
#
|
||||
# \brief Test for using the Block (Storage) service of usb_drv
|
||||
# \author Christian Prochaska
|
||||
# \date 2011-06-24
|
||||
#
|
||||
|
||||
assert_spec x86
|
||||
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
set build_components {
|
||||
core init timer
|
||||
drivers/usb
|
||||
test/block/client
|
||||
}
|
||||
|
||||
source ${genode_dir}/repos/base/run/platform_drv.inc
|
||||
append_platform_drv_build_components
|
||||
|
||||
build $build_components
|
||||
|
||||
create_boot_directory
|
||||
|
||||
#
|
||||
# Generate config
|
||||
#
|
||||
|
||||
set config {
|
||||
<config verbose="yes">
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="IRQ"/>
|
||||
<service name="IO_MEM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="PD"/>
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<default caps="100"/>}
|
||||
|
||||
append_platform_drv_config
|
||||
|
||||
append config {
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
<start name="usb_drv">
|
||||
<resource name="RAM" quantum="12M"/>
|
||||
<provides> <service name="Block"/> </provides>
|
||||
<config uhci="yes" ohci="yes" ehci="yes" xhci="yes"><storage /></config>
|
||||
</start>
|
||||
<start name="test-usb">
|
||||
<resource name="RAM" quantum="2M" />
|
||||
<binary name="test-block-client" />
|
||||
<config test_size="1M" />
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
install_config $config
|
||||
|
||||
#
|
||||
# Boot modules
|
||||
#
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core ld.lib.so init timer usb_drv test-block-client
|
||||
}
|
||||
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
#
|
||||
# Execute test case
|
||||
#
|
||||
set disk_image "bin/test.img"
|
||||
set cmd "dd if=/dev/zero of=$disk_image bs=1024 count=65536"
|
||||
puts "creating disk image:\n$cmd"
|
||||
catch { exec sh -c $cmd }
|
||||
|
||||
set cmd "mkfs.vfat -F32 $disk_image"
|
||||
puts "formating disk image with vfat file system:\$cmd"
|
||||
catch { exec sh -c $cmd }
|
||||
|
||||
#
|
||||
# Qemu opts for UHCI
|
||||
#
|
||||
#append qemu_args " -nographic -usbdevice disk::$disk_image -boot order=d"
|
||||
|
||||
#
|
||||
# Qemu opts for EHCI
|
||||
#
|
||||
append qemu_args "-drive if=none,id=disk,file=$disk_image"
|
||||
append qemu_args { \
|
||||
-nographic -M pc \
|
||||
-device usb-ehci,id=ehci \
|
||||
-device usb-storage,bus=ehci.0,drive=disk \
|
||||
-boot order=d }
|
||||
|
||||
#
|
||||
# Qemu opts for XHCI
|
||||
#
|
||||
#append qemu_args { \
|
||||
# -nographic -M pc \
|
||||
#-device nec-usb-xhci,id=xhci \
|
||||
#-device usb-storage,bus=xhci.0,drive=disk \
|
||||
#-boot order=d }
|
||||
|
||||
run_genode_until {.*child "test-usb" exited with exit value 0.*} 100
|
||||
|
||||
puts "\nTest succeeded\n"
|
||||
|
||||
# vi: set ft=tcl :
|
@ -17,7 +17,7 @@ if {[have_include power_on/qemu]} {
|
||||
#
|
||||
set build_components {
|
||||
core init timer
|
||||
drivers/usb
|
||||
drivers/usb_host
|
||||
server/usb_terminal
|
||||
test/terminal_echo
|
||||
}
|
||||
@ -57,13 +57,12 @@ append config {
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
</start>
|
||||
<start name="usb_drv">
|
||||
<start name="usb_drv" caps="120">
|
||||
<binary name="} [usb_host_drv_binary] {"/>
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
<provides><service name="Usb"/></provides>
|
||||
<config uhci="yes" ohci="yes" ehci="yes" xhci="yes">
|
||||
<raw>
|
||||
<policy label="usb_terminal -> usb_serial" vendor_id="0x67b" product_id="0x2303"/>
|
||||
</raw>
|
||||
<config>
|
||||
<policy label="usb_terminal -> usb_serial" vendor_id="0x67b" product_id="0x2303"/>
|
||||
</config>
|
||||
</start>
|
||||
<start name="usb_terminal">
|
||||
@ -83,9 +82,10 @@ install_config $config
|
||||
|
||||
# generic modules
|
||||
set boot_modules {
|
||||
core ld.lib.so init timer usb_drv test-terminal_echo
|
||||
core ld.lib.so init timer test-terminal_echo
|
||||
usb_terminal
|
||||
}
|
||||
append boot_modules [usb_host_drv_binary]
|
||||
|
||||
append_platform_drv_boot_modules
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,135 +0,0 @@
|
||||
/*
|
||||
* \brief Platform specific definitions
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-07-06
|
||||
*
|
||||
* These functions have to be implemented on all supported platforms.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _PLATFORM_H_
|
||||
#define _PLATFORM_H_
|
||||
|
||||
#include <base/log.h>
|
||||
#include <util/xml_node.h>
|
||||
#include <irq_session/capability.h>
|
||||
|
||||
#include <lx_kit/env.h>
|
||||
|
||||
struct Services
|
||||
{
|
||||
|
||||
Genode::Env &env;
|
||||
|
||||
/* USB profiles */
|
||||
bool hid = false;
|
||||
bool stor = false;
|
||||
bool nic = false;
|
||||
bool raw = false;
|
||||
|
||||
/* Controller types */
|
||||
bool uhci = false; /* 1.0 */
|
||||
bool ohci = false;
|
||||
bool ehci = false; /* 2.0 */
|
||||
bool xhci = false; /* 3.0 */
|
||||
|
||||
/*
|
||||
* Screen resolution used by touch devices to convert touchscreen
|
||||
* absolute coordinates to screen absolute coordinates
|
||||
*/
|
||||
bool multitouch = false;
|
||||
unsigned long screen_width = 0;
|
||||
unsigned long screen_height = 0;
|
||||
|
||||
/* report generation */
|
||||
bool raw_report_device_list = false;
|
||||
|
||||
Services(Genode::Env &env) : env(env)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Genode::Xml_node config_node = Lx_kit::env().config_rom().xml();
|
||||
try {
|
||||
Genode::Xml_node node_hid = config_node.sub_node("hid");
|
||||
hid = true;
|
||||
|
||||
try {
|
||||
Genode::Xml_node node_screen = node_hid.sub_node("touchscreen");
|
||||
node_screen.attribute("width").value(screen_width);
|
||||
node_screen.attribute("height").value(screen_height);
|
||||
multitouch = node_screen.attribute_value("multitouch", false);
|
||||
} catch (...) {
|
||||
screen_width = screen_height = 0;
|
||||
log("Could not read screen resolution in config node");
|
||||
}
|
||||
|
||||
log("Configured HID screen with ", screen_width, "x", screen_height,
|
||||
" (multitouch=", multitouch ? "true" : "false", ")");
|
||||
} catch (Xml_node::Nonexistent_sub_node) {
|
||||
log("No <hid> config node found - not starting the USB HID (Input) service");
|
||||
}
|
||||
|
||||
try {
|
||||
config_node.sub_node("storage");
|
||||
stor = true;
|
||||
} catch (Xml_node::Nonexistent_sub_node) {
|
||||
log("No <storage> config node found - not starting the USB Storage (Block) service");
|
||||
}
|
||||
|
||||
try {
|
||||
config_node.sub_node("nic");
|
||||
nic = true;
|
||||
} catch (Xml_node::Nonexistent_sub_node) {
|
||||
log("No <nic> config node found - not starting the USB Nic (Network) service");
|
||||
}
|
||||
|
||||
try {
|
||||
Genode::Xml_node node_raw = config_node.sub_node("raw");
|
||||
raw = true;
|
||||
|
||||
try {
|
||||
Genode::Xml_node node_report = node_raw.sub_node("report");
|
||||
raw_report_device_list = node_report.attribute_value("devices", false);
|
||||
} catch (...) { }
|
||||
} catch (Xml_node::Nonexistent_sub_node) {
|
||||
log("No <raw> config node found - not starting external USB service");
|
||||
}
|
||||
|
||||
if (config_node.attribute_value("uhci", false)) {
|
||||
uhci = true;
|
||||
log("Enabled UHCI (USB 1.0/1.1) support");
|
||||
}
|
||||
|
||||
if (config_node.attribute_value("ohci", false)) {
|
||||
ohci = true;
|
||||
log("Enabled OHCI (USB 1.0/1.1) support");
|
||||
}
|
||||
|
||||
if (config_node.attribute_value("ehci", false)) {
|
||||
ehci = true;
|
||||
log("Enabled EHCI (USB 2.0) support");
|
||||
}
|
||||
|
||||
if (config_node.attribute_value("xhci", false)) {
|
||||
xhci = true;
|
||||
log("Enabled XHCI (USB 3.0) support");
|
||||
}
|
||||
|
||||
if (!(uhci | ohci | ehci | xhci))
|
||||
warning("Warning: No USB controllers enabled.\n"
|
||||
"Use <config (u/o/e/x)hci=\"yes\"> in your 'usb_drv' configuration");
|
||||
}
|
||||
};
|
||||
|
||||
void backend_alloc_init(Genode::Env &env, Genode::Ram_allocator &ram, Genode::Allocator &alloc);
|
||||
|
||||
void platform_hcd_init(Genode::Env &, Services *services);
|
||||
Genode::Irq_session_capability platform_irq_activate(int irq);
|
||||
|
||||
#endif /* _PLATFORM_H_ */
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* \brief Main-signal receiver and signal-helper functions
|
||||
* \author Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
* \date 2012-05-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _SIGNAL_H_
|
||||
#define _SIGNAL_H_
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
#include <base/signal.h>
|
||||
|
||||
static bool const verbose = false;
|
||||
|
||||
/**
|
||||
* Helper that holds sender and entrypoint
|
||||
*/
|
||||
class Signal_helper
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
Genode::Signal_transmitter _sender;
|
||||
|
||||
public:
|
||||
|
||||
Signal_helper(Genode::Env &env) : _env(env) { }
|
||||
|
||||
Genode::Entrypoint &ep() { return _env.ep(); }
|
||||
Genode::Signal_transmitter &sender() { return _sender; }
|
||||
Genode::Parent &parent() { return _env.parent(); }
|
||||
Genode::Env &env() { return _env; }
|
||||
Genode::Ram_allocator &ram() { return _env.ram(); }
|
||||
Genode::Region_map &rm() { return _env.rm(); }
|
||||
};
|
||||
|
||||
|
||||
namespace Storage
|
||||
{
|
||||
void init(Genode::Env &env);
|
||||
}
|
||||
|
||||
namespace Nic
|
||||
{
|
||||
void init(Genode::Env &env);
|
||||
}
|
||||
|
||||
namespace Raw
|
||||
{
|
||||
void init(Genode::Env &env, bool report_device_list);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _SIGNAL_H_ */
|
@ -1,357 +0,0 @@
|
||||
/*
|
||||
* \brief Platform specific part of the Linux API emulation
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-06-18
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _ARM__PLATFORM__LX_EMUL_H_
|
||||
#define _ARM__PLATFORM__LX_EMUL_H_
|
||||
|
||||
#include <platform/lx_emul_barrier.h>
|
||||
|
||||
/*************************
|
||||
** asm-generic/sizes.h **
|
||||
*************************/
|
||||
|
||||
enum {
|
||||
SZ_1K = 0x00000400,
|
||||
SZ_4K = 0x00001000,
|
||||
};
|
||||
|
||||
struct platform_device
|
||||
{
|
||||
char *name;
|
||||
int id;
|
||||
struct device dev;
|
||||
u32 num_resources;
|
||||
struct resource *resource;
|
||||
};
|
||||
|
||||
|
||||
/**********************
|
||||
** linux/usb/ulpi.h **
|
||||
**********************/
|
||||
|
||||
enum {
|
||||
ULPI_FUNC_CTRL_RESET = (1 << 5),
|
||||
ULPI_FUNC_CTRL = (1 << 2),
|
||||
};
|
||||
|
||||
/*
|
||||
* Macros for Set and Clear
|
||||
* See ULPI 1.1 specification to find the registers with Set and Clear offsets
|
||||
*/
|
||||
|
||||
#define ULPI_SET(a) (a + 1)
|
||||
|
||||
|
||||
/*****************************
|
||||
** linux/platform_device.h **
|
||||
*****************************/
|
||||
|
||||
#define module_platform_driver(__platform_driver) \
|
||||
module_driver(__platform_driver, platform_driver_register, \
|
||||
platform_driver_unregister)
|
||||
|
||||
enum { PLATFORM_DEVID_AUTO = -2 };
|
||||
|
||||
struct platform_driver {
|
||||
int (*probe)(struct platform_device *);
|
||||
int (*remove)(struct platform_device *);
|
||||
void (*shutdown)(struct platform_device *);
|
||||
int (*suspend)(struct platform_device *, pm_message_t state);
|
||||
int (*resume)(struct platform_device *);
|
||||
struct device_driver driver;
|
||||
const struct platform_device_id *id_table;
|
||||
};
|
||||
|
||||
struct resource *platform_get_resource(struct platform_device *, unsigned, unsigned);
|
||||
struct resource *platform_get_resource_byname(struct platform_device *, unsigned int, const char *);
|
||||
|
||||
int platform_get_irq(struct platform_device *, unsigned int);
|
||||
int platform_get_irq_byname(struct platform_device *, const char *);
|
||||
|
||||
int platform_driver_register(struct platform_driver *);
|
||||
int platform_device_register(struct platform_device *);
|
||||
void platform_device_unregister(struct platform_device *);
|
||||
|
||||
struct platform_device *platform_device_alloc(const char *name, int id);
|
||||
int platform_device_add_data(struct platform_device *pdev, const void *data,
|
||||
size_t size);
|
||||
int platform_device_add_resources(struct platform_device *pdev,
|
||||
const struct resource *res, unsigned int num);
|
||||
|
||||
int platform_device_add(struct platform_device *pdev);
|
||||
int platform_device_del(struct platform_device *pdev);
|
||||
|
||||
int platform_device_put(struct platform_device *pdev);
|
||||
|
||||
|
||||
#define to_platform_device(x) container_of((x), struct platform_device, dev)
|
||||
|
||||
/**********************
|
||||
** asm/generic/io.h **
|
||||
**********************/
|
||||
|
||||
static inline u32 __raw_readl(const volatile void __iomem *addr)
|
||||
{
|
||||
return *(const volatile u32 __force *) addr;
|
||||
}
|
||||
|
||||
static inline void __raw_writel(u32 b, volatile void __iomem *addr)
|
||||
{
|
||||
*(volatile u32 __force *) addr = b;
|
||||
}
|
||||
|
||||
|
||||
static inline u8 __raw_readb(const volatile void __iomem *addr)
|
||||
{
|
||||
return *(const volatile u8 __force *) addr;
|
||||
}
|
||||
|
||||
static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
|
||||
{
|
||||
*(volatile u8 __force *) addr = b;
|
||||
}
|
||||
|
||||
|
||||
/********************************
|
||||
** linux/regulator/consumer.h **
|
||||
********************************/
|
||||
|
||||
struct regulator { };
|
||||
int regulator_enable(struct regulator *);
|
||||
int regulator_disable(struct regulator *);
|
||||
void regulator_put(struct regulator *regulator);
|
||||
struct regulator *regulator_get(struct device *dev, const char *id);
|
||||
|
||||
struct regulator *__must_check devm_regulator_get(struct device *dev,
|
||||
const char *id);
|
||||
|
||||
/*******************************************
|
||||
** arch/arm/plat-omap/include/plat/usb.h **
|
||||
*******************************************/
|
||||
|
||||
int omap_usbhs_enable(struct device *dev);
|
||||
void omap_usbhs_disable(struct device *dev);
|
||||
|
||||
|
||||
/*****************
|
||||
** linux/clk.h **
|
||||
*****************/
|
||||
|
||||
struct clk *clk_get(struct device *, const char *);
|
||||
int clk_enable(struct clk *);
|
||||
void clk_disable(struct clk *);
|
||||
void clk_put(struct clk *);
|
||||
struct clk *devm_clk_get(struct device *dev, const char *id);
|
||||
int clk_prepare_enable(struct clk *);
|
||||
void clk_disable_unprepare(struct clk *);
|
||||
|
||||
|
||||
/******************
|
||||
** linux/gpio.h **
|
||||
******************/
|
||||
|
||||
enum { GPIOF_OUT_INIT_HIGH = 0x2 };
|
||||
|
||||
bool gpio_is_valid(int);
|
||||
void gpio_set_value_cansleep(unsigned, int);
|
||||
int gpio_request_one(unsigned, unsigned long, const char *);
|
||||
|
||||
int devm_gpio_request_one(struct device *dev, unsigned gpio,
|
||||
unsigned long flags, const char *label);
|
||||
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
** linux/of.h **
|
||||
****************/
|
||||
|
||||
#define of_match_ptr(ptr) NULL
|
||||
#define for_each_available_child_of_node(parent, child) while (0)
|
||||
|
||||
|
||||
unsigned of_usb_get_maximum_speed(struct device_node *np);
|
||||
unsigned of_usb_get_dr_mode(struct device_node *np);
|
||||
int of_device_is_compatible(const struct device_node *device, const char *);
|
||||
void of_node_put(struct device_node *node);
|
||||
|
||||
int of_property_read_u32(const struct device_node *np, const char *propname,
|
||||
u32 *out_value);
|
||||
|
||||
|
||||
/*************************
|
||||
** linux/of_platform.h **
|
||||
*************************/
|
||||
|
||||
struct of_dev_auxdata;
|
||||
|
||||
int of_platform_populate(struct device_node *, const struct of_device_id *,
|
||||
const struct of_dev_auxdata *, struct device *);
|
||||
|
||||
|
||||
/*********************
|
||||
** linux/of_gpio.h **
|
||||
*********************/
|
||||
|
||||
int of_get_named_gpio(struct device_node *, const char *, int);
|
||||
|
||||
|
||||
/******************
|
||||
** linux/phy.h **
|
||||
******************/
|
||||
|
||||
enum {
|
||||
MII_BUS_ID_SIZE = 17,
|
||||
PHY_MAX_ADDR = 32,
|
||||
PHY_POLL = -1,
|
||||
};
|
||||
|
||||
|
||||
#define PHY_ID_FMT "%s:%02x"
|
||||
|
||||
struct mii_bus
|
||||
{
|
||||
const char *name;
|
||||
char id[MII_BUS_ID_SIZE];
|
||||
int (*read)(struct mii_bus *bus, int phy_id, int regnum);
|
||||
int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val);
|
||||
void *priv;
|
||||
int *irq;
|
||||
};
|
||||
|
||||
struct phy_device
|
||||
{
|
||||
int speed;
|
||||
int duplex;
|
||||
int link;
|
||||
};
|
||||
|
||||
struct mii_bus *mdiobus_alloc(void);
|
||||
int mdiobus_register(struct mii_bus *bus);
|
||||
void mdiobus_unregister(struct mii_bus *bus);
|
||||
void mdiobus_free(struct mii_bus *bus);
|
||||
|
||||
int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd);
|
||||
void phy_print_status(struct phy_device *phydev);
|
||||
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
|
||||
int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
|
||||
void phy_start(struct phy_device *phydev);
|
||||
int phy_start_aneg(struct phy_device *phydev);
|
||||
void phy_stop(struct phy_device *phydev);
|
||||
int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id);
|
||||
void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id);
|
||||
|
||||
|
||||
int genphy_resume(struct phy_device *phydev);
|
||||
|
||||
struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
|
||||
void (*handler)(struct net_device *),
|
||||
phy_interface_t interface);
|
||||
void phy_disconnect(struct phy_device *phydev);
|
||||
|
||||
struct phy *devm_phy_get(struct device *dev, const char *string);
|
||||
struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
|
||||
const char *con_id);
|
||||
|
||||
|
||||
/*********************************
|
||||
** linux/usb/usb_phy_generic.h **
|
||||
*********************************/
|
||||
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/phy.h>
|
||||
|
||||
struct usb_phy_generic_platform_data
|
||||
{
|
||||
enum usb_phy_type type;
|
||||
int gpio_reset;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*******************************
|
||||
** linux/usb/nop-usb-xceiv.h **
|
||||
*******************************/
|
||||
|
||||
struct nop_usb_xceiv_platform_data { int type; };
|
||||
|
||||
|
||||
/*******************************
|
||||
** linux/usb/samsung_usb_phy **
|
||||
*******************************/
|
||||
|
||||
enum samsung_usb_phy_type { USB_PHY_TYPE_HOST = 1 };
|
||||
|
||||
|
||||
/***********************
|
||||
** asm/dma-mapping.h **
|
||||
***********************/
|
||||
|
||||
/* needed by 'dwc_otg_hcd_linux.c' */
|
||||
void *dma_to_virt(struct device *dev, dma_addr_t addr);
|
||||
|
||||
|
||||
/********************
|
||||
** asm/irqflags.h **
|
||||
********************/
|
||||
|
||||
void local_fiq_disable();
|
||||
void local_fiq_enable();
|
||||
unsigned smp_processor_id(void);
|
||||
|
||||
/***************
|
||||
** asm/fiq.h **
|
||||
***************/
|
||||
|
||||
struct pt_regs;
|
||||
int claim_fiq(struct fiq_handler *f);
|
||||
void set_fiq_regs(struct pt_regs const *regs);
|
||||
void enable_fiq();
|
||||
void set_fiq_handler(void *start, unsigned int length);
|
||||
|
||||
|
||||
/************************************
|
||||
** /linux/usb/usb_phy_gen_xceiv.h **
|
||||
************************************/
|
||||
|
||||
|
||||
struct usb_phy_gen_xceiv_platform_data
|
||||
{
|
||||
unsigned type;
|
||||
int gpio_reset;
|
||||
};
|
||||
|
||||
|
||||
/******************************
|
||||
** linux/usb/xhci_pdriver.h **
|
||||
******************************/
|
||||
|
||||
struct usb_xhci_pdata {
|
||||
unsigned usb3_lpm_capable:1;
|
||||
};
|
||||
|
||||
|
||||
/******************
|
||||
** asm/memory.h **
|
||||
******************/
|
||||
|
||||
#define __bus_to_virt phys_to_virt
|
||||
|
||||
|
||||
/********************************************************
|
||||
** drivers/usb/host/dwc_otg/dwc_otg/dwc_otg_fiq_fsm.h **
|
||||
********************************************************/
|
||||
|
||||
extern bool fiq_enable, fiq_fsm_enable;
|
||||
|
||||
#endif /* _ARM__PLATFORM__LX_EMUL_H_ */
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* \brief ARMv6-specific part of the Linux API emulation
|
||||
* \author Christian Prochaska
|
||||
* \date 2014-05-28
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _ARMV6__PLATFORM__LX_EMUL_BARRIER_H_
|
||||
#define _ARMV6__PLATFORM__LX_EMUL_BARRIER_H_
|
||||
|
||||
|
||||
/*******************
|
||||
** asm/barrier.h **
|
||||
*******************/
|
||||
|
||||
#include <lx_emul/barrier.h>
|
||||
|
||||
#endif /* _ARMV6__PLATFORM__LX_EMUL_BARRIER_H_ */
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* \brief ARMv7-specific part of the Linux API emulation
|
||||
* \author Christian Prochaska
|
||||
* \date 2014-05-28
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _ARMV7__PLATFORM__LX_EMUL_BARRIER_H_
|
||||
#define _ARMV7__PLATFORM__LX_EMUL_BARRIER_H_
|
||||
|
||||
|
||||
/*******************
|
||||
** asm/barrier.h **
|
||||
*******************/
|
||||
|
||||
#include <lx_emul/barrier.h>
|
||||
|
||||
#endif /* _ARMV7__PLATFORM__LX_EMUL_BARRIER_H_ */
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* \brief USB: DWC-OTG RaspberryPI Interrupt (base-foc)
|
||||
* \author Reinier Millo Sánchez <rmillo@uclv.cu>
|
||||
* \date 2015-06-21
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_USB_IRQ_H_
|
||||
#define _INCLUDE_USB_IRQ_H_
|
||||
|
||||
enum{
|
||||
DWC_IRQ = 9,
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE_USB_IRQ_H_ */
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* \brief Platform specific part of the Linux API emulation
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-06-18
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _X86_32__PLATFORM__LX_EMUL_
|
||||
#define _X86_32__PLATFORM__LX_EMUL_
|
||||
|
||||
|
||||
/*******************
|
||||
** asm/barrier.h **
|
||||
*******************/
|
||||
|
||||
#include <lx_emul/barrier.h>
|
||||
|
||||
|
||||
struct platform_device
|
||||
{
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
#define dev_is_pci(d) (1)
|
||||
|
||||
#endif /* _X86_32__PLATFORM__LX_EMUL_ */
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* \brief SCSI helpers
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-05-06
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _SCSI_H_
|
||||
#define _SCSI_H_
|
||||
|
||||
struct scsi_cmnd;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Add a SCSI device
|
||||
*
|
||||
* \param sdev Device to add
|
||||
*/
|
||||
void scsi_add_device(struct scsi_device *sdev);
|
||||
|
||||
|
||||
/**
|
||||
* Alloc data buffer for command
|
||||
*
|
||||
* \param size Size of buffer
|
||||
* \param cmnd Command to assciate buffer
|
||||
*/
|
||||
void scsi_alloc_buffer(size_t size, struct scsi_cmnd *cmnd);
|
||||
|
||||
|
||||
/**
|
||||
* Fill command
|
||||
*
|
||||
* \param cmnd Command buffer to setup
|
||||
* \param size Data size
|
||||
* \param virt Virtual address of buffer
|
||||
* \param addr DMA address of buffer
|
||||
*/
|
||||
void scsi_setup_buffer(struct scsi_cmnd *cmnd, size_t size, void *virt, dma_addr_t addr);
|
||||
|
||||
|
||||
/**
|
||||
* Free data buffer of command
|
||||
*
|
||||
* \param cmnd Command
|
||||
*/
|
||||
void scsi_free_buffer(struct scsi_cmnd *cmnd);
|
||||
|
||||
|
||||
/**
|
||||
* Get buffer data for command
|
||||
*
|
||||
* \param cmnd Command to retrieve buffer pointer
|
||||
*
|
||||
* \return Buffer pointer
|
||||
*/
|
||||
void *scsi_buffer_data(struct scsi_cmnd *cmnd);
|
||||
|
||||
|
||||
/**
|
||||
* Allocate a SCSI command
|
||||
*
|
||||
* \return Allocated command or zero on failure
|
||||
*/
|
||||
struct scsi_cmnd *_scsi_alloc_command();
|
||||
|
||||
|
||||
/**
|
||||
* Free a SCSI command
|
||||
*
|
||||
* \param cmnd Command
|
||||
*/
|
||||
void _scsi_free_command(struct scsi_cmnd *cmnd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SCSI_H_ */
|
@ -1,441 +0,0 @@
|
||||
/*
|
||||
* \brief Block-session implementation for network devices
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-07-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _USB_NIC_COMPONENT_H_
|
||||
#define _USB_NIC_COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <nic/component.h>
|
||||
#include <root/component.h>
|
||||
|
||||
/* Linux emulation environment includes */
|
||||
#include <lx_emul.h>
|
||||
#include <lx_emul/extern_c_begin.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/usbnet.h>
|
||||
#include <lx_emul/extern_c_end.h>
|
||||
|
||||
/* NIC driver includes */
|
||||
#include <drivers/nic/uplink_client_base.h>
|
||||
|
||||
namespace Usb_nic {
|
||||
|
||||
using namespace Genode;
|
||||
using Genode::size_t;
|
||||
|
||||
class Session_component;
|
||||
struct Device;
|
||||
};
|
||||
|
||||
|
||||
class Usb_network_session
|
||||
{
|
||||
protected:
|
||||
|
||||
Usb_nic::Device &_device;
|
||||
|
||||
public:
|
||||
|
||||
Usb_network_session(Usb_nic::Device &device)
|
||||
:
|
||||
_device { device }
|
||||
{ }
|
||||
|
||||
virtual void link_state_changed() = 0;
|
||||
|
||||
virtual void rx(Genode::addr_t virt,
|
||||
Genode::size_t size) = 0;
|
||||
};
|
||||
|
||||
|
||||
struct Usb_nic::Device
|
||||
{
|
||||
Usb_network_session *_session;
|
||||
|
||||
/**
|
||||
* Transmit data to driver
|
||||
*/
|
||||
virtual bool tx(addr_t virt, size_t size) = 0;
|
||||
|
||||
/**
|
||||
* Return mac address of device
|
||||
*/
|
||||
virtual Nic::Mac_address mac_address() = 0;
|
||||
|
||||
/**
|
||||
* Return current link-state (true if link detected)
|
||||
*/
|
||||
virtual bool link_state() = 0;
|
||||
|
||||
/**
|
||||
* Set session belonging to this driver
|
||||
*/
|
||||
void session(Usb_network_session *s) { _session = s; }
|
||||
|
||||
/**
|
||||
* Check for session
|
||||
*/
|
||||
bool session() { return _session != 0; }
|
||||
|
||||
/**
|
||||
* Alloc an SKB
|
||||
*/
|
||||
virtual sk_buff *alloc_skb() = 0;
|
||||
|
||||
/**
|
||||
* Submit SKB to device
|
||||
*/
|
||||
virtual void tx_skb(sk_buff *skb) = 0;
|
||||
|
||||
/**
|
||||
* Setup SKB with 'data' of 'size', return 'false' if SKB is longer than
|
||||
* 'end'.
|
||||
*/
|
||||
virtual bool skb_fill(struct sk_buff *skb, unsigned char *data, Genode::size_t size, unsigned char *end) = 0;
|
||||
|
||||
/**
|
||||
* Call driver fixup function on SKB
|
||||
*/
|
||||
virtual void tx_fixup(struct sk_buff *skb) = 0;
|
||||
|
||||
/**
|
||||
* Return true if device supports burst operations
|
||||
*/
|
||||
virtual bool burst() = 0;
|
||||
|
||||
Device() : _session(0) { }
|
||||
};
|
||||
|
||||
|
||||
class Usb_nic::Session_component : public Usb_network_session,
|
||||
public Nic::Session_component
|
||||
{
|
||||
protected:
|
||||
|
||||
void _send_burst()
|
||||
{
|
||||
static sk_buff work_skb; /* dummy skb for fixup calls */
|
||||
static Packet_descriptor save;
|
||||
|
||||
sk_buff *skb = nullptr;
|
||||
unsigned char *ptr = nullptr;
|
||||
|
||||
/* submit received packets to lower layer */
|
||||
while (((_tx.sink()->packet_avail() || save.size()) && _tx.sink()->ready_to_ack()))
|
||||
{
|
||||
/* alloc skb */
|
||||
if (!skb) {
|
||||
if (!(skb = _device.alloc_skb()))
|
||||
return;
|
||||
|
||||
ptr = skb->data;
|
||||
work_skb.data = nullptr;
|
||||
}
|
||||
|
||||
Packet_descriptor packet = save.size() ? save : _tx.sink()->get_packet();
|
||||
save = Packet_descriptor();
|
||||
|
||||
if (!_device.skb_fill(&work_skb, ptr, packet.size(), skb->end)) {
|
||||
/* submit batch */
|
||||
_device.tx_skb(skb);
|
||||
skb = nullptr;
|
||||
save = packet;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* copy packet to current data pos */
|
||||
try { Genode::memcpy(work_skb.data, _tx.sink()->packet_content(packet), packet.size()); }
|
||||
catch (Genode::Packet_descriptor::Invalid_packet) { }
|
||||
/* call fixup on dummy SKB */
|
||||
_device.tx_fixup(&work_skb);
|
||||
/* advance to next slot */
|
||||
ptr = work_skb.end;
|
||||
skb->len += work_skb.truesize;
|
||||
/* acknowledge to client */
|
||||
_tx.sink()->acknowledge_packet(packet);
|
||||
}
|
||||
|
||||
/* submit last skb */
|
||||
if (skb)
|
||||
_device.tx_skb(skb);
|
||||
}
|
||||
|
||||
bool _send()
|
||||
{
|
||||
if (!_tx.sink()->ready_to_ack())
|
||||
return false;
|
||||
|
||||
if (!_tx.sink()->packet_avail())
|
||||
return false;
|
||||
|
||||
Genode::Packet_descriptor packet = _tx.sink()->get_packet();
|
||||
if (!packet.size() || !_tx.sink()->packet_valid(packet)) {
|
||||
Genode::warning("Invalid tx packet");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ret = _device.tx((addr_t)_tx.sink()->packet_content(packet), packet.size());
|
||||
_tx.sink()->acknowledge_packet(packet);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void _handle_packet_stream() override
|
||||
{
|
||||
while (_rx.source()->ack_avail())
|
||||
_rx.source()->release_packet(_rx.source()->get_acked_packet());
|
||||
|
||||
if (_device.burst())
|
||||
_send_burst();
|
||||
else
|
||||
while (_send());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Session_component(Genode::size_t const tx_buf_size,
|
||||
Genode::size_t const rx_buf_size,
|
||||
Genode::Allocator &rx_block_md_alloc,
|
||||
Genode::Env &env,
|
||||
Device &device)
|
||||
:
|
||||
Usb_network_session { device },
|
||||
Nic::Session_component { tx_buf_size, rx_buf_size, Genode::CACHED,
|
||||
rx_block_md_alloc, env }
|
||||
{
|
||||
_device.session(this);
|
||||
}
|
||||
|
||||
|
||||
/****************************
|
||||
** Nic::Session_component **
|
||||
****************************/
|
||||
|
||||
Nic::Mac_address mac_address() override { return _device.mac_address(); }
|
||||
bool link_state() override { return _device.link_state(); }
|
||||
|
||||
|
||||
/*************************
|
||||
** Usb_network_session **
|
||||
*************************/
|
||||
|
||||
void link_state_changed() override { _link_state_changed(); }
|
||||
|
||||
/**
|
||||
* Send packet to client (called from driver)
|
||||
*/
|
||||
void rx(addr_t virt, size_t size) override
|
||||
{
|
||||
_handle_packet_stream();
|
||||
|
||||
if (!_rx.source()->ready_to_submit())
|
||||
return;
|
||||
|
||||
try {
|
||||
Packet_descriptor p =_rx.source()->alloc_packet(size);
|
||||
Genode::memcpy(_rx.source()->packet_content(p), (void*)virt, size);
|
||||
_rx.source()->submit_packet(p);
|
||||
} catch (...) {
|
||||
/* drop */
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Shortcut for single-client root component
|
||||
*/
|
||||
typedef Genode::Root_component<Usb_nic::Session_component, Genode::Single_client> Root_component;
|
||||
|
||||
/**
|
||||
* Root component, handling new session requests
|
||||
*/
|
||||
class Root : public Root_component
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
Usb_nic::Device &_device;
|
||||
|
||||
protected:
|
||||
|
||||
Usb_nic::Session_component *_create_session(const char *args)
|
||||
{
|
||||
using namespace Genode;
|
||||
using Genode::size_t;
|
||||
|
||||
size_t ram_quota = Arg_string::find_arg(args, "ram_quota" ).ulong_value(0);
|
||||
size_t tx_buf_size = Arg_string::find_arg(args, "tx_buf_size").ulong_value(0);
|
||||
size_t rx_buf_size = Arg_string::find_arg(args, "rx_buf_size").ulong_value(0);
|
||||
|
||||
/* deplete ram quota by the memory needed for the session structure */
|
||||
size_t session_size = max(4096UL, (unsigned long)sizeof(Usb_nic::Session_component));
|
||||
if (ram_quota < session_size)
|
||||
throw Genode::Insufficient_ram_quota();
|
||||
|
||||
/*
|
||||
* Check if donated ram quota suffices for both communication
|
||||
* buffers and check for overflow
|
||||
*/
|
||||
if (tx_buf_size + rx_buf_size < tx_buf_size ||
|
||||
tx_buf_size + rx_buf_size > ram_quota - session_size) {
|
||||
Genode::error("insufficient 'ram_quota', got ", ram_quota, " need %ld",
|
||||
tx_buf_size + rx_buf_size + session_size);
|
||||
throw Genode::Insufficient_ram_quota();
|
||||
}
|
||||
|
||||
return new (Root::md_alloc())
|
||||
Usb_nic::Session_component(tx_buf_size, rx_buf_size,
|
||||
Lx::Malloc::mem(), _env,
|
||||
_device);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Root(Genode::Env &env,
|
||||
Genode::Allocator &md_alloc,
|
||||
Usb_nic::Device &device)
|
||||
:
|
||||
Root_component { &env.ep().rpc_ep(), &md_alloc },
|
||||
_env { env },
|
||||
_device { device }
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Uplink_client;
|
||||
}
|
||||
|
||||
|
||||
class Genode::Uplink_client : public Usb_network_session,
|
||||
public Uplink_client_base
|
||||
{
|
||||
private:
|
||||
|
||||
sk_buff _burst_work_skb { };
|
||||
sk_buff *_burst_skb { nullptr };
|
||||
unsigned char *_burst_ptr { nullptr };
|
||||
|
||||
|
||||
/************************
|
||||
** Uplink_client_base **
|
||||
************************/
|
||||
|
||||
Transmit_result
|
||||
_drv_transmit_pkt(const char *conn_rx_pkt_base,
|
||||
size_t conn_rx_pkt_size) override
|
||||
{
|
||||
if (_device.tx((addr_t)conn_rx_pkt_base, conn_rx_pkt_size) == 0) {
|
||||
return Transmit_result::ACCEPTED;
|
||||
}
|
||||
return Transmit_result::REJECTED;
|
||||
}
|
||||
|
||||
void _drv_transmit_pkt_burst_prepare() override
|
||||
{
|
||||
_burst_skb = nullptr;
|
||||
_burst_ptr = nullptr;
|
||||
}
|
||||
|
||||
Burst_result
|
||||
_drv_transmit_pkt_burst_step(Packet_descriptor const &packet,
|
||||
char const *packet_base,
|
||||
Packet_descriptor &save) override
|
||||
{
|
||||
/* alloc _burst_skb */
|
||||
if (!_burst_skb) {
|
||||
if (!(_burst_skb = _device.alloc_skb()))
|
||||
return Burst_result::BURST_FAILED;
|
||||
|
||||
_burst_ptr = _burst_skb->data;
|
||||
_burst_work_skb.data = nullptr;
|
||||
}
|
||||
|
||||
if (!_device.skb_fill(&_burst_work_skb, _burst_ptr, packet.size(), _burst_skb->end)) {
|
||||
|
||||
/* submit batch */
|
||||
_device.tx_skb(_burst_skb);
|
||||
_burst_skb = nullptr;
|
||||
save = packet;
|
||||
return Burst_result::BURST_CONTINUE;
|
||||
}
|
||||
|
||||
/* copy packet to current data pos */
|
||||
Genode::memcpy(_burst_work_skb.data, packet_base, packet.size());
|
||||
|
||||
/* call fixup on dummy SKB */
|
||||
_device.tx_fixup(&_burst_work_skb);
|
||||
|
||||
/* advance to next slot */
|
||||
_burst_ptr = _burst_work_skb.end;
|
||||
_burst_skb->len += _burst_work_skb.truesize;
|
||||
|
||||
return Burst_result::BURST_SUCCEEDED;
|
||||
}
|
||||
|
||||
void _drv_transmit_pkt_burst_finish() override
|
||||
{
|
||||
/* submit last _burst_skb */
|
||||
if (_burst_skb)
|
||||
_device.tx_skb(_burst_skb);
|
||||
}
|
||||
|
||||
bool _drv_supports_transmit_pkt_burst() override
|
||||
{
|
||||
return _device.burst();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Uplink_client(Env &env,
|
||||
Allocator &alloc,
|
||||
Usb_nic::Device &device)
|
||||
:
|
||||
Usb_network_session { device },
|
||||
Uplink_client_base { env, alloc, _device.mac_address() }
|
||||
{
|
||||
_device.session(this);
|
||||
_drv_handle_link_state(_device.link_state());
|
||||
}
|
||||
|
||||
|
||||
/*************************
|
||||
** Usb_network_session **
|
||||
*************************/
|
||||
|
||||
void link_state_changed() override
|
||||
{
|
||||
_drv_handle_link_state(_device.link_state());
|
||||
}
|
||||
|
||||
void rx(Genode::addr_t virt,
|
||||
Genode::size_t size) override
|
||||
{
|
||||
_drv_rx_handle_pkt(
|
||||
size,
|
||||
[&] (void *conn_tx_pkt_base,
|
||||
size_t &)
|
||||
{
|
||||
memcpy(conn_tx_pkt_base, (void *)virt, size);
|
||||
return Write_result::WRITE_SUCCEEDED;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _USB_NIC_COMPONENT_H_ */
|
@ -1,525 +0,0 @@
|
||||
/*
|
||||
* \brief Input service and event handler
|
||||
* \author Christian Helmuth
|
||||
* \author Dirk Vogt
|
||||
* \author Sebastian Sumpf
|
||||
* \author Christian Menard
|
||||
* \author Alexander Boettcher
|
||||
* \date 2009-04-20
|
||||
*
|
||||
* TODO make this a complete replacement for evdev.c from Linux
|
||||
* TODO per-device slot handling
|
||||
*
|
||||
* The original implementation was in the L4Env from the TUD:OS group
|
||||
* (l4/pkg/input/lib/src/l4evdev.c). This file was released under the terms of
|
||||
* the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
||||
* Copyright (C) 2014 Ksys Labs LLC
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <base/registry.h>
|
||||
#include <util/reconstructible.h>
|
||||
|
||||
/* LX kit */
|
||||
#include <lx_kit/env.h>
|
||||
#include <lx_kit/scheduler.h>
|
||||
|
||||
/* local */
|
||||
#include "led_state.h"
|
||||
|
||||
/* Linux includes */
|
||||
#include <lx_emul.h>
|
||||
#include <lx_emul/extern_c_begin.h>
|
||||
#include <linux/hid.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/usb.h>
|
||||
#include <lx_emul/extern_c_end.h>
|
||||
|
||||
|
||||
/* Callback function to Genode subsystem */
|
||||
static genode_input_event_cb handler;
|
||||
|
||||
static unsigned long screen_x;
|
||||
static unsigned long screen_y;
|
||||
|
||||
/*
|
||||
* We only send multi-touch events if enabled. Otherwise emulated pointer events
|
||||
* are generated.
|
||||
*/
|
||||
static bool multi_touch;
|
||||
|
||||
static struct slot
|
||||
{
|
||||
int id; /* current tracking id */
|
||||
int x; /* last reported x axis */
|
||||
int y; /* last reported y axis */
|
||||
int event; /* last reported ABS_MT_ event */
|
||||
} slots[16];
|
||||
|
||||
static int slot = 0; /* store current input slot */
|
||||
|
||||
|
||||
static bool transform(input_dev *dev, int &x, int &y)
|
||||
{
|
||||
if (!screen_x || !screen_y) return true;
|
||||
|
||||
int const min_x_dev = input_abs_get_min(dev, ABS_X);
|
||||
int const min_y_dev = input_abs_get_min(dev, ABS_Y);
|
||||
int const max_x_dev = input_abs_get_max(dev, ABS_X);
|
||||
int const max_y_dev = input_abs_get_max(dev, ABS_Y);
|
||||
int const max_y_norm = max_y_dev - min_y_dev;
|
||||
int const max_x_norm = max_x_dev - min_x_dev;
|
||||
|
||||
if (!max_x_norm || !max_y_norm ||
|
||||
x < min_x_dev || y < min_y_dev || x > max_x_dev || y > max_y_dev) {
|
||||
Genode::warning("ignore input source with coordinates out of range");
|
||||
return false;
|
||||
}
|
||||
|
||||
x = screen_x * (x - min_x_dev) / (max_x_norm);
|
||||
y = screen_y * (y - min_y_dev) / (max_y_norm);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void handle_mt_tracking_id(input_dev *dev, int value)
|
||||
{
|
||||
if (value != -1) {
|
||||
if (slots[slot].id != -1)
|
||||
Genode::warning("old tracking id in use and got new one");
|
||||
|
||||
slots[slot].id = value;
|
||||
return;
|
||||
}
|
||||
|
||||
/* send end of slot usage event for clients */
|
||||
int x = slots[slot].x < 0 ? 0 : slots[slot].x;
|
||||
int y = slots[slot].y < 0 ? 0 : slots[slot].y;
|
||||
|
||||
if (!transform(dev, x, y)) return;
|
||||
|
||||
if (handler)
|
||||
handler(EVENT_TYPE_TOUCH, slot, x, y, -1, -1);
|
||||
|
||||
slots[slot].event = slots[slot].x = slots[slot].y = -1;
|
||||
slots[slot].id = value;
|
||||
}
|
||||
|
||||
|
||||
static void handle_mt_slot(int value)
|
||||
{
|
||||
if ((unsigned)value >= sizeof(slots) / sizeof(slots[0])) {
|
||||
Genode::warning("drop multi-touch slot id ", value);
|
||||
return;
|
||||
}
|
||||
|
||||
slot = value;
|
||||
}
|
||||
|
||||
|
||||
enum Axis { AXIS_X, AXIS_Y };
|
||||
|
||||
static void handle_absolute_axis(input_dev *dev, unsigned code, int value, Axis axis)
|
||||
{
|
||||
slots[slot].event = code;
|
||||
|
||||
input_event_type type = EVENT_TYPE_MOTION;
|
||||
|
||||
switch (axis) {
|
||||
case AXIS_X:
|
||||
type = code == ABS_X ? EVENT_TYPE_MOTION : EVENT_TYPE_TOUCH;
|
||||
slots[slot].x = value;
|
||||
break;
|
||||
case AXIS_Y:
|
||||
type = code == ABS_Y ? EVENT_TYPE_MOTION : EVENT_TYPE_TOUCH;
|
||||
slots[slot].y = value;
|
||||
break;
|
||||
}
|
||||
|
||||
int x = slots[slot].x;
|
||||
int y = slots[slot].y;
|
||||
|
||||
if (x == -1 || y == -1) return;
|
||||
|
||||
if (!transform(dev, x, y)) return;
|
||||
|
||||
if (handler)
|
||||
handler(type, slot, x, y, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
static void handle_absolute(input_dev *dev, unsigned code, int value)
|
||||
{
|
||||
switch (code) {
|
||||
case ABS_WHEEL:
|
||||
if (handler)
|
||||
handler(EVENT_TYPE_WHEEL, 0, 0, 0, 0, value);
|
||||
return;
|
||||
|
||||
case ABS_X:
|
||||
if (dev->mt && multi_touch) return;
|
||||
handle_absolute_axis(dev, code, value, AXIS_X);
|
||||
return;
|
||||
|
||||
case ABS_MT_POSITION_X:
|
||||
if (!multi_touch) return;
|
||||
handle_absolute_axis(dev, code, value, AXIS_X);
|
||||
return;
|
||||
|
||||
case ABS_Y:
|
||||
if (dev->mt && multi_touch) return;
|
||||
handle_absolute_axis(dev, code, value, AXIS_Y);
|
||||
return;
|
||||
|
||||
case ABS_MT_POSITION_Y:
|
||||
if (!multi_touch) return;
|
||||
handle_absolute_axis(dev, code, value, AXIS_Y);
|
||||
return;
|
||||
|
||||
case ABS_MT_TRACKING_ID:
|
||||
if (!multi_touch) return;
|
||||
handle_mt_tracking_id(dev, value);
|
||||
return;
|
||||
|
||||
case ABS_MT_SLOT:
|
||||
if (!multi_touch) return;
|
||||
handle_mt_slot(value);
|
||||
return;
|
||||
|
||||
case ABS_MT_TOUCH_MAJOR:
|
||||
case ABS_MT_TOUCH_MINOR:
|
||||
case ABS_MT_ORIENTATION:
|
||||
case ABS_MT_TOOL_TYPE:
|
||||
case ABS_MT_BLOB_ID:
|
||||
case ABS_MT_PRESSURE:
|
||||
case ABS_MT_DISTANCE:
|
||||
case ABS_MT_TOOL_X:
|
||||
case ABS_MT_TOOL_Y:
|
||||
/* ignore unused multi-touch events */
|
||||
return;
|
||||
|
||||
default:
|
||||
Genode::warning("unknown absolute event code ", code, " not handled");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void handle_relative(unsigned code, int value)
|
||||
{
|
||||
input_event_type type;
|
||||
int x = 0, y = 0;
|
||||
|
||||
switch (code) {
|
||||
case REL_X:
|
||||
type = EVENT_TYPE_MOTION;
|
||||
x = value;
|
||||
break;
|
||||
|
||||
case REL_Y:
|
||||
type = EVENT_TYPE_MOTION;
|
||||
y = value;
|
||||
break;
|
||||
|
||||
case REL_HWHEEL:
|
||||
type = EVENT_TYPE_WHEEL;
|
||||
x = value;
|
||||
break;
|
||||
|
||||
case REL_WHEEL:
|
||||
type = EVENT_TYPE_WHEEL;
|
||||
y = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
Genode::warning("unknown relative event code ", code, " not handled");
|
||||
return;
|
||||
}
|
||||
|
||||
if (handler)
|
||||
handler(type, 0, 0, 0, x, y);
|
||||
}
|
||||
|
||||
|
||||
static void handle_key(input_dev *dev, unsigned code, int value)
|
||||
{
|
||||
/* no press/release events for multi-touch devices in multi-touch mode */
|
||||
if (dev->mt && multi_touch) return;
|
||||
|
||||
/* map BTN_TOUCH to BTN_LEFT */
|
||||
if (code == BTN_TOUCH) code = BTN_LEFT;
|
||||
|
||||
input_event_type type;
|
||||
switch (value) {
|
||||
case 0: type = EVENT_TYPE_RELEASE; break;
|
||||
case 1: type = EVENT_TYPE_PRESS; break;
|
||||
|
||||
default:
|
||||
Genode::warning("unknown key event value ", value, " not handled");
|
||||
return;
|
||||
}
|
||||
|
||||
if (handler)
|
||||
handler(type, code, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void genode_evdev_event(input_handle *handle, unsigned int type,
|
||||
unsigned int code, int value)
|
||||
{
|
||||
input_dev *dev = handle->dev;
|
||||
|
||||
/* filter sound events */
|
||||
if (test_bit(EV_SND, handle->dev->evbit)) return;
|
||||
|
||||
/* filter input_repeat_key() */
|
||||
if ((type == EV_KEY) && (value == 2)) return;
|
||||
|
||||
/* filter EV_SYN and EV_MSC */
|
||||
if (type == EV_SYN || type == EV_MSC) return;
|
||||
|
||||
switch (type) {
|
||||
case EV_KEY: handle_key(dev, code, value); return;
|
||||
case EV_REL: handle_relative(code, value); return;
|
||||
case EV_ABS: handle_absolute(dev, code, value); return;
|
||||
|
||||
default:
|
||||
Genode::warning("unknown event type ", type, " not handled");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void genode_input_register(genode_input_event_cb h, unsigned long res_x,
|
||||
unsigned long res_y, bool multitouch)
|
||||
{
|
||||
for (unsigned i = 0; i < sizeof(slots)/sizeof(*slots); ++i)
|
||||
slots[i].id = slots[i].event = slots[i].x = slots[i].y = -1;
|
||||
|
||||
handler = h;
|
||||
screen_x = res_x;
|
||||
screen_y = res_y;
|
||||
multi_touch = multitouch;
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
** Keyboard LED handling **
|
||||
***************************/
|
||||
|
||||
class Keyboard_led
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Registry<Keyboard_led>::Element _reg_elem;
|
||||
input_dev * const _input_dev;
|
||||
|
||||
usb_interface *_interface() {
|
||||
return container_of(_input_dev->dev.parent->parent, usb_interface, dev); }
|
||||
|
||||
usb_device *_usb_device() {
|
||||
return interface_to_usbdev(_interface()); }
|
||||
|
||||
public:
|
||||
|
||||
Keyboard_led(Genode::Registry<Keyboard_led> ®istry, input_dev *dev)
|
||||
: _reg_elem(registry, *this), _input_dev(dev) { }
|
||||
|
||||
bool match(input_dev const *other) const { return _input_dev == other; }
|
||||
|
||||
void update(unsigned leds)
|
||||
{
|
||||
unsigned *buf = (unsigned *)kmalloc(4, GFP_LX_DMA);
|
||||
*buf = leds;
|
||||
usb_control_msg(_usb_device(), usb_sndctrlpipe(_usb_device(), 0),
|
||||
0x9, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0x200,
|
||||
_interface()->cur_altsetting->desc.bInterfaceNumber,
|
||||
buf, 1, 500);
|
||||
kfree(buf);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static Genode::Registry<Keyboard_led> _registry;
|
||||
|
||||
|
||||
namespace Usb { class Led; }
|
||||
|
||||
class Usb::Led
|
||||
{
|
||||
private:
|
||||
|
||||
Lx::Task _task { _run, this, "led_worker", Lx::Task::PRIORITY_2,
|
||||
Lx::scheduler() };
|
||||
|
||||
completion _config_update;
|
||||
completion _led_update;
|
||||
|
||||
enum Update_state { NONE, UPDATE, BLOCKED };
|
||||
Update_state _update_state { NONE };
|
||||
|
||||
Led_state _capslock { Lx_kit::env().env(), "capslock" },
|
||||
_numlock { Lx_kit::env().env(), "numlock" },
|
||||
_scrlock { Lx_kit::env().env(), "scrlock" };
|
||||
|
||||
Genode::Signal_handler<Led> _config_handler {
|
||||
Lx_kit::env().env().ep(), *this, &Led::_handle_config };
|
||||
|
||||
void _handle_config()
|
||||
{
|
||||
Lx_kit::env().config_rom().update();
|
||||
Genode::Xml_node config = Lx_kit::env().config_rom().xml();
|
||||
|
||||
_capslock.update(config, _config_handler);
|
||||
_numlock .update(config, _config_handler);
|
||||
_scrlock .update(config, _config_handler);
|
||||
|
||||
complete(&_config_update);
|
||||
Lx::scheduler().schedule();
|
||||
}
|
||||
|
||||
static void _run(void *l)
|
||||
{
|
||||
Led *led = (Led *)l;
|
||||
|
||||
while (true) {
|
||||
/* config update from EP */
|
||||
wait_for_completion(&led->_config_update);
|
||||
|
||||
led->_update_state = UPDATE;
|
||||
|
||||
_registry.for_each([&] (Keyboard_led &keyboard) {
|
||||
led->update(keyboard); });
|
||||
|
||||
/* wake up other task that waits for regestry access */
|
||||
if (led->_update_state == BLOCKED)
|
||||
complete(&led->_led_update);
|
||||
|
||||
led->_update_state = NONE;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Led()
|
||||
{
|
||||
init_completion(&_config_update);
|
||||
init_completion(&_led_update);
|
||||
Genode::Signal_transmitter(_config_handler).submit();
|
||||
}
|
||||
|
||||
void update(Keyboard_led &keyboard)
|
||||
{
|
||||
unsigned leds = 0;
|
||||
|
||||
leds |= _capslock.enabled() ? 1u << LED_CAPSL : 0;
|
||||
leds |= _numlock.enabled() ? 1u << LED_NUML : 0;
|
||||
leds |= _scrlock.enabled() ? 1u << LED_SCROLLL : 0;
|
||||
|
||||
keyboard.update(leds);
|
||||
}
|
||||
|
||||
/*
|
||||
* wait for completion of registry and led state updates
|
||||
*/
|
||||
void wait_for_registry()
|
||||
{
|
||||
/* task in _run function might receive multiple updates */
|
||||
while ((_update_state == UPDATE)) {
|
||||
_update_state = BLOCKED;
|
||||
wait_for_completion(&_led_update);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static Genode::Constructible<Usb::Led> _led;
|
||||
|
||||
|
||||
static int led_connect(struct input_handler *handler, struct input_dev *dev,
|
||||
const struct input_device_id *id)
|
||||
{
|
||||
_led->wait_for_registry();
|
||||
|
||||
Keyboard_led *keyboard = new (Lx_kit::env().heap()) Keyboard_led(_registry, dev);
|
||||
_led->update(*keyboard);
|
||||
|
||||
input_handle *handle = (input_handle *)kzalloc(sizeof(input_handle), 0);
|
||||
handle->dev = input_get_device(dev);
|
||||
handle->handler = handler;
|
||||
|
||||
input_register_handle(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void led_disconnect(struct input_handle *handle)
|
||||
{
|
||||
input_dev *dev = handle->dev;
|
||||
|
||||
_led->wait_for_registry();
|
||||
|
||||
_registry.for_each([&] (Keyboard_led &keyboard) {
|
||||
if (keyboard.match(dev))
|
||||
destroy(Lx_kit::env().heap(), &keyboard);
|
||||
});
|
||||
|
||||
input_unregister_handle(handle);
|
||||
input_put_device(dev);
|
||||
kfree(handle);
|
||||
}
|
||||
|
||||
|
||||
static bool led_match(struct input_handler *handler, struct input_dev *dev)
|
||||
{
|
||||
hid_device *hid = (hid_device *)input_get_drvdata(dev);
|
||||
hid_report *report;
|
||||
|
||||
/* search report for keyboard entries */
|
||||
list_for_each_entry(report, &hid->report_enum[0].report_list, list) {
|
||||
|
||||
for (unsigned i = 0; i < report->maxfield; i++)
|
||||
for (unsigned j = 0; j < report->field[i]->maxusage; j++) {
|
||||
hid_usage *usage = report->field[i]->usage + j;
|
||||
if ((usage->hid & HID_USAGE_PAGE) == HID_UP_KEYBOARD) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static struct input_handler led_handler;
|
||||
static struct input_device_id led_ids[2];
|
||||
|
||||
static int led_init(void)
|
||||
{
|
||||
led_ids[0].driver_info = 1; /* match all */
|
||||
led_ids[1] = {};
|
||||
|
||||
led_handler.name = "led";
|
||||
led_handler.connect = led_connect;
|
||||
led_handler.disconnect = led_disconnect;
|
||||
led_handler.id_table = led_ids;
|
||||
led_handler.match = led_match;
|
||||
|
||||
_led.construct();
|
||||
|
||||
return input_register_handler(&led_handler);
|
||||
}
|
||||
|
||||
|
||||
extern "C" { module_init(led_init); }
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* \brief Linux 2.6 Input driver for USB HID
|
||||
* \author Christian Helmuth
|
||||
* \author Christian Prochaska
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2011-07-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <base/rpc_server.h>
|
||||
#include <event_session/connection.h>
|
||||
#include <os/ring_buffer.h>
|
||||
|
||||
#include <lx_emul.h>
|
||||
#include "platform.h"
|
||||
|
||||
#undef RELEASE
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/**
|
||||
* Singleton instance of input-session component
|
||||
*/
|
||||
static Genode::Constructible<Event::Connection> _event_session;
|
||||
|
||||
|
||||
/**
|
||||
* Input event call-back function
|
||||
*/
|
||||
static void input_callback(enum input_event_type type,
|
||||
unsigned code, int ax, int ay, int rx, int ry)
|
||||
{
|
||||
auto submit = [&] (Input::Event const &ev) {
|
||||
_event_session->with_batch([&] (Event::Session_client::Batch &batch) {
|
||||
batch.submit(ev); });
|
||||
};
|
||||
|
||||
using namespace Input;
|
||||
|
||||
switch (type) {
|
||||
case EVENT_TYPE_PRESS: submit(Press{Keycode(code)}); break;
|
||||
case EVENT_TYPE_RELEASE: submit(Release{Keycode(code)}); break;
|
||||
case EVENT_TYPE_MOTION:
|
||||
if (rx == 0 && ry == 0)
|
||||
submit(Absolute_motion{ax, ay});
|
||||
else
|
||||
submit(Relative_motion{rx, ry});
|
||||
break;
|
||||
case EVENT_TYPE_WHEEL: submit(Wheel{rx, ry}); break;
|
||||
case EVENT_TYPE_TOUCH:
|
||||
{
|
||||
Touch_id const id { (int)code };
|
||||
|
||||
if (rx == -1 && ry == -1)
|
||||
submit(Touch_release{id});
|
||||
else
|
||||
submit(Touch{id, (float)ax, (float)ay});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void start_input_service(void *service_ptr)
|
||||
{
|
||||
Services *service = static_cast<Services *>(service_ptr);
|
||||
Env &env = service->env;
|
||||
|
||||
_event_session.construct(env);
|
||||
|
||||
genode_input_register(input_callback, service->screen_width,
|
||||
service->screen_height, service->multitouch);
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* \brief Configuration of keyboard mode indicators
|
||||
* \author Norman Feske
|
||||
* \date 2017-10-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 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.
|
||||
*/
|
||||
|
||||
#ifndef _INPUT__LED_STATE_H_
|
||||
#define _INPUT__LED_STATE_H_
|
||||
|
||||
#include <util/xml_node.h>
|
||||
#include <util/reconstructible.h>
|
||||
#include <base/component.h>
|
||||
|
||||
namespace Usb { struct Led_state; }
|
||||
|
||||
|
||||
struct Usb::Led_state
|
||||
{
|
||||
Genode::Env &_env;
|
||||
|
||||
typedef Genode::String<32> Name;
|
||||
|
||||
Name const _name;
|
||||
|
||||
Genode::Constructible<Genode::Attached_rom_dataspace> _rom;
|
||||
|
||||
bool _enabled = false;
|
||||
|
||||
Led_state(Genode::Env &env, Name const &name) : _env(env), _name(name) { }
|
||||
|
||||
void update(Genode::Xml_node config, Genode::Signal_context_capability sigh)
|
||||
{
|
||||
typedef Genode::String<32> Attr;
|
||||
typedef Genode::String<16> Value;
|
||||
|
||||
Attr const attr(_name, "_led");
|
||||
Value const value = config.attribute_value(attr.string(), Value());
|
||||
|
||||
bool const rom_configured = (value == "rom");
|
||||
|
||||
if (rom_configured && !_rom.constructed()) {
|
||||
_rom.construct(_env, _name.string());
|
||||
_rom->sigh(sigh);
|
||||
}
|
||||
|
||||
if (!rom_configured && _rom.constructed())
|
||||
_rom.destruct();
|
||||
|
||||
if (_rom.constructed())
|
||||
_rom->update();
|
||||
|
||||
_enabled = _rom.constructed() ? _rom->xml().attribute_value("enabled", false)
|
||||
: config.attribute_value(attr.string(), false);
|
||||
}
|
||||
|
||||
bool enabled() const { return _enabled; }
|
||||
};
|
||||
|
||||
#endif /* _INPUT__LED_STATE_H_ */
|
File diff suppressed because it is too large
Load Diff
@ -1,221 +0,0 @@
|
||||
/*
|
||||
* \brief Startup USB driver library
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2013-02-20
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <base/component.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/sleep.h>
|
||||
#include <nic_session/nic_session.h>
|
||||
|
||||
/* Local */
|
||||
#include <signal.h>
|
||||
#include <lx_emul.h>
|
||||
|
||||
#include <lx_kit/env.h>
|
||||
#include <lx_kit/pci.h>
|
||||
#include <lx_kit/irq.h>
|
||||
#include <lx_kit/malloc.h>
|
||||
#include <lx_kit/scheduler.h>
|
||||
#include <lx_kit/timer.h>
|
||||
#include <lx_kit/work.h>
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern "C" int subsys_usb_init();
|
||||
extern "C" void subsys_input_init();
|
||||
extern "C" void module_evdev_init();
|
||||
extern "C" void module_hid_init();
|
||||
extern "C" void module_hid_init_core();
|
||||
extern "C" void module_hid_generic_init();
|
||||
extern "C" void module_usb_storage_driver_init();
|
||||
extern "C" void module_wacom_driver_init();
|
||||
extern "C" void module_ch_driver_init();
|
||||
extern "C" void module_ms_driver_init();
|
||||
extern "C" void module_mt_driver_init();
|
||||
extern "C" void module_raw_driver_init();
|
||||
extern "C" void module_led_init();
|
||||
|
||||
struct workqueue_struct *system_power_efficient_wq;
|
||||
struct workqueue_struct *system_wq;
|
||||
struct workqueue_struct *tasklet_wq;
|
||||
|
||||
void breakpoint() { Genode::log("BREAK"); }
|
||||
|
||||
|
||||
static void run_linux(void *s)
|
||||
{
|
||||
Services *services = (Services *)s;
|
||||
|
||||
system_power_efficient_wq = alloc_workqueue("system_power_efficient_wq", 0, 0);
|
||||
system_wq = alloc_workqueue("system_wq", 0, 0);
|
||||
tasklet_wq = alloc_workqueue("tasklet_wq", 0, 0);
|
||||
|
||||
/*
|
||||
* The RAW driver is initialized first to make sure that it doesn't miss
|
||||
* notifications about added devices.
|
||||
*/
|
||||
if (services->raw)
|
||||
/* low level interface */
|
||||
module_raw_driver_init();
|
||||
|
||||
/* USB */
|
||||
subsys_usb_init();
|
||||
|
||||
/* input + HID */
|
||||
if (services->hid) {
|
||||
subsys_input_init();
|
||||
module_evdev_init();
|
||||
module_led_init();
|
||||
|
||||
/* HID */
|
||||
module_hid_init_core();
|
||||
module_hid_init();
|
||||
module_hid_generic_init();
|
||||
module_ch_driver_init();
|
||||
module_ms_driver_init();
|
||||
module_mt_driver_init();
|
||||
module_wacom_driver_init();
|
||||
}
|
||||
|
||||
/* storage */
|
||||
if (services->stor)
|
||||
module_usb_storage_driver_init();
|
||||
|
||||
/* host controller */
|
||||
platform_hcd_init(Lx_kit::env().env(), services);
|
||||
|
||||
while (true)
|
||||
Lx::scheduler().current()->block_and_schedule();
|
||||
}
|
||||
|
||||
|
||||
void start_usb_driver(Genode::Env &env)
|
||||
{
|
||||
/* initialize USB env */
|
||||
Lx_kit::construct_env(env);
|
||||
|
||||
LX_MUTEX_INIT(hid_open_mut);
|
||||
LX_MUTEX_INIT(host_cmd_pool_mutex);
|
||||
LX_MUTEX_INIT(input_mutex);
|
||||
LX_MUTEX_INIT(usb_bus_list_lock);
|
||||
LX_MUTEX_INIT(usb_port_peer_mutex);
|
||||
LX_MUTEX_INIT(usbfs_mutex);
|
||||
LX_MUTEX_INIT(wacom_udev_list_lock);
|
||||
|
||||
/* sets up backend alloc needed by malloc */
|
||||
backend_alloc_init(env, env.ram(), Lx_kit::env().heap());
|
||||
|
||||
Lx::malloc_init(env, Lx_kit::env().heap());
|
||||
|
||||
static Services services(env);
|
||||
|
||||
if (services.hid)
|
||||
start_input_service(&services);
|
||||
|
||||
Storage::init(env);
|
||||
Nic::init(env);
|
||||
|
||||
if (services.raw)
|
||||
Raw::init(env, services.raw_report_device_list);
|
||||
|
||||
Lx::Scheduler &sched = Lx::scheduler(&env);
|
||||
Lx::Timer &timer = Lx::timer(&env, &env.ep(), &Lx_kit::env().heap(), &jiffies);
|
||||
|
||||
Lx::Irq::irq(&env.ep(), &Lx_kit::env().heap());
|
||||
Lx::Work::work_queue(&Lx_kit::env().heap());
|
||||
|
||||
static Lx::Task linux(run_linux, &services, "linux", Lx::Task::PRIORITY_0,
|
||||
Lx::scheduler());
|
||||
|
||||
Lx::scheduler().schedule();
|
||||
}
|
||||
|
||||
|
||||
namespace Usb_driver {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
struct Driver_starter { virtual void start_driver() = 0; };
|
||||
struct Main;
|
||||
}
|
||||
|
||||
|
||||
struct Usb_driver::Main : Driver_starter
|
||||
{
|
||||
Env &_env;
|
||||
|
||||
/*
|
||||
* Defer the startup of the USB driver until the first configuration
|
||||
* becomes available. This is needed in scenarios where the configuration
|
||||
* is dynamically generated and supplied to the USB driver via the
|
||||
* report-ROM service.
|
||||
*/
|
||||
struct Initial_config_handler
|
||||
{
|
||||
Driver_starter &_driver_starter;
|
||||
|
||||
Attached_rom_dataspace _config;
|
||||
|
||||
Signal_handler<Initial_config_handler> _config_handler;
|
||||
|
||||
void _handle_config()
|
||||
{
|
||||
_config.update();
|
||||
|
||||
if (_config.xml().type() == "config")
|
||||
_driver_starter.start_driver();
|
||||
}
|
||||
|
||||
Initial_config_handler(Env &env, Driver_starter &driver_starter)
|
||||
:
|
||||
_driver_starter(driver_starter),
|
||||
_config(env, "config"),
|
||||
_config_handler(env.ep(), *this, &Initial_config_handler::_handle_config)
|
||||
{
|
||||
_config.sigh(_config_handler);
|
||||
_handle_config();
|
||||
}
|
||||
};
|
||||
|
||||
void _handle_start()
|
||||
{
|
||||
if (_initial_config_handler.constructed()) {
|
||||
_initial_config_handler.destruct();
|
||||
start_usb_driver(_env);
|
||||
}
|
||||
}
|
||||
|
||||
Signal_handler<Main> _start_handler {
|
||||
_env.ep(), *this, &Main::_handle_start };
|
||||
|
||||
Reconstructible<Initial_config_handler> _initial_config_handler { _env, *this };
|
||||
|
||||
/*
|
||||
* Called from 'Initial_config_handler'
|
||||
*/
|
||||
void start_driver() override
|
||||
{
|
||||
Signal_transmitter(_start_handler).submit();
|
||||
}
|
||||
|
||||
Main(Env &env) : _env(env) { }
|
||||
};
|
||||
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
/* XXX execute constructors of global statics */
|
||||
env.exec_static_constructors();
|
||||
|
||||
static Usb_driver::Main main(env);
|
||||
}
|
@ -1,763 +0,0 @@
|
||||
/*
|
||||
* \brief Glue code for Linux network drivers
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-07-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/snprintf.h>
|
||||
#include <nic_session/nic_session.h>
|
||||
#include <util/xml_node.h>
|
||||
|
||||
/* Linux emulation environment includes */
|
||||
#include <lx_kit/env.h>
|
||||
#include <lx_kit/malloc.h>
|
||||
|
||||
/* NIC driver includes */
|
||||
#include <drivers/nic/mode.h>
|
||||
|
||||
/* local includes */
|
||||
#include <usb_nic_component.h>
|
||||
#include "signal.h"
|
||||
|
||||
|
||||
static Signal_helper *_signal = 0;
|
||||
|
||||
enum {
|
||||
HEAD_ROOM = 8, /* head room in skb in bytes */
|
||||
MAC_LEN = 17, /* 12 number and 6 colons */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Internal alloc function
|
||||
*/
|
||||
struct sk_buff *_alloc_skb(unsigned int size, bool tx = true);
|
||||
|
||||
|
||||
/**
|
||||
* Skb-bitmap allocator
|
||||
*/
|
||||
class Skb
|
||||
{
|
||||
private:
|
||||
|
||||
unsigned const _entries;
|
||||
|
||||
sk_buff *_buf;
|
||||
unsigned *_free;
|
||||
unsigned _idx;
|
||||
|
||||
enum { ENTRY_ELEMENT_SIZE = sizeof(unsigned) * 8 };
|
||||
|
||||
public:
|
||||
|
||||
Skb(unsigned const entries, unsigned const buffer_size)
|
||||
:
|
||||
_entries(entries), _idx(0)
|
||||
{
|
||||
unsigned const size = _entries / sizeof(unsigned);
|
||||
|
||||
_buf = (sk_buff *)kmalloc(sizeof(sk_buff) * _entries, GFP_KERNEL);
|
||||
_free = (unsigned *)kmalloc(sizeof(unsigned) * size, GFP_KERNEL);
|
||||
|
||||
Genode::memset(_free, 0xff, size * sizeof(unsigned));
|
||||
|
||||
for (unsigned i = 0; i < _entries; i++)
|
||||
_buf[i].start = (unsigned char *)kmalloc(buffer_size + NET_IP_ALIGN, GFP_NOIO);
|
||||
}
|
||||
|
||||
sk_buff *alloc()
|
||||
{
|
||||
unsigned const IDX = _entries / ENTRY_ELEMENT_SIZE;
|
||||
|
||||
for (unsigned i = 0; i < IDX; i++) {
|
||||
if (_free[_idx] != 0) {
|
||||
unsigned msb = Genode::log2(_free[_idx]);
|
||||
_free[_idx] ^= (1 << msb);
|
||||
|
||||
sk_buff *r = &_buf[(_idx * ENTRY_ELEMENT_SIZE) + msb];
|
||||
r->data = r->start;
|
||||
r->head = r->data;
|
||||
r->phys = 0;
|
||||
r->cloned = 0;
|
||||
r->clone = 0;
|
||||
r->len = 0;
|
||||
return r;
|
||||
}
|
||||
_idx = (_idx + 1) % IDX;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void free(sk_buff *buf)
|
||||
{
|
||||
unsigned entry = buf - &_buf[0];
|
||||
if (&_buf[0] > buf || entry > _entries)
|
||||
return;
|
||||
|
||||
_idx = entry / ENTRY_ELEMENT_SIZE;
|
||||
_free[_idx] |= (1 << (entry % ENTRY_ELEMENT_SIZE));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* send/receive skb allocators */
|
||||
static Skb *skb_tx(unsigned const elements = 0, unsigned const buffer_size = 0)
|
||||
{
|
||||
static Skb _skb(elements, buffer_size);
|
||||
return &_skb;
|
||||
}
|
||||
|
||||
|
||||
static Skb *skb_rx(unsigned const elements = 0, unsigned const buffer_size = 0)
|
||||
{
|
||||
static Skb _skb(elements, buffer_size);
|
||||
return &_skb;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prototype of fixup function
|
||||
*/
|
||||
extern "C" {
|
||||
typedef struct sk_buff* (*fixup_t)(struct usbnet *, struct sk_buff *, gfp_t);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Net_device to session glue code
|
||||
*/
|
||||
class Nic_device : public Usb_nic::Device
|
||||
{
|
||||
public:
|
||||
|
||||
struct net_device *_ndev; /* Linux-net device */
|
||||
fixup_t _tx_fixup;
|
||||
bool const _burst;
|
||||
bool _has_link { false };
|
||||
|
||||
public:
|
||||
|
||||
Nic_device(struct net_device *ndev)
|
||||
:
|
||||
_ndev(ndev),
|
||||
/* XXX should be configurable instead of guessing burst mode */
|
||||
_burst(((usbnet *)netdev_priv(ndev))->rx_urb_size > 2048)
|
||||
{
|
||||
struct usbnet *dev = (usbnet *)netdev_priv(_ndev);
|
||||
|
||||
/* initialize skb allocators */
|
||||
unsigned urb_cnt = dev->rx_urb_size <= 2048 ? 128 : 64;
|
||||
skb_rx(urb_cnt, dev->rx_urb_size);
|
||||
skb_tx(urb_cnt, dev->rx_urb_size);
|
||||
|
||||
if (!burst()) return;
|
||||
|
||||
/*
|
||||
* Retrieve 'tx_fixup' function from driver and set it to zero,
|
||||
* so it cannot be called by the actual driver. Required for
|
||||
* burst mode.
|
||||
*/
|
||||
_tx_fixup = dev->driver_info->tx_fixup;
|
||||
dev->driver_info->tx_fixup = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add device
|
||||
*/
|
||||
static Nic_device *add(struct net_device *ndev) {
|
||||
return new (Lx::Malloc::mem()) Nic_device(ndev); }
|
||||
|
||||
/**
|
||||
* Report link state
|
||||
*/
|
||||
void link_state(bool link)
|
||||
{
|
||||
/* only report changes of the link state */
|
||||
if (link == _has_link)
|
||||
return;
|
||||
|
||||
_has_link = link;
|
||||
|
||||
if (_session)
|
||||
_session->link_state_changed();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************
|
||||
** Device interface **
|
||||
**********************/
|
||||
|
||||
bool link_state() override { return _has_link; }
|
||||
|
||||
/**
|
||||
* Submit packet to driver
|
||||
*/
|
||||
bool tx(Genode::addr_t virt, Genode::size_t size)
|
||||
{
|
||||
sk_buff *skb;
|
||||
|
||||
if (!(skb = _alloc_skb(size + HEAD_ROOM)))
|
||||
return false;
|
||||
|
||||
skb->len = size;
|
||||
skb->data += HEAD_ROOM;
|
||||
Genode::memcpy(skb->data, (void *)virt, skb->len);
|
||||
|
||||
tx_skb(skb);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alloc an SKB
|
||||
*/
|
||||
sk_buff *alloc_skb()
|
||||
{
|
||||
struct usbnet *dev = (usbnet *)netdev_priv(_ndev);
|
||||
sk_buff *skb;
|
||||
|
||||
if (!(skb = _alloc_skb(dev->rx_urb_size)))
|
||||
return 0;
|
||||
|
||||
skb->len = 0;
|
||||
return skb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit SKB to the driver
|
||||
*/
|
||||
void tx_skb(sk_buff *skb)
|
||||
{
|
||||
struct usbnet *dev = (usbnet *)netdev_priv(_ndev);
|
||||
unsigned long dropped = dev->net->stats.tx_dropped;
|
||||
_ndev->netdev_ops->ndo_start_xmit(skb, _ndev);
|
||||
|
||||
if (dropped < dev->net->stats.tx_dropped)
|
||||
Genode::warning("Dropped SKB");
|
||||
}
|
||||
|
||||
/**
|
||||
* Call tx_fixup function of driver
|
||||
*/
|
||||
void tx_fixup(struct sk_buff *skb)
|
||||
{
|
||||
struct usbnet *dev = (usbnet *)netdev_priv(_ndev);
|
||||
if(!_tx_fixup || !_tx_fixup(dev, skb, 0))
|
||||
Genode::error("Tx fixup error");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fill an SKB with 'data' if 'size', return false if SKB is greater than
|
||||
* 'end'
|
||||
*/
|
||||
bool skb_fill(struct sk_buff *skb, unsigned char *data, Genode::size_t size, unsigned char *end)
|
||||
{
|
||||
Genode::addr_t align = ((Genode::addr_t)(data + 3) & ~3);
|
||||
skb->truesize = skb->data == 0 ? 0 : (unsigned char*)align - data;
|
||||
data = skb->data == 0 ? data : (unsigned char*)align;
|
||||
|
||||
skb->start = data;
|
||||
data += HEAD_ROOM;
|
||||
skb->len = size;
|
||||
skb->data = data;
|
||||
skb->end = skb->tail = data + size;
|
||||
skb->truesize += (skb->end - skb->start);
|
||||
|
||||
|
||||
return skb->end >= end ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit packet for session
|
||||
*/
|
||||
inline void rx(sk_buff *skb) { _session->rx((Genode::addr_t)skb->data, skb->len); }
|
||||
|
||||
/**
|
||||
* Return mac address
|
||||
*/
|
||||
Nic::Mac_address mac_address()
|
||||
{
|
||||
Nic::Mac_address m;
|
||||
Genode::memcpy(&m, _ndev->_dev_addr, ETH_ALEN);
|
||||
return m;
|
||||
}
|
||||
|
||||
bool burst() { return _burst; }
|
||||
};
|
||||
|
||||
|
||||
/* XXX support multiple devices */
|
||||
static Nic_device *_nic = 0;
|
||||
|
||||
|
||||
void Nic::init(Genode::Env &env) {
|
||||
_signal = new (Lx::Malloc::mem()) Signal_helper(env); }
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/netdevice.h **
|
||||
***********************/
|
||||
|
||||
int register_netdev(struct net_device *ndev)
|
||||
{
|
||||
using namespace Genode;
|
||||
static bool registered = false;
|
||||
int err = -ENODEV;
|
||||
|
||||
Nic_device *nic = Nic_device::add(ndev);
|
||||
if (nic == nullptr) {
|
||||
|
||||
class Invalid_nic_device { };
|
||||
throw Invalid_nic_device { };
|
||||
}
|
||||
|
||||
/* XXX: move to 'main' */
|
||||
if (!registered) {
|
||||
|
||||
registered = true;
|
||||
|
||||
Nic_driver_mode const mode {
|
||||
read_nic_driver_mode(Lx_kit::env().config_rom().xml()) };
|
||||
|
||||
switch (mode) {
|
||||
case Genode::Nic_driver_mode::NIC_SERVER:
|
||||
|
||||
static ::Root root(_signal->env(), Lx::Malloc::mem(), *nic);
|
||||
ndev->state |= 1 << __LINK_STATE_START;
|
||||
|
||||
if ((err = ndev->netdev_ops->ndo_open(ndev)))
|
||||
return err;
|
||||
|
||||
if (ndev->netdev_ops->ndo_set_rx_mode)
|
||||
ndev->netdev_ops->ndo_set_rx_mode(ndev);
|
||||
|
||||
_nic = nic;
|
||||
_signal->parent().announce(_signal->ep().rpc_ep().manage(&root));
|
||||
log("Acting as Nic server");
|
||||
break;
|
||||
|
||||
case Genode::Nic_driver_mode::UPLINK_CLIENT:
|
||||
|
||||
ndev->state |= 1 << __LINK_STATE_START;
|
||||
if ((err = ndev->netdev_ops->ndo_open(ndev)))
|
||||
return err;
|
||||
|
||||
_nic = nic;
|
||||
static Uplink_client uplink_client {
|
||||
_signal->env(), Lx::Malloc::mem(), *nic };
|
||||
|
||||
log("Acting as Uplink client");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int netif_running(const struct net_device *dev)
|
||||
{
|
||||
return dev->state & (1 << __LINK_STATE_START);
|
||||
}
|
||||
|
||||
|
||||
int netif_device_present(struct net_device *dev) { return 1; }
|
||||
|
||||
|
||||
int netif_carrier_ok(const struct net_device *dev)
|
||||
{
|
||||
return !(dev->state & (1 << __LINK_STATE_NOCARRIER));
|
||||
}
|
||||
|
||||
|
||||
void netif_carrier_on(struct net_device *dev)
|
||||
{
|
||||
dev->state &= ~(1 << __LINK_STATE_NOCARRIER);
|
||||
if (_nic)
|
||||
_nic->link_state(true);
|
||||
}
|
||||
|
||||
|
||||
void netif_carrier_off(struct net_device *dev)
|
||||
{
|
||||
dev->state |= 1 << __LINK_STATE_NOCARRIER;
|
||||
if (_nic)
|
||||
_nic->link_state(false);
|
||||
}
|
||||
|
||||
#ifdef GENODE_NET_STAT
|
||||
#include <nic/stat.h>
|
||||
static Timer::Connection _timer;
|
||||
static Nic::Measurement _stat(_timer);
|
||||
#endif
|
||||
|
||||
int netif_rx(struct sk_buff *skb)
|
||||
{
|
||||
if (_nic && _nic->session()) {
|
||||
_nic->rx(skb);
|
||||
}
|
||||
#ifdef GENODE_NET_STAT
|
||||
else if (_nic) {
|
||||
try {
|
||||
_stat.data(new (skb->data) Net::Ethernet_frame(skb->len), skb->len);
|
||||
} catch(Net::Ethernet_frame::No_ethernet_frame) {
|
||||
Genode::warning("No ether frame");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
dev_kfree_skb(skb);
|
||||
return NET_RX_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
** linux/skbuff.h **
|
||||
********************/
|
||||
|
||||
struct sk_buff *_alloc_skb(unsigned int size, bool tx)
|
||||
{
|
||||
sk_buff *skb = tx ? skb_tx()->alloc() : skb_rx()->alloc();
|
||||
|
||||
if (!skb)
|
||||
return 0;
|
||||
|
||||
size = (size + 3) & ~(0x3);
|
||||
|
||||
skb->end = skb->start + size;
|
||||
skb->tail = skb->start;
|
||||
skb->truesize = size;
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
|
||||
struct sk_buff *alloc_skb(unsigned int size, gfp_t priority)
|
||||
{
|
||||
/*
|
||||
* Note: This is only called for RX skb's by the driver
|
||||
*/
|
||||
struct sk_buff *skb = _alloc_skb(size, false);
|
||||
return skb;
|
||||
}
|
||||
|
||||
struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, unsigned int length)
|
||||
{
|
||||
struct sk_buff *s = _alloc_skb(length + NET_IP_ALIGN, false);
|
||||
if (s && dev->net_ip_align) {
|
||||
s->data += NET_IP_ALIGN;
|
||||
s->tail += NET_IP_ALIGN;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void dev_kfree_skb(struct sk_buff *skb)
|
||||
{
|
||||
lx_log(DEBUG_SKB, "free skb: %p start: %p cloned: %d",
|
||||
skb, skb->start, skb->cloned);
|
||||
|
||||
if (skb->cloned) {
|
||||
skb->start = skb->clone;
|
||||
skb->cloned = false;
|
||||
skb_rx()->free(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
skb_tx()->free(skb);
|
||||
skb_rx()->free(skb);
|
||||
}
|
||||
|
||||
|
||||
void dev_kfree_skb_any(struct sk_buff *skb) { dev_kfree_skb(skb); }
|
||||
|
||||
void kfree_skb(struct sk_buff *skb) { dev_kfree_skb(skb); }
|
||||
|
||||
|
||||
/**
|
||||
* Reserve 'len'
|
||||
*/
|
||||
void skb_reserve(struct sk_buff *skb, int len)
|
||||
{
|
||||
if ((skb->data + len) > skb->end) {
|
||||
Genode::error("Error resevring SKB data: skb: ", skb, " data: ", skb->data,
|
||||
" end: ", skb->end, "len: ", skb->len);
|
||||
return;
|
||||
}
|
||||
skb->data += len;
|
||||
lx_log(DEBUG_SKB, "skb: %p slen: %u len: %d", skb, skb->len, len);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepend 'len'
|
||||
*/
|
||||
unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
|
||||
{
|
||||
if((skb->data - len) < skb->start) {
|
||||
Genode::error("Error SKB head room too small: ", skb, " data: ", skb->data,
|
||||
" start: ", skb->start, " len: ", len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
skb->len += len;
|
||||
skb->data -= len;
|
||||
|
||||
lx_log(DEBUG_SKB, "skb: %p slen: %u len: %u", skb, skb->len, len);
|
||||
return skb->data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Append 'len'
|
||||
*/
|
||||
unsigned char *skb_put(struct sk_buff *skb, unsigned int len)
|
||||
{
|
||||
if ((skb->data + len > skb->end)) {
|
||||
Genode::error("Error increasing SKB length: skb: ", skb, " data: ", skb->data,
|
||||
" end: ", skb->end, " len: ", len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char *old = skb_tail_pointer(skb);
|
||||
skb->len += len;
|
||||
skb->tail += len;
|
||||
lx_log(DEBUG_SKB, "skb: %p slen: %u len: %u", skb, skb->len, len);
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return current head room
|
||||
*/
|
||||
unsigned int skb_headroom(const struct sk_buff *skb)
|
||||
{
|
||||
return skb->data - skb->start;
|
||||
}
|
||||
|
||||
|
||||
int skb_tailroom(const struct sk_buff *skb)
|
||||
{
|
||||
return skb->end - skb->tail;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Take 'len' from front
|
||||
*/
|
||||
unsigned char *skb_pull(struct sk_buff *skb, unsigned int len)
|
||||
{
|
||||
if (len > skb->len) {
|
||||
Genode::error("Error try to pull too much: skb: ", skb, " len: ", skb->len,
|
||||
" pull len: ", len);
|
||||
return 0;
|
||||
}
|
||||
skb->len -= len;
|
||||
lx_log(DEBUG_SKB, "skb: %p slen: %u len: %u", skb, skb->len, len);
|
||||
return skb->data += len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set 'len' and 'tail'
|
||||
*/
|
||||
void skb_trim(struct sk_buff *skb, unsigned int len)
|
||||
{
|
||||
if (skb->len < len) {
|
||||
Genode::error("Error trimming to ", len, " bytes skb: ", skb, " data: ",
|
||||
skb->data, " start: ", skb->start, " len ", skb->len);
|
||||
return;
|
||||
}
|
||||
|
||||
skb->len = len;
|
||||
skb_set_tail_pointer(skb, len);
|
||||
|
||||
lx_log(DEBUG_SKB, "skb: %p slen: %u len: %u", skb, skb->len, len);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clone skb
|
||||
*/
|
||||
struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
|
||||
{
|
||||
sk_buff *c;
|
||||
|
||||
if (!(c = alloc_skb(0,0)))
|
||||
return 0;
|
||||
|
||||
unsigned char *start = c->start;
|
||||
*c = *skb;
|
||||
|
||||
/* save old start pointer */
|
||||
c->cloned = 1;
|
||||
c->clone = start;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
int skb_header_cloned(const struct sk_buff *skb)
|
||||
{
|
||||
return skb->cloned;
|
||||
}
|
||||
|
||||
|
||||
void skb_set_tail_pointer(struct sk_buff *skb, const int offset)
|
||||
{
|
||||
skb->tail = skb->data + offset;
|
||||
}
|
||||
|
||||
|
||||
unsigned char *skb_tail_pointer(const struct sk_buff *skb)
|
||||
{
|
||||
return skb->tail;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dummy for shared info
|
||||
*/
|
||||
struct skb_shared_info *skb_shinfo(struct sk_buff const * /* skb */)
|
||||
{
|
||||
static skb_shared_info _s = { 0 };
|
||||
return &_s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Init list head
|
||||
*/
|
||||
void skb_queue_head_init(struct sk_buff_head *list)
|
||||
{
|
||||
static int count_x = 0;
|
||||
list->prev = list->next = (sk_buff *)list;
|
||||
list->qlen = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to tail of queue
|
||||
*/
|
||||
void __skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk)
|
||||
{
|
||||
newsk->next = (sk_buff *)list;
|
||||
newsk->prev = list->prev;
|
||||
list->prev->next = newsk;
|
||||
list->prev = newsk;
|
||||
list->qlen++;
|
||||
}
|
||||
|
||||
|
||||
void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk) {
|
||||
__skb_queue_tail(list, newsk); }
|
||||
|
||||
|
||||
/**
|
||||
* Remove skb from queue
|
||||
*/
|
||||
void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
|
||||
{
|
||||
if (!list->qlen)
|
||||
return;
|
||||
|
||||
skb->prev->next = skb->next;
|
||||
skb->next->prev = skb->prev;
|
||||
skb->next = skb->prev = 0;
|
||||
list->qlen--;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove from head of queue
|
||||
*/
|
||||
struct sk_buff *skb_dequeue(struct sk_buff_head *list)
|
||||
{
|
||||
if (list->qlen == 0)
|
||||
return 0;
|
||||
|
||||
sk_buff *skb = list->next;
|
||||
__skb_unlink(skb, list);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
** linux/inerrupt.h **
|
||||
**********************/
|
||||
|
||||
static void snprint_mac(char *buf, u8 *mac)
|
||||
{
|
||||
for (int i = 0; i < ETH_ALEN; i++)
|
||||
{
|
||||
Genode::snprintf((char *)&buf[i * 3], 3, "%02x", mac[i]);
|
||||
if ((i * 3) < MAC_LEN)
|
||||
buf[(i * 3) + 2] = ':';
|
||||
}
|
||||
|
||||
buf[MAC_LEN] = 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************
|
||||
** linux/etherdevice.h **
|
||||
*************************/
|
||||
|
||||
void eth_hw_addr_random(struct net_device *dev)
|
||||
{
|
||||
random_ether_addr(dev->_dev_addr);
|
||||
}
|
||||
|
||||
|
||||
void eth_random_addr(u8 *addr)
|
||||
{
|
||||
random_ether_addr(addr);
|
||||
}
|
||||
|
||||
|
||||
void random_ether_addr(u8 *addr)
|
||||
{
|
||||
using namespace Genode;
|
||||
char str[MAC_LEN + 1];
|
||||
u8 fallback[] = { 0x2e, 0x60, 0x90, 0x0c, 0x4e, 0x01 };
|
||||
Nic::Mac_address mac;
|
||||
|
||||
Xml_node config_node = Lx_kit::env().config_rom().xml();
|
||||
|
||||
/* try using configured mac */
|
||||
try {
|
||||
Xml_node nic_config = config_node.sub_node("nic");
|
||||
Xml_node::Attribute mac_node = nic_config.attribute("mac");
|
||||
mac_node.value(mac);
|
||||
} catch (...) {
|
||||
/* use fallback mac */
|
||||
snprint_mac(str, fallback);
|
||||
Genode::warning("No mac address or wrong format attribute in <nic> - using fallback (", Genode::Cstring(str), ")");
|
||||
|
||||
Genode::memcpy(addr, fallback, ETH_ALEN);
|
||||
return;
|
||||
}
|
||||
|
||||
/* use configured mac*/
|
||||
Genode::memcpy(addr, mac.addr, ETH_ALEN);
|
||||
snprint_mac(str, (u8 *)mac.addr);
|
||||
Genode::log("Using configured mac: ", Genode::Cstring(str));
|
||||
|
||||
#ifdef GENODE_NET_STAT
|
||||
_stat.set_mac(mac.addr);
|
||||
#endif
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,12 +0,0 @@
|
||||
#ifndef _RAW_H_
|
||||
#define _RAW_H_
|
||||
|
||||
struct usb_device;
|
||||
struct usb_driver;
|
||||
|
||||
extern struct usb_device_driver raw_driver;
|
||||
extern struct usb_driver raw_intf_driver;
|
||||
|
||||
int raw_notify(struct notifier_block *nb, unsigned long action, void *data);
|
||||
|
||||
#endif /* _RAW_H_ */
|
@ -1,94 +0,0 @@
|
||||
/*
|
||||
* \brief Low level USB access driver
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2014-11-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <linux/usb.h>
|
||||
#include "raw.h"
|
||||
|
||||
static int raw_probe(struct usb_device *udev)
|
||||
{
|
||||
printk("RAW: vendor: %x product: %x dev %p\n",
|
||||
udev->descriptor.idVendor, udev->descriptor.idProduct, udev);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void raw_disconnect(struct usb_device *udev)
|
||||
{
|
||||
printk("driver disconnect called\n");
|
||||
}
|
||||
|
||||
|
||||
struct usb_device_driver raw_driver =
|
||||
{
|
||||
.name = "raw",
|
||||
.probe = raw_probe,
|
||||
.disconnect = raw_disconnect,
|
||||
.supports_autosuspend = 0,
|
||||
};
|
||||
|
||||
|
||||
static int raw_intf_probe(struct usb_interface *intf,
|
||||
struct usb_device_id const *id)
|
||||
{
|
||||
struct usb_device *udev = interface_to_usbdev(intf);
|
||||
|
||||
printk("RAW_INTF: vendor: %04x product: %04x\n", udev->descriptor.idVendor,
|
||||
udev->descriptor.idProduct);
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
void raw_intf_disconnect(struct usb_interface *intf) { }
|
||||
|
||||
static const struct usb_device_id raw_intf_id_table[] = {
|
||||
{ .driver_info = 1 }
|
||||
};
|
||||
|
||||
|
||||
struct usb_driver raw_intf_driver =
|
||||
{
|
||||
.name = "rawintf",
|
||||
.probe = raw_intf_probe,
|
||||
.disconnect = raw_intf_disconnect,
|
||||
.supports_autosuspend = 0,
|
||||
};
|
||||
|
||||
|
||||
struct notifier_block usb_nb =
|
||||
{
|
||||
.notifier_call = raw_notify
|
||||
};
|
||||
|
||||
|
||||
static int raw_driver_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = usb_register_device_driver(&raw_driver, THIS_MODULE)))
|
||||
return err;
|
||||
|
||||
printk("RAW: driver registered\n");
|
||||
|
||||
if ((err = usb_register(&raw_intf_driver)))
|
||||
return err;
|
||||
|
||||
printk("RAW: interface driver registered\n");
|
||||
|
||||
usb_register_notify(&usb_nb);
|
||||
|
||||
printk("RAW: notify function registered\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
module_init(raw_driver_init);
|
@ -1,235 +0,0 @@
|
||||
/*
|
||||
* \brief Linux platform_device emulation
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-06-18
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <base/attached_io_mem_dataspace.h>
|
||||
#include <lx_emul.h>
|
||||
|
||||
#include <lx_kit/malloc.h>
|
||||
#include <lx_kit/env.h>
|
||||
|
||||
#define to_platform_driver(drv) (container_of((drv), struct platform_driver, \
|
||||
driver))
|
||||
|
||||
static int platform_match(struct device *dev, struct device_driver *drv)
|
||||
{
|
||||
if (!dev->name)
|
||||
return 0;
|
||||
|
||||
|
||||
printk("MATCH %s %s\n", dev->name, drv->name);
|
||||
return (strcmp(dev->name, drv->name) == 0);
|
||||
}
|
||||
|
||||
|
||||
static int platform_drv_probe(struct device *_dev)
|
||||
{
|
||||
struct platform_driver *drv = to_platform_driver(_dev->driver);
|
||||
struct platform_device *dev = to_platform_device(_dev);
|
||||
|
||||
return drv->probe(dev);
|
||||
}
|
||||
|
||||
|
||||
struct bus_type platform_bus_type = {
|
||||
.name = "platform",
|
||||
};
|
||||
|
||||
|
||||
int platform_driver_register(struct platform_driver *drv)
|
||||
{
|
||||
/* init plarform_bus_type */
|
||||
platform_bus_type.match = platform_match;
|
||||
platform_bus_type.probe = platform_drv_probe;
|
||||
|
||||
drv->driver.bus = &platform_bus_type;
|
||||
if (drv->probe)
|
||||
drv->driver.probe = platform_drv_probe;
|
||||
|
||||
printk("Register: %s\n", drv->driver.name);
|
||||
return driver_register(&drv->driver);
|
||||
}
|
||||
|
||||
|
||||
struct resource *platform_get_resource(struct platform_device *dev,
|
||||
unsigned int type, unsigned int num)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < dev->num_resources; i++) {
|
||||
struct resource *r = &dev->resource[i];
|
||||
|
||||
if ((type & r->flags) && num-- == 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct resource *platform_get_resource_byname(struct platform_device *dev,
|
||||
unsigned int type,
|
||||
const char *name)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < dev->num_resources; i++) {
|
||||
struct resource *r = &dev->resource[i];
|
||||
|
||||
if (type == r->flags && !strcmp(r->name, name))
|
||||
return r;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int platform_get_irq_byname(struct platform_device *dev, const char *name)
|
||||
{
|
||||
struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);
|
||||
return r ? r->start : -1;
|
||||
}
|
||||
|
||||
|
||||
int platform_get_irq(struct platform_device *dev, unsigned int num)
|
||||
{
|
||||
struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, 0);
|
||||
return r ? r->start : -1;
|
||||
}
|
||||
|
||||
|
||||
int platform_device_register(struct platform_device *pdev)
|
||||
{
|
||||
pdev->dev.bus = &platform_bus_type;
|
||||
pdev->dev.name = pdev->name;
|
||||
/*Set parent to ourselfs */
|
||||
if (!pdev->dev.parent)
|
||||
pdev->dev.parent = &pdev->dev;
|
||||
device_add(&pdev->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct platform_device *platform_device_alloc(const char *name, int id)
|
||||
{
|
||||
platform_device *pdev = (platform_device *)kzalloc(sizeof(struct platform_device), GFP_KERNEL);
|
||||
|
||||
if (!pdev)
|
||||
return 0;
|
||||
|
||||
int len = strlen(name);
|
||||
pdev->name = (char *)kzalloc(len + 1, GFP_KERNEL);
|
||||
|
||||
if (!pdev->name) {
|
||||
kfree(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(pdev->name, name, len);
|
||||
pdev->name[len] = 0;
|
||||
pdev->id = id;
|
||||
|
||||
return pdev;
|
||||
}
|
||||
|
||||
|
||||
int platform_device_add_data(struct platform_device *pdev, const void *data,
|
||||
size_t size)
|
||||
{
|
||||
void *d = NULL;
|
||||
|
||||
if (data && !(d = kmemdup(data, size, GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
|
||||
kfree(pdev->dev.platform_data);
|
||||
pdev->dev.platform_data = d;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int platform_device_add(struct platform_device *pdev)
|
||||
{
|
||||
return platform_device_register(pdev);
|
||||
}
|
||||
|
||||
int platform_device_add_resources(struct platform_device *pdev,
|
||||
const struct resource *res, unsigned int num)
|
||||
{
|
||||
struct resource *r = NULL;
|
||||
|
||||
if (res) {
|
||||
r = (resource *)kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
|
||||
if (!r)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
kfree(pdev->resource);
|
||||
pdev->resource = r;
|
||||
pdev->num_resources = num;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void *platform_get_drvdata(const struct platform_device *pdev)
|
||||
{
|
||||
return dev_get_drvdata(&pdev->dev);
|
||||
}
|
||||
|
||||
|
||||
void platform_set_drvdata(struct platform_device *pdev, void *data)
|
||||
{
|
||||
dev_set_drvdata(&pdev->dev, data);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
** asm-generic/io.h **
|
||||
**********************/
|
||||
|
||||
void *_ioremap(phys_addr_t phys_addr, unsigned long size, int wc)
|
||||
{
|
||||
try {
|
||||
Genode::Attached_io_mem_dataspace *ds = new(Lx::Malloc::mem())
|
||||
Genode::Attached_io_mem_dataspace(Lx_kit::env().env(), phys_addr, size, !!wc);
|
||||
return ds->local_addr<void>();
|
||||
} catch (...) {
|
||||
panic("Failed to request I/O memory: [%lx,%lx)", phys_addr, phys_addr + size);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *ioremap(phys_addr_t offset, unsigned long size)
|
||||
{
|
||||
return _ioremap(offset, size, 0);
|
||||
}
|
||||
|
||||
|
||||
void *devm_ioremap(struct device *dev, resource_size_t offset,
|
||||
unsigned long size)
|
||||
{
|
||||
return _ioremap(offset, size, 0);
|
||||
}
|
||||
|
||||
|
||||
void *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
|
||||
unsigned long size)
|
||||
{
|
||||
return _ioremap(offset, size, 0);
|
||||
}
|
||||
|
||||
|
||||
void *devm_ioremap_resource(struct device *dev, struct resource *res)
|
||||
{
|
||||
return _ioremap(res->start, res->end - res->start, 0);
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* \brief ARM specific implemenations used on all SOCs
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2016-04-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <base/env.h>
|
||||
#include <irq_session/connection.h>
|
||||
|
||||
#include <lx_emul/irq.h>
|
||||
#include <lx_kit/backend_alloc.h>
|
||||
#include <lx_kit/env.h>
|
||||
#include <lx_kit/irq.h>
|
||||
|
||||
|
||||
/****************************
|
||||
** lx_kit/backend_alloc.h **
|
||||
****************************/
|
||||
|
||||
void backend_alloc_init(Genode::Env&, Genode::Ram_allocator&,
|
||||
Genode::Allocator&)
|
||||
{
|
||||
/* intentionally left blank */
|
||||
}
|
||||
|
||||
|
||||
Genode::Ram_dataspace_capability
|
||||
Lx::backend_alloc(Genode::addr_t size, Genode::Cache cache) {
|
||||
return Lx_kit::env().env().ram().alloc(size, cache); }
|
||||
|
||||
|
||||
void Lx::backend_free(Genode::Ram_dataspace_capability cap) {
|
||||
return Lx_kit::env().env().ram().free(cap); }
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/interrupt.h **
|
||||
***********************/
|
||||
|
||||
extern "C" int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
|
||||
const char *name, void *dev)
|
||||
{
|
||||
struct Irq : Genode::List<Irq>::Element {
|
||||
unsigned const nr;
|
||||
Genode::Irq_connection irq_con { Lx_kit::env().env(), nr };
|
||||
Irq(unsigned const irq, Genode::List<Irq> & list)
|
||||
: nr(irq) { list.insert(this); }
|
||||
};
|
||||
|
||||
static Genode::List<Irq> irq_list;
|
||||
|
||||
Irq * i = irq_list.first();
|
||||
for (; i; i = i->next()) { if (i->nr == irq) break; }
|
||||
if (!i) i = new (Lx_kit::env().heap()) Irq(irq, irq_list);
|
||||
|
||||
Lx::Irq::irq().request_irq(i->irq_con.cap(), irq, handler, dev);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
include $(REP_DIR)/src/drivers/usb/target.inc
|
||||
|
||||
SRC_CC += platform_device.cc platform_generic.cc
|
||||
|
||||
INC_DIR += $(LIB_INC_DIR)/spec/arm
|
||||
INC_DIR += $(REP_DIR)/src/include/spec/arm
|
||||
|
||||
vpath platform_device.cc $(LIB_DIR)/spec/arm
|
||||
vpath platform_generic.cc $(LIB_DIR)/spec/arm
|
||||
|
||||
# vi:set ft=make :
|
@ -1,3 +0,0 @@
|
||||
include $(REP_DIR)/src/drivers/usb/spec/arm/target.inc
|
||||
|
||||
INC_DIR += $(LIB_INC_DIR)/spec/arm_v6
|
@ -1,3 +0,0 @@
|
||||
include $(REP_DIR)/src/drivers/usb/spec/arm/target.inc
|
||||
|
||||
INC_DIR += $(LIB_INC_DIR)/spec/arm_v7
|
@ -1,196 +0,0 @@
|
||||
/*
|
||||
* \brief USB initialization for Raspberry Pi
|
||||
* \author Norman Feske
|
||||
* \date 2013-09-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <io_mem_session/connection.h>
|
||||
#include <util/mmio.h>
|
||||
#include <platform_session/connection.h>
|
||||
|
||||
|
||||
/* emulation */
|
||||
#include <platform.h>
|
||||
#include <lx_emul.h>
|
||||
|
||||
/* dwc-otg */
|
||||
#define new new_
|
||||
#include <dwc_otg_dbg.h>
|
||||
#undef new
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/************************************************
|
||||
** Resource info passed to the dwc_otg driver **
|
||||
************************************************/
|
||||
|
||||
enum {
|
||||
DWC_BASE = 0x20980000,
|
||||
DWC_SIZE = 0x20000,
|
||||
DWC_IRQ = 9,
|
||||
};
|
||||
|
||||
|
||||
/***************************************
|
||||
** Supplement to lx_emul environment **
|
||||
***************************************/
|
||||
|
||||
#if VERBOSE_LX_EMUL
|
||||
#define TRACE lx_printf("\033[32m%s\033[0m called, not implemented\n", __PRETTY_FUNCTION__)
|
||||
#else
|
||||
#define TRACE
|
||||
#endif
|
||||
|
||||
#define DUMMY(retval, name) \
|
||||
extern "C" long name() { \
|
||||
lx_printf("\033[32m%s\033[0m called, not implemented, stop\n", #name); \
|
||||
bt(); \
|
||||
for (;;); \
|
||||
return retval; \
|
||||
}
|
||||
|
||||
#define CHECKED_DUMMY(retval, name) \
|
||||
extern "C" long name() { \
|
||||
lx_printf("\033[32m%s\033[0m called, not implemented, ignored\n", #name); \
|
||||
bt(); \
|
||||
return retval; \
|
||||
}
|
||||
|
||||
#define SILENT_DUMMY(retval, name) \
|
||||
extern "C" long name() { return retval; }
|
||||
|
||||
|
||||
/*********************
|
||||
** linux/hardirq.h **
|
||||
*********************/
|
||||
|
||||
int in_irq()
|
||||
{
|
||||
TRACE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*******************
|
||||
** linux/delay.h **
|
||||
*******************/
|
||||
|
||||
unsigned long loops_per_jiffy = 1;
|
||||
|
||||
/***********************************
|
||||
** Dummies for unused PCD driver **
|
||||
***********************************/
|
||||
|
||||
/*
|
||||
* The PCD driver is used for driving the DWC-OTG device as gadget. The
|
||||
* Raspberry Pi solely supports the use of the controller as host device.
|
||||
* Hence, the PCD parts are not needed.
|
||||
*/
|
||||
|
||||
DUMMY(-1, dwc_otg_pcd_disconnect_us);
|
||||
DUMMY(-1, dwc_otg_pcd_remote_wakeup);
|
||||
DUMMY(-1, dwc_otg_pcd_get_rmwkup_enable);
|
||||
DUMMY(-1, dwc_otg_pcd_initiate_srp);
|
||||
DUMMY(-1, pcd_remove);
|
||||
SILENT_DUMMY( 0, pcd_init);
|
||||
|
||||
|
||||
/************************************************************************
|
||||
** Prevent use of FIQ fix, need to resolve FIQ-related symbols anyway **
|
||||
************************************************************************/
|
||||
|
||||
void local_fiq_disable() { }
|
||||
void local_fiq_enable() { }
|
||||
extern "C" void fiq_fsm_spin_lock(void *lock) { }
|
||||
extern "C" void fiq_fsm_spin_unlock(void *lock) { }
|
||||
int claim_fiq(struct fiq_handler *f) { return 0; }
|
||||
void set_fiq_regs(struct pt_regs const *regs) { }
|
||||
void set_fiq_handler(void *start, unsigned int length) { }
|
||||
void enable_fiq() { }
|
||||
|
||||
void __FIQ_Branch(unsigned long *regs) { TRACE; }
|
||||
|
||||
extern "C" int fiq_fsm_too_late(struct fiq_state *st, int n) { TRACE; return 0; }
|
||||
extern "C" void dwc_otg_fiq_nop(struct fiq_state *state) { TRACE; }
|
||||
extern "C" void dwc_otg_fiq_fsm(struct fiq_state *state, int num_channels) { TRACE; }
|
||||
|
||||
unsigned char _dwc_otg_fiq_stub, _dwc_otg_fiq_stub_end;
|
||||
|
||||
|
||||
/***********************
|
||||
** asm/dma_mapping.h **
|
||||
***********************/
|
||||
|
||||
void *dma_to_virt(struct device *dev, dma_addr_t phys)
|
||||
{
|
||||
return phys_to_virt(phys);
|
||||
}
|
||||
|
||||
|
||||
/*******************
|
||||
** linux/timer.h **
|
||||
*******************/
|
||||
|
||||
struct tvec_base { };
|
||||
struct tvec_base boot_tvec_bases;
|
||||
|
||||
|
||||
/*******************
|
||||
** Init function **
|
||||
*******************/
|
||||
|
||||
extern "C" void module_dwc_otg_driver_init();
|
||||
extern "C" int module_usbnet_init();
|
||||
extern "C" int module_smsc95xx_driver_init();
|
||||
|
||||
void platform_hcd_init(Env &env, Services *services)
|
||||
{
|
||||
static resource _dwc_otg_resource[] =
|
||||
{
|
||||
{ DWC_BASE, DWC_BASE + DWC_SIZE - 1, "dwc_otg", IORESOURCE_MEM },
|
||||
{ DWC_IRQ, DWC_IRQ, "dwc_otg-irq" /* name unused */, IORESOURCE_IRQ }
|
||||
};
|
||||
|
||||
/* enable USB power */
|
||||
Platform::Connection platform(env);
|
||||
platform.power_state(Platform::Session::POWER_USB_HCD, true);
|
||||
|
||||
/* register network */
|
||||
if (services->nic) {
|
||||
module_usbnet_init();
|
||||
module_smsc95xx_driver_init();
|
||||
}
|
||||
|
||||
/* disable fiq optimization */
|
||||
fiq_enable = false;
|
||||
fiq_fsm_enable = false;
|
||||
|
||||
bool const verbose = false;
|
||||
if (verbose)
|
||||
g_dbg_lvl = DBG_HCD | DBG_CIL | DBG_HCD_URB;
|
||||
|
||||
module_dwc_otg_driver_init();
|
||||
|
||||
/* setup host-controller platform device */
|
||||
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
|
||||
pdev->name = (char *)"dwc_otg";
|
||||
pdev->id = 0;
|
||||
pdev->num_resources = sizeof(_dwc_otg_resource)/sizeof(resource);
|
||||
pdev->resource = _dwc_otg_resource;
|
||||
|
||||
/* needed for DMA buffer allocation. See 'hcd_buffer_alloc' in 'buffer.c' */
|
||||
static u64 dma_mask = ~(u64)0;
|
||||
pdev->dev.dma_mask = &dma_mask;
|
||||
pdev->dev.coherent_dma_mask = ~0;
|
||||
|
||||
platform_device_register(pdev);
|
||||
}
|
@ -1 +0,0 @@
|
||||
#include <spec/rpi/platform_session/client.h>
|
@ -1 +0,0 @@
|
||||
#include <spec/rpi/platform_session/platform_session.h>
|
@ -1,49 +0,0 @@
|
||||
TARGET = rpi_usb_drv
|
||||
REQUIRES = arm_v6
|
||||
|
||||
SRC_C += \
|
||||
usb/host/dwc_otg/dwc_otg/dwc_otg_adp.c \
|
||||
usb/host/dwc_otg/dwc_otg/dwc_otg_attr.c \
|
||||
usb/host/dwc_otg/dwc_otg/dwc_otg_cfi.c \
|
||||
usb/host/dwc_otg/dwc_otg/dwc_otg_cil.c \
|
||||
usb/host/dwc_otg/dwc_otg/dwc_otg_cil_intr.c \
|
||||
usb/host/dwc_otg/dwc_otg/dwc_otg_driver.c \
|
||||
usb/host/dwc_otg/dwc_otg/dwc_otg_hcd.c \
|
||||
usb/host/dwc_otg/dwc_otg/dwc_otg_hcd_ddma.c \
|
||||
usb/host/dwc_otg/dwc_otg/dwc_otg_hcd_intr.c \
|
||||
usb/host/dwc_otg/dwc_otg/dwc_otg_hcd_linux.c \
|
||||
usb/host/dwc_otg/dwc_otg/dwc_otg_hcd_queue.c \
|
||||
usb/host/dwc_otg/dwc_common_port/dwc_cc.c \
|
||||
usb/host/dwc_otg/dwc_common_port/dwc_common_linux.c \
|
||||
usb/host/dwc_otg/dwc_common_port/dwc_crypto.c \
|
||||
usb/host/dwc_otg/dwc_common_port/dwc_dh.c \
|
||||
usb/host/dwc_otg/dwc_common_port/dwc_mem.c \
|
||||
usb/host/dwc_otg/dwc_common_port/dwc_modpow.c \
|
||||
usb/host/dwc_otg/dwc_common_port/dwc_notifier.c
|
||||
|
||||
SRC_C += net/usb/usbnet.c net/usb/smsc95xx.c
|
||||
|
||||
include $(REP_DIR)/src/drivers/usb/spec/arm_v6/target.inc
|
||||
|
||||
CC_OPT += -DDWC_LINUX -DPLATFORM_INTERFACE
|
||||
|
||||
# needed for 'ehci-hcd.c', which we don't use on the rpi, but it is still
|
||||
# part of the generic usb USB driver
|
||||
CC_OPT += -DCONFIG_USB_EHCI_PCI=1
|
||||
|
||||
# for 'dwc_otg_hcd_linux.c' for enabling the FIQ, which we don't use anyway
|
||||
CC_OPT += -DINTERRUPT_VC_USB=9
|
||||
|
||||
# for 'dwc_otg_driver.c' for preventing calls to set_irq_type
|
||||
CC_OPT += -DIRQF_TRIGGER_LOW=1
|
||||
|
||||
INC_DIR += $(LX_CONTRIB_DIR)/drivers/usb/host/dwc_otg/dwc_common_port \
|
||||
$(LX_CONTRIB_DIR)/drivers/usb/host/dwc_otg/dwc_otg \
|
||||
$(call select_from_repositories,include/spec/rpi)
|
||||
SRC_CC += platform.cc
|
||||
|
||||
vpath platform.cc $(LIB_DIR)/spec/rpi
|
||||
vpath %.c $(LX_CONTRIB_DIR)/drivers/net/usb
|
||||
|
||||
# enable C++11 support
|
||||
CC_CXX_OPT += -std=gnu++11
|
@ -1,205 +0,0 @@
|
||||
/*
|
||||
* \brief PCI device handling
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2016-04-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/allocator.h>
|
||||
#include <base/entrypoint.h>
|
||||
#include <base/signal.h>
|
||||
#include <util/misc_math.h>
|
||||
|
||||
#include <lx_emul.h>
|
||||
|
||||
#include <lx_kit/env.h>
|
||||
#include <lx_kit/irq.h>
|
||||
#include <lx_kit/pci_dev_registry.h>
|
||||
#include <lx_kit/malloc.h>
|
||||
#include <lx_kit/mapped_io_mem_range.h>
|
||||
|
||||
#include <lx_emul/impl/io.h>
|
||||
#include <lx_emul/impl/pci_resource.h>
|
||||
|
||||
|
||||
/**
|
||||
* Quirks
|
||||
*/
|
||||
extern "C" void __pci_fixup_quirk_usb_early_handoff(void *data);
|
||||
|
||||
|
||||
/**
|
||||
* List of pci devices from platform driver
|
||||
*/
|
||||
class Pci_dev_list
|
||||
{
|
||||
private:
|
||||
|
||||
struct Element : public Lx_kit::List<Element>::Element
|
||||
{
|
||||
Platform::Device_capability cap;
|
||||
|
||||
Element(Platform::Device_capability cap) : cap(cap) { }
|
||||
};
|
||||
|
||||
Lx_kit::List<Element> _pci_caps;
|
||||
|
||||
public:
|
||||
|
||||
Pci_dev_list()
|
||||
{
|
||||
/*
|
||||
* Obtain first device, the operation may exceed the session quota.
|
||||
* So we use the 'with_upgrade' mechanism.
|
||||
*/
|
||||
Platform::Device_capability cap =
|
||||
Lx::pci()->with_upgrade([&] () {
|
||||
return Lx::pci()->first_device(); });
|
||||
|
||||
/*
|
||||
* Iterate over the devices of the platform session.
|
||||
*/
|
||||
while (cap.valid()) {
|
||||
|
||||
/*
|
||||
* Keep PCI devices in natural bus order. Otherwise on a Lenovo
|
||||
* ThinkCentre M57p, the system locks up when the UHCI
|
||||
* controller BIOS handoff (disabling bit 4 in the LEGSUP
|
||||
* register) for the controller with PCI BDF 00:1d:2 is
|
||||
* attempted before the handoff for the controller with BDF
|
||||
* 00:1a:0.
|
||||
*/
|
||||
_pci_caps.append(new (Lx::Malloc::mem()) Element(cap));
|
||||
|
||||
/* try next one. Upgrade session quota on demand.*/
|
||||
Lx::pci()->with_upgrade([&] () {
|
||||
cap = Lx::pci()->next_device(cap); });
|
||||
}
|
||||
}
|
||||
|
||||
template <typename FUNC>
|
||||
void for_each_pci_device(FUNC const &func)
|
||||
{
|
||||
for (Element *e = _pci_caps.first(); e; e = e->next())
|
||||
func(e->cap);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Pci_dev_list *pci_dev_list()
|
||||
{
|
||||
static Pci_dev_list _list;
|
||||
return &_list;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int pci_register_driver(struct pci_driver *driver)
|
||||
{
|
||||
driver->driver.name = driver->name;
|
||||
|
||||
pci_device_id const *id_table = driver->id_table;
|
||||
if (!id_table)
|
||||
return -ENODEV;
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
bool found = false;
|
||||
|
||||
auto lambda = [&] (Platform::Device_capability cap) {
|
||||
|
||||
Platform::Device_client client(cap);
|
||||
|
||||
/* request device ID from platform driver */
|
||||
unsigned const class_code = client.class_code();
|
||||
|
||||
/* look if we find the device ID in the driver's 'id_table' */
|
||||
pci_device_id const *matching_id = nullptr;
|
||||
for (pci_device_id const *id = id_table; id->device; id++) {
|
||||
|
||||
lx_log(DEBUG_PCI,"idclass: %x idclassm: %x devclass %x", id->class_,
|
||||
id->class_mask, class_code);
|
||||
|
||||
/* check for drivers that support any device for a given class */
|
||||
if (id->device != (unsigned)PCI_ANY_ID || !id->class_mask)
|
||||
continue;
|
||||
|
||||
if ((id->class_ & id->class_mask) == (class_code & id->class_mask)) {
|
||||
matching_id = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* skip device that is not handled by driver */
|
||||
if (!matching_id)
|
||||
return false;
|
||||
|
||||
/* create 'pci_dev' struct for matching device */
|
||||
Lx::Pci_dev *pci_dev = new (Lx::Malloc::mem()) Lx::Pci_dev(cap);
|
||||
|
||||
/* enable ioremap to work */
|
||||
Lx::pci_dev_registry()->insert(pci_dev);
|
||||
|
||||
/* register driver at the 'pci_dev' struct */
|
||||
pci_dev->dev.driver = &driver->driver;
|
||||
|
||||
/*
|
||||
* This quirk handles device handoff from BIOS, since the BIOS may still
|
||||
* access the USB controller after bootup. For this the ext cap register of
|
||||
* the PCI config space is checked
|
||||
*/
|
||||
if (Lx_kit::env().config_rom().xml().attribute_value("bios_handoff", true))
|
||||
__pci_fixup_quirk_usb_early_handoff(pci_dev);
|
||||
|
||||
/* call probe function of the Linux driver */
|
||||
if (driver->probe(pci_dev, matching_id)) {
|
||||
|
||||
/* if the probing failed, revert the creation of 'pci_dev' */
|
||||
pci_dev_put(pci_dev);
|
||||
return false;
|
||||
}
|
||||
|
||||
found = true;
|
||||
|
||||
/* multiple device support continue */
|
||||
return true;
|
||||
};
|
||||
|
||||
pci_dev_list()->for_each_pci_device(lambda);
|
||||
|
||||
return found ? 0 : -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/interrupt.h **
|
||||
***********************/
|
||||
|
||||
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
|
||||
const char *name, void *dev)
|
||||
{
|
||||
for (Lx::Pci_dev *pci_dev = Lx::pci_dev_registry()->first(); pci_dev; pci_dev = pci_dev->next())
|
||||
if (pci_dev->irq == irq) {
|
||||
Lx::Irq::irq().request_irq(pci_dev->client().irq(0), irq, handler, dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
/*********************************
|
||||
** Platform backend alloc init **
|
||||
*********************************/
|
||||
|
||||
void backend_alloc_init(Genode::Env &env, Genode::Ram_allocator &ram,
|
||||
Genode::Allocator &alloc)
|
||||
{
|
||||
Lx::pci_init(env, ram, alloc);
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* \brief X86 platform initialization
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2013-05-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
|
||||
extern "C" void module_ax88179_178a_driver_init();
|
||||
extern "C" void module_cdc_driver_init();
|
||||
extern "C" void module_rndis_driver_init();
|
||||
extern "C" void module_usbnet_init();
|
||||
extern "C" void module_ehci_hcd_init();
|
||||
extern "C" void module_ehci_pci_init();
|
||||
extern "C" void module_ohci_hcd_mod_init();
|
||||
extern "C" void module_ohci_pci_init();
|
||||
extern "C" void module_uhci_hcd_init();
|
||||
extern "C" void module_xhci_hcd_init();
|
||||
extern "C" void module_xhci_pci_init();
|
||||
|
||||
void platform_hcd_init(Genode::Env &, Services *s)
|
||||
{
|
||||
if (s->nic) {
|
||||
module_usbnet_init();
|
||||
module_ax88179_178a_driver_init();
|
||||
module_cdc_driver_init();
|
||||
module_rndis_driver_init();
|
||||
}
|
||||
|
||||
if (s->xhci) {
|
||||
module_xhci_hcd_init();
|
||||
module_xhci_pci_init();
|
||||
}
|
||||
|
||||
/* ehci_hcd should always be loaded before uhci_hcd and ohci_hcd, not after */
|
||||
if (s->ehci) {
|
||||
module_ehci_hcd_init();
|
||||
module_ehci_pci_init();
|
||||
}
|
||||
|
||||
if (s->ohci) {
|
||||
module_ohci_hcd_mod_init();
|
||||
module_ohci_pci_init();
|
||||
}
|
||||
|
||||
if (s->uhci) {
|
||||
module_uhci_hcd_init();
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
SRC_C += $(addprefix usb/host/,pci-quirks.c uhci-hcd.c ehci-pci.c ohci-hcd.c ohci-pci.c)
|
||||
SRC_C += usb/core/hcd-pci.c
|
||||
|
||||
#
|
||||
# USB netwpork support
|
||||
#
|
||||
SRC_C += $(addprefix net/usb/, usbnet.c ax88179_178a.c cdc_ether.c rndis_host.c)
|
||||
|
||||
# XHCI
|
||||
SRC_C += usb/host/xhci-pci.c
|
||||
|
||||
# PCI
|
||||
SRC_CC += pci_driver.cc platform.cc
|
||||
|
||||
# lx_kit
|
||||
SRC_CC += pci.cc mapped_io_mem_range.cc
|
||||
|
||||
|
||||
include $(REP_DIR)/src/drivers/usb/xhci.inc
|
||||
include $(REP_DIR)/src/drivers/usb/target.inc
|
||||
|
||||
CC_OPT += -DCONFIG_PCI -DCONFIG_USB_EHCI_PCI=1 -DCONFIG_USB_XHCI_HCD=1
|
||||
|
||||
vpath platform.cc $(LIB_DIR)/spec/x86
|
||||
vpath pci_driver.cc $(LIB_DIR)/spec/x86
|
||||
|
||||
# vi:set ft=make :
|
@ -1,7 +0,0 @@
|
||||
TARGET = usb_drv
|
||||
REQUIRES = x86_32
|
||||
|
||||
INC_DIR += $(LIB_INC_DIR)/spec/x86_32 $(LIB_INC_DIR)/spec/x86
|
||||
INC_DIR += $(REP_DIR)/src/include/spec/x86_32
|
||||
|
||||
include $(REP_DIR)/src/drivers/usb/spec/x86/target.inc
|
@ -1,7 +0,0 @@
|
||||
TARGET = usb_drv
|
||||
REQUIRES = x86_64
|
||||
|
||||
INC_DIR += $(LIB_INC_DIR)/spec/x86_64 $(LIB_INC_DIR)/spec/x86
|
||||
INC_DIR += $(REP_DIR)/src/include/spec/x86_64
|
||||
|
||||
include $(REP_DIR)/src/drivers/usb/spec/x86/target.inc
|
@ -1,235 +0,0 @@
|
||||
/*
|
||||
* \brief SCSI support emulation
|
||||
* \author Christian Helmuth
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2009-10-29
|
||||
*
|
||||
* XXX NOTES XXX
|
||||
*
|
||||
* struct scsi_host_template
|
||||
*
|
||||
* struct scsi_host
|
||||
*
|
||||
* host_lock used by scsi_unlock, scsi_lock
|
||||
* max_id used by usb_stor_report_device_reset
|
||||
*
|
||||
* struct scsi_cmnd
|
||||
*
|
||||
* functions
|
||||
*
|
||||
* scsi_add_host
|
||||
* scsi_host_alloc
|
||||
* scsi_host_get
|
||||
* scsi_host_put
|
||||
* scsi_remove_host
|
||||
* scsi_report_bus_reset
|
||||
* scsi_report_device_reset
|
||||
* scsi_scan_host
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <lx_emul.h>
|
||||
|
||||
#include <storage/scsi.h>
|
||||
|
||||
#define DEBUG_SCSI 0
|
||||
|
||||
/***************
|
||||
** SCSI host **
|
||||
***************/
|
||||
|
||||
struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *t, int priv_size)
|
||||
{
|
||||
lx_log(DEBUG_SCSI, "t=%p, priv_size=%d", t, priv_size);
|
||||
|
||||
static int free = 1;
|
||||
|
||||
/* XXX we not some extra space for hostdata[] */
|
||||
static char buffer[4096] __attribute__((aligned(4096)));
|
||||
static struct Scsi_Host *host = (struct Scsi_Host *)buffer;
|
||||
|
||||
/* FIXME we support only one host for now */
|
||||
if (!free) return 0;
|
||||
free = 0;
|
||||
|
||||
host->host_lock = &host->default_lock;
|
||||
spin_lock_init(host->host_lock);
|
||||
|
||||
host->host_no = 13;
|
||||
host->max_id = 8;
|
||||
host->hostt = t;
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
|
||||
static struct page *_page(struct scsi_cmnd *cmnd)
|
||||
{
|
||||
return (struct page *)cmnd->sdb.table.sgl->page_link;
|
||||
}
|
||||
|
||||
|
||||
void scsi_alloc_buffer(size_t size, struct scsi_cmnd *cmnd)
|
||||
{
|
||||
scsi_setup_buffer(cmnd, size, 0, 0);
|
||||
struct scatterlist *sgl = cmnd->sdb.table.sgl;
|
||||
struct page *page = _page(cmnd);
|
||||
page->virt = kmalloc(size, GFP_NOIO);
|
||||
page->phys = dma_map_single_attrs(0, page->virt, 0, 0, 0);
|
||||
sgl->dma_address = page->phys;
|
||||
}
|
||||
|
||||
|
||||
void scsi_setup_buffer(struct scsi_cmnd *cmnd, size_t size, void *virt, dma_addr_t addr)
|
||||
{
|
||||
cmnd->sdb.table.nents = 1;
|
||||
cmnd->sdb.length = size;
|
||||
|
||||
struct scatterlist *sgl = cmnd->sdb.table.sgl;
|
||||
|
||||
struct page *page = _page(cmnd);
|
||||
page->virt = virt;
|
||||
page->phys = addr;
|
||||
|
||||
sgl->page_link = (unsigned long)page;
|
||||
sgl->offset = 0;
|
||||
sgl->length = size;
|
||||
sgl->dma_address = addr;
|
||||
sgl->last = 1;
|
||||
}
|
||||
|
||||
|
||||
void scsi_free_buffer(struct scsi_cmnd *cmnd)
|
||||
{
|
||||
struct page *page = _page(cmnd);
|
||||
if (page)
|
||||
kfree(page->virt);
|
||||
}
|
||||
|
||||
|
||||
void *scsi_buffer_data(struct scsi_cmnd *cmnd)
|
||||
{
|
||||
return _page(cmnd)->virt;
|
||||
}
|
||||
|
||||
|
||||
struct scsi_cmnd *_scsi_alloc_command()
|
||||
{
|
||||
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)kmalloc(sizeof(struct scsi_cmnd), GFP_KERNEL);
|
||||
cmnd->sdb.table.sgl = (struct scatterlist *)kmalloc(sizeof(struct scatterlist), GFP_KERNEL);
|
||||
cmnd->cmnd = kzalloc(MAX_COMMAND_SIZE, 0);
|
||||
cmnd->sdb.table.sgl->page_link = (unsigned long) kzalloc(sizeof(struct page), 0);
|
||||
cmnd->sense_buffer = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
|
||||
return cmnd;
|
||||
}
|
||||
|
||||
|
||||
void _scsi_free_command(struct scsi_cmnd *cmnd)
|
||||
{
|
||||
kfree((void *)cmnd->sdb.table.sgl->page_link);
|
||||
kfree(cmnd->sdb.table.sgl);
|
||||
kfree(cmnd->sense_buffer);
|
||||
kfree(cmnd->cmnd);
|
||||
kfree(cmnd);
|
||||
}
|
||||
|
||||
|
||||
static void inquiry_done(struct scsi_cmnd *cmnd)
|
||||
{
|
||||
char *data = (char *)scsi_buffer_data(cmnd);
|
||||
lx_printf("Vendor id: %c%c%c%c%c%c%c%c Product id: %s\n",
|
||||
data[8], data[9], data[10], data[11], data[12],
|
||||
data[13], data[14], data[15], &data[16]);
|
||||
complete(cmnd->back);
|
||||
}
|
||||
|
||||
|
||||
static void scsi_done(struct scsi_cmnd *cmd)
|
||||
{
|
||||
complete(cmd->back);
|
||||
}
|
||||
|
||||
|
||||
void scsi_scan_host(struct Scsi_Host *host)
|
||||
{
|
||||
struct scsi_cmnd *cmnd;
|
||||
struct scsi_device *sdev;
|
||||
struct scsi_target *target;
|
||||
struct completion compl;
|
||||
void *result;
|
||||
|
||||
init_completion(&compl);
|
||||
|
||||
sdev = (struct scsi_device *)kmalloc(sizeof(struct scsi_device), GFP_KERNEL);
|
||||
target = (struct scsi_target *)kmalloc(sizeof(struct scsi_target), GFP_KERNEL);
|
||||
|
||||
cmnd = _scsi_alloc_command();
|
||||
|
||||
/* init device */
|
||||
sdev->sdev_target = target;
|
||||
sdev->host = host;
|
||||
sdev->id = 0;
|
||||
sdev->lun = 0;
|
||||
host->hostt->slave_alloc(sdev);
|
||||
host->hostt->slave_configure(sdev);
|
||||
|
||||
/* inquiry (36 bytes for usb) */
|
||||
scsi_alloc_buffer(sdev->inquiry_len, cmnd);
|
||||
cmnd->cmnd[0] = INQUIRY;
|
||||
cmnd->cmnd[4] = sdev->inquiry_len;
|
||||
cmnd->device = sdev;
|
||||
cmnd->cmd_len = 6;
|
||||
cmnd->sc_data_direction = DMA_FROM_DEVICE;
|
||||
|
||||
cmnd->back = &compl;
|
||||
cmnd->scsi_done = inquiry_done;
|
||||
|
||||
host->hostt->queuecommand(host, cmnd);
|
||||
wait_for_completion(&compl);
|
||||
|
||||
/* if PQ and PDT are zero we have a direct access block device conntected */
|
||||
result = scsi_buffer_data(cmnd);
|
||||
if (!((char*)result)[0])
|
||||
scsi_add_device(sdev);
|
||||
else {
|
||||
kfree(sdev);
|
||||
kfree(target);
|
||||
}
|
||||
|
||||
scsi_free_buffer(cmnd);
|
||||
_scsi_free_command(cmnd);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
** scsi/scsi_cmnd.h **
|
||||
**********************/
|
||||
|
||||
unsigned scsi_bufflen(struct scsi_cmnd *cmnd) { return cmnd->sdb.length; }
|
||||
struct scatterlist *scsi_sglist(struct scsi_cmnd *cmnd) { return cmnd->sdb.table.sgl; }
|
||||
unsigned scsi_sg_count(struct scsi_cmnd *cmnd) { return cmnd->sdb.table.nents; }
|
||||
|
||||
|
||||
/********************
|
||||
** scsi/scsi_eh.h **
|
||||
*******************/
|
||||
|
||||
void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd,
|
||||
struct scsi_eh_save *ses, unsigned char *cmnd,
|
||||
int cmnd_size, unsigned sense_bytes)
|
||||
{
|
||||
ses->cmd_len = scmd->cmd_len;
|
||||
}
|
||||
|
||||
|
||||
void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd,
|
||||
struct scsi_eh_save *ses)
|
||||
{
|
||||
scmd->cmd_len = ses->cmd_len;
|
||||
}
|
@ -1,246 +0,0 @@
|
||||
/*
|
||||
* \brief USB storage glue
|
||||
* \author Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
* \date 2012-05-06
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <block/component.h>
|
||||
#include <util/endian.h>
|
||||
#include <util/list.h>
|
||||
|
||||
#include <lx_emul.h>
|
||||
|
||||
#include <lx_kit/malloc.h>
|
||||
#include <lx_kit/backend_alloc.h>
|
||||
#include <lx_kit/scheduler.h>
|
||||
|
||||
#include <lx_emul/extern_c_begin.h>
|
||||
#include <storage/scsi.h>
|
||||
#include <drivers/usb/storage/usb.h>
|
||||
#include <lx_emul/extern_c_end.h>
|
||||
|
||||
#include "signal.h"
|
||||
|
||||
static Signal_helper *_signal = 0;
|
||||
|
||||
class Storage_device : public Genode::List<Storage_device>::Element,
|
||||
public Block::Driver
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::size_t _block_size;
|
||||
Block::sector_t _block_count;
|
||||
struct scsi_device *_sdev;
|
||||
|
||||
static void _sync_done(struct scsi_cmnd *cmnd) {
|
||||
complete((struct completion *)cmnd->back); }
|
||||
|
||||
static void _async_done(struct scsi_cmnd *cmnd);
|
||||
|
||||
void _capacity()
|
||||
{
|
||||
struct completion comp;
|
||||
|
||||
struct scsi_cmnd *cmnd = _scsi_alloc_command();
|
||||
|
||||
/* alloc data for command */
|
||||
scsi_alloc_buffer(8, cmnd);
|
||||
|
||||
cmnd->cmnd[0] = READ_CAPACITY;
|
||||
cmnd->cmd_len = 10;
|
||||
cmnd->device = _sdev;
|
||||
cmnd->sc_data_direction = DMA_FROM_DEVICE;
|
||||
|
||||
init_completion(&comp);
|
||||
cmnd->back = ∁
|
||||
cmnd->scsi_done = _sync_done;
|
||||
|
||||
_sdev->host->hostt->queuecommand(_sdev->host, cmnd);
|
||||
wait_for_completion(&comp);
|
||||
|
||||
Genode::uint32_t *data = (Genode::uint32_t *)scsi_buffer_data(cmnd);
|
||||
_block_count = host_to_big_endian(data[0]);
|
||||
_block_size = host_to_big_endian(data[1]);
|
||||
|
||||
/* if device returns the highest block number */
|
||||
if (!_sdev->fix_capacity)
|
||||
_block_count++;
|
||||
|
||||
if (verbose)
|
||||
Genode::log("block size: ", _block_size, " block count", _block_count);
|
||||
|
||||
scsi_free_buffer(cmnd);
|
||||
_scsi_free_command(cmnd);
|
||||
}
|
||||
|
||||
void _io(Block::sector_t block_nr, Genode::size_t block_count,
|
||||
Block::Packet_descriptor packet,
|
||||
Genode::addr_t phys, bool read)
|
||||
{
|
||||
if (block_nr > _block_count)
|
||||
throw Io_error();
|
||||
|
||||
if (verbose)
|
||||
log("PACKET: phys: ", Genode::Hex(phys), " block: ", block_nr, "count: ", block_count,
|
||||
read ? " read" : " write");
|
||||
|
||||
/* check if we can call queuecommand */
|
||||
struct us_data *us = (struct us_data *) _sdev->host->hostdata;
|
||||
if (us->srb != NULL)
|
||||
throw Request_congestion();
|
||||
|
||||
struct scsi_cmnd *cmnd = _scsi_alloc_command();
|
||||
|
||||
cmnd->cmnd[0] = read ? READ_10 : WRITE_10;
|
||||
cmnd->cmd_len = 10;
|
||||
cmnd->device = _sdev;
|
||||
cmnd->sc_data_direction = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
|
||||
cmnd->scsi_done = _async_done;
|
||||
|
||||
Block::Packet_descriptor *p = new (Lx::Malloc::mem()) Block::Packet_descriptor();
|
||||
*p = packet;
|
||||
cmnd->packet = (void *)p;
|
||||
|
||||
Genode::uint32_t be_block_nr = host_to_big_endian<Genode::uint32_t>(block_nr);
|
||||
memcpy(&cmnd->cmnd[2], &be_block_nr, 4);
|
||||
|
||||
/* transfer one block */
|
||||
Genode::uint16_t be_block_count = host_to_big_endian<Genode::uint16_t>(block_count);
|
||||
memcpy(&cmnd->cmnd[7], &be_block_count, 2);
|
||||
|
||||
/* setup command */
|
||||
scsi_setup_buffer(cmnd, block_count * _block_size, (void *)0, phys);
|
||||
|
||||
/*
|
||||
* Required by 'last_sector_hacks' in 'drivers/usb/storage/transprot.c
|
||||
*/
|
||||
struct request req;
|
||||
req.rq_disk = 0;
|
||||
cmnd->request = &req;
|
||||
|
||||
/* send command to host driver */
|
||||
_sdev->host->hostt->queuecommand(_sdev->host, cmnd);
|
||||
|
||||
/* schedule next task if we come from EP */
|
||||
if (Lx::scheduler().active() == false)
|
||||
Lx::scheduler().schedule();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Storage_device(Genode::Ram_allocator &ram, struct scsi_device *sdev)
|
||||
: Block::Driver(ram), _sdev(sdev)
|
||||
{
|
||||
/* read device capacity */
|
||||
_capacity();
|
||||
}
|
||||
|
||||
Block::Session::Info info() const override
|
||||
{
|
||||
return { .block_size = _block_size,
|
||||
.block_count = _block_count,
|
||||
.align_log2 = Genode::log2(_block_size),
|
||||
.writeable = true };
|
||||
}
|
||||
|
||||
void read_dma(Block::sector_t block_number,
|
||||
Genode::size_t block_count,
|
||||
Genode::addr_t phys,
|
||||
Block::Packet_descriptor &packet) {
|
||||
_io(block_number, block_count, packet, phys, true); }
|
||||
|
||||
void write_dma(Block::sector_t block_number,
|
||||
Genode::size_t block_count,
|
||||
Genode::addr_t phys,
|
||||
Block::Packet_descriptor &packet) {
|
||||
_io(block_number, block_count, packet, phys, false); }
|
||||
|
||||
bool dma_enabled() { return true; }
|
||||
|
||||
Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t size) {
|
||||
return Lx::backend_alloc(size, Genode::UNCACHED); }
|
||||
|
||||
void free_dma_buffer(Genode::Ram_dataspace_capability cap) {
|
||||
return Lx::backend_free(cap); }
|
||||
};
|
||||
|
||||
|
||||
void Storage::init(Genode::Env &env) {
|
||||
_signal = new (Lx::Malloc::mem()) Signal_helper(env); }
|
||||
|
||||
|
||||
struct Factory : Block::Driver_factory
|
||||
{
|
||||
Storage_device device;
|
||||
|
||||
Factory(Genode::Ram_allocator &ram, struct scsi_device *sdev)
|
||||
: device(ram, sdev) {}
|
||||
|
||||
Block::Driver *create() { return &device; }
|
||||
void destroy(Block::Driver *driver) { }
|
||||
};
|
||||
|
||||
|
||||
static Storage_device *device = nullptr;
|
||||
static work_struct delayed;
|
||||
|
||||
|
||||
extern "C" void ack_packet(work_struct *work)
|
||||
{
|
||||
Block::Packet_descriptor *packet =
|
||||
(Block::Packet_descriptor *)(work->data);
|
||||
|
||||
if (verbose)
|
||||
Genode::log("ACK packet for block: ", packet->block_number());
|
||||
|
||||
device->ack_packet(*packet);
|
||||
Genode::destroy(Lx::Malloc::mem(), packet);
|
||||
}
|
||||
|
||||
|
||||
void scsi_add_device(struct scsi_device *sdev)
|
||||
{
|
||||
using namespace Genode;
|
||||
static bool announce = false;
|
||||
|
||||
static struct Factory factory(_signal->ram(), sdev);
|
||||
device = &factory.device;
|
||||
|
||||
/*
|
||||
* XXX move to 'main'
|
||||
*/
|
||||
if (!announce) {
|
||||
enum { WRITEABLE = true };
|
||||
|
||||
PREPARE_WORK(&delayed, ack_packet);
|
||||
static Block::Root root(_signal->ep(), Lx::Malloc::mem(),
|
||||
_signal->rm(), factory, WRITEABLE);
|
||||
_signal->parent().announce(_signal->ep().rpc_ep().manage(&root));
|
||||
announce = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Storage_device::_async_done(struct scsi_cmnd *cmnd)
|
||||
{
|
||||
/*
|
||||
* Schedule packet ack, because we are called here in USB storage thread
|
||||
* context, the from code that will clear the command queue later, so we
|
||||
* cannot send the next packet from here
|
||||
*/
|
||||
delayed.data = cmnd->packet;
|
||||
schedule_work(&delayed);
|
||||
|
||||
scsi_free_buffer(cmnd);
|
||||
_scsi_free_command(cmnd);
|
||||
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
SRC_CC += main.cc
|
||||
LIBS = base nic_driver
|
||||
|
||||
CC_CXX_WARN_STRICT =
|
||||
|
||||
LIB_DIR = $(REP_DIR)/src/drivers/usb
|
||||
LIB_INC_DIR = $(LIB_DIR)/include
|
||||
|
||||
LIBS += usb_include lx_kit_setjmp
|
||||
SRC_CC += lx_emul.cc storage.cc \
|
||||
input_component.cc evdev.cc nic.cc raw.cc
|
||||
SRC_C += dummies.c scsi.c raw_driver.c
|
||||
|
||||
LX_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/lib/usb
|
||||
DRIVERS_DIR := $(LX_CONTRIB_DIR)/drivers
|
||||
USB_DIR := $(DRIVERS_DIR)/usb
|
||||
|
||||
#
|
||||
# The order of include-search directories is important, we need to look into
|
||||
# 'contrib' before falling back to our custom 'lx_emul.h' header.
|
||||
#
|
||||
INC_DIR += $(PRG_DIR)
|
||||
INC_DIR += $(LIB_INC_DIR) $(REP_DIR)/src/include
|
||||
INC_DIR += $(LX_CONTRIB_DIR)/include $(LX_CONTRIB_DIR)/include/uapi $(LX_CONTRIB_DIR)
|
||||
|
||||
CC_OPT += -U__linux__ -D__KERNEL__
|
||||
CC_OPT += -DCONFIG_USB_DEVICEFS -DCONFIG_HOTPLUG -DDEBUG -DCONFIG_USB_PHY=1 \
|
||||
-DCONFIG_GENERIC_PHY=0 -DCONFIG_USB_OTG_WHITELIST=0 \
|
||||
-DCONFIG_USB_OTG=0 -DCONFIG_USB_NET_RNDIS_HOST=1
|
||||
|
||||
CC_WARN = -Wall -Wno-unused-variable -Wno-uninitialized \
|
||||
-Wno-unused-function -Wno-overflow
|
||||
|
||||
CC_C_OPT += -std=gnu89 -Wno-unused-but-set-variable -Wno-pointer-sign -Wno-unused-label
|
||||
CC_C_OPT += -include $(LIB_INC_DIR)/lx_emul.h
|
||||
|
||||
CC_CXX_OPT += -fpermissive
|
||||
|
||||
#
|
||||
# Suffix of global 'module_init' function
|
||||
#
|
||||
MOD_SUFFIX =
|
||||
CC_OPT += -DMOD_SUFFIX=$(MOD_SUFFIX)
|
||||
|
||||
# lx_kit
|
||||
SRC_CC += printf.cc bug.cc work.cc timer.cc scheduler.cc irq.cc malloc.cc env.cc
|
||||
|
||||
# common lib
|
||||
SRC_C += lib/ctype.c
|
||||
SRC_C += lib/int_sqrt.c
|
||||
|
||||
# USB core
|
||||
SRC_C += $(addprefix usb/core/, buffer.c config.c devices.c driver.c endpoint.c file.c \
|
||||
generic.c hcd.c hub.c message.c notify.c port.c quirks.c\
|
||||
urb.c usb.c)
|
||||
|
||||
# USB host-controller driver
|
||||
SRC_C += $(addprefix usb/host/, ehci-hcd.c)
|
||||
|
||||
# common
|
||||
SRC_C += usb/common/common.c
|
||||
|
||||
# USB hid
|
||||
SRC_C += $(addprefix hid/usbhid/, hid-core.c hid-quirks.c)
|
||||
SRC_C += $(addprefix hid/, hid-core.c hid-generic.c hid-input.c \
|
||||
hid-cherry.c hid-microsoft.c hid-multitouch.c \
|
||||
wacom_sys.c wacom_wac.c)
|
||||
SRC_C += $(addprefix input/, evdev.c input.c input-mt.c)
|
||||
|
||||
# USB storage
|
||||
SRC_C += $(addprefix usb/storage/,scsiglue.c protocol.c transport.c usb.c \
|
||||
initializers.c option_ms.c sierra_ms.c usual-tables.c)
|
||||
|
||||
# SCSI
|
||||
SRC_C += $(addprefix scsi/,scsi.c constants.c)
|
||||
|
||||
#SRC_CC = storage.cc
|
||||
#SRC_C =
|
||||
|
||||
#
|
||||
# Add suffix, since there are two hid-core.c with the same module init function
|
||||
#
|
||||
hid/hid-core.o: MOD_SUFFIX="_core"
|
||||
|
||||
vpath %.c $(DRIVERS_DIR)
|
||||
vpath %.c $(LIB_DIR)
|
||||
vpath %.cc $(LIB_DIR)
|
||||
vpath %.cc $(LIB_DIR)/signal
|
||||
vpath %.c $(LIB_DIR)/input
|
||||
vpath %.cc $(LIB_DIR)/input
|
||||
vpath %.cc $(LIB_DIR)/storage
|
||||
vpath %.c $(LIB_DIR)/storage
|
||||
vpath %.cc $(LIB_DIR)/nic
|
||||
vpath %.cc $(LIB_DIR)/raw
|
||||
vpath %.c $(LIB_DIR)/raw
|
||||
vpath lib/int_sqrt.c $(LX_CONTRIB_DIR)
|
||||
vpath lib/ctype.c $(LX_CONTRIB_DIR)
|
||||
vpath %.cc $(REP_DIR)/src/lx_kit
|
||||
|
||||
# vi: set ft=make :
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* \brief Test functions
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-08-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
|
||||
void tx_test() {
|
||||
char *data = (char *)skb->data;
|
||||
if (data[0x2a] == (char)0xaa && data[0x2b] == (char)0xbb) {
|
||||
Genode::log("Got server signal");
|
||||
static char data[1066];
|
||||
static char header[] = {
|
||||
0x00, 0x1c, 0x25, 0x9e, 0x92, 0x4a, 0x2e, 0x60, 0x90, 0x0c, 0x4e, 0x01, 0x08, 0x00, 0x45, 0x00,
|
||||
0x04, 0x1c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, 0x22, 0x88, 0x0a, 0x00, 0x00, 0x3b, 0x0a, 0x00,
|
||||
0x00, 0x0f, 0x89, 0xc5, 0x04, 0xd2, 0x04, 0x08, 0x54, 0xfd};
|
||||
Genode::memset(data, 0, 1065);
|
||||
memcpy(data, header, sizeof(header));
|
||||
while (1) {
|
||||
sk_buff *skb = alloc_skb(1066 + HEAD_ROOM, 0);
|
||||
if (!skb) {
|
||||
Service_handler::s()->check_signal();
|
||||
continue;
|
||||
}
|
||||
skb->len = 1066;
|
||||
skb->data += HEAD_ROOM;
|
||||
|
||||
memcpy(skb->data, data, 1066);
|
||||
|
||||
_nic->_ndev->netdev_ops->ndo_start_xmit(skb, _nic->_ndev);
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,6 +0,0 @@
|
||||
#
|
||||
# Generic XHCI files
|
||||
#
|
||||
SRC_C += $(addprefix usb/host/, xhci-dbg.c xhci-hub.c xhci-mem.c xhci-ring.c xhci.c)
|
||||
|
||||
# vi:set ft=make :
|
@ -1,14 +1,15 @@
|
||||
USB host controller driver
|
||||
##########################
|
||||
|
||||
Allows access to USB devices via the 'Usb' session interface.
|
||||
|
||||
Configuration snippet:
|
||||
The driver will start all USB controller types a platform offers
|
||||
(USB 1.0/2.0/3.0). Controllers can be disabled as attribute in the config node
|
||||
of the driver. Supported attributes are: 'uhci', 'ohci', 'ehci', and 'xhci'.
|
||||
|
||||
!<start name="usb_host_drv">
|
||||
! <binary name="platform_specific_usb_host_drv_name"/>
|
||||
! <resource name="RAM" quantum="10M"/>
|
||||
! <provides><service name="Usb"/></provides>
|
||||
! <config>
|
||||
! <config uhci="yes" ohci="yes" ehci="yes" xhci="yes">
|
||||
! <report devices="yes"/>
|
||||
! </config>
|
||||
!</start>
|
||||
@ -28,14 +29,12 @@ USB device. Only devices that have a valid policy configured at the USB driver
|
||||
can be accessed by a client. The following configuration allows 'comp1' to
|
||||
access the device 'usb-1-6':
|
||||
|
||||
!<start name="usb_drv">
|
||||
!<start name="usb_host_drv">
|
||||
! <resource name="RAM" quantum="12M"/>
|
||||
! <provides><service name="Usb"/></provides>
|
||||
! <config uhci="yes" ohci="yes" ehci="yes" xhci="yes">
|
||||
! <raw>
|
||||
! <report devices="yes"/>
|
||||
! <policy label="comp1 -> usb-1-6" vendor_id="0x13fe" product_id="0x5200" bus="0x0001" dev="0x0006"/>
|
||||
! </raw>
|
||||
! <config>
|
||||
! <report devices="yes"/>
|
||||
! <policy label="comp1 -> usb-1-6" vendor_id="0x13fe" product_id="0x5200" bus="0x0001" dev="0x0006"/>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
|
@ -68,7 +68,6 @@ timeout
|
||||
timeout_smp
|
||||
timer_accuracy
|
||||
tz_vmm
|
||||
usb_hid
|
||||
usb_hid_raw
|
||||
vbox5_genode_usb_hid_raw
|
||||
vbox5_ubuntu_16_04_32
|
||||
|
Loading…
x
Reference in New Issue
Block a user