【发布时间】:2013-12-03 12:11:44
【问题描述】:
我正在尝试编写一个 pci 驱动程序,它可以显示我的以太网卡的 MAC 地址。 在 VM 上运行 Ubuntu,我的以太网卡是 Intel 的,如下所示 00:08.0 以太网控制器:英特尔公司 82540EM 千兆以太网控制器(修订版 02)
我能够从英特尔网站获得相同的数据表,并且根据数据表,它说 IO 地址映射到第 2 条(请参阅第 87 页)并且可以使用位于的 RAL/RAH 寄存器读取 MAC偏移量 RAL (05400h + 8*n; R/W) 和 RAH (05404h + 8n; R/W) 2 18h IO 寄存器基地址(位 31:2) 0b 内存
基于此信息,我编写了一个小型 PCI 驱动程序,但我总是将 MAC 设为 fff,当我进一步调试时,我看到 io_base 地址始终为零。
下面是代码
1 /*
2 Program to find a device on the PCI sub-system
3 */
4 #define VENDOR_ID 0x8086
5 #define DEVICE_ID 0x100e
6
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/stddef.h>
10 #include <linux/pci.h>
11 #include <linux/init.h>
12 #include <linux/cdev.h>
13 #include <linux/device.h>
14 #include <asm/io.h>
15
16 #define LOG(string...) printk(KERN_INFO string)
17
18 #define CDEV_MAJOR 227
19 #define CDEV_MINOR 0
20
21
22 MODULE_LICENSE("GPL");
23
24 struct pci_dev *pci_dev;
25 unsigned long mmio_addr;
26 unsigned long reg_len;
27 unsigned long *base_addr;
28
29 int device_probe(struct pci_dev *dev, const struct pci_device_id *id);
30 void device_remove(struct pci_dev *dev);
31
32 struct pci_device_id pci_device_id_DevicePCI[] =
33 {
34 {VENDOR_ID, DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
35 };
36
37 struct pci_driver pci_driver_DevicePCI =
38 {
39 name: "MyPCIDevice",
40 id_table: pci_device_id_DevicePCI,
41 probe: device_probe,
42 remove: device_remove
43 };
44
45
46 int init_module(void)
47 {
48 //struct pci_dev *pdev = NULL;
49 int ret = 0;
50
51 pci_register_driver(&pci_driver_DevicePCI);
52
53 return ret;
54 }
55
56 void cleanup_module(void)
57 {
58 pci_unregister_driver(&pci_driver_DevicePCI);
59
60 }
61
62 #define REGISTER_OFFSET 0x05400
64 int device_probe(struct pci_dev *dev, const struct pci_device_id *id)
65 {
66 int ret;
67 int bar = 2; // Bar to be reserved
68 unsigned long io_base = 0;
69 unsigned long mem_len = 0;
70 unsigned int register_data = 0;
71
72 LOG("Device probed");
73
74 /* Reserve the access to PCI device */
75 ret = pci_request_region(dev, bar, "my_pci");
76 if (ret) {
77 printk(KERN_ERR "request region failed :%d\n", ret);
78 return ret;
79 }
80
81 ret = pci_enable_device(dev);
82 if (ret < 0 ) LOG("Failed while enabling ... ");
83
84 io_base = pci_resource_start(dev, bar);
85 mem_len = pci_resource_len(dev, bar);
86
87 request_region(io_base, mem_len, "my_pci");
88 register_data = inw(io_base + REGISTER_OFFSET);
89 printk(KERN_INFO "IO base = %lx", io_base);
90 printk(KERN_INFO "MAC = %x", register_data);
91
92 return ret;
93 }
94
95 void device_remove(struct pci_dev *dev)
96 {
97 pci_release_regions(dev);
98 pci_disable_device(dev);
99 }
100
lspci -x 我卡的输出 00:08.0 以太网控制器:英特尔公司 82540EM 千兆以太网控制器(rev 02) 00: 86 80 0e 10 07 00 30 02 02 00 00 02 00 40 00 00 10: 00 00 82 f0 00 00 00 00 41 d2 00 00 00 00 00 00 20: 00 00 00 00 00 00 00 00 00 00 00 00 86 80 1e 00 30: 00 00 00 00 直流 00 00 00 00 00 00 00 09 01 ff 00
谁能告诉我我做错了什么?
【问题讨论】:
-
@pkumarn..必须尝试使用pci_read_config_dword()函数读取,该函数用于访问配置空间寄存器?
标签: linux driver linux-device-driver ethernet pci