At Tue, 12 Jan 2010 08:02:36 +0100, I wrote:
At Fri, 1 Jan 2010 20:31:30 +0100, Andreas Mohr wrote:
Hi,
I've tried this patch set (with the typo-corrected part 4) on my ASUS WL-500gP v2 MIPSEL via a backport to 2.6.31.9, but all I get is a small blip of the sound I wanted to play, and then the system is fubar (I believe just the same thing as what happened without having this patch applied).
As I mentioned in the previous followup, if your device is a USB-audio, the patch doesn't help because it's for devices with buffers using dma_alloc_coherent(). For USB-audio, it uses vmalloc for an intermediate buffer. Maybe this should be changed to dma_*() stuff for such architectures.
A quick patch below (totally untested!) might do that. It's passing the device struct blindly, so not sure whether this would actually work for all dma_alloc_coherent().
Takashi
--- diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 9edef46..6c82026 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -734,7 +734,7 @@ static void snd_complete_sync_urb(struct urb *urb) } }
- +#ifdef USBAUDIO_VMALLOC_BUFFER /* get the physical page pointer at the given offset */ static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, unsigned long offset) @@ -769,6 +769,24 @@ static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs) return 0; }
+#define preallocate_buffer(chip, pcm, stream) /* NOP */ + +#else +#define snd_pcm_get_vmalloc_page NULL +#define snd_pcm_alloc_vmalloc_buffer snd_pcm_lib_malloc_pages +#define snd_pcm_free_vmalloc_buffer snd_pcm_lib_free_pages + +static int preallocate_buffer(struct snd_usb_audio *chip, struct snd_pcm *pcm, + int stream) +{ + struct snd_pcm_substream *subs = pcm->streams[stream].substream; + if (!subs) + return 0; + return snd_pcm_lib_preallocate_pages(subs, SNDRV_DMA_TYPE_DEV, + chip->card->dev, + 1024 * 64, 1024 * 1024); +} +#endif
/* * unlink active urbs. @@ -2328,6 +2346,7 @@ static int add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct aud err = snd_pcm_new_stream(as->pcm, stream, 1); if (err < 0) return err; + preallocate_buffer(chip, as->pcm, stream); init_substream(as, stream, fp); return 0; } @@ -2356,6 +2375,7 @@ static int add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct aud else strcpy(pcm->name, "USB Audio");
+ preallocate_buffer(chip, pcm, stream); init_substream(as, stream, fp);
list_add(&as->list, &chip->pcm_list);