diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index 150cb7e..09fb994 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -107,6 +107,7 @@ int snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream)
 #endif
 	return 0;
 }
+EXPORT_SYMBOL(snd_pcm_lib_preallocate_free);
 
 /**
  * snd_pcm_lib_preallocate_free_for_all - release all pre-allocated buffers on the pcm
diff --git a/sound/usb/card.h b/sound/usb/card.h
index ae4251d..18dfa38 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -1,11 +1,13 @@
 #ifndef __USBAUDIO_CARD_H
 #define __USBAUDIO_CARD_H
 
-#define MAX_PACKS	20
+//#define MAX_PACKS	20
+#define MAX_PACKS	40
 #define MAX_PACKS_HS	(MAX_PACKS * 8)	/* in high speed mode */
 #define MAX_URBS	8
 #define SYNC_URBS	4	/* always four urbs for sync */
-#define MAX_QUEUE	24	/* try not to exceed this queue length, in ms */
+//#define MAX_QUEUE	24	/* try not to exceed this queue length, in ms */
+#define MAX_QUEUE	48	/* try not to exceed this queue length, in ms */
 
 struct audioformat {
 	struct list_head list;
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index b8dcbf4..5ca7999 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -328,11 +328,41 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
 	struct audioformat *fmt;
 	unsigned int channels, rate, format;
 	int ret, changed;
-
+#define PLB
+#ifndef PLB
 	ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
 					       params_buffer_bytes(hw_params));
-	if (ret < 0)
-		return ret;
+#else
+	{
+#define MAX_PREALLOC_SIZE	(32 * 1024 * 1024)
+#define USB_PREALLOC_SIZE	(128 * 1024)
+		int size;
+
+		size = USB_PREALLOC_SIZE;
+		if (size > MAX_PREALLOC_SIZE)
+			size = MAX_PREALLOC_SIZE;
+
+		ret = snd_pcm_lib_preallocate_pages(substream, 
+						SNDRV_DMA_TYPE_CONTINUOUS,
+						snd_dma_continuous_data(GFP_KERNEL),
+						size, MAX_PREALLOC_SIZE);
+		if (ret < 0) {
+			printk(KERN_ERR "plb: could not preallocate data");
+			return ret;
+		} else {
+			printk(KERN_ERR "plb: success preallocate data");
+		}
+		
+		ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+		
+		if (ret < 0) {
+			printk(KERN_ERR "plb: could not malloc data");
+			return ret;
+		} else {
+			printk(KERN_ERR "plb: success malloc data");
+		}
+	}
+#endif
 
 	format = params_format(hw_params);
 	rate = params_rate(hw_params);
@@ -391,7 +421,30 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
 	mutex_lock(&subs->stream->chip->shutdown_mutex);
 	snd_usb_release_substream_urbs(subs, 0);
 	mutex_unlock(&subs->stream->chip->shutdown_mutex);
+#ifndef PLB
 	return snd_pcm_lib_free_vmalloc_buffer(substream);
+#else
+	{ 
+		int ret;
+
+		ret = snd_pcm_lib_free_pages(substream);
+		
+		if (ret < 0) {
+			printk(KERN_ERR "plb: could not free data");
+			return ret;
+		} else {
+			printk(KERN_ERR "plb: success free data");
+		}
+
+		ret = snd_pcm_lib_preallocate_free(substream);
+		if (ret < 0) {
+			printk(KERN_ERR "plb: could not free preallocated data");
+			return ret;
+		} else {
+			printk(KERN_ERR "plb: success free prealloc data");
+		}
+	}
+#endif
 }
 
 /*
@@ -424,8 +477,11 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
 
 static struct snd_pcm_hardware snd_usb_hardware =
 {
-	.info =			SNDRV_PCM_INFO_MMAP |
-				SNDRV_PCM_INFO_MMAP_VALID |
+	.info =	
+#ifndef PLB		
+	SNDRV_PCM_INFO_MMAP |
+	SNDRV_PCM_INFO_MMAP_VALID |
+#endif
 				SNDRV_PCM_INFO_BATCH |
 				SNDRV_PCM_INFO_INTERLEAVED |
 				SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -853,8 +909,10 @@ static struct snd_pcm_ops snd_usb_playback_ops = {
 	.prepare =	snd_usb_pcm_prepare,
 	.trigger =	snd_usb_substream_playback_trigger,
 	.pointer =	snd_usb_pcm_pointer,
+#ifndef PLB
 	.page =		snd_pcm_lib_get_vmalloc_page,
 	.mmap =		snd_pcm_lib_mmap_vmalloc,
+#endif
 };
 
 static struct snd_pcm_ops snd_usb_capture_ops = {
@@ -866,8 +924,10 @@ static struct snd_pcm_ops snd_usb_capture_ops = {
 	.prepare =	snd_usb_pcm_prepare,
 	.trigger =	snd_usb_substream_capture_trigger,
 	.pointer =	snd_usb_pcm_pointer,
+#ifndef PLB
 	.page =		snd_pcm_lib_get_vmalloc_page,
 	.mmap =		snd_pcm_lib_mmap_vmalloc,
+#endif
 };
 
 void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream)
diff --git a/sound/usb/urb.c b/sound/usb/urb.c
index e184349..a091f57 100644
--- a/sound/usb/urb.c
+++ b/sound/usb/urb.c
@@ -251,7 +251,8 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
 		packs_per_ms = 1;
 
 	if (is_playback) {
-		urb_packs = max(chip->nrpacks, 1);
+		//urb_packs = max(chip->nrpacks, 1);
+		urb_packs = 32; //max(chip->nrpacks, 1);
 		urb_packs = min(urb_packs, (unsigned int)MAX_PACKS);
 	} else
 		urb_packs = 1;
@@ -270,6 +271,9 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
 			minsize -= minsize >> 3;
 		minsize = max(minsize, 1u);
 		total_packs = (period_bytes + minsize - 1) / minsize;
+
+		printk(KERN_ERR "plb: urb_packs %d period_bytes %d minsize %d, total_packs %d \n", urb_packs, period_bytes, minsize, total_packs);
+
 		/* we need at least two URBs for queueing */
 		if (total_packs < 2) {
 			total_packs = 2;
@@ -284,6 +288,7 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
 		total_packs = MAX_URBS * urb_packs;
 	}
 	subs->nurbs = (total_packs + urb_packs - 1) / urb_packs;
+	printk(KERN_ERR "plb: total_packs %d nurbs %d \n", total_packs, subs->nurbs);
 	if (subs->nurbs > MAX_URBS) {
 		/* too much... */
 		subs->nurbs = MAX_URBS;
@@ -305,6 +310,9 @@ int snd_usb_init_substream_urbs(struct snd_usb_substream *subs,
 		u->buffer_size = maxsize * u->packets;
 		if (subs->fmt_type == UAC_FORMAT_TYPE_II)
 			u->packets++; /* for transfer delimiter */
+
+		printk(KERN_ERR "plb: urb %d packets %d buffer_size %d \n", i, u->packets, u->buffer_size);
+
 		u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
 		if (!u->urb)
 			goto out_of_memory;
