diff -ur /tracks/cvs/handheld/linux/kernel/arch/arm/mach-sa1100/h3600_asic_mmc.c linux/arch/arm/mach-sa1100/h3600_asic_mmc.c
--- /tracks/cvs/handheld/linux/kernel/arch/arm/mach-sa1100/h3600_asic_mmc.c	2003-09-25 11:55:59.000000000 +0400
+++ linux/arch/arm/mach-sa1100/h3600_asic_mmc.c	2004-01-31 22:07:09.000000000 +0400
@@ -42,6 +42,8 @@
 	u16 cdc_flags;
 };
 
+extern char * g_mmc_map[128];
+
 /* straight out of the MMC spec.  Different commands return different length responses */
 static struct response_info rinfo[] = {
 	{ 0,  MMC_CMD_DATA_CONT_FORMAT_NO_RESPONSE                     }, /* R0 */
@@ -71,6 +73,9 @@
 };
 
 static struct h3800_mmc_data g_h3800_data;
+static int intcount;
+static int enabled;
+static int g_mmc_block_count;
 
 #define MMC_IRQ_TIMEOUT  (3 * HZ)
 #define H3800_MASTER_CLOCK 33868800
@@ -195,7 +200,8 @@
 	printk(KERN_DEBUG "%sresult %d\n", header, request->result);
 }
 #endif /* CONFIG_MMC_DEBUG */
-
+extern int g_mmc_mask;
+extern int g_mmc_mode;
 /*
 static void printk_asic_state( char *header )
 {
@@ -380,6 +386,8 @@
 	u8 *buf = request->buffer;
 	u16 data;
 	int i;
+	if (g_mmc_mode)
+		buf = g_mmc_map[g_mmc_block_count];
 
 	MMC_DEBUG(2,": nob=%d block_len=%d", request->nob, request->block_len);
 	if ( request->nob <= 0 ) {
@@ -408,9 +416,11 @@
 #endif
 
 	/* Updated the request buffer to reflect the current state */
-	request->buffer = (u8 *) buf;
+	if (!g_mmc_mode)
+		request->buffer = (u8 *) buf;
 	request->nob--;
 	g_h3600_asic_statistics.mmc_written++;
+	g_mmc_block_count++;
 }
 
 static void mmc_h3800_receive_data( struct mmc_request *request )
@@ -418,7 +428,8 @@
 	u8 *buf = request->buffer;
 	u16 data;
 	int i;
-
+	if (g_mmc_mode)
+		buf = g_mmc_map[g_mmc_block_count];
 	MMC_DEBUG(2,": nob=%d block_len=%d buf=%p", request->nob, request->block_len, buf);
 	if ( request->nob <= 0 ) {
 		MMC_DEBUG(1,": *** nob already at 0 ***");
@@ -439,9 +450,11 @@
 #endif
 
 	/* Updated the request buffer to reflect the current state */
-	request->buffer = (u8 *) buf;
+	if (!g_mmc_mode)
+		request->buffer = (u8 *) buf;
 	request->nob--;
 	g_h3600_asic_statistics.mmc_read++;
+	g_mmc_block_count++;
 }
 
 #define STATBUG(_x) \
@@ -468,21 +481,38 @@
 
 	STATBUG("set_command");
 
+	g_mmc_block_count=0;
+
 	switch (request->cmd) {
+
 	case MMC_READ_SINGLE_BLOCK:
-	case MMC_READ_MULTIPLE_BLOCK:
 		mmc_h3800_set_transfer( request->block_len, request->nob );
 		cdc = MMC_CMD_DATA_CONT_READ | MMC_CMD_DATA_CONT_DATA_ENABLE;
 		irq = MMC_INT_MASK_ALL;
 		g_h3800_data.type = RT_READ;
 		break;
+
+	case MMC_READ_MULTIPLE_BLOCK:
+		mmc_h3800_set_transfer( request->block_len, request->nob );
+		cdc = MMC_CMD_DATA_CONT_READ | MMC_CMD_DATA_CONT_DATA_ENABLE | MMC_CMD_DATA_CONT_BC_MODE;
+		irq = MMC_INT_MASK_ALL;
+		g_h3800_data.type = RT_READ;
+		break;
+
 	case MMC_WRITE_BLOCK:
-	case MMC_WRITE_MULTIPLE_BLOCK:
 		mmc_h3800_set_transfer( request->block_len, request->nob );
 		cdc = MMC_CMD_DATA_CONT_WRITE | MMC_CMD_DATA_CONT_DATA_ENABLE;
 		irq = MMC_INT_MASK_ALL;
 		g_h3800_data.type = RT_WRITE;
 		break;
+	
+	case MMC_WRITE_MULTIPLE_BLOCK:
+		mmc_h3800_set_transfer( request->block_len, request->nob );
+		cdc = MMC_CMD_DATA_CONT_WRITE | MMC_CMD_DATA_CONT_DATA_ENABLE | MMC_CMD_DATA_CONT_BC_MODE; 
+		irq = MMC_INT_MASK_ALL;
+		g_h3800_data.type = RT_WRITE;
+		break;
+
 	default:
 		irq = MMC_INT_MASK_END_COMMAND_RESPONSE;
 		g_h3800_data.type = RT_RESPONSE_ONLY;
@@ -514,7 +544,8 @@
 #endif
 
 	mod_timer( &g_h3800_data.irq_timer, jiffies + MMC_IRQ_TIMEOUT); 
-	enable_irq( IRQ_GPIO_H3800_MMC_INT );
+	if (g_mmc_mask)
+		enable_irq( IRQ_GPIO_H3800_MMC_INT );
 	g_h3600_asic_statistics.mmc_command++;
 	return MMC_NO_ERROR;
 }
@@ -594,7 +625,8 @@
 {
 	int retval = MMC_NO_ERROR;
 
-	disable_irq( IRQ_GPIO_H3800_MMC_INT );
+	if (g_mmc_mask)
+		disable_irq( IRQ_GPIO_H3800_MMC_INT );
 
 	if ( status & (MMC_STATUS_READ_TIMEOUT 
 		       | MMC_STATUS_RESPONSE_TIMEOUT )) {
@@ -615,13 +647,12 @@
 		mmc_h3800_get_response( sd->request );
 
 	if ( g_h3800_data.type == RT_READ && 
-	     (status & (MMC_STATUS_FIFO_FULL | MMC_STATUS_DATA_TRANSFER_DONE)) != 0)
+	     (status & (MMC_STATUS_FIFO_FULL | MMC_STATUS_DATA_TRANSFER_DONE)) != 0){
 		mmc_h3800_receive_data( sd->request );
-
-	if ( g_h3800_data.type == RT_WRITE && (status & MMC_STATUS_FIFO_EMPTY ) != 0
-	     && sd->request->nob > 0 )
+	}
+	if ( g_h3800_data.type == RT_WRITE && (H3800_ASIC1_MMC_Status & MMC_STATUS_FIFO_EMPTY) != 0 && sd->request->nob > 0 ) {
 		mmc_h3800_transmit_data( sd->request );
-
+	}
 	switch (g_h3800_data.type) {
 	case RT_NO_RESPONSE:
 		break;
@@ -635,25 +666,28 @@
 	case RT_READ:
 		if ( sd->request->nob ) {
 			MMC_DEBUG(2,": read re-enabling IRQ mask=0x%04x", H3800_ASIC1_MMC_InterruptMask);
-			mod_timer( &sd->irq_timer, jiffies + MMC_IRQ_TIMEOUT); 
 			mmc_h3800_start_clock();
+			mod_timer( &sd->irq_timer, jiffies + MMC_IRQ_TIMEOUT); 
+	if (g_mmc_mask)
 			enable_irq( IRQ_GPIO_H3800_MMC_INT );
 			return;
 		}
 		break;
 	case RT_WRITE:
 		if ( sd->request->nob || !(status & MMC_STATUS_END_PROGRAM)  ) {
+//		if ( sd->request->nob) {
 			MMC_DEBUG(2,": write re-enabling IRQ mask=0x%04x", H3800_ASIC1_MMC_InterruptMask);
-			mod_timer( &sd->irq_timer, jiffies + MMC_IRQ_TIMEOUT); 
 			mmc_h3800_start_clock();
+			mod_timer( &sd->irq_timer, jiffies + MMC_IRQ_TIMEOUT); 
+	if (g_mmc_mask)
 			enable_irq( IRQ_GPIO_H3800_MMC_INT );
 			return;
 		}
 		break;
 	}
 	
-	MMC_DEBUG(2,": terminating status=0x%04x", H3800_ASIC1_MMC_Status );
 terminate_int:
+	MMC_DEBUG(2,": terminating status=0x%04x", H3800_ASIC1_MMC_Status );
 	H3800_ASIC1_MMC_InterruptMask = MMC_INT_MASK_ALL & ~MMC_INT_MASK_END_COMMAND_RESPONSE;
 	del_timer_sync( &sd->irq_timer );
 	sd->request->result = retval;
@@ -665,7 +699,6 @@
 {
 	struct h3800_mmc_data *sd = (struct h3800_mmc_data *) dev_id;
 	u16 status = H3800_ASIC1_MMC_Status;
-	
 #ifdef CONFIG_MMC_DEBUG
 	START_MMC_DEBUG(2) { 
 		printk(KERN_DEBUG "%s: sd=%p status=0x%04x (", __FUNCTION__, sd, status);
@@ -673,7 +706,6 @@
 		printk(")\n"); 
 	} END_MMC_DEBUG;
 #endif
-
 	mmc_h3800_handle_int( sd, status, 0 );
 }
 
@@ -692,9 +724,9 @@
 		printk_request( sd->request, "  " );
 	} END_MMC_DEBUG;
 #endif
-
 	g_h3600_asic_statistics.mmc_timeout++;
 	mmc_h3800_handle_int( sd, status, 1 );
+	intcount=0;
 }
 
 
@@ -794,6 +826,7 @@
 	int retval;
 	MMC_DEBUG(1,"");
 
+	intcount=0;
 	/* Set up timers */
 	g_h3800_data.sd_detect_timer.function = mmc_h3800_fix_sd_detect;
 	g_h3800_data.sd_detect_timer.data     = (unsigned long) &g_h3800_data;
@@ -810,6 +843,7 @@
 	/* Basic service interrupt */
 	H3800_ASIC1_MMC_InterruptMask = MMC_INT_MASK_ALL;
 	set_GPIO_IRQ_edge( GPIO_H3800_MMC_INT, GPIO_RISING_EDGE );
+
 	retval = request_irq( IRQ_GPIO_H3800_MMC_INT, mmc_h3800_int,
 			      SA_INTERRUPT, "mmc_h3800_int", &g_h3800_data );
 	if ( retval ) {
@@ -817,7 +851,6 @@
 		return retval;
 	}
 	disable_irq( IRQ_GPIO_H3800_MMC_INT );
-
 	mmc_h3800_slot_up(); /* Fixes the sd_detect interrupt direction */
 
 	retval = request_irq( IRQ_H3800_SD_DETECT, mmc_h3800_sd_detect_int, 
diff -ur /tracks/cvs/handheld/linux/kernel/drivers/mmc/mmc_core.c linux/drivers/mmc/mmc_core.c
--- /tracks/cvs/handheld/linux/kernel/drivers/mmc/mmc_core.c	2003-09-22 11:53:10.000000000 +0400
+++ linux/drivers/mmc/mmc_core.c	2004-01-31 21:51:16.000000000 +0400
@@ -39,6 +39,15 @@
 static struct mmc_dev          g_mmc_dev;
 static struct proc_dir_entry  *proc_mmc_dir;
 
+int g_mmc_mode = 1;
+int g_mmc_mask = 0;
+EXPORT_SYMBOL(g_mmc_mask);
+EXPORT_SYMBOL(g_mmc_mode);
+
+// This is a hack and becomes a global kernel symbol, but it works for now
+char * g_mmc_map[128];
+EXPORT_SYMBOL(g_mmc_map);
+
 #ifdef CONFIG_MMC_DEBUG
 int g_mmc_debug = CONFIG_MMC_DEBUG_VERBOSE;
 EXPORT_SYMBOL(g_mmc_debug);
@@ -206,8 +215,9 @@
 
 	r1->cmd    = buf[0];
 	r1->status = PARSE_U32(buf,1);
-
+	
 	MMC_DEBUG(2,"cmd=%d status=%08x", r1->cmd, r1->status);
+	MMC_DEBUG(1,"cmd=%d status=%u", r1->cmd, R1_CURRENT_STATE(r1->status));
 
 	/* SD card return in upper status the cardid */
 
@@ -350,6 +360,8 @@
 	dev->request.nob       = nob;
 	dev->request.block_len = block_len;
 	dev->request.buffer    = NULL;
+//	for (loop=0; loop<nob; loop++)
+//		MMC_DEBUG(0,"Map entry - %p\n",g_mmc_map[loop]);
 	if ( nob && dev->io_request )
 		dev->request.buffer = dev->io_request->buffer;
 
@@ -740,6 +752,8 @@
 #endif
 	{ 2, "eject", NULL, 0, 0600, NULL, &mmc_do_eject },
 	{ 3, "insert", NULL, 0, 0600, NULL, &mmc_do_insert },
+	{ 4, "mode", &g_mmc_mode, sizeof(int), 0666, NULL, &proc_dointvec },
+	{ 5, "mask", &g_mmc_mask, sizeof(int), 0666, NULL, &proc_dointvec },
 	{0}
 };
 
diff -ur /tracks/cvs/handheld/linux/kernel/drivers/mmc/mmc_media.c linux/drivers/mmc/mmc_media.c
--- /tracks/cvs/handheld/linux/kernel/drivers/mmc/mmc_media.c	2003-09-22 11:53:10.000000000 +0400
+++ linux/drivers/mmc/mmc_media.c	2004-01-31 21:56:04.000000000 +0400
@@ -29,6 +29,7 @@
 #include <linux/hdreg.h>  /* HDIO_GETGEO */
 #include <linux/init.h>
 #include <linux/devfs_fs_kernel.h>
+#include <linux/list.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -51,7 +52,8 @@
 #include <linux/blkpg.h>
 
 static int rahead     = 8;
-static int maxsectors = 4;
+static int maxsectors = 31;
+extern int g_mmc_mode;
 
 MODULE_PARM(maxsectors,"i");
 MODULE_PARM_DESC(maxsectors,"Maximum number of sectors for a single request");
@@ -69,7 +71,7 @@
 
 static int              mmc_sizes[MMC_NDISK];        /* Used in gendisk - gives whole size of partition */
 static struct hd_struct mmc_partitions[MMC_NDISK];   /* Used in gendisk - gives particular partition information */
-
+ 
 static char             mmc_gendisk_flags;
 static devfs_handle_t   mmc_devfs_handle;
 
@@ -85,10 +87,12 @@
 	int              write_block_len;     // Valid write block length
 };
 
+// This is a hack and becomes a global kernel symbol, but it works for now
+extern char * g_mmc_map[128];
+
 static struct mmc_media_dev   g_media_dev[MMC_MAX_SLOTS];
 static struct mmc_io_request  g_io_request;
 static int                    g_busy;
-
 static struct gendisk mmc_gendisk = {
         major:	        0,               /* major number dynamically assigned */
 	major_name:	DEVICE_NAME,
@@ -157,7 +161,7 @@
 	for ( i = max_p - 1 ; i >= 0 ; i-- ) {
 		int item = start + i;
 
-		invalidate_device(MKDEV(mmc_major,item),1);
+		invalidate_device(MKDEV(mmc_major,item),0);
 		mmc_gendisk.part[item].start_sect = 0;
 		mmc_gendisk.part[item].nr_sects   = 0;
 		/* TODO: Fix the blocksize? */
@@ -243,7 +247,7 @@
 	return &g_media_dev[num];
 }
 
-static int mmc_media_transfer( struct mmc_media_dev *dev, const struct request *req )
+static int mmc_media_transfer( struct mmc_media_dev *dev, const struct request *req)
 {
 	int minor = MINOR(req->rq_dev);
 	unsigned long flags;
@@ -262,14 +266,15 @@
 	g_io_request.id         = DEVICE_NR(req->rq_dev);
 	g_io_request.cmd        = req->cmd;
 	g_io_request.sector     = mmc_partitions[minor].start_sect + req->sector;
-	g_io_request.nr_sectors = req->current_nr_sectors;
+	if (g_mmc_mode)	
+		g_io_request.nr_sectors = req->nr_sectors;
+	else
+		g_io_request.nr_sectors = req->current_nr_sectors;
 	g_io_request.block_len  = mmc_blk[minor];
 	g_io_request.buffer     = req->buffer;
-
-	MMC_DEBUG(2,": id=%d cmd=%d sector=%ld nr_sectors=%ld block_len=%ld buf=%p",
+	MMC_DEBUG(1,": id=%d cmd=%d sector=%ld nr_sectors=%ld block_len=%ld buf=%p",
 	      g_io_request.id, g_io_request.cmd, g_io_request.sector, g_io_request.nr_sectors,
 	      g_io_request.block_len, g_io_request.buffer );
-
 	mmc_handle_io_request(&g_io_request);
 	spin_unlock_irqrestore(&dev->lock, flags);
 	return 1;
@@ -278,9 +283,12 @@
 static void mmc_media_request( request_queue_t *q )
 {
 	struct mmc_media_dev *dev;
-
-	if ( g_busy )
+	struct buffer_head *bh;
+	int map_ptr;
+	if ( g_busy ) {
 		return;
+	}
+
 
 	while(1) {
 		INIT_REQUEST;  /* returns when queue is empty */
@@ -290,23 +298,112 @@
 			continue;
 		}
 
-		MMC_DEBUG(2," (%p): cmd %i sec %li (nr. %li)", CURRENT,
+		MMC_DEBUG(1," (%p): cmd %i sec %li (nr. %li)", CURRENT,
 		      CURRENT->cmd, CURRENT->sector, CURRENT->current_nr_sectors);
+	if (g_mmc_mode) {
+		bh = CURRENT->bh;
 
+		for (map_ptr=0;map_ptr < 128; map_ptr++)
+			g_mmc_map[map_ptr] = NULL;
+		map_ptr = 0;
+		do {
+			int loop = 0;
+//			MMC_DEBUG(4,"BH Entry - %p %u %u",bh->b_data,bh->b_blocknr,bh->b_size);
+			for(loop=0;loop < (bh->b_size >> 9); loop++){
+				g_mmc_map[map_ptr] = bh->b_data + ((1 << 9) * loop);
+//				MMC_DEBUG(4,"Map Loop %u %p %u",loop,g_mmc_map[map_ptr],map_ptr);
+				map_ptr++;
+			}
+			bh = bh->b_reqnext;
+		} while (bh);
+//		for (map_ptr=0;map_ptr < CURRENT->nr_sectors; map_ptr++)
+//			MMC_DEBUG(0,"Map pointer %u -- %p",map_ptr,g_mmc_map[map_ptr]);
+		if (map_ptr != CURRENT->nr_sectors)
+			MMC_DEBUG(0,"Total Sector Count WRONG! %u %lu",map_ptr,CURRENT->nr_sectors);		
+	}
 		if ( mmc_media_transfer(dev,CURRENT) ) {
-			g_busy = 1;
-			return;
-		}
+				g_busy = 1;
+				return;
+			}
 		end_request(0);  /* There was a problem with the request */
 	}
+
+}
+/*
+int mmc_end_that_request_first (struct request *req, int uptodate, char *name)
+{
+	struct buffer_head * bh;
+	int nsect;
+
+	MMC_DEBUG(2,"End Request First");
+	req->errors = 0;
+	if (!uptodate)
+		printk("end_request: I/O error, dev %s (%s), sector %lu\n",
+			kdevname(req->rq_dev), name, req->sector);
+
+	if ((bh = req->bh) != NULL) {
+		nsect = bh->b_size >> 9;
+		blk_finished_io(nsect);
+		req->bh = bh->b_reqnext;
+		bh->b_reqnext = NULL;
+		bh->b_end_io(bh, uptodate);
+		if ((bh = req->bh) != NULL) {
+			req->hard_sector += nsect;
+			req->hard_nr_sectors -= nsect;
+			req->sector = req->hard_sector;
+			req->nr_sectors = req->hard_nr_sectors;
+
+			req->current_nr_sectors = bh->b_size >> 9;
+			if (req->nr_sectors < req->current_nr_sectors) {
+				req->nr_sectors = req->current_nr_sectors;
+				printk("end_request: buffer-list destroyed\n");
+			}
+			req->buffer = bh->b_data;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+void mmc_end_that_request_last(struct request *req)
+{
+	MMC_DEBUG(2,"End that request last");
+	if (req->waiting != NULL)
+		complete(req->waiting);
+	req_finished_io(req);
+
+	blkdev_release_request(req);
+}
+*/
+static inline void mmc_end_request(int uptodate) {
+	struct request *req = CURRENT;
+	
+	if (g_mmc_mode ){
+		while (end_that_request_first(req, uptodate, DEVICE_NAME)){
+			MMC_DEBUG(1,"End Reqeust");
+		}
+	}
+	else 
+		if (end_that_request_first(req, uptodate, DEVICE_NAME))
+			return;
+#ifndef DEVICE_NO_RANDOM
+	add_blkdev_randomness(MAJOR(req->rq_dev));
+#endif
+	DEVICE_OFF(req->rq_dev);
+	blkdev_dequeue_request(req);
+	end_that_request_last(req);
 }
 
 static void mmc_media_transfer_done( struct mmc_io_request *trans, int result )
 {
 	unsigned long flags;
-	MMC_DEBUG(3,": result=%d", result);
+
+	MMC_DEBUG(2,": result=%d", result);
 	spin_lock_irqsave(&io_request_lock, flags);
-	end_request(result);
+	if (g_mmc_mode)
+			mmc_end_request(result);
+	else
+			end_request(result);	
 	g_busy = 0;
 	if (!QUEUE_EMPTY)
 		mmc_media_request(NULL);  // Start the next transfer
@@ -452,7 +549,6 @@
 	for(i=0; i < MMC_NDISK; i++)
 		mmc_max[i] = maxsectors;
 	max_sectors[mmc_major]   = mmc_max;
-
 	/* Start with zero-sized partitions : we'll fix this later */
 	memset(mmc_sizes, 0, sizeof(int) * MMC_NDISK);
 	blk_size[mmc_major] = mmc_sizes;
diff -ur /tracks/cvs/handheld/linux/kernel/drivers/mmc/mmc_protocol.c linux/drivers/mmc/mmc_protocol.c
--- /tracks/cvs/handheld/linux/kernel/drivers/mmc/mmc_protocol.c	2003-09-22 11:53:10.000000000 +0400
+++ linux/drivers/mmc/mmc_protocol.c	2004-01-31 22:04:59.000000000 +0400
@@ -27,10 +27,11 @@
 
 #include <linux/version.h>
 #include <linux/proc_fs.h>
-
 #include "mmc_core.h"
 
 static void * mmc_cim_default_state( struct mmc_dev *dev, int first );
+extern int g_mmc_mode;
+extern char * g_mmc_map[128];
 
 /******************************************************************
  *
@@ -207,6 +208,147 @@
 	return mmc_cim_default_state;
 }
 
+static void * mmc_cim_get_status( struct mmc_dev *dev, int first );
+
+static void * mmc_cim_read_write_block_new( struct mmc_dev *dev, int first )
+{
+	struct mmc_io_request *t = dev->io_request;
+	struct mmc_response_r1 r1;
+	struct mmc_slot *slot = dev->slot + t->id;
+	int    retval = 0;
+	int    i;
+
+	MMC_DEBUG(2,"first=%d",first);
+	MMC_DEBUG(1,"Card State %u %u\n",slot->state,dev->request.cmd);
+//	for (i=0;i<t->nr_sectors;i++)
+//		MMC_DEBUG(0,"Map Entry - %u %p",i,g_mmc_map[i]);
+	if ( first ) {
+		mmc_fix_request_block_size( dev );
+		switch ( slot->state ) {
+		case CARD_STATE_STBY:
+			mmc_simple_cmd(dev, MMC_SELECT_CARD, slot->addr, RESPONSE_R1B );
+			break;
+		case CARD_STATE_TRAN:
+			if ( t->nr_sectors == 1 || g_mmc_mode == 0)
+				mmc_send_cmd(dev, (t->cmd == READ ? MMC_READ_SINGLE_BLOCK : MMC_WRITE_BLOCK), 
+				     t->sector * t->block_len, 1, t->block_len, RESPONSE_R1 );
+			else
+				mmc_send_cmd(dev, (t->cmd == READ ? MMC_READ_MULTIPLE_BLOCK : MMC_WRITE_MULTIPLE_BLOCK), 
+				     t->sector * t->block_len, t->nr_sectors, t->block_len, RESPONSE_R1 );
+			break;
+		case CARD_STATE_DATA:
+		case CARD_STATE_RCV:
+		case CARD_STATE_PRG:
+			MMC_DEBUG(1,"Card State  %u  - Resending Status request in First",slot->state);
+			return mmc_cim_get_status;
+			break;
+		default:
+			MMC_DEBUG(0,"invalid card state %d", slot->state);
+			goto read_block_error;
+			break;
+		}
+		return NULL;
+	}
+		switch ( slot->state ) {
+		case CARD_STATE_DATA:
+			if (t->cmd == READ)
+				break;
+			MMC_DEBUG(0,"Card State  %u  - Resending Status request in Normal",slot->state);
+			return mmc_cim_get_status;
+
+		case CARD_STATE_RCV:
+			if (t->cmd == WRITE)
+				break;
+			MMC_DEBUG(0,"Card State  %u  - Resending Status request in Normal",slot->state);
+			return mmc_cim_get_status;
+
+		case CARD_STATE_PRG:
+			MMC_DEBUG(1,"Card State  %u  - Resending Status request in Normal",slot->state);
+			return mmc_cim_get_status;
+			break;
+		default:
+			break;
+	}
+
+	switch (dev->request.cmd) {
+
+	case MMC_SELECT_CARD:
+		if ( (retval = mmc_unpack_r1( &dev->request, &r1, slot->state )) ){
+			slot->state = R1_CURRENT_STATE(r1.status);
+			goto read_block_error;
+		}
+		for ( i = 0 ; i < dev->num_slots ; i++ )
+			dev->slot[i].state = ( i == t->id ? CARD_STATE_TRAN : CARD_STATE_STBY );
+
+		if ( t->nr_sectors == 1)
+		mmc_send_cmd(dev, (t->cmd == READ ? MMC_READ_SINGLE_BLOCK : MMC_WRITE_BLOCK), 
+			     t->sector * t->block_len, 1, t->block_len, RESPONSE_R1 );
+		else
+		mmc_send_cmd(dev, (t->cmd == READ ? MMC_READ_MULTIPLE_BLOCK : MMC_WRITE_MULTIPLE_BLOCK), 
+			     t->sector * t->block_len, t->nr_sectors, t->block_len, RESPONSE_R1 );
+		break;
+
+	case MMC_SET_BLOCKLEN:
+		if ( (retval = mmc_unpack_r1( &dev->request, &r1, slot->state )) ){
+			slot->state = R1_CURRENT_STATE(r1.status);
+			goto read_block_error;
+		}
+		if ( t->nr_sectors == 1)
+		mmc_send_cmd(dev, (t->cmd == READ ? MMC_READ_SINGLE_BLOCK : MMC_WRITE_BLOCK), 
+			     t->sector * t->block_len, 1, t->block_len, RESPONSE_R1 );
+		else
+		mmc_send_cmd(dev, (t->cmd == READ ? MMC_READ_MULTIPLE_BLOCK : MMC_WRITE_MULTIPLE_BLOCK), 
+			     t->sector * t->block_len, t->nr_sectors, t->block_len, RESPONSE_R1 );
+
+		break;
+
+	case MMC_READ_SINGLE_BLOCK:
+	case MMC_READ_MULTIPLE_BLOCK:
+	case MMC_WRITE_BLOCK:
+	case MMC_WRITE_MULTIPLE_BLOCK:
+		if ( (retval = mmc_unpack_r1( &dev->request, &r1, slot->state )) ){
+			slot->state = R1_CURRENT_STATE(r1.status);
+			goto read_block_error;
+		}
+		if ( (dev->request.cmd == MMC_READ_MULTIPLE_BLOCK || dev->request.cmd == MMC_WRITE_MULTIPLE_BLOCK) ){ 
+			mmc_simple_cmd(dev, MMC_STOP_TRANSMISSION, 0, RESPONSE_R1B );
+		} else 
+		{
+		mmc_finish_io_request( dev, 1 );
+		if ( mmc_has_valid_request(dev) )
+			return mmc_cim_read_write_block_new;
+		return mmc_cim_default_state;
+		}
+		break;
+
+	case MMC_STOP_TRANSMISSION:
+		if ( (retval = mmc_unpack_r1( &dev->request, &r1, slot->state )) != MMC_ERROR_STATE_MISMATCH){
+			MMC_DEBUG(0," Stop_Transmission failure during cmd %d, error %d (%s)", 
+	      		dev->request.cmd, retval, mmc_result_to_string(retval));
+		}			
+		if (t->cmd == READ)
+			slot->state=CARD_STATE_TRAN;
+		else
+			slot->state=CARD_STATE_RCV;
+		mmc_finish_io_request( dev, 1 );
+		if ( mmc_has_valid_request(dev) )
+			return mmc_cim_read_write_block_new;
+		return mmc_cim_default_state;
+		break;
+
+	default:
+		goto read_block_error;
+		break;
+	}
+	return NULL;
+
+read_block_error:
+	MMC_DEBUG(0,"failure during cmd %d, error %d (%s)", 
+	      dev->request.cmd, retval, mmc_result_to_string(retval));
+	mmc_finish_io_request( dev, 0 );   // Failure
+	return mmc_cim_default_state;
+}
+
 /* Update the card's status information in preparation to running a read/write cycle */
 
 static void * mmc_cim_get_status( struct mmc_dev *dev, int first )
@@ -227,7 +369,10 @@
 		retval = mmc_unpack_r1(&dev->request,&r1,slot->state);
 		if ( !retval || retval == MMC_ERROR_STATE_MISMATCH ) {
 			slot->state = R1_CURRENT_STATE(r1.status);
-			return mmc_cim_read_write_block;
+			if (g_mmc_mode) 
+				return mmc_cim_read_write_block_new;
+			else
+				return mmc_cim_read_write_block;
 		}
 		break;
 
@@ -254,7 +399,10 @@
 	if ( first )
 		return mmc_cim_get_status;
 
-	return mmc_cim_read_write_block;
+	if (g_mmc_mode)
+		return mmc_cim_read_write_block_new;
+	else
+		return mmc_cim_read_write_block;
 }
 
 /******************************************************************
@@ -295,18 +443,18 @@
 
 	switch (dev->request.cmd) {
 	case MMC_GO_IDLE_STATE: /* No response to parse */
-	        MMC_DEBUG(0,"==> MMC_GO_IDLE_STATE");
+	        MMC_DEBUG(1,"==> MMC_GO_IDLE_STATE");
 		if ( (dev->sdrive->flags & MMC_SDFLAG_VOLTAGE )) {
 			MMC_DEBUG(0,"error - current driver doesn't do OCR");
 		}
-		MMC_DEBUG(0,"==> before sending MMC_APP_CMD ");
+		MMC_DEBUG(1,"==> before sending MMC_APP_CMD ");
 		mmc_simple_cmd(dev, MMC_APP_CMD, 0, RESPONSE_R1);
-		MMC_DEBUG(0,"==> after sending MMC_APP_CMD ");
-	        MMC_DEBUG(0,"<== MMC_GO_IDLE_STATE");
+		MMC_DEBUG(1,"==> after sending MMC_APP_CMD ");
+	        MMC_DEBUG(1,"<== MMC_GO_IDLE_STATE");
 		break;
 
 	case MMC_APP_CMD:
-	        MMC_DEBUG(0,"==> MMC_APP_CMD ");
+	        MMC_DEBUG(1,"==> MMC_APP_CMD ");
 		retval = mmc_unpack_r1(&dev->request,&r1,slot->state);
 		if ( retval ) {
 			MMC_DEBUG(0,"failed MMC_APP_CMD error=%d (%s)", 
@@ -317,11 +465,11 @@
 			break;
 		}
 		mmc_simple_cmd(dev, SD_APP_OP_COND, dev->sdrive->ocr, RESPONSE_R3);
-	        MMC_DEBUG(0,"<== MMC_APP_CMD ");
+	        MMC_DEBUG(1,"<== MMC_APP_CMD ");
 		break;
 
 	case SD_APP_OP_COND:
-		MMC_DEBUG(0,"==> SD_APP_OP_COND ");
+		MMC_DEBUG(1,"==> SD_APP_OP_COND ");
 		retval = mmc_unpack_r3(&dev->request, &r3);
 		if ( retval ) {
 		   MMC_DEBUG(0,"failed SD_APP_OP_COND error=%d (%s) - could be MMC card", 
@@ -330,29 +478,29 @@
 		     mmc_simple_cmd(dev, MMC_SEND_OP_COND, 0x00ffc000, RESPONSE_R3);
 		}
 	       	else {
-		   MMC_DEBUG(0,"==> SD_APP_OP_COND 1");
+		   MMC_DEBUG(1,"==> SD_APP_OP_COND 1");
 		   MMC_DEBUG(2,"read ocr value = 0x%08x", r3.ocr);
 
 		   if (!(r3.ocr & MMC_CARD_BUSY)) {
-		      MMC_DEBUG(0,"==> SD_APP_OP_COND / card is busy wait until retry => resend ");
+		      MMC_DEBUG(1,"==> SD_APP_OP_COND / card is busy wait until retry => resend ");
 		      /* Need to add an time (or loop limit) */
 		      dev->sdrive->ocr = r3.ocr;
 		      mmc_simple_cmd(dev, MMC_APP_CMD, 0, RESPONSE_R3);
 		   }
 		   else {
-		      MMC_DEBUG(0,"==> SD_APP_OP_COND / CARD_STATE_READY ");
+		      MMC_DEBUG(1,"==> SD_APP_OP_COND / CARD_STATE_READY ");
 		      /* This seems to be a sd card */
 		      slot->flags |= MMC_SLOT_FLAG_SDCARD;
 		      slot->state = CARD_STATE_READY;
 		      mmc_simple_cmd(dev, MMC_ALL_SEND_CID, 0, RESPONSE_R2_CID);
-		      MMC_DEBUG(0,"==> MMC_ALL_SEND_CID ");
+		      MMC_DEBUG(1,"==> MMC_ALL_SEND_CID ");
 		   }
 		}
-	        MMC_DEBUG(0,"<== SD_APP_OP_COND ");
+	        MMC_DEBUG(1,"<== SD_APP_OP_COND ");
 		break;
 
 	case MMC_SEND_OP_COND:
-	        MMC_DEBUG(0,"==> MMC_SEND_OP_COND ");
+	        MMC_DEBUG(1,"==> MMC_SEND_OP_COND ");
 		retval = mmc_unpack_r3(&dev->request, &r3);
 		if ( retval ) {
 			MMC_DEBUG(0,"failed MMC_SEND_OP_COND error=%d (%s) - could be SD card but sdcard init failed. Aborting!", 
@@ -362,18 +510,18 @@
 
 		MMC_DEBUG(2,"read ocr value = 0x%08x", r3.ocr);
 		if (!(r3.ocr & MMC_CARD_BUSY)) {
-		   MMC_DEBUG(0,"    MMC_SEND_OP_COND Busy retrying ...");
+		   MMC_DEBUG(1,"    MMC_SEND_OP_COND Busy retrying ...");
 			mmc_simple_cmd(dev, MMC_SEND_OP_COND, dev->sdrive->ocr, RESPONSE_R3);
 		}
 		else {
 			slot->state = CARD_STATE_READY;
 			mmc_simple_cmd(dev, MMC_ALL_SEND_CID, 0, RESPONSE_R2_CID);
 		}
-	        MMC_DEBUG(0,"<== MMC_SEND_OP_COND ");
+	        MMC_DEBUG(1,"<== MMC_SEND_OP_COND ");
 		break;
 		
 	case MMC_ALL_SEND_CID: 
-	        MMC_DEBUG(0,"==> MMC_ALL_SEND_CID ()");
+	        MMC_DEBUG(1,"==> MMC_ALL_SEND_CID ()");
 
 		if (slot->flags & MMC_SLOT_FLAG_SDCARD)
 		  retval = mmc_unpack_cid_sd( &dev->request, &slot->cid );
@@ -386,11 +534,11 @@
 		}
 		slot->state = CARD_STATE_IDENT;
 		mmc_simple_cmd(dev, MMC_SET_RELATIVE_ADDR, ID_TO_RCA(slot->id) << 16, RESPONSE_R1);
-	        MMC_DEBUG(0,"<== MMC_ALL_SEND_CID ()");
+	        MMC_DEBUG(1,"<== MMC_ALL_SEND_CID ()");
 		break;
 
         case MMC_SET_RELATIVE_ADDR:
-	        MMC_DEBUG(0,"==> MMC_SET_RELATIVE_ADDR ");
+	        MMC_DEBUG(1,"==> MMC_SET_RELATIVE_ADDR ");
 		retval = mmc_unpack_r1(&dev->request,&r1,slot->state);
 		if ( retval ) {
 			MMC_DEBUG(0, "unable to SET_RELATIVE_ADDR error=%d (%s)", 
@@ -403,11 +551,11 @@
 		  slot->addr = ID_TO_RCA(slot->id) << 16; /* for MMC, this is slot +1  */
 		slot->state = CARD_STATE_STBY;
 		mmc_simple_cmd(dev, MMC_SEND_CSD, slot->addr, RESPONSE_R2_CSD);
-	        MMC_DEBUG(0,"<== MMC_SET_RELATIVE_ADDR ");
+	        MMC_DEBUG(1,"<== MMC_SET_RELATIVE_ADDR ");
 		break;
 
 	case MMC_SEND_CSD:
-	        MMC_DEBUG(0,"<== MMC_SEND_CSD () ");
+	        MMC_DEBUG(1,"<== MMC_SEND_CSD () ");
 		retval = mmc_unpack_csd(&dev->request, &slot->csd);
 		if ( retval ) {
 			MMC_DEBUG(0, "unable to SEND_CSD error=%d (%s)", 
@@ -419,7 +567,7 @@
 			// mmc_simple_cmd(dev, MMC_SET_DSR, 0, RESPONSE_NONE);
 		}
 		mmc_configure_card( dev, 0 );
-	        MMC_DEBUG(0,"==> MMC_SEND_CSD () ");
+	        MMC_DEBUG(1,"==> MMC_SEND_CSD () ");
 		return mmc_cim_default_state;
 
 	default:
