If your hardware supports the page table as in emu10k1 or the
      buffer descriptors as in via82xx, you can use the scatter-gather
      (SG) DMA. ALSA provides an interface for handling SG-buffers.
      The API is provided in <sound/pcm.h>. 
      
        For creating the SG-buffer handler, call
        snd_pcm_lib_preallocate_pages() or
        snd_pcm_lib_preallocate_pages_for_all()
        with SNDRV_DMA_TYPE_DEV_SG
	in the PCM constructor like other PCI pre-allocator.
        You need to pass snd_dma_pci_data(pci),
        where pci is the struct pci_dev pointer
        of the chip as well.
        The struct snd_sg_buf instance is created as
        substream->dma_private. You can cast
        the pointer like: 
        
  struct snd_sg_buf *sgbuf = (struct snd_sg_buf *)substream->dma_private;
          
        Then call snd_pcm_lib_malloc_pages()
      in the hw_params callback
      as well as in the case of normal PCI buffer.
      The SG-buffer handler will allocate the non-contiguous kernel
      pages of the given size and map them onto the virtually contiguous
      memory.  The virtual pointer is addressed in runtime->dma_area.
      The physical address (runtime->dma_addr) is set to zero,
      because the buffer is physically non-contiguous.
      The physical address table is set up in sgbuf->table.
      You can get the physical address at a certain offset via
      snd_pcm_sgbuf_get_addr(). 
      
        When a SG-handler is used, you need to set
      snd_pcm_sgbuf_ops_page as
      the page callback.
      (See 
      page callback section.)
      
        To release the data, call
      snd_pcm_lib_free_pages() in the
      hw_free callback as usual.