Serenity Operating System
at master 150 lines 7.0 kB view raw
1/* 2 * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/OwnPtr.h> 8#include <AK/Types.h> 9#include <AK/Vector.h> 10#include <Kernel/Bus/USB/USBController.h> 11#include <Kernel/Bus/USB/USBDescriptors.h> 12#include <Kernel/Bus/USB/USBDevice.h> 13#include <Kernel/Bus/USB/USBRequest.h> 14#include <Kernel/FileSystem/SysFS/Subsystems/Bus/USB/DeviceInformation.h> 15#include <Kernel/StdLib.h> 16 17namespace Kernel::USB { 18 19ErrorOr<NonnullLockRefPtr<Device>> Device::try_create(USBController const& controller, u8 port, DeviceSpeed speed) 20{ 21 auto pipe = TRY(ControlPipe::create(controller, 0, 8, 0)); 22 auto device = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) Device(controller, port, speed, move(pipe)))); 23 auto sysfs_node = TRY(SysFSUSBDeviceInformation::create(*device)); 24 device->m_sysfs_device_info_node = move(sysfs_node); 25 TRY(device->enumerate_device()); 26 return device; 27} 28 29Device::Device(USBController const& controller, u8 port, DeviceSpeed speed, NonnullOwnPtr<ControlPipe> default_pipe) 30 : m_device_port(port) 31 , m_device_speed(speed) 32 , m_address(0) 33 , m_controller(controller) 34 , m_default_pipe(move(default_pipe)) 35{ 36} 37 38Device::Device(NonnullLockRefPtr<USBController> controller, u8 address, u8 port, DeviceSpeed speed, NonnullOwnPtr<ControlPipe> default_pipe) 39 : m_device_port(port) 40 , m_device_speed(speed) 41 , m_address(address) 42 , m_controller(move(controller)) 43 , m_default_pipe(move(default_pipe)) 44{ 45} 46 47Device::Device(Device const& device, NonnullOwnPtr<ControlPipe> default_pipe) 48 : m_device_port(device.port()) 49 , m_device_speed(device.speed()) 50 , m_address(device.address()) 51 , m_device_descriptor(device.device_descriptor()) 52 , m_controller(device.controller()) 53 , m_default_pipe(move(default_pipe)) 54{ 55} 56 57Device::~Device() = default; 58 59ErrorOr<void> Device::enumerate_device() 60{ 61 USBDeviceDescriptor dev_descriptor {}; 62 63 // Send 8-bytes to get at least the `max_packet_size` from the device 64 constexpr u8 short_device_descriptor_length = 8; 65 auto transfer_length = TRY(m_default_pipe->submit_control_transfer(USB_REQUEST_TRANSFER_DIRECTION_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, (DESCRIPTOR_TYPE_DEVICE << 8), 0, short_device_descriptor_length, &dev_descriptor)); 66 67 // FIXME: This be "not equal to" instead of "less than", but control transfers report a higher transfer length than expected. 68 if (transfer_length < short_device_descriptor_length) { 69 dbgln("USB Device: Not enough bytes for short device descriptor. Expected {}, got {}.", short_device_descriptor_length, transfer_length); 70 return EIO; 71 } 72 73 if constexpr (USB_DEBUG) { 74 dbgln("USB Short Device Descriptor:"); 75 dbgln("Descriptor length: {}", dev_descriptor.descriptor_header.length); 76 dbgln("Descriptor type: {}", dev_descriptor.descriptor_header.descriptor_type); 77 78 dbgln("Device Class: {:02x}", dev_descriptor.device_class); 79 dbgln("Device Sub-Class: {:02x}", dev_descriptor.device_sub_class); 80 dbgln("Device Protocol: {:02x}", dev_descriptor.device_protocol); 81 dbgln("Max Packet Size: {:02x} bytes", dev_descriptor.max_packet_size); 82 } 83 84 // Ensure that this is actually a valid device descriptor... 85 VERIFY(dev_descriptor.descriptor_header.descriptor_type == DESCRIPTOR_TYPE_DEVICE); 86 m_default_pipe->set_max_packet_size(dev_descriptor.max_packet_size); 87 88 transfer_length = TRY(m_default_pipe->submit_control_transfer(USB_REQUEST_TRANSFER_DIRECTION_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, (DESCRIPTOR_TYPE_DEVICE << 8), 0, sizeof(USBDeviceDescriptor), &dev_descriptor)); 89 90 // FIXME: This be "not equal to" instead of "less than", but control transfers report a higher transfer length than expected. 91 if (transfer_length < sizeof(USBDeviceDescriptor)) { 92 dbgln("USB Device: Unexpected device descriptor length. Expected {}, got {}.", sizeof(USBDeviceDescriptor), transfer_length); 93 return EIO; 94 } 95 96 // Ensure that this is actually a valid device descriptor... 97 VERIFY(dev_descriptor.descriptor_header.descriptor_type == DESCRIPTOR_TYPE_DEVICE); 98 99 if constexpr (USB_DEBUG) { 100 dbgln("USB Device Descriptor for {:04x}:{:04x}", dev_descriptor.vendor_id, dev_descriptor.product_id); 101 dbgln("Device Class: {:02x}", dev_descriptor.device_class); 102 dbgln("Device Sub-Class: {:02x}", dev_descriptor.device_sub_class); 103 dbgln("Device Protocol: {:02x}", dev_descriptor.device_protocol); 104 dbgln("Max Packet Size: {:02x} bytes", dev_descriptor.max_packet_size); 105 dbgln("Number of configurations: {:02x}", dev_descriptor.num_configurations); 106 } 107 108 auto new_address = m_controller->allocate_address(); 109 110 // Attempt to set devices address on the bus 111 transfer_length = TRY(m_default_pipe->submit_control_transfer(USB_REQUEST_TRANSFER_DIRECTION_HOST_TO_DEVICE, USB_REQUEST_SET_ADDRESS, new_address, 0, 0, nullptr)); 112 113 // This has to be set after we send out the "Set Address" request because it might be sent to the root hub. 114 // The root hub uses the address to intercept requests to itself. 115 m_address = new_address; 116 m_default_pipe->set_device_address(new_address); 117 118 dbgln_if(USB_DEBUG, "USB Device: Set address to {}", m_address); 119 120 memcpy(&m_device_descriptor, &dev_descriptor, sizeof(USBDeviceDescriptor)); 121 122 // Fetch the configuration descriptors from the device 123 m_configurations.ensure_capacity(m_device_descriptor.num_configurations); 124 for (auto configuration = 0u; configuration < m_device_descriptor.num_configurations; configuration++) { 125 USBConfigurationDescriptor configuration_descriptor; 126 transfer_length = TRY(m_default_pipe->submit_control_transfer(USB_REQUEST_TRANSFER_DIRECTION_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, (DESCRIPTOR_TYPE_CONFIGURATION << 8u) | configuration, 0, sizeof(USBConfigurationDescriptor), &configuration_descriptor)); 127 128 if constexpr (USB_DEBUG) { 129 dbgln("USB Configuration Descriptor {}", configuration); 130 dbgln("Total Length: {}", configuration_descriptor.total_length); 131 dbgln("Number of interfaces: {}", configuration_descriptor.number_of_interfaces); 132 dbgln("Configuration Value: {}", configuration_descriptor.configuration_value); 133 dbgln("Attributes Bitmap: {:08b}", configuration_descriptor.attributes_bitmap); 134 dbgln("Maximum Power: {}mA", configuration_descriptor.max_power_in_ma * 2u); // This value is in 2mA steps 135 } 136 137 USBConfiguration device_configuration(*this, configuration_descriptor); 138 TRY(device_configuration.enumerate_interfaces()); 139 m_configurations.append(device_configuration); 140 } 141 142 return {}; 143} 144 145ErrorOr<size_t> Device::control_transfer(u8 request_type, u8 request, u16 value, u16 index, u16 length, void* data) 146{ 147 return TRY(m_default_pipe->submit_control_transfer(request_type, request, value, index, length, data)); 148} 149 150}