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