Kernel: Implement basic USB Mass Storage support
I finally decided to do this :D
This commit is contained in:
@@ -66,6 +66,7 @@
|
||||
#define DEBUG_USB_HID 0
|
||||
#define DEBUG_USB_KEYBOARD 0
|
||||
#define DEBUG_USB_MOUSE 0
|
||||
#define DEBUG_USB_MASS_STORAGE 0
|
||||
|
||||
|
||||
namespace Debug
|
||||
|
||||
29
kernel/include/kernel/USB/MassStorage/Definitions.h
Normal file
29
kernel/include/kernel/USB/MassStorage/Definitions.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Kernel::USBMassStorage
|
||||
{
|
||||
|
||||
struct CBW
|
||||
{
|
||||
uint32_t dCBWSignature;
|
||||
uint32_t dCBWTag;
|
||||
uint32_t dCBWDataTransferLength;
|
||||
uint8_t bmCBWFlags;
|
||||
uint8_t bCBWLUN;
|
||||
uint8_t bCBWCBLength;
|
||||
uint8_t CBWCB[16];
|
||||
} __attribute__((packed));
|
||||
static_assert(sizeof(CBW) == 31);
|
||||
|
||||
struct CSW
|
||||
{
|
||||
uint32_t dCSWSignature;
|
||||
uint32_t dCSWTag;
|
||||
uint32_t dCSWDataResidue;
|
||||
uint8_t bmCSWStatus;
|
||||
} __attribute__((packed));
|
||||
static_assert(sizeof(CSW) == 13);
|
||||
|
||||
}
|
||||
49
kernel/include/kernel/USB/MassStorage/MassStorageDriver.h
Normal file
49
kernel/include/kernel/USB/MassStorage/MassStorageDriver.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <BAN/Function.h>
|
||||
|
||||
#include <kernel/Lock/Mutex.h>
|
||||
#include <kernel/Storage/StorageDevice.h>
|
||||
#include <kernel/USB/Device.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
class USBMassStorageDriver final : public USBClassDriver
|
||||
{
|
||||
BAN_NON_COPYABLE(USBMassStorageDriver);
|
||||
BAN_NON_MOVABLE(USBMassStorageDriver);
|
||||
|
||||
public:
|
||||
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> recv_bytes(paddr_t, size_t count);
|
||||
|
||||
void lock() { m_mutex.lock(); }
|
||||
void unlock() { m_mutex.unlock(); }
|
||||
|
||||
private:
|
||||
USBMassStorageDriver(USBDevice&, const USBDevice::InterfaceDescriptor&);
|
||||
~USBMassStorageDriver();
|
||||
|
||||
BAN::ErrorOr<void> initialize() override;
|
||||
|
||||
private:
|
||||
USBDevice& m_device;
|
||||
USBDevice::InterfaceDescriptor m_interface;
|
||||
|
||||
Mutex m_mutex;
|
||||
|
||||
uint8_t m_in_endpoint_id { 0 };
|
||||
BAN::Function<void(size_t)> m_in_callback;
|
||||
|
||||
uint8_t m_out_endpoint_id { 0 };
|
||||
BAN::Function<void(size_t)> m_out_callback;
|
||||
|
||||
BAN::Vector<BAN::RefPtr<StorageDevice>> m_storage_devices;
|
||||
|
||||
friend class BAN::UniqPtr<USBMassStorageDriver>;
|
||||
};
|
||||
|
||||
}
|
||||
46
kernel/include/kernel/USB/MassStorage/SCSIDevice.h
Normal file
46
kernel/include/kernel/USB/MassStorage/SCSIDevice.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <kernel/FS/DevFS/FileSystem.h>
|
||||
#include <kernel/Storage/StorageDevice.h>
|
||||
#include <kernel/USB/MassStorage/MassStorageDriver.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
class USBSCSIDevice : public StorageDevice
|
||||
{
|
||||
public:
|
||||
static BAN::ErrorOr<BAN::RefPtr<USBSCSIDevice>> create(USBMassStorageDriver& driver, uint8_t lun, uint32_t max_packet_size);
|
||||
|
||||
uint32_t sector_size() const override { return m_block_size; }
|
||||
uint64_t total_size() const override { return m_block_size * m_block_count; }
|
||||
|
||||
dev_t rdev() const override { return m_rdev; }
|
||||
BAN::StringView name() const override { return m_name; }
|
||||
|
||||
private:
|
||||
USBSCSIDevice(USBMassStorageDriver& driver, uint8_t lun, BAN::UniqPtr<DMARegion>&&, uint64_t block_count, uint32_t block_size);
|
||||
~USBSCSIDevice();
|
||||
|
||||
static BAN::ErrorOr<size_t> send_scsi_command_impl(USBMassStorageDriver&, DMARegion& dma_region, uint8_t lun, BAN::ConstByteSpan command, BAN::ByteSpan data, bool in);
|
||||
BAN::ErrorOr<size_t> send_scsi_command(BAN::ConstByteSpan command, BAN::ByteSpan data, bool in);
|
||||
|
||||
BAN::ErrorOr<void> read_sectors_impl(uint64_t first_lba, uint64_t sector_count, BAN::ByteSpan buffer) override;
|
||||
BAN::ErrorOr<void> write_sectors_impl(uint64_t lba, uint64_t sector_count, BAN::ConstByteSpan buffer) override;
|
||||
|
||||
private:
|
||||
USBMassStorageDriver& m_driver;
|
||||
BAN::UniqPtr<DMARegion> m_dma_region;
|
||||
|
||||
const uint8_t m_lun;
|
||||
|
||||
const uint64_t m_block_count;
|
||||
const uint32_t m_block_size;
|
||||
|
||||
const dev_t m_rdev;
|
||||
const char m_name[4];
|
||||
|
||||
friend class BAN::RefPtr<USBSCSIDevice>;
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user