linux-i2c.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
To: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Bill Brown <bill.e.brown-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
	Seth Heasley
	<seth.heasley-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Subject: Re: [PATCH v6] i2c: Adding support for Intel iSMT SMBus 2.0 host controller
Date: Mon, 4 Feb 2013 10:47:44 +0100	[thread overview]
Message-ID: <20130204104744.5f83541e@endymion.delvare> (raw)
In-Reply-To: <1359748083-24423-1-git-send-email-nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>

Hi Neil,

On Fri,  1 Feb 2013 14:48:03 -0500, Neil Horman wrote:
> The iSMT (Intel SMBus Message Transport) supports multi-master I2C/SMBus,
> as well as IPMI.  It's operation is DMA-based and utilizes descriptors to
> initiate transactions on the bus.
> 
> The iSMT hardware can act as both a master and a target, although this
> driver only supports being a master.
> 
> Signed-off-by: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
> Signed-off-by: Bill Brown <bill.e.brown-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> Tested-by: Seth Heasley <seth.heasley-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> CC: Seth Heasley <seth.heasley-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> CC: Jean Delvare <khali-PUYAD+kWke1g9hUCZPvPmw@public.gmane.org>
> 
> ---
> General note - Seth had mentioned to me that he was unable to get writes to work
> on his system.  I'm not sure of the details, but I've done some rudimentary
> read/write testing here on my system, and it seems to work well (for the limited
> testing I can do).  Seth if you could please provide details of your testing, or
> give this patch a try, I would appreciate it.

I am still trying to get my hands on a test machine. I am told we have
a few, however they are currently either not setup or reserved.

Until then, a few remaining comments:

> +/**
> + * ismt_gen_reg_dump() - dump the iSMT General Registers
> + * @priv: iSMT private data
> + */
> +static void ismt_gen_reg_dump(struct ismt_priv *priv)
> +{
> +	struct device *dev = &priv->pci_dev->dev;
> +
> +	dev_dbg(dev, "Dump of the iSMT General Registers\n");
> +	dev_dbg(dev, "  GCTRL.... : (0x%p)=0x%X\n",
> +		priv->smba + ISMT_GR_GCTRL,
> +		readl(priv->smba + ISMT_GR_GCTRL));
> +	dev_dbg(dev, "  SMTICL... : (0x%p)=0x%016lX\n",
> +		priv->smba + ISMT_GR_SMTICL,
> +		(long unsigned int)readq(priv->smba + ISMT_GR_SMTICL));

On 32-bit systems, a long unsigned int can only hold 4 bytes, not 8, so
the top 32 bits of the value returned by readq() will be lost. I think
you have to use format 0x%016llX and cast to long long unsigned int.

> +	dev_dbg(dev, "  ERRINTMSK : (0x%p)=0x%X\n",
> +		priv->smba + ISMT_GR_ERRINTMSK,
> +		readl(priv->smba + ISMT_GR_ERRINTMSK));
> +	dev_dbg(dev, "  ERRAERMSK : (0x%p)=0x%X\n",
> +		priv->smba + ISMT_GR_ERRAERMSK,
> +		readl(priv->smba + ISMT_GR_ERRAERMSK));
> +	dev_dbg(dev, "  ERRSTS... : (0x%p)=0x%X\n",
> +		priv->smba + ISMT_GR_ERRSTS,
> +		readl(priv->smba + ISMT_GR_ERRSTS));
> +	dev_dbg(dev, "  ERRINFO.. : (0x%p)=0x%X\n",
> +		priv->smba + ISMT_GR_ERRINFO,
> +		readl(priv->smba + ISMT_GR_ERRINFO));
> +}
> +
> +/**
> + * ismt_mstr_reg_dump() - dump the iSMT Master Registers
> + * @priv: iSMT private data
> + */
> +static void ismt_mstr_reg_dump(struct ismt_priv *priv)
> +{
> +	struct device *dev = &priv->pci_dev->dev;
> +
> +	dev_dbg(dev, "Dump of the iSMT Master Registers\n");
> +	dev_dbg(dev, "  MDBA..... : (0x%p)=0x%016lX\n",
> +		priv->smba + ISMT_MSTR_MDBA,
> +		(long unsigned int)readq(priv->smba + ISMT_MSTR_MDBA));

Same here.

> +	dev_dbg(dev, "  MCTRL.... : (0x%p)=0x%X\n",
> +		priv->smba + ISMT_MSTR_MCTRL,
> +		readl(priv->smba + ISMT_MSTR_MCTRL));
> +	dev_dbg(dev, "  MSTS..... : (0x%p)=0x%X\n",
> +		priv->smba + ISMT_MSTR_MSTS,
> +		readl(priv->smba + ISMT_MSTR_MSTS));
> +	dev_dbg(dev, "  MDS...... : (0x%p)=0x%X\n",
> +		priv->smba + ISMT_MSTR_MDS,
> +		readl(priv->smba + ISMT_MSTR_MDS));
> +	dev_dbg(dev, "  RPOLICY.. : (0x%p)=0x%X\n",
> +		priv->smba + ISMT_MSTR_RPOLICY,
> +		readl(priv->smba + ISMT_MSTR_RPOLICY));
> +	dev_dbg(dev, "  SPGT..... : (0x%p)=0x%X\n",
> +		priv->smba + ISMT_SPGT,
> +		readl(priv->smba + ISMT_SPGT));
> +}

> (...)
> +/**
> + * ismt_process_desc() - handle the completion of the descriptor
> + * @desc: the iSMT hardware descriptor
> + * @data: data buffer from the upper layer
> + * @priv: ismt_priv struct holding our dma buffer
> + * @size: SMBus transaction type
> + * @read_write flag to indicate if this is a read or write

Missing colon after parameter name.

> + * @dma_size size of the dma transfer

This function has no parameter named dma_size.

> + */
> +static int ismt_process_desc(const struct ismt_desc *desc,
> +			     union i2c_smbus_data *data,
> +			     struct ismt_priv *priv, int size,
> +			     char read_write)
> +{
> +	u8 *dma_buffer = priv->dma_buffer;
> +
> +	dev_dbg(&priv->pci_dev->dev, "Processing completed descriptor\n");
> +	__ismt_desc_dump(&priv->pci_dev->dev, desc);
> +
> +	if (desc->status & ISMT_DESC_SCS) {
> +		if ((size != I2C_SMBUS_QUICK) &&
> +		    (read_write == I2C_SMBUS_READ)) {
> +			memcpy(&data->block[1], dma_buffer, desc->rxbytes);
> +			data->block[0] = desc->rxbytes;

This looks good for block reads. But for receive byte, read byte and
read word transactions, this can't be correct. You have to copy the
contents of dma_buffer to data->byte or data->word for these
transactions.

> +		}
> +		return 0;
> +	}
> +
> +	if (likely(desc->status & ISMT_DESC_NAK))
> +		return -ENXIO;
> +
> +	if (desc->status & ISMT_DESC_CRC)
> +		return -EBADMSG;
> +
> +	if (desc->status & ISMT_DESC_COL)
> +		return -EAGAIN;
> +
> +	if (desc->status & ISMT_DESC_LPR)
> +		return -EPROTO;
> +
> +	if (desc->status & (ISMT_DESC_DLTO | ISMT_DESC_CLTO))
> +		return -ETIMEDOUT;
> +
> +	return -EIO;
> +}

> (...)
> +	/* Create a temporary buffer for the DMA transaction */
> +	/* and insert the command at the beginning of the buffer */
> +	if ((read_write == I2C_SMBUS_WRITE) &&
> +	    (size > I2C_SMBUS_BYTE)) {
> +		memcpy(&priv->dma_buffer[1], &data->block[1], dma_size);
> +		priv->dma_buffer[0] = command;
> +	}

Again this looks good for block writes, but not for send byte, write
byte and write word transactions. data->block is only relevant for
block transactions, and &data->block[1] is off by one compared to
&data->byte and &data->word.

We did not discuss it yet but you should also pay attention to
I2C_SMBUS_PROC_CALL. It is the only bidirectional transaction, so the
value of read_write is irrelevant there. So I'm reasonably certain your
code doesn't implement it properly. Either fix it or drop support
altogether. I can't remember this transaction type ever being used by
any slave device in practice, and it can always be added back later if
really needed.

> +
> +	/* map the data buffer */
> +	if (dma_size != 0) {
> +		dev_dbg(dev, " dev=%p\n", dev);
> +		dev_dbg(dev, " data=%p\n", data);
> +		dev_dbg(dev, " dma_buffer=%p\n", priv->dma_buffer);
> +		dev_dbg(dev, " dma_size=%d\n", dma_size);
> +		dev_dbg(dev, " dma_direction=%d\n", dma_direction);
> +
> +		dma_addr = dma_map_single(dev,
> +				      priv->dma_buffer,
> +				      dma_size,
> +				      dma_direction);
> +
> +		if (dma_mapping_error(dev, dma_addr)) {
> +			dev_err(dev, "Error in mapping dma buffer %p\n",
> +				priv->dma_buffer);
> +			return -EIO;
> +		}
> +
> +		dev_dbg(dev, " dma_addr = 0x%016llX\n",
> +			dma_addr);
> +
> +		desc->dptr_low = lower_32_bits(dma_addr);
> +		desc->dptr_high = upper_32_bits(dma_addr);
> +	}
> +
> +	INIT_COMPLETION(priv->cmp);
> +
> +	/* Add the descriptor */
> +	ismt_submit_desc(priv);
> +
> +	/* Now we wait for interrupt completion, 1s */
> +	ret = wait_for_completion_timeout(&priv->cmp, HZ*1);
> +
> +	/* unmap the data buffer */
> +	if (dma_size != 0)
> +		dma_unmap_single(&adap->dev, dma_addr, dma_size, dma_direction);
> +
> +	if (unlikely(!ret)) {
> +		dev_err(dev, "completion wait timed out\n");
> +		ret = -ETIMEDOUT;
> +		goto out;
> +	}
> +
> +	/* do any post processing of the descriptor here */
> +	ret = ismt_process_desc(desc, data, priv, size, read_write);
> +
> +out:
> +	/* Update the ring pointer */
> +	priv->head++;
> +	priv->head %= ISMT_DESC_ENTRIES;
> +
> +	return ret;
> +}

I have backported your code to kernel 3.0 and I'll get back to you when
I finally get a chance to test it.

-- 
Jean Delvare

  parent reply	other threads:[~2013-02-04  9:47 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-07  0:36 [PATCH v4] i2c: Adding support for Intel iSMT SMBus 2.0 host controller Bill E Brown
     [not found] ` <1354840604-8160-1-git-send-email-bill.e.brown-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2012-12-07  0:34   ` Brown, Bill E
2012-12-18 14:03   ` Jean Delvare
     [not found]     ` <20121218150337.5b861ae3-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
2013-01-28 19:43       ` [PATCH v5] " Neil Horman
     [not found]         ` <1359402232-21369-1-git-send-email-nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
2013-01-29 14:05           ` Jean Delvare
     [not found]             ` <20130129150551.498b2a9b-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
2013-01-29 15:32               ` Neil Horman
     [not found]                 ` <20130129153253.GA14044-B26myB8xz7F8NnZeBjwnZQMhkBWG/bsMQH7oEaQurus@public.gmane.org>
2013-01-29 22:10                   ` Jean Delvare
     [not found]                     ` <20130129231028.41b04fc9-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
2013-01-30 14:15                       ` Neil Horman
     [not found]                         ` <20130130141504.GA2968-0o1r3XBGOEbbgkc5XkKeNuvMHUBZFtU3YPYVAmT7z5s@public.gmane.org>
2013-01-30 21:55                           ` Jean Delvare
2013-01-29 16:57               ` Heasley, Seth
     [not found]                 ` <DEC3922D1904474A8862C7BFF516EA9A59B47EB2-P5GAC/sN6hmkrb+BlOpmy7fspsVTdybXVpNB7YpNyf8@public.gmane.org>
2013-01-29 18:52                   ` Jean Delvare
2013-01-29 14:29           ` Jean Delvare
2013-02-01 19:48           ` [PATCH v6] " Neil Horman
     [not found]             ` <1359748083-24423-1-git-send-email-nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
2013-02-04  9:47               ` Jean Delvare [this message]
     [not found]                 ` <20130204104744.5f83541e-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
2013-02-04 17:19                   ` Jean Delvare
     [not found]                     ` <20130204181902.06c247ad-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
2013-02-04 17:28                       ` Neil Horman
     [not found]                         ` <20130204172851.GA24749-B26myB8xz7F8NnZeBjwnZQMhkBWG/bsMQH7oEaQurus@public.gmane.org>
2013-02-05  7:21                           ` Jean Delvare
2013-02-04 19:54           ` [PATCH v7] " Neil Horman
     [not found]             ` <1360007650-26272-1-git-send-email-nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
2013-02-05  1:13               ` Heasley, Seth
     [not found]                 ` <DEC3922D1904474A8862C7BFF516EA9A59B4A8B8-P5GAC/sN6hmkrb+BlOpmy7fspsVTdybXVpNB7YpNyf8@public.gmane.org>
2013-02-05  7:16                   ` Jean Delvare
     [not found]                     ` <20130205081642.5349bd1a-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
2013-02-05 14:52                       ` Neil Horman
     [not found]                         ` <20130205145230.GA4511-B26myB8xz7F8NnZeBjwnZQMhkBWG/bsMQH7oEaQurus@public.gmane.org>
2013-02-05 16:41                           ` Jean Delvare
2013-02-05 16:41               ` Jean Delvare
2013-02-10 15:02               ` Wolfram Sang
     [not found]                 ` <20130210150205.GB6282-8EAEigeeuNG034pCzgS/Qg7AFbiQbgqx@public.gmane.org>
2013-03-05 14:22                   ` Neil Horman
     [not found]                     ` <20130305142225.GA23095-B26myB8xz7F8NnZeBjwnZQMhkBWG/bsMQH7oEaQurus@public.gmane.org>
2013-03-05 14:42                       ` Jean Delvare
     [not found]                         ` <20130305154253.317bd23a-R0o5gVi9kd7kN2dkZ6Wm7A@public.gmane.org>
2013-03-05 16:09                           ` Neil Horman

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=20130204104744.5f83541e@endymion.delvare \
    --to=khali-puyad+kwke1g9huczpvpmw@public.gmane.org \
    --cc=bill.e.brown-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
    --cc=linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org \
    --cc=seth.heasley-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
    /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;
as well as URLs for NNTP newsgroup(s).