LINUX.ORG.RU

История изменений

Исправление I-Love-Microsoft, (текущая версия) :

Iron_Bug В общем, сделал устройство со своими ID (AAAA/BBBB), один регион памяти 4 килобайта:

Region 0: Memory at fe9ff000 (32-bit, non-prefetchable) [size=4K]
Всё успешно определяется, показывает мой модуль в поле «Kernel driver in use:». У самого устройства есть счетчик принятых пакетов (выводится на гребенку светодиодов), периодически ловит пакеты для соседних устройств, но корка проверяет диапазоны адресов и если он попадает в BAR0 - есть возможность увидеть это.

А теперь конкретный вопрос: где смотреть результаты pci_request_regions? В lspci видно что в данный конкретный момент моему устройству выделена память начиная с fe9ff000 и так до fe9fffff, т.е. 4К. Где увидеть этот адрес в драйвере, через какие структуры? Как осуществить запись N байт начиная с fe9ff000? Но для начала этот адрес еще узнать надо...

#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
//MODULE_LICENSE("GPL");

#define VENDOR_ID 0xAAAA
#define DEVICE_ID 0xBBBB

static struct pci_device_id mypci_id[] =
{
    { VENDOR_ID, DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
    {}
};

int device_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
    int ret;
    ret = pci_enable_device(dev);
    if(ret < 0)
    {
        printk(KERN_WARNING "mypci: unable to initialize PCI device\n");
        return ret;
    }

    ret = pci_request_regions(dev, "mypci");
    if(ret < 0)
    {
        printk(KERN_WARNING "mypci: unable to reserve PCI resources\n");
        pci_disable_device(dev);
        return ret;
    }

    printk(KERN_INFO "mypci: device_probe successful\n");
    return ret;
}

void device_remove(struct pci_dev *dev)
{
    pci_release_regions(dev);
    pci_disable_device(dev);
    printk(KERN_INFO "mypci: device removed\n");
}

struct pci_driver mypci =
{
    name: "mypci",
    id_table: mypci_id,
    probe: device_probe,
    remove: device_remove
};

static int __init init_module_mypci(void)
{
    printk(KERN_INFO "mypci: init\n");
    return pci_register_driver(&mypci);
}

static void __exit cleanup_module_mypci(void)
{
    printk(KERN_INFO "mypci: cleanup\n");
    pci_unregister_driver(&mypci);
}

module_init(init_module_mypci);
module_exit(cleanup_module_mypci);

Исходная версия I-Love-Microsoft, :

Iron_Bug В общем, сделал устройство со своими ID (AAAA/BBBB), один регион памяти 4 килобайта:

Region 0: Memory at fe9ff000 (32-bit, non-prefetchable) [size=4K]
Всё успешно определяется, показывает мой модуль в поле «Kernel driver in use:». У самого устройства есть счетчик принятых пакетов (выводится на гребенку светодиодов), периодически ловит пакеты для соседних устройств, но корка проверяет диапазоны адресов и если он попадает в BAR0 - есть возможность увидеть это.

А теперь конкретный вопрос: где смотреть результаты pci_request_regions? В lspci видно что в данный конкретный момент моему устройству выделена память начиная с fe9ff000 и так до fe9fffff, т.е. 4К. Где увидеть этот адрес в драйвере, через какие структуры? Как осуществить запить N байт начиная с fe9ff000? Но для начала этот адрес еще узнать надо...

#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
//MODULE_LICENSE("GPL");

#define VENDOR_ID 0xAAAA
#define DEVICE_ID 0xBBBB

static struct pci_device_id mypci_id[] =
{
    { VENDOR_ID, DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
    {}
};

int device_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
    int ret;
    ret = pci_enable_device(dev);
    if(ret < 0)
    {
        printk(KERN_WARNING "mypci: unable to initialize PCI device\n");
        return ret;
    }

    ret = pci_request_regions(dev, "mypci");
    if(ret < 0)
    {
        printk(KERN_WARNING "mypci: unable to reserve PCI resources\n");
        pci_disable_device(dev);
        return ret;
    }

    printk(KERN_INFO "mypci: device_probe successful\n");
    return ret;
}

void device_remove(struct pci_dev *dev)
{
    pci_release_regions(dev);
    pci_disable_device(dev);
    printk(KERN_INFO "mypci: device removed\n");
}

struct pci_driver mypci =
{
    name: "mypci",
    id_table: mypci_id,
    probe: device_probe,
    remove: device_remove
};

static int __init init_module_mypci(void)
{
    printk(KERN_INFO "mypci: init\n");
    return pci_register_driver(&mypci);
}

static void __exit cleanup_module_mypci(void)
{
    printk(KERN_INFO "mypci: cleanup\n");
    pci_unregister_driver(&mypci);
}

module_init(init_module_mypci);
module_exit(cleanup_module_mypci);