Commit Graph

81 Commits

Author SHA1 Message Date
Hendiadyoin1
66cfe47ed8 Kernel/USBMS: Add a basic UAS driver
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
```
2024-10-30 18:47:50 -04:00
Hendiadyoin1
435d78c575 Kernel/USBMS: Move the BOT/BBB driver to its own directory 2024-10-30 18:47:50 -04:00
Liav A.
3edc6ae0d6 Kernel/Devices: Improve construction paths semantically
Do this by:
- Removing more instances of `LockRefPtr` and `NonnullLockRefPtr`.
- Using better names of construction methods (i.e. `create` instead of
  `try_create`).
- Only returning `NonnullRefPtr` on the `Device::try_create_device`
  method.
- Removing a version of the `Device::try_create_device` method that
  called `DeviceType::try_create(forward<Args>(args)...)`, which was
  only used in a construction point in a VirtIO driver which now doesn't
  need this anymore.
2024-10-05 12:26:48 +02:00
Liav A.
96e1391c23 Kernel/Devices: Remove the DeviceManagement singleton
This change has many improvements:
- We don't use `LockRefPtr` to hold instances of many base devices as
  with the DeviceManagement class. Instead, we have a saner pattern of
  holding them in a `NonnullRefPtr<T> const`, in a small-text footprint
  class definition in the `Device.cpp` file.
- The awkwardness of using `::the()` each time we need to get references
  to mostly-static objects (like the Event queue) in runtime is now gone
  in the migration to using the `Device` class.
- Acquiring a device feel more obvious because we use now the Device
  class for this method. The method name is improved as well.
2024-10-05 12:26:48 +02:00
Sönke Holz
801a0c35cd Kernel/USBMS: Add some optional verbose debug output
The static_assert is needed so we can safely print the SCSI opcode
(bCBWCBLength also always has to be > 1).
2024-09-25 14:41:23 -04:00
Sönke Holz
f1d7b87cba Kernel/USBMS: Handle data transport errors 2024-09-25 14:41:23 -04:00
Sönke Holz
24e74086b5 Kernel/USBMS: Handle CBW transport errors 2024-09-25 14:41:23 -04:00
Sönke Holz
54709af2f5 Kernel/USBMS: Perform a Reset Recovery when CSW transport fails twice
This requires storing a const reference to the interface, as the
Bulk-Only Mass Storage Reset request takes the interface number as an
argument.
2024-09-25 14:41:23 -04:00
Sönke Holz
55b80252d9 Kernel/USBMS: Handle CSW transport errors 2024-09-25 14:41:23 -04:00
Sönke Holz
2099647cc0 Kernel/USBMS: Make send_scsi_command a member function 2024-09-25 14:41:23 -04:00
Sönke Holz
f5cd7ec711 Kernel/USBMS: Unify the two send_scsi_command implementations
These two versions can be unified with a bit of template
metaprogramming.
2024-09-25 14:41:23 -04:00
Sönke Holz
7173a02728 Kernel/USBMS: Move device initialization to BulkSCSIInterface 2024-09-25 14:41:23 -04:00
Sönke Holz
c5f4469b32 Kernel/USBMS: Move StorageDevice functions into a separate class
This will allow us to make send_scsi_command a member function. This is
necessary because we need to execute some SCSI commands
(with send_scsi_command) to get all arguments necessary for the
StorageDevice constructor.

This change should will likely also be necessary to support USB mass
storage devices with multiple LUNs.
2024-09-25 14:41:23 -04:00
Liav A.
0482f4e117 Kernel: Remove passing of register state to IRQ handlers
Linux did the same thing 18 years ago and their reasons for the change
are similar to ours - https://github.com/torvalds/linux/commit/7d12e78

Most interrupt handlers (i.e. IRQ handlers) never used the register
state reference anywhere so there's simply no need of passing it around.
I didn't measure the performance boost but surely this change can't make
things worse anyway.
2024-09-01 21:00:18 +02:00
Hendiadyoin1
f5d2671718 Kernel/USBMS: Query and use the Block Limits VPD page
This allows us to properly limit our block requests to the device's
capabilities, and choose more optimal block counts for I/O operations.
In theory, as Qemu  only advertises a block limit above our current
internal block size limit of u16::max and does not advertise any optimal
transfer lengths.
2024-08-20 22:06:51 -04:00
Hendiadyoin1
0d2e8ec96f Kernel/USBMS: Inquire and wait for the storage device to become ready
This is apparently what bootloaders do before using a USB storage device
so we should likely do so as well, especially when no BIOS is present,
like on riscv.

Co-Authored-By: Sönke Holz <sholz8530@gmail.com>
2024-08-20 22:06:51 -04:00
Hendiadyoin1
e3567969d4 Kernel/USBMS: Add and use a send_scsi_command helper
This makes sending commands less repetitive
2024-08-20 22:06:51 -04:00
Liav A.
3692af528e Kernel: Move most of VirtualFileSystem code to be in a namespace
There's no point in constructing an object just for the sake of keeping
a state that can be touched by anything in the kernel code.

Let's reduce everything to be in a C++ namespace called with the
previous name "VirtualFileSystem" and keep a smaller textual-footprint
struct called "VirtualFileSystemDetails".

This change also cleans up old "friend class" statements that were no
longer needed, and move methods from the VirtualFileSystem code to more
appropriate places as well.
Please note that the method of locking all filesystems during shutdown
is removed, as in that place there's no meaning to actually locking all
filesystems because of running in kernel mode entirely.
2024-07-21 11:44:23 +02:00
Liav A.
01e1af732b Kernel/FileSystem: Introduce the VFSRootContext class
The VFSRootContext class, as its name suggests, holds a context for a
root directory with its mount table and the root custody/inode in the
same class.

The idea is derived from the Linux mount namespace mechanism.
It mimicks the concept of the ProcessList object, but it is adjusted for
a root directory tree context.
In contrast to the ProcessList concept, processes that share the default
VFSRootContext can't see other VFSRootContext related properties such as
as the mount table and root custody/inode.

To accommodate to this change progressively, we internally create 2 main
VFS root contexts for now - one for kernel processes (as they don't need
to care about VFS root contexts for the most part), and another for all
userspace programs.
This separation allows us to continue pretending for userspace that
everything is "normal" as it is used to be, until we introduce proper
interfaces in the mount-related syscalls as well as in the SysFS.

We make VFSRootContext objects being listed, as another preparation
before we could expose interfaces to userspace.
As a result, the PowerStateSwitchTask now iterates on all contexts
and tear them down one by one.
2024-07-21 11:44:23 +02:00
Liav A.
16244c490a Kernel: Allocate all device major numbers within one known header file
We used to allocate major numbers quite randomly, with no common place
to look them up if needed.
This commit is changing that by placing all major number allocations
under a new C++ namespace, in the API/MajorNumberAllocation.h file.

We also add the foundations of what is needed before we can publish this
information (allocated numbers for block and char devices) to userspace.
2024-07-06 21:42:32 +02:00
Liav A.
7f5a2c1466 Kernel: Register block and character devices in separate HashMaps
Instead of putting everything in one hash map, let's distinguish between
the devices based on their type.

This change makes the devices semantically separated, and is considered
a preparation before we could expose a comprehensive list of allocations
per major numbers and their purpose.
2024-07-06 21:42:32 +02:00
Sönke Holz
facca92780 Kernel/Storage: Dump storage devices to the framebuffer console as well
This is helps bringing up bare metal devices without having to use the
serial console.
2024-06-26 08:47:00 +02:00
Kirill Nikolaev
99f6528009 Kernel: Implement virtio-blk driver 2024-05-23 00:59:39 -06:00
Idan Horowitz
26cff62a0a Kernel: Rename Memory::PhysicalPage to Memory::PhysicalRAMPage
Since these are now only used to represent RAM pages, (and not MMIO
pages) rename them to make their purpose more obvious.
2024-05-17 15:38:28 -06:00
Idan Horowitz
827322c139 Kernel: Stop allocating physical pages for mapped MMIO regions
As MMIO is placed at fixed physical addressed, and does not need to be
backed by real RAM physical pages, there's no need to use PhysicalPage
instances to track their pages.
This results in slightly reduced allocations, but more importantly
makes MMIO addresses which end up after the normal RAM ranges work,
like 64-bit PCI BARs usually are.
2024-05-17 15:38:28 -06:00
Liav A.
b4c218168f Kernel/Storage: Remove StorageController reset and shutdown methods
We never used these virtual methods outside their own implementation,
so let's stop pretending that we should be able to utilize this for
unknown purpose.
2024-05-14 15:42:29 -06:00
Liav A.
2cb86c1309 Kernel/Storage: Remove ATA IDE support
Nobody uses this functionality. I used this code on my old 2007 ICH7
test machine about a year ago, but bare metal is a small aspect of the
project, so it's safe to assume that nobody really tests this piece of
code.
Therefore, let's drop this for good and focus on more modern hardware.
2024-05-14 12:38:05 -06:00
Liav A.
f7a85401bb Kernel/Storage: Remove a stale StorageDevice constructor method
ramdisk devices are long gone by now, so this is a stale method.
2024-05-07 17:02:09 -06:00
Idan Horowitz
7339409575 Kernel: Properly initialize NVMe admin queue depth
We were reading the value instead of setting it (as required by the
specification). This worked only when we booted with a bootloader which
initialized NVMe before us.
2024-04-26 09:52:56 +02:00
Idan Horowitz
a2b2209ea5 Kernel: Fix definition of CAP_TO_MASK
The default type for integer literals is signed int, so we were
accidentally smearing those bits to the upper 32 bit of the result.
This resulted in extremely unreasonable timeouts.
2024-04-26 09:52:56 +02:00
Timothy Flynn
ec492a1a08 Everywhere: Run clang-format
The following command was used to clang-format these files:

    clang-format-18 -i $(find . \
        -not \( -path "./\.*" -prune \) \
        -not \( -path "./Base/*" -prune \) \
        -not \( -path "./Build/*" -prune \) \
        -not \( -path "./Toolchain/*" -prune \) \
        -not \( -path "./Ports/*" -prune \) \
        -type f -name "*.cpp" -o -name "*.mm" -o -name "*.h")

There are a couple of weird cases where clang-format now thinks that a
pointer access in an initializer list, e.g. `m_member(ptr->foo)`, is a
lambda return statement, and it puts spaces around the `->`.
2024-04-24 16:50:01 -04:00
Dan Klishch
5ed7cd6e32 Everywhere: Use east const in more places
These changes are compatible with clang-format 16 and will be mandatory
when we eventually bump clang-format version. So, since there are no
real downsides, let's commit them now.
2024-04-19 06:31:19 -04:00
Sönke Holz
6daa0da3c6 Kernel/NVMe: Fix calculation of "Maximum Queue Entries Supported" field
The value of this field is incremented by one, as a value of 0 for this
field means 1 entry supported.

A value of 0xffff for CAP.MQES would incorrectly by truncated to 0x0000,
if we don't increase the bit width of the return type.
2024-03-25 14:08:28 -06:00
Liav A
11ead5c84f Kernel: Get RefPtr<Device> from the DeviceManagement::get_device method
Instead of returning a raw pointer, which could be technically invalid
when using it in the caller function, we return a valid RefPtr of such
device.

This ensures that the code in DevPtsFS is now safe from a rare race
condition in which the SlavePTY device is gone but we still have a
pointer to it.
2024-03-13 15:33:47 -06:00
Hendiadyoin1
3e3b34ab8a Kernel/NVMe: Use a struct for the namespace features, instead of a Tuple 2024-03-01 14:05:53 -07:00
Sönke Holz
cdc0c9f094 Kernel/Storage: Don't allocate IRQs in NVMeCntlr when nvme_poll passed 2024-02-25 17:20:40 -07:00
Sönke Holz
f6151b3c9e Kernel/Storage: Add AssertSizes to AHCI structs 2024-02-24 16:36:47 -07:00
Sönke Holz
f85099ea47 Kernel/Storage: Make AHCI::HBA::port_regs a flexible array member
Some real hardware apparently uses smaller BAR sizes than sizeof(HBA)
with a completely filled port_regs member.
Change the port_regs array to a flexible array member, so we don't panic
while verifying that the BAR size is large enough to map this struct.
Accesses to this array are already bounds checked against
AHCI::Limits::MaxPorts.
2024-02-24 16:36:47 -07:00
Liav A
c216e7439f Kernel: Require StorageDevice reference for StorageDevicePartition
Allowing creation of StorageDevicePartition objects for any arbitrary
BlockDevice objects means that we could technically create a
StorageDevicePartition for another StorageDevicePartition which is
obviously not the intention for this code. Instead, require to pass a
StorageDevice reference to ensure this cannot happen.
2024-02-24 16:01:26 -07:00
Liav A
f08f339e9a Kernel: Return EIO if attached device is gone in StorageDevicePartition
The previous code will just do a nullptr-dereference if the underlying
device is gone, so instead gracefully return EIO error.
2024-02-24 16:01:26 -07:00
Liav A
67e028e4f4 Kernel: Declare proper blocking support for StorageDevicePartitions 2024-02-24 16:01:26 -07:00
Liav A
42ed0a6c94 Kernel/Storage: Rename DiskPartition => StorageDevicePartition
We deal with partitions for storage devices, not only for disk devices,
originally harddrives.
2024-02-24 16:01:26 -07:00
Liav A
4e651d0e4f Kernel/Storage: Convert StorageDevice class members to be const
It is expected that these class members will be set when the object is
created (so they're set in the class constructor method) and never
change again, as its the driver responsibility to find these values
before creating a StorageDevice object.

This makes it easier to rely on these values later on as we don't expect
them to ever change for a StorageDevice object during its lifetime.
2024-02-24 16:01:26 -07:00
Liav A
c8bdcd90a8 Kernel/Storage: Fix StorageDevice STORAGE_DEVICE_GET_SIZE ioctl option
It calculated the disk size with the zero-based max addressable block
value.
For example, for a disk device with a block size of 512 bytes that has 2
LBAs so it can address LBA 0 and LBA 1 (so m_max_addressable_block is 1)
the calculated disk size will be 512 instead of 1024 bytes.
2024-02-24 16:01:26 -07:00
Liav A
763ef690c6 Kernel/Storage: Declare proper blocking support for StorageDevices
We remove can_read() and can_write(), as both of these methods should be
implemented for proper blocking support.
For our case, the previous code will simply block the user if they tries
to read beyond the max addressable offset, which is not a correct
behavior.

Instead, just do proper EOF guarding when calling read() and write() on
such objects.
2024-02-24 16:01:26 -07:00
Liav A
c33246235a Kernel/Storage: Change semantics for addressing block methods
Add a method for matehmatical operations when verifying IO operation
boundaries.
Also, make max_addressable_block method non-virtual, since no other
derived class actually has ever overrided this method.
2024-02-24 16:01:26 -07:00
Tim Ledbetter
532f2b644c Kernel: Propagate errors with TRY() where possible 2024-02-14 17:46:06 -05:00
Nico Weber
4409b33145 AK: Make IndexSequence use size_t
This makes it possible to use MakeIndexSequqnce in functions like:

    template<typename T, size_t N>
    constexpr auto foo(T (&a)[N])

This means AK/StdLibExtraDetails.h must now include AK/Types.h
for size_t, which means AK/Types.h can no longer include
AK/StdLibExtras.h (which arguably it shouldn't do anyways),
which requires rejiggering some things.

(IMHO Types.h shouldn't use AK::Details metaprogramming at all.
FlatPtr doesn't necessarily have to use Conditional<> and ssize_t could
maybe be in its own header or something. But since it's tangential to
this PR, going with the tried and true "lift things that cause the
cycle up to the top" approach.)
2024-02-11 18:53:00 +01:00
Idan Horowitz
03cb3e5370 Kernel: Move NVMeQueue's m_cq_lock to NVMePollQueue
It's only used by that subclass, so there's no reason for it to be
defined as part of the parent class.
2024-02-10 08:42:53 +01:00
Idan Horowitz
45aee20ea9 Kernel: Switch to SpinlockProtected to protect NVMeQueue's requests map
This helps ensure no one accidentally accesses m_requests without first
locking it's spinlock. In fact this change fixed such a case, since
process_cq() implicitly assumed the caller locked the lock, which was
not the case for NVMePollQueue::submit_sqe().
2024-02-10 08:42:53 +01:00