#pragma once #include #include #include #include #include namespace Kernel { class USBClassDriver { BAN_NON_COPYABLE(USBClassDriver); BAN_NON_MOVABLE(USBClassDriver); public: USBClassDriver() = default; virtual ~USBClassDriver() = default; virtual void handle_input_data(BAN::ConstByteSpan, uint8_t endpoint_id) = 0; }; class USBDevice { BAN_NON_COPYABLE(USBDevice); BAN_NON_MOVABLE(USBDevice); public: struct EndpointDescriptor { USBEndpointDescriptor descriptor; }; struct InterfaceDescriptor { USBInterfaceDescriptor descriptor; BAN::Vector endpoints; BAN::Vector> misc_descriptors; }; struct ConfigurationDescriptor { USBConfigurationDescriptor desciptor; BAN::Vector interfaces; }; struct DeviceDescriptor { USBDeviceDescriptor descriptor; BAN::Vector configurations; }; public: USBDevice(USB::SpeedClass speed_class) : m_speed_class(speed_class) {} virtual ~USBDevice() = default; BAN::ErrorOr initialize(); const BAN::Vector& configurations() { return m_descriptor.configurations; } virtual BAN::ErrorOr initialize_endpoint(const USBEndpointDescriptor&) = 0; virtual BAN::ErrorOr send_request(const USBDeviceRequest&, paddr_t buffer) = 0; static USB::SpeedClass determine_speed_class(uint64_t bits_per_second); protected: void handle_input_data(BAN::ConstByteSpan, uint8_t endpoint_id); virtual BAN::ErrorOr initialize_control_endpoint() = 0; private: BAN::ErrorOr parse_configuration(size_t index); protected: const USB::SpeedClass m_speed_class; private: DeviceDescriptor m_descriptor; BAN::UniqPtr m_dma_buffer; // FIXME: support more than one interface from a configuration BAN::UniqPtr m_class_driver; }; }