Serenity Operating System
at master 108 lines 3.3 kB view raw
1/* 2 * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/Types.h> 10#include <Kernel/Bus/USB/USBDevice.h> 11 12namespace Kernel::USB { 13 14// USB 2.0 Specification Page 421 Table 11-16 15enum HubRequest : u8 { 16 GET_STATUS = 0, 17 CLEAR_FEATURE = 1, 18 // 2 is reserved. 19 SET_FEATURE = 3, 20 // 4-5 are reserved. 21 GET_DESCRIPTOR = 6, 22 SET_DESCRIPTOR = 7, 23 CLEAR_TT_BUFFER = 8, 24 RESET_TT = 9, 25 GET_TT_STATE = 10, 26 STOP_TT = 11, 27}; 28 29// USB 2.0 Specification Pages 421-422 Table 11-17 30enum HubFeatureSelector : u8 { 31 C_HUB_LOCAL_POWER = 0, 32 C_HUB_OVER_CURRENT = 1, 33 PORT_CONNECTION = 0, 34 PORT_ENABLE = 1, 35 PORT_SUSPEND = 2, 36 PORT_OVER_CURRENT = 3, 37 PORT_RESET = 4, 38 PORT_POWER = 8, 39 PORT_LOW_SPEED = 9, 40 C_PORT_CONNECTION = 16, 41 C_PORT_ENABLE = 17, 42 C_PORT_SUSPEND = 18, 43 C_PORT_OVER_CURRENT = 19, 44 C_PORT_RESET = 20, 45 PORT_TEST = 21, 46 PORT_INDICATOR = 22, 47}; 48 49// USB 2.0 Specification Section 11.24.2.{6,7} 50// This is used to store both the hub status and port status, as they have the same layout. 51struct [[gnu::packed]] HubStatus { 52 u16 status { 0 }; 53 u16 change { 0 }; 54}; 55static_assert(AssertSize<HubStatus, 4>()); 56 57static constexpr u16 HUB_STATUS_LOCAL_POWER_SOURCE = (1 << 0); 58static constexpr u16 HUB_STATUS_OVER_CURRENT = (1 << 1); 59 60static constexpr u16 HUB_STATUS_LOCAL_POWER_SOURCE_CHANGED = (1 << 0); 61static constexpr u16 HUB_STATUS_OVER_CURRENT_CHANGED = (1 << 1); 62 63static constexpr u16 PORT_STATUS_CURRENT_CONNECT_STATUS = (1 << 0); 64static constexpr u16 PORT_STATUS_PORT_ENABLED = (1 << 1); 65static constexpr u16 PORT_STATUS_SUSPEND = (1 << 2); 66static constexpr u16 PORT_STATUS_OVER_CURRENT = (1 << 3); 67static constexpr u16 PORT_STATUS_RESET = (1 << 4); 68static constexpr u16 PORT_STATUS_PORT_POWER = (1 << 8); 69static constexpr u16 PORT_STATUS_LOW_SPEED_DEVICE_ATTACHED = (1 << 9); 70static constexpr u16 PORT_STATUS_HIGH_SPEED_DEVICE_ATTACHED = (1 << 10); 71static constexpr u16 PORT_STATUS_PORT_STATUS_MODE = (1 << 11); 72static constexpr u16 PORT_STATUS_PORT_INDICATOR_CONTROL = (1 << 12); 73 74static constexpr u16 PORT_STATUS_CONNECT_STATUS_CHANGED = (1 << 0); 75static constexpr u16 PORT_STATUS_PORT_ENABLED_CHANGED = (1 << 1); 76static constexpr u16 PORT_STATUS_SUSPEND_CHANGED = (1 << 2); 77static constexpr u16 PORT_STATUS_OVER_CURRENT_INDICATOR_CHANGED = (1 << 3); 78static constexpr u16 PORT_STATUS_RESET_CHANGED = (1 << 4); 79 80class Hub : public Device { 81public: 82 static ErrorOr<NonnullLockRefPtr<Hub>> try_create_root_hub(NonnullLockRefPtr<USBController>, DeviceSpeed); 83 static ErrorOr<NonnullLockRefPtr<Hub>> try_create_from_device(Device const&); 84 85 virtual ~Hub() override = default; 86 87 ErrorOr<void> enumerate_and_power_on_hub(); 88 89 ErrorOr<void> get_port_status(u8, HubStatus&); 90 ErrorOr<void> clear_port_feature(u8, HubFeatureSelector); 91 ErrorOr<void> set_port_feature(u8, HubFeatureSelector); 92 93 void check_for_port_updates(); 94 95private: 96 // Root Hub constructor 97 Hub(NonnullLockRefPtr<USBController>, DeviceSpeed, NonnullOwnPtr<ControlPipe> default_pipe); 98 99 Hub(Device const&, NonnullOwnPtr<ControlPipe> default_pipe); 100 101 USBHubDescriptor m_hub_descriptor {}; 102 103 Device::List m_children; 104 105 void remove_children_from_sysfs(); 106}; 107 108}