mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-30 16:14:13 +00:00
parent
bcefc874d6
commit
369ff2a001
@ -16,6 +16,20 @@ 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"/>
|
||||
|
||||
HID
|
||||
~~~
|
||||
|
||||
|
36
repos/dde_linux/lib/import/import-usb_include.mk
Normal file
36
repos/dde_linux/lib/import/import-usb_include.mk
Normal file
@ -0,0 +1,36 @@
|
||||
USB_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/lib/usb
|
||||
|
||||
LIB_DIR := $(REP_DIR)/src/lib/usb
|
||||
LIB_INC_DIR := $(LIB_DIR)/include
|
||||
|
||||
# architecture-dependent includes
|
||||
ifeq ($(filter-out $(SPECS),x86),)
|
||||
ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/spec/x86
|
||||
ifeq ($(filter-out $(SPECS),32bit),)
|
||||
ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/spec/x86_32
|
||||
endif # 32bit
|
||||
ifeq ($(filter-out $(SPECS),64bit),)
|
||||
ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/spec/x86_64
|
||||
endif # 64bit
|
||||
endif # x86
|
||||
|
||||
ifeq ($(filter-out $(SPECS),arm),)
|
||||
ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/spec/arm
|
||||
ifeq ($(filter-out $(SPECS),arm_v6),)
|
||||
ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/spec/arm_v6
|
||||
endif # arm_v6
|
||||
ifeq ($(filter-out $(SPECS),arm_v7),)
|
||||
ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/spec/arm_v7
|
||||
endif # arm_v7
|
||||
endif # arm
|
||||
|
||||
|
||||
#
|
||||
# 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,6 +1,11 @@
|
||||
include $(REP_DIR)/lib/mk/usb.inc
|
||||
|
||||
SRC_CC += platform_device.c
|
||||
INC_DIR += $(LIB_INC_DIR)/spec/arm
|
||||
SRC_CC += platform_device.cc platform_generic.cc
|
||||
|
||||
vpath platform_device.cc $(LIB_DIR)/spec/arm
|
||||
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 :
|
||||
|
@ -11,7 +11,7 @@ INC_DIR += $(LX_CONTRIB_DIR)/arch/arm/plat-samsung/include
|
||||
SRC_CC += platform.cc
|
||||
|
||||
#DWC3
|
||||
SRC_C += $(addprefix usb/dwc3/, host.c core.c)
|
||||
SRC_C += $(addprefix usb/dwc3/, dwc3-exynos.c host.c core.c)
|
||||
|
||||
#XHCI
|
||||
SRC_C += usb/host/xhci-plat.c
|
||||
|
@ -1,20 +1,27 @@
|
||||
SRC_C += $(addprefix usb/host/,pci-quirks.c uhci-hcd.c ehci-pci.c)
|
||||
SRC_C += usb/core/hcd-pci.c
|
||||
|
||||
#
|
||||
# USB netwpork support
|
||||
#
|
||||
SRC_C += $(addprefix net/usb/, usbnet.c ax88179_178a.c)
|
||||
|
||||
#XHCI
|
||||
# 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)/lib/mk/xhci.inc
|
||||
include $(REP_DIR)/lib/mk/usb.inc
|
||||
|
||||
CC_OPT += -DCONFIG_PCI -DCONFIG_USB_EHCI_PCI=1 -DCONFIG_USB_XHCI_HCD=1
|
||||
|
||||
vpath platform.cc $(LIB_DIR)/spec/x86
|
||||
vpath platform.cc $(LIB_DIR)/spec/x86
|
||||
vpath pci_driver.cc $(LIB_DIR)/spec/x86
|
||||
|
||||
# vi:set ft=make :
|
||||
|
@ -1,4 +1,5 @@
|
||||
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)/lib/mk/spec/x86/usb.inc
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
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)/lib/mk/spec/x86/usb.inc
|
||||
|
@ -1,8 +1,8 @@
|
||||
LIB_DIR = $(REP_DIR)/src/lib/usb
|
||||
LIB_INC_DIR = $(LIB_DIR)/include
|
||||
|
||||
LIBS += libc-setjmp config
|
||||
SRC_CC += main.cc lx_emul.cc irq.cc timer.cc event.cc storage.cc \
|
||||
LIBS += usb_include libc-setjmp config
|
||||
SRC_CC += main.cc lx_emul.cc storage.cc \
|
||||
input_component.cc nic.cc raw.cc
|
||||
SRC_C += dummies.c scsi.c evdev.c raw_driver.c
|
||||
|
||||
@ -16,11 +16,13 @@ CC_OLEVEL = -O2
|
||||
# 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 += $(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
|
||||
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
|
||||
|
||||
CC_WARN = -Wall -Wno-unused-variable -Wno-uninitialized \
|
||||
-Wno-unused-function -Wno-overflow
|
||||
@ -35,22 +37,29 @@ CC_CXX_OPT = -fpermissive
|
||||
MOD_SUFFIX =
|
||||
CC_OPT += -DMOD_SUFFIX=$(MOD_SUFFIX)
|
||||
|
||||
# lx_kit
|
||||
SRC_CC += printf.cc work.cc timer.cc scheduler.cc irq.cc malloc.cc
|
||||
|
||||
# common lib
|
||||
SRC_C += lib/int_sqrt.c
|
||||
|
||||
# USB core
|
||||
SRC_C += $(addprefix usb/core/,$(notdir $(wildcard $(USB_DIR)/core/*.c)))
|
||||
SRC_C += usb/usb-common.c
|
||||
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)
|
||||
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)
|
||||
SRC_C += $(addprefix input/, tablet/wacom_sys.c tablet/wacom_wac.c)
|
||||
|
||||
# USB storage
|
||||
SRC_C += $(addprefix usb/storage/,scsiglue.c protocol.c transport.c usb.c \
|
||||
@ -59,46 +68,14 @@ SRC_C += $(addprefix usb/storage/,scsiglue.c protocol.c transport.c usb.c \
|
||||
# SCSI
|
||||
SRC_C += $(addprefix scsi/,scsi.c constants.c)
|
||||
|
||||
|
||||
#
|
||||
# Determine the header files included by the contrib code. For each
|
||||
# of these header files we create a symlink to 'lx_emul.h'.
|
||||
#
|
||||
GEN_INCLUDES := $(shell grep -rh "^\#include .*\/" $(LX_CONTRIB_DIR) |\
|
||||
sed "s/^\#include [^<\"]*[<\"]\([^>\"]*\)[>\"].*/\1/" | sort | uniq)
|
||||
|
||||
#
|
||||
# Filter out original Linux headers that exist in the contrib directory
|
||||
#
|
||||
NO_GEN_INCLUDES := $(shell cd $(LX_CONTRIB_DIR)/include; find -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
|
||||
|
||||
$(shell mkdir -p $(GEN_INC))
|
||||
|
||||
GEN_INCLUDES := $(addprefix $(GEN_INC)/,$(GEN_INCLUDES))
|
||||
INC_DIR += $(GEN_INC)
|
||||
|
||||
#
|
||||
# Make sure to create the header symlinks prior building
|
||||
#
|
||||
$(SRC_C:.c=.o) $(SRC_CC:.cc=.o): $(GEN_INCLUDES)
|
||||
|
||||
#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"
|
||||
|
||||
$(GEN_INCLUDES):
|
||||
$(VERBOSE)mkdir -p $(dir $@)
|
||||
$(VERBOSE)ln -s $(LIB_INC_DIR)/lx_emul.h $@
|
||||
|
||||
vpath %.c $(DRIVERS_DIR)
|
||||
vpath %.c $(LIB_DIR)
|
||||
vpath %.cc $(LIB_DIR)
|
||||
@ -111,5 +88,6 @@ vpath %.cc $(LIB_DIR)/nic
|
||||
vpath %.cc $(LIB_DIR)/raw
|
||||
vpath %.c $(LIB_DIR)/raw
|
||||
vpath lib/int_sqrt.c $(LX_CONTRIB_DIR)
|
||||
vpath %.cc $(REP_DIR)/src/lx_kit
|
||||
|
||||
# vi: set ft=make :
|
||||
|
35
repos/dde_linux/lib/mk/usb_include.mk
Normal file
35
repos/dde_linux/lib/mk/usb_include.mk
Normal file
@ -0,0 +1,35 @@
|
||||
ifeq ($(called_from_lib_mk),yes)
|
||||
|
||||
USB_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/lib/usb
|
||||
LX_EMUL_H := $(REP_DIR)/src/lib/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'.
|
||||
#
|
||||
GEN_INCLUDES := $(shell grep -rh "^\#include .*\/" $(USB_CONTRIB_DIR) |\
|
||||
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 :
|
@ -1,12 +1,8 @@
|
||||
commit 5151dad7cc61bf2b4527c56bd0dffcea2da25905
|
||||
Author: Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
Date: Mon Jun 2 13:23:44 2014 +0200
|
||||
|
||||
ax88179_178a.patch
|
||||
|
||||
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
|
||||
@@ -1019,6 +1019,7 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
|
||||
@@ -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;
|
||||
|
@ -1,12 +1,8 @@
|
||||
commit e3804842c60157bab0d5bf2daa42f99ec3f8499d
|
||||
Author: Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
Date: Mon Jun 2 13:24:37 2014 +0200
|
||||
|
||||
csum.patch
|
||||
|
||||
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
|
||||
@@ -1716,7 +1716,13 @@ static int smsc95xx_resume(struct usb_interface *intf)
|
||||
@@ -1730,7 +1730,13 @@ static int smsc95xx_reset_resume(struct usb_interface *intf)
|
||||
|
||||
static void smsc95xx_rx_csum_offload(struct sk_buff *skb)
|
||||
{
|
||||
|
@ -1,12 +1,8 @@
|
||||
commit a30968815ec1e4967a6c531744b2788f2c25e675
|
||||
Author: Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
Date: Mon Jun 2 13:25:03 2014 +0200
|
||||
|
||||
evdev.patch
|
||||
|
||||
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
|
||||
@@ -1168,6 +1168,9 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
|
||||
@@ -1425,6 +1425,9 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
|
||||
if (error)
|
||||
goto err_cleanup_evdev;
|
||||
|
||||
@ -16,7 +12,7 @@ Date: Mon Jun 2 13:25:03 2014 +0200
|
||||
return 0;
|
||||
|
||||
err_cleanup_evdev:
|
||||
@@ -1200,8 +1203,7 @@ static const struct input_device_id evdev_ids[] = {
|
||||
@@ -1457,8 +1460,7 @@ static const struct input_device_id evdev_ids[] = {
|
||||
MODULE_DEVICE_TABLE(input, evdev_ids);
|
||||
|
||||
static struct input_handler evdev_handler = {
|
||||
|
@ -1,180 +1,137 @@
|
||||
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 44df131..0d0aa68 100644
|
||||
index 5dd426f..6b4294a 100644
|
||||
--- a/drivers/hid/usbhid/hid-core.c
|
||||
+++ b/drivers/hid/usbhid/hid-core.c
|
||||
@@ -840,7 +840,7 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
|
||||
@@ -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_NOIO);
|
||||
+ 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 ||
|
||||
@@ -998,7 +998,7 @@ static int usbhid_parse(struct hid_device *hid)
|
||||
@@ -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_NOIO))) {
|
||||
+ 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 f9e96c4..31d8b12 100644
|
||||
index 0744bf2..6237370 100644
|
||||
--- a/drivers/net/usb/usbnet.c
|
||||
+++ b/drivers/net/usb/usbnet.c
|
||||
@@ -228,7 +228,7 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf)
|
||||
@@ -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_NOIO);
|
||||
+ buf = kmalloc (maxp, GFP_LX_DMA);
|
||||
if (buf) {
|
||||
dev->interrupt = usb_alloc_urb (0, GFP_KERNEL);
|
||||
if (!dev->interrupt) {
|
||||
@@ -1772,7 +1772,7 @@ int usbnet_resume (struct usb_interface *intf)
|
||||
|
||||
if (!--dev->suspend_count) {
|
||||
/* resume interrupt URB if it was previously submitted */
|
||||
- __usbnet_status_start_force(dev, GFP_NOIO);
|
||||
+ __usbnet_status_start_force(dev, GFP_KERNEL);
|
||||
|
||||
spin_lock_irq(&dev->txq.lock);
|
||||
while ((res = usb_get_from_anchor(&dev->deferred))) {
|
||||
@@ -1801,7 +1801,7 @@ int usbnet_resume (struct usb_interface *intf)
|
||||
if (netif_device_present(dev->net) &&
|
||||
!timer_pending(&dev->delay) &&
|
||||
!test_bit(EVENT_RX_HALT, &dev->flags))
|
||||
- rx_alloc_submit(dev, GFP_NOIO);
|
||||
+ rx_alloc_submit(dev, GFP_KERNEL);
|
||||
|
||||
if (!(dev->txq.qlen >= TX_QLEN(dev)))
|
||||
netif_tx_wake_all_queues(dev->net);
|
||||
@@ -1867,7 +1867,7 @@ static int __usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
|
||||
@@ -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_NOIO);
|
||||
+ buf = kmalloc(size, GFP_LX_DMA);
|
||||
if (!buf)
|
||||
goto out;
|
||||
}
|
||||
@@ -1894,7 +1894,7 @@ static int __usbnet_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
|
||||
@@ -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_NOIO);
|
||||
+ buf = kmemdup(data, size, GFP_LX_DMA);
|
||||
if (!buf)
|
||||
goto out;
|
||||
}
|
||||
@@ -2006,7 +2006,7 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
|
||||
@@ -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_NOIO);
|
||||
+ buf = kmemdup(data, size, GFP_LX_DMA);
|
||||
if (!buf) {
|
||||
netdev_err(dev->net, "Error allocating buffer"
|
||||
" in %s!\n", __func__);
|
||||
@@ -2014,7 +2014,7 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
|
||||
@@ -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_NOIO);
|
||||
+ 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 062967c..f5da439 100644
|
||||
index 5050760..9ac55f9 100644
|
||||
--- a/drivers/usb/core/config.c
|
||||
+++ b/drivers/usb/core/config.c
|
||||
@@ -683,7 +683,7 @@ int usb_get_configuration(struct usb_device *dev)
|
||||
@@ -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_NOIO);
|
||||
+ desc = kmalloc(USB_DT_CONFIG_SIZE, GFP_LX_DMA);
|
||||
if (!desc)
|
||||
goto err2;
|
||||
|
||||
@@ -712,7 +712,7 @@ int usb_get_configuration(struct usb_device *dev)
|
||||
@@ -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_NOIO);
|
||||
+ bigbuffer = kmalloc(length, GFP_LX_DMA);
|
||||
if (!bigbuffer) {
|
||||
result = -ENOMEM;
|
||||
goto err;
|
||||
@@ -774,7 +774,7 @@ int usb_get_bos_descriptor(struct usb_device *dev)
|
||||
@@ -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_NOIO);
|
||||
+ bos = kzalloc(sizeof(struct usb_bos_descriptor), GFP_LX_DMA);
|
||||
if (!bos)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -800,7 +800,7 @@ int usb_get_bos_descriptor(struct usb_device *dev)
|
||||
@@ -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_NOIO);
|
||||
+ buffer = kzalloc(total_len, GFP_LX_DMA);
|
||||
if (!buffer) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
|
||||
index 2a3bbdf..c78eedd 100644
|
||||
--- a/drivers/usb/core/devices.c
|
||||
+++ b/drivers/usb/core/devices.c
|
||||
@@ -513,7 +513,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
|
||||
return 0;
|
||||
/* allocate 2^1 pages = 8K (on i386);
|
||||
* should be more than enough for one device */
|
||||
- pages_start = (char *)__get_free_pages(GFP_NOIO, 1);
|
||||
+ pages_start = (char *)__get_free_pages(GFP_KERNEL, 1);
|
||||
if (!pages_start)
|
||||
return -ENOMEM;
|
||||
|
||||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
|
||||
index d498d03..87b0b6b 100644
|
||||
index 1560f3f..54e99b5 100644
|
||||
--- a/drivers/usb/core/hub.c
|
||||
+++ b/drivers/usb/core/hub.c
|
||||
@@ -1056,7 +1056,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
|
||||
hcd = bus_to_hcd(hdev->bus);
|
||||
if (hcd->driver->update_hub_device) {
|
||||
ret = hcd->driver->update_hub_device(hcd, hdev,
|
||||
- &hub->tt, GFP_NOIO);
|
||||
+ &hub->tt, GFP_KERNEL);
|
||||
if (ret < 0) {
|
||||
dev_err(hub->intfdev, "Host not "
|
||||
"accepting hub info "
|
||||
@@ -1205,7 +1205,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
|
||||
init3:
|
||||
hub->quiescing = 0;
|
||||
|
||||
- status = usb_submit_urb(hub->urb, GFP_NOIO);
|
||||
+ status = usb_submit_urb(hub->urb, GFP_KERNEL);
|
||||
if (status < 0)
|
||||
dev_err(hub->intfdev, "activate --> %d\n", status);
|
||||
if (hub->has_indicators && blinkenlights)
|
||||
@@ -1296,20 +1296,20 @@ static int hub_configure(struct usb_hub *hub,
|
||||
unsigned unit_load;
|
||||
@@ -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_NOIO);
|
||||
+ 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_NOIO);
|
||||
+ hub->status = kmalloc(sizeof(*hub->status), GFP_LX_DMA);
|
||||
if (!hub->status) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
@ -182,105 +139,34 @@ index d498d03..87b0b6b 100644
|
||||
mutex_init(&hub->status_mutex);
|
||||
|
||||
- hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
|
||||
+ hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_NOIO);
|
||||
+ hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_LX_DMA);
|
||||
if (!hub->descriptor) {
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
@@ -3464,9 +3464,9 @@ static int usb_req_set_sel(struct usb_device *udev, enum usb3_link_state state)
|
||||
/*
|
||||
* usb_enable_lpm() can be called as part of a failed device reset,
|
||||
* which may be initiated by an error path of a mass storage driver.
|
||||
- * Therefore, use GFP_NOIO.
|
||||
+ * Therefore, use GFP_KERNEL.
|
||||
*/
|
||||
- sel_values = kmalloc(sizeof *(sel_values), GFP_NOIO);
|
||||
+ sel_values = kmalloc(sizeof *(sel_values), GFP_KERNEL);
|
||||
if (!sel_values)
|
||||
return -ENOMEM;
|
||||
@@ -4586,7 +4586,7 @@ check_highspeed(struct usb_hub *hub, struct usb_device *udev, int port1)
|
||||
if (udev->quirks & USB_QUIRK_DEVICE_QUALIFIER)
|
||||
return;
|
||||
|
||||
@@ -4299,7 +4299,7 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1)
|
||||
struct usb_qualifier_descriptor *qual;
|
||||
int status;
|
||||
|
||||
- qual = kmalloc (sizeof *qual, GFP_KERNEL);
|
||||
+ qual = kmalloc (sizeof *qual, GFP_NOIO);
|
||||
- qual = kmalloc(sizeof *qual, GFP_KERNEL);
|
||||
+ qual = kmalloc(sizeof *qual, GFP_LX_DMA);
|
||||
if (qual == NULL)
|
||||
return;
|
||||
|
||||
@@ -5030,7 +5030,7 @@ static int descriptors_changed(struct usb_device *udev,
|
||||
len = max(len, old_length);
|
||||
}
|
||||
|
||||
- buf = kmalloc(len, GFP_NOIO);
|
||||
+ buf = kmalloc(len, GFP_KERNEL);
|
||||
if (buf == NULL) {
|
||||
dev_err(&udev->dev, "no mem to re-read configs after reset\n");
|
||||
/* assume the worst */
|
||||
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
|
||||
index f829a1a..91aa41a 100644
|
||||
index 8e641b5..5807f68 100644
|
||||
--- a/drivers/usb/core/message.c
|
||||
+++ b/drivers/usb/core/message.c
|
||||
@@ -49,7 +49,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length)
|
||||
init_completion(&ctx.done);
|
||||
urb->context = &ctx;
|
||||
urb->actual_length = 0;
|
||||
- retval = usb_submit_urb(urb, GFP_NOIO);
|
||||
+ retval = usb_submit_urb(urb, GFP_KERNEL);
|
||||
if (unlikely(retval))
|
||||
goto out;
|
||||
|
||||
@@ -86,7 +86,7 @@ static int usb_internal_control_msg(struct usb_device *usb_dev,
|
||||
int retv;
|
||||
int length;
|
||||
|
||||
- urb = usb_alloc_urb(0, GFP_NOIO);
|
||||
+ urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!urb)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -869,11 +869,11 @@ char *usb_cache_string(struct usb_device *udev, int index)
|
||||
if (index <= 0)
|
||||
return NULL;
|
||||
|
||||
- buf = kmalloc(MAX_USB_STRING_SIZE, GFP_NOIO);
|
||||
+ buf = kmalloc(MAX_USB_STRING_SIZE, GFP_KERNEL);
|
||||
if (buf) {
|
||||
len = usb_string(udev, index, buf, MAX_USB_STRING_SIZE);
|
||||
if (len > 0) {
|
||||
- smallbuf = kmalloc(++len, GFP_NOIO);
|
||||
+ smallbuf = kmalloc(++len, GFP_KERNEL);
|
||||
if (!smallbuf)
|
||||
return buf;
|
||||
memcpy(smallbuf, buf, len);
|
||||
@@ -944,7 +944,7 @@ int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)
|
||||
@@ -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_NOIO);
|
||||
+ __le16 *status = kmalloc(sizeof(*status), GFP_LX_DMA);
|
||||
|
||||
if (!status)
|
||||
return -ENOMEM;
|
||||
@@ -1743,7 +1743,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
|
||||
if (cp) {
|
||||
nintf = cp->desc.bNumInterfaces;
|
||||
new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
|
||||
- GFP_NOIO);
|
||||
+ GFP_KERNEL);
|
||||
if (!new_interfaces) {
|
||||
dev_err(&dev->dev, "Out of memory\n");
|
||||
return -ENOMEM;
|
||||
@@ -1752,7 +1752,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
|
||||
for (; n < nintf; ++n) {
|
||||
new_interfaces[n] = kzalloc(
|
||||
sizeof(struct usb_interface),
|
||||
- GFP_NOIO);
|
||||
+ GFP_KERNEL);
|
||||
if (!new_interfaces[n]) {
|
||||
dev_err(&dev->dev, "Out of memory\n");
|
||||
ret = -ENOMEM;
|
||||
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
|
||||
index c0fb6a8..107f41d 100644
|
||||
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)
|
||||
@ -288,104 +174,154 @@ index c0fb6a8..107f41d 100644
|
||||
dma_addr_t dma;
|
||||
|
||||
- qh = kzalloc(sizeof *qh, GFP_ATOMIC);
|
||||
+ qh = kzalloc(sizeof *qh, GFP_NOIO);
|
||||
+ qh = kzalloc(sizeof *qh, GFP_LX_DMA);
|
||||
if (!qh)
|
||||
goto done;
|
||||
qh->hw = (struct ehci_qh_hw *)
|
||||
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
|
||||
index 9992fbf..10f539c 100644
|
||||
--- a/drivers/usb/host/xhci-hub.c
|
||||
+++ b/drivers/usb/host/xhci-hub.c
|
||||
@@ -276,7 +276,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
|
||||
|
||||
ret = 0;
|
||||
virt_dev = xhci->devs[slot_id];
|
||||
- cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO);
|
||||
+ cmd = xhci_alloc_command(xhci, false, true, GFP_KERNEL);
|
||||
if (!cmd) {
|
||||
xhci_dbg(xhci, "Couldn't allocate command structure.\n");
|
||||
return -ENOMEM;
|
||||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
|
||||
index cca2896..9b5c07e 100644
|
||||
index 776d59c..e32db7b 100644
|
||||
--- a/drivers/usb/host/xhci.c
|
||||
+++ b/drivers/usb/host/xhci.c
|
||||
@@ -1279,7 +1279,7 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
|
||||
@@ -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_NOIO);
|
||||
+ size * sizeof(struct xhci_td *), GFP_LX_DMA);
|
||||
if (!urb_priv)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -1722,7 +1722,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
* process context, not interrupt context (or so documenation
|
||||
* for usb_set_interface() and usb_set_configuration() claim).
|
||||
*/
|
||||
- if (xhci_endpoint_init(xhci, virt_dev, udev, ep, GFP_NOIO) < 0) {
|
||||
+ if (xhci_endpoint_init(xhci, virt_dev, udev, ep, GFP_KERNEL) < 0) {
|
||||
dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n",
|
||||
__func__, ep->desc.bEndpointAddress);
|
||||
return -ENOMEM;
|
||||
@@ -3435,10 +3435,10 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
/* Allocate the command structure that holds the struct completion.
|
||||
* Assume we're in process context, since the normal device reset
|
||||
* process has to wait for the device anyway. Storage devices are
|
||||
- * reset as part of error handling, so use GFP_NOIO instead of
|
||||
+ * reset as part of error handling, so use GFP_KERNEL instead of
|
||||
* GFP_KERNEL.
|
||||
*/
|
||||
- reset_device_cmd = xhci_alloc_command(xhci, false, true, GFP_NOIO);
|
||||
+ reset_device_cmd = xhci_alloc_command(xhci, false, true, GFP_KERNEL);
|
||||
if (!reset_device_cmd) {
|
||||
xhci_dbg(xhci, "Couldn't allocate command structure.\n");
|
||||
return -ENOMEM;
|
||||
@@ -3682,11 +3682,11 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
}
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
}
|
||||
- /* Use GFP_NOIO, since this function can be called from
|
||||
+ /* Use GFP_KERNEL, since this function can be called from
|
||||
* xhci_discover_or_reset_device(), which may be called as part of
|
||||
* mass storage driver error handling.
|
||||
*/
|
||||
- if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_NOIO)) {
|
||||
+ if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) {
|
||||
xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
|
||||
goto disable_slot;
|
||||
}
|
||||
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
|
||||
index 22c7d43..783f745 100644
|
||||
--- a/drivers/usb/storage/transport.c
|
||||
+++ b/drivers/usb/storage/transport.c
|
||||
@@ -151,7 +151,7 @@ static int usb_stor_msg_common(struct us_data *us, int timeout)
|
||||
us->current_urb->transfer_dma = us->iobuf_dma;
|
||||
|
||||
/* submit the URB */
|
||||
- status = usb_submit_urb(us->current_urb, GFP_NOIO);
|
||||
+ status = usb_submit_urb(us->current_urb, GFP_KERNEL);
|
||||
if (status) {
|
||||
/* something went wrong */
|
||||
return status;
|
||||
@@ -427,7 +427,7 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
|
||||
/* initialize the scatter-gather request block */
|
||||
usb_stor_dbg(us, "xfer %u bytes, %d entries\n", length, num_sg);
|
||||
result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0,
|
||||
- sg, num_sg, length, GFP_NOIO);
|
||||
+ sg, num_sg, length, GFP_KERNEL);
|
||||
if (result) {
|
||||
usb_stor_dbg(us, "usb_sg_init returned %d\n", result);
|
||||
return USB_STOR_XFER_ERROR;
|
||||
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
|
||||
index 1c0b89f..e34e087 100644
|
||||
index 43576ed..2b13b4e 100644
|
||||
--- a/drivers/usb/storage/usb.c
|
||||
+++ b/drivers/usb/storage/usb.c
|
||||
@@ -442,7 +442,7 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf)
|
||||
@@ -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_NOIO);
|
||||
+ 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,12 +1,8 @@
|
||||
commit e500c61c5fce23cf3a44bdd45fded0a3f34cf4f0
|
||||
Author: Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
Date: Mon Jun 2 13:35:56 2014 +0200
|
||||
|
||||
usbnet.patch
|
||||
|
||||
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
|
||||
@@ -63,8 +63,30 @@
|
||||
@@ -64,8 +64,30 @@
|
||||
* the equation.
|
||||
*/
|
||||
#define MAX_QUEUE_MEMORY (60 * 1518)
|
||||
|
@ -1,181 +0,0 @@
|
||||
From aa61126013bd3f9bb41e5256e4246bc0c5bf348d Mon Sep 17 00:00:00 2001
|
||||
From: Jason Gerecke <killertofu@gmail.com>
|
||||
Date: Tue, 6 May 2014 17:14:59 -0700
|
||||
Subject: [PATCH] Add support for 056a:5002 (Fujitsu T904)
|
||||
|
||||
The 5002 appears to use a standard multitouch packet type, but the
|
||||
pen packet has a new report ID.
|
||||
|
||||
Signed-off-by: Jason Gerecke <killertofu@gmail.com>
|
||||
---
|
||||
drivers/input/tablet/wacom_sys.c | 19 +++++++++++++++++++
|
||||
drivers/input/tablet/wacom_wac.c | 12 +++++++++++-
|
||||
drivers/input/tablet/wacom_wac.h | 3 +++
|
||||
3 files changed, 33 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
|
||||
index b16ebef..0056a6d 100644
|
||||
--- a/drivers/input/tablet/wacom_sys.c
|
||||
+++ b/drivers/input/tablet/wacom_sys.c
|
||||
@@ -364,6 +364,7 @@ static int wacom_parse_hid(struct usb_interface *intf,
|
||||
break;
|
||||
|
||||
case MTTPC:
|
||||
+ case MTTPC_B:
|
||||
features->pktlen = WACOM_PKGLEN_MTTPC;
|
||||
break;
|
||||
|
||||
@@ -395,6 +396,16 @@ static int wacom_parse_hid(struct usb_interface *intf,
|
||||
i += 12;
|
||||
break;
|
||||
|
||||
+ case MTTPC_B:
|
||||
+ features->x_max =
|
||||
+ get_unaligned_le16(&report[i + 3]);
|
||||
+ features->x_phy =
|
||||
+ get_unaligned_le16(&report[i + 6]);
|
||||
+ features->unit = report[i - 5];
|
||||
+ features->unitExpo = report[i - 3];
|
||||
+ i += 9;
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
features->x_max =
|
||||
get_unaligned_le16(&report[i + 3]);
|
||||
@@ -447,6 +458,14 @@ static int wacom_parse_hid(struct usb_interface *intf,
|
||||
i += 12;
|
||||
break;
|
||||
|
||||
+ case MTTPC_B:
|
||||
+ features->y_max =
|
||||
+ get_unaligned_le16(&report[i + 3]);
|
||||
+ features->y_phy =
|
||||
+ get_unaligned_le16(&report[i + 6]);
|
||||
+ i += 9;
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
features->y_max =
|
||||
features->x_max;
|
||||
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
|
||||
index 05f371d..9330e17 100644
|
||||
--- a/drivers/input/tablet/wacom_wac.c
|
||||
+++ b/drivers/input/tablet/wacom_wac.c
|
||||
@@ -966,7 +966,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom)
|
||||
int x_offset = 0;
|
||||
|
||||
/* MTTPC does not support Height and Width */
|
||||
- if (wacom->features.type == MTTPC)
|
||||
+ if (wacom->features.type == MTTPC || wacom->features.type == MTTPC_B)
|
||||
x_offset = -4;
|
||||
|
||||
/*
|
||||
@@ -1119,6 +1119,9 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
|
||||
case WACOM_PKGLEN_TPC2FG:
|
||||
return wacom_tpc_mt_touch(wacom);
|
||||
|
||||
+ case WACOM_PKGLEN_PENABLED:
|
||||
+ return wacom_tpc_pen(wacom);
|
||||
+
|
||||
default:
|
||||
switch (data[0]) {
|
||||
case WACOM_REPORT_TPC1FG:
|
||||
@@ -1128,6 +1131,7 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
|
||||
return wacom_tpc_single_touch(wacom, len);
|
||||
|
||||
case WACOM_REPORT_TPCMT:
|
||||
+ case WACOM_REPORT_TPCMT2:
|
||||
return wacom_mt_touch(wacom);
|
||||
|
||||
case WACOM_REPORT_PENABLED:
|
||||
@@ -1470,6 +1474,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
|
||||
case TABLETPC2FG:
|
||||
case MTSCREEN:
|
||||
case MTTPC:
|
||||
+ case MTTPC_B:
|
||||
sync = wacom_tpc_irq(wacom_wac, len);
|
||||
break;
|
||||
|
||||
@@ -1811,6 +1816,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
|
||||
|
||||
case MTSCREEN:
|
||||
case MTTPC:
|
||||
+ case MTTPC_B:
|
||||
case TABLETPC2FG:
|
||||
if (features->device_type == BTN_TOOL_FINGER) {
|
||||
unsigned int flags = INPUT_MT_DIRECT;
|
||||
@@ -2245,6 +2251,9 @@ static const struct wacom_features wacom_features_0x10F =
|
||||
static const struct wacom_features wacom_features_0x4001 =
|
||||
{ "Wacom ISDv4 4001", WACOM_PKGLEN_MTTPC, 26202, 16325, 255,
|
||||
0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
|
||||
+static const struct wacom_features wacom_features_0x5002 =
|
||||
+ { "Wacom ISDv4 5002", WACOM_PKGLEN_MTTPC, 29576, 16724, 1023,
|
||||
+ 0, MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
|
||||
static const struct wacom_features wacom_features_0x47 =
|
||||
{ "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023,
|
||||
31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
|
||||
@@ -2466,6 +2475,7 @@ const struct usb_device_id wacom_ids[] = {
|
||||
{ USB_DEVICE_DETAILED(0x315, USB_CLASS_HID, 0, 0) },
|
||||
{ USB_DEVICE_DETAILED(0x317, USB_CLASS_HID, 0, 0) },
|
||||
{ USB_DEVICE_WACOM(0x4001) },
|
||||
+ { USB_DEVICE_WACOM(0x5002) },
|
||||
{ USB_DEVICE_WACOM(0x47) },
|
||||
{ USB_DEVICE_WACOM(0xF4) },
|
||||
{ USB_DEVICE_WACOM(0xF8) },
|
||||
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h
|
||||
index f69c0eb..620dae8 100644
|
||||
--- a/drivers/input/tablet/wacom_wac.h
|
||||
+++ b/drivers/input/tablet/wacom_wac.h
|
||||
@@ -30,6 +30,7 @@
|
||||
#define WACOM_PKGLEN_MTOUCH 62
|
||||
#define WACOM_PKGLEN_MTTPC 40
|
||||
#define WACOM_PKGLEN_DTUS 68
|
||||
+#define WACOM_PKGLEN_PENABLED 8
|
||||
|
||||
/* wacom data size per MT contact */
|
||||
#define WACOM_BYTES_PER_MT_PACKET 11
|
||||
@@ -52,6 +53,7 @@
|
||||
#define WACOM_REPORT_TPC1FG 6
|
||||
#define WACOM_REPORT_TPC2FG 13
|
||||
#define WACOM_REPORT_TPCMT 13
|
||||
+#define WACOM_REPORT_TPCMT2 3
|
||||
#define WACOM_REPORT_TPCHID 15
|
||||
#define WACOM_REPORT_TPCST 16
|
||||
#define WACOM_REPORT_DTUS 17
|
||||
@@ -105,6 +107,7 @@ enum {
|
||||
TABLETPC2FG,
|
||||
MTSCREEN,
|
||||
MTTPC,
|
||||
+ MTTPC_B,
|
||||
MAX_TYPE
|
||||
};
|
||||
|
||||
--- a/drivers/input/tablet/wacom_sys.c
|
||||
+++ b/drivers/input/tablet/wacom_sys.c
|
||||
@@ -246,7 +248,7 @@
|
||||
int result = 0;
|
||||
unsigned char *rep_data;
|
||||
|
||||
- rep_data = kmalloc(2, GFP_KERNEL);
|
||||
+ rep_data = kmalloc(2, GFP_NOIO);
|
||||
if (rep_data) {
|
||||
|
||||
rep_data[0] = 12;
|
||||
@@ -308,7 +310,7 @@
|
||||
int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0;
|
||||
unsigned char *report;
|
||||
|
||||
- report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL);
|
||||
+ report = kzalloc(hid_desc->wDescriptorLength, GFP_NOIO);
|
||||
if (!report)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -517,7 +538,7 @@
|
||||
unsigned char *rep_data;
|
||||
int error = -ENOMEM, limit = 0;
|
||||
|
||||
- rep_data = kzalloc(length, GFP_KERNEL);
|
||||
+ rep_data = kzalloc(length, GFP_NOIO);
|
||||
if (!rep_data)
|
||||
return error;
|
||||
|
@ -1,28 +0,0 @@
|
||||
commit 00c1504c478a364d74cf9720643a57d9fd180a6b
|
||||
Author: Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
Date: Mon Jun 2 13:36:46 2014 +0200
|
||||
|
||||
xhci-quirks.patch
|
||||
|
||||
--- a/drivers/usb/host/xhci-pci.c
|
||||
+++ b/drivers/usb/host/xhci-pci.c
|
||||
@@ -38,6 +38,8 @@
|
||||
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31
|
||||
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
|
||||
|
||||
+#define PCI_VENDOR_ID_RENESAS 0x1912
|
||||
+
|
||||
static const char hcd_name[] = "xhci_hcd";
|
||||
|
||||
/* called after powerup, by probe or system-pm "wakeup" */
|
||||
@@ -95,6 +97,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
|
||||
if (pdev->vendor == PCI_VENDOR_ID_NEC)
|
||||
xhci->quirks |= XHCI_NEC_HOST;
|
||||
|
||||
+ /* Quirk for RENESAS USB 3.0 express cards */
|
||||
+ if (pdev->vendor == PCI_VENDOR_ID_RENESAS)
|
||||
+ xhci->quirks |= XHCI_TRUST_TX_LENGTH;
|
||||
+
|
||||
if (pdev->vendor == PCI_VENDOR_ID_AMD && xhci->hci_version == 0x96)
|
||||
xhci->quirks |= XHCI_AMD_0x96_HOST;
|
||||
|
@ -1,14 +0,0 @@
|
||||
--- a/drivers/usb/host/xhci-ring.c
|
||||
+++ b/drivers/usb/host/xhci-ring.c
|
||||
@@ -688,6 +688,11 @@
|
||||
{
|
||||
struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index];
|
||||
|
||||
+ if (!deq_state->new_deq_seg) {
|
||||
+ deq_state->new_deq_ptr = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
|
||||
"Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), "
|
||||
"new deq ptr = %p (0x%llx dma), new cycle = %u",
|
@ -1 +1 @@
|
||||
9f095930834c35a2dfc8eaf58b6905081f206c34
|
||||
c63f9c4df89a087251bafa448b8fd99f04334564
|
||||
|
@ -14,6 +14,12 @@ $(call check_tool,bison)
|
||||
FLEX = flex
|
||||
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
|
||||
|
||||
|
||||
#
|
||||
# The git checkout checks for the existence of SRC_DIR, which is created by the
|
||||
@ -25,9 +31,9 @@ usb.archive: dwc_otg.git
|
||||
# USB
|
||||
#
|
||||
SRC_DIR_USB := src/lib/usb
|
||||
VERSION_USB := 3.14.5
|
||||
URL(usb) := http://www.kernel.org/pub/linux/kernel/v3.x/linux-$(VERSION_USB).tar.gz
|
||||
SHA(usb) := 675bb3446cbf0889d59a048f6af177ca0a7aacb5
|
||||
VERSION_USB := 4.4.3
|
||||
URL(usb) := http://www.kernel.org/pub/linux/kernel/v4.x/linux-$(VERSION_USB).tar.xz
|
||||
SHA(usb) := 336d66925a15ce9077cbf2c38acbdc6c2644e33f
|
||||
DIR(usb) := $(SRC_DIR_USB)
|
||||
TAR_OPT(usb) := --strip-components=1 --files-from $(REP_DIR)/usb.list
|
||||
HASH_INPUT += $(REP_DIR)/usb.list
|
||||
@ -35,8 +41,8 @@ HASH_INPUT += $(REP_DIR)/usb.list
|
||||
#
|
||||
# Raspberry Pi USB controller
|
||||
#
|
||||
URL(dwc_otg) := https://github.com/nfeske/dwc_otg.git
|
||||
REV(dwc_otg) := r2
|
||||
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
|
||||
|
||||
|
||||
@ -44,8 +50,9 @@ DIR(dwc_otg) := $(SRC_DIR_USB)/drivers/usb/host/dwc_otg
|
||||
# Intel framebuffer driver
|
||||
#
|
||||
SRC_DIR_INTEL_FB := src/drivers/framebuffer/intel
|
||||
URL(intel_fb) := ${URL(usb)}
|
||||
SHA(intel_fb) := ${SHA(usb)}
|
||||
VERSION_INTEL_FB := 3.14.5
|
||||
URL(intel_fb) := http://www.kernel.org/pub/linux/kernel/v3.x/linux-$(VERSION_INTEL_FB).tar.gz
|
||||
SHA(intel_fb) := 675bb3446cbf0889d59a048f6af177ca0a7aacb5
|
||||
DIR(intel_fb) := $(SRC_DIR_INTEL_FB)
|
||||
TAR_OPT(intel_fb) := --strip-components=1 --files-from $(REP_DIR)/intel_fb.list
|
||||
HASH_INPUT += $(REP_DIR)/intel_fb.list
|
||||
@ -189,8 +196,5 @@ PATCH_OPT(patches/usb_csum.patch) := $(USB_OPT)
|
||||
PATCH_OPT(patches/usb_evdev.patch) := $(USB_OPT)
|
||||
PATCH_OPT(patches/usb_mem.patch) := $(USB_OPT)
|
||||
PATCH_OPT(patches/usb_usbnet.patch) := $(USB_OPT)
|
||||
PATCH_OPT(patches/usb_xchi-quirks.patch) := $(USB_OPT)
|
||||
PATCH_OPT(patches/usb_wacom.patch) := $(USB_OPT)
|
||||
PATCH_OPT(patches/usb_xhci-ring.patch) := $(USB_OPT)
|
||||
|
||||
# vi: set ft=make :
|
||||
|
@ -54,7 +54,7 @@ append config {
|
||||
<provides><service name="Timer"/></provides>
|
||||
</start>
|
||||
<start name="usb_drv">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<provides><service name="Input"/></provides>
|
||||
<config uhci="yes" ehci="yes" xhci="yes">
|
||||
<hid/>
|
||||
|
@ -67,6 +67,7 @@ append config {
|
||||
<start name="test-usb">
|
||||
<resource name="RAM" quantum="2M" />
|
||||
<binary name="test-blk-cli" />
|
||||
<config test_size="1M" />
|
||||
</start>
|
||||
</config>
|
||||
}
|
||||
@ -100,18 +101,27 @@ catch { exec sh -c $cmd }
|
||||
#
|
||||
# Qemu opts for UHCI
|
||||
#
|
||||
#append qemu_args " -m 64 -nographic -usbdevice disk::$disk_image -boot order=d"
|
||||
#append qemu_args " -m 128 -nographic -usbdevice disk::$disk_image -boot order=d"
|
||||
|
||||
#
|
||||
# Qemu opts for EHCI
|
||||
#
|
||||
append qemu_args "-drive if=none,id=disk,file=$disk_image,format=raw"
|
||||
append qemu_args "-drive if=none,id=disk,file=$disk_image"
|
||||
append qemu_args { \
|
||||
-m 128 -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 { \
|
||||
#-m 128 -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"
|
||||
|
@ -51,5 +51,7 @@ struct kobj_uevent_env
|
||||
struct kobj_uevent_env;
|
||||
|
||||
int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...);
|
||||
void kobject_put(struct kobject *);
|
||||
char *kobject_name(const struct kobject *kobj);
|
||||
char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask);
|
||||
struct kobject * kobject_create_and_add(const char *, struct kobject *);
|
||||
|
@ -32,6 +32,12 @@
|
||||
#define SKIP
|
||||
#endif
|
||||
|
||||
/******************
|
||||
** linux/slab.h **
|
||||
******************/
|
||||
|
||||
void *kmalloc_array(size_t n, size_t size, gfp_t flags) { TRACE; return (void *)0xdeadbeaf; }
|
||||
|
||||
|
||||
/******************
|
||||
** asm/atomic.h **
|
||||
@ -40,13 +46,6 @@
|
||||
int atomic_inc_return(atomic_t *v) { TRACE; return 0; }
|
||||
|
||||
|
||||
/*******************************
|
||||
** linux/errno.h and friends **
|
||||
*******************************/
|
||||
|
||||
long PTR_ERR(const void *ptr) { TRACE; return 0; }
|
||||
|
||||
|
||||
/********************
|
||||
** linux/kernel.h **
|
||||
********************/
|
||||
@ -55,6 +54,7 @@ void might_sleep() { SKIP; }
|
||||
char *kasprintf(gfp_t gfp, const char *fmt, ...) { TRACE; return NULL; }
|
||||
int kstrtouint(const char *s, unsigned int base, unsigned int *res) { TRACE; return 0; }
|
||||
int kstrtoul(const char *s, unsigned int base, unsigned long *res) { TRACE; return 0; }
|
||||
int kstrtou8(const char *s, unsigned int base, u8 *x) { TRACE; return 1; }
|
||||
int sprintf(char *buf, const char *fmt, ...) { TRACE; return 0; }
|
||||
int sscanf(const char *b, const char *s, ...) { TRACE; return 0; }
|
||||
int scnprintf(char *buf, size_t size, const char *fmt, ...);
|
||||
@ -76,8 +76,8 @@ int roundup_pow_of_two(u32 n) { TRACE; return 0; }
|
||||
void print_hex_dump(const char *level, const char *prefix_str,
|
||||
int prefix_type, int rowsize, int groupsize,
|
||||
const void *buf, size_t len, bool ascii) { TRACE; }
|
||||
int printk_ratelimit() { TRACE; return 0; }
|
||||
int printk_ratelimited() { TRACE; return 0; }
|
||||
bool printk_ratelimit() { TRACE; return 0; }
|
||||
bool printk_ratelimited() { TRACE; return 0; }
|
||||
bool printk_timed_ratelimit(unsigned long *caller_jiffies,
|
||||
unsigned int interval_msec) { TRACE; return false; }
|
||||
|
||||
@ -132,21 +132,20 @@ void assert_spin_locked(spinlock_t *lock) { TRACE;}
|
||||
** linux/mutex.h **
|
||||
*******************/
|
||||
|
||||
void mutex_lock_nested(struct mutex *lock, unsigned int subclass) { TRACE; }
|
||||
int mutex_lock_interruptible(struct mutex *m) { TRACE; return 0; }
|
||||
void mutex_init (struct mutex *m) { TRACE; }
|
||||
void mutex_lock (struct mutex *m) { TRACE; }
|
||||
void mutex_unlock(struct mutex *m) { TRACE; }
|
||||
int mutex_lock_interruptible(struct mutex *m) { SKIP; return 0; }
|
||||
void mutex_init (struct mutex *m) { SKIP; }
|
||||
void mutex_lock (struct mutex *m) { SKIP; }
|
||||
void mutex_unlock(struct mutex *m) { SKIP; }
|
||||
|
||||
|
||||
/*******************
|
||||
** linux/rwsem.h **
|
||||
*******************/
|
||||
|
||||
void down_read(struct rw_semaphore *sem) { TRACE; }
|
||||
void up_read(struct rw_semaphore *sem) { TRACE; }
|
||||
void down_write(struct rw_semaphore *sem) { TRACE; }
|
||||
void up_write(struct rw_semaphore *sem) { TRACE; }
|
||||
void down_read(struct rw_semaphore *sem) { SKIP; }
|
||||
void up_read(struct rw_semaphore *sem) { SKIP; }
|
||||
void down_write(struct rw_semaphore *sem) { SKIP; }
|
||||
void up_write(struct rw_semaphore *sem) { SKIP; }
|
||||
|
||||
|
||||
/*********************
|
||||
@ -173,8 +172,7 @@ ktime_t ktime_add_ns(const ktime_t kt, u64 nsec) { KTIME_RET; }
|
||||
ktime_t ktime_get_monotonic_offset(void) { KTIME_RET; }
|
||||
ktime_t ktime_sub(const ktime_t lhs, const ktime_t rhs) { KTIME_RET; }
|
||||
ktime_t ktime_get_real(void) { TRACE; ktime_t ret; return ret; }
|
||||
|
||||
struct timeval ktime_to_timeval(const ktime_t kt) { TRACE; struct timeval ret; return ret; }
|
||||
ktime_t ktime_get_boottime(void) { TRACE; KTIME_RET; }
|
||||
|
||||
s64 ktime_us_delta(const ktime_t later, const ktime_t earlier) { TRACE; return 0; };
|
||||
|
||||
@ -187,12 +185,18 @@ unsigned long round_jiffies(unsigned long j) { TRACE; return 1; }
|
||||
void set_timer_slack(struct timer_list *time, int slack_hz) { TRACE; }
|
||||
|
||||
|
||||
/*******************
|
||||
** linux/delay.h **
|
||||
*******************/
|
||||
|
||||
void usleep_range(unsigned long min, unsigned long max) { TRACE; }
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/workquque.h **
|
||||
***********************/
|
||||
|
||||
bool cancel_work_sync(struct work_struct *work) { TRACE; return 0; }
|
||||
int cancel_delayed_work_sync(struct delayed_work *work) { TRACE; return 0; }
|
||||
void destroy_workqueue(struct workqueue_struct *wq) { TRACE; }
|
||||
|
||||
bool flush_work(struct work_struct *work) { TRACE; return 0; }
|
||||
bool flush_work_sync(struct work_struct *work) { TRACE; return 0; }
|
||||
@ -223,12 +227,18 @@ void __set_current_state(int state) { TRACE; }
|
||||
int signal_pending(struct task_struct *p) { TRACE; return 0; }
|
||||
void schedule(void) { TRACE; }
|
||||
void yield(void) { TRACE; }
|
||||
void cpu_relax(void) { TRACE; udelay(1); }
|
||||
signed long schedule_timeout(signed long timeout) { TRACE; return 0; }
|
||||
void cpu_relax(void) { SKIP; }
|
||||
|
||||
struct task_struct *current;
|
||||
|
||||
|
||||
/******************
|
||||
** linux/wait.h **
|
||||
******************/
|
||||
|
||||
void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait) { TRACE; }
|
||||
|
||||
|
||||
/*********************
|
||||
** linux/kthread.h **
|
||||
*********************/
|
||||
@ -271,6 +281,8 @@ int sysfs_create_link(struct kobject *kobj, struct kobject *target,
|
||||
const char *name) { TRACE; return 0; }
|
||||
void sysfs_remove_link(struct kobject *kobj, const char *name) { TRACE; }
|
||||
|
||||
int sysfs_create_files(struct kobject *kobj, const struct attribute **attr) { TRACE; return 1; }
|
||||
|
||||
int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp) { TRACE; return 0; }
|
||||
|
||||
ssize_t simple_read_from_buffer(void __user *to, size_t count,
|
||||
@ -280,22 +292,24 @@ ssize_t simple_read_from_buffer(void __user *to, size_t count,
|
||||
** linux/pm_runtime.h **
|
||||
************************/
|
||||
|
||||
int pm_runtime_set_active(struct device *dev) { TRACE; return 0; }
|
||||
void pm_suspend_ignore_children(struct device *dev, bool enable) { TRACE; }
|
||||
void pm_runtime_enable(struct device *dev) { TRACE; }
|
||||
void pm_runtime_disable(struct device *dev) { TRACE; }
|
||||
void pm_runtime_allow(struct device *dev) { TRACE; }
|
||||
void pm_runtime_forbid(struct device *dev) { TRACE; }
|
||||
void pm_runtime_set_suspended(struct device *dev) { TRACE; }
|
||||
void pm_runtime_get_noresume(struct device *dev) { TRACE; }
|
||||
void pm_runtime_put_noidle(struct device *dev) { TRACE; }
|
||||
void pm_runtime_use_autosuspend(struct device *dev) { TRACE; }
|
||||
int pm_runtime_put_sync_autosuspend(struct device *dev) { TRACE; return 0; }
|
||||
void pm_runtime_no_callbacks(struct device *dev) { TRACE; }
|
||||
void pm_runtime_set_autosuspend_delay(struct device *dev, int delay) { TRACE; }
|
||||
int pm_runtime_get_sync(struct device *dev) { TRACE; return 0; }
|
||||
int pm_runtime_put_sync(struct device *dev) { TRACE; return 0; }
|
||||
int pm_runtime_put(struct device *dev) { TRACE; return 0; }
|
||||
bool pm_runtime_active(struct device *dev) { SKIP; return true; }
|
||||
int pm_runtime_set_active(struct device *dev) { SKIP; return 0; }
|
||||
void pm_suspend_ignore_children(struct device *dev, bool enable) { SKIP; }
|
||||
void pm_runtime_enable(struct device *dev) { SKIP; }
|
||||
void pm_runtime_disable(struct device *dev) { SKIP; }
|
||||
void pm_runtime_allow(struct device *dev) { SKIP; }
|
||||
void pm_runtime_forbid(struct device *dev) { SKIP; }
|
||||
void pm_runtime_set_suspended(struct device *dev) { SKIP; }
|
||||
void pm_runtime_get_noresume(struct device *dev) { SKIP; }
|
||||
void pm_runtime_put_noidle(struct device *dev) { SKIP; }
|
||||
void pm_runtime_use_autosuspend(struct device *dev) { SKIP; }
|
||||
int pm_runtime_put_sync_autosuspend(struct device *dev) { SKIP; return 0; }
|
||||
void pm_runtime_no_callbacks(struct device *dev) { SKIP; }
|
||||
void pm_runtime_set_autosuspend_delay(struct device *dev, int delay) { SKIP; }
|
||||
int pm_runtime_get_sync(struct device *dev) { SKIP; return 0; }
|
||||
int pm_runtime_put_sync(struct device *dev) { SKIP; return 0; }
|
||||
int pm_runtime_put(struct device *dev) { SKIP; return 0; }
|
||||
int pm_runtime_barrier(struct device *dev) { SKIP; return 0; }
|
||||
|
||||
|
||||
/***********************
|
||||
@ -314,6 +328,9 @@ bool device_can_wakeup(struct device *dev) { TRACE; return 0; }
|
||||
********************/
|
||||
|
||||
int dev_pm_qos_expose_flags(struct device *dev, s32 value) { TRACE; return 0; }
|
||||
int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
|
||||
enum dev_pm_qos_req_type type, s32 value) { TRACE; return 0; }
|
||||
int dev_pm_qos_remove_request(struct dev_pm_qos_request *req) { TRACE; return 0; }
|
||||
|
||||
|
||||
/********************
|
||||
@ -373,6 +390,8 @@ int bus_register_notifier(struct bus_type *bus,
|
||||
struct notifier_block *nb) { TRACE; return 0; }
|
||||
int bus_unregister_notifier(struct bus_type *bus,
|
||||
struct notifier_block *nb) { TRACE; return 0; }
|
||||
int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data,
|
||||
int (*fn)(struct device *dev, void *data)) { TRACE; return 0; }
|
||||
|
||||
struct class *__class_create(struct module *owner,
|
||||
const char *name,
|
||||
@ -530,6 +549,7 @@ bool is_highmem(void *ptr) { TRACE; return 0; }
|
||||
|
||||
struct zone *page_zone(const struct page *page) { TRACE; return NULL; }
|
||||
int is_vmalloc_addr(const void *x) { TRACE; return 0; }
|
||||
void kvfree(const void *addr) { TRACE; }
|
||||
|
||||
|
||||
/**********************
|
||||
@ -587,11 +607,8 @@ bool in_interrupt(void) { TRACE; return 1; }
|
||||
** linux/pci.h **
|
||||
*****************/
|
||||
|
||||
int pci_bus_read_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 *val) { TRACE; return 0; }
|
||||
int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn, int where, u32 val) { TRACE; return 0; }
|
||||
|
||||
void *pci_get_drvdata(struct pci_dev *pdev) { TRACE; return NULL; }
|
||||
void pci_dev_put(struct pci_dev *dev) { TRACE; }
|
||||
struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
|
||||
struct pci_dev *from) { TRACE; return NULL; }
|
||||
|
||||
@ -613,6 +630,7 @@ int pci_enable_msi(struct pci_dev *pdev) { TRACE; return -1; }
|
||||
void pci_disable_msi(struct pci_dev *pdev) { TRACE; }
|
||||
|
||||
int pci_enable_msix(struct pci_dev *pdev, struct msix_entry *entries, int vec) { TRACE; return -1; }
|
||||
int pci_enable_msix_exact(struct pci_dev *pdef,struct msix_entry *entries, int vec) { TRACE; return -1; }
|
||||
void pci_disable_msix(struct pci_dev *pdev) { TRACE; }
|
||||
|
||||
|
||||
@ -634,7 +652,7 @@ void pci_set_master(struct pci_dev *dev) { SKIP; }
|
||||
|
||||
unsigned long local_irq_save(unsigned long flags) { SKIP; return 0; }
|
||||
unsigned long local_irq_restore(unsigned long flags) { SKIP; return 0; }
|
||||
|
||||
unsigned smp_processor_id() { return 0; }
|
||||
|
||||
/*************************
|
||||
** linux/scatterlist.h **
|
||||
@ -673,6 +691,12 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
|
||||
int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { SKIP; return 0; }
|
||||
|
||||
|
||||
/*********************
|
||||
** linux/uaccess.h **
|
||||
*********************/
|
||||
|
||||
unsigned long clear_user(void *to, unsigned long n) { TRACE; return 0; }
|
||||
|
||||
/*****************
|
||||
** linux/pid.h **
|
||||
*****************/
|
||||
@ -736,10 +760,11 @@ int match_octal(substring_t *s, int *result) { TRACE; return 0; }
|
||||
/*********************
|
||||
** linux/semaphore **
|
||||
*********************/
|
||||
void sema_init(struct semaphore *sem, int val) { TRACE; }
|
||||
int down_trylock(struct semaphore *sem) { TRACE; return 0; }
|
||||
int down_interruptible(struct semaphore *sem) { TRACE; return 0; }
|
||||
void up(struct semaphore *sem) { TRACE; }
|
||||
|
||||
void sema_init(struct semaphore *sem, int val) { SKIP; }
|
||||
int down_trylock(struct semaphore *sem) { SKIP; return 0; }
|
||||
int down_interruptible(struct semaphore *sem) { SKIP; return 0; }
|
||||
void up(struct semaphore *sem) { SKIP; }
|
||||
|
||||
|
||||
/*******************
|
||||
@ -781,8 +806,8 @@ unsigned int queue_max_hw_sectors(struct request_queue *q) { TRACE; return 0; }
|
||||
** scsi/scsi_cmnd.h **
|
||||
**********************/
|
||||
|
||||
void scsi_set_resid(struct scsi_cmnd *cmd, int resid) { TRACE; }
|
||||
int scsi_get_resid(struct scsi_cmnd *cmd) { TRACE; return 0; }
|
||||
void scsi_set_resid(struct scsi_cmnd *cmd, int resid) { SKIP; }
|
||||
int scsi_get_resid(struct scsi_cmnd *cmd) { SKIP; return 0; }
|
||||
|
||||
|
||||
/********************
|
||||
@ -907,6 +932,15 @@ int generic_mii_ioctl(struct mii_if_info *mii_if,
|
||||
struct mii_ioctl_data *if_mii(struct ifreq *rq) { TRACE; return 0; }
|
||||
|
||||
|
||||
/***********************
|
||||
** uapi/linux/mdio.h **
|
||||
***********************/
|
||||
|
||||
u16 ethtool_adv_to_mmd_eee_adv_t(u32 adv) { TRACE; return 0; }
|
||||
u32 mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv) { TRACE; return 0; }
|
||||
u32 mmd_eee_cap_to_ethtool_sup_t(u16 eee_cap) { TRACE; return 0; }
|
||||
|
||||
|
||||
/*************************
|
||||
** linux/etherdevice.h **
|
||||
*************************/
|
||||
@ -961,6 +995,8 @@ void clk_disable_unprepare(struct clk *clk) { TRACE; }
|
||||
int bitmap_subset(const unsigned long *src1,
|
||||
const unsigned long *src2, int nbits) { TRACE; return 1; }
|
||||
|
||||
int bitmap_weight(const unsigned long *src, unsigned int nbits) { TRACE; return 0; }
|
||||
|
||||
|
||||
/*****************
|
||||
** linux/idr.h **
|
||||
@ -1013,8 +1049,11 @@ u16 bitrev16(u16 in) { TRACE; return 0; }
|
||||
************************/
|
||||
|
||||
void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index) { TRACE; return 0; }
|
||||
int radix_tree_insert(struct radix_tree_root *root, unsigned long index, void *item) { TRACE; return 0; }
|
||||
void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) { TRACE; return 0; }
|
||||
void radix_tree_preload_end(void) { TRACE; }
|
||||
|
||||
int radix_tree_insert(struct radix_tree_root *root, unsigned long index, void *item) { TRACE; return 0; }
|
||||
int radix_tree_maybe_preload(gfp_t gfp_mask) { TRACE; return 0; }
|
||||
|
||||
/******************
|
||||
** linux/gpio.h **
|
||||
@ -1036,6 +1075,14 @@ int devm_gpio_request_one(struct device *dev, unsigned gpio,
|
||||
const char *propname, int index) { TRACE; return 0; }
|
||||
|
||||
|
||||
/********************
|
||||
** linux/module.h **
|
||||
********************/
|
||||
|
||||
void module_put(struct module *m) { TRACE; }
|
||||
void __module_get(struct module *m) { TRACE; }
|
||||
|
||||
|
||||
/******************
|
||||
** linux/phy.h **
|
||||
******************/
|
||||
@ -1054,6 +1101,13 @@ int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd) { TRAC
|
||||
int phy_start_aneg(struct phy_device *phydev) { TRACE; return 0; }
|
||||
void phy_start(struct phy_device *phydev) { TRACE; }
|
||||
void phy_stop(struct phy_device *phydev) { TRACE; }
|
||||
int phy_init(struct phy *phy) { TRACE; return 0; }
|
||||
int phy_exit(struct phy *phy) { TRACE; return 0; }
|
||||
int phy_power_on(struct phy *phy) { TRACE; return 0; }
|
||||
int phy_power_off(struct phy *phy) { TRACE; return 0; }
|
||||
int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id) { TRACE; return 0; }
|
||||
void phy_remove_lookup(struct phy *phy, const char *con_id, const char *dev_id) { TRACE; }
|
||||
|
||||
int genphy_resume(struct phy_device *phydev) { TRACE; return 0; }
|
||||
|
||||
struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
|
||||
@ -1068,6 +1122,8 @@ struct usb_phy *devm_usb_get_phy_dev(struct device *dev, u8 index) { TRACE; retu
|
||||
struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index) { TRACE; return 0; }
|
||||
void usb_put_phy(struct usb_phy *x) { TRACE; }
|
||||
|
||||
struct phy *devm_phy_get(struct device *dev, const char *string) { TRACE; return 0; }
|
||||
|
||||
|
||||
/****************
|
||||
** linux/of.h **
|
||||
@ -1082,6 +1138,18 @@ int of_platform_populate(struct device_node *root, const struct of_device_i
|
||||
int of_device_is_compatible(const struct device_node *device, const char *compat) { TRACE; return 1; }
|
||||
|
||||
|
||||
/**********************
|
||||
** linux/property.h **
|
||||
**********************/
|
||||
|
||||
bool device_property_read_bool(struct device *dev, const char *propname) { TRACE; return false; }
|
||||
int device_property_read_u8(struct device *dev, const char *propname, u8 *val) { TRACE; return 0; }
|
||||
|
||||
int device_property_read_string(struct device *dev, const char *propname,
|
||||
const char **val) { TRACE; *val = 0; return -EINVAL; }
|
||||
int device_property_read_u32(struct device *dev, const char *propname, u32 *val) { TRACE; return 0; }
|
||||
|
||||
|
||||
/******************************
|
||||
** drivers/usb/dwc3/debug.h **
|
||||
******************************/
|
||||
@ -1090,11 +1158,26 @@ struct dwc3;
|
||||
|
||||
int dwc3_debugfs_init(struct dwc3 *d){ SKIP; return 0; }
|
||||
void dwc3_debugfs_exit(struct dwc3 *d) { SKIP; }
|
||||
void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...) { SKIP; }
|
||||
|
||||
|
||||
/**************************
|
||||
** linux/power_supply.h **
|
||||
**************************/
|
||||
|
||||
#include <linux/power_supply.h>
|
||||
int power_supply_register(struct device *parent, struct power_supply *psy) { TRACE; return 0; }
|
||||
struct power_supply *
|
||||
power_supply_register(struct device *parent, const struct power_supply_desc *desc,
|
||||
const struct power_supply_config *cfg) { TRACE; return 0; }
|
||||
void power_supply_unregister(struct power_supply *psy) { TRACE; }
|
||||
int power_supply_powers(struct power_supply *psy, struct device *dev) { TRACE; return 0; }
|
||||
void *power_supply_get_drvdata(struct power_supply *psy) { TRACE; return 0; }
|
||||
void power_supply_changed(struct power_supply *psy) { TRACE; }
|
||||
|
||||
|
||||
/*********************
|
||||
** linux/kobject.h **
|
||||
*********************/
|
||||
|
||||
void kobject_put(struct kobject *kobj) { TRACE; }
|
||||
struct kobject *kobject_create_and_add(const char *name, struct kobject *kobj) { TRACE; return 0; }
|
||||
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* \brief Include before including Linux headers in C++
|
||||
* \author Christian Helmuth
|
||||
* \date 2014-08-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#define extern_c_begin
|
||||
|
||||
extern "C" {
|
||||
|
||||
/* some warnings should only be switched of for Linux headers */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpointer-arith"
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
|
||||
/* deal with C++ keywords used for identifiers etc. */
|
||||
#define private private_
|
||||
#define class class_
|
||||
#define new new_
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* \brief Include after including Linux headers in C++
|
||||
* \author Christian Helmuth
|
||||
* \date 2014-08-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#undef new
|
||||
#undef class
|
||||
#undef private
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
} /* extern "C" */
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* \brief Slightly improved list
|
||||
* \author Christian Helmuth
|
||||
* \date 2014-09-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _LIST_H_
|
||||
#define _LIST_H_
|
||||
|
||||
#include <util/list.h>
|
||||
|
||||
|
||||
namespace Lx {
|
||||
template <typename> class List;
|
||||
template <typename> class List_element;
|
||||
}
|
||||
|
||||
template <typename LT>
|
||||
class Lx::List : private Genode::List<LT>
|
||||
{
|
||||
private:
|
||||
|
||||
typedef Genode::List<LT> Base;
|
||||
|
||||
public:
|
||||
|
||||
using Base::Element;
|
||||
|
||||
void append(LT const *le)
|
||||
{
|
||||
LT *at = nullptr;
|
||||
|
||||
for (LT *l = first(); l; l = l->next())
|
||||
at = l;
|
||||
|
||||
Base::insert(le, at);
|
||||
}
|
||||
|
||||
void prepend(LT const *le)
|
||||
{
|
||||
Base::insert(le);
|
||||
}
|
||||
|
||||
void insert_before(LT const *le, LT const *at)
|
||||
{
|
||||
if (at == first()) {
|
||||
prepend(le);
|
||||
return;
|
||||
} else if (!at) {
|
||||
append(le);
|
||||
return;
|
||||
}
|
||||
|
||||
for (LT *l = first(); l; l = l->next())
|
||||
if (l->next() == at)
|
||||
at = l;
|
||||
|
||||
Base::insert(le, at);
|
||||
}
|
||||
|
||||
|
||||
/****************************
|
||||
** Genode::List interface **
|
||||
****************************/
|
||||
|
||||
LT *first() { return Base::first(); }
|
||||
LT const *first() const { return Base::first(); }
|
||||
|
||||
void insert(LT const *le, LT const *at = 0)
|
||||
{
|
||||
Base::insert(le, at);
|
||||
}
|
||||
|
||||
void remove(LT const *le)
|
||||
{
|
||||
Base::remove(le);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class Lx::List_element : public Lx::List<List_element<T> >::Element
|
||||
{
|
||||
private:
|
||||
|
||||
T *_object;
|
||||
|
||||
public:
|
||||
|
||||
List_element(T *object) : _object(object) { }
|
||||
|
||||
T *object() const { return _object; }
|
||||
};
|
||||
|
||||
#endif /* _LIST_H_ */
|
File diff suppressed because it is too large
Load Diff
0
repos/dde_linux/src/lib/usb/include/otg_whitelist.h
Normal file
0
repos/dde_linux/src/lib/usb/include/otg_whitelist.h
Normal file
@ -1,214 +0,0 @@
|
||||
/*
|
||||
* \brief Pseudo-thread implementation using setjmp/longjmp
|
||||
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
|
||||
* \date 2012-04-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _ROUTINE_H_
|
||||
#define _ROUTINE_H_
|
||||
|
||||
#include <base/env.h>
|
||||
#include <util/list.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include <platform/platform.h>
|
||||
|
||||
static const bool verbose = false;
|
||||
|
||||
namespace Timer {
|
||||
void update_jiffies();
|
||||
}
|
||||
/**
|
||||
* Allows pseudo-parallel execution of functions
|
||||
*/
|
||||
class Routine : public Genode::List<Routine>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
enum { STACK_SIZE = 4 * 1024 * sizeof(long) };
|
||||
bool _started; /* true if already started */
|
||||
jmp_buf _env; /* state */
|
||||
int (*_func)(void *); /* function to call*/
|
||||
void *_arg; /* argument for function */
|
||||
char const *_name; /* name of this object */
|
||||
char *_stack; /* stack pointer */
|
||||
static Routine *_current; /* currently scheduled object */
|
||||
static Routine *_dead; /* object to remove */
|
||||
static Routine *_main; /* main routine */
|
||||
static bool _all; /* true when all objects must be scheduled */
|
||||
|
||||
|
||||
/**
|
||||
* List containing all registered objects
|
||||
*/
|
||||
static Genode::List<Routine> *_list()
|
||||
{
|
||||
static Genode::List<Routine> _l;
|
||||
return &_l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start/restore
|
||||
*/
|
||||
void _run()
|
||||
{
|
||||
/* will never return */
|
||||
if (!_started) {
|
||||
_started = true;
|
||||
Genode::Thread *th = Genode::Thread::myself();
|
||||
_stack = (char *) th->alloc_secondary_stack(_name, STACK_SIZE);
|
||||
|
||||
if (verbose)
|
||||
PDBG("Start func %s (%p) sp: %p", _name, _func, _stack);
|
||||
|
||||
/* XXX move to platform code */
|
||||
|
||||
/* switch stack and call '_func(_arg)' */
|
||||
platform_execute((void *)(_stack), (void *)_func, _arg);
|
||||
}
|
||||
|
||||
/* restore old state */
|
||||
if (verbose)
|
||||
PDBG("Schedule %s (%p)", _name, _func);
|
||||
|
||||
_longjmp(_env, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for and remove dead objects
|
||||
*/
|
||||
static void _check_dead()
|
||||
{
|
||||
if (!_dead)
|
||||
return;
|
||||
|
||||
_list()->remove(_dead);
|
||||
destroy(Genode::env()->heap(), _dead);
|
||||
_dead = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get next object to schedule
|
||||
*/
|
||||
static Routine *_next(bool all)
|
||||
{
|
||||
/* on schedule all start at first element */
|
||||
if (all) {
|
||||
_all = true;
|
||||
return _list()->first();
|
||||
}
|
||||
|
||||
/* disable all at last element */
|
||||
if (_all && _current && !_current->next())
|
||||
_all = false;
|
||||
|
||||
/* return next element (wrap at the end) */
|
||||
return _current && _current->next() ? _current->next() : _list()->first();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Routine(int (*func)(void*), void *arg, char const *name, bool started)
|
||||
: _started(started), _func(func), _arg(arg), _name(name), _stack(0) { }
|
||||
|
||||
~Routine()
|
||||
{
|
||||
if (_stack)
|
||||
Genode::Thread::myself()->free_secondary_stack(_stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule next object
|
||||
*
|
||||
* If all is true, each object will be scheduled once.
|
||||
*/
|
||||
static void schedule(bool all = false, bool main = false)
|
||||
__attribute__((noinline))
|
||||
{
|
||||
if (!_list()->first() && !_main)
|
||||
return;
|
||||
|
||||
if (_current == _main)
|
||||
all = true;
|
||||
|
||||
Routine *next = main ? _main : _next(all);
|
||||
|
||||
if (next == _current) {
|
||||
_check_dead();
|
||||
return;
|
||||
}
|
||||
|
||||
/* return when restored */
|
||||
if (_current && _setjmp(_current->_env)) {
|
||||
_check_dead();
|
||||
return;
|
||||
}
|
||||
|
||||
_current = next;
|
||||
_current->_run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule each object once
|
||||
*/
|
||||
static void schedule_all() { schedule(true); }
|
||||
|
||||
/**
|
||||
* Set current to first object
|
||||
*/
|
||||
static void make_main_current() { _main = _current = _list()->first(); }
|
||||
|
||||
/**
|
||||
* Add an object
|
||||
*/
|
||||
static Routine *add(int (*func)(void *), void *arg, char const *name,
|
||||
bool started = false)
|
||||
{
|
||||
Routine *r = new (Genode::env()->heap()) Routine(func, arg, name, started);
|
||||
_list()->insert(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove this object
|
||||
*/
|
||||
static void remove(Routine *r = nullptr)
|
||||
{
|
||||
if (!_current && !r)
|
||||
return;
|
||||
|
||||
_dead = r ? r : _current;
|
||||
|
||||
schedule_main();
|
||||
}
|
||||
|
||||
static void main()
|
||||
{
|
||||
if (!_current)
|
||||
return;
|
||||
|
||||
_list()->remove(_current);
|
||||
|
||||
if (_main && _setjmp(_main->_env))
|
||||
return;
|
||||
|
||||
schedule();
|
||||
}
|
||||
|
||||
static void schedule_main() { schedule(false, true); }
|
||||
|
||||
/**
|
||||
* True when 'schedule_all' has been called and is still in progress
|
||||
*/
|
||||
static bool all() { return _all; }
|
||||
};
|
||||
|
||||
#endif /* _ROUTINE_H_ */
|
||||
|
@ -19,41 +19,7 @@
|
||||
#include <base/signal.h>
|
||||
#include <os/server.h>
|
||||
|
||||
#include "routine.h"
|
||||
|
||||
/**
|
||||
* This singleton currently received all signals
|
||||
*/
|
||||
class Service_handler
|
||||
{
|
||||
private:
|
||||
|
||||
Service_handler() { }
|
||||
|
||||
public:
|
||||
|
||||
static Service_handler * s()
|
||||
{
|
||||
static Service_handler _s;
|
||||
return &_s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch for wait for signal
|
||||
*/
|
||||
void process()
|
||||
{
|
||||
Timer::update_jiffies();
|
||||
|
||||
if (Routine::all()) {
|
||||
Routine::schedule();
|
||||
return;
|
||||
}
|
||||
|
||||
Routine::schedule_main();
|
||||
}
|
||||
};
|
||||
|
||||
static bool const verbose = false;
|
||||
|
||||
/**
|
||||
* Helper that holds sender and entrypoint
|
||||
@ -74,21 +40,6 @@ class Signal_helper
|
||||
};
|
||||
|
||||
|
||||
namespace Timer
|
||||
{
|
||||
void init(Server::Entrypoint &ep);
|
||||
}
|
||||
|
||||
namespace Irq
|
||||
{
|
||||
void init(Server::Entrypoint &ep);
|
||||
void check_irq();
|
||||
}
|
||||
|
||||
namespace Event
|
||||
{
|
||||
void init(Server::Entrypoint &ep);
|
||||
}
|
||||
|
||||
namespace Storage
|
||||
{
|
||||
|
@ -131,6 +131,8 @@ 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 **
|
||||
@ -174,11 +176,16 @@ int devm_gpio_request_one(struct device *dev, unsigned gpio,
|
||||
****************/
|
||||
|
||||
#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 *);
|
||||
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);
|
||||
|
||||
|
||||
/*************************
|
||||
@ -240,6 +247,10 @@ 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,
|
||||
@ -247,6 +258,25 @@ struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
|
||||
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 **
|
||||
@ -276,7 +306,7 @@ void *dma_to_virt(struct device *dev, dma_addr_t addr);
|
||||
|
||||
void local_fiq_disable();
|
||||
void local_fiq_enable();
|
||||
|
||||
unsigned smp_processor_id(void);
|
||||
|
||||
/***************
|
||||
** asm/fiq.h **
|
||||
@ -300,7 +330,20 @@ struct usb_phy_gen_xceiv_platform_data
|
||||
int gpio_reset;
|
||||
};
|
||||
|
||||
#include <linux/usb/ch9.h>
|
||||
#include <linux/usb/phy.h>
|
||||
|
||||
/******************************
|
||||
** linux/usb/xhci_pdriver.h **
|
||||
******************************/
|
||||
|
||||
struct usb_xhci_pdata {
|
||||
unsigned usb3_lpm_capable:1;
|
||||
};
|
||||
|
||||
|
||||
/******************
|
||||
** asm/memory.h **
|
||||
******************/
|
||||
|
||||
#define __bus_to_virt phys_to_virt
|
||||
|
||||
#endif /* _ARM__PLATFORM__LX_EMUL_H_ */
|
||||
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* \brief Platform specific part of memory allocation
|
||||
* \author Alexander Boettcher
|
||||
* \date 2013-03-18
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _ARM__PLATFORM__LX_MEM_
|
||||
#define _ARM__PLATFORM__LX_MEM_
|
||||
|
||||
#include <base/cache.h>
|
||||
|
||||
class Backend_memory {
|
||||
|
||||
public:
|
||||
|
||||
static Genode::Ram_dataspace_capability alloc(Genode::addr_t size,
|
||||
Genode::Cache_attribute c)
|
||||
{
|
||||
return Genode::env()->ram_session()->alloc(size, c);
|
||||
}
|
||||
|
||||
static void free(Genode::Ram_dataspace_capability cap) {
|
||||
return Genode::env()->ram_session()->free(cap); }
|
||||
};
|
||||
|
||||
#endif /* _ARM__PLATFORM__LX_MEM_ */
|
@ -1,35 +0,0 @@
|
||||
/**
|
||||
* \brief Platform specific code
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-06-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _ARM__PLATFORM_H_
|
||||
#define _ARM__PLATFORM_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline
|
||||
void platform_execute(void *sp, void *func, void *arg)
|
||||
{
|
||||
asm volatile ("mov r0, %2;" /* set arg */
|
||||
"mov sp, %0;" /* set stack */
|
||||
"mov pc, %1;" /* call func */
|
||||
""
|
||||
: : "r"(sp), "r"(func), "r"(arg) : "r0");
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ARM__PLATFORM_H_ */
|
@ -0,0 +1,73 @@
|
||||
/**
|
||||
* \brief Platform_device implementation for ARM
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2016-04-25
|
||||
*
|
||||
* Note: Throw away when there exists a plaform device implementation for ARM
|
||||
* in generic code
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
|
||||
#define _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_
|
||||
|
||||
#include <platform_device/device.h>
|
||||
|
||||
#include <irq_session/connection.h>
|
||||
#include <util/list.h>
|
||||
#include <util/volatile_object.h>
|
||||
|
||||
|
||||
namespace Platform { struct Device; }
|
||||
|
||||
struct Platform::Device : Platform::Abstract_device, Genode::List<Device>::Element
|
||||
{
|
||||
unsigned irq_num;
|
||||
Genode::Lazy_volatile_object<Genode::Irq_connection> irq_connection;
|
||||
|
||||
Device(unsigned irq) : irq_num(irq) { }
|
||||
|
||||
unsigned vendor_id() { return ~0U; }
|
||||
unsigned device_id() { return ~0U; }
|
||||
|
||||
Genode::Irq_session_capability irq(Genode::uint8_t) override
|
||||
{
|
||||
irq_connection.construct(irq_num);
|
||||
return irq_connection->cap();
|
||||
}
|
||||
|
||||
Genode::Io_mem_session_capability io_mem(Genode::uint8_t,
|
||||
Genode::Cache_attribute,
|
||||
Genode::addr_t, Genode::size_t) override
|
||||
{
|
||||
PERR("%s: not implemented", __PRETTY_FUNCTION__);
|
||||
return Genode::Io_mem_session_capability();
|
||||
}
|
||||
|
||||
static Genode::List<Device> &list()
|
||||
{
|
||||
static Genode::List<Device> l;
|
||||
return l;
|
||||
}
|
||||
|
||||
static Device &create(unsigned irq_num)
|
||||
{
|
||||
Device *d;
|
||||
for (d = list().first(); d; d = d->next())
|
||||
if (d->irq_num == irq_num)
|
||||
return *d;
|
||||
|
||||
d = new (Genode::env()->heap()) Device(irq_num);
|
||||
list().insert(d);
|
||||
|
||||
return *d;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _ARM__PLATFORM_DEVICE__PLATFORM_DEVICE_H_ */
|
@ -18,15 +18,6 @@
|
||||
** asm/barrier.h **
|
||||
*******************/
|
||||
|
||||
#define mb() asm volatile ("": : :"memory")
|
||||
#define rmb() mb()
|
||||
#define wmb() asm volatile ("": : :"memory")
|
||||
|
||||
#define smp_mb() asm volatile ("": : :"memory")
|
||||
#define smp_rmb() smp_mb()
|
||||
#define smp_wmb() asm volatile ("": : :"memory")
|
||||
|
||||
static inline void barrier() { asm volatile ("": : :"memory"); }
|
||||
|
||||
#include <lx_emul/barrier.h>
|
||||
|
||||
#endif /* _ARMV6__PLATFORM__LX_EMUL_BARRIER_H_ */
|
||||
|
@ -18,20 +18,6 @@
|
||||
** asm/barrier.h **
|
||||
*******************/
|
||||
|
||||
/*
|
||||
* This is the "safe" implementation as needed for a configuration
|
||||
* with bufferable DMA memory and SMP enabled.
|
||||
*/
|
||||
|
||||
#define mb() asm volatile ("dsb": : :"memory")
|
||||
#define rmb() mb()
|
||||
#define wmb() asm volatile ("dsb st": : :"memory")
|
||||
|
||||
#define smp_mb() asm volatile ("dmb ish": : :"memory")
|
||||
#define smp_rmb() smp_mb()
|
||||
#define smp_wmb() asm volatile ("dmb ishst": : :"memory")
|
||||
|
||||
static inline void barrier() { asm volatile ("": : :"memory"); }
|
||||
|
||||
#include <lx_emul/barrier.h>
|
||||
|
||||
#endif /* _ARMV7__PLATFORM__LX_EMUL_BARRIER_H_ */
|
||||
|
@ -14,28 +14,20 @@
|
||||
#ifndef _X86_32__PLATFORM__LX_EMUL_
|
||||
#define _X86_32__PLATFORM__LX_EMUL_
|
||||
|
||||
struct platform_device
|
||||
{
|
||||
void *data;
|
||||
};
|
||||
|
||||
/*******************
|
||||
** asm/barrier.h **
|
||||
*******************/
|
||||
|
||||
#define mb() asm volatile ("mfence": : :"memory")
|
||||
#define rmb() asm volatile ("lfence": : :"memory")
|
||||
#define wmb() asm volatile ("sfence": : :"memory")
|
||||
#include <lx_emul/barrier.h>
|
||||
|
||||
/*
|
||||
* This is the "safe" implementation as needed for a configuration
|
||||
* with SMP enabled.
|
||||
*/
|
||||
|
||||
#define smp_mb() mb()
|
||||
#define smp_rmb() barrier()
|
||||
#define smp_wmb() barrier()
|
||||
struct platform_device
|
||||
{
|
||||
void *data;
|
||||
};
|
||||
|
||||
static inline void barrier() { asm volatile ("": : :"memory"); }
|
||||
|
||||
#define dev_is_pci(d) (1)
|
||||
|
||||
#endif /* _X86_32__PLATFORM__LX_EMUL_ */
|
||||
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* \brief Platform specific part of memory allocation
|
||||
* \author Alexander Boettcher
|
||||
* \date 2013-03-18
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _X86__PLATFORM__LX_MEM_
|
||||
#define _X86__PLATFORM__LX_MEM_
|
||||
|
||||
#include <base/cache.h>
|
||||
|
||||
class Backend_memory {
|
||||
|
||||
public:
|
||||
|
||||
static Genode::Ram_dataspace_capability alloc(Genode::addr_t size,
|
||||
Genode::Cache_attribute);
|
||||
|
||||
static void free(Genode::Ram_dataspace_capability cap);
|
||||
};
|
||||
|
||||
#endif /* _X86__PLATFORM__LX_MEM_ */
|
@ -1,29 +0,0 @@
|
||||
/**
|
||||
* \brief Platform specific code
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2012-06-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _X86_32__PLATFORM_H_
|
||||
#define _X86_32__PLATFORM_H_
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
static inline
|
||||
void platform_execute(void *sp, void *func, void *arg)
|
||||
{
|
||||
asm volatile ("movl %2, 0(%0);"
|
||||
"movl %1, -0x4(%0);"
|
||||
"movl %0, %%esp;"
|
||||
"call *-4(%%esp);"
|
||||
: : "r" (sp), "r" (func), "r" (arg));
|
||||
}
|
||||
|
||||
#endif /* _X86_32__PLATFORM_H_ */
|
@ -1,34 +0,0 @@
|
||||
/**
|
||||
* \brief Platform specific code
|
||||
* \author Sebastian Sumpf
|
||||
* \author Alexander Boettcher
|
||||
* \date 2012-06-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _X86_64__PLATFORM_H_
|
||||
#define _X86_64__PLATFORM_H_
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
static inline
|
||||
void platform_execute(void *sp, void *func, void *arg)
|
||||
{
|
||||
asm volatile ("movq %0, %%rsp;" /* load stack pointer */
|
||||
"movq %%rsp, %%rbp;" /* caller stack frame (for GDB debugging) */
|
||||
"movq %0, -8(%%rbp);"
|
||||
"movq %1, -16(%%rbp);"
|
||||
"movq %2, -24(%%rbp);"
|
||||
"sub $24, %%rsp;" /* adjust to next stack frame */
|
||||
"movq %2, %%rdi;" /* 1st argument */
|
||||
"call *-16(%%rbp);" /* call func */
|
||||
: : "r" (sp), "r" (func), "r" (arg));
|
||||
}
|
||||
|
||||
#endif /* _X86_64__PLATFORM_H_ */
|
@ -18,11 +18,9 @@
|
||||
#include <input/root.h>
|
||||
#include <os/ring_buffer.h>
|
||||
|
||||
#include <extern_c_begin.h>
|
||||
#include <lx_emul.h>
|
||||
#include <extern_c_end.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#undef RELEASE
|
||||
|
||||
using namespace Genode;
|
||||
|
@ -20,362 +20,25 @@
|
||||
#include <util/string.h>
|
||||
|
||||
/* Local includes */
|
||||
#include "routine.h"
|
||||
#include "signal.h"
|
||||
#include "platform/lx_mem.h"
|
||||
|
||||
#include <extern_c_begin.h>
|
||||
#include "lx_emul.h"
|
||||
#include <extern_c_end.h>
|
||||
|
||||
#include <lx_kit/backend_alloc.h>
|
||||
#include <lx_kit/irq.h>
|
||||
#include <lx_kit/scheduler.h>
|
||||
#include <lx_kit/work.h>
|
||||
|
||||
|
||||
#include <lx_emul/impl/slab.h>
|
||||
|
||||
namespace Genode {
|
||||
class Slab_backend_alloc;
|
||||
class Slab_alloc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Back-end allocator for Genode's slab allocator
|
||||
*/
|
||||
class Genode::Slab_backend_alloc : public Genode::Allocator,
|
||||
public Genode::Rm_connection,
|
||||
public Genode::Region_map_client
|
||||
{
|
||||
private:
|
||||
|
||||
enum {
|
||||
VM_SIZE = 64 * 1024 * 1024, /* size of VM region to reserve */
|
||||
P_BLOCK_SIZE = 2 * 1024 * 1024, /* 2 MB physical contiguous */
|
||||
V_BLOCK_SIZE = P_BLOCK_SIZE * 2, /* 2 MB virtual used, 2 MB virtual left free to avoid that Allocator_avl merges virtual contiguous regions which are physically non-contiguous */
|
||||
ELEMENTS = VM_SIZE / V_BLOCK_SIZE /* MAX number of dataspaces in VM */
|
||||
};
|
||||
|
||||
addr_t _base; /* virt. base address */
|
||||
Genode::Cache_attribute _cached; /* non-/cached RAM */
|
||||
Ram_dataspace_capability _ds_cap[ELEMENTS]; /* dataspaces to put in VM */
|
||||
addr_t _ds_phys[ELEMENTS]; /* physical bases of dataspaces */
|
||||
int _index; /* current index in ds_cap */
|
||||
Allocator_avl _range; /* manage allocations */
|
||||
|
||||
bool _alloc_block()
|
||||
{
|
||||
if (_index == ELEMENTS) {
|
||||
PERR("Slab-backend exhausted!");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
_ds_cap[_index] = Backend_memory::alloc(P_BLOCK_SIZE, _cached);
|
||||
/* attach at index * V_BLOCK_SIZE */
|
||||
Region_map_client::attach_at(_ds_cap[_index], _index * V_BLOCK_SIZE, P_BLOCK_SIZE, 0);
|
||||
|
||||
/* lookup phys. address */
|
||||
_ds_phys[_index] = Dataspace_client(_ds_cap[_index]).phys_addr();
|
||||
} catch (...) { return false; }
|
||||
|
||||
/* return base + offset in VM area */
|
||||
addr_t block_base = _base + (_index * V_BLOCK_SIZE);
|
||||
++_index;
|
||||
|
||||
_range.add_range(block_base, P_BLOCK_SIZE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Slab_backend_alloc(Genode::Cache_attribute cached)
|
||||
:
|
||||
Region_map_client(Rm_connection::create(VM_SIZE)),
|
||||
_cached(cached), _index(0), _range(env()->heap())
|
||||
{
|
||||
/* reserver attach us, anywere */
|
||||
_base = env()->rm_session()->attach(dataspace());
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate
|
||||
*/
|
||||
bool alloc(size_t size, void **out_addr) override
|
||||
{
|
||||
bool done = _range.alloc(size, out_addr);
|
||||
|
||||
if (done)
|
||||
return done;
|
||||
|
||||
done = _alloc_block();
|
||||
if (!done) {
|
||||
PERR("Backend allocator exhausted\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return _range.alloc(size, out_addr);
|
||||
}
|
||||
|
||||
void free(void *addr) { _range.free(addr); }
|
||||
void free(void *addr, size_t size) override { _range.free(addr, size); }
|
||||
size_t overhead(size_t size) const override { return 0; }
|
||||
bool need_size_for_free() const override { return false; }
|
||||
|
||||
/**
|
||||
* Return phys address for given virtual addr.
|
||||
*/
|
||||
addr_t phys_addr(addr_t addr)
|
||||
{
|
||||
if (addr < _base || addr >= (_base + VM_SIZE))
|
||||
return ~0UL;
|
||||
|
||||
int index = (addr - _base) / V_BLOCK_SIZE;
|
||||
|
||||
/* physical base of dataspace */
|
||||
addr_t phys = _ds_phys[index];
|
||||
|
||||
if (!phys)
|
||||
return ~0UL;
|
||||
|
||||
/* add offset */
|
||||
phys += (addr - _base - (index * V_BLOCK_SIZE));
|
||||
return phys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate given physical address to virtual address
|
||||
*
|
||||
* \return virtual address, or 0 if no translation exists
|
||||
*/
|
||||
addr_t virt_addr(addr_t phys)
|
||||
{
|
||||
for (unsigned i = 0; i < ELEMENTS; i++) {
|
||||
if (_ds_cap[i].valid()
|
||||
&& phys >= _ds_phys[i] && phys < _ds_phys[i] + P_BLOCK_SIZE)
|
||||
return _base + i * V_BLOCK_SIZE + (phys - _ds_phys[i]);
|
||||
}
|
||||
|
||||
PWRN("virt_addr(0x%lx) - no translation", phys);
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr_t start() const { return _base; }
|
||||
addr_t end() const { return _base + VM_SIZE - 1; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Slab allocator using our back-end allocator
|
||||
*/
|
||||
class Genode::Slab_alloc : public Genode::Slab
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::size_t const _object_size;
|
||||
|
||||
static Genode::size_t _calculate_block_size(Genode::size_t object_size)
|
||||
{
|
||||
Genode::size_t const block_size = 16*object_size;
|
||||
return Genode::align_addr(block_size, 12);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Slab_alloc(Genode::size_t object_size, Slab_backend_alloc &allocator)
|
||||
:
|
||||
Slab(object_size, _calculate_block_size(object_size), 0, &allocator),
|
||||
_object_size(object_size)
|
||||
{ }
|
||||
|
||||
Genode::addr_t alloc()
|
||||
{
|
||||
Genode::addr_t result;
|
||||
return (Slab::alloc(_object_size, (void **)&result) ? result : 0);
|
||||
}
|
||||
|
||||
void free(void *ptr) { Slab::free(ptr, _object_size); }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Memory interface used used for Linux emulation
|
||||
*/
|
||||
class Malloc
|
||||
{
|
||||
private:
|
||||
|
||||
enum {
|
||||
SLAB_START_LOG2 = 3, /* 8 B */
|
||||
SLAB_STOP_LOG2 = 16, /* 64 KB */
|
||||
NUM_SLABS = (SLAB_STOP_LOG2 - SLAB_START_LOG2) + 1,
|
||||
};
|
||||
|
||||
typedef Genode::addr_t addr_t;
|
||||
typedef Genode::Slab_alloc Slab_alloc;
|
||||
typedef Genode::Slab_backend_alloc Slab_backend_alloc;
|
||||
|
||||
Slab_backend_alloc *_back_allocator;
|
||||
Slab_alloc *_allocator[NUM_SLABS];
|
||||
Genode::Cache_attribute _cached; /* cached or un-cached memory */
|
||||
addr_t _start; /* VM region of this allocator */
|
||||
addr_t _end;
|
||||
|
||||
/**
|
||||
* Set 'value' at 'addr'
|
||||
*/
|
||||
void _set_at(addr_t addr, addr_t value) { *((addr_t *)addr) = value; }
|
||||
|
||||
/**
|
||||
* Retrieve slab index belonging to given address
|
||||
*/
|
||||
unsigned _slab_index(Genode::addr_t **addr)
|
||||
{
|
||||
using namespace Genode;
|
||||
/* get index */
|
||||
addr_t index = *(*addr - 1);
|
||||
|
||||
/*
|
||||
* If index large, we use aligned memory, retrieve beginning of slab entry
|
||||
* and read index from there
|
||||
*/
|
||||
if (index > 32) {
|
||||
*addr = (addr_t *)*(*addr - 1);
|
||||
index = *(*addr - 1);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Malloc(Slab_backend_alloc *alloc, Genode::Cache_attribute cached)
|
||||
: _back_allocator(alloc), _cached(cached), _start(alloc->start()),
|
||||
_end(alloc->end())
|
||||
{
|
||||
/* init slab allocators */
|
||||
for (unsigned i = SLAB_START_LOG2; i <= SLAB_STOP_LOG2; i++)
|
||||
_allocator[i - SLAB_START_LOG2] = new (Genode::env()->heap())
|
||||
Slab_alloc(1U << i, *alloc);
|
||||
}
|
||||
|
||||
static unsigned long max_alloc() { return 1U << SLAB_STOP_LOG2; }
|
||||
|
||||
/**
|
||||
* Alloc in slabs
|
||||
*/
|
||||
void *alloc(Genode::size_t size, int align = 0, Genode::addr_t *phys = 0)
|
||||
{
|
||||
using namespace Genode;
|
||||
/* += slab index + aligment size */
|
||||
size += sizeof(addr_t) + (align > 2 ? (1 << align) : 0);
|
||||
|
||||
int msb = Genode::log2(size);
|
||||
|
||||
if (size > (1U << msb))
|
||||
msb++;
|
||||
|
||||
if (size < (1U << SLAB_START_LOG2))
|
||||
msb = SLAB_STOP_LOG2;
|
||||
|
||||
if (msb > SLAB_STOP_LOG2) {
|
||||
PERR("Slab too large %u reqested %zu cached %d", 1U << msb, size, _cached);
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr_t addr = _allocator[msb - SLAB_START_LOG2]->alloc();
|
||||
if (!addr) {
|
||||
PERR("Failed to get slab for %u", 1 << msb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_set_at(addr, msb - SLAB_START_LOG2);
|
||||
addr += sizeof(addr_t);
|
||||
|
||||
if (align > 2) {
|
||||
/* save */
|
||||
addr_t ptr = addr;
|
||||
addr_t align_val = (1U << align);
|
||||
addr_t align_mask = align_val - 1;
|
||||
/* align */
|
||||
addr = (addr + align_val) & ~align_mask;
|
||||
/* write start address before aligned address */
|
||||
_set_at(addr - sizeof(addr_t), ptr);
|
||||
}
|
||||
|
||||
if (phys)
|
||||
*phys = _back_allocator->phys_addr(addr);
|
||||
return (addr_t *)addr;
|
||||
}
|
||||
|
||||
void free(void const *a)
|
||||
{
|
||||
using namespace Genode;
|
||||
addr_t *addr = (addr_t *)a;
|
||||
|
||||
unsigned nr = _slab_index(&addr);
|
||||
_allocator[nr]->free((void *)(addr - 1));
|
||||
}
|
||||
|
||||
void *alloc_large(size_t size)
|
||||
{
|
||||
void *addr;
|
||||
if (!_back_allocator->alloc(size, &addr)) {
|
||||
PERR("Large back end allocation failed (%zu bytes)", size);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void free_large(void *ptr)
|
||||
{
|
||||
_back_allocator->free(ptr);
|
||||
}
|
||||
|
||||
Genode::addr_t phys_addr(void *a)
|
||||
{
|
||||
return _back_allocator->phys_addr((addr_t)a);
|
||||
}
|
||||
|
||||
Genode::addr_t virt_addr(Genode::addr_t phys)
|
||||
{
|
||||
return _back_allocator->virt_addr(phys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Belongs given address to this allocator
|
||||
*/
|
||||
bool inside(addr_t const addr) const { return (addr > _start) && (addr <= _end); }
|
||||
|
||||
/**
|
||||
* Cached memory allocator
|
||||
*/
|
||||
static Malloc *mem()
|
||||
{
|
||||
static Slab_backend_alloc _b(Genode::CACHED);
|
||||
static Malloc _m(&_b, Genode::CACHED);
|
||||
return &_m;
|
||||
}
|
||||
|
||||
/**
|
||||
* DMA allocator
|
||||
*/
|
||||
static Malloc *dma()
|
||||
{
|
||||
static Slab_backend_alloc _b(Genode::UNCACHED);
|
||||
static Malloc _m(&_b, Genode::UNCACHED);
|
||||
return &_m;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void lx_printf(char const *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
Genode::vprintf(fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
|
||||
void lx_vprintf(char const *fmt, va_list va) {
|
||||
Genode::vprintf(fmt, va); }
|
||||
unsigned long jiffies;
|
||||
void backtrace() { }
|
||||
|
||||
|
||||
/***********************
|
||||
@ -386,15 +49,15 @@ void lx_vprintf(char const *fmt, va_list va) {
|
||||
* Actually not atomic, for now
|
||||
*/
|
||||
|
||||
unsigned int atomic_read(atomic_t *p) { return *(volatile int *)p; }
|
||||
unsigned int atomic_read(atomic_t *p) { return p->v; }
|
||||
|
||||
void atomic_inc(atomic_t *v) { (*(volatile int *)v)++; }
|
||||
void atomic_dec(atomic_t *v) { (*(volatile int *)v)--; }
|
||||
void atomic_inc(atomic_t *v) { v->v++; }
|
||||
void atomic_dec(atomic_t *v) { v->v--; }
|
||||
|
||||
void atomic_add(int i, atomic_t *v) { (*(volatile int *)v) += i; }
|
||||
void atomic_sub(int i, atomic_t *v) { (*(volatile int *)v) -= i; }
|
||||
void atomic_add(int i, atomic_t *v) { v->v += i; }
|
||||
void atomic_sub(int i, atomic_t *v) { v->v -= i; }
|
||||
|
||||
void atomic_set(atomic_t *p, unsigned int v) { (*(volatile int *)p) = v; }
|
||||
void atomic_set(atomic_t *p, unsigned int v) { p->v = v; }
|
||||
|
||||
|
||||
/*************************************
|
||||
@ -403,58 +66,13 @@ void atomic_set(atomic_t *p, unsigned int v) { (*(volatile int *)p) = v; }
|
||||
|
||||
void *dma_malloc(size_t size)
|
||||
{
|
||||
return Malloc::dma()->alloc_large(size);
|
||||
return Lx::Malloc::dma().alloc_large(size);
|
||||
}
|
||||
|
||||
|
||||
void dma_free(void *ptr)
|
||||
{
|
||||
Malloc::dma()->free_large(ptr);
|
||||
}
|
||||
|
||||
|
||||
void *kmalloc(size_t size, gfp_t flags)
|
||||
{
|
||||
void *addr = flags & GFP_NOIO ? Malloc::dma()->alloc(size) : Malloc::mem()->alloc(size);
|
||||
|
||||
unsigned long a = (unsigned long)addr;
|
||||
|
||||
if (a & 0x3)
|
||||
PERR("Unaligned kmalloc %lx", a);
|
||||
|
||||
//PDBG("Kmalloc: [%lx-%lx) from %p", a, a + size, __builtin_return_address(0));
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
void *kzalloc(size_t size, gfp_t flags)
|
||||
{
|
||||
void *addr = kmalloc(size, flags);
|
||||
if (addr)
|
||||
Genode::memset(addr, 0, size);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
void *kcalloc(size_t n, size_t size, gfp_t flags)
|
||||
{
|
||||
if (size != 0 && n > ~0UL / size)
|
||||
return 0;
|
||||
|
||||
return kzalloc(n * size, flags);
|
||||
}
|
||||
|
||||
void kfree(const void *p)
|
||||
{
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
if (Malloc::mem()->inside((Genode::addr_t)p))
|
||||
Malloc::mem()->free(p);
|
||||
|
||||
if (Malloc::dma()->inside((Genode::addr_t)p))
|
||||
Malloc::dma()->free(p);
|
||||
Lx::Malloc::dma().free_large(ptr);
|
||||
}
|
||||
|
||||
|
||||
@ -588,7 +206,11 @@ int scnprintf(char *buf, size_t size, const char *fmt, ...)
|
||||
return sc.len();
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2) { return Genode::strcmp(s1, s2); }
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
printk("%s:%d from %p\n", __func__, __LINE__, __builtin_return_address(0));
|
||||
return Genode::strcmp(s1, s2);
|
||||
}
|
||||
size_t strlen(const char *s) { return Genode::strlen(s); }
|
||||
|
||||
|
||||
@ -621,14 +243,6 @@ size_t strlcpy(char *dest, const char *src, size_t size)
|
||||
}
|
||||
|
||||
|
||||
void *kmemdup(const void *src, size_t len, gfp_t gfp)
|
||||
{
|
||||
void *ptr = kmalloc(len, gfp);
|
||||
memcpy(ptr, src, len);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
void *memscan(void *addr, int c, size_t size)
|
||||
{
|
||||
unsigned char* p = (unsigned char *)addr;
|
||||
@ -652,75 +266,28 @@ int ilog2(u32 n) { return Genode::log2(n); }
|
||||
** linux/slab.h **
|
||||
********************/
|
||||
|
||||
struct kmem_cache
|
||||
{
|
||||
const char *name; /* cache name */
|
||||
unsigned size; /* object size */
|
||||
};
|
||||
|
||||
|
||||
struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align,
|
||||
unsigned long falgs, void (*ctor)(void *))
|
||||
{
|
||||
lx_log(DEBUG_SLAB, "\"%s\" obj_size=%zd", name, size);
|
||||
|
||||
if (size > Malloc::max_alloc()) {
|
||||
PERR("kmem_cache_create: slab size > %lu", Malloc::max_alloc());
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct kmem_cache *cache;
|
||||
|
||||
if (!name) {
|
||||
printk("kmem_cache name reqeuired\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cache = (struct kmem_cache *)kmalloc(sizeof(*cache), 0);
|
||||
if (!cache) {
|
||||
printk("No memory for slab cache\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cache->name = name;
|
||||
cache->size = size;
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
|
||||
void kmem_cache_destroy(struct kmem_cache *cache)
|
||||
{
|
||||
lx_log(DEBUG_SLAB, "\"%s\"", cache->name);
|
||||
kfree(cache);
|
||||
destroy(Genode::env()->heap(), cache);
|
||||
}
|
||||
|
||||
|
||||
void *kmem_cache_zalloc(struct kmem_cache *cache, gfp_t flags)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
lx_log(DEBUG_SLAB, "\"%s\" flags=%x", cache->name, flags);
|
||||
|
||||
ret = kzalloc(cache->size, flags);
|
||||
ret = kmem_cache_alloc(cache, flags);
|
||||
memset(ret, 0, cache->size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void kmem_cache_free(struct kmem_cache *cache, void *objp)
|
||||
{
|
||||
lx_log(DEBUG_SLAB, "\"%s\" (%p)", cache->name, objp);
|
||||
kfree(objp);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
** asm-generic/io.h **
|
||||
**********************/
|
||||
|
||||
void *phys_to_virt(unsigned long address)
|
||||
{
|
||||
return (void *)Malloc::dma()->virt_addr(address);
|
||||
return (void *)Lx::Malloc::dma().virt_addr(address);
|
||||
}
|
||||
|
||||
|
||||
@ -847,6 +414,22 @@ int dev_set_drvdata(struct device *dev, void *data)
|
||||
|
||||
const char *dev_name(const struct device *dev) { return dev->name; }
|
||||
|
||||
/*******************************
|
||||
** asm-generic/bitops/find.h **
|
||||
*******************************/
|
||||
|
||||
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
|
||||
unsigned long offset)
|
||||
{
|
||||
unsigned long i = offset / BITS_PER_LONG;
|
||||
offset -= (i * BITS_PER_LONG);
|
||||
|
||||
for (; offset < size; offset++)
|
||||
if (addr[i] & (1UL << offset))
|
||||
return offset;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
long find_next_zero_bit_le(const void *addr,
|
||||
unsigned long size, unsigned long offset)
|
||||
@ -944,30 +527,7 @@ int fls(int x)
|
||||
** linux/delay.h **
|
||||
*******************/
|
||||
|
||||
static Timer::Connection _timer;
|
||||
|
||||
|
||||
void udelay(unsigned long usecs)
|
||||
{
|
||||
_timer.usleep(usecs);
|
||||
}
|
||||
|
||||
|
||||
void msleep(unsigned int msecs) { _timer.msleep(msecs); }
|
||||
void mdelay(unsigned long msecs) { msleep(msecs); }
|
||||
|
||||
|
||||
/*********************
|
||||
** linux/jiffies.h **
|
||||
*********************/
|
||||
|
||||
enum { JIFFIES_TICK_MS = 1000 / HZ };
|
||||
|
||||
unsigned long msecs_to_jiffies(const unsigned int m) { return m / JIFFIES_TICK_MS; }
|
||||
unsigned int jiffies_to_msecs(const unsigned long j) { return j * JIFFIES_TICK_MS; }
|
||||
|
||||
long time_after_eq(long a, long b) { return (a - b) >= 0; }
|
||||
long time_after(long a, long b) { return (b - a) < 0; }
|
||||
#include <lx_emul/impl/delay.h>
|
||||
|
||||
|
||||
/*********
|
||||
@ -1016,13 +576,13 @@ void *dma_pool_alloc(struct dma_pool *d, gfp_t f, dma_addr_t *dma)
|
||||
void dma_pool_free(struct dma_pool *d, void *vaddr, dma_addr_t a)
|
||||
{
|
||||
lx_log(DEBUG_DMA, "free: addr %p, size: %zx", vaddr, d->size);
|
||||
Malloc::dma()->free(vaddr);
|
||||
Lx::Malloc::dma().free(vaddr);
|
||||
}
|
||||
|
||||
|
||||
void *dma_alloc_coherent(struct device *, size_t size, dma_addr_t *dma, gfp_t)
|
||||
{
|
||||
void *addr = Malloc::dma()->alloc(size, PAGE_SHIFT, dma);
|
||||
void *addr = Lx::Malloc::dma().alloc(size, PAGE_SHIFT, dma);
|
||||
|
||||
if (!addr)
|
||||
return 0;
|
||||
@ -1036,7 +596,7 @@ void *dma_alloc_coherent(struct device *, size_t size, dma_addr_t *dma, gfp_t)
|
||||
void dma_free_coherent(struct device *, size_t size, void *vaddr, dma_addr_t)
|
||||
{
|
||||
lx_log(DEBUG_DMA, "free: addr %p, size: %zx", vaddr, size);
|
||||
Malloc::dma()->free(vaddr);
|
||||
Lx::Malloc::dma().free(vaddr);
|
||||
}
|
||||
|
||||
|
||||
@ -1049,7 +609,7 @@ dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr,
|
||||
enum dma_data_direction dir,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
dma_addr_t phys = (dma_addr_t)Malloc::dma()->phys_addr(ptr);
|
||||
dma_addr_t phys = (dma_addr_t)Lx::Malloc::dma().phys_addr(ptr);
|
||||
|
||||
if (phys == ~0UL)
|
||||
PERR("translation virt->phys %p->%lx failed, return ip %p", ptr, phys,
|
||||
@ -1079,23 +639,16 @@ int dma_map_sg_attrs(struct device *dev, struct scatterlist *sg,
|
||||
*********************/
|
||||
|
||||
struct task_struct *kthread_run(int (*fn)(void *), void *arg, const char *n, ...)
|
||||
{
|
||||
lx_log(DEBUG_THREAD, "Run %s", n);
|
||||
Routine::add(fn, arg, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct task_struct *kthread_create(int (*threadfn)(void *data),
|
||||
void *data,
|
||||
const char namefmt[], ...)
|
||||
{
|
||||
/*
|
||||
* This is just called for delayed device scanning (see
|
||||
* 'drivers/usb/storage/usb.c')
|
||||
*/
|
||||
lx_log(DEBUG_THREAD, "Create %s", namefmt);
|
||||
Routine::add(threadfn, data, namefmt);
|
||||
lx_log(DEBUG_THREAD, "Run %s", n);
|
||||
|
||||
new (Genode::env()->heap()) Lx::Task((void (*)(void *))fn, arg, n,
|
||||
Lx::Task::PRIORITY_2,
|
||||
Lx::scheduler());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1152,6 +705,15 @@ struct resource * devm_request_mem_region(struct device *dev, resource_size_t st
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** linux/smp.h **
|
||||
*****************/
|
||||
|
||||
int smp_call_function_single(int cpu, smp_call_func_t func, void *info,
|
||||
int wait) { func(info); return 0; }
|
||||
|
||||
|
||||
/****************
|
||||
** Networking **
|
||||
****************/
|
||||
@ -1275,44 +837,6 @@ int rounddown_pow_of_two(u32 n)
|
||||
}
|
||||
|
||||
|
||||
/******************
|
||||
** linux/wait.h **
|
||||
******************/
|
||||
|
||||
void init_waitqueue_head(wait_queue_head_t *q)
|
||||
{
|
||||
q->q = 0;
|
||||
}
|
||||
|
||||
|
||||
void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
|
||||
{
|
||||
if (q->q) {
|
||||
PERR("Non-empty wait queue");
|
||||
return;
|
||||
}
|
||||
|
||||
q->q = wait;
|
||||
}
|
||||
|
||||
|
||||
void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
|
||||
{
|
||||
if (q->q != wait) {
|
||||
PERR("Remove unkown element from wait queue");
|
||||
return;
|
||||
}
|
||||
|
||||
q->q = 0;
|
||||
}
|
||||
|
||||
|
||||
int waitqueue_active(wait_queue_head_t *q)
|
||||
{
|
||||
return q->q ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** linux/nls.h **
|
||||
*****************/
|
||||
@ -1389,3 +913,116 @@ int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
|
||||
{
|
||||
return raw_notifier_call_chain((struct raw_notifier_head *)nh, val, v);
|
||||
}
|
||||
|
||||
|
||||
/*******************
|
||||
** linux/timer.h **
|
||||
*******************/
|
||||
|
||||
#include <lx_emul/impl/timer.h>
|
||||
#include <lx_emul/impl/sched.h>
|
||||
|
||||
signed long schedule_timeout_uninterruptible(signed long timeout)
|
||||
{
|
||||
lx_log(DEBUG_COMPLETION, "%ld\n", timeout);
|
||||
schedule_timeout(timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
** linux/completion.h **
|
||||
************************/
|
||||
|
||||
#include <lx_emul/impl/completion.h>
|
||||
|
||||
|
||||
static void _completion_timeout(unsigned long t)
|
||||
{
|
||||
Lx::Task *task = (Lx::Task *)t;
|
||||
task->unblock();
|
||||
}
|
||||
|
||||
|
||||
long __wait_completion(struct completion *work, unsigned long timeout)
|
||||
{
|
||||
timer_list t;
|
||||
unsigned long j = timeout ? jiffies + timeout : 0;
|
||||
|
||||
if (timeout) {
|
||||
setup_timer(&t, _completion_timeout, (unsigned long)Lx::scheduler().current());
|
||||
mod_timer(&t, timeout);
|
||||
}
|
||||
|
||||
while (!work->done) {
|
||||
|
||||
if (j && j <= jiffies) {
|
||||
lx_log(1, "timeout jiffies %lu", jiffies);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Lx::Task *task = Lx::scheduler().current();
|
||||
work->task = (void *)task;
|
||||
task->block_and_schedule();
|
||||
}
|
||||
|
||||
if (timeout)
|
||||
del_timer(&t);
|
||||
|
||||
work->done = 0;
|
||||
|
||||
return j ? j - jiffies : 1;
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/workqueue.h **
|
||||
***********************/
|
||||
|
||||
#include <lx_emul/impl/work.h>
|
||||
|
||||
|
||||
void tasklet_init(struct tasklet_struct *t, void (*f)(unsigned long), unsigned long d)
|
||||
{
|
||||
t->func = f;
|
||||
t->data = d;
|
||||
}
|
||||
|
||||
|
||||
void tasklet_schedule(struct tasklet_struct *tasklet)
|
||||
{
|
||||
Lx::Work *lx_work = (Lx::Work *)tasklet_wq->task;
|
||||
lx_work->schedule_tasklet(tasklet);
|
||||
lx_work->unblock();
|
||||
}
|
||||
|
||||
|
||||
void tasklet_hi_schedule(struct tasklet_struct *tasklet)
|
||||
{
|
||||
tasklet_schedule(tasklet);
|
||||
}
|
||||
|
||||
|
||||
struct workqueue_struct *create_singlethread_workqueue(char const *name)
|
||||
{
|
||||
workqueue_struct *wq = (workqueue_struct *)kzalloc(sizeof(workqueue_struct), 0);
|
||||
Lx::Work *work = Lx::Work::alloc_work_queue(Genode::env()->heap(), name);
|
||||
wq->task = (void *)work;
|
||||
|
||||
return wq;
|
||||
}
|
||||
|
||||
|
||||
struct workqueue_struct *alloc_workqueue(const char *fmt, unsigned int flags,
|
||||
int max_active, ...)
|
||||
{
|
||||
return create_singlethread_workqueue(fmt);
|
||||
}
|
||||
|
||||
|
||||
/******************
|
||||
** linux/wait.h **
|
||||
******************/
|
||||
|
||||
#include <lx_emul/impl/wait.h>
|
||||
|
||||
|
@ -23,8 +23,14 @@
|
||||
|
||||
/* Local */
|
||||
#include <platform.h>
|
||||
#include <routine.h>
|
||||
#include <signal.h>
|
||||
#include <lx_emul.h>
|
||||
|
||||
#include <lx_kit/irq.h>
|
||||
#include <lx_kit/scheduler.h>
|
||||
#include <lx_kit/timer.h>
|
||||
#include <lx_kit/work.h>
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
@ -43,16 +49,22 @@ extern "C" void module_raw_driver_init();
|
||||
|
||||
extern "C" void start_input_service(void *ep, void *services);
|
||||
|
||||
Routine *Routine::_current = 0;
|
||||
Routine *Routine::_dead = 0;
|
||||
Routine *Routine::_main = 0;
|
||||
bool Routine::_all = false;
|
||||
struct workqueue_struct *system_power_efficient_wq;
|
||||
struct workqueue_struct *system_wq;
|
||||
struct workqueue_struct *tasklet_wq;
|
||||
|
||||
void breakpoint() { PDBG("BREAK"); }
|
||||
|
||||
extern "C" int stdout_write(const char *);
|
||||
|
||||
static void init(Services *services)
|
||||
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.
|
||||
@ -79,34 +91,40 @@ static void init(Services *services)
|
||||
module_wacom_driver_init();
|
||||
}
|
||||
|
||||
/* host controller */
|
||||
platform_hcd_init(services);
|
||||
|
||||
/* storage */
|
||||
if (services->stor)
|
||||
module_usb_storage_driver_init();
|
||||
|
||||
/* host controller */
|
||||
platform_hcd_init(services);
|
||||
|
||||
while (true)
|
||||
Lx::scheduler().current()->block_and_schedule();
|
||||
}
|
||||
|
||||
|
||||
void start_usb_driver(Server::Entrypoint &ep)
|
||||
{
|
||||
Services services;
|
||||
static Services services;
|
||||
|
||||
if (services.hid)
|
||||
start_input_service(&ep.rpc_ep(), &services);
|
||||
|
||||
Timer::init(ep);
|
||||
Irq::init(ep);
|
||||
Event::init(ep);
|
||||
Storage::init(ep);
|
||||
Nic::init(ep);
|
||||
|
||||
if (services.raw)
|
||||
Raw::init(ep, services.raw_report_device_list);
|
||||
|
||||
Routine::add(0, 0, "Main", true);
|
||||
Routine::make_main_current();
|
||||
init(&services);
|
||||
Lx::Scheduler &sched = Lx::scheduler();
|
||||
Lx::Timer &timer = Lx::timer(&ep, &jiffies);
|
||||
|
||||
Routine::main();
|
||||
Lx::Irq::irq(&ep, Genode::env()->heap());
|
||||
Lx::Work::work_queue(Genode::env()->heap());
|
||||
|
||||
|
||||
static Lx::Task linux(run_linux, &services, "linux", Lx::Task::PRIORITY_0,
|
||||
Lx::scheduler());
|
||||
|
||||
Lx::scheduler().schedule();
|
||||
}
|
||||
|
@ -19,11 +19,11 @@
|
||||
#include <util/xml_node.h>
|
||||
#include <os/config.h>
|
||||
|
||||
#include <extern_c_begin.h>
|
||||
#include <lx_emul.h>
|
||||
#include <lx_emul/extern_c_begin.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/usbnet.h>
|
||||
#include <extern_c_end.h>
|
||||
#include <lx_emul/extern_c_end.h>
|
||||
|
||||
#include <usb_nic_component.h>
|
||||
#include "signal.h"
|
||||
|
@ -1,623 +0,0 @@
|
||||
/*
|
||||
* \brief Emulate 'pci_dev' structure
|
||||
* \author Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
* \date 2012-04-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode base includes */
|
||||
#include <base/object_pool.h>
|
||||
#include <io_mem_session/client.h>
|
||||
#include <irq_session/connection.h>
|
||||
#include <ram_session/client.h>
|
||||
#include <util/retry.h>
|
||||
|
||||
/* Genode os includes */
|
||||
#include <io_port_session/client.h>
|
||||
#include <platform_session/connection.h>
|
||||
#include <platform_device/client.h>
|
||||
#include <util/volatile_object.h>
|
||||
|
||||
/* Linux includes */
|
||||
#include <extern_c_begin.h>
|
||||
#include <lx_emul.h>
|
||||
#include <extern_c_end.h>
|
||||
#include <platform/lx_mem.h>
|
||||
|
||||
struct bus_type pci_bus_type;
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
class Io_port
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
unsigned _base = 0;
|
||||
unsigned _size = 0;
|
||||
Io_port_session_capability _cap;
|
||||
Lazy_volatile_object<Io_port_session_client> _port;
|
||||
|
||||
bool _valid(unsigned port) {
|
||||
return _cap.valid() && port >= _base && port < _base + _size; }
|
||||
|
||||
public:
|
||||
|
||||
~Io_port()
|
||||
{
|
||||
if (_cap.valid())
|
||||
_port.destruct();
|
||||
}
|
||||
|
||||
void session(unsigned base, unsigned size, Io_port_session_capability cap)
|
||||
{
|
||||
_base = base;
|
||||
_size = size;
|
||||
_cap = cap;
|
||||
_port.construct(_cap);
|
||||
}
|
||||
|
||||
template<typename POD>
|
||||
bool out(unsigned port, POD val)
|
||||
{
|
||||
if (!_valid(port))
|
||||
return false;
|
||||
|
||||
switch (sizeof(POD)) {
|
||||
case 1: _port->outb(port, val); break;
|
||||
case 2: _port->outw(port, val); break;
|
||||
case 4: _port->outl(port, val); break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename POD>
|
||||
bool in(unsigned port, POD *val)
|
||||
{
|
||||
if (!_valid(port))
|
||||
return false;;
|
||||
|
||||
switch (sizeof(POD)) {
|
||||
case 1: *val = _port->inb(port); break;
|
||||
case 2: *val = _port->inw(port); break;
|
||||
case 4: *val = _port->inl(port); break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Virtual IRQ number (monotonically increasing)
|
||||
*/
|
||||
static unsigned virq_num()
|
||||
{
|
||||
static unsigned instance = 128;
|
||||
return ++instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan PCI bus and probe for HCDs
|
||||
*/
|
||||
class Pci_driver : public Genode::List<Pci_driver>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
pci_driver *_drv; /* Linux PCI driver */
|
||||
Platform::Device_capability _cap; /* PCI cap */
|
||||
pci_device_id const *_id; /* matched id for this driver */
|
||||
Io_port _port;
|
||||
|
||||
public:
|
||||
|
||||
pci_dev *_dev; /* Linux PCI device */
|
||||
|
||||
private:
|
||||
|
||||
/* offset used in PCI config space */
|
||||
enum Pci_config { IRQ = 0x3c, REV = 0x8, CMD = 0x4 };
|
||||
|
||||
/**
|
||||
* Fill Linux device informations
|
||||
*/
|
||||
void _setup_pci_device()
|
||||
{
|
||||
using namespace Platform;
|
||||
|
||||
Device_client client(_cap);
|
||||
uint8_t bus, dev, func;
|
||||
client.bus_address(&bus, &dev, &func);
|
||||
|
||||
_dev = new (Genode::env()->heap()) pci_dev;
|
||||
_dev->devfn = ((uint16_t)bus << 8) | (0xff & PCI_DEVFN(dev, func));
|
||||
_dev->vendor = client.vendor_id();
|
||||
_dev->device = client.device_id();
|
||||
_dev->class_ = client.class_code();
|
||||
_dev->revision = client.config_read(REV, Device::ACCESS_8BIT);
|
||||
_dev->dev.driver = &_drv->driver;
|
||||
|
||||
/* dummy dma mask used to mark device as DMA capable */
|
||||
static u64 dma_mask = ~(u64)0;
|
||||
_dev->dev.dma_mask = &dma_mask;
|
||||
_dev->dev.coherent_dma_mask = ~0;
|
||||
|
||||
/*
|
||||
* We initialize the IRQ line with a virtual number to ensure that
|
||||
* each device gets a unique number and, hence, requests its
|
||||
* associated IRQ capability at the platform driver. Consequently,
|
||||
* we give a away the questionable option to implement IRQ sharing
|
||||
* locally and leave it to the platform driver, which just uses
|
||||
* signalling anyway.
|
||||
*/
|
||||
_dev->irq = virq_num();
|
||||
|
||||
/* hide ourselfs in bus structure */
|
||||
_dev->bus = (struct pci_bus *)this;
|
||||
|
||||
/* setup resources */
|
||||
bool io = false;
|
||||
for (unsigned i = 0; i < Device::NUM_RESOURCES; i++) {
|
||||
Device::Resource res = client.resource(i);
|
||||
_dev->resource[i].start = res.base();
|
||||
_dev->resource[i].end = res.base() + res.size() - 1;
|
||||
|
||||
unsigned flags = 0;
|
||||
if (res.type() == Device::Resource::IO) flags |= IORESOURCE_IO;
|
||||
if (res.type() == Device::Resource::MEMORY) flags |= IORESOURCE_MEM;
|
||||
_dev->resource[i].flags = flags;
|
||||
|
||||
/* request port I/O session */
|
||||
if (res.type() == Device::Resource::IO) {
|
||||
uint8_t virt_bar = client.phys_bar_to_virt(i);
|
||||
_port.session(res.base(), res.size(), client.io_port(virt_bar));
|
||||
io = true;
|
||||
lx_log(DEBUG_PCI, "I/O [%u-%u)",
|
||||
res.base(), res.base() + res.size());
|
||||
}
|
||||
|
||||
/* request I/O memory (write combined) */
|
||||
if (res.type() == Device::Resource::MEMORY)
|
||||
lx_log(DEBUG_PCI, "I/O memory [%x-%x)", res.base(),
|
||||
res.base() + res.size());
|
||||
}
|
||||
|
||||
/* enable bus master and io bits */
|
||||
uint16_t cmd = client.config_read(CMD, Device::ACCESS_16BIT);
|
||||
cmd |= io ? 0x1 : 0;
|
||||
|
||||
/* enable bus master */
|
||||
cmd |= 0x4;
|
||||
client.config_write(CMD, cmd, Device::ACCESS_16BIT);
|
||||
|
||||
_drivers().insert(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Probe device with driver
|
||||
*/
|
||||
bool _probe()
|
||||
{
|
||||
_setup_pci_device();
|
||||
|
||||
if (!_drv->probe(_dev, _id))
|
||||
return true;
|
||||
|
||||
PERR("Probe failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Platform::Device::Access_size _access_size(T t)
|
||||
{
|
||||
switch (sizeof(T))
|
||||
{
|
||||
case 1:
|
||||
return Platform::Device::ACCESS_8BIT;
|
||||
case 2:
|
||||
return Platform::Device::ACCESS_16BIT;
|
||||
default:
|
||||
return Platform::Device::ACCESS_32BIT;
|
||||
}
|
||||
}
|
||||
|
||||
static Genode::List<Pci_driver> & _drivers()
|
||||
{
|
||||
static Genode::List<Pci_driver> _list;
|
||||
return _list;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Pci_driver(pci_driver *drv, Platform::Device_capability cap,
|
||||
pci_device_id const * id)
|
||||
: _drv(drv), _cap(cap), _id(id), _dev(0)
|
||||
{
|
||||
if (!_probe())
|
||||
throw -1;
|
||||
}
|
||||
|
||||
~Pci_driver()
|
||||
{
|
||||
if (!_dev)
|
||||
return;
|
||||
|
||||
_drivers().remove(this);
|
||||
|
||||
destroy(Genode::env()->heap(), _dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read/write data from/to config space
|
||||
*/
|
||||
template <typename T>
|
||||
void config_read(unsigned int devfn, T *val)
|
||||
{
|
||||
Platform::Device_client client(_cap);
|
||||
*val = client.config_read(devfn, _access_size(*val));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void config_write(unsigned int devfn, T val)
|
||||
{
|
||||
Platform::Device_client client(_cap);
|
||||
client.config_write(devfn, val, _access_size(val));
|
||||
}
|
||||
|
||||
static Genode::Irq_session_capability irq_cap(unsigned irq)
|
||||
{
|
||||
for (Pci_driver *d = _drivers().first(); d; d = d->next()) {
|
||||
if (d->_dev && d->_dev->irq != irq)
|
||||
continue;
|
||||
|
||||
Platform::Device_client client(d->_cap);
|
||||
return client.irq(0);
|
||||
}
|
||||
|
||||
return Genode::Irq_session_capability();
|
||||
}
|
||||
|
||||
static Genode::Io_mem_session_capability io_mem(resource_size_t phys) {
|
||||
|
||||
for (Pci_driver *d = _drivers().first(); d; d = d->next()) {
|
||||
if (!d->_dev)
|
||||
continue;
|
||||
|
||||
unsigned bar = 0;
|
||||
for (; bar < PCI_ROM_RESOURCE; bar++) {
|
||||
if ((pci_resource_flags(d->_dev, bar) & IORESOURCE_MEM) &&
|
||||
(pci_resource_start(d->_dev, bar) == phys))
|
||||
break;
|
||||
}
|
||||
if (bar >= PCI_ROM_RESOURCE)
|
||||
continue;
|
||||
|
||||
Platform::Device_client client(d->_cap);
|
||||
return client.io_mem(bar);
|
||||
}
|
||||
|
||||
PERR("Device using i/o memory of address %zx is unknown", phys);
|
||||
return Genode::Io_mem_session_capability();
|
||||
}
|
||||
|
||||
template <typename POD, bool READ = true>
|
||||
static POD port_io(unsigned port, POD val = 0)
|
||||
{
|
||||
for (Pci_driver *d = _drivers().first(); d; d = d->next()) {
|
||||
if (!d->_dev)
|
||||
continue;
|
||||
|
||||
if (READ && d->_port.in<POD>(port, &val))
|
||||
return val;
|
||||
else if (!READ && d->_port.out<POD>(port, val))
|
||||
return (POD)~0;
|
||||
}
|
||||
|
||||
return (POD)~0;
|
||||
}
|
||||
};
|
||||
|
||||
/********************************
|
||||
** Backend memory definitions **
|
||||
********************************/
|
||||
|
||||
struct Memory_object_base : Genode::Object_pool<Memory_object_base>::Entry
|
||||
{
|
||||
Memory_object_base(Genode::Ram_dataspace_capability cap)
|
||||
: Genode::Object_pool<Memory_object_base>::Entry(cap) {}
|
||||
virtual ~Memory_object_base() {};
|
||||
|
||||
virtual void free() = 0;
|
||||
|
||||
Genode::Ram_dataspace_capability ram_cap()
|
||||
{
|
||||
using namespace Genode;
|
||||
return reinterpret_cap_cast<Ram_dataspace>(cap());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Ram_object : Memory_object_base
|
||||
{
|
||||
Ram_object(Genode::Ram_dataspace_capability cap)
|
||||
: Memory_object_base(cap) {}
|
||||
|
||||
void free();
|
||||
};
|
||||
|
||||
|
||||
struct Dma_object : Memory_object_base
|
||||
{
|
||||
Dma_object(Genode::Ram_dataspace_capability cap)
|
||||
: Memory_object_base(cap) {}
|
||||
|
||||
void free();
|
||||
};
|
||||
|
||||
|
||||
/*********************
|
||||
** Linux interface **
|
||||
*********************/
|
||||
|
||||
static Platform::Connection pci;
|
||||
static Genode::Object_pool<Memory_object_base> memory_pool;
|
||||
|
||||
int pci_register_driver(struct pci_driver *drv)
|
||||
{
|
||||
lx_log(DEBUG_PCI, "DRIVER name: %s", drv->name);
|
||||
drv->driver.name = drv->name;
|
||||
|
||||
pci_device_id const *id = drv->id_table;
|
||||
if (!id)
|
||||
return -ENODEV;
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
bool found = false;
|
||||
|
||||
while (id->class_ || id->class_mask || id->class_) {
|
||||
|
||||
if (id->class_ == (unsigned)PCI_ANY_ID) {
|
||||
lx_log(DEBUG_PCI, "Skipping PCI_ANY_ID device class");
|
||||
id++;
|
||||
continue;
|
||||
}
|
||||
|
||||
Genode::env()->parent()->upgrade(pci.cap(), "ram_quota=4096");
|
||||
|
||||
Platform::Device_capability cap = pci.first_device(id->class_,
|
||||
id->class_mask);
|
||||
while (cap.valid()) {
|
||||
|
||||
if (DEBUG_PCI) {
|
||||
uint8_t bus, dev, func;
|
||||
Platform::Device_client client(cap);
|
||||
client.bus_address(&bus, &dev, &func);
|
||||
lx_log(DEBUG_PCI, "bus: %x dev: %x func: %x", bus, dev, func);
|
||||
}
|
||||
|
||||
Pci_driver *pci_drv = 0;
|
||||
try {
|
||||
/* probe device */
|
||||
pci_drv = new (env()->heap()) Pci_driver(drv, cap, id);
|
||||
pci.on_destruction(Platform::Connection::KEEP_OPEN);
|
||||
found = true;
|
||||
|
||||
} catch (Platform::Device::Quota_exceeded) {
|
||||
Genode::env()->parent()->upgrade(pci.cap(), "ram_quota=4096");
|
||||
continue;
|
||||
} catch (...) {
|
||||
destroy(env()->heap(), pci_drv);
|
||||
pci_drv = 0;
|
||||
}
|
||||
|
||||
Platform::Device_capability free_up = cap;
|
||||
|
||||
try {
|
||||
cap = pci.next_device(cap, id->class_, id->class_mask);
|
||||
} catch (Platform::Session::Out_of_metadata) {
|
||||
Genode::env()->parent()->upgrade(pci.cap(), "ram_quota=4096");
|
||||
cap = pci.next_device(cap, id->class_, id->class_mask);
|
||||
}
|
||||
|
||||
if (!pci_drv)
|
||||
pci.release_device(free_up);
|
||||
}
|
||||
id++;
|
||||
}
|
||||
|
||||
return found ? 0 : -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
size_t pci_resource_start(struct pci_dev *dev, unsigned bar)
|
||||
{
|
||||
if (bar >= DEVICE_COUNT_RESOURCE)
|
||||
return 0;
|
||||
|
||||
return dev->resource[bar].start;
|
||||
}
|
||||
|
||||
|
||||
size_t pci_resource_len(struct pci_dev *dev, unsigned bar)
|
||||
{
|
||||
size_t start = pci_resource_start(dev, bar);
|
||||
|
||||
if (!start)
|
||||
return 0;
|
||||
|
||||
return (dev->resource[bar].end - start) + 1;
|
||||
}
|
||||
|
||||
|
||||
unsigned int pci_resource_flags(struct pci_dev *dev, unsigned bar)
|
||||
{
|
||||
if (bar >= DEVICE_COUNT_RESOURCE)
|
||||
return 0;
|
||||
|
||||
return dev->resource[bar].flags;
|
||||
}
|
||||
|
||||
|
||||
int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int, int where, u8 *val)
|
||||
{
|
||||
Pci_driver *drv = (Pci_driver *)bus;
|
||||
drv->config_read(where, val);
|
||||
lx_log(DEBUG_PCI, "READ %p: where: %x val: %x", drv, where, *val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int pci_bus_read_config_word(struct pci_bus *bus, unsigned int, int where, u16 *val)
|
||||
{
|
||||
Pci_driver *drv = (Pci_driver *)bus;
|
||||
drv->config_read(where, val);
|
||||
lx_log(DEBUG_PCI, "READ %p: where: %x val: %x", drv, where, *val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int pci_bus_write_config_word(struct pci_bus *bus, unsigned int, int where, u16 val)
|
||||
{
|
||||
Pci_driver *drv = (Pci_driver *)bus;
|
||||
lx_log(DEBUG_PCI, "WRITE %p: where: %x val: %x", drv, where, val);
|
||||
drv->config_write(where, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int pci_bus_write_config_byte(struct pci_bus *bus, unsigned int, int where, u8 val)
|
||||
{
|
||||
Pci_driver *drv = (Pci_driver *)bus;
|
||||
lx_log(DEBUG_PCI, "WRITE %p: where: %x val: %x", drv, where, val);
|
||||
drv->config_write(where, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const char *pci_name(const struct pci_dev *pdev)
|
||||
{
|
||||
/* simply return driver name */
|
||||
return "dummy";
|
||||
}
|
||||
|
||||
|
||||
void Ram_object::free() { Genode::env()->ram_session()->free(ram_cap()); }
|
||||
|
||||
|
||||
void Dma_object::free() { pci.free_dma_buffer(ram_cap()); }
|
||||
|
||||
|
||||
Genode::Ram_dataspace_capability
|
||||
Backend_memory::alloc(Genode::addr_t size, Genode::Cache_attribute cached)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Memory_object_base *o;
|
||||
Genode::Ram_dataspace_capability cap;
|
||||
if (cached == CACHED) {
|
||||
cap = env()->ram_session()->alloc(size);
|
||||
o = new (env()->heap()) Ram_object(cap);
|
||||
} else {
|
||||
size_t donate = size;
|
||||
cap = Genode::retry<Platform::Session::Out_of_metadata>(
|
||||
[&] () { return pci.alloc_dma_buffer(size); },
|
||||
[&] () {
|
||||
char quota[32];
|
||||
Genode::snprintf(quota, sizeof(quota), "ram_quota=%zd",
|
||||
donate);
|
||||
Genode::env()->parent()->upgrade(pci.cap(), quota);
|
||||
donate = donate * 2 > size ? 4096 : donate * 2;
|
||||
});
|
||||
o = new (env()->heap()) Dma_object(cap);
|
||||
}
|
||||
|
||||
memory_pool.insert(o);
|
||||
return cap;
|
||||
}
|
||||
|
||||
|
||||
void Backend_memory::free(Genode::Ram_dataspace_capability cap)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Memory_object_base *object;
|
||||
auto lambda = [&] (Memory_object_base *o) {
|
||||
object = o;
|
||||
|
||||
if (object) {
|
||||
object->free();
|
||||
memory_pool.remove(object);
|
||||
}
|
||||
};
|
||||
memory_pool.apply(cap, lambda);
|
||||
destroy(env()->heap(), object);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
** asm-generic/io.h **
|
||||
**********************/
|
||||
|
||||
void outb(u8 value, u32 port) { Pci_driver::port_io<u8, false>(port, value); }
|
||||
void outw(u16 value, u32 port) { Pci_driver::port_io<u16, false>(port, value); }
|
||||
void outl(u32 value, u32 port) { Pci_driver::port_io<u32, false>(port, value); }
|
||||
|
||||
u8 inb(u32 port) { return Pci_driver::port_io<u8>(port); }
|
||||
u16 inw(u32 port) { return Pci_driver::port_io<u16>(port); }
|
||||
u32 inl(u32 port) { return Pci_driver::port_io<u32>(port); }
|
||||
|
||||
|
||||
/*****************************************
|
||||
** Platform specific irq cap discovery **
|
||||
*****************************************/
|
||||
|
||||
Genode::Irq_session_capability platform_irq_activate(int irq)
|
||||
{
|
||||
return Pci_driver::irq_cap(irq);
|
||||
}
|
||||
|
||||
/******************
|
||||
** MMIO regions **
|
||||
******************/
|
||||
|
||||
class Mem_range : public Genode::Io_mem_session_client
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Io_mem_dataspace_capability _ds;
|
||||
Genode::addr_t _vaddr;
|
||||
|
||||
public:
|
||||
|
||||
Mem_range(Genode::addr_t base,
|
||||
Genode::Io_mem_session_capability io_cap)
|
||||
:
|
||||
Io_mem_session_client(io_cap), _ds(dataspace()), _vaddr(0UL)
|
||||
{
|
||||
_vaddr = Genode::env()->rm_session()->attach(_ds);
|
||||
_vaddr |= base & 0xfffUL;
|
||||
}
|
||||
|
||||
Genode::addr_t vaddr() const { return _vaddr; }
|
||||
};
|
||||
|
||||
|
||||
void *ioremap(resource_size_t phys_addr, unsigned long size)
|
||||
{
|
||||
Mem_range * io_mem = new (Genode::env()->heap()) Mem_range(phys_addr, Pci_driver::io_mem(phys_addr));
|
||||
if (io_mem->vaddr())
|
||||
return (void *)io_mem->vaddr();
|
||||
|
||||
PERR("Failed to request I/O memory: [%zx,%lx)", phys_addr,
|
||||
phys_addr + size);
|
||||
|
||||
return nullptr;
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
#include <usb_session/rpc_object.h>
|
||||
#include <util/list.h>
|
||||
|
||||
#include <extern_c_begin.h>
|
||||
#include <lx_emul.h>
|
||||
#include <lx_emul/extern_c_begin.h>
|
||||
#include <linux/usb.h>
|
||||
#include "raw.h"
|
||||
#include "lx_emul.h"
|
||||
#include <extern_c_end.h>
|
||||
#include <lx_emul/extern_c_end.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <lx_kit/scheduler.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern "C" int usb_set_configuration(struct usb_device *dev, int configuration);
|
||||
@ -109,6 +111,11 @@ struct Device : List<Device>::Element
|
||||
|
||||
Genode::snprintf(buf, sizeof(buf), "0x%4x", dev);
|
||||
xml.attribute("dev", buf);
|
||||
|
||||
usb_interface *iface = d->interface(0);
|
||||
Genode::snprintf(buf, sizeof(buf), "0x%02x",
|
||||
iface->cur_altsetting->desc.bInterfaceClass);
|
||||
xml.attribute("class", buf);
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -157,7 +164,7 @@ class Usb::Worker
|
||||
Session::Tx::Sink *_sink;
|
||||
Device *_device = nullptr;
|
||||
Signal_context_capability _sigh_ready;
|
||||
Routine *_routine = nullptr;
|
||||
Lx::Task *_task = nullptr;
|
||||
unsigned _p_in_flight = 0;
|
||||
bool _device_ready = false;
|
||||
|
||||
@ -453,8 +460,9 @@ class Usb::Worker
|
||||
|
||||
void _wait_for_device()
|
||||
{
|
||||
_wait_event(_device);
|
||||
_wait_event(_device->udev->actconfig);
|
||||
wait_queue_head_t wait;
|
||||
_wait_event(wait, _device);
|
||||
_wait_event(wait, _device->udev->actconfig);
|
||||
|
||||
if (_sigh_ready.valid())
|
||||
Signal_transmitter(_sigh_ready).submit(1);
|
||||
@ -469,24 +477,20 @@ class Usb::Worker
|
||||
{
|
||||
/* wait for device to become ready */
|
||||
init_completion(&_packet_avail);
|
||||
|
||||
_wait_for_device();
|
||||
|
||||
while (true) {
|
||||
wait_for_completion(&_packet_avail);
|
||||
|
||||
_dispatch();
|
||||
Routine::schedule_all();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static int run(void *worker)
|
||||
static void run(void *worker)
|
||||
{
|
||||
Worker *w = static_cast<Worker *>(worker);
|
||||
w->_wait();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Worker(Session::Tx::Sink *sink)
|
||||
@ -495,17 +499,23 @@ class Usb::Worker
|
||||
|
||||
void start()
|
||||
{
|
||||
if (!_routine) {
|
||||
_routine = Routine::add(run, this, "worker");
|
||||
Routine::schedule_all();
|
||||
if (!_task) {
|
||||
_task = new (Genode::env()->heap()) Lx::Task(run, this, "raw_worker",
|
||||
Lx::Task::PRIORITY_2,
|
||||
Lx::scheduler());
|
||||
if (!Lx::scheduler().active()) {
|
||||
Lx::scheduler().schedule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
if (_routine)
|
||||
Routine::remove(_routine);
|
||||
_routine = nullptr;
|
||||
if (_task) {
|
||||
Lx::scheduler().remove(_task);
|
||||
destroy(Genode::env()->heap(), _task);
|
||||
_task = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void packet_avail() { ::complete(&_packet_avail); }
|
||||
@ -551,6 +561,7 @@ class Usb::Session_component : public Session_rpc_object,
|
||||
void _receive(unsigned)
|
||||
{
|
||||
_worker.packet_avail();
|
||||
Lx::scheduler().schedule();
|
||||
}
|
||||
|
||||
public:
|
||||
@ -852,6 +863,12 @@ int raw_notify(struct notifier_block *nb, unsigned long action, void *data)
|
||||
{
|
||||
struct usb_device *udev = (struct usb_device*)data;
|
||||
|
||||
if (verbose_raw)
|
||||
PDBG("RAW: %s vendor: %04x product: %04x\n",
|
||||
action == USB_DEVICE_ADD ? "Add" : "Remove",
|
||||
udev->descriptor.idVendor, udev->descriptor.idProduct);
|
||||
|
||||
|
||||
switch (action) {
|
||||
|
||||
case USB_DEVICE_ADD:
|
||||
|
@ -1,300 +0,0 @@
|
||||
/*
|
||||
* \brief Signal context for completions and events
|
||||
* \author Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
* \date 2012-05-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <extern_c_begin.h>
|
||||
#include <lx_emul.h>
|
||||
#include <extern_c_end.h>
|
||||
|
||||
static Signal_helper *_signal = 0;
|
||||
|
||||
/**
|
||||
* Context for events
|
||||
*/
|
||||
class Event_context
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Signal_rpc_member<Event_context> _dispatcher;
|
||||
|
||||
void _handle(unsigned) {
|
||||
Routine::schedule_all(); }
|
||||
|
||||
Event_context()
|
||||
: _dispatcher(_signal->ep(), *this, &Event_context::_handle) {
|
||||
_signal->sender().context(_dispatcher); }
|
||||
|
||||
public:
|
||||
|
||||
static Event_context *e()
|
||||
{
|
||||
static Event_context _e;
|
||||
return &_e;
|
||||
}
|
||||
|
||||
void submit() {
|
||||
_signal->sender().submit(); }
|
||||
|
||||
char const *debug() { return "Event_context"; }
|
||||
};
|
||||
|
||||
|
||||
void Event::init(Server::Entrypoint &ep) {
|
||||
_signal = new (Genode::env()->heap()) Signal_helper(ep); }
|
||||
|
||||
|
||||
/**
|
||||
* Delayed work
|
||||
*/
|
||||
class Work : public Genode::List<Work>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
void *_work;
|
||||
|
||||
enum Type { NORMAL, DELAYED, TASKLET } _type;
|
||||
|
||||
static Genode::List<Work> *_list()
|
||||
{
|
||||
static Genode::List<Work> _l;
|
||||
return &_l;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Work(delayed_work *work) : _work(work), _type(DELAYED) { }
|
||||
Work(work_struct *work) : _work(work), _type(NORMAL) { }
|
||||
Work(tasklet_struct *work) : _work(work), _type(TASKLET) { }
|
||||
|
||||
template <typename WORK>
|
||||
static void schedule(WORK *work)
|
||||
{
|
||||
if (work->pending)
|
||||
return;
|
||||
|
||||
work->pending = 1;
|
||||
_list()->insert(new (Genode::env()->heap()) Work(work));
|
||||
}
|
||||
|
||||
static void exec()
|
||||
{
|
||||
while (_list()->first()) {
|
||||
Work *w = _list()->first();
|
||||
_list()->remove(w);
|
||||
|
||||
switch (w->_type) {
|
||||
|
||||
case NORMAL:
|
||||
{
|
||||
work_struct *work = static_cast<work_struct *>(w->_work);
|
||||
work->func(work);
|
||||
work->pending = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case DELAYED:
|
||||
{
|
||||
delayed_work *work = static_cast<delayed_work *>(w->_work);
|
||||
work->work.func(&(work)->work);
|
||||
work->pending = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case TASKLET:
|
||||
{
|
||||
tasklet_struct *tasklet = static_cast<tasklet_struct *>(w->_work);
|
||||
tasklet->func(tasklet->data);
|
||||
tasklet->pending = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
destroy(Genode::env()->heap(), w);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/************************
|
||||
** linux/completion.h **
|
||||
************************/
|
||||
|
||||
void __wake_up() { Routine::schedule_all(); }
|
||||
|
||||
|
||||
void __wait_event()
|
||||
{
|
||||
/* schedule work first */
|
||||
Work::exec();
|
||||
|
||||
/* schedule other routines or wait for signals */
|
||||
Service_handler::s()->process();
|
||||
}
|
||||
|
||||
|
||||
void init_completion(struct completion *work)
|
||||
{
|
||||
lx_log(DEBUG_COMPLETION, "New completion %p", work);
|
||||
work->done = 0;
|
||||
}
|
||||
|
||||
|
||||
void complete(struct completion *work)
|
||||
{
|
||||
lx_log(DEBUG_COMPLETION, "%p", work);
|
||||
work->done = 1;
|
||||
|
||||
/* send signal */
|
||||
Event_context::e()->submit();
|
||||
}
|
||||
|
||||
|
||||
void complete_and_exit(struct completion *work, long code)
|
||||
{
|
||||
lx_log(DEBUG_COMPLETION, "%p", work);
|
||||
complete(work);
|
||||
Routine::remove();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void __wait_completion(struct completion *work)
|
||||
{
|
||||
while (!work->done)
|
||||
__wait_event();
|
||||
|
||||
work->done = 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned long
|
||||
__wait_completion_timeout(struct completion *work, unsigned long timeout)
|
||||
{
|
||||
unsigned long _j = jiffies + timeout;
|
||||
while (!work->done) {
|
||||
__wait_event();
|
||||
|
||||
if (_j <= jiffies) {
|
||||
lx_log(1, "Timeout");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
work->done = 0;
|
||||
|
||||
return _j - jiffies;
|
||||
}
|
||||
|
||||
|
||||
unsigned long wait_for_completion_timeout(struct completion *work,
|
||||
unsigned long timeout)
|
||||
{
|
||||
lx_log(DEBUG_COMPLETION, "%p state: %u timeout: %lu", work, work->done, timeout);
|
||||
return __wait_completion_timeout(work, timeout);
|
||||
}
|
||||
|
||||
|
||||
int wait_for_completion_interruptible(struct completion *work)
|
||||
{
|
||||
lx_log(DEBUG_COMPLETION, "%p state: %u", work, work->done);
|
||||
|
||||
__wait_completion(work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long wait_for_completion_interruptible_timeout(struct completion *work,
|
||||
unsigned long timeout)
|
||||
{
|
||||
lx_log(DEBUG_COMPLETION, "%p state: %u", work, work->done);
|
||||
__wait_completion(work);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void wait_for_completion(struct completion *work)
|
||||
{
|
||||
lx_log(DEBUG_COMPLETION, "%p state: %u", work, work->done);
|
||||
__wait_completion(work);
|
||||
}
|
||||
|
||||
|
||||
/*******************
|
||||
** linux/timer.h **
|
||||
*******************/
|
||||
|
||||
signed long schedule_timeout_uninterruptible(signed long timeout)
|
||||
{
|
||||
lx_log(DEBUG_COMPLETION, "%ld\n", timeout);
|
||||
__wait_event();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int wake_up_process(struct task_struct *tsk)
|
||||
{
|
||||
Routine::schedule_all();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/workquque.h **
|
||||
***********************/
|
||||
|
||||
int schedule_delayed_work(struct delayed_work *work, unsigned long delay)
|
||||
{
|
||||
Work::schedule(work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int schedule_work(struct work_struct *work)
|
||||
{
|
||||
Work::schedule(work);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
bool queue_delayed_work(struct workqueue_struct *wq,
|
||||
struct delayed_work *dwork, unsigned long delay)
|
||||
{
|
||||
Work::schedule(dwork);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/interrupt.h **
|
||||
***********************/
|
||||
|
||||
void tasklet_init(struct tasklet_struct *t, void (*f)(unsigned long), unsigned long d)
|
||||
{
|
||||
t->func = f;
|
||||
t->data = d;
|
||||
t->pending = 0;
|
||||
}
|
||||
|
||||
|
||||
void tasklet_schedule(struct tasklet_struct *tasklet)
|
||||
{
|
||||
Work::schedule(tasklet);
|
||||
}
|
||||
|
||||
|
||||
void tasklet_hi_schedule(struct tasklet_struct *tasklet)
|
||||
{
|
||||
/*
|
||||
* High priority, execute immediately
|
||||
*/
|
||||
tasklet->func(tasklet->data);
|
||||
}
|
@ -1,193 +0,0 @@
|
||||
/*
|
||||
* \brief Signal context for IRQ's
|
||||
* \author Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
* \date 2012-05-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <irq_session/client.h>
|
||||
|
||||
#include <extern_c_begin.h>
|
||||
#include <lx_emul.h>
|
||||
#include <extern_c_end.h>
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
|
||||
/* our local incarnation of sender and receiver */
|
||||
static Signal_helper *_signal = 0;
|
||||
|
||||
/**
|
||||
* This contains the Linux-driver handlers
|
||||
*/
|
||||
struct Irq_handler : Genode::List<Irq_handler>::Element
|
||||
{
|
||||
void *dev; /* Linux device */
|
||||
irq_handler_t handler; /* Linux handler */
|
||||
|
||||
Irq_handler(void *dev, irq_handler_t handler)
|
||||
: dev(dev), handler(handler) { }
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Signal context for IRQs
|
||||
*/
|
||||
class Irq_context : public Genode::List<Irq_context>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
typedef Genode::List<Irq_context>::Element LE;
|
||||
|
||||
unsigned int _irq; /* IRQ number */
|
||||
Genode::List<Irq_handler> _handler_list; /* List of registered handlers */
|
||||
Genode::Signal_rpc_member<Irq_context> _dispatcher;
|
||||
Genode::Irq_session_capability _irq_cap;
|
||||
Genode::Irq_session_client _irq_client;
|
||||
|
||||
static Genode::List<Irq_context> *_list()
|
||||
{
|
||||
static Genode::List<Irq_context> _l;
|
||||
return &_l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find context for given IRQ number
|
||||
*/
|
||||
static Irq_context *_find_ctx(unsigned int irq)
|
||||
{
|
||||
|
||||
for (Irq_context *i = _list()->first(); i; i = i->LE::next())
|
||||
if (i->_irq == irq)
|
||||
return i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call one IRQ handler
|
||||
*/
|
||||
inline bool _handle_one(Irq_handler *h)
|
||||
{
|
||||
bool handled = false;
|
||||
|
||||
/*
|
||||
* It might be that the next interrupt triggers right after the
|
||||
* device has acknowledged the IRQ. To reduce per-IRQ context
|
||||
* switches, we merge up to 'MAX_MERGED_IRQS' calls to the
|
||||
* interrupt handler.
|
||||
*/
|
||||
enum { MAX_MERGED_IRQS = 8 };
|
||||
for (unsigned i = 0; i < MAX_MERGED_IRQS; i++) {
|
||||
if (h->handler(_irq, h->dev) != IRQ_HANDLED)
|
||||
break;
|
||||
|
||||
handled = true;
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call all handlers registered for this context
|
||||
*/
|
||||
bool _handle()
|
||||
{
|
||||
bool handled = false;
|
||||
|
||||
/* report IRQ to all clients */
|
||||
for (Irq_handler *h = _handler_list.first(); h; h = h->next())
|
||||
if ((handled = _handle_one(h))) {
|
||||
lx_log(DEBUG_IRQ, "IRQ: %u ret: %u h: %p dev: %p", _irq, handled, h->handler, h->dev);
|
||||
break;
|
||||
}
|
||||
|
||||
/* ack interrupt */
|
||||
_irq_client.ack_irq();
|
||||
|
||||
if (handled)
|
||||
Routine::schedule_all();
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
void _handle(unsigned) { _handle(); }
|
||||
|
||||
public:
|
||||
|
||||
Irq_context(unsigned int irq)
|
||||
: _irq(irq),
|
||||
_dispatcher(_signal->ep(), *this, &Irq_context::_handle),
|
||||
_irq_cap(platform_irq_activate(_irq)),
|
||||
_irq_client(_irq_cap)
|
||||
{
|
||||
if (!_irq_cap.valid()) {
|
||||
PERR("Interrupt %d attach failed", irq);
|
||||
return;
|
||||
}
|
||||
|
||||
_irq_client.sigh(_dispatcher);
|
||||
_irq_client.ack_irq();
|
||||
|
||||
_list()->insert(this);
|
||||
}
|
||||
|
||||
|
||||
const char *debug() { return "Irq_context"; }
|
||||
|
||||
/**
|
||||
* Request an IRQ
|
||||
*/
|
||||
static void request_irq(unsigned int irq, irq_handler_t handler, void *dev)
|
||||
{
|
||||
Irq_handler *h = new(Genode::env()->heap()) Irq_handler(dev, handler);
|
||||
Irq_context *ctx = _find_ctx(irq);
|
||||
|
||||
/* if this IRQ is not registered */
|
||||
if (!ctx)
|
||||
ctx = new (Genode::env()->heap()) Irq_context(irq);
|
||||
|
||||
/* register Linux handler */
|
||||
ctx->_handler_list.insert(h);
|
||||
}
|
||||
|
||||
static bool check_irq()
|
||||
{
|
||||
bool handled = false;
|
||||
for (Irq_context *i = _list()->first(); i; i = i->LE::next())
|
||||
handled |= i->_handle();
|
||||
|
||||
return handled;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Irq::init(Server::Entrypoint &ep) {
|
||||
_signal = new (Genode::env()->heap()) Signal_helper(ep); }
|
||||
|
||||
|
||||
void Irq::check_irq()
|
||||
{
|
||||
Irq_context::check_irq();
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/interrupt.h **
|
||||
***********************/
|
||||
|
||||
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
|
||||
const char *name, void *dev)
|
||||
{
|
||||
lx_log(DEBUG_IRQ, "Request irq %u handler %p", irq, handler);
|
||||
Irq_context::request_irq(irq, handler, dev);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,395 +0,0 @@
|
||||
/*
|
||||
* \brief Signal context for timer events
|
||||
* \author Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
* \date 2012-05-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/env.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/tslab.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <util/volatile_object.h>
|
||||
|
||||
/*
|
||||
* The Genode headers must be included before any Linux header. Otherwise,
|
||||
* the 'SUCCESS' macro defined in scsi/scsi_host.h collides with Genode's
|
||||
* 'Rpc_exception_code::SUCCESS' enum value.
|
||||
*/
|
||||
#include "signal.h"
|
||||
#include "list.h"
|
||||
|
||||
#include <extern_c_begin.h>
|
||||
#include <lx_emul.h>
|
||||
#include <extern_c_end.h>
|
||||
|
||||
unsigned long jiffies;
|
||||
|
||||
|
||||
static void handler(void *timer);
|
||||
|
||||
namespace Lx {
|
||||
class Timer;
|
||||
}
|
||||
|
||||
static int run_timer(void *);
|
||||
|
||||
/**
|
||||
* Lx::Timer
|
||||
*/
|
||||
class Lx::Timer
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Context encapsulates a regular linux timer_list
|
||||
*/
|
||||
struct Context : public Lx::List<Context>::Element
|
||||
{
|
||||
enum { INVALID_TIMEOUT = ~0UL };
|
||||
enum Type { LIST, HR };
|
||||
|
||||
Type type;
|
||||
void *timer;
|
||||
bool pending { false };
|
||||
unsigned long timeout { INVALID_TIMEOUT }; /* absolute in jiffies */
|
||||
bool programmed { false };
|
||||
|
||||
Context(struct timer_list *timer) : type(LIST), timer(timer) { }
|
||||
Context(struct hrtimer *timer) : type(HR), timer(timer) { }
|
||||
|
||||
void expires(unsigned long e)
|
||||
{
|
||||
if (type == LIST)
|
||||
static_cast<timer_list *>(timer)->expires = e;
|
||||
}
|
||||
|
||||
void function()
|
||||
{
|
||||
switch (type) {
|
||||
case LIST:
|
||||
{
|
||||
timer_list *t = static_cast<timer_list *>(timer);
|
||||
if (t->function)
|
||||
t->function(t->data);
|
||||
}
|
||||
break;
|
||||
|
||||
case HR:
|
||||
{
|
||||
hrtimer *t = static_cast<hrtimer *>(timer);
|
||||
if (t->function)
|
||||
t->function(t);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
::Timer::Connection _timer_conn;
|
||||
Lx::List<Context> _list;
|
||||
Routine *_timer_task = Routine::add(run_timer, nullptr, "timer");
|
||||
Genode::Signal_rpc_member<Lx::Timer> _dispatcher;
|
||||
Genode::Tslab<Context, 32 * sizeof(Context)> _timer_alloc;
|
||||
|
||||
public:
|
||||
|
||||
bool ready { true };
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Lookup local timer
|
||||
*/
|
||||
Context *_find_context(void const *timer)
|
||||
{
|
||||
for (Context *c = _list.first(); c; c = c->next())
|
||||
if (c->timer == timer)
|
||||
return c;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Program the first timer in the list
|
||||
*
|
||||
* The first timer is programmed if the 'programmed' flag was not set
|
||||
* before. The second timer is flagged as not programmed as
|
||||
* 'Timer::trigger_once' invalidates former registered one-shot
|
||||
* timeouts.
|
||||
*/
|
||||
void _program_first_timer()
|
||||
{
|
||||
Context *ctx = _list.first();
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
if (ctx->programmed)
|
||||
return;
|
||||
|
||||
/* calculate relative microseconds for trigger */
|
||||
unsigned long us = ctx->timeout > jiffies ?
|
||||
jiffies_to_msecs(ctx->timeout - jiffies) * 1000 : 0;
|
||||
_timer_conn.trigger_once(us);
|
||||
|
||||
ctx->programmed = true;
|
||||
|
||||
/* possibly programmed successor must be reprogrammed later */
|
||||
if (Context *next = ctx->next())
|
||||
next->programmed = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule timer
|
||||
*
|
||||
* Add the context to the scheduling list depending on its timeout
|
||||
* and reprogram the first timer.
|
||||
*/
|
||||
void _schedule_timer(Context *ctx, unsigned long expires)
|
||||
{
|
||||
_list.remove(ctx);
|
||||
|
||||
ctx->timeout = expires;
|
||||
ctx->pending = true;
|
||||
ctx->programmed = false;
|
||||
/*
|
||||
* Also write the timeout value to the expires field in
|
||||
* struct timer_list because the checks
|
||||
* it directly.
|
||||
*/
|
||||
ctx->expires(expires);
|
||||
|
||||
Context *c;
|
||||
for (c = _list.first(); c; c = c->next())
|
||||
if (ctx->timeout <= c->timeout)
|
||||
break;
|
||||
_list.insert_before(ctx, c);
|
||||
|
||||
_program_first_timer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle trigger_once signal
|
||||
*/
|
||||
void _handle(unsigned)
|
||||
{
|
||||
ready = true;
|
||||
Routine::schedule_all();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Timer(Server::Entrypoint &ep)
|
||||
:
|
||||
_dispatcher(ep, *this, &Lx::Timer::_handle),
|
||||
_timer_alloc(Genode::env()->heap())
|
||||
{
|
||||
_timer_conn.sigh(_dispatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new linux timer
|
||||
*/
|
||||
template <typename TIMER>
|
||||
void add(TIMER *timer)
|
||||
{
|
||||
Context *t = new (&_timer_alloc) Context(timer);
|
||||
_list.append(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete linux timer
|
||||
*/
|
||||
int del(void *timer)
|
||||
{
|
||||
Context *ctx = _find_context(timer);
|
||||
|
||||
/**
|
||||
* If the timer expired it was already cleaned up after its
|
||||
* execution.
|
||||
*/
|
||||
if (!ctx)
|
||||
return 0;
|
||||
|
||||
int rv = ctx->timeout != Context::INVALID_TIMEOUT ? 1 : 0;
|
||||
|
||||
_list.remove(ctx);
|
||||
destroy(&_timer_alloc, ctx);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial scheduling of linux timer
|
||||
*/
|
||||
int schedule(void *timer, unsigned long expires)
|
||||
{
|
||||
Context *ctx = _find_context(timer);
|
||||
if (!ctx) {
|
||||
PERR("schedule unknown timer %p", timer);
|
||||
return -1; /* XXX better use 0 as rv? */
|
||||
}
|
||||
|
||||
/*
|
||||
* If timer was already active return 1, otherwise 0. The return
|
||||
* value is needed by mod_timer().
|
||||
*/
|
||||
int rv = ctx->timeout != Context::INVALID_TIMEOUT ? 1 : 0;
|
||||
|
||||
_schedule_timer(ctx, expires);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule next linux timer
|
||||
*/
|
||||
void schedule_next() { _program_first_timer(); }
|
||||
|
||||
/**
|
||||
* Check if the timer is currently pending
|
||||
*/
|
||||
bool pending(void const *timer)
|
||||
{
|
||||
Context *ctx = _find_context(timer);
|
||||
if (!ctx) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ctx->pending;
|
||||
}
|
||||
|
||||
Context *find(void const *timer) {
|
||||
return _find_context(timer); }
|
||||
|
||||
/**
|
||||
* Update jiffie counter
|
||||
*/
|
||||
void update_jiffies()
|
||||
{
|
||||
jiffies = msecs_to_jiffies(_timer_conn.elapsed_ms());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get first timer context
|
||||
*/
|
||||
Context* first() { return _list.first(); }
|
||||
};
|
||||
|
||||
|
||||
Genode::Lazy_volatile_object<Lx::Timer> _lx_timer;
|
||||
|
||||
|
||||
void Timer::init(Server::Entrypoint &ep)
|
||||
{
|
||||
_lx_timer.construct(ep);
|
||||
|
||||
/* initialize value explicitly */
|
||||
jiffies = 0UL;
|
||||
}
|
||||
|
||||
void Timer::update_jiffies()
|
||||
{
|
||||
_lx_timer->update_jiffies();
|
||||
}
|
||||
|
||||
static int run_timer(void *)
|
||||
{
|
||||
while (1) {
|
||||
_wait_event(_lx_timer->ready);
|
||||
|
||||
while (Lx::Timer::Context *ctx = _lx_timer->first()) {
|
||||
if (ctx->timeout > jiffies)
|
||||
break;
|
||||
|
||||
ctx->function();
|
||||
_lx_timer->del(ctx->timer);
|
||||
}
|
||||
|
||||
_lx_timer->ready = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*******************
|
||||
** linux/timer.h **
|
||||
*******************/
|
||||
|
||||
void init_timer(struct timer_list *timer) { }
|
||||
|
||||
|
||||
int mod_timer(struct timer_list *timer, unsigned long expires)
|
||||
{
|
||||
if (!_lx_timer->find(timer))
|
||||
_lx_timer->add(timer);
|
||||
|
||||
return _lx_timer->schedule(timer, expires);
|
||||
}
|
||||
|
||||
|
||||
void setup_timer(struct timer_list *timer,void (*function)(unsigned long),
|
||||
unsigned long data)
|
||||
{
|
||||
timer->function = function;
|
||||
timer->data = data;
|
||||
}
|
||||
|
||||
|
||||
int timer_pending(const struct timer_list * timer)
|
||||
{
|
||||
bool pending = _lx_timer->pending(timer);
|
||||
lx_log(DEBUG_TIMER, "Pending %p %u", timer, pending);
|
||||
return pending;
|
||||
}
|
||||
|
||||
|
||||
int del_timer(struct timer_list *timer)
|
||||
{
|
||||
lx_log(DEBUG_TIMER, "Delete timer %p", timer);
|
||||
int rv = _lx_timer->del(timer);
|
||||
_lx_timer->schedule_next();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/*********************
|
||||
** linux/hrtimer.h **
|
||||
*********************/
|
||||
|
||||
void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode) { }
|
||||
|
||||
|
||||
int hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
|
||||
unsigned long delta_ns, const enum hrtimer_mode mode)
|
||||
{
|
||||
unsigned long expires = tim.tv64 / (NSEC_PER_MSEC * HZ);
|
||||
|
||||
if (!_lx_timer->find(timer))
|
||||
_lx_timer->add(timer);
|
||||
|
||||
lx_log(DEBUG_TIMER, "HR: e: %lu j %lu", jiffies, expires);
|
||||
return _lx_timer->schedule(timer, expires);
|
||||
}
|
||||
|
||||
|
||||
int hrtimer_cancel(struct hrtimer *timer)
|
||||
{
|
||||
int rv = _lx_timer->del(timer);
|
||||
_lx_timer->schedule_next();
|
||||
|
||||
return rv;
|
||||
}
|
@ -12,11 +12,7 @@
|
||||
*/
|
||||
|
||||
#include <os/attached_io_mem_dataspace.h>
|
||||
|
||||
#include <lx/extern_c_begin.h>
|
||||
#include <lx_emul.h>
|
||||
#include <lx/extern_c_end.h>
|
||||
|
||||
|
||||
|
||||
#define to_platform_driver(drv) (container_of((drv), struct platform_driver, \
|
||||
@ -198,20 +194,20 @@ void platform_set_drvdata(struct platform_device *pdev, void *data)
|
||||
** asm-generic/io.h **
|
||||
**********************/
|
||||
|
||||
void *_ioremap(resource_size_t phys_addr, unsigned long size, int wc)
|
||||
void *_ioremap(phys_addr_t phys_addr, unsigned long size, int wc)
|
||||
{
|
||||
try {
|
||||
Genode::Attached_io_mem_dataspace *ds = new(Genode::env()->heap())
|
||||
Genode::Attached_io_mem_dataspace(phys_addr, size, !!wc);
|
||||
return ds->local_addr<void>();
|
||||
} catch (...) {
|
||||
panic("Failed to request I/O memory: [%zx,%lx)", phys_addr, phys_addr + size);
|
||||
panic("Failed to request I/O memory: [%lx,%lx)", phys_addr, phys_addr + size);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *ioremap(resource_size_t offset, unsigned long size)
|
||||
void *ioremap(phys_addr_t offset, unsigned long size)
|
||||
{
|
||||
return _ioremap(offset, size, 0);
|
||||
}
|
||||
|
45
repos/dde_linux/src/lib/usb/spec/arm/platform_generic.cc
Normal file
45
repos/dde_linux/src/lib/usb/spec/arm/platform_generic.cc
Normal file
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* \brief ARM specific implemenations used on all SOCs
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2016-04-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/env.h>
|
||||
|
||||
#include <lx_emul/irq.h>
|
||||
|
||||
#include <lx_kit/backend_alloc.h>
|
||||
#include <lx_kit/irq.h>
|
||||
|
||||
|
||||
/****************************
|
||||
** lx_kit/backend_alloc.h **
|
||||
****************************/
|
||||
|
||||
Genode::Ram_dataspace_capability
|
||||
Lx::backend_alloc(Genode::addr_t size, Genode::Cache_attribute cached) {
|
||||
return Genode::env()->ram_session()->alloc(size, cached); }
|
||||
|
||||
|
||||
void Lx::backend_free(Genode::Ram_dataspace_capability cap) {
|
||||
return Genode::env()->ram_session()->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)
|
||||
{
|
||||
Lx::Irq::irq().request_irq(Platform::Device::create(irq), handler, dev);
|
||||
|
||||
return 0;
|
||||
}
|
@ -21,21 +21,10 @@
|
||||
#include <irq_session/connection.h>
|
||||
#include <util/mmio.h>
|
||||
|
||||
/*
|
||||
* The Genode headers must be included before any Linux header. Otherwise,
|
||||
* the 'SUCCESS' macro defined in scsi/scsi_host.h collides with Genode's
|
||||
* 'Rpc_exception_code::SUCCESS' enum value.
|
||||
*/
|
||||
#include <platform.h>
|
||||
#include <platform/platform.h>
|
||||
|
||||
/* Emulation */
|
||||
#include <extern_c_begin.h>
|
||||
#include <lx_emul.h>
|
||||
#include <extern_c_end.h>
|
||||
#include <platform.h>
|
||||
|
||||
/* Linux */
|
||||
#include <linux/platform_data/dwc3-exynos.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
@ -60,7 +49,6 @@ static resource _dwc3[] =
|
||||
{ DWC3_IRQ, DWC3_IRQ, "dwc3-irq", IORESOURCE_IRQ },
|
||||
};
|
||||
|
||||
static struct dwc3_exynos_data _dwc3_data;
|
||||
|
||||
/**
|
||||
* EHCI controller
|
||||
@ -299,8 +287,7 @@ extern "C" void module_usbnet_init();
|
||||
extern "C" void module_asix_driver_init();
|
||||
extern "C" void module_ax88179_178a_driver_init();
|
||||
extern "C" void module_dwc3_driver_init();
|
||||
extern "C" void module_xhci_hcd_init();
|
||||
|
||||
extern "C" void module_xhci_plat_init();
|
||||
extern "C" void module_asix_init();
|
||||
|
||||
|
||||
@ -337,7 +324,7 @@ void xhci_setup(Services *services)
|
||||
module_ax88179_178a_driver_init();
|
||||
|
||||
module_dwc3_driver_init();
|
||||
module_xhci_hcd_init();
|
||||
module_xhci_plat_init();
|
||||
|
||||
arndale_xhci_init();
|
||||
|
||||
@ -347,7 +334,6 @@ void xhci_setup(Services *services)
|
||||
pdev->id = 0;
|
||||
pdev->num_resources = 2;
|
||||
pdev->resource = _dwc3;
|
||||
pdev->dev.platform_data = &_dwc3_data;
|
||||
|
||||
/*needed for DMA buffer allocation. See 'hcd_buffer_alloc' in 'buffer.c' */
|
||||
static u64 dma_mask = ~(u64)0;
|
||||
|
@ -26,10 +26,7 @@
|
||||
#include <gpio_session/connection.h>
|
||||
|
||||
/* Emulation */
|
||||
#include <platform/platform.h>
|
||||
#include <extern_c_begin.h>
|
||||
#include <lx_emul.h>
|
||||
#include <extern_c_end.h>
|
||||
#include <platform.h>
|
||||
|
||||
#include <usb_masks.h>
|
||||
|
@ -11,7 +11,6 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <platform/platform.h>
|
||||
#include <platform.h>
|
||||
|
||||
#include <drivers/board_base.h>
|
||||
@ -20,9 +19,7 @@
|
||||
#include <irq_session/connection.h>
|
||||
#include <util/mmio.h>
|
||||
|
||||
#include <extern_c_begin.h>
|
||||
#include <lx_emul.h>
|
||||
#include <extern_c_end.h>
|
||||
|
||||
#include <linux/platform_data/usb-omap.h>
|
||||
|
||||
|
@ -18,12 +18,8 @@
|
||||
#include <platform_session/connection.h>
|
||||
|
||||
/* emulation */
|
||||
#include <platform/platform.h>
|
||||
#include <platform.h>
|
||||
|
||||
#include <extern_c_begin.h>
|
||||
#include <lx_emul.h>
|
||||
#include <extern_c_end.h>
|
||||
|
||||
/* dwc-otg */
|
||||
#define new new_
|
||||
@ -115,7 +111,6 @@ DUMMY(-1, dwc_otg_pcd_get_rmwkup_enable);
|
||||
DUMMY(-1, dwc_otg_pcd_initiate_srp);
|
||||
DUMMY(-1, pcd_remove);
|
||||
SILENT_DUMMY( 0, pcd_init);
|
||||
DUMMY(-1, printk_once);
|
||||
|
||||
|
||||
/************************************************************************
|
||||
@ -124,6 +119,8 @@ DUMMY(-1, printk_once);
|
||||
|
||||
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) { }
|
||||
@ -140,22 +137,6 @@ unsigned char _dwc_otg_fiq_stub, _dwc_otg_fiq_stub_end;
|
||||
extern int fiq_enable, fiq_fsm_enable;
|
||||
|
||||
|
||||
/***********************
|
||||
** linux/workqueue.h **
|
||||
***********************/
|
||||
|
||||
struct workqueue_struct *create_singlethread_workqueue(char *)
|
||||
{
|
||||
workqueue_struct *wq = (workqueue_struct *)kzalloc(sizeof(workqueue_struct), 0);
|
||||
return wq;
|
||||
}
|
||||
|
||||
void destroy_workqueue(struct workqueue_struct *wq) { TRACE; }
|
||||
|
||||
|
||||
bool queue_work(struct workqueue_struct *wq, struct work_struct *work) { TRACE; return 0; }
|
||||
|
||||
|
||||
/***********************
|
||||
** asm/dma_mapping.h **
|
||||
***********************/
|
||||
|
203
repos/dde_linux/src/lib/usb/spec/x86/pci_driver.cc
Normal file
203
repos/dde_linux/src/lib/usb/spec/x86/pci_driver.cc
Normal file
@ -0,0 +1,203 @@
|
||||
/**
|
||||
* \brief PCI device handling
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2016-04-25
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which 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/lock.h>
|
||||
#include <base/signal.h>
|
||||
#include <os/config.h>
|
||||
#include <util/misc_math.h>
|
||||
|
||||
#include <lx_emul.h>
|
||||
|
||||
#include <lx_kit/irq.h>
|
||||
#include <lx_kit/pci_dev_registry.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()
|
||||
{
|
||||
/*
|
||||
* Functor that is called if the platform driver throws a
|
||||
* 'Out_of_metadata' exception.
|
||||
*/
|
||||
auto handler = [&] () {
|
||||
Genode::env()->parent()->upgrade(Lx::pci()->cap(),
|
||||
"ram_quota=4096"); };
|
||||
|
||||
/*
|
||||
* Obtain first device, the operation may exceed the session quota.
|
||||
* So we use the 'retry' mechanism.
|
||||
*/
|
||||
Platform::Device_capability cap;
|
||||
auto attempt = [&] () { cap = Lx::pci()->first_device(); };
|
||||
Genode::retry<Platform::Session::Out_of_metadata>(attempt, handler);
|
||||
|
||||
/*
|
||||
* Iterate over the devices of the platform session.
|
||||
*/
|
||||
while (cap.valid()) {
|
||||
|
||||
_pci_caps.insert(new (Genode::env()->heap()) Element(cap));
|
||||
|
||||
/* try next one. Upgrade session * quota on demand.*/
|
||||
auto attempt = [&] () {
|
||||
cap = Lx::pci()->next_device(cap);
|
||||
};
|
||||
|
||||
Genode::retry<Platform::Session::Out_of_metadata>(attempt, handler);
|
||||
}
|
||||
}
|
||||
|
||||
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 lamda = [&] (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 (env()->heap()) 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;
|
||||
|
||||
bool bios_handoff = true;
|
||||
try {
|
||||
if (config()->xml_node().attribute("bios_handoff").has_value("no"))
|
||||
bios_handoff = false;
|
||||
} catch (...) { }
|
||||
|
||||
/*
|
||||
* 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 (bios_handoff)
|
||||
__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(lamda);
|
||||
|
||||
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(), handler, dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
@ -12,7 +12,6 @@
|
||||
*/
|
||||
|
||||
#include <platform.h>
|
||||
#include <platform/platform.h>
|
||||
|
||||
|
||||
extern "C" void module_ax88179_178a_driver_init();
|
||||
@ -21,6 +20,7 @@ extern "C" void module_ehci_hcd_init();
|
||||
extern "C" void module_ehci_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(Services *s)
|
||||
{
|
||||
@ -29,8 +29,10 @@ void platform_hcd_init(Services *s)
|
||||
module_ax88179_178a_driver_init();
|
||||
}
|
||||
|
||||
if (s->xhci)
|
||||
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) {
|
||||
|
@ -17,13 +17,16 @@
|
||||
#include <util/endian.h>
|
||||
#include <util/list.h>
|
||||
|
||||
#include <extern_c_begin.h>
|
||||
#include <lx_emul.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 <extern_c_end.h>
|
||||
#include <lx_emul/extern_c_end.h>
|
||||
|
||||
#include <platform/lx_mem.h>
|
||||
#include "signal.h"
|
||||
|
||||
static Signal_helper *_signal = 0;
|
||||
@ -125,6 +128,10 @@ class Storage_device : public Genode::List<Storage_device>::Element,
|
||||
|
||||
/* 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:
|
||||
@ -162,10 +169,10 @@ class Storage_device : public Genode::List<Storage_device>::Element,
|
||||
bool dma_enabled() { return true; }
|
||||
|
||||
Genode::Ram_dataspace_capability alloc_dma_buffer(Genode::size_t size) {
|
||||
return Backend_memory::alloc(size, Genode::UNCACHED); }
|
||||
return Lx::backend_alloc(size, Genode::UNCACHED); }
|
||||
|
||||
void free_dma_buffer(Genode::Ram_dataspace_capability cap) {
|
||||
return Backend_memory::free(cap); }
|
||||
return Lx::backend_free(cap); }
|
||||
};
|
||||
|
||||
|
||||
@ -191,7 +198,7 @@ static work_struct delayed;
|
||||
extern "C" void ack_packet(work_struct *work)
|
||||
{
|
||||
Block::Packet_descriptor *packet =
|
||||
static_cast<Block::Packet_descriptor *>(work->data);
|
||||
(Block::Packet_descriptor *)(work->data);
|
||||
|
||||
if (verbose)
|
||||
PDBG("ACK packet for block: %llu", packet->block_number());
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/entrypoint.h>
|
||||
#include <base/snprintf.h>
|
||||
#include <base/tslab.h>
|
||||
#include <irq_session/client.h>
|
||||
|
@ -1,155 +1,167 @@
|
||||
linux-3.14.5/drivers/hid/hid-cherry.c
|
||||
linux-3.14.5/drivers/hid/hid-core.c
|
||||
linux-3.14.5/drivers/hid/hid-generic.c
|
||||
linux-3.14.5/drivers/hid/hid-ids.h
|
||||
linux-3.14.5/drivers/hid/hid-input.c
|
||||
linux-3.14.5/drivers/hid/hid-microsoft.c
|
||||
linux-3.14.5/drivers/hid/hid-multitouch.c
|
||||
linux-3.14.5/drivers/hid/usbhid/hid-core.c
|
||||
linux-3.14.5/drivers/hid/usbhid/hid-quirks.c
|
||||
linux-3.14.5/drivers/hid/usbhid/usbhid.h
|
||||
linux-3.14.5/drivers/input/evdev.c
|
||||
linux-3.14.5/drivers/input/input-compat.h
|
||||
linux-3.14.5/drivers/input/input-mt.c
|
||||
linux-3.14.5/drivers/input/input.c
|
||||
linux-3.14.5/drivers/input/tablet/wacom.h
|
||||
linux-3.14.5/drivers/input/tablet/wacom_sys.c
|
||||
linux-3.14.5/drivers/input/tablet/wacom_wac.c
|
||||
linux-3.14.5/drivers/input/tablet/wacom_wac.h
|
||||
linux-3.14.5/drivers/net/usb/asix_common.c
|
||||
linux-3.14.5/drivers/net/usb/asix_devices.c
|
||||
linux-3.14.5/drivers/net/usb/asix.h
|
||||
linux-3.14.5/drivers/net/usb/ax88172a.c
|
||||
linux-3.14.5/drivers/net/usb/ax88179_178a.c
|
||||
linux-3.14.5/drivers/net/usb/smsc95xx.h
|
||||
linux-3.14.5/drivers/net/usb/smsc95xx.c
|
||||
linux-3.14.5/drivers/net/usb/usbnet.c
|
||||
linux-3.14.5/drivers/scsi/constants.c
|
||||
linux-3.14.5/drivers/scsi/scsi_logging.h
|
||||
linux-3.14.5/drivers/scsi/scsi.c
|
||||
linux-3.14.5/drivers/scsi/scsi_priv.h
|
||||
linux-3.14.5/drivers/usb/core/buffer.c
|
||||
linux-3.14.5/drivers/usb/core/config.c
|
||||
linux-3.14.5/drivers/usb/core/devices.c
|
||||
linux-3.14.5/drivers/usb/core/driver.c
|
||||
linux-3.14.5/drivers/usb/core/endpoint.c
|
||||
linux-3.14.5/drivers/usb/core/file.c
|
||||
linux-3.14.5/drivers/usb/core/generic.c
|
||||
linux-3.14.5/drivers/usb/core/hcd.c
|
||||
linux-3.14.5/drivers/usb/core/hcd-pci.c
|
||||
linux-3.14.5/drivers/usb/core/hub.h
|
||||
linux-3.14.5/drivers/usb/core/hub.c
|
||||
linux-3.14.5/drivers/usb/core/message.c
|
||||
linux-3.14.5/drivers/usb/core/notify.c
|
||||
linux-3.14.5/drivers/usb/core/port.c
|
||||
linux-3.14.5/drivers/usb/core/quirks.c
|
||||
linux-3.14.5/drivers/usb/core/urb.c
|
||||
linux-3.14.5/drivers/usb/core/usb.h
|
||||
linux-3.14.5/drivers/usb/core/usb.c
|
||||
linux-3.14.5/drivers/usb/dwc3/core.h
|
||||
linux-3.14.5/drivers/usb/dwc3/core.c
|
||||
linux-3.14.5/drivers/usb/dwc3/debug.h
|
||||
linux-3.14.5/drivers/usb/dwc3/gadget.h
|
||||
linux-3.14.5/drivers/usb/dwc3/host.c
|
||||
linux-3.14.5/drivers/usb/dwc3/io.h
|
||||
linux-3.14.5/drivers/usb/dwc3/platform_data.h
|
||||
linux-3.14.5/drivers/usb/host/ehci-dbg.c
|
||||
linux-3.14.5/drivers/usb/host/ehci-exynos.c
|
||||
linux-3.14.5/drivers/usb/host/ehci.h
|
||||
linux-3.14.5/drivers/usb/host/ehci-hcd.c
|
||||
linux-3.14.5/drivers/usb/host/ehci-hub.c
|
||||
linux-3.14.5/drivers/usb/host/ehci-mem.c
|
||||
linux-3.14.5/drivers/usb/host/ehci-omap.c
|
||||
linux-3.14.5/drivers/usb/host/ehci-pci.c
|
||||
linux-3.14.5/drivers/usb/host/ehci-q.c
|
||||
linux-3.14.5/drivers/usb/host/ehci-sched.c
|
||||
linux-3.14.5/drivers/usb/host/ehci-sysfs.c
|
||||
linux-3.14.5/drivers/usb/host/ehci-timer.c
|
||||
linux-3.14.5/drivers/usb/host/pci-quirks.h
|
||||
linux-3.14.5/drivers/usb/host/pci-quirks.c
|
||||
linux-3.14.5/drivers/usb/host/uhci-debug.c
|
||||
linux-3.14.5/drivers/usb/host/uhci-hcd.h
|
||||
linux-3.14.5/drivers/usb/host/uhci-hcd.c
|
||||
linux-3.14.5/drivers/usb/host/uhci-hub.c
|
||||
linux-3.14.5/drivers/usb/host/uhci-pci.c
|
||||
linux-3.14.5/drivers/usb/host/uhci-q.c
|
||||
linux-3.14.5/drivers/usb/host/xhci-dbg.c
|
||||
linux-3.14.5/drivers/usb/host/xhci-ext-caps.h
|
||||
linux-3.14.5/drivers/usb/host/xhci.h
|
||||
linux-3.14.5/drivers/usb/host/xhci-hub.c
|
||||
linux-3.14.5/drivers/usb/host/xhci-mem.c
|
||||
linux-3.14.5/drivers/usb/host/xhci.c
|
||||
linux-3.14.5/drivers/usb/host/xhci-pci.c
|
||||
linux-3.14.5/drivers/usb/host/xhci-plat.c
|
||||
linux-3.14.5/drivers/usb/host/xhci-ring.c
|
||||
linux-3.14.5/drivers/usb/host/xhci-trace.h
|
||||
linux-3.14.5/drivers/usb/storage/debug.h
|
||||
linux-3.14.5/drivers/usb/storage/initializers.h
|
||||
linux-3.14.5/drivers/usb/storage/initializers.c
|
||||
linux-3.14.5/drivers/usb/storage/option_ms.h
|
||||
linux-3.14.5/drivers/usb/storage/option_ms.c
|
||||
linux-3.14.5/drivers/usb/storage/protocol.h
|
||||
linux-3.14.5/drivers/usb/storage/protocol.c
|
||||
linux-3.14.5/drivers/usb/storage/scsiglue.h
|
||||
linux-3.14.5/drivers/usb/storage/scsiglue.c
|
||||
linux-3.14.5/drivers/usb/storage/sierra_ms.h
|
||||
linux-3.14.5/drivers/usb/storage/sierra_ms.c
|
||||
linux-3.14.5/drivers/usb/storage/transport.h
|
||||
linux-3.14.5/drivers/usb/storage/transport.c
|
||||
linux-3.14.5/drivers/usb/storage/unusual_alauda.h
|
||||
linux-3.14.5/drivers/usb/storage/unusual_cypress.h
|
||||
linux-3.14.5/drivers/usb/storage/unusual_datafab.h
|
||||
linux-3.14.5/drivers/usb/storage/unusual_devs.h
|
||||
linux-3.14.5/drivers/usb/storage/unusual_ene_ub6250.h
|
||||
linux-3.14.5/drivers/usb/storage/unusual_freecom.h
|
||||
linux-3.14.5/drivers/usb/storage/unusual_isd200.h
|
||||
linux-3.14.5/drivers/usb/storage/unusual_jumpshot.h
|
||||
linux-3.14.5/drivers/usb/storage/unusual_karma.h
|
||||
linux-3.14.5/drivers/usb/storage/unusual_onetouch.h
|
||||
linux-3.14.5/drivers/usb/storage/unusual_realtek.h
|
||||
linux-3.14.5/drivers/usb/storage/unusual_sddr09.h
|
||||
linux-3.14.5/drivers/usb/storage/unusual_sddr55.h
|
||||
linux-3.14.5/drivers/usb/storage/unusual_usbat.h
|
||||
linux-3.14.5/drivers/usb/storage/usb.h
|
||||
linux-3.14.5/drivers/usb/storage/usb.c
|
||||
linux-3.14.5/drivers/usb/storage/usual-tables.c
|
||||
linux-3.14.5/drivers/usb/usb-common.c
|
||||
linux-3.14.5/include/asm-generic/bitops/__ffs.h
|
||||
linux-3.14.5/include/asm-generic/bitops/non-atomic.h
|
||||
linux-3.14.5/include/asm-generic/ioctl.h
|
||||
linux-3.14.5/include/linux/hiddev.h
|
||||
linux-3.14.5/include/linux/hid.h
|
||||
linux-3.14.5/include/linux/input.h
|
||||
linux-3.14.5/include/linux/input/mt.h
|
||||
linux-3.14.5/include/linux/leds.h
|
||||
linux-3.14.5/include/linux/list.h
|
||||
linux-3.14.5/include/linux/mod_devicetable.h
|
||||
linux-3.14.5/include/linux/netdev_features.h
|
||||
linux-3.14.5/include/linux/platform_data/dwc3-exynos.h
|
||||
linux-3.14.5/include/linux/pci_ids.h
|
||||
linux-3.14.5/include/linux/platform_data/usb-omap.h
|
||||
linux-3.14.5/include/linux/power_supply.h
|
||||
linux-3.14.5/include/linux/swab.h
|
||||
linux-3.14.5/include/linux/usb.h
|
||||
linux-3.14.5/include/linux/usb_usual.h
|
||||
linux-3.14.5/include/linux/usb/ch9.h
|
||||
linux-3.14.5/include/linux/usb/ehci_def.h
|
||||
linux-3.14.5/include/linux/usb/hcd.h
|
||||
linux-3.14.5/include/linux/usb/input.h
|
||||
linux-3.14.5/include/linux/usb/otg.h
|
||||
linux-3.14.5/include/linux/usb/phy.h
|
||||
linux-3.14.5/include/linux/usb/quirks.h
|
||||
linux-3.14.5/include/linux/usb/storage.h
|
||||
linux-3.14.5/include/linux/usb/usbnet.h
|
||||
linux-3.14.5/include/scsi/scsi.h
|
||||
linux-3.14.5/include/scsi/scsi_host.h
|
||||
linux-3.14.5/include/uapi/asm-generic/ioctl.h
|
||||
linux-3.14.5/include/uapi/linux/byteorder/little_endian.h
|
||||
linux-3.14.5/include/uapi/linux/hid.h
|
||||
linux-3.14.5/include/uapi/linux/input.h
|
||||
linux-3.14.5/include/uapi/linux/pci_regs.h
|
||||
linux-3.14.5/include/uapi/linux/stat.h
|
||||
linux-3.14.5/include/uapi/linux/swab.h
|
||||
linux-3.14.5/include/uapi/linux/usb/ch11.h
|
||||
linux-3.14.5/include/uapi/linux/usb/ch9.h
|
||||
linux-3.14.5/lib/int_sqrt.c
|
||||
linux-4.4.3/drivers/hid/hid-cherry.c
|
||||
linux-4.4.3/drivers/hid/hid-core.c
|
||||
linux-4.4.3/drivers/hid/hid-generic.c
|
||||
linux-4.4.3/drivers/hid/hid-ids.h
|
||||
linux-4.4.3/drivers/hid/hid-input.c
|
||||
linux-4.4.3/drivers/hid/hid-microsoft.c
|
||||
linux-4.4.3/drivers/hid/hid-multitouch.c
|
||||
linux-4.4.3/drivers/hid/wacom.h
|
||||
linux-4.4.3/drivers/hid/wacom_sys.c
|
||||
linux-4.4.3/drivers/hid/wacom_wac.c
|
||||
linux-4.4.3/drivers/hid/wacom_wac.h
|
||||
linux-4.4.3/drivers/hid/usbhid/hid-core.c
|
||||
linux-4.4.3/drivers/hid/usbhid/hid-quirks.c
|
||||
linux-4.4.3/drivers/hid/usbhid/usbhid.h
|
||||
linux-4.4.3/drivers/input/evdev.c
|
||||
linux-4.4.3/drivers/input/input-compat.h
|
||||
linux-4.4.3/drivers/input/input-mt.c
|
||||
linux-4.4.3/drivers/input/input.c
|
||||
linux-4.4.3/drivers/net/usb/asix_common.c
|
||||
linux-4.4.3/drivers/net/usb/asix_devices.c
|
||||
linux-4.4.3/drivers/net/usb/asix.h
|
||||
linux-4.4.3/drivers/net/usb/ax88172a.c
|
||||
linux-4.4.3/drivers/net/usb/ax88179_178a.c
|
||||
linux-4.4.3/drivers/net/usb/smsc95xx.h
|
||||
linux-4.4.3/drivers/net/usb/smsc95xx.c
|
||||
linux-4.4.3/drivers/net/usb/usbnet.c
|
||||
linux-4.4.3/drivers/scsi/constants.c
|
||||
linux-4.4.3/drivers/scsi/scsi_logging.h
|
||||
linux-4.4.3/drivers/scsi/scsi.c
|
||||
linux-4.4.3/drivers/scsi/scsi_priv.h
|
||||
linux-4.4.3/drivers/usb/common/common.c
|
||||
linux-4.4.3/drivers/usb/core/buffer.c
|
||||
linux-4.4.3/drivers/usb/core/config.c
|
||||
linux-4.4.3/drivers/usb/core/devices.c
|
||||
linux-4.4.3/drivers/usb/core/driver.c
|
||||
linux-4.4.3/drivers/usb/core/endpoint.c
|
||||
linux-4.4.3/drivers/usb/core/file.c
|
||||
linux-4.4.3/drivers/usb/core/generic.c
|
||||
linux-4.4.3/drivers/usb/core/hcd.c
|
||||
linux-4.4.3/drivers/usb/core/hcd-pci.c
|
||||
linux-4.4.3/drivers/usb/core/hub.h
|
||||
linux-4.4.3/drivers/usb/core/hub.c
|
||||
linux-4.4.3/drivers/usb/core/message.c
|
||||
linux-4.4.3/drivers/usb/core/notify.c
|
||||
linux-4.4.3/drivers/usb/core/port.c
|
||||
linux-4.4.3/drivers/usb/core/quirks.c
|
||||
linux-4.4.3/drivers/usb/core/urb.c
|
||||
linux-4.4.3/drivers/usb/core/usb.h
|
||||
linux-4.4.3/drivers/usb/core/usb.c
|
||||
linux-4.4.3/drivers/usb/dwc3/core.h
|
||||
linux-4.4.3/drivers/usb/dwc3/core.c
|
||||
linux-4.4.3/drivers/usb/dwc3/debug.h
|
||||
linux-4.4.3/drivers/usb/dwc3/dwc3-exynos.c
|
||||
linux-4.4.3/drivers/usb/dwc3/gadget.h
|
||||
linux-4.4.3/drivers/usb/dwc3/host.c
|
||||
linux-4.4.3/drivers/usb/dwc3/io.h
|
||||
linux-4.4.3/drivers/usb/dwc3/platform_data.h
|
||||
linux-4.4.3/drivers/usb/dwc3/trace.h
|
||||
linux-4.4.3/drivers/usb/host/ehci-dbg.c
|
||||
linux-4.4.3/drivers/usb/host/ehci-exynos.c
|
||||
linux-4.4.3/drivers/usb/host/ehci.h
|
||||
linux-4.4.3/drivers/usb/host/ehci-hcd.c
|
||||
linux-4.4.3/drivers/usb/host/ehci-hub.c
|
||||
linux-4.4.3/drivers/usb/host/ehci-mem.c
|
||||
linux-4.4.3/drivers/usb/host/ehci-omap.c
|
||||
linux-4.4.3/drivers/usb/host/ehci-pci.c
|
||||
linux-4.4.3/drivers/usb/host/ehci-q.c
|
||||
linux-4.4.3/drivers/usb/host/ehci-sched.c
|
||||
linux-4.4.3/drivers/usb/host/ehci-sysfs.c
|
||||
linux-4.4.3/drivers/usb/host/ehci-timer.c
|
||||
linux-4.4.3/drivers/usb/host/pci-quirks.h
|
||||
linux-4.4.3/drivers/usb/host/pci-quirks.c
|
||||
linux-4.4.3/drivers/usb/host/uhci-debug.c
|
||||
linux-4.4.3/drivers/usb/host/uhci-hcd.h
|
||||
linux-4.4.3/drivers/usb/host/uhci-hcd.c
|
||||
linux-4.4.3/drivers/usb/host/uhci-hub.c
|
||||
linux-4.4.3/drivers/usb/host/uhci-pci.c
|
||||
linux-4.4.3/drivers/usb/host/uhci-q.c
|
||||
linux-4.4.3/drivers/usb/host/xhci-dbg.c
|
||||
linux-4.4.3/drivers/usb/host/xhci-ext-caps.h
|
||||
linux-4.4.3/drivers/usb/host/xhci.h
|
||||
linux-4.4.3/drivers/usb/host/xhci-hub.c
|
||||
linux-4.4.3/drivers/usb/host/xhci-mem.c
|
||||
linux-4.4.3/drivers/usb/host/xhci-mvebu.h
|
||||
linux-4.4.3/drivers/usb/host/xhci-rcar.h
|
||||
linux-4.4.3/drivers/usb/host/xhci.c
|
||||
linux-4.4.3/drivers/usb/host/xhci-pci.c
|
||||
linux-4.4.3/drivers/usb/host/xhci-plat.c
|
||||
linux-4.4.3/drivers/usb/host/xhci-ring.c
|
||||
linux-4.4.3/drivers/usb/host/xhci-trace.h
|
||||
linux-4.4.3/drivers/usb/storage/debug.h
|
||||
linux-4.4.3/drivers/usb/storage/initializers.h
|
||||
linux-4.4.3/drivers/usb/storage/initializers.c
|
||||
linux-4.4.3/drivers/usb/storage/option_ms.h
|
||||
linux-4.4.3/drivers/usb/storage/option_ms.c
|
||||
linux-4.4.3/drivers/usb/storage/protocol.h
|
||||
linux-4.4.3/drivers/usb/storage/protocol.c
|
||||
linux-4.4.3/drivers/usb/storage/scsiglue.h
|
||||
linux-4.4.3/drivers/usb/storage/scsiglue.c
|
||||
linux-4.4.3/drivers/usb/storage/sierra_ms.h
|
||||
linux-4.4.3/drivers/usb/storage/sierra_ms.c
|
||||
linux-4.4.3/drivers/usb/storage/transport.h
|
||||
linux-4.4.3/drivers/usb/storage/transport.c
|
||||
linux-4.4.3/drivers/usb/storage/unusual_alauda.h
|
||||
linux-4.4.3/drivers/usb/storage/unusual_cypress.h
|
||||
linux-4.4.3/drivers/usb/storage/unusual_datafab.h
|
||||
linux-4.4.3/drivers/usb/storage/unusual_devs.h
|
||||
linux-4.4.3/drivers/usb/storage/unusual_ene_ub6250.h
|
||||
linux-4.4.3/drivers/usb/storage/unusual_freecom.h
|
||||
linux-4.4.3/drivers/usb/storage/unusual_isd200.h
|
||||
linux-4.4.3/drivers/usb/storage/unusual_jumpshot.h
|
||||
linux-4.4.3/drivers/usb/storage/unusual_karma.h
|
||||
linux-4.4.3/drivers/usb/storage/unusual_onetouch.h
|
||||
linux-4.4.3/drivers/usb/storage/unusual_realtek.h
|
||||
linux-4.4.3/drivers/usb/storage/unusual_sddr09.h
|
||||
linux-4.4.3/drivers/usb/storage/unusual_sddr55.h
|
||||
linux-4.4.3/drivers/usb/storage/unusual_usbat.h
|
||||
linux-4.4.3/drivers/usb/storage/usb.h
|
||||
linux-4.4.3/drivers/usb/storage/usb.c
|
||||
linux-4.4.3/drivers/usb/storage/usual-tables.c
|
||||
linux-4.4.3/include/asm-generic/bitops/__ffs.h
|
||||
linux-4.4.3/include/asm-generic/bitops/__fls.h
|
||||
linux-4.4.3/include/asm-generic/bitops/fls64.h
|
||||
linux-4.4.3/include/asm-generic/bitops/non-atomic.h
|
||||
linux-4.4.3/include/asm-generic/ioctl.h
|
||||
linux-4.4.3/include/linux/hiddev.h
|
||||
linux-4.4.3/include/linux/hid.h
|
||||
linux-4.4.3/include/linux/input.h
|
||||
linux-4.4.3/include/linux/input/mt.h
|
||||
linux-4.4.3/include/linux/leds.h
|
||||
linux-4.4.3/include/linux/list.h
|
||||
linux-4.4.3/include/linux/log2.h
|
||||
linux-4.4.3/include/linux/mod_devicetable.h
|
||||
linux-4.4.3/include/linux/netdev_features.h
|
||||
linux-4.4.3/include/linux/pci_ids.h
|
||||
linux-4.4.3/include/linux/platform_data/usb-omap.h
|
||||
linux-4.4.3/include/linux/power_supply.h
|
||||
linux-4.4.3/include/linux/swab.h
|
||||
linux-4.4.3/include/linux/usb.h
|
||||
linux-4.4.3/include/linux/usb_usual.h
|
||||
linux-4.4.3/include/linux/usb/ch9.h
|
||||
linux-4.4.3/include/linux/usb/cdc.h
|
||||
linux-4.4.3/include/linux/usb/ehci-dbgp.h
|
||||
linux-4.4.3/include/linux/usb/ehci_def.h
|
||||
linux-4.4.3/include/linux/usb/hcd.h
|
||||
linux-4.4.3/include/linux/usb/input.h
|
||||
linux-4.4.3/include/linux/io-64-nonatomic-lo-hi.h
|
||||
linux-4.4.3/include/linux/usb/otg.h
|
||||
linux-4.4.3/include/linux/usb/phy.h
|
||||
linux-4.4.3/include/linux/usb/quirks.h
|
||||
linux-4.4.3/include/linux/usb/storage.h
|
||||
linux-4.4.3/include/linux/usb/usbnet.h
|
||||
linux-4.4.3/include/scsi/scsi.h
|
||||
linux-4.4.3/include/scsi/scsi_host.h
|
||||
linux-4.4.3/include/scsi/scsi_proto.h
|
||||
linux-4.4.3/include/uapi/asm-generic/ioctl.h
|
||||
linux-4.4.3/include/uapi/linux/byteorder/little_endian.h
|
||||
linux-4.4.3/include/uapi/linux/hid.h
|
||||
linux-4.4.3/include/uapi/linux/input.h
|
||||
linux-4.4.3/include/uapi/linux/input-event-codes.h
|
||||
linux-4.4.3/include/uapi/linux/pci_regs.h
|
||||
linux-4.4.3/include/uapi/linux/stat.h
|
||||
linux-4.4.3/include/uapi/linux/swab.h
|
||||
linux-4.4.3/include/uapi/linux/usb/ch11.h
|
||||
linux-4.4.3/include/uapi/linux/usb/ch9.h
|
||||
linux-4.4.3/include/uapi/linux/usb/cdc.h
|
||||
linux-4.4.3/lib/int_sqrt.c
|
||||
|
Loading…
x
Reference in New Issue
Block a user