summaryrefslogtreecommitdiff
path: root/Kernel/Bus
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2023-04-05 13:21:11 +0300
committerLinus Groh <mail@linusgroh.de>2023-04-14 19:24:54 +0200
commitb02ee664e7f62e19c48657034e779c53d11325a9 (patch)
treed5238be614caba8b365c7d9833ff0146655ddf52 /Kernel/Bus
parentdd7633c5f418952390d056146510040d08125ee4 (diff)
downloadserenity-b02ee664e7f62e19c48657034e779c53d11325a9.zip
Kernel: Get rid of *LockRefPtr in the SysFS filesystem code
To do this we also need to get rid of LockRefPtrs in the USB code as well. Most of the SysFS nodes are statically generated during boot and are not mutated afterwards. The same goes for general device code - once we generate the appropriate SysFS nodes, we almost never mutate the node pointers afterwards, making locking unnecessary.
Diffstat (limited to 'Kernel/Bus')
-rw-r--r--Kernel/Bus/USB/USBDevice.cpp4
-rw-r--r--Kernel/Bus/USB/USBDevice.h5
-rw-r--r--Kernel/Bus/USB/USBHub.cpp24
3 files changed, 24 insertions, 9 deletions
diff --git a/Kernel/Bus/USB/USBDevice.cpp b/Kernel/Bus/USB/USBDevice.cpp
index a6e3531f8b..95a0f10d6e 100644
--- a/Kernel/Bus/USB/USBDevice.cpp
+++ b/Kernel/Bus/USB/USBDevice.cpp
@@ -21,7 +21,9 @@ ErrorOr<NonnullLockRefPtr<Device>> Device::try_create(USBController const& contr
auto pipe = TRY(ControlPipe::create(controller, 0, 8, 0));
auto device = TRY(adopt_nonnull_lock_ref_or_enomem(new (nothrow) Device(controller, port, speed, move(pipe))));
auto sysfs_node = TRY(SysFSUSBDeviceInformation::create(*device));
- device->m_sysfs_device_info_node = move(sysfs_node);
+ device->m_sysfs_device_info_node.with([&](auto& node) {
+ node = move(sysfs_node);
+ });
TRY(device->enumerate_device());
return device;
}
diff --git a/Kernel/Bus/USB/USBDevice.h b/Kernel/Bus/USB/USBDevice.h
index e11fab6cbe..47144d36ed 100644
--- a/Kernel/Bus/USB/USBDevice.h
+++ b/Kernel/Bus/USB/USBDevice.h
@@ -12,6 +12,7 @@
#include <AK/Vector.h>
#include <Kernel/Bus/USB/USBConfiguration.h>
#include <Kernel/Bus/USB/USBPipe.h>
+#include <Kernel/Locking/SpinlockProtected.h>
namespace Kernel {
class SysFSUSBDeviceInformation;
@@ -57,7 +58,7 @@ public:
Vector<USBConfiguration> const& configurations() const { return m_configurations; }
- SysFSUSBDeviceInformation& sysfs_device_info_node(Badge<USB::Hub>) { return *m_sysfs_device_info_node; }
+ SpinlockProtected<RefPtr<SysFSUSBDeviceInformation>, LockRank::None>& sysfs_device_info_node(Badge<USB::Hub>) { return m_sysfs_device_info_node; }
protected:
Device(NonnullLockRefPtr<USBController> controller, u8 address, u8 port, DeviceSpeed speed, NonnullOwnPtr<ControlPipe> default_pipe);
@@ -79,7 +80,7 @@ private:
IntrusiveListNode<Device, NonnullLockRefPtr<Device>> m_hub_child_node;
protected:
- LockRefPtr<SysFSUSBDeviceInformation> m_sysfs_device_info_node;
+ SpinlockProtected<RefPtr<SysFSUSBDeviceInformation>, LockRank::None> m_sysfs_device_info_node;
public:
using List = IntrusiveList<&Device::m_hub_child_node>;
diff --git a/Kernel/Bus/USB/USBHub.cpp b/Kernel/Bus/USB/USBHub.cpp
index 297c9752e4..e6a3f7bc8d 100644
--- a/Kernel/Bus/USB/USBHub.cpp
+++ b/Kernel/Bus/USB/USBHub.cpp
@@ -46,7 +46,10 @@ ErrorOr<void> Hub::enumerate_and_power_on_hub()
// USBDevice::enumerate_device must be called before this.
VERIFY(m_address > 0);
- m_sysfs_device_info_node = TRY(SysFSUSBDeviceInformation::create(*this));
+ TRY(m_sysfs_device_info_node.with([&](auto& node) -> ErrorOr<void> {
+ node = TRY(SysFSUSBDeviceInformation::create(*this));
+ return {};
+ }));
if (m_device_descriptor.device_class != USB_CLASS_HUB) {
dbgln("USB Hub: Trying to enumerate and power on a device that says it isn't a hub.");
@@ -133,8 +136,11 @@ ErrorOr<void> Hub::set_port_feature(u8 port, HubFeatureSelector feature_selector
void Hub::remove_children_from_sysfs()
{
- for (auto& child : m_children)
- SysFSUSBBusDirectory::the().unplug({}, child.sysfs_device_info_node({}));
+ for (auto& child : m_children) {
+ child.sysfs_device_info_node({}).with([](auto& node) {
+ SysFSUSBBusDirectory::the().unplug({}, *node);
+ });
+ }
}
void Hub::check_for_port_updates()
@@ -260,10 +266,14 @@ void Hub::check_for_port_updates()
auto hub = hub_or_error.release_value();
m_children.append(hub);
- SysFSUSBBusDirectory::the().plug({}, hub->sysfs_device_info_node({}));
+ hub->sysfs_device_info_node({}).with([](auto& node) {
+ SysFSUSBBusDirectory::the().plug({}, *node);
+ });
} else {
m_children.append(device);
- SysFSUSBBusDirectory::the().plug({}, device->sysfs_device_info_node({}));
+ device->sysfs_device_info_node({}).with([](auto& node) {
+ SysFSUSBBusDirectory::the().plug({}, *node);
+ });
}
} else {
@@ -278,7 +288,9 @@ void Hub::check_for_port_updates()
}
if (device_to_remove) {
- SysFSUSBBusDirectory::the().unplug({}, device_to_remove->sysfs_device_info_node({}));
+ device_to_remove->sysfs_device_info_node({}).with([](auto& node) {
+ SysFSUSBBusDirectory::the().unplug({}, *node);
+ });
if (device_to_remove->device_descriptor().device_class == USB_CLASS_HUB) {
auto* hub_child = static_cast<Hub*>(device_to_remove.ptr());
hub_child->remove_children_from_sysfs();