vserver 1.9.3
[linux-2.6.git] / include / sound / pcm.h
index 4229360..c780e10 100644 (file)
@@ -52,10 +52,8 @@ typedef struct sndrv_pcm_mmap_control snd_pcm_mmap_control_t;
 typedef struct sndrv_mask snd_mask_t;
 typedef struct snd_sg_buf snd_pcm_sgbuf_t;
 
-#define _snd_pcm_substream_chip(substream) ((substream)->private_data)
-#define snd_pcm_substream_chip(substream) snd_magic_cast1(chip_t, _snd_pcm_substream_chip(substream), return -ENXIO)
-#define _snd_pcm_chip(pcm) ((pcm)->private_data)
-#define snd_pcm_chip(pcm) snd_magic_cast1(chip_t, _snd_pcm_chip(pcm), return -ENXIO)
+#define snd_pcm_substream_chip(substream) ((substream)->private_data)
+#define snd_pcm_chip(pcm) ((pcm)->private_data)
 
 typedef struct _snd_pcm_file snd_pcm_file_t;
 typedef struct _snd_pcm_runtime snd_pcm_runtime_t;
@@ -99,6 +97,7 @@ typedef struct _snd_pcm_ops {
        int (*silence)(snd_pcm_substream_t *substream, int channel, 
                       snd_pcm_uframes_t pos, snd_pcm_uframes_t count);
        struct page *(*page)(snd_pcm_substream_t *substream, unsigned long offset);
+       int (*mmap)(snd_pcm_substream_t *substream, struct vm_area_struct *vma);
        int (*ack)(snd_pcm_substream_t *substream);
 } snd_pcm_ops_t;
 
@@ -123,6 +122,8 @@ typedef struct _snd_pcm_ops {
 #define SNDRV_PCM_TRIGGER_SUSPEND      5
 #define SNDRV_PCM_TRIGGER_RESUME       6
 
+#define SNDRV_PCM_POS_XRUN             ((snd_pcm_uframes_t)-1)
+
 /* If you change this don't forget to change rates[] table in pcm_native.c */
 #define SNDRV_PCM_RATE_5512            (1<<0)          /* 5512Hz */
 #define SNDRV_PCM_RATE_8000            (1<<1)          /* 8000Hz */
@@ -351,7 +352,8 @@ struct _snd_pcm_runtime {
        unsigned char *dma_area;        /* DMA area */
        dma_addr_t dma_addr;            /* physical bus address (not accessible from main CPU) */
        size_t dma_bytes;               /* size of DMA area */
-       void *dma_private;              /* private DMA data for the memory allocator */
+
+       struct snd_dma_buffer *dma_buffer_p;    /* allocated buffer */
 
 #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
        /* -- OSS things -- */
@@ -372,8 +374,8 @@ struct _snd_pcm_substream {
        char name[32];                  /* substream name */
        int stream;                     /* stream (direction) */
        size_t buffer_bytes_max;        /* limit ring buffer size */
-       struct snd_dma_device dma_device;
        struct snd_dma_buffer dma_buffer;
+       unsigned int dma_buf_id;
        size_t dma_max;
        /* -- hardware operations -- */
        unsigned int open_flag: 1;      /* lowlevel device has been opened */
@@ -382,7 +384,7 @@ struct _snd_pcm_substream {
        snd_pcm_runtime_t *runtime;
         /* -- timer section -- */
        snd_timer_t *timer;             /* timer */
-       int timer_running: 1;           /* time is running */
+       unsigned timer_running: 1;      /* time is running */
        spinlock_t timer_lock;
        /* -- next substream -- */
        snd_pcm_substream_t *next;
@@ -851,7 +853,7 @@ int snd_pcm_format_little_endian(snd_pcm_format_t format);
 int snd_pcm_format_big_endian(snd_pcm_format_t format);
 int snd_pcm_format_width(snd_pcm_format_t format);                     /* in bits */
 int snd_pcm_format_physical_width(snd_pcm_format_t format);            /* in bits */
-u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format);
+const unsigned char *snd_pcm_format_silence_64(snd_pcm_format_t format);
 int snd_pcm_format_set_silence(snd_pcm_format_t format, void *buf, unsigned int frames);
 snd_pcm_format_t snd_pcm_build_linear_format(int width, int unsignd, int big_endian);
 ssize_t snd_pcm_format_size(snd_pcm_format_t format, size_t samples);
@@ -892,6 +894,22 @@ snd_pcm_sframes_t snd_pcm_lib_readv(snd_pcm_substream_t *substream,
 
 int snd_pcm_limit_hw_rates(snd_pcm_runtime_t *runtime);
 
+static inline void snd_pcm_set_runtime_buffer(snd_pcm_substream_t *substream,
+                                             struct snd_dma_buffer *bufp)
+{
+       snd_pcm_runtime_t *runtime = substream->runtime;
+       if (bufp) {
+               runtime->dma_buffer_p = bufp;
+               runtime->dma_area = bufp->area;
+               runtime->dma_addr = bufp->addr;
+               runtime->dma_bytes = bufp->bytes;
+       } else {
+               runtime->dma_buffer_p = NULL;
+               runtime->dma_area = NULL;
+               runtime->dma_addr = 0;
+               runtime->dma_bytes = 0;
+       }
+}
 
 /*
  *  Timer interface
@@ -916,11 +934,33 @@ int snd_pcm_lib_preallocate_pages_for_all(snd_pcm_t *pcm,
 int snd_pcm_lib_malloc_pages(snd_pcm_substream_t *substream, size_t size);
 int snd_pcm_lib_free_pages(snd_pcm_substream_t *substream);
 
-#define snd_pcm_substream_sgbuf(substream) ((substream)->runtime->dma_private)
+#define snd_pcm_substream_sgbuf(substream) ((substream)->runtime->dma_buffer_p->private_data)
 #define snd_pcm_sgbuf_pages(size) snd_sgbuf_aligned_pages(size)
 #define snd_pcm_sgbuf_get_addr(sgbuf,ofs) snd_sgbuf_get_addr(sgbuf,ofs)
 struct page *snd_pcm_sgbuf_ops_page(snd_pcm_substream_t *substream, unsigned long offset);
 
+/* handle mmap counter - PCM mmap callback should handle this counter properly */
+static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
+{
+       snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
+       atomic_inc(&substream->runtime->mmap_count);
+}
+
+static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area)
+{
+       snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
+       atomic_dec(&substream->runtime->mmap_count);
+}
+
+/* mmap for io-memory area */
+#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_ALPHA)
+#define SNDRV_PCM_INFO_MMAP_IOMEM      SNDRV_PCM_INFO_MMAP
+int snd_pcm_lib_mmap_iomem(snd_pcm_substream_t *substream, struct vm_area_struct *area);
+#else
+#define SNDRV_PCM_INFO_MMAP_IOMEM      0
+#define snd_pcm_lib_mmap_iomem NULL
+#endif
+
 static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max)
 {
        *max = dma < 4 ? 64 * 1024 : 128 * 1024;