usb: Make host controller types configurable

The host controller type (u/e/xhci) usded by the drivers can be configured
through attributes of the config node. See: README
This commit is contained in:
Sebastian Sumpf 2013-05-17 14:40:48 +02:00 committed by Norman Feske
parent 6d07fff07c
commit cda25a481b
16 changed files with 142 additions and 72 deletions

View File

@ -3,6 +3,19 @@ Device drivers ported from the Linux kernel
USB USB
### ###
Controller configuration
~~~~~~~~~~~~~~~~~~~~~~~~
The driver can be started using different or all USB controller types a platform
offers (USB 1.0/2.0/3.0). Note that not all controllers are supported by all
platforms. Controllers can be enabled as attribute in the config node of the
driver. Supported attributes are: 'uhci', 'ehci', and 'xhci'.
Configuration snippet to enable UHCI and EHCI
! <config uhci="yes" ehci="yes">
HID HID
~~~ ~~~
@ -13,7 +26,7 @@ Configuration snippet:
!<start name="usb_drv"> !<start name="usb_drv">
! <resource name="RAM" quantum="3M"/> ! <resource name="RAM" quantum="3M"/>
! <provides><service name="Input"/></provides> ! <provides><service name="Input"/></provides>
! <config> ! <config uhci="yes" ehci="yes" xhci="yes">
! <hid/> ! <hid/>
! </config> ! </config>
!</start> !</start>
@ -34,14 +47,12 @@ Configuration snippet:
! <resource name="RAM" quantum="2M"/> ! <resource name="RAM" quantum="2M"/>
! <provides> <service name="Block"/> </provides> ! <provides> <service name="Block"/> </provides>
! <config><storage /></config> ! <config><storage /></config>
!</start> !</start uhci="yes">
Network (Nic) Network (Nic)
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
Supported on PandaBoard only using the 'smsc95xx' driver.
Configuration snippet: Configuration snippet:
!<start name="usb_drv"> !<start name="usb_drv">
@ -50,7 +61,7 @@ Configuration snippet:
! <service name="Nic"/> ! <service name="Nic"/>
! <service name="Input"/> ! <service name="Input"/>
! </provides> ! </provides>
! <config> ! <config ehci="yes" xhci="yes">
! <nic mac="2e:60:90:0c:4e:01" /> ! <nic mac="2e:60:90:0c:4e:01" />
! <hid/> ! <hid/>
! </config> ! </config>

View File

@ -4,4 +4,6 @@ include $(REP_DIR)/lib/mk/usb.inc
CC_OPT += -DCONFIG_PCI -DCONFIG_USB_EHCI_PCI=1 -DCONFIG_USB_XHCI_HCD=0 CC_OPT += -DCONFIG_PCI -DCONFIG_USB_EHCI_PCI=1 -DCONFIG_USB_XHCI_HCD=0
INC_DIR += $(LIB_INC_DIR)/x86_32 $(LIB_INC_DIR)/x86 INC_DIR += $(LIB_INC_DIR)/x86_32 $(LIB_INC_DIR)/x86
SRC_CC += pci_driver.cc SRC_CC += pci_driver.cc platform.cc
vpath platform.cc $(LIB_DIR)/x86

View File

@ -4,4 +4,6 @@ include $(REP_DIR)/lib/mk/usb.inc
CC_OPT += -DCONFIG_PCI -DCONFIG_USB_EHCI_PCI=1 -DCONFIG_USB_XHCI_HCD=0 CC_OPT += -DCONFIG_PCI -DCONFIG_USB_EHCI_PCI=1 -DCONFIG_USB_XHCI_HCD=0
INC_DIR += $(LIB_INC_DIR)/x86_64 $(LIB_INC_DIR)/x86 INC_DIR += $(LIB_INC_DIR)/x86_64 $(LIB_INC_DIR)/x86
SRC_CC += pci_driver.cc SRC_CC += pci_driver.cc platform.cc
vpath platform.cc $(LIB_DIR)/x86

View File

@ -57,7 +57,7 @@ set config {
<service name="Input"/> <service name="Input"/>
<service name="Nic"/> <service name="Nic"/>
</provides> </provides>
<config> <config ehci="yes">
<hid/> <hid/>
<nic mac="2e:60:90:0c:4e:01" /> <nic mac="2e:60:90:0c:4e:01" />
</config> </config>

View File

@ -68,7 +68,7 @@ append config {
<start name="usb_drv"> <start name="usb_drv">
<resource name="RAM" quantum="7M"/> <resource name="RAM" quantum="7M"/>
<provides><service name="Input"/></provides> <provides><service name="Input"/></provides>
<config> <config uhci="yes" ehci="yes" xhci="yes">
<hid/> <hid/>
</config> </config>
</start> </start>

View File

@ -54,7 +54,7 @@ set config {
<service name="Nic"/> <service name="Nic"/>
<service name="Input"/> <service name="Input"/>
</provides> </provides>
<config> <config ehci="yes" xhci="yes">
<nic mac="2e:60:90:0c:4e:01" /> <nic mac="2e:60:90:0c:4e:01" />
<hid/> <hid/>
</config> </config>

View File

@ -72,7 +72,7 @@ append config {
<start name="usb_drv"> <start name="usb_drv">
<resource name="RAM" quantum="6M"/> <resource name="RAM" quantum="6M"/>
<provides> <service name="Block"/> </provides> <provides> <service name="Block"/> </provides>
<config><storage /></config> <config uhci="yes" ehci="yes" xhci="yes"><storage /></config>
</start> </start>
<start name="test-usb"> <start name="test-usb">
<resource name="RAM" quantum="2M" /> <resource name="RAM" quantum="2M" />

View File

@ -20,6 +20,7 @@
/* Emulation */ /* Emulation */
#include <platform/platform.h> #include <platform/platform.h>
#include <lx_emul.h> #include <lx_emul.h>
#include <platform.h>
/* Linux */ /* Linux */
#include <linux/platform_data/usb-ehci-s5p.h> #include <linux/platform_data/usb-ehci-s5p.h>
@ -356,6 +357,9 @@ void platform_hcd_init(Services *services)
if (services->nic) if (services->nic)
module_usbnet_init(); module_usbnet_init();
//ehci_setup(services); if (services->ehci)
xhci_setup(services); ehci_setup(services);
if (services->xhci)
xhci_setup(services);
} }

View File

@ -12,6 +12,7 @@
*/ */
#include <platform/platform.h> #include <platform/platform.h>
#include <platform.h>
#include <io_mem_session/connection.h> #include <io_mem_session/connection.h>
#include <util/mmio.h> #include <util/mmio.h>
@ -367,6 +368,9 @@ extern "C" int module_smsc95xx_driver_init();
void platform_hcd_init(Services *services) void platform_hcd_init(Services *services)
{ {
if (!services->ehci)
return;
/* register network */ /* register network */
if (services->nic) { if (services->nic) {
module_usbnet_init(); module_usbnet_init();
@ -381,7 +385,7 @@ void platform_hcd_init(Services *services)
/* setup EHCI-controller platform device */ /* setup EHCI-controller platform device */
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0); platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
pdev->name = "ehci-omap"; pdev->name = (char *)"ehci-omap";
pdev->id = 0; pdev->id = 0;
pdev->num_resources = 2; pdev->num_resources = 2;
pdev->resource = _ehci; pdev->resource = _ehci;

View File

@ -18,8 +18,6 @@
extern "C" { extern "C" {
#endif #endif
#include <platform.h>
static inline static inline
void platform_execute(void *sp, void *func, void *arg) void platform_execute(void *sp, void *func, void *arg)
{ {

View File

@ -16,13 +16,74 @@
#ifndef _PLATFORM_H_ #ifndef _PLATFORM_H_
#define _PLATFORM_H_ #define _PLATFORM_H_
#include <base/printf.h>
#include <os/config.h>
#include <util/xml_node.h>
struct Services struct Services
{ {
/* USB profiles */
bool hid; bool hid;
bool stor; bool stor;
bool nic; bool nic;
Services() : hid(false), stor(false), nic(false) { } /* Controller types */
bool uhci; /* 1.0 */
bool ehci; /* 2.0 */
bool xhci; /* 3.0 */
Services()
: hid(false), stor(false), nic(false),
uhci(false), ehci(false), xhci(false)
{
using namespace Genode;
try {
config()->xml_node().sub_node("hid");
hid = true;
} catch (Config::Invalid) {
PDBG("No <config> node found - not starting any USB services");
return;
} catch (Xml_node::Nonexistent_sub_node) {
PDBG("No <hid> config node found - not starting the USB HID (Input) service");
}
try {
config()->xml_node().sub_node("storage");
stor = true;
} catch (Xml_node::Nonexistent_sub_node) {
PDBG("No <storage> config node found - not starting the USB Storage (Block) service");
}
try {
config()->xml_node().sub_node("nic");
nic = true;
} catch (Xml_node::Nonexistent_sub_node) {
PDBG("No <nic> config node found - not starting the USB Nic (Network) service");
}
try {
config()->xml_node().attribute("uhci").has_value("yes");
uhci = true;
PINF("Enabled UHCI (USB 1.0/1.1) support");
} catch (...) { }
try {
config()->xml_node().attribute("ehci").has_value("yes");
ehci = true;
PINF("Enabled EHCI (USB 2.0) support");
} catch (...) { }
try {
config()->xml_node().attribute("xhci").has_value("yes");
xhci = true;
PINF("Enabled XHCI (USB 3.0) support");
} catch (...) { }
if (!(uhci | ehci | xhci))
PWRN("Warning: No USB controllers enabled.\n"
"Use <config (u/e/x)hci=\"yes\"> in your 'usb_drv' configuration");
}
}; };
void platform_hcd_init(Services *services); void platform_hcd_init(Services *services);

View File

@ -26,17 +26,4 @@ void platform_execute(void *sp, void *func, void *arg)
: : "r" (sp), "r" (func), "r" (arg)); : : "r" (sp), "r" (func), "r" (arg));
} }
extern "C" void module_ehci_hcd_init();
extern "C" void module_ehci_pci_init();
extern "C" void module_uhci_hcd_init();
inline void platform_hcd_init(Services *s)
{
/* ehci_hcd should always be loaded before uhci_hcd and ohci_hcd, not after */
module_ehci_hcd_init();
module_ehci_pci_init();
module_uhci_hcd_init();
}
#endif /* _X86_32__PLATFORM_H_ */ #endif /* _X86_32__PLATFORM_H_ */

View File

@ -27,17 +27,4 @@ void platform_execute(void *sp, void *func, void *arg)
: "+r" (sp), "+r" (func), "+r" (arg) : : "memory"); : "+r" (sp), "+r" (func), "+r" (arg) : : "memory");
} }
extern "C" void module_ehci_hcd_init();
extern "C" void module_ehci_pci_init();
extern "C" void module_uhci_hcd_init();
inline void platform_hcd_init(Services *s)
{
/* ehci_hcd should always be loaded before uhci_hcd and ohci_hcd, not after */
module_ehci_hcd_init();
module_ehci_pci_init();
module_uhci_hcd_init();
}
#endif /* _X86_64__PLATFORM_H_ */ #endif /* _X86_64__PLATFORM_H_ */

View File

@ -18,14 +18,14 @@
#include <base/printf.h> #include <base/printf.h>
#include <base/sleep.h> #include <base/sleep.h>
#include <cap_session/connection.h> #include <cap_session/connection.h>
#include <os/config.h>
#include <util/xml_node.h>
#include <nic_session/nic_session.h> #include <nic_session/nic_session.h>
/* Local */ /* Local */
#include "storage/component.h" #include <storage/component.h>
#include "routine.h" #include <platform.h>
#include "signal.h" #include <routine.h>
#include <signal.h>
extern "C" { extern "C" {
#include <dde_kit/timer.h> #include <dde_kit/timer.h>
@ -92,30 +92,8 @@ void start_usb_driver()
Services services; Services services;
try { if (services.hid)
config()->xml_node().sub_node("hid");
start_input_service(&ep_hid); start_input_service(&ep_hid);
services.hid = true;
} catch (Config::Invalid) {
PDBG("No <config> node found - not starting any USB services");
return;
} catch (Xml_node::Nonexistent_sub_node) {
PDBG("No <hid> config node found - not starting the USB HID (Input) service");
}
try {
config()->xml_node().sub_node("storage");
services.stor = true;
} catch (Xml_node::Nonexistent_sub_node) {
PDBG("No <storage> config node found - not starting the USB Storage (Block) service");
}
try {
config()->xml_node().sub_node("nic");
services.nic = true;
} catch (Xml_node::Nonexistent_sub_node) {
PDBG("No <nic> config node found - not starting the USB Nic (Network) service");
}
Timer::init(&recv); Timer::init(&recv);
Irq::init(&recv); Irq::init(&recv);

View File

@ -0,0 +1,36 @@
/**
* \brief X86 platform initialization
* \author Sebastian Sumpf
* \date 2013-05-17
*/
/*
* 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 <platform.h>
#include <platform/platform.h>
extern "C" void module_ehci_hcd_init();
extern "C" void module_ehci_pci_init();
extern "C" void module_uhci_hcd_init();
void platform_hcd_init(Services *s)
{
/* ehci_hcd should always be loaded before uhci_hcd and ohci_hcd, not after */
if (s->ehci) {
module_ehci_hcd_init();
module_ehci_pci_init();
}
if (s->uhci)
module_uhci_hcd_init();
}

View File

@ -81,7 +81,7 @@ append_if $use_usb_driver config {
<provides> <provides>
<service name="Nic"/> <service name="Nic"/>
</provides> </provides>
<config> <config ehci="yes">
<nic mac="2e:60:90:0c:4e:01" /> <nic mac="2e:60:90:0c:4e:01" />
</config> </config>
</start>} </start>}