DeviceAttribute.cpp 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <Kernel/Bus/PCI/API.h>
  7. #include <Kernel/Bus/PCI/Access.h>
  8. #include <Kernel/FileSystem/SysFS/Subsystems/Bus/PCI/DeviceAttribute.h>
  9. #include <Kernel/Sections.h>
  10. namespace Kernel {
  11. StringView PCIDeviceAttributeSysFSComponent::name() const
  12. {
  13. switch (m_offset) {
  14. case PCI::RegisterOffset::VENDOR_ID:
  15. return "vendor"sv;
  16. case PCI::RegisterOffset::DEVICE_ID:
  17. return "device_id"sv;
  18. case PCI::RegisterOffset::CLASS:
  19. return "class"sv;
  20. case PCI::RegisterOffset::SUBCLASS:
  21. return "subclass"sv;
  22. case PCI::RegisterOffset::REVISION_ID:
  23. return "revision"sv;
  24. case PCI::RegisterOffset::PROG_IF:
  25. return "progif"sv;
  26. case PCI::RegisterOffset::SUBSYSTEM_VENDOR_ID:
  27. return "subsystem_vendor"sv;
  28. case PCI::RegisterOffset::SUBSYSTEM_ID:
  29. return "subsystem_id"sv;
  30. case PCI::RegisterOffset::BAR0:
  31. return "bar0"sv;
  32. case PCI::RegisterOffset::BAR1:
  33. return "bar1"sv;
  34. case PCI::RegisterOffset::BAR2:
  35. return "bar2"sv;
  36. case PCI::RegisterOffset::BAR3:
  37. return "bar3"sv;
  38. case PCI::RegisterOffset::BAR4:
  39. return "bar4"sv;
  40. case PCI::RegisterOffset::BAR5:
  41. return "bar5"sv;
  42. default:
  43. VERIFY_NOT_REACHED();
  44. }
  45. }
  46. NonnullRefPtr<PCIDeviceAttributeSysFSComponent> PCIDeviceAttributeSysFSComponent::create(PCIDeviceSysFSDirectory const& device, PCI::RegisterOffset offset, size_t field_bytes_width)
  47. {
  48. return adopt_ref(*new (nothrow) PCIDeviceAttributeSysFSComponent(device, offset, field_bytes_width));
  49. }
  50. PCIDeviceAttributeSysFSComponent::PCIDeviceAttributeSysFSComponent(PCIDeviceSysFSDirectory const& device, PCI::RegisterOffset offset, size_t field_bytes_width)
  51. : SysFSComponent()
  52. , m_device(device)
  53. , m_offset(offset)
  54. , m_field_bytes_width(field_bytes_width)
  55. {
  56. }
  57. ErrorOr<size_t> PCIDeviceAttributeSysFSComponent::read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription*) const
  58. {
  59. auto blob = TRY(try_to_generate_buffer());
  60. if ((size_t)offset >= blob->size())
  61. return 0;
  62. ssize_t nread = min(static_cast<off_t>(blob->size() - offset), static_cast<off_t>(count));
  63. TRY(buffer.write(blob->data() + offset, nread));
  64. return nread;
  65. }
  66. ErrorOr<NonnullOwnPtr<KBuffer>> PCIDeviceAttributeSysFSComponent::try_to_generate_buffer() const
  67. {
  68. OwnPtr<KString> value;
  69. SpinlockLocker locker(m_device->device_identifier().operation_lock());
  70. switch (m_field_bytes_width) {
  71. case 1:
  72. value = TRY(KString::formatted("{:#x}", PCI::read8_locked(m_device->device_identifier(), m_offset)));
  73. break;
  74. case 2:
  75. value = TRY(KString::formatted("{:#x}", PCI::read16_locked(m_device->device_identifier(), m_offset)));
  76. break;
  77. case 4:
  78. value = TRY(KString::formatted("{:#x}", PCI::read32_locked(m_device->device_identifier(), m_offset)));
  79. break;
  80. default:
  81. VERIFY_NOT_REACHED();
  82. }
  83. return KBuffer::try_create_with_bytes("PCIDeviceAttributeSysFSComponent: Device address"sv, value->view().bytes());
  84. }
  85. }