Serenity Operating System
at master 95 lines 3.0 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/IntegralMath.h> 10#include <Kernel/Devices/Device.h> 11#include <Kernel/Library/LockWeakable.h> 12 13namespace Kernel { 14 15class AsyncBlockDeviceRequest; 16 17class BlockDevice : public Device { 18public: 19 virtual ~BlockDevice() override; 20 21 size_t block_size() const { return m_block_size; } 22 u8 block_size_log() const { return m_block_size_log; } 23 virtual bool is_seekable() const override { return true; } 24 25 bool read_block(u64 index, UserOrKernelBuffer&); 26 bool write_block(u64 index, UserOrKernelBuffer const&); 27 28 virtual void start_request(AsyncBlockDeviceRequest&) = 0; 29 30protected: 31 BlockDevice(MajorNumber major, MinorNumber minor, size_t block_size = PAGE_SIZE) 32 : Device(major, minor) 33 , m_block_size(block_size) 34 { 35 // 512 is the minimum sector size in most block devices 36 VERIFY(m_block_size >= 512); 37 VERIFY(is_power_of_two(m_block_size)); 38 m_block_size_log = AK::log2(m_block_size); 39 } 40 41protected: 42 virtual bool is_block_device() const final { return true; } 43 44 virtual void after_inserting_add_symlink_to_device_identifier_directory() override final; 45 virtual void before_will_be_destroyed_remove_symlink_from_device_identifier_directory() override final; 46 47private: 48 // FIXME: These methods will be eventually removed after all nodes in /sys/dev/block/ are symlinks 49 virtual void after_inserting_add_to_device_identifier_directory() override final; 50 virtual void before_will_be_destroyed_remove_from_device_identifier_directory() override final; 51 52 size_t m_block_size { 0 }; 53 u8 m_block_size_log { 0 }; 54}; 55 56class AsyncBlockDeviceRequest final : public AsyncDeviceRequest { 57public: 58 enum RequestType { 59 Read, 60 Write 61 }; 62 AsyncBlockDeviceRequest(Device& block_device, RequestType request_type, 63 u64 block_index, u32 block_count, UserOrKernelBuffer const& buffer, size_t buffer_size); 64 65 RequestType request_type() const { return m_request_type; } 66 u64 block_index() const { return m_block_index; } 67 u32 block_count() const { return m_block_count; } 68 size_t block_size() const { return m_block_device.block_size(); } 69 UserOrKernelBuffer& buffer() { return m_buffer; } 70 UserOrKernelBuffer const& buffer() const { return m_buffer; } 71 size_t buffer_size() const { return m_buffer_size; } 72 73 virtual void start() override; 74 virtual StringView name() const override 75 { 76 switch (m_request_type) { 77 case Read: 78 return "BlockDeviceRequest (read)"sv; 79 case Write: 80 return "BlockDeviceRequest (write)"sv; 81 default: 82 VERIFY_NOT_REACHED(); 83 } 84 } 85 86private: 87 BlockDevice& m_block_device; 88 const RequestType m_request_type; 89 const u64 m_block_index; 90 const u32 m_block_count; 91 UserOrKernelBuffer m_buffer; 92 const size_t m_buffer_size; 93}; 94 95}