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