Skip to content

Commit 6f3baa2

Browse files
author
alex
committed
Fix AMD GPU i2c bus PCI ID detection on Linux
On newer kernels with the amdgpu driver, i2c bus symlinks in /sys/bus/i2c/devices/ resolve to paths like: /sys/devices/pci.../0000:03:00.0/i2c-4 The previous code appended '/..' and relied on sysfs path traversal to reach the parent PCI device directory. This is unreliable and causes 'Failed to read i2c device PCI device ID' errors for all AMDGPU i2c buses. Fix: after resolving the symlink with realpath(), truncate at the last '/' to directly obtain the parent PCI device directory path. Also handle DT_UNKNOWN d_type which some kernels return for sysfs symlink entries instead of DT_LNK. This allows OpenRGB to correctly register AMDGPU i2c buses with their proper vendor/device/subsystem PCI IDs, which is a prerequisite for any GPU RGB controller detection on AMD hardware under Linux. Tested on Linux Mint with ASRock Radeon RX 7700 XT (1002:747E, subsystem 1849:5323) and kernel 6.x.
1 parent 2eb5699 commit 6f3baa2

1 file changed

Lines changed: 14 additions & 3 deletions

File tree

i2c_smbus/Linux/i2c_smbus_linux.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,17 +147,28 @@ bool i2c_smbus_linux_detect()
147147
path[sizeof(path) - 1] = '\0';
148148
strncat(path, ent->d_name, sizeof(path) - strlen(path) - 1);
149149
path[sizeof(path) - 1] = '\0';
150-
if(ent->d_type == DT_LNK)
150+
if(ent->d_type == DT_LNK || ent->d_type == DT_UNKNOWN)
151151
{
152152
ptr = realpath(path, NULL);
153153
if(ptr == NULL)
154154
continue;
155155

156156
strncpy(path, ptr, sizeof(path) - 1);
157157
path[sizeof(path) - 1] = '\0';
158-
strncat(path, "/..", sizeof(path) - strlen(path) - 1);
159-
path[sizeof(path) - 1] = '\0';
160158
free(ptr);
159+
160+
/*-------------------------------------------------------------*\
161+
| Truncate at last '/' to get the parent PCI device directory. |
162+
| For AMDGPU i2c buses the realpath resolves to something like: |
163+
| /sys/devices/pci.../0000:03:00.0/i2c-4 |
164+
| The parent (0000:03:00.0) contains vendor/device/subsystem |
165+
| files. Using /..' traversal is unreliable in sysfs; directly |
166+
| truncating the path is correct and portable. |
167+
\*-------------------------------------------------------------*/
168+
char* last_slash = strrchr(path, '/');
169+
if(last_slash == NULL || last_slash == path)
170+
continue;
171+
*last_slash = '\0';
161172
}
162173
else
163174
{

0 commit comments

Comments
 (0)