From 7b42146f332a9d68ca1a56f73771b29a550be66a Mon Sep 17 00:00:00 2001 From: Jesse Buhagiar Date: Tue, 8 Jun 2021 00:08:41 +1000 Subject: [PATCH] USB: Store devices in globally accessible array USB Devices are now stored so that they may be later retrieved and operated on (i.e, fetching their assigned device address via ProcFS) --- Kernel/Devices/USB/UHCIController.cpp | 25 +++++++++++++++++++++++++ Kernel/Devices/USB/UHCIController.h | 6 ++++++ Kernel/Devices/USB/USBDevice.cpp | 4 ++-- Kernel/Devices/USB/USBDevice.h | 10 +++++----- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/Kernel/Devices/USB/UHCIController.cpp b/Kernel/Devices/USB/UHCIController.cpp index d11a887789d..e5b3af0cf83 100644 --- a/Kernel/Devices/USB/UHCIController.cpp +++ b/Kernel/Devices/USB/UHCIController.cpp @@ -103,6 +103,27 @@ UNMAP_AFTER_INIT UHCIController::~UHCIController() { } +RefPtr const UHCIController::get_device_at_port(USB::Device::PortNumber port) +{ + if (!m_devices.at(to_underlying(port))) + return nullptr; + + return m_devices.at(to_underlying(port)); +} + +RefPtr const UHCIController::get_device_from_address(u8 device_address) +{ + for (auto const& device : m_devices) { + if (!device) + continue; + + if (device->address() == device_address) + return device; + } + + return nullptr; +} + void UHCIController::reset() { stop(); @@ -545,6 +566,8 @@ void UHCIController::spawn_port_proc() if (device.is_error()) dmesgln("UHCI: Device creation failed on port 1 ({})", device.error()); + + m_devices.at(0) = device.value(); } else { dmesgln("UHCI: Device detach detected on Root Port 1"); } @@ -575,6 +598,8 @@ void UHCIController::spawn_port_proc() if (device.is_error()) dmesgln("UHCI: Device creation failed on port 2 ({})", device.error()); + + m_devices.at(1) = device.value(); } else { dmesgln("UHCI: Device detach detected on Root Port 2"); } diff --git a/Kernel/Devices/USB/UHCIController.h b/Kernel/Devices/USB/UHCIController.h index 8ebbc907989..97318773721 100644 --- a/Kernel/Devices/USB/UHCIController.h +++ b/Kernel/Devices/USB/UHCIController.h @@ -26,6 +26,7 @@ class UHCIController final : public PCI::Device { public: static void detect(); static UHCIController& the(); + virtual ~UHCIController() override; virtual const char* purpose() const override { return "UHCI"; } @@ -39,6 +40,9 @@ public: KResultOr submit_control_transfer(Transfer& transfer); + RefPtr const get_device_at_port(USB::Device::PortNumber); + RefPtr const get_device_from_address(u8 device_address); + private: UHCIController(PCI::Address, PCI::ID); @@ -89,6 +93,8 @@ private: OwnPtr m_framelist; OwnPtr m_qh_pool; OwnPtr m_td_pool; + + Array, 2> m_devices; // Devices connected to the root ports (of which there are two) }; } diff --git a/Kernel/Devices/USB/USBDevice.cpp b/Kernel/Devices/USB/USBDevice.cpp index b13f568a3af..fcb5773a81f 100644 --- a/Kernel/Devices/USB/USBDevice.cpp +++ b/Kernel/Devices/USB/USBDevice.cpp @@ -16,13 +16,13 @@ static u32 s_next_usb_address = 1; // Next address we hand out to a device once namespace Kernel::USB { -KResultOr> Device::try_create(PortNumber port, DeviceSpeed speed) +KResultOr> Device::try_create(PortNumber port, DeviceSpeed speed) { auto pipe_or_error = Pipe::try_create_pipe(Pipe::Type::Control, Pipe::Direction::Bidirectional, 0, 8, 0); if (pipe_or_error.is_error()) return pipe_or_error.error(); - auto device = adopt_own_if_nonnull(new Device(port, speed, pipe_or_error.release_value())); + auto device = adopt_ref_if_nonnull(new Device(port, speed, pipe_or_error.release_value())); if (!device) return ENOMEM; diff --git a/Kernel/Devices/USB/USBDevice.h b/Kernel/Devices/USB/USBDevice.h index 8b08d9552df..bcf95a4dcbb 100644 --- a/Kernel/Devices/USB/USBDevice.h +++ b/Kernel/Devices/USB/USBDevice.h @@ -17,7 +17,7 @@ namespace Kernel::USB { // glues together: // // https://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_113_Simplified%20Description%20of%20USB%20Device%20Enumeration.pdf -class Device { +class Device : public RefCounted { public: enum class PortNumber : u8 { Port1 = 0, @@ -30,8 +30,7 @@ public: }; public: - static KResultOr> try_create(PortNumber, DeviceSpeed); - static Device* get(PortNumber); + static KResultOr> try_create(PortNumber, DeviceSpeed); Device(PortNumber, DeviceSpeed, NonnullOwnPtr default_pipe); ~Device(); @@ -50,8 +49,9 @@ private: u8 m_address { 0 }; // USB address assigned to this device // Device description - 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 + 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 NonnullOwnPtr m_default_pipe; // Default communication pipe (endpoint0) used during enumeration };