- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用 educational edu PCI device 通过 QEMU 学习 Linux 内核 PCI 开发。
如果我将设备用于:
-device edu
它是在启动时插入的,我的中断编号为 11 并且运行良好。
但是,我开始尝试在使用 monitor 命令启动后插入设备:
device_add edu
其次是:
echo 1 > /sys/bus/pci/rescan
如果我这样做,IRQ 将被分配给一个中断 0,它上面已经有一个不可共享的中断(计时器),并且我的:
request_irq(pci_irq, irq_handler, IRQF_SHARED, "pci_irq_handler0", &major)
失败并显示消息:
genirq: Flags mismatch irq 0. 00000080 (pci_irq_handler0) vs. 00015a00 (timer)
从内核源代码中,我们看到 0x80
是可共享标志,它不存在于计时器中。
这是 edu 设备中的错误,还是我可以在我的内核模块中做些什么?
启动时带有 -device
的状态可以:
device BDF IRQ
========== ======= ===
edu 00:04.0 10
virtio-pci 00:05.0 11
而 device_add
给出:
device BDF IRQ
========== ======= ===
virtio-pci 00:04.0 10
edu 00:05.0 0
所以我们看到 edu
和 virtio-pci
在探测器上交换了位置,但不幸的是没有 IRQ。
full device code with all boilerplate is on GitHub,这是一个最小化的复制版本:
#include <asm/uaccess.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#define BAR 0
#define CDEV_NAME "lkmc_pci"
#define EDU_DEVICE_ID 0x11e8
#define IO_IRQ_ACK 0x64
#define IO_IRQ_STATUS 0x24
#define QEMU_VENDOR_ID 0x1234
MODULE_LICENSE("GPL");
static struct pci_device_id pci_ids[] = {
{ PCI_DEVICE(QEMU_VENDOR_ID, EDU_DEVICE_ID), },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, pci_ids);
static int major;
static int pci_irq;
static struct pci_dev *pdev;
static void __iomem *mmio;
static struct file_operations fops = {
.owner = THIS_MODULE,
};
static irqreturn_t irq_handler(int irq, void *dev)
{
int devi;
irqreturn_t ret;
u32 irq_status;
devi = *(int *)dev;
irq_status = ioread32(mmio + IO_IRQ_STATUS);
pr_info("irq_handler irq = %d dev = %d irq_status = %llx\n",
irq, devi, (unsigned long long)irq_status);
iowrite32(irq_status, mmio + IO_IRQ_ACK);
ret = IRQ_HANDLED;
return ret;
}
static int pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
u8 val;
pr_info("pci_probe\n");
major = register_chrdev(0, CDEV_NAME, &fops);
pdev = dev;
if (pci_enable_device(dev) < 0) {
dev_err(&(pdev->dev), "pci_enable_device\n");
goto error;
}
if (pci_request_region(dev, BAR, "myregion0")) {
dev_err(&(pdev->dev), "pci_request_region\n");
goto error;
}
mmio = pci_iomap(pdev, BAR, pci_resource_len(pdev, BAR));
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &val);
pci_irq = val;
if (request_irq(pci_irq, irq_handler, IRQF_SHARED, "pci_irq_handler0", &major) < 0) {
dev_err(&(dev->dev), "request_irq\n");
goto error;
}
/* This makes the device generate an interrupt. */
iowrite32(0x12345678, mmio + 0x60);
return 0;
error:
return 1;
}
static void pci_remove(struct pci_dev *dev)
{
pr_info("pci_remove\n");
free_irq(pci_irq, &major);
pci_release_region(dev, BAR);
unregister_chrdev(major, CDEV_NAME);
}
static struct pci_driver pci_driver = {
.name = "lkmc_pci",
.id_table = pci_ids,
.probe = pci_probe,
.remove = pci_remove,
};
static int myinit(void)
{
if (pci_register_driver(&pci_driver) < 0) {
return 1;
}
return 0;
}
static void myexit(void)
{
pci_unregister_driver(&pci_driver);
}
module_init(myinit);
module_exit(myexit);
可能相关:https://serverfault.com/questions/70585/manually-assign-a-pci-card-to-an-interrupt
最佳答案
正如 0andriy 所提到的,我们需要使用 dev->pci
而不是使用 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &val); 读取配置;
。 TODO 遵循内核代码并准确理解原因。这有效:
#include <asm/uaccess.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#define BAR 0
#define CDEV_NAME "lkmc_hw_pci_min"
#define EDU_DEVICE_ID 0x11e9
#define QEMU_VENDOR_ID 0x1234
MODULE_LICENSE("GPL");
static struct pci_device_id id_table[] = {
{ PCI_DEVICE(QEMU_VENDOR_ID, EDU_DEVICE_ID), },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, id_table);
static int major;
static struct pci_dev *pdev;
static void __iomem *mmio;
static struct file_operations fops = {
.owner = THIS_MODULE,
};
static irqreturn_t irq_handler(int irq, void *dev)
{
pr_info("irq_handler irq = %d dev = %d\n", irq, *(int *)dev);
iowrite32(0, mmio + 4);
return IRQ_HANDLED;
}
static int probe(struct pci_dev *dev, const struct pci_device_id *id)
{
pr_info("probe\n");
major = register_chrdev(0, CDEV_NAME, &fops);
pdev = dev;
if (pci_enable_device(dev) < 0) {
dev_err(&(pdev->dev), "pci_enable_device\n");
goto error;
}
if (pci_request_region(dev, BAR, "myregion0")) {
dev_err(&(pdev->dev), "pci_request_region\n");
goto error;
}
mmio = pci_iomap(pdev, BAR, pci_resource_len(pdev, BAR));
pr_info("dev->irq = %u\n", dev->irq);
if (request_irq(dev->irq, irq_handler, IRQF_SHARED, "pci_irq_handler0", &major) < 0) {
dev_err(&(dev->dev), "request_irq\n");
goto error;
}
iowrite32(0x12345678, mmio);
return 0;
error:
return 1;
}
static void remove(struct pci_dev *dev)
{
pr_info("remove\n");
free_irq(dev->irq, &major);
pci_release_region(dev, BAR);
unregister_chrdev(major, CDEV_NAME);
}
static struct pci_driver pci_driver = {
.name = CDEV_NAME,
.id_table = id_table,
.probe = probe,
.remove = remove,
};
static int myinit(void)
{
if (pci_register_driver(&pci_driver) < 0) {
return 1;
}
return 0;
}
static void myexit(void)
{
pci_unregister_driver(&pci_driver);
}
module_init(myinit);
module_exit(myexit);
关于c - 如何处理来自 Linux 内核模块中已经具有不可共享处理程序的 PCI 设备的中断?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44740254/
当操作系统枚举 PCI 总线时,它会从每个 PCI 设备收集信息。我的问题是,操作系统在哪里存储这些信息?每个操作系统在运行时是否在 RAM 中都有一个 64KB 的数组? 最佳答案 PCI 信息被存
我们正在做一个项目,它的性质有点像拼车,我读到了 PCI 合规性,我知道如果我们处理信用卡或付款,我们必须符合 PCI 合规性我有点模棱两可,我们是否存储我们的司机银行信息例如数据库中的帐号(加密),
我们过去从未传输、处理或存储信用卡信息,因为我们通过 PayPal 完成所有操作,因此我们从不需要符合 PCI 标准。 但是,我们正在推出一个新的在线商店,并通过无缝结账处理信用卡信息而不重定向到 P
我有一个 NIC 卡和一个 HDD,它们都连接在 Linux 机器的 PCIe 插槽上。理想情况下,我希望在不涉及 CPU 或最少涉及 CPU 的情况下将传入数据包传送到 HDD。是否可以像这样沿着
根据 PCI 标准,设备是根据供应商 ID、设备 ID 和总线编号来识别的。所有相同类型的设备都具有相同的供应商 ID 和设备 ID。如果我将两个这样的设备放在同一条总线上,比如总线 0。PCI 软件
我正在查看商家帐户,据我所知,存储送货地址符合 PCI 合规性,这是真的吗?此外,Recurly 的 API 似乎需要 SAQ C 或 SAQ D,我查看了一些示例问题: 配置标准是否包括对防火墙的要
我们进行的某些信用卡处理需要符合 PCI 标准。人们在其他商店是如何做到这一点的? 如何保护您的 SVN? 如何保护构建服务器的安全? 代码如何从开发人员迁移到生产环境? 最佳答案 不是为了转移其他答
我只是想知道如果您存储加密的信用卡号以进行定期计费,PCI 认证级别会是多少。 我计划每年交易量少于 20,000 笔,但我不确定存储的信用卡号码。 最佳答案 如果您确实(确实)需要存储卡号,那么您就
我正在查看商家帐户,据我所知,存储送货地址符合 PCI 合规性,这是真的吗?此外,Recurly 的 API 似乎需要 SAQ C 或 SAQ D,我查看了一些示例问题: 配置标准是否包括对防火墙的要
我知道 PCI 配置空间中的基地址寄存器 (BAR) 定义了 PCI 地址的起始位置,但是该区域的大小是如何确定的? 当然,这是硬件的一个属性,因为只有它知道它可以处理的地址空间有多远。但是,我似乎在
我正在做的是开发一款财务软件,并将其连接到符合 pci 标准的第三方信用卡公司。我们公司是一家加拿大公司。我们不符合 pci,也不打算符合 pci。但我们希望保存 PAN 的后 4 位数字,以帮助一线
我目前正在从事该项目,其功能之一是电子商务,因此我们的系统应负责用户信用卡信息和其他凭证信息的安全性。 我知道任何处理用户支付卡信息的网络服务都应遵循 PCI 合规性(支付卡信息数据安全标准)。作为前
我们需要为基于订阅/定期付款的 SaaS 应用程序存储信用卡的最后 4 位数字(以便让客户知道他们使用了哪张卡?)和到期日期(通知客户他们的卡即将到期)。 PCI DSS 中允许这两种数据存储吗?请引
我正在用 C# 编写一个程序来对许多 Windows XP 工作站执行硬件审核。 我需要确定哪些 PCI 设备是通过主板插槽连接的实际卡 - 而不是也使用 PCI 总线(内置于主板中)的板载设备。 我
在 Linux 中,有没有办法找出哪个 PCI 卡插入哪个 PCI 插槽? /sys/bus/pci/devices/包含许多不是卡的设备(网桥、CPU channel 等),我无法在设备目录中找到有
我们想使用银行 API 从我们的银行账户到用户的银行账户进行 SEPA 转账。为此,用户需要在表格中输入他的 IBAN 和 BIC。我们获取这些数据(受 SSL 保护)并使用银行 REST API 转
我以前从未处理过 PCI 合规性问题。我一直在阅读他们的文档,它说我需要保护信用卡号、到期日期和持卡人的姓名。永远不会存储安全代码。 在他们的文档中,它只是说保护。这是说我需要加密数据库中的这 3 列
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 2 年前。 Improve th
我正在做一个项目,我需要从用户空间通过 PCI BAR0 访问 FPGA 内存。 我以前在旧内核中所做的是打开位于 /sys/bus/pci/devices/my_device/ 中的名为 resou
如果我的 PCI 总线(没有 PCI-PCI 桥)有 3 个设备: spy 设备、发送方 PCI 设备和接收方设备(例如,从 PCI 到 CPU 的桥接器)。 发送方开始向接收方传输数据。 spy 设
我是一名优秀的程序员,十分优秀!