pci_rescan_bus() 不会在 Linux 中重新扫描 PCI 总线
pci_rescan_bus() doesn't rescan PCI bus in Linux
我试图在 pci_rescan_bus()
内核函数的帮助下在我自己的内核驱动程序中重新扫描 PCI 总线,但我没有看到它的功能相同。
如果我尝试通过 运行 从用户 space 执行相同的命令,我看到重新扫描发生了:
echo 1 > /sys/devices/pci0000:00/0000:00:14.1/rescan
我正在尝试重新初始化位于 PCI 总线上的以太网端口。下面是我现在使用的代码:
struct pci_dev *pci_eth_dev01, *pci_eth_dev02 = NULL;
pci_eth_dev01 = pci_get_device(0x10ec, 0x8168, NULL);
if (pci_eth_dev01 != NULL)
dev_info(&info->client->dev, "class - %2X\tbus number - %d\n", pci_eth_dev01->class, pci_eth_dev01->bus->number);
else
dev_info(&info->client->dev, "Error retreiving pci device\n");
pci_eth_dev02 = pci_get_device(0x10ec, 0x8168, pci_eth_dev01);
if (pci_eth_dev02 != NULL)
dev_info(&info->client->dev, "class - %2X\tbus number - %d\n", pci_eth_dev02->class, pci_eth_dev02->bus->number);
else
dev_info(&info->client->dev, "Error retreiving pci device\n");
pci_stop_and_remove_bus_device(pci_eth_dev02);
pci_remove_bus(pci_eth_dev02->bus);
unsigned int ret = 0;
pci_lock_rescan_remove();
ret = pci_rescan_bus(pci_eth_dev02->bus);
pci_unlock_rescan_remove();
dev_info(&info->client->dev, "ret from pci_rescan_bus - %d\n", ret);
我从 pci_rescan_bus()
函数调用中得到 2
作为 return 值。
我是不是做错了什么?
发现 pci_rescan_bus(pci_eth_dev02->bus->parent)
是正确的调用而不是 pci_rescan_bus(pci_eth_dev02->bus)
并且稍作修改这就是我当前实现的样子,
static bool re_initialize_eth_ports(struct supercap_info *info)
{
struct pci_dev *pci_eth_dev01 = NULL;
struct pci_dev *pci_eth_dev02 = NULL;
// Get PCI device structures since ethernet ports sit on PCI bus.
pci_eth_dev01 = pci_get_device(REALTEK_ETH_VENDOR_ID,
REALTEK_ETH_DEVICE_ID, NULL);
pci_eth_dev02 = pci_get_device(REALTEK_ETH_VENDOR_ID,
REALTEK_ETH_DEVICE_ID, pci_eth_dev01);
if (!pci_eth_dev01 || !pci_eth_dev02) {
dev_err(&info->client->dev, "Error retrieving PCI device structure\n");
return false;
}
dev_dbg(&info->client->dev, "Device Class - 0x%X\tPCI Bus Number - %d\n",
pci_eth_dev01->class, pci_eth_dev01->bus->number);
dev_dbg(&info->client->dev, "Device Class - 0x%X\tPCI Bus Number - %d\n",
pci_eth_dev02->class, pci_eth_dev02->bus->number);
// Remove PCI bus devices from the device lists.
pci_stop_and_remove_bus_device_locked(pci_eth_dev01);
pci_stop_and_remove_bus_device_locked(pci_eth_dev02);
// Acquire a mutex lock before re-scanning PCI buses.
pci_lock_rescan_remove();
// Re-scan PCI parent buses for devices.
pci_rescan_bus(pci_eth_dev01->bus->parent);
pci_rescan_bus(pci_eth_dev02->bus->parent);
// Release a mutex lock.
pci_unlock_rescan_remove();
return true;
}
我试图在 pci_rescan_bus()
内核函数的帮助下在我自己的内核驱动程序中重新扫描 PCI 总线,但我没有看到它的功能相同。
如果我尝试通过 运行 从用户 space 执行相同的命令,我看到重新扫描发生了:
echo 1 > /sys/devices/pci0000:00/0000:00:14.1/rescan
我正在尝试重新初始化位于 PCI 总线上的以太网端口。下面是我现在使用的代码:
struct pci_dev *pci_eth_dev01, *pci_eth_dev02 = NULL;
pci_eth_dev01 = pci_get_device(0x10ec, 0x8168, NULL);
if (pci_eth_dev01 != NULL)
dev_info(&info->client->dev, "class - %2X\tbus number - %d\n", pci_eth_dev01->class, pci_eth_dev01->bus->number);
else
dev_info(&info->client->dev, "Error retreiving pci device\n");
pci_eth_dev02 = pci_get_device(0x10ec, 0x8168, pci_eth_dev01);
if (pci_eth_dev02 != NULL)
dev_info(&info->client->dev, "class - %2X\tbus number - %d\n", pci_eth_dev02->class, pci_eth_dev02->bus->number);
else
dev_info(&info->client->dev, "Error retreiving pci device\n");
pci_stop_and_remove_bus_device(pci_eth_dev02);
pci_remove_bus(pci_eth_dev02->bus);
unsigned int ret = 0;
pci_lock_rescan_remove();
ret = pci_rescan_bus(pci_eth_dev02->bus);
pci_unlock_rescan_remove();
dev_info(&info->client->dev, "ret from pci_rescan_bus - %d\n", ret);
我从 pci_rescan_bus()
函数调用中得到 2
作为 return 值。
我是不是做错了什么?
发现 pci_rescan_bus(pci_eth_dev02->bus->parent)
是正确的调用而不是 pci_rescan_bus(pci_eth_dev02->bus)
并且稍作修改这就是我当前实现的样子,
static bool re_initialize_eth_ports(struct supercap_info *info)
{
struct pci_dev *pci_eth_dev01 = NULL;
struct pci_dev *pci_eth_dev02 = NULL;
// Get PCI device structures since ethernet ports sit on PCI bus.
pci_eth_dev01 = pci_get_device(REALTEK_ETH_VENDOR_ID,
REALTEK_ETH_DEVICE_ID, NULL);
pci_eth_dev02 = pci_get_device(REALTEK_ETH_VENDOR_ID,
REALTEK_ETH_DEVICE_ID, pci_eth_dev01);
if (!pci_eth_dev01 || !pci_eth_dev02) {
dev_err(&info->client->dev, "Error retrieving PCI device structure\n");
return false;
}
dev_dbg(&info->client->dev, "Device Class - 0x%X\tPCI Bus Number - %d\n",
pci_eth_dev01->class, pci_eth_dev01->bus->number);
dev_dbg(&info->client->dev, "Device Class - 0x%X\tPCI Bus Number - %d\n",
pci_eth_dev02->class, pci_eth_dev02->bus->number);
// Remove PCI bus devices from the device lists.
pci_stop_and_remove_bus_device_locked(pci_eth_dev01);
pci_stop_and_remove_bus_device_locked(pci_eth_dev02);
// Acquire a mutex lock before re-scanning PCI buses.
pci_lock_rescan_remove();
// Re-scan PCI parent buses for devices.
pci_rescan_bus(pci_eth_dev01->bus->parent);
pci_rescan_bus(pci_eth_dev02->bus->parent);
// Release a mutex lock.
pci_unlock_rescan_remove();
return true;
}