// SPDX-License-Identifier: GPL-2.0+
/*
 * Driver for Realtek PCI-Express card reader
 *
 * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
 *
 * Author:
 *   Wei WANG (wei_wang@realsil.com.cn)
 *   Micky Ching (micky_ching@realsil.com.cn)
 */

#include <linux/blkdev.h>
#include <linux/kthread.h>
#include <linux/sched.h>

#include "rtsx.h"

/***********************************************************************
 * Scatter-gather transfer buffer access routines
 ***********************************************************************/

/*
 * Copy a buffer of length buflen to/from the srb's transfer buffer.
 * (Note: for scatter-gather transfers (srb->use_sg > 0), srb->request_buffer
 * points to a list of s-g entries and we ignore srb->request_bufflen.
 * For non-scatter-gather transfers, srb->request_buffer points to the
 * transfer buffer itself and srb->request_bufflen is the buffer's length.)
 * Update the *index and *offset variables so that the next copy will
 * pick up from where this one left off.
 */

unsigned int rtsx_stor_access_xfer_buf(unsigned char *buffer,
				       unsigned int buflen,
				       struct scsi_cmnd *srb,
				       unsigned int *index,
				       unsigned int *offset,
				       enum xfer_buf_dir dir)
{
	unsigned int cnt;

	/* If not using scatter-gather, just transfer the data directly. */
	if (scsi_sg_count(srb) == 0) {
		unsigned char *sgbuffer;

		if (*offset >= scsi_bufflen(srb))
			return 0;
		cnt = min(buflen, scsi_bufflen(srb) - *offset);

		sgbuffer = (unsigned char *)scsi_sglist(srb) + *offset;

		if (dir == TO_XFER_BUF)
			memcpy(sgbuffer, buffer, cnt);
		else
			memcpy(buffer, sgbuffer, cnt);
		*offset += cnt;

	/*
	 * Using scatter-gather.  We have to go through the list one entry
	 * at a time.  Each s-g entry contains some number of pages, and
	 * each page has to be kmap()'ed separately.
	 */
	} else {
		struct scatterlist *sg =
				(struct scatterlist *)scsi_sglist(srb)
				+ *index;

		/*
		 * This loop handles a single s-g list entry, which may
		 * include multiple pages.  Find the initial page structure
		 * and the starting offset within the page, and update
		 * the *offset and *index values for the next loop.
		 */
		cnt = 0;
		while (cnt < buflen && *index < scsi_sg_count(srb)) {
			struct page *page = sg_page(sg) +
					((sg->offset + *offset) >> PAGE_SHIFT);
			unsigned int poff = (sg->offset + *offset) &
					    (PAGE_SIZE - 1);
			unsigned int sglen = sg->length - *offset;

			if (sglen > buflen - cnt) {
				/* Transfer ends within this s-g entry */
				sglen = buflen - cnt;
				*offset += sglen;
			} else {
				/* Transfer continues to next s-g entry */
				*offset = 0;
				++*index;
				++sg;
			}

			while (sglen > 0) {
				unsigned int plen = min(sglen, (unsigned int)
						PAGE_SIZE - poff);
				unsigned char *ptr = kmap(page);

				if (dir == TO_XFER_BUF)
					memcpy(ptr + poff, buffer + cnt, plen);
				else
					memcpy(buffer + cnt, ptr + poff, plen);
				kunmap(page);

				/* Start at the beginning of the next page */
				poff = 0;
				++page;
				cnt += plen;
				sglen -= plen;
			}
		}
	}

	/* Return the amount actually transferred */
	return cnt;
}

/*
 * Store the contents of buffer into srb's transfer buffer and set the
 * SCSI residue.
 */
void rtsx_stor_set_xfer_buf(unsigned char *buffer,
			    unsigned int buflen, struct scsi_cmnd *srb)
{
	unsigned int index = 0, offset = 0;

	rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset,
				  TO_XFER_BUF);
	if (buflen < scsi_bufflen(srb))
		scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
}

void rtsx_stor_get_xfer_buf(unsigned char *buffer,
			    unsigned int buflen, struct scsi_cmnd *srb)
{
	unsigned int index = 0, offset = 0;

	rtsx_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset,
				  FROM_XFER_BUF);
	if (buflen < scsi_bufflen(srb))
		scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
}

/***********************************************************************
 * Transport routines
 ***********************************************************************/

/*
 * Invoke the transport and basic error-handling/recovery methods
 *
 * This is used to send the message to the device and receive the response.
 */
void rtsx_invoke_transport(struct scsi_cmnd *srb, struct rtsx_chip *chip)
{
	int result;

	result = rtsx_scsi_handler(srb, chip);

	/*
	 * if the command gets aborted by the higher layers, we need to
	 * short-circuit all other processing.
	 */
	if (rtsx_chk_stat(chip, RTSX_STAT_ABORT)) {
		dev_dbg(rtsx_dev(chip), "-- command was aborted\n");
		srb->result = DID_ABORT << 16;
		goto handle_errors;
	}

	/* if there is a transport error, reset and don't auto-sense */
	if (result == TRANSPORT_ERROR) {
		dev_dbg(rtsx_dev(chip), "-- transport indicates error, resetting\n");
		srb->result = DID_ERROR << 16;
		goto handle_errors;
	}

	srb->result = SAM_STAT_GOOD;

	/*
	 * If we have a failure, we're going to do a REQUEST_SENSE
	 * automatically.  Note that we differentiate between a command
	 * "failure" and an "error" in the transport mechanism.
	 */
	if (result == TRANSPORT_FAILED) {
		/* set the result so the higher layers expect this data */
		srb->result = SAM_STAT_CHECK_CONDITION;
		memcpy(srb->sense_buffer,
		       (unsigned char *)&chip->sense_buffer[SCSI_LUN(srb)],
		       sizeof(struct sense_data_t));
	}

	return;

handle_errors:
	return;
}

void rtsx_add_cmd(struct rtsx_chip *chip,
		  u8 cmd_type, u16 reg_addr, u8 mask, u8 data)
{
	__le32 *cb = (__le32 *)(chip->host_cmds_ptr);
	u32 val = 0;

	val |= (u32)(cmd_type & 0x03) << 30;
	val |= (u32)(reg_addr & 0x3FFF) << 16;
	val |= (u32)mask << 8;
	val |= (u32)data;

	spin_lock_irq(&chip->rtsx->reg_lock);
	if (chip->ci < (HOST_CMDS_BUF_LEN / 4))
		cb[(chip->ci)++] = cpu_to_le32(val);

	spin_unlock_irq(&chip->rtsx->reg_lock);
}

void rtsx_send_cmd_no_wait(struct rtsx_chip *chip)
{
	u32 val = BIT(31);

	rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr);

	val |= (u32)(chip->ci * 4) & 0x00FFFFFF;
	/* Hardware Auto Response */
	val |= 0x40000000;
	rtsx_writel(chip, RTSX_HCBCTLR, val);
}

int rtsx_send_cmd(struct rtsx_chip *chip, u8 card, int timeout)
{
	struct rtsx_dev *rtsx = chip->rtsx;
	struct completion trans_done;
	u32 val = BIT(31);
	long timeleft;
	int err = 0;

	if (card == SD_CARD)
		rtsx->check_card_cd = SD_EXIST;
	else if (card == MS_CARD)
		rtsx->check_card_cd = MS_EXIST;
	else if (card == XD_CARD)
		rtsx->check_card_cd = XD_EXIST;
	else
		rtsx->check_card_cd = 0;

	spin_lock_irq(&rtsx->reg_lock);

	/* set up data structures for the wakeup system */
	rtsx->done = &trans_done;
	rtsx->trans_result = TRANS_NOT_READY;
	init_completion(&trans_done);
	rtsx->trans_state = STATE_TRANS_CMD;

	rtsx_writel(chip, RTSX_HCBAR, chip->host_cmds_addr);

	val |= (u32)(chip->ci * 4) & 0x00FFFFFF;
	/* Hardware Auto Response */
	val |= 0x40000000;
	rtsx_writel(chip, RTSX_HCBCTLR, val);

	spin_unlock_irq(&rtsx->reg_lock);

	/* Wait for TRANS_OK_INT */
	timeleft = wait_for_completion_interruptible_timeout(&trans_done,
							     msecs_to_jiffies(timeout));
	if (timeleft <= 0) {
		dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n",
			chip->int_reg);
		err = -ETIMEDOUT;
		goto finish_send_cmd;
	}

	spin_lock_irq(&rtsx->reg_lock);
	if (rtsx->trans_result == TRANS_RESULT_FAIL)
		err = -EIO;
	else if (rtsx->trans_result == TRANS_RESULT_OK)
		err = 0;

	spin_unlock_irq(&rtsx->reg_lock);

finish_send_cmd:
	rtsx->done = NULL;
	rtsx->trans_state = STATE_TRANS_NONE;

	if (err < 0)
		rtsx_stop_cmd(chip, card);

	return err;
}

static inline void rtsx_add_sg_tbl(struct rtsx_chip *chip,
				   u32 addr, u32 len, u8 option)
{
	__le64 *sgb = (__le64 *)(chip->host_sg_tbl_ptr);
	u64 val = 0;
	u32 temp_len = 0;
	u8  temp_opt = 0;

	do {
		if (len > 0x80000) {
			temp_len = 0x80000;
			temp_opt = option & (~RTSX_SG_END);
		} else {
			temp_len = len;
			temp_opt = option;
		}
		val = ((u64)addr << 32) | ((u64)temp_len << 12) | temp_opt;

		if (chip->sgi < (HOST_SG_TBL_BUF_LEN / 8))
			sgb[(chip->sgi)++] = cpu_to_le64(val);

		len -= temp_len;
		addr += temp_len;
	} while (len);
}

static int rtsx_transfer_sglist_adma_partial(struct rtsx_chip *chip, u8 card,
					     struct scatterlist *sg, int num_sg,
					     unsigned int *index,
					     unsigned int *offset, int size,
					     enum dma_data_direction dma_dir,
					     int timeout)
{
	struct rtsx_dev *rtsx = chip->rtsx;
	struct completion trans_done;
	u8 dir;
	int sg_cnt, i, resid;
	int err = 0;
	long timeleft;
	struct scatterlist *sg_ptr;
	u32 val = TRIG_DMA;

	if (!sg || (num_sg <= 0) || !offset || !index)
		return -EIO;

	if (dma_dir == DMA_TO_DEVICE)
		dir = HOST_TO_DEVICE;
	else if (dma_dir == DMA_FROM_DEVICE)
		dir = DEVICE_TO_HOST;
	else
		return -ENXIO;

	if (card == SD_CARD)
		rtsx->check_card_cd = SD_EXIST;
	else if (card == MS_CARD)
		rtsx->check_card_cd = MS_EXIST;
	else if (card == XD_CARD)
		rtsx->check_card_cd = XD_EXIST;
	else
		rtsx->check_card_cd = 0;

	spin_lock_irq(&rtsx->reg_lock);

	/* set up data structures for the wakeup system */
	rtsx->done = &trans_done;

	rtsx->trans_state = STATE_TRANS_SG;
	rtsx->trans_result = TRANS_NOT_READY;

	spin_unlock_irq(&rtsx->reg_lock);

	sg_cnt = dma_map_sg(&rtsx->pci->dev, sg, num_sg, dma_dir);

	resid = size;
	sg_ptr = sg;
	chip->sgi = 0;
	/*
	 * Usually the next entry will be @sg@ + 1, but if this sg element
	 * is part of a chained scatterlist, it could jump to the start of
	 * a new scatterlist array. So here we use sg_next to move to
	 * the proper sg.
	 */
	for (i = 0; i < *index; i++)
		sg_ptr = sg_next(sg_ptr);
	for (i = *index; i < sg_cnt; i++) {
		dma_addr_t addr;
		unsigned int len;
		u8 option;

		addr = sg_dma_address(sg_ptr);
		len = sg_dma_len(sg_ptr);

		dev_dbg(rtsx_dev(chip), "DMA addr: 0x%x, Len: 0x%x\n",
			(unsigned int)addr, len);
		dev_dbg(rtsx_dev(chip), "*index = %d, *offset = %d\n",
			*index, *offset);

		addr += *offset;

		if ((len - *offset) > resid) {
			*offset += resid;
			len = resid;
			resid = 0;
		} else {
			resid -= (len - *offset);
			len -= *offset;
			*offset = 0;
			*index = *index + 1;
		}
		option = RTSX_SG_VALID | RTSX_SG_TRANS_DATA;
		if ((i == sg_cnt - 1) || !resid)
			option |= RTSX_SG_END;

		rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option);

		if (!resid)
			break;

		sg_ptr = sg_next(sg_ptr);
	}

	dev_dbg(rtsx_dev(chip), "SG table count = %d\n", chip->sgi);

	val |= (u32)(dir & 0x01) << 29;
	val |= ADMA_MODE;

	spin_lock_irq(&rtsx->reg_lock);

	init_completion(&trans_done);

	rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr);
	rtsx_writel(chip, RTSX_HDBCTLR, val);

	spin_unlock_irq(&rtsx->reg_lock);

	timeleft = wait_for_completion_interruptible_timeout(&trans_done,
							     msecs_to_jiffies(timeout));
	if (timeleft <= 0) {
		dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
			__func__, __LINE__);
		dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n",
			chip->int_reg);
		err = -ETIMEDOUT;
		goto out;
	}

	spin_lock_irq(&rtsx->reg_lock);
	if (rtsx->trans_result == TRANS_RESULT_FAIL) {
		err = -EIO;
		spin_unlock_irq(&rtsx->reg_lock);
		goto out;
	}
	spin_unlock_irq(&rtsx->reg_lock);

	/* Wait for TRANS_OK_INT */
	spin_lock_irq(&rtsx->reg_lock);
	if (rtsx->trans_result == TRANS_NOT_READY) {
		init_completion(&trans_done);
		spin_unlock_irq(&rtsx->reg_lock);
		timeleft = wait_for_completion_interruptible_timeout(&trans_done,
								     msecs_to_jiffies(timeout));
		if (timeleft <= 0) {
			dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
				__func__, __LINE__);
			dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n",
				chip->int_reg);
			err = -ETIMEDOUT;
			goto out;
		}
	} else {
		spin_unlock_irq(&rtsx->reg_lock);
	}

	spin_lock_irq(&rtsx->reg_lock);
	if (rtsx->trans_result == TRANS_RESULT_FAIL)
		err = -EIO;
	else if (rtsx->trans_result == TRANS_RESULT_OK)
		err = 0;

	spin_unlock_irq(&rtsx->reg_lock);

out:
	rtsx->done = NULL;
	rtsx->trans_state = STATE_TRANS_NONE;
	dma_unmap_sg(&rtsx->pci->dev, sg, num_sg, dma_dir);

	if (err < 0)
		rtsx_stop_cmd(chip, card);

	return err;
}

static int rtsx_transfer_sglist_adma(struct rtsx_chip *chip, u8 card,
				     struct scatterlist *sg, int num_sg,
				     enum dma_data_direction dma_dir,
				     int timeout)
{
	struct rtsx_dev *rtsx = chip->rtsx;
	struct completion trans_done;
	u8 dir;
	int buf_cnt, i;
	int err = 0;
	long timeleft;
	struct scatterlist *sg_ptr;

	if (!sg || (num_sg <= 0))
		return -EIO;

	if (dma_dir == DMA_TO_DEVICE)
		dir = HOST_TO_DEVICE;
	else if (dma_dir == DMA_FROM_DEVICE)
		dir = DEVICE_TO_HOST;
	else
		return -ENXIO;

	if (card == SD_CARD)
		rtsx->check_card_cd = SD_EXIST;
	else if (card == MS_CARD)
		rtsx->check_card_cd = MS_EXIST;
	else if (card == XD_CARD)
		rtsx->check_card_cd = XD_EXIST;
	else
		rtsx->check_card_cd = 0;

	spin_lock_irq(&rtsx->reg_lock);

	/* set up data structures for the wakeup system */
	rtsx->done = &trans_done;

	rtsx->trans_state = STATE_TRANS_SG;
	rtsx->trans_result = TRANS_NOT_READY;

	spin_unlock_irq(&rtsx->reg_lock);

	buf_cnt = dma_map_sg(&rtsx->pci->dev, sg, num_sg, dma_dir);

	sg_ptr = sg;

	for (i = 0; i <= buf_cnt / (HOST_SG_TBL_BUF_LEN / 8); i++) {
		u32 val = TRIG_DMA;
		int sg_cnt, j;

		if (i == buf_cnt / (HOST_SG_TBL_BUF_LEN / 8))
			sg_cnt = buf_cnt % (HOST_SG_TBL_BUF_LEN / 8);
		else
			sg_cnt = HOST_SG_TBL_BUF_LEN / 8;

		chip->sgi = 0;
		for (j = 0; j < sg_cnt; j++) {
			dma_addr_t addr = sg_dma_address(sg_ptr);
			unsigned int len = sg_dma_len(sg_ptr);
			u8 option;

			dev_dbg(rtsx_dev(chip), "DMA addr: 0x%x, Len: 0x%x\n",
				(unsigned int)addr, len);

			option = RTSX_SG_VALID | RTSX_SG_TRANS_DATA;
			if (j == (sg_cnt - 1))
				option |= RTSX_SG_END;

			rtsx_add_sg_tbl(chip, (u32)addr, (u32)len, option);

			sg_ptr = sg_next(sg_ptr);
		}

		dev_dbg(rtsx_dev(chip), "SG table count = %d\n", chip->sgi);

		val |= (u32)(dir & 0x01) << 29;
		val |= ADMA_MODE;

		spin_lock_irq(&rtsx->reg_lock);

		init_completion(&trans_done);

		rtsx_writel(chip, RTSX_HDBAR, chip->host_sg_tbl_addr);
		rtsx_writel(chip, RTSX_HDBCTLR, val);

		spin_unlock_irq(&rtsx->reg_lock);

		timeleft = wait_for_completion_interruptible_timeout(&trans_done,
								     msecs_to_jiffies(timeout));
		if (timeleft <= 0) {
			dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
				__func__, __LINE__);
			dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n",
				chip->int_reg);
			err = -ETIMEDOUT;
			goto out;
		}

		spin_lock_irq(&rtsx->reg_lock);
		if (rtsx->trans_result == TRANS_RESULT_FAIL) {
			err = -EIO;
			spin_unlock_irq(&rtsx->reg_lock);
			goto out;
		}
		spin_unlock_irq(&rtsx->reg_lock);

		sg_ptr += sg_cnt;
	}

	/* Wait for TRANS_OK_INT */
	spin_lock_irq(&rtsx->reg_lock);
	if (rtsx->trans_result == TRANS_NOT_READY) {
		init_completion(&trans_done);
		spin_unlock_irq(&rtsx->reg_lock);
		timeleft = wait_for_completion_interruptible_timeout(&trans_done,
								     msecs_to_jiffies(timeout));
		if (timeleft <= 0) {
			dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
				__func__, __LINE__);
			dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n",
				chip->int_reg);
			err = -ETIMEDOUT;
			goto out;
		}
	} else {
		spin_unlock_irq(&rtsx->reg_lock);
	}

	spin_lock_irq(&rtsx->reg_lock);
	if (rtsx->trans_result == TRANS_RESULT_FAIL)
		err = -EIO;
	else if (rtsx->trans_result == TRANS_RESULT_OK)
		err = 0;

	spin_unlock_irq(&rtsx->reg_lock);

out:
	rtsx->done = NULL;
	rtsx->trans_state = STATE_TRANS_NONE;
	dma_unmap_sg(&rtsx->pci->dev, sg, num_sg, dma_dir);

	if (err < 0)
		rtsx_stop_cmd(chip, card);

	return err;
}

static int rtsx_transfer_buf(struct rtsx_chip *chip, u8 card, void *buf,
			     size_t len, enum dma_data_direction dma_dir,
			     int timeout)
{
	struct rtsx_dev *rtsx = chip->rtsx;
	struct completion trans_done;
	dma_addr_t addr;
	u8 dir;
	int err = 0;
	u32 val = BIT(31);
	long timeleft;

	if (!buf || (len <= 0))
		return -EIO;

	if (dma_dir == DMA_TO_DEVICE)
		dir = HOST_TO_DEVICE;
	else if (dma_dir == DMA_FROM_DEVICE)
		dir = DEVICE_TO_HOST;
	else
		return -ENXIO;

	addr = dma_map_single(&rtsx->pci->dev, buf, len, dma_dir);
	if (dma_mapping_error(&rtsx->pci->dev, addr))
		return -ENOMEM;

	if (card == SD_CARD)
		rtsx->check_card_cd = SD_EXIST;
	else if (card == MS_CARD)
		rtsx->check_card_cd = MS_EXIST;
	else if (card == XD_CARD)
		rtsx->check_card_cd = XD_EXIST;
	else
		rtsx->check_card_cd = 0;

	val |= (u32)(dir & 0x01) << 29;
	val |= (u32)(len & 0x00FFFFFF);

	spin_lock_irq(&rtsx->reg_lock);

	/* set up data structures for the wakeup system */
	rtsx->done = &trans_done;

	init_completion(&trans_done);

	rtsx->trans_state = STATE_TRANS_BUF;
	rtsx->trans_result = TRANS_NOT_READY;

	rtsx_writel(chip, RTSX_HDBAR, addr);
	rtsx_writel(chip, RTSX_HDBCTLR, val);

	spin_unlock_irq(&rtsx->reg_lock);

	/* Wait for TRANS_OK_INT */
	timeleft = wait_for_completion_interruptible_timeout(&trans_done,
							     msecs_to_jiffies(timeout));
	if (timeleft <= 0) {
		dev_dbg(rtsx_dev(chip), "Timeout (%s %d)\n",
			__func__, __LINE__);
		dev_dbg(rtsx_dev(chip), "chip->int_reg = 0x%x\n",
			chip->int_reg);
		err = -ETIMEDOUT;
		goto out;
	}

	spin_lock_irq(&rtsx->reg_lock);
	if (rtsx->trans_result == TRANS_RESULT_FAIL)
		err = -EIO;
	else if (rtsx->trans_result == TRANS_RESULT_OK)
		err = 0;

	spin_unlock_irq(&rtsx->reg_lock);

out:
	rtsx->done = NULL;
	rtsx->trans_state = STATE_TRANS_NONE;
	dma_unmap_single(&rtsx->pci->dev, addr, len, dma_dir);

	if (err < 0)
		rtsx_stop_cmd(chip, card);

	return err;
}

int rtsx_transfer_data_partial(struct rtsx_chip *chip, u8 card,
			       void *buf, size_t len, int use_sg,
			       unsigned int *index, unsigned int *offset,
			       enum dma_data_direction dma_dir, int timeout)
{
	int err = 0;

	/* don't transfer data during abort processing */
	if (rtsx_chk_stat(chip, RTSX_STAT_ABORT))
		return -EIO;

	if (use_sg) {
		struct scatterlist *sg = buf;

		err = rtsx_transfer_sglist_adma_partial(chip, card, sg, use_sg,
							index, offset, (int)len,
							dma_dir, timeout);
	} else {
		err = rtsx_transfer_buf(chip, card,
					buf, len, dma_dir, timeout);
	}
	if (err < 0) {
		if (RTSX_TST_DELINK(chip)) {
			RTSX_CLR_DELINK(chip);
			chip->need_reinit = SD_CARD | MS_CARD | XD_CARD;
			rtsx_reinit_cards(chip, 1);
		}
	}

	return err;
}

int rtsx_transfer_data(struct rtsx_chip *chip, u8 card, void *buf, size_t len,
		       int use_sg, enum dma_data_direction dma_dir, int timeout)
{
	int err = 0;

	dev_dbg(rtsx_dev(chip), "use_sg = %d\n", use_sg);

	/* don't transfer data during abort processing */
	if (rtsx_chk_stat(chip, RTSX_STAT_ABORT))
		return -EIO;

	if (use_sg) {
		err = rtsx_transfer_sglist_adma(chip, card, buf,
						use_sg, dma_dir, timeout);
	} else {
		err = rtsx_transfer_buf(chip, card, buf, len, dma_dir, timeout);
	}

	if (err < 0) {
		if (RTSX_TST_DELINK(chip)) {
			RTSX_CLR_DELINK(chip);
			chip->need_reinit = SD_CARD | MS_CARD | XD_CARD;
			rtsx_reinit_cards(chip, 1);
		}
	}

	return err;
}

