mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Oliver Neukum <oliver@neukum.org>
To: wei_wang@realsil.com.cn
Cc: gregkh@linuxfoundation.org, devel@linuxdriverproject.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/3] drivers/misc: Add realtek pci card reader driver
Date: Thu, 19 Jul 2012 14:57:55 +0200	[thread overview]
Message-ID: <1416801.Uc45iJreQi@linux-lqwf.site> (raw)
In-Reply-To: <1342691710-23164-1-git-send-email-wei_wang@realsil.com.cn>

On Thursday 19 July 2012 17:55:10 wei_wang@realsil.com.cn wrote:

> +static int rtsx_pci_transfer_sglist_adma(struct rtsx_pdev *pdev,
> +		struct scatterlist *sg, int num_sg, int read, int timeout)
> +{
> +	struct completion trans_done;
> +	u8 dir;
> +	int buf_cnt, i;
> +	int err = 0;
> +	long timeleft;
> +	unsigned long flags;
> +	struct scatterlist *sg_ptr;
> +	enum dma_data_direction dma_dir;
> +
> +	if ((sg == NULL) || (num_sg <= 0))
> +		return -EINVAL;
> +
> +	if (read) {
> +		dir = DEVICE_TO_HOST;
> +		dma_dir = DMA_FROM_DEVICE;
> +	} else {
> +		dir = HOST_TO_DEVICE;
> +		dma_dir = DMA_TO_DEVICE;
> +	}
> +
> +	spin_lock_irqsave(&pdev->lock, flags);
> +
> +	/* set up data structures for the wakeup system */
> +	pdev->done = &trans_done;
> +	pdev->trans_state = STATE_TRANS_SG;
> +	pdev->trans_result = TRANS_NOT_READY;
> +
> +	spin_unlock_irqrestore(&pdev->lock, flags);
> +
> +	buf_cnt = dma_map_sg(&(pdev->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);
> +
> +		pdev->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;
> +
> +			pr_debug("DMA addr: 0x%x, Len: 0x%x\n",
> +					(unsigned int)addr, len);
> +
> +			if (j == (sg_cnt - 1))
> +				option = SG_VALID | SG_END | SG_TRANS_DATA;
> +			else
> +				option = SG_VALID | SG_TRANS_DATA;
> +
> +			rtsx_pci_add_sg_tbl(pdev, (u32)addr, (u32)len, option);
> +			sg_ptr = sg_next(sg_ptr);
> +		}
> +
> +		pr_debug("SG table count = %d\n", pdev->sgi);
> +
> +		val |= (u32)(dir & 0x01) << 29;
> +		val |= ADMA_MODE;
> +
> +		spin_lock_irqsave(&pdev->lock, flags);
> +
> +		init_completion(&trans_done);
> +
> +		rtsx_pci_writel(pdev, RTSX_HDBAR, pdev->host_sg_tbl_addr);
> +		rtsx_pci_writel(pdev, RTSX_HDBCTLR, val);
> +
> +		spin_unlock_irqrestore(&pdev->lock, flags);
> +
> +		timeleft = wait_for_completion_interruptible_timeout(
> +				&trans_done, msecs_to_jiffies(timeout));
> +		if (timeleft <= 0) {
> +			pr_debug("Timeout (%s %d)\n", __func__, __LINE__);
> +			pr_debug("pdev->int_reg = 0x%x\n", pdev->int_reg);
> +			err = -ETIMEDOUT;
> +			goto out;
> +		}
> +
> +		spin_lock_irqsave(&pdev->lock, flags);
> +		if (pdev->trans_result == TRANS_RESULT_FAIL) {
> +			err = -EINVAL;
> +			spin_unlock_irqrestore(&pdev->lock, flags);
> +			goto out;
> +		} else if (pdev->trans_result == TRANS_NO_DEVICE) {
> +			err = -ENODEV;
> +			spin_unlock_irqrestore(&pdev->lock, flags);
> +			goto out;
> +		}
> +		spin_unlock_irqrestore(&pdev->lock, flags);
> +
> +		sg_ptr += sg_cnt;
> +	}
> +
> +	/* Wait for TRANS_OK_INT */
> +	spin_lock_irqsave(&pdev->lock, flags);
> +	if (pdev->trans_result == TRANS_NOT_READY) {
> +		init_completion(&trans_done);
> +		spin_unlock_irqrestore(&pdev->lock, flags);
> +		timeleft = wait_for_completion_interruptible_timeout(
> +				&trans_done, msecs_to_jiffies(timeout));
> +		if (timeleft <= 0) {
> +			pr_debug("Timeout (%s %d)\n", __func__, __LINE__);
> +			pr_debug("pdev->int_reg = 0x%x\n", pdev->int_reg);
> +			err = -ETIMEDOUT;
> +			goto out;
> +		}
> +	} else {
> +		spin_unlock_irqrestore(&pdev->lock, flags);
> +	}
> +
> +	spin_lock_irqsave(&pdev->lock, flags);

So why drop the lock?

> +	if (pdev->trans_result == TRANS_RESULT_FAIL)
> +		err = -EINVAL;
> +	else if (pdev->trans_result == TRANS_RESULT_OK)
> +		err = 0;
> +	else if (pdev->trans_result == TRANS_NO_DEVICE)
> +		err = -ENODEV;
> +	spin_unlock_irqrestore(&pdev->lock, flags);
> +
> +out:
> +	spin_lock_irqsave(&pdev->lock, flags);
> +	pdev->done = NULL;
> +	pdev->trans_state = STATE_TRANS_NONE;
> +	spin_unlock_irqrestore(&pdev->lock, flags);
> +
> +	dma_unmap_sg(&(pdev->pci->dev), sg, num_sg, dma_dir);

You must not unmap before you stop the hardware

> +	if ((err < 0) && (err != -ENODEV))
> +		rtsx_pci_stop_cmd(pdev);
> +
> +	if (pdev->finish_me)
> +		complete(pdev->finish_me);
> +
> +	return err;
> +}
> +
> +/**
> + * rtsx_pci_transfer_buf - transfer data in linear buffer.
> + * @pdev: Realtek's card reader pdev
> + * @card: this command is relevant to card or not
> + * @buf: data buffer
> + * @len: buffer length
> + * @dma_dir: transfer direction (DMA_FROM_DEVICE or DMA_TO_DEVICE)
> + * @timeout: time out in millisecond

	Regards
		Oliver


  reply	other threads:[~2012-07-19 13:10 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-19  9:55 wei_wang
2012-07-19 12:57 ` Oliver Neukum [this message]
2012-07-20  5:58 ` Rusty Russell
2012-07-23  2:00   ` wwang
2012-07-20 10:09 wei_wang
2012-07-26 13:17 ` Rusty Russell
2012-07-23  9:42 wei_wang
2012-07-23 11:24 ` Borislav Petkov
2012-07-25  3:02 wei_wang
2012-07-26 19:05 ` Bjørn Mork
2012-07-31  7:42 wei_wang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1416801.Uc45iJreQi@linux-lqwf.site \
    --to=oliver@neukum.org \
    --cc=devel@linuxdriverproject.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=wei_wang@realsil.com.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®