public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] memstick: rtsx: fix ms card data transfer bug
@ 2013-10-30  6:40 micky_ching
  2013-11-05 21:10 ` Andrew Morton
  0 siblings, 1 reply; 5+ messages in thread
From: micky_ching @ 2013-10-30  6:40 UTC (permalink / raw)
  To: devel, linux-kernel
  Cc: sameo, maximlevitsky, gregkh, rogerable, oakad, wei_wang,
	Micky Ching

From: Micky Ching <micky_ching@realsil.com.cn>

unlike mspro card, ms card use normal read/write mode for DMA
data transfer.

Signed-off-by: Micky Ching <micky_ching@realsil.com.cn>
---
 drivers/memstick/host/rtsx_pci_ms.c |   87 ++++++++++++++++++++++++++++++++---
 1 file changed, 81 insertions(+), 6 deletions(-)

diff --git a/drivers/memstick/host/rtsx_pci_ms.c b/drivers/memstick/host/rtsx_pci_ms.c
index 25f8f93..95eb208 100644
--- a/drivers/memstick/host/rtsx_pci_ms.c
+++ b/drivers/memstick/host/rtsx_pci_ms.c
@@ -137,8 +137,9 @@ static int ms_power_off(struct realtek_pci_ms *host)
 	return rtsx_pci_card_pull_ctl_disable(pcr, RTSX_MS_CARD);
 }
 
-static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir,
-		u8 tpc, u8 cfg, struct scatterlist *sg)
+static int mspro_transfer_data(struct realtek_pci_ms *host,
+			unsigned char data_dir, u8 tpc, u8 cfg,
+			struct scatterlist *sg)
 {
 	struct rtsx_pcr *pcr = host->pcr;
 	int err;
@@ -198,6 +199,77 @@ static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir,
 	return 0;
 }
 
+static int ms_transfer_data(struct realtek_pci_ms *host,
+			unsigned char data_dir, u8 tpc, u8 cfg,
+			struct scatterlist *sg)
+{
+	struct rtsx_pcr *pcr = host->pcr;
+	int err;
+	unsigned int length = sg->length;
+	u8 val, trans_mode, dma_dir;
+	struct completion trans_done;
+	int timeleft;
+
+	dev_dbg(ms_dev(host), "%s: tpc = 0x%02x, data_dir = %s, length = %d\n",
+			__func__, tpc, (data_dir == READ) ? "READ" : "WRITE",
+			length);
+
+	if (data_dir == READ) {
+		dma_dir = DMA_DIR_FROM_CARD;
+		trans_mode = MS_TM_NORMAL_READ;
+	} else {
+		dma_dir = DMA_DIR_TO_CARD;
+		trans_mode = MS_TM_NORMAL_WRITE;
+	}
+
+	rtsx_pci_init_cmd(pcr);
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0,
+			DMA_DONE_INT, DMA_DONE_INT);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC3, 0xFF, (u8)(length >> 24));
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC2, 0xFF, (u8)(length >> 16));
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC1, 0xFF, (u8)(length >> 8));
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMATC0, 0xFF, (u8)length);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, DMACTL,
+			0x03 | DMA_PACK_SIZE_MASK, dma_dir | DMA_EN | DMA_512);
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_DATA_SOURCE,
+			0x01, RING_BUFFER);
+
+	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANSFER,
+			0xFF, MS_TRANSFER_START | trans_mode);
+	rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, MS_TRANSFER,
+			MS_TRANSFER_END, MS_TRANSFER_END);
+
+	rtsx_pci_send_cmd_no_wait(pcr);
+
+	err = rtsx_pci_transfer_data(pcr, sg, 1, data_dir == READ, 10000);
+	if (err < 0) {
+		ms_print_debug_regs(host);
+		ms_clear_error(host);
+		return err;
+	}
+
+	if (pcr->trans_result == TRANS_NOT_READY) {
+		init_completion(&trans_done);
+		timeleft = wait_for_completion_interruptible_timeout(
+			&trans_done, 1000);
+		if (timeleft < 0) {
+			dev_dbg(ms_dev(host),
+				"%s: timeout wait for ok interrupt.\n",
+				__func__);
+			return -ETIMEDOUT;
+		}
+	}
+	rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val);
+	if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT))
+		return -EIO;
+
+	return 0;
+}
+
 static int ms_write_bytes(struct realtek_pci_ms *host, u8 tpc,
 		u8 cfg, u8 cnt, u8 *data, u8 *int_reg)
 {
@@ -340,6 +412,7 @@ static int ms_read_bytes(struct realtek_pci_ms *host, u8 tpc,
 static int rtsx_pci_ms_issue_cmd(struct realtek_pci_ms *host)
 {
 	struct memstick_request *req = host->req;
+	struct memstick_dev *card = host->msh->card;
 	int err = 0;
 	u8 cfg = 0, int_reg;
 
@@ -350,9 +423,12 @@ static int rtsx_pci_ms_issue_cmd(struct realtek_pci_ms *host)
 			cfg = WAIT_INT;
 	}
 
-	if (req->long_data) {
+	if (req->long_data && card->id.type != MEMSTICK_TYPE_PRO) {
 		err = ms_transfer_data(host, req->data_dir,
 				req->tpc, cfg, &(req->sg));
+	} else if (req->long_data) {
+		err = mspro_transfer_data(host, req->data_dir,
+				req->tpc, cfg, &(req->sg));
 	} else {
 		if (req->data_dir == READ) {
 			err = ms_read_bytes(host, req->tpc, cfg,
@@ -461,9 +537,8 @@ static int rtsx_pci_ms_set_param(struct memstick_host *msh,
 		if (value == MEMSTICK_SERIAL) {
 			clock = 19000000;
 			ssc_depth = RTSX_SSC_DEPTH_500K;
-
-			err = rtsx_pci_write_register(pcr, MS_CFG,
-					0x18, MS_BUS_WIDTH_1);
+			err = rtsx_pci_write_register(pcr, MS_CFG, 0x58,
+					MS_BUS_WIDTH_1 | PUSH_TIME_DEFAULT);
 			if (err < 0)
 				return err;
 		} else if (value == MEMSTICK_PAR4) {
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 5+ messages in thread
* [PATCH] memstick: rtsx: fix ms card data transfer bug
@ 2013-11-07  3:18 micky_ching
  0 siblings, 0 replies; 5+ messages in thread
From: micky_ching @ 2013-11-07  3:18 UTC (permalink / raw)
  To: devel, linux-kernel
  Cc: sameo, maximlevitsky, gregkh, rogerable, oakad, wei_wang,
	Micky Ching

From: Micky Ching <micky_ching@realsil.com.cn>

This patch is used to add support for ms card. The main difference
between ms card and mspro card is long data transfer mode. mspro card
can use auto mode DMA for long data transfer, but ms can not use this
mode, it should use normal mode DMA.

The memstick core add support for ms card, but the original driver will
make ms card fail at initialize, because it use auto mode DMA. This
patch can make ms card work properly.

Signed-off-by: Micky Ching <micky_ching@realsil.com.cn>
---
 drivers/memstick/host/rtsx_pci_ms.c |   30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/memstick/host/rtsx_pci_ms.c b/drivers/memstick/host/rtsx_pci_ms.c
index 25f8f93..2a635b6 100644
--- a/drivers/memstick/host/rtsx_pci_ms.c
+++ b/drivers/memstick/host/rtsx_pci_ms.c
@@ -145,6 +145,8 @@ static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir,
 	unsigned int length = sg->length;
 	u16 sec_cnt = (u16)(length / 512);
 	u8 val, trans_mode, dma_dir;
+	struct memstick_dev *card = host->msh->card;
+	bool pro_card = card->id.type == MEMSTICK_TYPE_PRO;
 
 	dev_dbg(ms_dev(host), "%s: tpc = 0x%02x, data_dir = %s, length = %d\n",
 			__func__, tpc, (data_dir == READ) ? "READ" : "WRITE",
@@ -152,19 +154,21 @@ static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir,
 
 	if (data_dir == READ) {
 		dma_dir = DMA_DIR_FROM_CARD;
-		trans_mode = MS_TM_AUTO_READ;
+		trans_mode = pro_card ? MS_TM_AUTO_READ : MS_TM_NORMAL_READ;
 	} else {
 		dma_dir = DMA_DIR_TO_CARD;
-		trans_mode = MS_TM_AUTO_WRITE;
+		trans_mode = pro_card ? MS_TM_AUTO_WRITE : MS_TM_NORMAL_WRITE;
 	}
 
 	rtsx_pci_init_cmd(pcr);
 
 	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc);
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_H,
-			0xFF, (u8)(sec_cnt >> 8));
-	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_L,
-			0xFF, (u8)sec_cnt);
+	if (pro_card) {
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_H,
+				0xFF, (u8)(sec_cnt >> 8));
+		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_SECTOR_CNT_L,
+				0xFF, (u8)sec_cnt);
+	}
 	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg);
 
 	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, IRQSTAT0,
@@ -192,8 +196,14 @@ static int ms_transfer_data(struct realtek_pci_ms *host, unsigned char data_dir,
 	}
 
 	rtsx_pci_read_register(pcr, MS_TRANS_CFG, &val);
-	if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT))
-		return -EIO;
+	if (pro_card) {
+		if (val & (MS_INT_CMDNK | MS_INT_ERR |
+				MS_CRC16_ERR | MS_RDY_TIMEOUT))
+			return -EIO;
+	} else {
+		if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT))
+			return -EIO;
+	}
 
 	return 0;
 }
@@ -462,8 +472,8 @@ static int rtsx_pci_ms_set_param(struct memstick_host *msh,
 			clock = 19000000;
 			ssc_depth = RTSX_SSC_DEPTH_500K;
 
-			err = rtsx_pci_write_register(pcr, MS_CFG,
-					0x18, MS_BUS_WIDTH_1);
+			err = rtsx_pci_write_register(pcr, MS_CFG, 0x58,
+					MS_BUS_WIDTH_1 | PUSH_TIME_DEFAULT);
 			if (err < 0)
 				return err;
 		} else if (value == MEMSTICK_PAR4) {
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-11-07  3:17 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-30  6:40 [PATCH] memstick: rtsx: fix ms card data transfer bug micky_ching
2013-11-05 21:10 ` Andrew Morton
2013-11-06  1:14   ` micky
2013-11-06 23:03     ` Andrew Morton
  -- strict thread matches above, loose matches on Subject: below --
2013-11-07  3:18 micky_ching

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox