open()返回“没有这样的设备”错误,但是确实存在这样的设备(Linux)

5

我正在尝试使用一款有些老旧的DAQ,并且不得不跳过一些障碍来编译一个旧的(大约是2004年)设备驱动程序(DTI-DT340 Linux-DAQ-PCI)。

我已经到了编译的阶段,可以加载内核模块,找到了卡片,并且可以使用mknod创建字符设备。

但是我似乎无法打开这些设备,并且在尝试时不断收到errno 19 (ENODEV) 'No such device'的错误提示。

open("/dev/dt340/0",O_RDWR);

但是mknod在创建它时没有任何投诉,它就在那里:

# ls -l /dev/dt340/
total 0
crw-rw-r-- 1 root staff 250, 0 2009-04-23 11:02 0
crw-rw-r-- 1 root staff 250, 1 2009-04-23 11:02 1
crw-rw-r-- 1 root staff 250, 2 2009-04-23 11:02 2
crw-rw-r-- 1 root staff 250, 3 2009-04-23 11:02 3

我有什么忽略的事情吗?打开失败的原因可能是什么?

这是我用来加载驱动程序和创建设备的脚本。

#!/bin/bash
module="dt340"
device="dt340"
mode="664"

# invoke modprobe with all arguments we were passed
#/sbin/modprobe -t misc -lroot -f -s $module.o $* || exit 1
insmod $module.ko

# remove stale nodes
rm -f /dev/${device}/[0-3]

major=`awk "\\$2==\"$module\" {print \\$1}" /proc/devices`
mkdir -p /dev/${device}
mknod /dev/${device}/0 c $major 0
mknod /dev/${device}/1 c $major 1
mknod /dev/${device}/2 c $major 2
mknod /dev/${device}/3 c $major 3

# give appropriate group/permissions, and change the group
# not all distributions have staff; some have "users" instead
group="staff"
grep '^staff:' /etc/group > /dev/null || group="users"

chgrp $group /dev/${device}/[0-3]
chmod $mode  /dev/${device}/[0-3]

一些额外的信息:

#grep dt340 /proc/devices 
250 dt340
# lsmod | grep dt340
dt340                  21516  0 
# tail /var/log/messages
Apr 23 11:59:26 ve kernel: [  412.862139] dt340 0000:03:01.0: PCI INT A -> GSI 22 (level, low) -> IRQ 22
Apr 23 11:59:26 ve kernel: [  412.862362] dt340: In function dt340_init_one:
Apr 23 11:59:26 ve kernel: [  412.862363] Device DT340 Rev 0x0 detected at address 0xfebf0000
#lspci | grep 340
03:01.0 Multimedia controller: Data Translation DT340

答案:一个printk确认-ENODEV是从open()内部抛出的。遵循旧式

while ((pdev = pci_find_device(PCI_VENDOR_ID_DTI, PCI_ANY_ID, pdev)))

(已经过时),if(!pdev)最终为真,返回-ENODEV。

我正在逐步接近 - 我想我必须通过更新pci代码来使用更现代的机制...


你是使用udev还是旧式的dev?这也可能会产生影响... - Avery Payne
唯一的影响将是促使进一步的问题“为什么要手动创建设备节点?”;否则,没有任何区别。 - ephemient
驱动程序正在使用旧式的dev - 这是我第一次涉足设备驱动程序,所以我只是尽可能地利用已有的内容。 - Paul Ivanov
4个回答

8
如果设备出现在/proc/devices中,并且您确定在mknod中输入了正确的号码,那么驱动程序本身会拒绝打开。驱动程序可以从open()返回任何错误代码-包括“没有这样的设备”,如果它发现初始化硬件时出现问题,则可能会返回此错误代码。

1

我猜测这是驱动程序的问题,请检查打开函数。

在/proc/devices中显示,因此所有通用设备的内容似乎都没问题。


0

通过 lspci 检查并确保硬件已正确初始化。如果您的系统支持热插拔,则 pci_find_device 将无法工作。这个问题与 refcnt 有关。处理和学习的最佳方法是解剖 API。BOL!!


0

mknod不在意是否有与给定主/次设备号对应的设备。您确定insmod正在安装您的模块吗?lsmod告诉你什么?

我不熟悉必须添加“.ko”扩展名。这是你的设备驱动程序特有的东西吗?


在上面添加了lsmod信息 - 我认为如果没有加载,我就不会从/proc/devices得到那个主要数字。我使用.ko扩展名,因为我正在将模块加载到我构建它的地方 - 它不在标准模块加载的任何一个位置。 - Paul Ivanov
自2.4版本以来,.ko是Linux驱动程序通常使用的扩展名。旧内核使用.o,但这会与其他不是内核对象的目标文件混淆。 - MarkR
好吧,我上一次编写内核模块是在1993年,所以我知道什么呢? - Paul Tomblin
@MarkR - 2.4版本仍然使用.o模块;.ko扩展名是在2.5.51版(2002年12月10日)引入的。 - ephemient

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接