помогите завести пример, взятый из книжки Олега Цилюрика. Падает на pci_map_single и dma_pool_create, что с моей точки зрения не удивительно - указатели на pci_dev передаются нулевые, но dma_alloc_coherent это проглатывает...
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#define pool_size 1024
#define pool_align 8
// int direction = PCI_DMA_TODEVICE ;
// int direction = PCI_DMA_FROMDEVICE ;
static int direction = PCI_DMA_BIDIRECTIONAL;
//int direction = PCI_DMA_NONE;
static void output(char *kbuf, dma_addr_t handle, size_t size, char *string);
static int __init my_init(void)
{
    char *kbuf;
    dma_addr_t handle;
    size_t size = (10 * PAGE_SIZE);
    struct dma_pool *mypool;
/* dma_alloc_coherent method */
    kbuf = dma_alloc_coherent(NULL, size, &handle, GFP_KERNEL);
    output(kbuf, handle, size, "This is the dma_alloc_coherent() string");
    dma_free_coherent(NULL, size, kbuf, handle);
    goto out;
/* dma_map/unmap_single */
    kbuf = kzalloc(size, GFP_KERNEL);
    if (!kbuf) {
        printk("error: no memory\n");
        goto out;
    }   
    handle = pci_map_single(NULL, kbuf, size, direction);
    if(dma_mapping_error(NULL, handle)) {
        printk("dma_map_single error");
        kfree(kbuf);
    }
    output( kbuf, handle, size, "This is the dma_map_single() string" );
    dma_unmap_single( NULL, handle, size, direction );
    kfree( kbuf );
/* dma_pool method */
    mypool = dma_pool_create("mypool", NULL, pool_size, pool_align, 0);
    kbuf = dma_pool_alloc(mypool, GFP_KERNEL, &handle);
    output(kbuf, handle, size, "This is the dma_pool_alloc() string");
    dma_pool_free(mypool, kbuf, handle);
    dma_pool_destroy(mypool);
    goto out;
out:
    return -1;
}
module_init(my_init);
MODULE_AUTHOR("Jerry Cooperstein");
MODULE_AUTHOR("Oleg Tsiliuric");
MODULE_DESCRIPTION("LDD:1.0 s_23/lab1_dma.c");
MODULE_LICENSE("GPL v2");
#define MARK "=> "
static void output(char *kbuf, dma_addr_t handle, size_t size, char *string)
{
    unsigned long long diff;
    diff = (unsigned long long)kbuf - handle;
    printk(KERN_INFO MARK "kbuf=%p, handle=%p, size = %d\n", kbuf,
           (void *)(unsigned long long)handle, (int)size);
    printk(KERN_INFO MARK
           "(kbuf-handle)= %p, %llu, PAGE_OFFSET=%lu, compare=%llu\n",
           (void *)diff, diff, PAGE_OFFSET, diff - PAGE_OFFSET);
    strcpy(kbuf, string);
    printk(KERN_INFO MARK "string written was, %s\n", kbuf);
}
upd: ядро 3.9/3.10


