我们有一些定制的驱动程序在5.4.0上工作。它已经很老了,原来的开发人员已经不再支持它了,所以我们必须在我们的系统中维护它。当升级到Ubuntu 22 (Kernel 5.15)时,驱动程序突然停止工作,并使用命令SIOCDEVPRIVATE发送ioctl (它以前在内核5.4.0中工作,实际上用于获取一些必要的设备信息),现在提供了"ioctl:操作不受支持“错误,日志中任何地方都没有额外的信息。
所以..。这两个内核之间有什么变化吗?我们确实需要调整一些用于注册驱动程序的结构,但是我看不到任何关于注册有效操作的信息。我现在必须在某个地方注册有效的操作吗?或者,有人知道内核代码的哪一部分正在检查要支持的操作吗?我一直试图从ioctl.c中找到它,但是我似乎找不到这个错误的来源。
据称负责这一问题的驱动程序代码(甚至没有到达5.15的第一行):
static int u50_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) {
struct u50_priv *priv = netdev_priv(dev);
if (cmd == SIOCDEVPRIVATE) {
memcpy(&ifr->ifr_data, priv->tty->name, strlen(priv->tty->name));
}
return 0;
}
而试图访问它不再起作用:
struct ifreq ifr = {0};
struct ifaddrs *ifaddr, *ifa;
getifaddrs(&ifaddr);
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
memcpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ);
if (ioctl(lonsd, SIOCDEVPRIVATE, &ifr) < 0) {
perror("ioctl");
syslog(LOG_ERR, "Ioctl:%d: %s\n", __LINE__, strerror(errno));
}
...
以及注册的结构
static const struct net_device_ops u50_netdev_ops = {
.ndo_init = u50_dev_init,
.ndo_uninit = u50_dev_uninit,
.ndo_open = u50_dev_open,
.ndo_stop = u50_dev_stop,
.ndo_start_xmit = u50_dev_xmit,
.ndo_do_ioctl = u50_dev_ioctl,
.ndo_set_mac_address = U50SetHWAddr,
};
发布于 2022-07-25 13:57:54
如果您需要一些代码来响应SIOCDEVPRIVATE,您过去可以通过ndo_do_ioctl (编写兼容的函数,然后在5.4中将其链接到net_device_ops结构中)。但是,在5.15中,它被更改了,因此根据内核文档,现在必须实现ndo_siocdevprivate函数,而不是不再调用的ndo_do_ioctl。
来源:https://elixir.bootlin.com/linux/v5.15.57/source/include/linux/netdevice.h
这样做的补丁:spinics.net/list/netdev/ did 698158.html
https://stackoverflow.com/questions/73079492
复制相似问题