diff -urN linux-2.6.14/drivers/mmc/mmc_block.c ../linux-2.6.14/drivers/mmc/mmc_block.c
--- linux-2.6.14/drivers/mmc/mmc_block.c	2008-06-29 00:58:26.000000000 -0700
+++ ../linux-2.6.14/drivers/mmc/mmc_block.c	2008-06-29 01:16:27.000000000 -0700
@@ -196,10 +196,11 @@
 			brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK;
 			brq.data.flags |= MMC_DATA_READ;
 		} else {
-			brq.cmd.opcode = MMC_WRITE_BLOCK;
+			//brq.cmd.opcode = MMC_WRITE_BLOCK;
+			brq.cmd.opcode = brq.data.blocks > 1 ? MMC_WRITE_MULTIPLE_BLOCK : MMC_WRITE_BLOCK;
 			brq.cmd.flags = MMC_RSP_R1B;
 			brq.data.flags |= MMC_DATA_WRITE;
-			brq.data.blocks = 1;
+			//brq.data.blocks = 1;
 		}
 		brq.mrq.stop = brq.data.blocks > 1 ? &brq.stop : NULL;
 
diff -urN linux-2.6.14/drivers/mmc/mmc_queue.c ../linux-2.6.14/drivers/mmc/mmc_queue.c
--- linux-2.6.14/drivers/mmc/mmc_queue.c	2005-10-27 17:02:08.000000000 -0700
+++ ../linux-2.6.14/drivers/mmc/mmc_queue.c	2008-06-29 01:19:23.000000000 -0700
@@ -78,8 +78,11 @@
 
 		spin_lock_irq(q->queue_lock);
 		set_current_state(TASK_INTERRUPTIBLE);
-		if (!blk_queue_plugged(q))
-			mq->req = req = elv_next_request(q);
+		//if (!blk_queue_plugged(q))
+		//	mq->req = req = elv_next_request(q);
+		if (blk_queue_plugged(q))
+			printk(KERN_WARNING "blk_queue_plugged! unplug_timer func = %08x, unplug_fn = %08x, unplug_thresh = %d, unplug_jiffies = %d\n", q->unplug_timer.function, q->unplug_fn, q->unplug_thresh, q->unplug_delay);
+		mq->req = req = elv_next_request(q);
 		spin_unlock_irq(q->queue_lock);
 
 		if (!req) {
@@ -126,7 +131,8 @@
 int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock)
 {
 	struct mmc_host *host = card->host;
-	u64 limit = BLK_BOUNCE_HIGH;
+	//u64 limit = BLK_BOUNCE_HIGH;
+	u64 limit = BLK_BOUNCE_ANY;
 	int ret;
 
 	if (host->dev->dma_mask && *host->dev->dma_mask)
diff -urN linux-2.6.14/drivers/mmc/pxamci.c ../linux-2.6.14/drivers/mmc/pxamci.c
--- linux-2.6.14/drivers/mmc/pxamci.c	2008-06-29 00:58:26.000000000 -0700
+++ ../linux-2.6.14/drivers/mmc/pxamci.c	2008-06-29 01:15:29.000000000 -0700
@@ -46,7 +46,12 @@
 
 #define DRIVER_NAME	"pxa2xx-mci"
 
+#ifdef CONFIG_PXA27x
+#define NR_SG	256
+#else
 #define NR_SG	1
+#endif
+
 
 struct pxamci_host {
 	struct mmc_host		*mmc;
@@ -70,6 +75,8 @@
 	unsigned int		dma_len;
 
 	unsigned int		dma_dir;
+
+	unsigned char		bus_width;
 };
 
 static inline unsigned int ns_to_clocks(unsigned int ns)
@@ -124,6 +131,9 @@
 	u32 dcmd;
 	int i;
 
+	//printk(KERN_DEBUG "PXAMCI: Setting up DMA for a %d block (%d bytes, sg_len = %d) transfer.\n",
+	//	 nob, 1 << data->blksz_bits, data->sg_len);
+
 	host->data = data;
 
 	if (data->flags & MMC_DATA_STREAM)
@@ -147,6 +157,7 @@
 		DRCMRTXMMC = host->dma | DRCMR_MAPVLD;
 	}
 
+	/* FIXME: A burst of 32 bytes may interfere with the camera. */
 	dcmd |= DCMD_BURST32 | DCMD_WIDTH1;
 
 	host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
@@ -294,7 +305,11 @@
 	if (data->error == MMC_ERR_NONE)
 		data->bytes_xfered = data->blocks << data->blksz_bits;
 	else
+#ifdef CONFIG_PXA27x
+		data->bytes_xfered = (data->blocks - readl(host->base + MMC_BLKS_REM)) << data->blksz_bits;
+#else
 		data->bytes_xfered = 0;
+#endif
 
 	pxamci_disable_irq(host, DATA_TRAN_DONE);
 
@@ -366,6 +381,9 @@
 
 		if (mrq->data->flags & MMC_DATA_STREAM)
 			cmdat |= CMDAT_STREAM;
+
+		if (host->bus_width == MMC_BUS_WIDTH_4)
+			cmdat |= CMDAT_SD_4DAT;
 	}
 
 	pxamci_start_cmd(host, mrq->cmd, cmdat);
@@ -414,6 +432,8 @@
 			host->cmdat |= CMDAT_INIT;
 	}
 
+	host->bus_width = ios->bus_width;
+
 	DBG("pxamci_set_ios: clkrt = %x cmdat = %x\n",
 	    host->clkrt, host->cmdat);
 }
@@ -470,6 +490,8 @@
 	 * data we successfully wrote to the card.
 	 */
 	mmc->max_phys_segs = NR_SG;
+	mmc->max_hw_segs = NR_SG;
+	mmc->max_sectors = 255;
 
 	/*
 	 * Our hardware DMA can handle a maximum of one page per SG entry.
@@ -483,6 +505,9 @@
 	mmc->ocr_avail = host->pdata ?
 			 host->pdata->ocr_mask :
 			 MMC_VDD_32_33|MMC_VDD_33_34;
+#ifdef CONFIG_PXA27x
+	mmc->caps = MMC_CAP_4_BIT_DATA;
+#endif
 
 	host->sg_cpu = dma_alloc_coherent(dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL);
 	if (!host->sg_cpu) {
diff -urN linux-2.6.14/drivers/mmc/pxamci.h ../linux-2.6.14/drivers/mmc/pxamci.h
--- linux-2.6.14/drivers/mmc/pxamci.h	2005-10-27 17:02:08.000000000 -0700
+++ ../linux-2.6.14/drivers/mmc/pxamci.h	2008-06-29 01:17:51.000000000 -0700
@@ -9,6 +9,7 @@
 #undef MMC_NOB
 #undef MMC_PRTBUF
 #undef MMC_I_MASK
+#undef MMC_BLKS_REM
 #undef END_CMD_RES
 #undef PRG_DONE
 #undef DATA_TRAN_DONE
@@ -47,6 +48,7 @@
 #define SPI_EN			(1 << 0)
 
 #define MMC_CMDAT	0x0010
+#define CMDAT_SD_4DAT		(1 << 8)
 #define CMDAT_DMAEN		(1 << 7)
 #define CMDAT_INIT		(1 << 6)
 #define CMDAT_BUSY		(1 << 5)
@@ -71,6 +73,8 @@
 
 #define MMC_I_MASK	0x0028
 
+#define MMC_BLKS_REM	0x004c	/* 16 bit */
+
 /*PXA27x MMC interrupts*/
 #define SDIO_SUSPEND_ACK  	(1 << 12)
 #define SDIO_INT          	(1 << 11)
