mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 16:18:12 +00:00
Kernel: Implement an asynchronous device request stack
This allows issuing asynchronous requests for devices and waiting on the completion of the request. The requests can cascade into multiple sub-requests. Since IRQs may complete at any time, if the current process is no longer the same that started the process, we need to swich the paging context before accessing user buffers. Change the PATA driver to use this model.
This commit is contained in:
parent
96081010dc
commit
2fd5ce1eb0
17 changed files with 804 additions and 246 deletions
|
@ -30,6 +30,46 @@
|
|||
|
||||
namespace Kernel {
|
||||
|
||||
class BlockDevice;
|
||||
|
||||
class AsyncBlockDeviceRequest : public AsyncDeviceRequest {
|
||||
public:
|
||||
enum RequestType {
|
||||
Read,
|
||||
Write
|
||||
};
|
||||
AsyncBlockDeviceRequest(Device& block_device, RequestType request_type,
|
||||
u32 block_index, u32 block_count, const UserOrKernelBuffer& buffer, size_t buffer_size);
|
||||
|
||||
RequestType request_type() const { return m_request_type; }
|
||||
u32 block_index() const { return m_block_index; }
|
||||
u32 block_count() const { return m_block_count; }
|
||||
UserOrKernelBuffer& buffer() { return m_buffer; }
|
||||
const UserOrKernelBuffer& buffer() const { return m_buffer; }
|
||||
size_t buffer_size() const { return m_buffer_size; }
|
||||
|
||||
virtual void start() override;
|
||||
virtual const char* name() const override
|
||||
{
|
||||
switch (m_request_type) {
|
||||
case Read:
|
||||
return "BlockDeviceRequest (read)";
|
||||
case Write:
|
||||
return "BlockDeviceRequest (read)";
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
BlockDevice& m_block_device;
|
||||
const RequestType m_request_type;
|
||||
const u32 m_block_index;
|
||||
const u32 m_block_count;
|
||||
UserOrKernelBuffer m_buffer;
|
||||
const size_t m_buffer_size;
|
||||
};
|
||||
|
||||
class BlockDevice : public Device {
|
||||
public:
|
||||
virtual ~BlockDevice() override;
|
||||
|
@ -37,11 +77,10 @@ public:
|
|||
size_t block_size() const { return m_block_size; }
|
||||
virtual bool is_seekable() const override { return true; }
|
||||
|
||||
bool read_block(unsigned index, UserOrKernelBuffer&) const;
|
||||
bool read_block(unsigned index, UserOrKernelBuffer&);
|
||||
bool write_block(unsigned index, const UserOrKernelBuffer&);
|
||||
|
||||
virtual bool read_blocks(unsigned index, u16 count, UserOrKernelBuffer&) = 0;
|
||||
virtual bool write_blocks(unsigned index, u16 count, const UserOrKernelBuffer&) = 0;
|
||||
virtual void start_request(AsyncBlockDeviceRequest&) = 0;
|
||||
|
||||
protected:
|
||||
BlockDevice(unsigned major, unsigned minor, size_t block_size = PAGE_SIZE)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue