diff options
author | Jesse Buhagiar <jooster669@gmail.com> | 2022-04-11 20:18:31 +1000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-04-22 15:16:56 +0200 |
commit | dac26f89cb4407133d73e1dc6ceae022f3837572 (patch) | |
tree | f0ffbb7e5c3477b6509e987589e87d9e0475617f /Kernel/Bus | |
parent | 1409a48da63fdeb841474302c43141a56e7c8e81 (diff) | |
download | serenity-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/Bus')
-rw-r--r-- | Kernel/Bus/USB/USBConfiguration.h | 38 | ||||
-rw-r--r-- | Kernel/Bus/USB/USBDevice.cpp | 20 | ||||
-rw-r--r-- | Kernel/Bus/USB/USBDevice.h | 4 |
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 |