summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorJesse Buhagiar <jooster669@gmail.com>2022-04-11 20:18:31 +1000
committerAndreas Kling <kling@serenityos.org>2022-04-22 15:16:56 +0200
commitdac26f89cb4407133d73e1dc6ceae022f3837572 (patch)
treef0ffbb7e5c3477b6509e987589e87d9e0475617f /Kernel
parent1409a48da63fdeb841474302c43141a56e7c8e81 (diff)
downloadserenity-dac26f89cb4407133d73e1dc6ceae022f3837572.zip
Kernel/USB: Fetch configuration descriptors on enumeration
This also introduces a new class, `USBConfiguration` that stores a configuration. The device, when instructed, sets this configuration and holds a pointer to it so we have a record of what configuration is currently active.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Bus/USB/USBConfiguration.h38
-rw-r--r--Kernel/Bus/USB/USBDevice.cpp20
-rw-r--r--Kernel/Bus/USB/USBDevice.h4
3 files changed, 62 insertions, 0 deletions
diff --git a/Kernel/Bus/USB/USBConfiguration.h b/Kernel/Bus/USB/USBConfiguration.h
new file mode 100644
index 0000000000..3fba019ef8
--- /dev/null
+++ b/Kernel/Bus/USB/USBConfiguration.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2022, Jesse Buhagiar <jesse.buhagiar@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/Vector.h>
+#include <Kernel/Bus/USB/USBDescriptors.h>
+#include <Kernel/Bus/USB/USBDevice.h>
+
+namespace Kernel::USB {
+
+class Device;
+
+class USBConfiguration {
+public:
+ USBConfiguration() = delete;
+ USBConfiguration(Device& device, USBConfigurationDescriptor const configuration_descriptor)
+ : m_device(device)
+ , m_descriptor(configuration_descriptor)
+ {
+ }
+
+ Device const& device() const { return m_device; }
+
+ u8 interface_count() const { return m_descriptor.number_of_interfaces; }
+ u8 configuration_id() const { return m_descriptor.configuration_value; }
+ u8 attributes() const { return m_descriptor.attributes_bitmap; }
+ u16 max_power_ma() const { return m_descriptor.max_power_in_ma * 2u; } // Note: "Power" is used incorrectly here, however it's what it's called in the descriptor/documentation
+
+private:
+ Device& m_device; // Reference to the device linked to this configuration
+ USBConfigurationDescriptor m_descriptor; // Descriptor that backs this configuration
+};
+
+}
diff --git a/Kernel/Bus/USB/USBDevice.cpp b/Kernel/Bus/USB/USBDevice.cpp
index 73257b20ea..4e21a3ca69 100644
--- a/Kernel/Bus/USB/USBDevice.cpp
+++ b/Kernel/Bus/USB/USBDevice.cpp
@@ -115,6 +115,26 @@ ErrorOr<void> Device::enumerate_device()
dbgln_if(USB_DEBUG, "USB Device: Set address to {}", m_address);
memcpy(&m_device_descriptor, &dev_descriptor, sizeof(USBDeviceDescriptor));
+
+ // Fetch the configuration descriptors from the device
+ m_configurations.ensure_capacity(m_device_descriptor.num_configurations);
+ for (auto configuration = 0u; configuration < m_device_descriptor.num_configurations; configuration++) {
+ USBConfigurationDescriptor configuration_descriptor;
+ transfer_length = TRY(m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, (DESCRIPTOR_TYPE_CONFIGURATION << 8u) | configuration, 0, sizeof(USBConfigurationDescriptor), &configuration_descriptor));
+
+ if constexpr (USB_DEBUG) {
+ dbgln("USB Configuration Descriptor {}", configuration);
+ dbgln("Total Length: {}", configuration_descriptor.total_length);
+ dbgln("Number of interfaces: {}", configuration_descriptor.number_of_interfaces);
+ dbgln("Configuration Value: {}", configuration_descriptor.configuration_value);
+ dbgln("Attributes Bitmap: {:08b}", configuration_descriptor.attributes_bitmap);
+ dbgln("Maximum Power: {}mA", configuration_descriptor.max_power_in_ma * 2u); // This value is in 2mA steps
+ }
+
+ USBConfiguration device_configuration(*this, configuration_descriptor);
+ m_configurations.append(device_configuration);
+ }
+
return {};
}
diff --git a/Kernel/Bus/USB/USBDevice.h b/Kernel/Bus/USB/USBDevice.h
index 2ac68482ba..e2a1aac4ff 100644
--- a/Kernel/Bus/USB/USBDevice.h
+++ b/Kernel/Bus/USB/USBDevice.h
@@ -8,11 +8,14 @@
#include <AK/OwnPtr.h>
#include <AK/Types.h>
+#include <AK/Vector.h>
+#include <Kernel/Bus/USB/USBConfiguration.h>
#include <Kernel/Bus/USB/USBPipe.h>
namespace Kernel::USB {
class USBController;
+class USBConfiguration;
//
// Some nice info from FTDI on device enumeration and how some of this
@@ -55,6 +58,7 @@ protected:
u16 m_vendor_id { 0 }; // This device's vendor ID assigned by the USB group
u16 m_product_id { 0 }; // This device's product ID assigned by the USB group
USBDeviceDescriptor m_device_descriptor {}; // Device Descriptor obtained from USB Device
+ Vector<USBConfiguration> m_configurations; // Configurations for this device
NonnullRefPtr<USBController> m_controller;
NonnullOwnPtr<Pipe> m_default_pipe; // Default communication pipe (endpoint0) used during enumeration