diff --git a/dde_linux/src/drivers/usb/arm/platform/mem.cc b/dde_linux/src/drivers/usb/arm/platform/mem.cc
new file mode 100644
index 0000000000..9327d6d37f
--- /dev/null
+++ b/dde_linux/src/drivers/usb/arm/platform/mem.cc
@@ -0,0 +1,18 @@
+/*
+ * \brief Backend for allocating DMA memory on ARM
+ * \author Alexander Boettcher
+ * \date 2013-02-19
+ */
+
+/*
+ * Copyright (C) 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
+#include "mem.h"
+
+Genode::Ram_dataspace_capability Genode::Mem::alloc_dma_buffer(size_t size) {
+ return Genode::env()->ram_session()->alloc(size, false); }
diff --git a/dde_linux/src/drivers/usb/mem.h b/dde_linux/src/drivers/usb/mem.h
index e0c731133a..750b806873 100644
--- a/dde_linux/src/drivers/usb/mem.h
+++ b/dde_linux/src/drivers/usb/mem.h
@@ -47,13 +47,22 @@ namespace Genode {
Ram_dataspace_capability _ds_cap; /* backing store */
+ /**
+ * Allocates memory which can be used for DMA.
+ */
+ Genode::Ram_dataspace_capability alloc_dma_buffer(size_t size);
+
/**
* Private constructor
*/
Mem(size_t size, bool cached = true)
: _size(size), _range(env()->heap()),_zone_count(0), _zone_alloc(0)
{
- _ds_cap = env()->ram_session()->alloc(_size, cached);
+ if (cached)
+ _ds_cap = env()->ram_session()->alloc(_size, cached);
+ else
+ _ds_cap = alloc_dma_buffer(_size);
+
_base_phys = Dataspace_client(_ds_cap).phys_addr();
_base = (addr_t)env()->rm_session()->attach(_ds_cap);
diff --git a/dde_linux/src/drivers/usb/pci_driver.cc b/dde_linux/src/drivers/usb/pci_driver.cc
index 8279afbeb5..43697c8d4f 100644
--- a/dde_linux/src/drivers/usb/pci_driver.cc
+++ b/dde_linux/src/drivers/usb/pci_driver.cc
@@ -18,6 +18,7 @@
/* Linux includes */
#include
+#include "mem.h"
struct bus_type pci_bus_type;
@@ -179,6 +180,9 @@ class Pci_driver
** Linux interface **
*********************/
+static Pci::Device_capability pci_device_cap;
+static Pci::Connection pci;
+
int pci_register_driver(struct pci_driver *drv)
{
dde_kit_log(DEBUG_PCI, "DRIVER name: %s", drv->name);
@@ -189,7 +193,6 @@ int pci_register_driver(struct pci_driver *drv)
return -ENODEV;
using namespace Genode;
- Pci::Connection pci;
bool found = false;
@@ -207,9 +210,20 @@ int pci_register_driver(struct pci_driver *drv)
Pci_driver *pci_drv = 0;
try {
+ /*
+ * Assign cap already here, since for probing already DMA
+ * buffer is required and allocated by
+ * Genode::Mem::alloc_dma_buffer(size_t size)
+ */
+ pci_device_cap = cap;
+
+ /* probe device */
pci_drv = new (env()->heap()) Pci_driver(drv, cap, id);
pci.on_destruction(Pci::Connection::KEEP_OPEN);
found = true;
+
+ /* trigger that the device get be assigned to the usb driver */
+ pci.config_extended(cap);
} catch (...) {
destroy(env()->heap(), pci_drv);
pci_drv = 0;
@@ -297,3 +311,10 @@ const char *pci_name(const struct pci_dev *pdev)
return "dummy";
}
+Genode::Ram_dataspace_capability Genode::Mem::alloc_dma_buffer(size_t size)
+{
+ using namespace Genode;
+ Ram_dataspace_capability ram_cap = pci.alloc_dma_buffer(pci_device_cap,
+ size);
+ return ram_cap;
+}
diff --git a/dde_linux/src/drivers/usb/target.mk b/dde_linux/src/drivers/usb/target.mk
index e2d3613067..ae833ebf38 100644
--- a/dde_linux/src/drivers/usb/target.mk
+++ b/dde_linux/src/drivers/usb/target.mk
@@ -83,7 +83,7 @@ CC_OPT += -DCONFIG_USB_EHCI_HCD_OMAP -DCONFIG_USB_EHCI_TT_NEWSCHED -DVERBOSE_DE
INC_DIR += $(PRG_DIR)/arm
INC_DIR += $(CONTRIB_DIR)/arch/arm/plat-omap/include
SRC_C += platform_device.c usbnet.c smsc95xx.c
-SRC_CC += platform.cc
+SRC_CC += platform.cc mem.cc
vpath %.c $(PRG_DIR)/arm/platform
vpath %.cc $(PRG_DIR)/arm/platform
vpath %.c $(CONTRIB_DIR)/drivers/net/usb