mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 05:17:34 +00:00
Kernel/USB: Add a crude USB MassStorage driver :^)
This commit is contained in:
parent
c230a0d96f
commit
29292bbdbf
8 changed files with 615 additions and 0 deletions
85
Kernel/Devices/Storage/USB/BulkSCSIInterface.h
Normal file
85
Kernel/Devices/Storage/USB/BulkSCSIInterface.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Leon Albrecht <leon.a@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/IntrusiveList.h>
|
||||
#include <Kernel/Bus/USB/USBDevice.h>
|
||||
#include <Kernel/Bus/USB/USBPipe.h>
|
||||
#include <Kernel/Devices/Storage/StorageDevice.h>
|
||||
|
||||
namespace Kernel::USB {
|
||||
|
||||
enum class CBWDirection : u8 {
|
||||
DataOut = 0,
|
||||
DataIn = 1
|
||||
};
|
||||
|
||||
struct CommandBlockWrapper {
|
||||
LittleEndian<u32> signature { 0x43425355 };
|
||||
LittleEndian<u32> tag { 0 };
|
||||
LittleEndian<u32> transfer_length { 0 };
|
||||
union {
|
||||
u8 flags { 0 };
|
||||
struct {
|
||||
u8 flag_reserved : 6;
|
||||
u8 flag_obsolete : 1;
|
||||
CBWDirection direction : 1;
|
||||
};
|
||||
};
|
||||
u8 lun { 0 }; // only 4 bits
|
||||
u8 command_length { 0 }; // 5 bits, range 1-16
|
||||
u8 command_block[16] { 0 };
|
||||
|
||||
template<typename T>
|
||||
requires(sizeof(T) <= 16)
|
||||
void set_command(T const& command)
|
||||
{
|
||||
command_length = sizeof(command);
|
||||
memcpy(&command_block, &command, sizeof(command));
|
||||
}
|
||||
};
|
||||
static_assert(AssertSize<CommandBlockWrapper, 31>());
|
||||
|
||||
enum class CSWStatus : u8 {
|
||||
Passed = 0x00,
|
||||
Failed = 0x01,
|
||||
PhaseError = 0x02
|
||||
};
|
||||
|
||||
struct CommandStatusWrapper {
|
||||
LittleEndian<u32> signature;
|
||||
LittleEndian<u32> tag;
|
||||
LittleEndian<u32> data_residue;
|
||||
CSWStatus status;
|
||||
};
|
||||
static_assert(AssertSize<CommandStatusWrapper, 13>());
|
||||
|
||||
class BulkSCSIInterface : public StorageDevice {
|
||||
// https://www.usb.org/sites/default/files/usbmassbulk_10.pdf
|
||||
public:
|
||||
BulkSCSIInterface(LUNAddress logical_unit_number_address, u32 hardware_relative_controller_id, size_t sector_size, u64 max_addressable_block, USB::Device& device, NonnullOwnPtr<BulkInPipe> in_pipe, NonnullOwnPtr<BulkOutPipe> out_pipe);
|
||||
|
||||
USB::Device const& device() const { return m_device; }
|
||||
|
||||
virtual void start_request(AsyncBlockDeviceRequest&) override;
|
||||
virtual CommandSet command_set() const override { return CommandSet::SCSI; }
|
||||
|
||||
private:
|
||||
USB::Device& m_device;
|
||||
NonnullOwnPtr<BulkInPipe> m_in_pipe;
|
||||
NonnullOwnPtr<BulkOutPipe> m_out_pipe;
|
||||
|
||||
ErrorOr<void> do_read(u32 block_index, u32 block_count, UserOrKernelBuffer& buffer, size_t buffer_size);
|
||||
ErrorOr<void> do_write(u32 block_index, u32 block_count, UserOrKernelBuffer& buffer, size_t buffer_size);
|
||||
|
||||
IntrusiveListNode<BulkSCSIInterface, NonnullLockRefPtr<BulkSCSIInterface>> m_list_node;
|
||||
|
||||
public:
|
||||
using List = IntrusiveList<&BulkSCSIInterface::m_list_node>;
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue