mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:07:45 +00:00
Kernel/USB: Use TRY() in the various USB classes
This commit is contained in:
parent
f8fba5f017
commit
29a9f80ecf
5 changed files with 39 additions and 117 deletions
|
@ -64,15 +64,9 @@ static constexpr u16 UHCI_NUMBER_OF_FRAMES = 1024;
|
||||||
KResultOr<NonnullRefPtr<UHCIController>> UHCIController::try_to_initialize(PCI::Address address)
|
KResultOr<NonnullRefPtr<UHCIController>> UHCIController::try_to_initialize(PCI::Address address)
|
||||||
{
|
{
|
||||||
// NOTE: This assumes that address is pointing to a valid UHCI controller.
|
// NOTE: This assumes that address is pointing to a valid UHCI controller.
|
||||||
auto controller = adopt_ref_if_nonnull(new (nothrow) UHCIController(address));
|
auto controller = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) UHCIController(address)));
|
||||||
if (!controller)
|
TRY(controller->initialize());
|
||||||
return ENOMEM;
|
return controller;
|
||||||
|
|
||||||
auto init_result = controller->initialize();
|
|
||||||
if (init_result.is_error())
|
|
||||||
return init_result;
|
|
||||||
|
|
||||||
return controller.release_nonnull();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KResult UHCIController::initialize()
|
KResult UHCIController::initialize()
|
||||||
|
@ -83,12 +77,8 @@ KResult UHCIController::initialize()
|
||||||
|
|
||||||
spawn_port_proc();
|
spawn_port_proc();
|
||||||
|
|
||||||
auto reset_result = reset();
|
TRY(reset());
|
||||||
if (reset_result.is_error())
|
return start();
|
||||||
return reset_result;
|
|
||||||
|
|
||||||
auto start_result = start();
|
|
||||||
return start_result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UNMAP_AFTER_INIT UHCIController::UHCIController(PCI::Address address)
|
UNMAP_AFTER_INIT UHCIController::UHCIController(PCI::Address address)
|
||||||
|
@ -104,8 +94,7 @@ UNMAP_AFTER_INIT UHCIController::~UHCIController()
|
||||||
|
|
||||||
KResult UHCIController::reset()
|
KResult UHCIController::reset()
|
||||||
{
|
{
|
||||||
if (auto stop_result = stop(); stop_result.is_error())
|
TRY(stop());
|
||||||
return stop_result;
|
|
||||||
|
|
||||||
write_usbcmd(UHCI_USBCMD_HOST_CONTROLLER_RESET);
|
write_usbcmd(UHCI_USBCMD_HOST_CONTROLLER_RESET);
|
||||||
|
|
||||||
|
@ -117,17 +106,14 @@ KResult UHCIController::reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's allocate the physical page for the Frame List (which is 4KiB aligned)
|
// Let's allocate the physical page for the Frame List (which is 4KiB aligned)
|
||||||
auto maybe_framelist_vmobj = Memory::AnonymousVMObject::try_create_physically_contiguous_with_size(PAGE_SIZE);
|
auto vmobject = TRY(Memory::AnonymousVMObject::try_create_physically_contiguous_with_size(PAGE_SIZE));
|
||||||
if (maybe_framelist_vmobj.is_error())
|
|
||||||
return maybe_framelist_vmobj.error();
|
|
||||||
|
|
||||||
m_framelist = MM.allocate_kernel_region_with_vmobject(maybe_framelist_vmobj.release_value(), PAGE_SIZE, "UHCI Framelist", Memory::Region::Access::Write);
|
m_framelist = MM.allocate_kernel_region_with_vmobject(move(vmobject), PAGE_SIZE, "UHCI Framelist", Memory::Region::Access::Write);
|
||||||
dbgln("UHCI: Allocated framelist at physical address {}", m_framelist->physical_page(0)->paddr());
|
dbgln("UHCI: Allocated framelist at physical address {}", m_framelist->physical_page(0)->paddr());
|
||||||
dbgln("UHCI: Framelist is at virtual address {}", m_framelist->vaddr());
|
dbgln("UHCI: Framelist is at virtual address {}", m_framelist->vaddr());
|
||||||
write_sofmod(64); // 1mS frame time
|
write_sofmod(64); // 1mS frame time
|
||||||
|
|
||||||
if (auto result = create_structures(); result.is_error())
|
TRY(create_structures());
|
||||||
return result;
|
|
||||||
|
|
||||||
setup_schedule();
|
setup_schedule();
|
||||||
|
|
||||||
|
@ -158,9 +144,7 @@ UNMAP_AFTER_INIT KResult UHCIController::create_structures()
|
||||||
m_dummy_qh = allocate_queue_head();
|
m_dummy_qh = allocate_queue_head();
|
||||||
|
|
||||||
// Now the Transfer Descriptor pool
|
// Now the Transfer Descriptor pool
|
||||||
auto maybe_td_pool_vmobject = Memory::AnonymousVMObject::try_create_physically_contiguous_with_size(PAGE_SIZE);
|
auto td_pool_vmobject = TRY(Memory::AnonymousVMObject::try_create_physically_contiguous_with_size(PAGE_SIZE));
|
||||||
if (maybe_td_pool_vmobject.is_error())
|
|
||||||
return maybe_td_pool_vmobject.error();
|
|
||||||
|
|
||||||
m_transfer_descriptor_pool = UHCIDescriptorPool<TransferDescriptor>::try_create("Transfer Descriptor Pool");
|
m_transfer_descriptor_pool = UHCIDescriptorPool<TransferDescriptor>::try_create("Transfer Descriptor Pool");
|
||||||
if (!m_transfer_descriptor_pool) {
|
if (!m_transfer_descriptor_pool) {
|
||||||
|
@ -168,7 +152,7 @@ UNMAP_AFTER_INIT KResult UHCIController::create_structures()
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_isochronous_transfer_pool = MM.allocate_kernel_region_with_vmobject(*maybe_td_pool_vmobject.release_value(), PAGE_SIZE, "UHCI Isochronous Descriptor Pool", Memory::Region::Access::ReadWrite);
|
m_isochronous_transfer_pool = MM.allocate_kernel_region_with_vmobject(move(td_pool_vmobject), PAGE_SIZE, "UHCI Isochronous Descriptor Pool", Memory::Region::Access::ReadWrite);
|
||||||
if (!m_isochronous_transfer_pool) {
|
if (!m_isochronous_transfer_pool) {
|
||||||
dmesgln("UHCI: Failed to allocated Isochronous Descriptor Pool!");
|
dmesgln("UHCI: Failed to allocated Isochronous Descriptor Pool!");
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
@ -293,15 +277,8 @@ KResult UHCIController::start()
|
||||||
}
|
}
|
||||||
dbgln("UHCI: Started");
|
dbgln("UHCI: Started");
|
||||||
|
|
||||||
auto root_hub_or_error = UHCIRootHub::try_create(*this);
|
m_root_hub = TRY(UHCIRootHub::try_create(*this));
|
||||||
if (root_hub_or_error.is_error())
|
TRY(m_root_hub->setup({}));
|
||||||
return root_hub_or_error.error();
|
|
||||||
|
|
||||||
m_root_hub = root_hub_or_error.release_value();
|
|
||||||
auto result = m_root_hub->setup({});
|
|
||||||
if (result.is_error())
|
|
||||||
return result;
|
|
||||||
|
|
||||||
return KSuccess;
|
return KSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,8 +393,7 @@ KResultOr<size_t> UHCIController::submit_control_transfer(Transfer& transfer)
|
||||||
TransferDescriptor* last_data_descriptor;
|
TransferDescriptor* last_data_descriptor;
|
||||||
TransferDescriptor* data_descriptor_chain;
|
TransferDescriptor* data_descriptor_chain;
|
||||||
auto buffer_address = Ptr32<u8>(transfer.buffer_physical().as_ptr() + sizeof(USBRequestData));
|
auto buffer_address = Ptr32<u8>(transfer.buffer_physical().as_ptr() + sizeof(USBRequestData));
|
||||||
if (auto result = create_chain(pipe, direction_in ? PacketID::IN : PacketID::OUT, buffer_address, pipe.max_packet_size(), transfer.transfer_data_size(), &data_descriptor_chain, &last_data_descriptor); result.is_error())
|
TRY(create_chain(pipe, direction_in ? PacketID::IN : PacketID::OUT, buffer_address, pipe.max_packet_size(), transfer.transfer_data_size(), &data_descriptor_chain, &last_data_descriptor));
|
||||||
return result;
|
|
||||||
|
|
||||||
// Status TD always has toggle set to 1
|
// Status TD always has toggle set to 1
|
||||||
pipe.set_toggle(true);
|
pipe.set_toggle(true);
|
||||||
|
|
|
@ -99,22 +99,14 @@ UHCIRootHub::UHCIRootHub(NonnullRefPtr<UHCIController> uhci_controller)
|
||||||
|
|
||||||
KResult UHCIRootHub::setup(Badge<UHCIController>)
|
KResult UHCIRootHub::setup(Badge<UHCIController>)
|
||||||
{
|
{
|
||||||
auto hub_or_error = Hub::try_create_root_hub(m_uhci_controller, Device::DeviceSpeed::FullSpeed);
|
m_hub = TRY(Hub::try_create_root_hub(m_uhci_controller, Device::DeviceSpeed::FullSpeed));
|
||||||
if (hub_or_error.is_error())
|
|
||||||
return hub_or_error.error();
|
|
||||||
|
|
||||||
m_hub = hub_or_error.release_value();
|
|
||||||
|
|
||||||
// NOTE: The root hub will be on the default address at this point.
|
// NOTE: The root hub will be on the default address at this point.
|
||||||
// The root hub must be the first device to be created, otherwise the HCD will intercept all default address transfers as though they're targeted at the root hub.
|
// The root hub must be the first device to be created, otherwise the HCD will intercept all default address transfers as though they're targeted at the root hub.
|
||||||
auto result = m_hub->enumerate_device();
|
TRY(m_hub->enumerate_device());
|
||||||
if (result.is_error())
|
|
||||||
return result;
|
|
||||||
|
|
||||||
// NOTE: The root hub is no longer on the default address.
|
// NOTE: The root hub is no longer on the default address.
|
||||||
result = m_hub->enumerate_and_power_on_hub();
|
TRY(m_hub->enumerate_and_power_on_hub());
|
||||||
if (result.is_error())
|
|
||||||
return result;
|
|
||||||
|
|
||||||
return KSuccess;
|
return KSuccess;
|
||||||
}
|
}
|
||||||
|
@ -219,9 +211,7 @@ KResultOr<size_t> UHCIRootHub::handle_control_transfer(Transfer& transfer)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
auto feature_selector = (HubFeatureSelector)request.value;
|
auto feature_selector = (HubFeatureSelector)request.value;
|
||||||
auto result = m_uhci_controller->set_port_feature({}, port - 1, feature_selector);
|
TRY(m_uhci_controller->set_port_feature({}, port - 1, feature_selector));
|
||||||
if (result.is_error())
|
|
||||||
return result.error();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HubRequest::CLEAR_FEATURE: {
|
case HubRequest::CLEAR_FEATURE: {
|
||||||
|
@ -246,9 +236,7 @@ KResultOr<size_t> UHCIRootHub::handle_control_transfer(Transfer& transfer)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
auto feature_selector = (HubFeatureSelector)request.value;
|
auto feature_selector = (HubFeatureSelector)request.value;
|
||||||
auto result = m_uhci_controller->clear_port_feature({}, port - 1, feature_selector);
|
TRY(m_uhci_controller->clear_port_feature({}, port - 1, feature_selector));
|
||||||
if (result.is_error())
|
|
||||||
return result.error();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -18,17 +18,13 @@ namespace Kernel::USB {
|
||||||
|
|
||||||
KResultOr<NonnullRefPtr<Device>> Device::try_create(USBController const& controller, u8 port, DeviceSpeed speed)
|
KResultOr<NonnullRefPtr<Device>> Device::try_create(USBController const& controller, u8 port, DeviceSpeed speed)
|
||||||
{
|
{
|
||||||
auto pipe_or_error = Pipe::try_create_pipe(controller, Pipe::Type::Control, Pipe::Direction::Bidirectional, 0, 8, 0);
|
auto pipe = TRY(Pipe::try_create_pipe(controller, Pipe::Type::Control, Pipe::Direction::Bidirectional, 0, 8, 0));
|
||||||
if (pipe_or_error.is_error())
|
|
||||||
return pipe_or_error.error();
|
|
||||||
|
|
||||||
auto device = try_make_ref_counted<Device>(controller, port, speed, pipe_or_error.release_value());
|
auto device = try_make_ref_counted<Device>(controller, port, speed, move(pipe));
|
||||||
if (!device)
|
if (!device)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
auto enumerate_result = device->enumerate_device();
|
TRY(device->enumerate_device());
|
||||||
if (enumerate_result.is_error())
|
|
||||||
return enumerate_result;
|
|
||||||
|
|
||||||
return device.release_nonnull();
|
return device.release_nonnull();
|
||||||
}
|
}
|
||||||
|
@ -71,12 +67,7 @@ KResult Device::enumerate_device()
|
||||||
|
|
||||||
// Send 8-bytes to get at least the `max_packet_size` from the device
|
// Send 8-bytes to get at least the `max_packet_size` from the device
|
||||||
constexpr u8 short_device_descriptor_length = 8;
|
constexpr u8 short_device_descriptor_length = 8;
|
||||||
auto transfer_length_or_error = m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, (DESCRIPTOR_TYPE_DEVICE << 8), 0, short_device_descriptor_length, &dev_descriptor);
|
auto transfer_length = TRY(m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, (DESCRIPTOR_TYPE_DEVICE << 8), 0, short_device_descriptor_length, &dev_descriptor));
|
||||||
|
|
||||||
if (transfer_length_or_error.is_error())
|
|
||||||
return transfer_length_or_error.error();
|
|
||||||
|
|
||||||
auto transfer_length = transfer_length_or_error.release_value();
|
|
||||||
|
|
||||||
// FIXME: This be "not equal to" instead of "less than", but control transfers report a higher transfer length than expected.
|
// FIXME: This be "not equal to" instead of "less than", but control transfers report a higher transfer length than expected.
|
||||||
if (transfer_length < short_device_descriptor_length) {
|
if (transfer_length < short_device_descriptor_length) {
|
||||||
|
@ -99,12 +90,7 @@ KResult Device::enumerate_device()
|
||||||
VERIFY(dev_descriptor.descriptor_header.descriptor_type == DESCRIPTOR_TYPE_DEVICE);
|
VERIFY(dev_descriptor.descriptor_header.descriptor_type == DESCRIPTOR_TYPE_DEVICE);
|
||||||
m_default_pipe->set_max_packet_size(dev_descriptor.max_packet_size);
|
m_default_pipe->set_max_packet_size(dev_descriptor.max_packet_size);
|
||||||
|
|
||||||
transfer_length_or_error = m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, (DESCRIPTOR_TYPE_DEVICE << 8), 0, sizeof(USBDeviceDescriptor), &dev_descriptor);
|
transfer_length = TRY(m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_DEVICE_TO_HOST, USB_REQUEST_GET_DESCRIPTOR, (DESCRIPTOR_TYPE_DEVICE << 8), 0, sizeof(USBDeviceDescriptor), &dev_descriptor));
|
||||||
|
|
||||||
if (transfer_length_or_error.is_error())
|
|
||||||
return transfer_length_or_error.error();
|
|
||||||
|
|
||||||
transfer_length = transfer_length_or_error.release_value();
|
|
||||||
|
|
||||||
// FIXME: This be "not equal to" instead of "less than", but control transfers report a higher transfer length than expected.
|
// FIXME: This be "not equal to" instead of "less than", but control transfers report a higher transfer length than expected.
|
||||||
if (transfer_length < sizeof(USBDeviceDescriptor)) {
|
if (transfer_length < sizeof(USBDeviceDescriptor)) {
|
||||||
|
@ -127,10 +113,7 @@ KResult Device::enumerate_device()
|
||||||
auto new_address = m_controller->allocate_address();
|
auto new_address = m_controller->allocate_address();
|
||||||
|
|
||||||
// Attempt to set devices address on the bus
|
// Attempt to set devices address on the bus
|
||||||
transfer_length_or_error = m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_HOST_TO_DEVICE, USB_REQUEST_SET_ADDRESS, new_address, 0, 0, nullptr);
|
transfer_length = TRY(m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_HOST_TO_DEVICE, USB_REQUEST_SET_ADDRESS, new_address, 0, 0, nullptr));
|
||||||
|
|
||||||
if (transfer_length_or_error.is_error())
|
|
||||||
return transfer_length_or_error.error();
|
|
||||||
|
|
||||||
// This has to be set after we send out the "Set Address" request because it might be sent to the root hub.
|
// This has to be set after we send out the "Set Address" request because it might be sent to the root hub.
|
||||||
// The root hub uses the address to intercept requests to itself.
|
// The root hub uses the address to intercept requests to itself.
|
||||||
|
|
|
@ -15,11 +15,8 @@ namespace Kernel::USB {
|
||||||
|
|
||||||
KResultOr<NonnullRefPtr<Hub>> Hub::try_create_root_hub(NonnullRefPtr<USBController> controller, DeviceSpeed device_speed)
|
KResultOr<NonnullRefPtr<Hub>> Hub::try_create_root_hub(NonnullRefPtr<USBController> controller, DeviceSpeed device_speed)
|
||||||
{
|
{
|
||||||
auto pipe_or_error = Pipe::try_create_pipe(controller, Pipe::Type::Control, Pipe::Direction::Bidirectional, 0, 8, 0);
|
auto pipe = TRY(Pipe::try_create_pipe(controller, Pipe::Type::Control, Pipe::Direction::Bidirectional, 0, 8, 0));
|
||||||
if (pipe_or_error.is_error())
|
auto hub = try_make_ref_counted<Hub>(controller, device_speed, move(pipe));
|
||||||
return pipe_or_error.error();
|
|
||||||
|
|
||||||
auto hub = try_make_ref_counted<Hub>(controller, device_speed, pipe_or_error.release_value());
|
|
||||||
if (!hub)
|
if (!hub)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
|
@ -30,18 +27,11 @@ KResultOr<NonnullRefPtr<Hub>> Hub::try_create_root_hub(NonnullRefPtr<USBControll
|
||||||
|
|
||||||
KResultOr<NonnullRefPtr<Hub>> Hub::try_create_from_device(Device const& device)
|
KResultOr<NonnullRefPtr<Hub>> Hub::try_create_from_device(Device const& device)
|
||||||
{
|
{
|
||||||
auto pipe_or_error = Pipe::try_create_pipe(device.controller(), Pipe::Type::Control, Pipe::Direction::Bidirectional, 0, device.device_descriptor().max_packet_size, device.address());
|
auto pipe = TRY(Pipe::try_create_pipe(device.controller(), Pipe::Type::Control, Pipe::Direction::Bidirectional, 0, device.device_descriptor().max_packet_size, device.address()));
|
||||||
if (pipe_or_error.is_error())
|
auto hub = try_make_ref_counted<Hub>(device, move(pipe));
|
||||||
return pipe_or_error.error();
|
|
||||||
|
|
||||||
auto hub = try_make_ref_counted<Hub>(device, pipe_or_error.release_value());
|
|
||||||
if (!hub)
|
if (!hub)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
TRY(hub->enumerate_and_power_on_hub());
|
||||||
auto result = hub->enumerate_and_power_on_hub();
|
|
||||||
if (result.is_error())
|
|
||||||
return result;
|
|
||||||
|
|
||||||
return hub.release_nonnull();
|
return hub.release_nonnull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,13 +60,11 @@ KResult Hub::enumerate_and_power_on_hub()
|
||||||
USBHubDescriptor descriptor {};
|
USBHubDescriptor descriptor {};
|
||||||
|
|
||||||
// Get the first hub descriptor. All hubs are required to have a hub descriptor at index 0. USB 2.0 Specification Section 11.24.2.5.
|
// Get the first hub descriptor. All hubs are required to have a hub descriptor at index 0. USB 2.0 Specification Section 11.24.2.5.
|
||||||
auto transfer_length_or_error = m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS, HubRequest::GET_DESCRIPTOR, (DESCRIPTOR_TYPE_HUB << 8), 0, sizeof(USBHubDescriptor), &descriptor);
|
auto transfer_length = TRY(m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS, HubRequest::GET_DESCRIPTOR, (DESCRIPTOR_TYPE_HUB << 8), 0, sizeof(USBHubDescriptor), &descriptor));
|
||||||
if (transfer_length_or_error.is_error())
|
|
||||||
return transfer_length_or_error.error();
|
|
||||||
|
|
||||||
// FIXME: This be "not equal to" instead of "less than", but control transfers report a higher transfer length than expected.
|
// FIXME: This be "not equal to" instead of "less than", but control transfers report a higher transfer length than expected.
|
||||||
if (transfer_length_or_error.value() < sizeof(USBHubDescriptor)) {
|
if (transfer_length < sizeof(USBHubDescriptor)) {
|
||||||
dbgln("USB Hub: Unexpected hub descriptor size. Expected {}, got {}", sizeof(USBHubDescriptor), transfer_length_or_error.value());
|
dbgln("USB Hub: Unexpected hub descriptor size. Expected {}, got {}", sizeof(USBHubDescriptor), transfer_length);
|
||||||
return EIO;
|
return EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,13 +100,11 @@ KResult Hub::get_port_status(u8 port, HubStatus& hub_status)
|
||||||
if (port == 0 || port > m_hub_descriptor.number_of_downstream_ports)
|
if (port == 0 || port > m_hub_descriptor.number_of_downstream_ports)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
auto transfer_length_or_error = m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_REQUEST_RECIPIENT_OTHER, HubRequest::GET_STATUS, 0, port, sizeof(HubStatus), &hub_status);
|
auto transfer_length = TRY(m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_REQUEST_RECIPIENT_OTHER, HubRequest::GET_STATUS, 0, port, sizeof(HubStatus), &hub_status));
|
||||||
if (transfer_length_or_error.is_error())
|
|
||||||
return transfer_length_or_error.error();
|
|
||||||
|
|
||||||
// FIXME: This be "not equal to" instead of "less than", but control transfers report a higher transfer length than expected.
|
// FIXME: This be "not equal to" instead of "less than", but control transfers report a higher transfer length than expected.
|
||||||
if (transfer_length_or_error.value() < sizeof(HubStatus)) {
|
if (transfer_length < sizeof(HubStatus)) {
|
||||||
dbgln("USB Hub: Unexpected hub status size. Expected {}, got {}.", sizeof(HubStatus), transfer_length_or_error.value());
|
dbgln("USB Hub: Unexpected hub status size. Expected {}, got {}.", sizeof(HubStatus), transfer_length);
|
||||||
return EIO;
|
return EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,10 +118,7 @@ KResult Hub::clear_port_feature(u8 port, HubFeatureSelector feature_selector)
|
||||||
if (port == 0 || port > m_hub_descriptor.number_of_downstream_ports)
|
if (port == 0 || port > m_hub_descriptor.number_of_downstream_ports)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
auto result = m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_REQUEST_RECIPIENT_OTHER, HubRequest::CLEAR_FEATURE, feature_selector, port, 0, nullptr);
|
TRY(m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_REQUEST_RECIPIENT_OTHER, HubRequest::CLEAR_FEATURE, feature_selector, port, 0, nullptr));
|
||||||
if (result.is_error())
|
|
||||||
return result.error();
|
|
||||||
|
|
||||||
return KSuccess;
|
return KSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,10 +129,7 @@ KResult Hub::set_port_feature(u8 port, HubFeatureSelector feature_selector)
|
||||||
if (port == 0 || port > m_hub_descriptor.number_of_downstream_ports)
|
if (port == 0 || port > m_hub_descriptor.number_of_downstream_ports)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
auto result = m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_REQUEST_RECIPIENT_OTHER, HubRequest::SET_FEATURE, feature_selector, port, 0, nullptr);
|
TRY(m_default_pipe->control_transfer(USB_REQUEST_TRANSFER_DIRECTION_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_REQUEST_RECIPIENT_OTHER, HubRequest::SET_FEATURE, feature_selector, port, 0, nullptr));
|
||||||
if (result.is_error())
|
|
||||||
return result.error();
|
|
||||||
|
|
||||||
return KSuccess;
|
return KSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,12 +69,7 @@ KResultOr<size_t> Pipe::control_transfer(u8 request_type, u8 request, u16 value,
|
||||||
transfer->set_setup_packet(usb_request);
|
transfer->set_setup_packet(usb_request);
|
||||||
|
|
||||||
dbgln_if(USB_DEBUG, "Pipe: Transfer allocated @ {}", transfer->buffer_physical());
|
dbgln_if(USB_DEBUG, "Pipe: Transfer allocated @ {}", transfer->buffer_physical());
|
||||||
auto transfer_len_or_error = m_controller->submit_control_transfer(*transfer);
|
auto transfer_length = TRY(m_controller->submit_control_transfer(*transfer));
|
||||||
|
|
||||||
if (transfer_len_or_error.is_error())
|
|
||||||
return transfer_len_or_error.error();
|
|
||||||
|
|
||||||
auto transfer_length = transfer_len_or_error.release_value();
|
|
||||||
|
|
||||||
// TODO: Check transfer for completion and copy data from transfer buffer into data
|
// TODO: Check transfer for completion and copy data from transfer buffer into data
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue