diff options
author | Sami Nurmenniemi <sami.nurmenniemi@qt.io> | 2017-09-19 12:47:29 +0300 |
---|---|---|
committer | Kari Oikarinen <kari.oikarinen@qt.io> | 2018-09-10 11:54:40 +0000 |
commit | 8bac1ae8253645bd680f4f2157ec43732fd5de00 (patch) | |
tree | c3023586bb09527689ae2319815df81e3679b560 | |
parent | 7ae645c0333a8a87d8ba854e071dd7bc63eaa46d (diff) |
Add gadget initialization to the qdbd daemon
It's not possible to deterministically control timings of gadget
initialization from an external script. Moved gadget initialization
logic from /usr/bin/qdbd-init.sh to the qdbd USB gadget
initialization. This was causing problems when qdbd daemon launch
was delayed because of kernel random pool initialization.
Done-with: Kari Oikarinen <kari.oikarinen@qt.io>
Task-number: QTBUG-63029
Change-Id: Ia403fbe6ebdbc83908bafb023a88fff058efc840
Reviewed-by: Sami Nurmenniemi <sami.nurmenniemi@qt.io>
Reviewed-by: Samuli Piippo <samuli.piippo@qt.io>
-rw-r--r-- | qdbd/configuration.cpp | 6 | ||||
-rw-r--r-- | qdbd/configuration.h | 2 | ||||
-rw-r--r-- | qdbd/usb-gadget/usbgadget.cpp | 43 | ||||
-rw-r--r-- | qdbd/usb-gadget/usbgadget.h | 1 |
4 files changed, 52 insertions, 0 deletions
diff --git a/qdbd/configuration.cpp b/qdbd/configuration.cpp index b53defb..9ae452c 100644 --- a/qdbd/configuration.cpp +++ b/qdbd/configuration.cpp @@ -50,6 +50,11 @@ QString Configuration::rndisFunctionName() return s_rndisFunctionName; } +QString Configuration::udcDriverDir() +{ + return s_udcDriverDir; +} + void Configuration::setFunctionFsDir(const QString &path) { s_functionFsDir = QDir::cleanPath(path); @@ -74,3 +79,4 @@ QString Configuration::s_functionFsDir = "/dev/usb-ffs/qdb"; QString Configuration::s_gadgetConfigFsDir = "/sys/kernel/config/usb_gadget/g1"; QString Configuration::s_rndisFunctionName = "rndis.usb0"; QString Configuration::s_networkScript = "b2qt-gadget-network.sh"; +QString Configuration::s_udcDriverDir = "/sys/class/udc/"; diff --git a/qdbd/configuration.h b/qdbd/configuration.h index eb34cd7..dadc2c0 100644 --- a/qdbd/configuration.h +++ b/qdbd/configuration.h @@ -38,6 +38,7 @@ public: static QString gadgetConfigFsDir(); static QString networkScript(); static QString rndisFunctionName(); + static QString udcDriverDir(); static void setFunctionFsDir(const QString &path); static void setGadgetConfigFsDir(const QString &path); static void setNetworkScript(const QString &script); @@ -48,6 +49,7 @@ private: static QString s_gadgetConfigFsDir; static QString s_networkScript; static QString s_rndisFunctionName; + static QString s_udcDriverDir; }; #endif // CONFIGURATION_H diff --git a/qdbd/usb-gadget/usbgadget.cpp b/qdbd/usb-gadget/usbgadget.cpp index 020b293..599de48 100644 --- a/qdbd/usb-gadget/usbgadget.cpp +++ b/qdbd/usb-gadget/usbgadget.cpp @@ -40,6 +40,8 @@ #include <QtCore/qloggingcategory.h> #include <QtCore/qthread.h> +#include <QDirIterator> + #include <linux/usb/functionfs.h> Q_LOGGING_CATEGORY(usbC, "qdb.usb"); @@ -186,6 +188,7 @@ bool UsbGadget::open(QIODevice::OpenMode mode) startControlThread(); startReadThread(); startWriteThread(); + initializeGadgetWithUdc(); return true; } @@ -271,3 +274,43 @@ bool UsbGadget::openControlEndpoint() return true; } +/** + * Initialize usb gadget with the first UDC driver + */ +void UsbGadget::initializeGadgetWithUdc() +{ + QString driverName = []() { + QDirIterator it(Configuration::udcDriverDir()); + while (it.hasNext()) { + it.next(); + const QString candidate = it.fileName(); + if (candidate != QLatin1String(".") && candidate != QLatin1String("..")) + return candidate; + } + return QString{}; + }(); + if (driverName.isEmpty()) { + qCCritical(usbC) << "Failed to initialize USB gadget, no UDC drivers found in" + << Configuration::udcDriverDir(); + return; + } + + const QString gadgetConfigPath = Configuration::gadgetConfigFsDir() + QLatin1String("/UDC"); + QFile gadgetConfigFile{gadgetConfigPath}; + if (!gadgetConfigFile.exists()) { + qCCritical(usbC) << "Failed to initialize USB gadget, no gadget file found in" + << gadgetConfigPath; + return; + } + if (!gadgetConfigFile.open(QIODevice::ReadWrite | QIODevice::Unbuffered)) { + qCCritical(usbC) << "Failed to initialize USB gadget, can't open" << gadgetConfigPath; + return; + } + if (gadgetConfigFile.write(driverName.toUtf8()) == -1) { + qCCritical(usbC) << "Failed to initialize USB gadget, can't write to" + << gadgetConfigPath; + return; + } + gadgetConfigFile.close(); + qCDebug(usbC) << "Initialized USB gadget UDC driver"; +} diff --git a/qdbd/usb-gadget/usbgadget.h b/qdbd/usb-gadget/usbgadget.h index 857f213..afae869 100644 --- a/qdbd/usb-gadget/usbgadget.h +++ b/qdbd/usb-gadget/usbgadget.h @@ -68,6 +68,7 @@ private: void startControlThread(); void startReadThread(); void startWriteThread(); + void initializeGadgetWithUdc(); QFile m_controlEndpoint; // Endpoints are named in line with USB terminology. Out means from host to |