aboutsummaryrefslogtreecommitdiff
path: root/kernel/kapi/devices/device.cpp
blob: 2576e20a6abcf3227674abec5228b820edb13f09 (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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <kapi/devices/device.hpp>

#include <kapi/capabilities/facet_id.hpp>
#include <kapi/devices.hpp>
#include <kapi/devices/bus.hpp>
#include <kapi/devices/resource.hpp>

#include <kstd/memory.hpp>
#include <kstd/mutex.hpp>
#include <kstd/result.hpp>
#include <kstd/string.hpp>
#include <kstd/system_error.hpp>
#include <kstd/vector.hpp>

#include <algorithm>
#include <cstddef>
#include <ranges>
#include <utility>

namespace kapi::devices
{
  device::device(kstd::string const & name)
      : m_name(name)
  {}

  auto device::facet(kapi::capabilities::facet_id facet) noexcept -> void *
  {
    return query_facet(facet);
  }

  auto device::facet(kapi::capabilities::facet_id facet) const noexcept -> void const *
  {
    return const_cast<device *>(this)->query_facet(facet);
  }

  auto device::has_facet(kapi::capabilities::facet_id facet) const noexcept -> bool
  {
    return const_cast<device *>(this)->query_facet(facet) != nullptr;
  }

  auto device::name() const -> kstd::string const &
  {
    return m_name;
  }

  auto device::parent() const -> kstd::shared_ptr<bus>
  {
    auto guard = kstd::lock_guard{m_lock};
    return m_parent.lock();
  }

  auto device::state() const noexcept -> enum state
  {
    auto guard = kstd::lock_guard{m_lock};
    return m_state;
  }

  auto device::set_state(enum state state) -> void
  {
    auto guard = kstd::lock_guard{m_lock};
    m_state = state;
  }

  auto device::bound_driver() const noexcept -> driver *
  {
    auto guard = kstd::lock_guard{m_lock};
    return m_driver.lock().get();
  }

  auto device::bind_driver(kstd::weak_ptr<struct driver> driver) -> void
  {
    auto guard = kstd::lock_guard{m_lock};
    m_driver = driver;
  }

  auto device::driver_data() const -> kstd::shared_ptr<void>
  {
    auto guard = kstd::lock_guard{m_lock};
    return m_driver_data;
  }

  auto device::set_driver_data(kstd::shared_ptr<void> data) -> void
  {
    auto guard = kstd::lock_guard{m_lock};
    m_driver_data = data;
  }

  auto device::resources() const -> kstd::vector<resource>
  {
    auto guard = kstd::lock_guard{m_lock};
    return m_resources;
  }

  auto device::request_resource(resource_type type, std::size_t index) const -> kstd::result<resource>
  {
    auto guard = kstd::lock_guard{m_lock};

    auto filtered = std::views::filter(m_resources, [&](auto e) { return e.type == type; });
    auto numbered_resources = std::views::enumerate(filtered);
    auto found = std::ranges::find_if(
        numbered_resources, [&](auto entry) { return static_cast<std::size_t>(std::get<0>(entry)) == index; });

    if (found != numbered_resources.end())
    {
      return kstd::success(*found.base());
    }

    return kstd::failure(make_error_code(kstd::errc::invalid_argument));
  }

  auto device::set_resources(kstd::vector<resource> resources) -> void
  {
    auto guard = kstd::lock_guard{m_lock};
    m_resources = std::move(resources);
  }

  auto device::query_facet(kapi::capabilities::facet_id) -> void *
  {
    return nullptr;
  }

  auto device::set_parent(kstd::weak_ptr<bus> parent) -> void
  {
    auto guard = kstd::lock_guard{m_lock};
    m_parent = parent;
  }

}  // namespace kapi::devices