if (event == BUS_NOTIFY_ADD_DEVICE) {
for (tmp = dev; tmp; tmp = tmp->bus->self) {
level--;
+ info->path[level].bus = tmp->bus->number;
info->path[level].device = PCI_SLOT(tmp->devfn);
info->path[level].function = PCI_FUNC(tmp->devfn);
if (pci_is_root_bus(tmp->bus))
int i;
if (info->bus != bus)
- return false;
+ goto fallback;
if (info->level != count)
- return false;
+ goto fallback;
for (i = 0; i < count; i++) {
if (path[i].device != info->path[i].device ||
path[i].function != info->path[i].function)
- return false;
+ goto fallback;
}
return true;
+
+fallback:
+
+ if (count != 1)
+ return false;
+
+ i = info->level - 1;
+ if (bus == info->path[i].bus &&
+ path[0].device == info->path[i].device &&
+ path[0].function == info->path[i].function) {
+ pr_info(FW_BUG "RMRR entry for device %02x:%02x.%x is broken - applying workaround\n",
+ bus, path[0].device, path[0].function);
+ return true;
+ }
+
+ return false;
}
/* Return: > 0 if match found, 0 if no match found, < 0 if error happens */
for_each_active_dev_scope(devices, count, index, tmp)
if (tmp == &info->dev->dev) {
- rcu_assign_pointer(devices[index].dev, NULL);
+ RCU_INIT_POINTER(devices[index].dev, NULL);
synchronize_rcu();
put_device(tmp);
return 1;