diff options
Diffstat (limited to 'Kernel/Bus')
-rw-r--r-- | Kernel/Bus/USB/USBDevice.cpp | 8 | ||||
-rw-r--r-- | Kernel/Bus/USB/USBDevice.h | 8 | ||||
-rw-r--r-- | Kernel/Bus/USB/USBHub.cpp | 8 | ||||
-rw-r--r-- | Kernel/Bus/USB/USBHub.h | 4 | ||||
-rw-r--r-- | Kernel/Bus/USB/USBPipe.cpp | 128 | ||||
-rw-r--r-- | Kernel/Bus/USB/USBPipe.h | 84 |
6 files changed, 175 insertions, 65 deletions
diff --git a/Kernel/Bus/USB/USBDevice.cpp b/Kernel/Bus/USB/USBDevice.cpp index 955da88ae7..53a7f2a78e 100644 --- a/Kernel/Bus/USB/USBDevice.cpp +++ b/Kernel/Bus/USB/USBDevice.cpp @@ -18,7 +18,7 @@ namespace Kernel::USB { ErrorOr<NonnullLockRefPtr<Device>> Device::try_create(USBController const& controller, u8 port, DeviceSpeed speed) { - auto pipe = TRY(Pipe::try_create_pipe(controller, Pipe::Type::Control, Pipe::Direction::Bidirectional, 0, 8, 0)); + auto pipe = TRY(ControlPipe::create(controller, 0, 8, 0)); auto device = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) Device(controller, port, speed, move(pipe)))); auto sysfs_node = TRY(SysFSUSBDeviceInformation::create(*device)); device->m_sysfs_device_info_node = move(sysfs_node); @@ -26,7 +26,7 @@ ErrorOr<NonnullLockRefPtr<Device>> Device::try_create(USBController const& contr return device; } -Device::Device(USBController const& controller, u8 port, DeviceSpeed speed, NonnullOwnPtr<Pipe> default_pipe) +Device::Device(USBController const& controller, u8 port, DeviceSpeed speed, NonnullOwnPtr<ControlPipe> default_pipe) : m_device_port(port) , m_device_speed(speed) , m_address(0) @@ -35,7 +35,7 @@ Device::Device(USBController const& controller, u8 port, DeviceSpeed speed, Nonn { } -Device::Device(NonnullLockRefPtr<USBController> controller, u8 address, u8 port, DeviceSpeed speed, NonnullOwnPtr<Pipe> default_pipe) +Device::Device(NonnullLockRefPtr<USBController> controller, u8 address, u8 port, DeviceSpeed speed, NonnullOwnPtr<ControlPipe> default_pipe) : m_device_port(port) , m_device_speed(speed) , m_address(address) @@ -44,7 +44,7 @@ Device::Device(NonnullLockRefPtr<USBController> controller, u8 address, u8 port, { } -Device::Device(Device const& device, NonnullOwnPtr<Pipe> default_pipe) +Device::Device(Device const& device, NonnullOwnPtr<ControlPipe> default_pipe) : m_device_port(device.port()) , m_device_speed(device.speed()) , m_address(device.address()) diff --git a/Kernel/Bus/USB/USBDevice.h b/Kernel/Bus/USB/USBDevice.h index 0eb5b20718..c1069b9939 100644 --- a/Kernel/Bus/USB/USBDevice.h +++ b/Kernel/Bus/USB/USBDevice.h @@ -36,8 +36,8 @@ public: static ErrorOr<NonnullLockRefPtr<Device>> try_create(USBController const&, u8, DeviceSpeed); - Device(USBController const&, u8, DeviceSpeed, NonnullOwnPtr<Pipe> default_pipe); - Device(Device const& device, NonnullOwnPtr<Pipe> default_pipe); + Device(USBController const&, u8, DeviceSpeed, NonnullOwnPtr<ControlPipe> default_pipe); + Device(Device const& device, NonnullOwnPtr<ControlPipe> default_pipe); virtual ~Device(); ErrorOr<void> enumerate_device(); @@ -59,7 +59,7 @@ public: SysFSUSBDeviceInformation& sysfs_device_info_node(Badge<USB::Hub>) { return *m_sysfs_device_info_node; } protected: - Device(NonnullLockRefPtr<USBController> controller, u8 address, u8 port, DeviceSpeed speed, NonnullOwnPtr<Pipe> default_pipe); + Device(NonnullLockRefPtr<USBController> controller, u8 address, u8 port, DeviceSpeed speed, NonnullOwnPtr<ControlPipe> default_pipe); u8 m_device_port { 0 }; // What port is this device attached to. NOTE: This is 1-based. DeviceSpeed m_device_speed; // What speed is this device running at @@ -72,7 +72,7 @@ protected: Vector<USBConfiguration> m_configurations; // Configurations for this device NonnullLockRefPtr<USBController> m_controller; - NonnullOwnPtr<Pipe> m_default_pipe; // Default communication pipe (endpoint0) used during enumeration + NonnullOwnPtr<ControlPipe> m_default_pipe; // Default communication pipe (endpoint0) used during enumeration private: IntrusiveListNode<Device, NonnullLockRefPtr<Device>> m_hub_child_node; diff --git a/Kernel/Bus/USB/USBHub.cpp b/Kernel/Bus/USB/USBHub.cpp index bb80647ed2..629c00f299 100644 --- a/Kernel/Bus/USB/USBHub.cpp +++ b/Kernel/Bus/USB/USBHub.cpp @@ -18,25 +18,25 @@ namespace Kernel::USB { ErrorOr<NonnullLockRefPtr<Hub>> Hub::try_create_root_hub(NonnullLockRefPtr<USBController> controller, DeviceSpeed device_speed) { // NOTE: Enumeration does not happen here, as the controller must know what the device address is at all times during enumeration to intercept requests. - auto pipe = TRY(Pipe::try_create_pipe(controller, Pipe::Type::Control, Pipe::Direction::Bidirectional, 0, 8, 0)); + auto pipe = TRY(ControlPipe::create(controller, 0, 8, 0)); auto hub = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) Hub(controller, device_speed, move(pipe)))); return hub; } ErrorOr<NonnullLockRefPtr<Hub>> Hub::try_create_from_device(Device const& device) { - auto pipe = TRY(Pipe::try_create_pipe(device.controller(), Pipe::Type::Control, Pipe::Direction::Bidirectional, 0, device.device_descriptor().max_packet_size, device.address())); + auto pipe = TRY(ControlPipe::create(device.controller(), 0, device.device_descriptor().max_packet_size, device.address())); auto hub = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) Hub(device, move(pipe)))); TRY(hub->enumerate_and_power_on_hub()); return hub; } -Hub::Hub(NonnullLockRefPtr<USBController> controller, DeviceSpeed device_speed, NonnullOwnPtr<Pipe> default_pipe) +Hub::Hub(NonnullLockRefPtr<USBController> controller, DeviceSpeed device_speed, NonnullOwnPtr<ControlPipe> default_pipe) : Device(move(controller), 1 /* Port 1 */, device_speed, move(default_pipe)) { } -Hub::Hub(Device const& device, NonnullOwnPtr<Pipe> default_pipe) +Hub::Hub(Device const& device, NonnullOwnPtr<ControlPipe> default_pipe) : Device(device, move(default_pipe)) { } diff --git a/Kernel/Bus/USB/USBHub.h b/Kernel/Bus/USB/USBHub.h index aaefe513d4..6108bf8828 100644 --- a/Kernel/Bus/USB/USBHub.h +++ b/Kernel/Bus/USB/USBHub.h @@ -96,9 +96,9 @@ public: private: // Root Hub constructor - Hub(NonnullLockRefPtr<USBController>, DeviceSpeed, NonnullOwnPtr<Pipe> default_pipe); + Hub(NonnullLockRefPtr<USBController>, DeviceSpeed, NonnullOwnPtr<ControlPipe> default_pipe); - Hub(Device const&, NonnullOwnPtr<Pipe> default_pipe); + Hub(Device const&, NonnullOwnPtr<ControlPipe> default_pipe); USBHubDescriptor m_hub_descriptor {}; diff --git a/Kernel/Bus/USB/USBPipe.cpp b/Kernel/Bus/USB/USBPipe.cpp index ab1cd8bb3b..ac4c79bc57 100644 --- a/Kernel/Bus/USB/USBPipe.cpp +++ b/Kernel/Bus/USB/USBPipe.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com> + * Copyright (c) 2022, blackcat <b14ckcat@protonmail.com> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -12,48 +13,33 @@ namespace Kernel::USB { -ErrorOr<NonnullOwnPtr<Pipe>> Pipe::try_create_pipe(USBController const& controller, Type type, Direction direction, u8 endpoint_address, u16 max_packet_size, i8 device_address, size_t buffer_size, u8 poll_interval) -{ - auto dma_region = TRY(MM.allocate_dma_buffer_pages(TRY(Memory::page_round_up(buffer_size)), "USB device DMA buffer"sv, Memory::Region::Access::ReadWrite)); - return adopt_nonnull_own_or_enomem(new (nothrow) Pipe(controller, type, direction, endpoint_address, max_packet_size, poll_interval, device_address, move(dma_region))); -} - -Pipe::Pipe(USBController const& controller, Type type, Pipe::Direction direction, u16 max_packet_size, NonnullOwnPtr<Memory::Region> dma_buffer) +Pipe::Pipe(USBController const& controller, Type type, Direction direction, u8 endpoint_address, u16 max_packet_size, i8 device_address, NonnullOwnPtr<Memory::Region> dma_buffer) : m_controller(controller) , m_type(type) , m_direction(direction) - , m_endpoint_address(0) + , m_device_address(device_address) + , m_endpoint_address(endpoint_address) , m_max_packet_size(max_packet_size) - , m_poll_interval(0) , m_data_toggle(false) , m_dma_buffer(move(dma_buffer)) { } -Pipe::Pipe(USBController const& controller, Type type, Direction direction, USBEndpointDescriptor& endpoint [[maybe_unused]], NonnullOwnPtr<Memory::Region> dma_buffer) - : m_controller(controller) - , m_type(type) - , m_direction(direction) - , m_dma_buffer(move(dma_buffer)) +ErrorOr<NonnullOwnPtr<ControlPipe>> ControlPipe::create(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, size_t buffer_size) { - // TODO: decode endpoint structure + auto dma_buffer = TRY(MM.allocate_dma_buffer_pages(TRY(Memory::page_round_up(buffer_size)), "USB device DMA buffer"sv, Memory::Region::Access::ReadWrite)); + return adopt_nonnull_own_or_enomem(new (nothrow) ControlPipe(controller, endpoint_address, max_packet_size, device_address, move(dma_buffer))); } -Pipe::Pipe(USBController const& controller, Type type, Direction direction, u8 endpoint_address, u16 max_packet_size, u8 poll_interval, i8 device_address, NonnullOwnPtr<Memory::Region> dma_buffer) - : m_controller(controller) - , m_type(type) - , m_direction(direction) - , m_device_address(device_address) - , m_endpoint_address(endpoint_address) - , m_max_packet_size(max_packet_size) - , m_poll_interval(poll_interval) - , m_data_toggle(false) - , m_dma_buffer(move(dma_buffer)) +ControlPipe::ControlPipe(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, NonnullOwnPtr<Memory::Region> dma_buffer) + : Pipe(controller, Type::Control, Direction::Bidirectional, endpoint_address, max_packet_size, device_address, move(dma_buffer)) { } -ErrorOr<size_t> Pipe::control_transfer(u8 request_type, u8 request, u16 value, u16 index, u16 length, void* data) +ErrorOr<size_t> ControlPipe::control_transfer(u8 request_type, u8 request, u16 value, u16 index, size_t length, void* data) { + VERIFY(length <= m_dma_buffer->size()); + MutexLocker lock(m_dma_buffer_lock); USBRequestData usb_request; @@ -67,7 +53,7 @@ ErrorOr<size_t> Pipe::control_transfer(u8 request_type, u8 request, u16 value, u auto transfer = TRY(Transfer::try_create(*this, length, *m_dma_buffer)); transfer->set_setup_packet(usb_request); - dbgln_if(USB_DEBUG, "Pipe: Transfer allocated @ {}", transfer->buffer_physical()); + dbgln_if(USB_DEBUG, "ControlPipe: Transfer allocated @ {}", transfer->buffer_physical()); auto transfer_length = TRY(m_controller->submit_control_transfer(*transfer)); // TODO: Check transfer for completion and copy data from transfer buffer into data @@ -78,26 +64,90 @@ ErrorOr<size_t> Pipe::control_transfer(u8 request_type, u8 request, u16 value, u return transfer_length; } -ErrorOr<size_t> Pipe::bulk_transfer(u16 length, void* data) +ErrorOr<NonnullOwnPtr<BulkInPipe>> BulkInPipe::create(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, size_t buffer_size) { + VERIFY(buffer_size >= max_packet_size); + auto dma_buffer = TRY(MM.allocate_dma_buffer_pages(TRY(Memory::page_round_up(buffer_size)), "USB pipe DMA buffer"sv, Memory::Region::Access::ReadWrite)); + return adopt_nonnull_own_or_enomem(new (nothrow) BulkInPipe(controller, endpoint_address, max_packet_size, device_address, move(dma_buffer))); +} + +BulkInPipe::BulkInPipe(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, NonnullOwnPtr<Memory::Region> dma_buffer) + : Pipe(controller, Pipe::Type::Bulk, Direction::In, endpoint_address, max_packet_size, device_address, move(dma_buffer)) +{ +} + +ErrorOr<size_t> BulkInPipe::bulk_in_transfer(size_t length, void* data) +{ + VERIFY(length <= m_dma_buffer->size()); + MutexLocker lock(m_dma_buffer_lock); size_t transfer_length = 0; + auto transfer = TRY(Transfer::try_create(*this, length, *m_dma_buffer)); - if (m_direction == Direction::In) { - dbgln_if(USB_DEBUG, "Pipe: Bulk in transfer allocated @ {}", transfer->buffer_physical()); - transfer_length = TRY(m_controller->submit_bulk_transfer(*transfer)); - memcpy(data, transfer->buffer().as_ptr(), min(length, transfer_length)); - dbgln_if(USB_DEBUG, "Pipe: Bulk in transfer complete!"); - } else if (m_direction == Direction::Out) { - TRY(transfer->write_buffer(length, data)); - dbgln_if(USB_DEBUG, "Pipe: Bulk out transfer allocated @ {}", transfer->buffer_physical()); - transfer_length = TRY(m_controller->submit_bulk_transfer(*transfer)); - dbgln_if(USB_DEBUG, "Pipe: Bulk out transfer complete!"); - } + dbgln_if(USB_DEBUG, "Pipe: Bulk in transfer allocated @ {}", transfer->buffer_physical()); + transfer_length = TRY(m_controller->submit_bulk_transfer(*transfer)); + memcpy(data, transfer->buffer().as_ptr(), min(length, transfer_length)); + dbgln_if(USB_DEBUG, "Pipe: Bulk in transfer complete!"); return transfer_length; } +ErrorOr<NonnullOwnPtr<BulkOutPipe>> BulkOutPipe::create(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, size_t buffer_size) +{ + VERIFY(buffer_size >= max_packet_size); + auto dma_buffer = TRY(MM.allocate_dma_buffer_pages(TRY(Memory::page_round_up(buffer_size)), "USB pipe DMA buffer"sv, Memory::Region::Access::ReadWrite)); + return adopt_nonnull_own_or_enomem(new (nothrow) BulkOutPipe(controller, endpoint_address, max_packet_size, device_address, move(dma_buffer))); +} + +BulkOutPipe::BulkOutPipe(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, NonnullOwnPtr<Memory::Region> dma_buffer) + : Pipe(controller, Type::Bulk, Direction::Out, endpoint_address, max_packet_size, device_address, move(dma_buffer)) + +{ +} + +ErrorOr<size_t> BulkOutPipe::bulk_out_transfer(size_t length, void* data) +{ + VERIFY(length <= m_dma_buffer->size()); + + MutexLocker lock(m_dma_buffer_lock); + + size_t transfer_length = 0; + auto transfer = TRY(Transfer::try_create(*this, length, *m_dma_buffer)); + + TRY(transfer->write_buffer(length, data)); + dbgln_if(USB_DEBUG, "Pipe: Bulk out transfer allocated @ {}", transfer->buffer_physical()); + transfer_length = TRY(m_controller->submit_bulk_transfer(*transfer)); + dbgln_if(USB_DEBUG, "Pipe: Bulk out transfer complete!"); + + return transfer_length; +} + +ErrorOr<NonnullOwnPtr<InterruptInPipe>> InterruptInPipe::create(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, u16 poll_interval, size_t buffer_size) +{ + VERIFY(buffer_size >= max_packet_size); + auto dma_buffer = TRY(MM.allocate_dma_buffer_pages(TRY(Memory::page_round_up(buffer_size)), "USB pipe DMA buffer"sv, Memory::Region::Access::ReadWrite)); + return adopt_nonnull_own_or_enomem(new (nothrow) InterruptInPipe(controller, endpoint_address, max_packet_size, device_address, poll_interval, move(dma_buffer))); +} + +InterruptInPipe::InterruptInPipe(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, u16 poll_interval, NonnullOwnPtr<Memory::Region> dma_buffer) + : Pipe(controller, Type::Interrupt, Direction::In, endpoint_address, max_packet_size, device_address, move(dma_buffer)) + , m_poll_interval(poll_interval) +{ +} + +ErrorOr<NonnullOwnPtr<InterruptOutPipe>> InterruptOutPipe::create(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, u16 poll_interval, size_t buffer_size) +{ + VERIFY(buffer_size >= max_packet_size); + auto dma_buffer = TRY(MM.allocate_dma_buffer_pages(TRY(Memory::page_round_up(buffer_size)), "USB pipe DMA buffer"sv, Memory::Region::Access::ReadWrite)); + return adopt_nonnull_own_or_enomem(new (nothrow) InterruptOutPipe(controller, endpoint_address, max_packet_size, device_address, poll_interval, move(dma_buffer))); +} + +InterruptOutPipe::InterruptOutPipe(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, u16 poll_interval, NonnullOwnPtr<Memory::Region> dma_buffer) + : Pipe(controller, Type::Interrupt, Direction::In, endpoint_address, max_packet_size, device_address, move(dma_buffer)) + , m_poll_interval(poll_interval) +{ +} + } diff --git a/Kernel/Bus/USB/USBPipe.h b/Kernel/Bus/USB/USBPipe.h index 73c423b2d2..578852dc0f 100644 --- a/Kernel/Bus/USB/USBPipe.h +++ b/Kernel/Bus/USB/USBPipe.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2021, Jesse Buhagiar <jooster669@gmail.com> + * Copyright (c) 2022, blackcat <b14ckcat@protonmail.com> * * SPDX-License-Identifier: BSD-2-Clause */ @@ -15,6 +16,7 @@ namespace Kernel::USB { class USBController; +class Transfer; // // A pipe is the logical connection between a memory buffer on the PC (host) and @@ -41,8 +43,6 @@ public: FullSpeed }; - static ErrorOr<NonnullOwnPtr<Pipe>> try_create_pipe(USBController const& controller, Type type, Direction direction, u8 endpoint_address, u16 max_packet_size, i8 device_address, size_t buffer_size = PAGE_SIZE, u8 poll_interval = 0); - Type type() const { return m_type; } Direction direction() const { return m_direction; } DeviceSpeed device_speed() const { return m_speed; } @@ -50,23 +50,17 @@ public: i8 device_address() const { return m_device_address; } u8 endpoint_address() const { return m_endpoint_address; } u16 max_packet_size() const { return m_max_packet_size; } - u8 poll_interval() const { return m_poll_interval; } bool data_toggle() const { return m_data_toggle; } void set_max_packet_size(u16 max_size) { m_max_packet_size = max_size; } void set_toggle(bool toggle) { m_data_toggle = toggle; } void set_device_address(i8 addr) { m_device_address = addr; } - ErrorOr<size_t> control_transfer(u8 request_type, u8 request, u16 value, u16 index, u16 length, void* data); - ErrorOr<size_t> bulk_transfer(u16 length, void* data); - - Pipe(USBController const& controller, Type type, Direction direction, u16 max_packet_size, NonnullOwnPtr<Memory::Region> dma_buffer); - Pipe(USBController const& controller, Type type, Direction direction, USBEndpointDescriptor& endpoint, NonnullOwnPtr<Memory::Region> dma_buffer); - Pipe(USBController const& controller, Type type, Direction direction, u8 endpoint_address, u16 max_packet_size, u8 poll_interval, i8 device_address, NonnullOwnPtr<Memory::Region> dma_buffer); - -private: +protected: friend class Device; + Pipe(USBController const& controller, Type type, Direction direction, u8 endpoint_address, u16 max_packet_size, i8 device_address, NonnullOwnPtr<Memory::Region> dma_buffer); + NonnullLockRefPtr<USBController> m_controller; Type m_type; @@ -76,11 +70,77 @@ private: i8 m_device_address { 0 }; // Device address of this pipe u8 m_endpoint_address { 0 }; // Corresponding endpoint address for this pipe u16 m_max_packet_size { 0 }; // Max packet size for this pipe - u8 m_poll_interval { 0 }; // Polling interval (in frames) bool m_data_toggle { false }; // Data toggle for stuffing bit Mutex m_dma_buffer_lock { "USB pipe mutex"sv }; NonnullOwnPtr<Memory::Region> m_dma_buffer; }; + +class ControlPipe : public Pipe { +public: + static ErrorOr<NonnullOwnPtr<ControlPipe>> create(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, size_t buffer_size = PAGE_SIZE); + + ErrorOr<size_t> control_transfer(u8 request_type, u8 request, u16 value, u16 index, size_t length, void* data); + +private: + ControlPipe(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, NonnullOwnPtr<Memory::Region> dma_buffer); +}; + +class BulkInPipe : public Pipe { +public: + static ErrorOr<NonnullOwnPtr<BulkInPipe>> create(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, size_t buffer_size = PAGE_SIZE); + + ErrorOr<size_t> bulk_in_transfer(size_t length, void* data); + +private: + BulkInPipe(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, NonnullOwnPtr<Memory::Region> dma_buffer); +}; + +class BulkOutPipe : public Pipe { +public: + static ErrorOr<NonnullOwnPtr<BulkOutPipe>> create(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, size_t buffer_size = PAGE_SIZE); + + ErrorOr<size_t> bulk_out_transfer(size_t length, void* data); + +private: + BulkOutPipe(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, NonnullOwnPtr<Memory::Region> dma_buffer); +}; + +class InterruptInPipe : public Pipe { +public: + static ErrorOr<NonnullOwnPtr<InterruptInPipe>> create(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, u16 poll_interval, size_t buffer_size = PAGE_SIZE); + + u16 poll_interval() const { return m_poll_interval; } + +private: + InterruptInPipe(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, u16 poll_interval, NonnullOwnPtr<Memory::Region> dma_pool); + + u16 m_poll_interval; +}; + +class InterruptOutPipe : public Pipe { +public: + static ErrorOr<NonnullOwnPtr<InterruptOutPipe>> create(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, u16 poll_interval, size_t buffer_size = PAGE_SIZE); + + u16 poll_interval() const { return m_poll_interval; } + +private: + InterruptOutPipe(USBController const& controller, u8 endpoint_address, u16 max_packet_size, i8 device_address, u16 poll_interval, NonnullOwnPtr<Memory::Region> dma_pool); + + u16 m_poll_interval; +}; + +class IsochronousInPipe : public Pipe { + // TODO +public: +private: +}; + +class IsochronousOutPipe : public Pipe { + // TODO +public: +private: +}; + } |