summaryrefslogtreecommitdiff
path: root/Kernel/Bus/USB/SysFSUSB.h
blob: 87a5b8857e0e1027ca9150f2a89341b59a2005ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
 * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

#include <Kernel/Bus/USB/USBDevice.h>
#include <Kernel/FileSystem/SysFS.h>
#include <Kernel/KBufferBuilder.h>
#include <Kernel/Locking/Mutex.h>

namespace Kernel::USB {

class SysFSUSBDeviceInformation : public SysFSComponent {
    friend class SysFSUSBBusDirectory;

public:
    virtual ~SysFSUSBDeviceInformation() override;

    static NonnullRefPtr<SysFSUSBDeviceInformation> create(USB::Device&);
    virtual StringView name() const override { return m_device_name->view(); }

    RefPtr<USB::Device> device() const { return m_device; }

protected:
    SysFSUSBDeviceInformation(NonnullOwnPtr<KString> device_name, USB::Device& device);

    virtual ErrorOr<size_t> read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;

    IntrusiveListNode<SysFSUSBDeviceInformation, RefPtr<SysFSUSBDeviceInformation>> m_list_node;

    NonnullRefPtr<USB::Device> m_device;

private:
    ErrorOr<void> try_generate(KBufferBuilder&);
    virtual ErrorOr<void> refresh_data(OpenFileDescription& description) const override;
    mutable Mutex m_lock { "SysFSUSBDeviceInformation" };
    NonnullOwnPtr<KString> m_device_name;
};

class SysFSUSBBusDirectory final : public SysFSDirectory {
public:
    static void initialize();
    static SysFSUSBBusDirectory& the();

    virtual StringView name() const override { return "usb"sv; }

    void plug(USB::Device&);
    void unplug(USB::Device&);

    virtual ErrorOr<void> traverse_as_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override;
    virtual RefPtr<SysFSComponent> lookup(StringView name) override;

private:
    explicit SysFSUSBBusDirectory(SysFSBusDirectory&);

    RefPtr<SysFSUSBDeviceInformation> device_node_for(USB::Device& device);

    IntrusiveList<&SysFSUSBDeviceInformation::m_list_node> m_device_nodes;
    mutable Spinlock m_lock;
};

}