Serenity Operating System
at master 140 lines 3.9 kB view raw
1/* 2 * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/HashTable.h> 8#include <AK/Singleton.h> 9#include <Kernel/Devices/DeviceManagement.h> 10#include <Kernel/FileSystem/InodeMetadata.h> 11#include <Kernel/Sections.h> 12 13namespace Kernel { 14 15static Singleton<DeviceManagement> s_the; 16 17UNMAP_AFTER_INIT DeviceManagement::DeviceManagement() 18{ 19} 20UNMAP_AFTER_INIT void DeviceManagement::initialize() 21{ 22 s_the.ensure_instance(); 23} 24 25UNMAP_AFTER_INIT void DeviceManagement::attach_console_device(ConsoleDevice const& device) 26{ 27 m_console_device = device; 28} 29 30UNMAP_AFTER_INIT void DeviceManagement::attach_null_device(NullDevice const& device) 31{ 32 m_null_device = device; 33} 34 35UNMAP_AFTER_INIT void DeviceManagement::attach_device_control_device(DeviceControlDevice const& device) 36{ 37 m_device_control_device = device; 38} 39 40DeviceManagement& DeviceManagement::the() 41{ 42 return *s_the; 43} 44 45Device* DeviceManagement::get_device(MajorNumber major, MinorNumber minor) 46{ 47 return m_devices.with([&](auto& map) -> Device* { 48 auto it = map.find(encoded_device(major.value(), minor.value())); 49 if (it == map.end()) 50 return nullptr; 51 return it->value; 52 }); 53} 54 55Optional<DeviceEvent> DeviceManagement::dequeue_top_device_event(Badge<DeviceControlDevice>) 56{ 57 SpinlockLocker locker(m_event_queue_lock); 58 if (m_event_queue.is_empty()) 59 return {}; 60 return m_event_queue.dequeue(); 61} 62 63void DeviceManagement::before_device_removal(Badge<Device>, Device& device) 64{ 65 u64 device_id = encoded_device(device.major(), device.minor()); 66 m_devices.with([&](auto& map) -> void { 67 VERIFY(map.contains(device_id)); 68 map.remove(encoded_device(device.major(), device.minor())); 69 }); 70 71 { 72 DeviceEvent event { DeviceEvent::State::Removed, device.is_block_device(), device.major().value(), device.minor().value() }; 73 SpinlockLocker locker(m_event_queue_lock); 74 m_event_queue.enqueue(event); 75 } 76 if (m_device_control_device) 77 m_device_control_device->evaluate_block_conditions(); 78} 79 80void DeviceManagement::after_inserting_device(Badge<Device>, Device& device) 81{ 82 u64 device_id = encoded_device(device.major(), device.minor()); 83 m_devices.with([&](auto& map) -> void { 84 if (map.contains(device_id)) { 85 dbgln("Already registered {},{}: {}", device.major(), device.minor(), device.class_name()); 86 VERIFY_NOT_REACHED(); 87 } 88 auto result = map.set(device_id, &device); 89 if (result != AK::HashSetResult::InsertedNewEntry) { 90 dbgln("Failed to register {},{}: {}", device.major(), device.minor(), device.class_name()); 91 VERIFY_NOT_REACHED(); 92 } 93 }); 94 95 { 96 DeviceEvent event { DeviceEvent::State::Inserted, device.is_block_device(), device.major().value(), device.minor().value() }; 97 SpinlockLocker locker(m_event_queue_lock); 98 m_event_queue.enqueue(event); 99 } 100 if (m_device_control_device) 101 m_device_control_device->evaluate_block_conditions(); 102} 103 104void DeviceManagement::for_each(Function<void(Device&)> callback) 105{ 106 m_devices.with([&](auto& map) -> void { 107 for (auto& entry : map) 108 callback(*entry.value); 109 }); 110} 111 112ErrorOr<void> DeviceManagement::try_for_each(Function<ErrorOr<void>(Device&)> callback) 113{ 114 return m_devices.with([&](auto& map) -> ErrorOr<void> { 115 for (auto& entry : map) 116 TRY(callback(*entry.value)); 117 return {}; 118 }); 119} 120 121NullDevice& DeviceManagement::null_device() 122{ 123 return *m_null_device; 124} 125 126NullDevice const& DeviceManagement::null_device() const 127{ 128 return *m_null_device; 129} 130 131ConsoleDevice const& DeviceManagement::console_device() const 132{ 133 return *m_console_device; 134} 135ConsoleDevice& DeviceManagement::console_device() 136{ 137 return *m_console_device; 138} 139 140}