Kernel: Allow USB devices to handle STALL conditions
This commit is contained in:
parent
8e624ca85a
commit
e620068416
|
@ -21,6 +21,7 @@ namespace Kernel
|
||||||
|
|
||||||
virtual BAN::ErrorOr<void> initialize() { return {}; };
|
virtual BAN::ErrorOr<void> initialize() { return {}; };
|
||||||
|
|
||||||
|
virtual void handle_stall(uint8_t endpoint_id) = 0;
|
||||||
virtual void handle_input_data(size_t byte_count, uint8_t endpoint_id) = 0;
|
virtual void handle_input_data(size_t byte_count, uint8_t endpoint_id) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -71,6 +72,7 @@ namespace Kernel
|
||||||
static USB::SpeedClass determine_speed_class(uint64_t bits_per_second);
|
static USB::SpeedClass determine_speed_class(uint64_t bits_per_second);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void handle_stall(uint8_t endpoint_id);
|
||||||
void handle_input_data(size_t byte_count, uint8_t endpoint_id);
|
void handle_input_data(size_t byte_count, uint8_t endpoint_id);
|
||||||
virtual BAN::ErrorOr<void> initialize_control_endpoint() = 0;
|
virtual BAN::ErrorOr<void> initialize_control_endpoint() = 0;
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ namespace Kernel
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void handle_stall(uint8_t endpoint_id) override;
|
||||||
void handle_input_data(size_t byte_count, uint8_t endpoint_id) override;
|
void handle_input_data(size_t byte_count, uint8_t endpoint_id) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace Kernel
|
||||||
BAN_NON_MOVABLE(USBMassStorageDriver);
|
BAN_NON_MOVABLE(USBMassStorageDriver);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void handle_stall(uint8_t endpoint_id) override;
|
||||||
void handle_input_data(size_t byte_count, uint8_t endpoint_id) override;
|
void handle_input_data(size_t byte_count, uint8_t endpoint_id) override;
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> send_bytes(paddr_t, size_t count);
|
BAN::ErrorOr<size_t> send_bytes(paddr_t, size_t count);
|
||||||
|
|
|
@ -328,6 +328,12 @@ namespace Kernel
|
||||||
return BAN::move(configuration);
|
return BAN::move(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USBDevice::handle_stall(uint8_t endpoint_id)
|
||||||
|
{
|
||||||
|
for (auto& driver : m_class_drivers)
|
||||||
|
driver->handle_stall(endpoint_id);
|
||||||
|
}
|
||||||
|
|
||||||
void USBDevice::handle_input_data(size_t byte_count, uint8_t endpoint_id)
|
void USBDevice::handle_input_data(size_t byte_count, uint8_t endpoint_id)
|
||||||
{
|
{
|
||||||
for (auto& driver : m_class_drivers)
|
for (auto& driver : m_class_drivers)
|
||||||
|
|
|
@ -272,6 +272,12 @@ namespace Kernel
|
||||||
return BAN::move(result);
|
return BAN::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USBHIDDriver::handle_stall(uint8_t endpoint_id)
|
||||||
|
{
|
||||||
|
(void)endpoint_id;
|
||||||
|
// FIXME: do something :)
|
||||||
|
}
|
||||||
|
|
||||||
void USBHIDDriver::handle_input_data(size_t byte_count, uint8_t endpoint_id)
|
void USBHIDDriver::handle_input_data(size_t byte_count, uint8_t endpoint_id)
|
||||||
{
|
{
|
||||||
if (m_data_endpoint_id != endpoint_id)
|
if (m_data_endpoint_id != endpoint_id)
|
||||||
|
|
|
@ -169,6 +169,12 @@ namespace Kernel
|
||||||
return static_cast<size_t>(bytes_recv);
|
return static_cast<size_t>(bytes_recv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void USBMassStorageDriver::handle_stall(uint8_t endpoint_id)
|
||||||
|
{
|
||||||
|
(void)endpoint_id;
|
||||||
|
// FIXME: do something :)
|
||||||
|
}
|
||||||
|
|
||||||
void USBMassStorageDriver::handle_input_data(size_t byte_count, uint8_t endpoint_id)
|
void USBMassStorageDriver::handle_input_data(size_t byte_count, uint8_t endpoint_id)
|
||||||
{
|
{
|
||||||
if (endpoint_id != m_in_endpoint_id && endpoint_id != m_out_endpoint_id)
|
if (endpoint_id != m_in_endpoint_id && endpoint_id != m_out_endpoint_id)
|
||||||
|
|
|
@ -295,15 +295,19 @@ namespace Kernel
|
||||||
void XHCIDevice::on_interrupt_or_bulk_endpoint_event(XHCI::TRB trb)
|
void XHCIDevice::on_interrupt_or_bulk_endpoint_event(XHCI::TRB trb)
|
||||||
{
|
{
|
||||||
ASSERT(trb.trb_type == XHCI::TRBType::TransferEvent);
|
ASSERT(trb.trb_type == XHCI::TRBType::TransferEvent);
|
||||||
|
|
||||||
|
const uint32_t endpoint_id = trb.transfer_event.endpoint_id;
|
||||||
|
auto& endpoint = m_endpoints[endpoint_id - 1];
|
||||||
|
|
||||||
|
if (trb.transfer_event.completion_code == 6)
|
||||||
|
return handle_stall(endpoint_id);
|
||||||
|
|
||||||
if (trb.transfer_event.completion_code != 1 && trb.transfer_event.completion_code != 13)
|
if (trb.transfer_event.completion_code != 1 && trb.transfer_event.completion_code != 13)
|
||||||
{
|
{
|
||||||
dwarnln("Interrupt or bulk endpoint got transfer event with completion code {}", +trb.transfer_event.completion_code);
|
dwarnln("Interrupt or bulk endpoint got transfer event with completion code {}", +trb.transfer_event.completion_code);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t endpoint_id = trb.transfer_event.endpoint_id;
|
|
||||||
auto& endpoint = m_endpoints[endpoint_id - 1];
|
|
||||||
|
|
||||||
const auto* transfer_trb_arr = reinterpret_cast<volatile XHCI::TRB*>(endpoint.transfer_ring->vaddr());
|
const auto* transfer_trb_arr = reinterpret_cast<volatile XHCI::TRB*>(endpoint.transfer_ring->vaddr());
|
||||||
const uint32_t transfer_trb_index = (trb.transfer_event.trb_pointer - endpoint.transfer_ring->paddr()) / sizeof(XHCI::TRB);
|
const uint32_t transfer_trb_index = (trb.transfer_event.trb_pointer - endpoint.transfer_ring->paddr()) / sizeof(XHCI::TRB);
|
||||||
const uint32_t original_len = transfer_trb_arr[transfer_trb_index].normal.trb_transfer_length;
|
const uint32_t original_len = transfer_trb_arr[transfer_trb_index].normal.trb_transfer_length;
|
||||||
|
|
Loading…
Reference in New Issue