--- c/ar6000/hif/hif2.c	2009-03-30 01:20:20.000000000 +0400
+++ d/ar6000//hif/hif2.c	2009-03-30 01:11:04.000000000 +0400
@@ -121,14 +121,10 @@
 struct hif_request {
 	struct list_head list;
 	struct sdio_func *func;
-	int (*read)(struct sdio_func *func,
-	    void *dst, unsigned int addr, int count);
-	int (*write)(struct sdio_func *func,
-	    unsigned int addr, void *src, int count);
 	void *buf;
-	unsigned long addr;
-	int len;
-	A_STATUS (*completion)(void *context, A_STATUS status);
+	u32  addr;
+	u32  len;
+	u32  flags;
 	void *context;
 };
 
@@ -144,36 +140,90 @@
 /* ----- Request processing ------------------------------------------------ */
 
 
-static A_STATUS process_request(struct hif_request *req)
+static A_STATUS \
+process_request(struct sdio_func *func, A_UCHAR *buff, A_UINT32 addr,
+                A_UINT32 len, A_UINT32 flags)
 {
-	int ret;
-	A_STATUS status;
+	u32 blksz, blocks, arg;
+	struct hif_device *hif;
+	struct mmc_card *card;
+	struct mmc_host *host;
+	struct {
+		struct mmc_request mrq;
+		struct mmc_command cmd;
+		struct mmc_data data;
+		struct scatterlist sg;
+	} req;
 
-	dev_dbg(&req->func->dev, "process_request(req %p)\n", req);
-	sdio_claim_host(req->func);
-	if (req->read) {
-#ifdef _GTA02_
-		while (!s3c2410_gpio_getpin(S3C2410_GPE7)) {
-			printk(KERN_INFO "READ WHILE BUSY !\n");
-			yield();
-		}
-#endif /* end _GTA02_ */
-		ret = req->read(req->func, req->buf, req->addr, req->len);
+	/*
+	 * Next code based on: 'mmc_io_rw_extended' (mmc/core/sdio_ops.c),
+	 * but have shorten path and send small blocks not in byte mode.
+	 */
+
+	memset(&req, 0, sizeof(req));
+
+	req.mrq.cmd  = &req.cmd;
+	req.mrq.data = &req.data;
+
+	req.cmd.opcode = SD_IO_RW_EXTENDED;
+
+	arg  = (flags & HIF_WRITE) ? 0x80000000 : 0x00000000;
+	arg |= (func->num << 28);
+	arg |= (flags & HIF_INCREMENTAL_ADDRESS) ? 0x04000000 : 0x00000000;
+ 	arg |= (addr << 9);
+
+	if (flags & HIF_BYTE_BASIS) {
+		/* byte mode */
+		blksz  = len;
+		blocks = 1;
+		arg   |= blksz;
 	} else {
+		/* block mode */
+		blksz  = HIF_MBOX_BLOCK_SIZE;
+		blocks = len / HIF_MBOX_BLOCK_SIZE;
+		arg   |= blocks | 0x08000000;
+	}
+
+	req.cmd.arg = arg;
+	req.cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
+
+	req.data.blksz  = blksz;
+	req.data.blocks = blocks;
+	req.data.flags  = (flags & HIF_WRITE) ? MMC_DATA_WRITE : MMC_DATA_READ;
+	req.data.sg     = &req.sg;
+	req.data.sg_len = 1;
+
+	sg_init_one(&req.sg, buff, blksz * blocks);
+
+	card = func->card;
+	host = card->host;
+
+	mmc_set_data_timeout(&req.data, card);
+
+	hif = sdio_get_drvdata(func);
+
+	sdio_claim_host(func);
+
 #ifdef _GTA02_
-		while (!s3c2410_gpio_getpin(S3C2410_GPE7)) {
-			printk(KERN_INFO "WRITE WHILE BUSY !\n");
-			yield();
-		}
+	while (!s3c2410_gpio_getpin(S3C2410_GPE7)) {
+		printk(KERN_INFO "READ/WRITE WHILE BUSY !\n");
+		yield();
 #endif /* end _GTA02_ */
-		ret = req->write(req->func, req->addr, req->buf, req->len);
+
+	mmc_wait_for_req(host, &req.mrq);
+
+	sdio_release_host(func);
+
+	if ((req.cmd.error) || (req.data.error))
+		return A_ERROR;
+
+	if (!(mmc_host_is_spi(host))) {
+		if (req.cmd.resp[0] & (R5_ERROR|R5_FUNCTION_NUMBER|R5_OUT_OF_RANGE)) {
+			return A_ERROR;
+		}
 	}
-	sdio_release_host(req->func);
-	status = ret ? A_ERROR : A_OK;
-	if (req->completion)
-		req->completion(req->context, status);
-	kfree(req);
-	return status;
+
+	return A_OK;
 }
 
 
@@ -254,7 +304,18 @@
 		}
 		finish_wait(&hif->wait, &wait);
 
-		(void) process_request(req);
+		{
+			A_STATUS status;
+			void *context;
+
+			status = process_request(req->func, req->buf, req->addr, 
+			                         req->len, req->flags);
+			context = req->context;
+
+			kfree(req);
+
+			htcCallbacks.rwCompletionHandler(context, status);
+		}
 	}
 	return 0;
 }
@@ -283,38 +344,25 @@
 		address += HIF_MBOX_WIDTH-length;
 	}
 
-	req = kzalloc(sizeof(*req), GFP_ATOMIC);
-	if (!req) {
-		if (request & HIF_ASYNCHRONOUS)
-			htcCallbacks.rwCompletionHandler(context, A_ERROR);
-		return A_ERROR;
+	if (!(request & HIF_ASYNCHRONOUS)) {
+		return process_request(hif->func, buffer, address, length, request);
 	}
 
-	req->func = hif->func;
-	req->addr = address;
-	req->buf = buffer;
-	req->len = length;
-
-	if (request & HIF_READ) {
-		if (request & HIF_FIXED_ADDRESS)
-			req->read = sdio_readsb;
-		else
-			req->read = sdio_memcpy_fromio;
-	} else {
-		if (request & HIF_FIXED_ADDRESS)
-			req->write = sdio_writesb;
-		else
-			req->write = sdio_memcpy_toio;
-	}
+	if ((req = kzalloc(sizeof(*req), GFP_ATOMIC))) {
+		req->func    = hif->func;
+		req->buf     = buffer;
+		req->addr    = address;
+		req->len     = length;
+		req->flags   = request;
+		req->context = context;
 
-	if (!(request & HIF_ASYNCHRONOUS))
-		return process_request(req);
+		enqueue_request(hif, req);
 
-	req->completion = htcCallbacks.rwCompletionHandler;
-	req->context = context;
-	enqueue_request(hif, req);
+		return A_OK;
+	}
 
-	return A_OK;
+	htcCallbacks.rwCompletionHandler(context, A_ERROR);
+	return A_ERROR;
 }
 
 
