0

I'm a newbie to driver development in Linux. I want to trigger a DMA read operation at specified target address, but I have no basic concept about how to do it. Should I write a new driver for my sound card? Or just invoke some APIs(if any) provided by current sound card driver?

I can imagine that what I want looks like this (from LDD3 Ch15),

int dad_transfer(struct dad_dev *dev, int write, void *buffer, 
                 size_t count)
{
    dma_addr_t bus_addr;

    /* Map the buffer for DMA */
    dev->dma_dir = (write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
    dev->dma_size = count;
    bus_addr = dma_map_single(&dev->pci_dev->dev, buffer, count, 
                              dev->dma_dir);
    dev->dma_addr = bus_addr;

    /* Set up the device */

    writeb(dev->registers.command, DAD_CMD_DISABLEDMA);
    writeb(dev->registers.command, write ? DAD_CMD_WR : DAD_CMD_RD);
    writel(dev->registers.addr, cpu_to_le32(bus_addr));
    writel(dev->registers.len, cpu_to_le32(count));

    /* Start the operation */
    writeb(dev->registers.command, DAD_CMD_ENABLEDMA);
    return 0;
}

But what should this be, a user-space program or a module? And where can I grub more device-specific details in order to know which and how the registers should be write?

qweruiop
  • 3,156
  • 6
  • 31
  • 55

1 Answers1

1

You have several questions buried in here, so I will take them one at a time:

  1. Should I write a new driver or invoke some API function calls?

If the existing driver has such a function accessible from userspace, yes you should use them - they will the easiest option. If they do not already exist, you will have to write a driver because you cannot directly access the kernel's DMA engine from userspace. You need a driver to help you along.

  1. Should this be a userspace program or module?

It would have to be a module so that it can access low-level kernel features. Using your included code as an example, you cannot call "dma_map_single" from userspace or access a PCI device's device structure. You need to be in kernel space to do that, which requires either a driver module or static kernel driver.

  1. Where can I get more device-specific details?

(I assume you meant Grep.) You will have to get a hold of a programmer's guide for the device you want to access. Regular user's manuals won't have the level of detail you need (register addresses, bit patterns, etc) so you may have to contact the manufacturer to get a driver writer's guide. You also may be able to find some examples in the kernel source code. Check http://lxr.free-electrons.com/ for a searchable, up-to-date listing of the entire kernel source. If you look in /drivers/, you may be able to find some examples to get you started.

skrrgwasme
  • 9,358
  • 11
  • 54
  • 84