/* * Copyright (c) 2021, Jesse Buhagiar * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include namespace Kernel::USB { class USBController; // // Some nice info from FTDI on device enumeration and how some of this // glues together: // // https://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_113_Simplified%20Description%20of%20USB%20Device%20Enumeration.pdf class Device : public RefCounted { public: enum class DeviceSpeed : u8 { FullSpeed = 0, LowSpeed }; static ErrorOr> try_create(USBController const&, u8, DeviceSpeed); Device(USBController const&, u8, DeviceSpeed, NonnullOwnPtr default_pipe); Device(Device const& device, NonnullOwnPtr default_pipe); virtual ~Device(); ErrorOr enumerate_device(); u8 port() const { return m_device_port; } DeviceSpeed speed() const { return m_device_speed; } u8 address() const { return m_address; } const USBDeviceDescriptor& device_descriptor() const { return m_device_descriptor; } USBController& controller() { return *m_controller; } USBController const& controller() const { return *m_controller; } protected: Device(NonnullRefPtr controller, u8 address, u8 port, DeviceSpeed speed, NonnullOwnPtr default_pipe); u8 m_device_port { 0 }; // What port is this device attached to. NOTE: This is 1-based. DeviceSpeed m_device_speed; // What speed is this device running at 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 USBDeviceDescriptor m_device_descriptor; // Device Descriptor obtained from USB Device NonnullRefPtr m_controller; NonnullOwnPtr m_default_pipe; // Default communication pipe (endpoint0) used during enumeration private: IntrusiveListNode> m_hub_child_node; public: using List = IntrusiveList<&Device::m_hub_child_node>; }; }