Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kernel: Add a basic USB Attached SCSI (UAS) driver #25067

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

Hendiadyoin1
Copy link
Contributor

Kernel/USBMS: Move the BOT/BBB driver to its own directory

Kernel/USB: Save all USB descriptors and allow iterating over them

This makes it easier to access class specific descriptors, which
are sometimes dependent on the device configuration immediately before
them.

Kernel/USBMS: Add a basic UAS driver

For now we only support USB <3.0 devices, as we don't lissten for
ERDY transaction packets.
We also don't leverage the benefits of UAS, as we pretend to have a
queue depth of 1, ie are single threaded.

To test this driver, you can use the following command:

SERENITY_BOOT_DRIVE=usb-uas Meta/serenity.sh run x86_64 Clang

SideNote: This can't legally fly drones

CC: @spholz

@github-actions github-actions bot added the 👀 pr-needs-review PR needs review from a maintainer or community member label Oct 2, 2024
Copy link
Collaborator

@kleinesfilmroellchen kleinesfilmroellchen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

last commit idk, rest is fine

Copy link
Collaborator

@spholz spholz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, that's a lot of FIXMEs

Kernel/Bus/USB/USBConfiguration.h Outdated Show resolved Hide resolved
Kernel/Bus/USB/USBConfiguration.h Show resolved Hide resolved
Kernel/Bus/USB/Drivers/MassStorage/MassStorageDriver.cpp Outdated Show resolved Hide resolved
Kernel/Devices/Storage/USB/UAS/UASInterface.cpp Outdated Show resolved Hide resolved
Comment on lines 21 to 27
// Note: The maximum packet size for the endpoints is 512 bytes on USB2 and 1024 bytes on USB3
// As the SenseIU is of flexible size we need to forcefully allocate some data here
// The actual max size of the sense data is controlled by the MAXIMUM SENSE DATA LENGTH field in the
// Control extension mode page of the device
// The maximum size of the sense data is 252 bytes
// Meaning the maximum size of the IU is 252+16=268 bytes
// Just to be safe we allocate 512 bytes here
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This should probably be formatted into a normal sentence, like what we usually do for comments.
Same for all other comments in this commit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the new text better?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I guess it's ok.

Kernel/Devices/Storage/USB/UAS/UASInterface.h Outdated Show resolved Hide resolved
Kernel/Devices/Storage/USB/UAS/UASInterface.h Outdated Show resolved Hide resolved
Kernel/Devices/Storage/USB/UAS/Structures.h Show resolved Hide resolved
@@ -97,4 +97,37 @@ ErrorOr<size_t> Device::control_transfer(u8 request_type, u8 request, u16 value,
return TRY(m_default_pipe->submit_control_transfer(request_type, request, value, index, length, data));
}

ErrorOr<void> Device::activate_configuration(USBConfiguration const& configuration)
{
if (m_was_configured.was_set() && m_current_configuration != configuration.configuration_id())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still don't think this check is necessary. Only one driver can be attached to a USB device. So unless a driver attempts to change configurations more than once, this will never happen.
And if we think so such a check is necessary, shouldn't we also do a similar check for alternate settings?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracking interface usage is a bit harder to track with minimal invasiveness, but might be missing something
I can remove the check but prefer to be better safe now then forgetting it later

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, let's keep that check for now then. We can maybe remove it once we have a better way of probing USB drivers instead of trying all drivers one by one. That theoretical new abstraction would probably have to keep track of configurations itself.

@@ -97,4 +97,37 @@ ErrorOr<size_t> Device::control_transfer(u8 request_type, u8 request, u16 value,
return TRY(m_default_pipe->submit_control_transfer(request_type, request, value, index, length, data));
}

ErrorOr<void> Device::activate_configuration(USBConfiguration const& configuration)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would personally just call this function like the actual USB request it runs, set_configuration.
And activate_interface can probably be called something like set_configuration_and_interface so it's clearer what it actually does.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure

Comment on lines 21 to 27
// Note: The maximum packet size for the endpoints is 512 bytes on USB2 and 1024 bytes on USB3
// As the SenseIU is of flexible size we need to forcefully allocate some data here
// The actual max size of the sense data is controlled by the MAXIMUM SENSE DATA LENGTH field in the
// Control extension mode page of the device
// The maximum size of the sense data is 252 bytes
// Meaning the maximum size of the IU is 252+16=268 bytes
// Just to be safe we allocate 512 bytes here
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I guess it's ok.

Copy link
Collaborator

@spholz spholz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I didn't mean to finish my review (Adding a response to a comment appears to submit reviews?).

// FIXME: When we use the default alternate_setting of interface/the current alternate setting, we don't need to SET_INTERFACE it
// but that gets a bit difficult to track
TRY(control_transfer(USB_REQUEST_TRANSFER_DIRECTION_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE, USB_REQUEST_SET_INTERFACE,
interface.descriptor().interface_id, interface.descriptor().alternate_setting, 0, nullptr));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be interface.descriptor().alternate_setting, interface.descriptor().interface_id, 0, nullptr));

@@ -41,6 +41,7 @@ static constexpr u8 USB_REQUEST_GET_DESCRIPTOR = 0x06;
static constexpr u8 USB_REQUEST_SET_DESCRIPTOR = 0x07;
static constexpr u8 USB_REQUEST_GET_CONFIGURATION = 0x08;
static constexpr u8 USB_REQUEST_SET_CONFIGURATION = 0x09;
static constexpr u8 USB_REQUEST_SET_INTERFACE = 0x11;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0x0b

@timschumi timschumi self-requested a review October 7, 2024 14:34

if (uas_interface.has_value() && device.speed() != USB::Device::DeviceSpeed::SuperSpeed) {
// FIXME: We only support UAS on version < 3.0 devices
// as we don't support waiting ERDY transactions yet
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These references to ERDY should probably replaced with streams (also in the commit message).

This makes it easier to access class specific descriptors, which
are sometimes dependent on the descriptors immediately before them.
For now we only support USB <3.0 devices, as we don't support streams.
We also don't leverage the benefits of UAS, as we pretend to have a
queue depth of 1, ie are single threaded.

To test this driver, you can use the following command:
```
SERENITY_BOOT_DRIVE=usb-uas Meta/serenity.sh run x86_64 Clang
```
Copy link

@kiruthikpurpose kiruthikpurpose left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

Copy link

@kiruthikpurpose kiruthikpurpose left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the way you added the offset to the function parameter. Make sure it has no leaks thoroughly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
👀 pr-needs-review PR needs review from a maintainer or community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants