All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marc Kleine-Budde <mkl@pengutronix.de>
To: Tomoya MORINAGA <tomoya-linux@dsn.okisemi.com>
Cc: Wolfgang Grandegger <wg@grandegger.com>,
	andrew.chih.howe.khor@intel.com, socketcan-core@lists.berlios.de,
	sameo@linux.intel.com, margie.foster@intel.com,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	yong.y.wang@intel.com, masa-korg@dsn.okisemi.com,
	kok.howg.ewe@intel.com, chripell@fsfe.org,
	morinaga526@dsn.okisemi.com, David Miller <davem@davemloft.net>,
	joel.clark@intel.com, qi.wang@intel.com
Subject: Re: [PATCH net-next-2.6 v2] can: Topcliff: PCH_CAN driver: Fix buildwarnings
Date: Wed, 27 Oct 2010 15:14:58 +0200	[thread overview]
Message-ID: <4CC825D2.3030108@pengutronix.de> (raw)
In-Reply-To: <008201cb75c9$f27ff720$66f8800a@maildom.okisemi.com>

[-- Attachment #1: Type: text/plain, Size: 7018 bytes --]

On 10/27/2010 01:27 PM, Tomoya MORINAGA wrote:
> On Wednesday, October 27, 2010 3:52 AM :  Marc Kleine-Budde and Wolfgang Grandegge wrote:

>> Do I understand your code correctly? You have a big loop, but only do
>>  two different things at certain values of the loop? Smells fishy.
> Uh, I can't understand your intention.
> Please show in detail.

It's easier to talk about code when we can see it, pelase don't delete :)

>> +static void pch_can_config_rx_tx_buffers(struct pch_can_priv *priv)
>> > +{
>> > +	int i;
>> > +	unsigned long flags;
>> > +
>> > +	spin_lock_irqsave(&priv->msgif_reg_lock, flags);
>> > +
>> > +	for (i = 0; i < PCH_OBJ_NUM; i++) {
>> > +		if (priv->msg_obj[i] == MSG_OBJ_RX) {
>                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> > +			iowrite32(CAN_CMASK_RX_TX_GET,
>> > +				&priv->regs->if1_cmask);
>> > +			pch_can_check_if_busy(&priv->regs->if1_creq, i+1);
>> > +
>> > +			iowrite32(0x0, &priv->regs->if1_id1);
>> > +			iowrite32(0x0, &priv->regs->if1_id2);
>> > +
>> > +			pch_can_bit_set(&priv->regs->if1_mcont,
>> > +					CAN_IF_MCONT_UMASK);
>> > +
>> > +			/* Set FIFO mode set to 0 except last Rx Obj*/
>> > +			pch_can_bit_clear(&priv->regs->if1_mcont,
>> > +					  CAN_IF_MCONT_EOB);
>> > +			/* In case FIFO mode, Last EoB of Rx Obj must be 1 */
>> > +			if (i == (PCH_RX_OBJ_NUM - 1))
>> > +				pch_can_bit_set(&priv->regs->if1_mcont,
>> > +						  CAN_IF_MCONT_EOB);
>> > +
>> > +			iowrite32(0, &priv->regs->if1_mask1);
>> > +			pch_can_bit_clear(&priv->regs->if1_mask2,
>> > +					  0x1fff | CAN_MASK2_MDIR_MXTD);
>> > +
>> > +			/* Setting CMASK for writing */
>> > +			iowrite32(CAN_CMASK_RDWR | CAN_CMASK_MASK |
>> > +				  CAN_CMASK_ARB | CAN_CMASK_CTRL,
>> > +				  &priv->regs->if1_cmask);
>> > +
>> > +			pch_can_check_if_busy(&priv->regs->if1_creq, i+1);
>> > +		} else if (priv->msg_obj[i] == MSG_OBJ_TX) {
>                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
> Do I understand your code correctly? You have a big loop, but only do
> two different things at certain values of the loop? Smells fishy.

Looking again at the code it makes sense as it is :) Sorry for the
confusion.

>> > +			iowrite32(CAN_CMASK_RX_TX_GET,
>> > +				&priv->regs->if2_cmask);
>> > +			pch_can_check_if_busy(&priv->regs->if2_creq, i+1);
>> > +
>> > +			/* Resetting DIR bit for reception */
>> > +			iowrite32(0x0, &priv->regs->if2_id1);
>> > +			iowrite32(0x0, &priv->regs->if2_id2);
>> > +			pch_can_bit_set(&priv->regs->if2_id2, CAN_ID2_DIR);
>> > +
>> > +			/* Setting EOB bit for transmitter */
>> > +			iowrite32(CAN_IF_MCONT_EOB, &priv->regs->if2_mcont);
>> > +
>> > +			pch_can_bit_set(&priv->regs->if2_mcont,
>> > +					CAN_IF_MCONT_UMASK);
>> > +
>> > +			iowrite32(0, &priv->regs->if2_mask1);
>> > +			pch_can_bit_clear(&priv->regs->if2_mask2, 0x1fff);
>> > +
>> > +			/* Setting CMASK for writing */
>> > +			iowrite32(CAN_CMASK_RDWR | CAN_CMASK_MASK |
>> > +				  CAN_CMASK_ARB | CAN_CMASK_CTRL,
>> > +				  &priv->regs->if2_cmask);
>> > +
>> > +			pch_can_check_if_busy(&priv->regs->if2_creq, i+1);
>> > +		}
>> > +	}
>> > +	spin_unlock_irqrestore(&priv->msgif_reg_lock, flags);
>> > +}

> This processing does configuration for all message objects.

Yeah, got it. However I think you can get rid of the priv->msg_obj
variable altogether. Let me recapitulate:
- you setup priv->msg_obj[] in the probe function, which defines if a
  msg_obj is a rx or tx
- this definition is never changed
- all objects of one kind are in a row

So you can identify the purpose of a msg_obj by simply looking at it's
number. If you need to loop over them you can even define helper
functions like, for_each_rx_obj().

>> what does this loop do? why is it nessecarry? I don't like delay loops
>>   in the hot path of a driver.
> This loop is for waiting for all tx Message Object completion.
> This is Topcliff CAN HW specification.

Can you give us a pointer into intel's documentation?
I think Wolfgang already suggested to check if the chip is busy _before_
accessing it instead of waiting the chip to finish after accessing.

>> If you figured out how to use the endianess conversion functions from
>> the cpu_to_{le,be}-{le,to}_to_cpup family use them here, too.
> Uh,le32_to_cpu have been used already here.

Let's look at the code:

>> +		for (i = 0, j = 0; i < cf->can_dlc; j++) {
>> > +			reg = ioread32(&priv->regs->if1_dataa1 + j*4);
>> > +			cf->data[i++] = cpu_to_le32(reg & 0xff);
>> > +			if (i == cf->can_dlc)
>> > +				break;
>> > +			cf->data[i++] = cpu_to_le32((reg >> 8) & 0xff);
>> > +		}

What does the code do? It swaps bytes because the data bytes in the can
core is arranged differently compared to the data in the struct can_frame.

According to the datasheet if_dataa1 holds 1st byte in bits 07:00 and
2nd byte in 15:08. (The rest is reserved.) So in the memory it looks
like this:

  xx xx byte1 byte0

The can_frame has a different layout:

	__u8    data[8] __attribute__((aligned(8)));

which is in memory:

  byte0 byte1 byte2 byte3  byte4 byte5 byte6 byte7

This is why you swap. However in Linux no need to do this by hand.

The if_dataXX have a little endian layout, while the can frame has a big
endian layout. Further if_dataXX has only 16 bit of can data.

I think it should look like this:

	for (i = 0; i < cf->can_dlc; i += 2) {
		reg = ioread32(&priv->regs->if1_data[i >> 1]);
		*(__be16 *)cf->data[i] = cpu_to_be16(reg);
	}

You have to change the definition of the regs struct a bit:

>	u32 if1_mcont;
>	u32 if1_data[4];
>	u32 reserve2;

Totally untested, though.
BTW: Where can I get this Intel Hardware to improve and test the driver?

> I can't understand your intention.
> Please show in detail.

Above we have the RX-Path, the TX-path would probably use a
"be16_to_cpup", have a look at the flexcan driver. It uses the whole 32
bit for candata, though.

>>> All these check if busy in the code make me a bit nervous, can you
>>> please explain why they are needed. A pointer to the manual is okay, too.
>> Me too. I already ask in my previous mail how long that functions
>> usually blocks.
> When accessing read/write from/to Message RAM,
> Since it takes much time for transferring between Register and Message RAM,
> SW must check busy flag of CAN register.
> This is a Topcliff HW specification.

see above.

>> is there some pdev->name instead of KBUILD_MODNAME that can be used?
> I can't understand your intention.
> pdev(struct pci_dev) doesn't have "name" member. 

I was just asking :) As it doesn't have a name, KBUILD_MODNAME is fine.

regards,
Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]

  parent reply	other threads:[~2010-10-27 13:15 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-26  0:04 [PATCH net-next-2.6 v2] can: Topcliff: PCH_CAN driver: Fix build warnings Tomoya
2010-10-26 17:52 ` David Miller
2010-10-26 17:55   ` David Miller
2010-10-26 18:27     ` Wolfgang Grandegger
2010-10-26 18:52       ` Marc Kleine-Budde
2010-10-27 11:27         ` [PATCH net-next-2.6 v2] can: Topcliff: PCH_CAN driver: Fix buildwarnings Tomoya MORINAGA
2010-10-27 11:57           ` Wolfgang Grandegger
2010-10-27 11:58             ` Marc Kleine-Budde
2010-10-27 13:14           ` Marc Kleine-Budde [this message]
2010-10-27  0:50       ` [PATCH net-next-2.6 v2] can: Topcliff: PCH_CAN driver: Fix build warnings Tomoya MORINAGA
2010-10-27  4:29   ` can: About Socket CAN with MSI issue Tomoya MORINAGA
2010-10-27  7:31     ` Wolfgang Grandegger
2010-10-27  7:56     ` Dave Airlie
2010-10-27 11:41       ` Tomoya MORINAGA

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=4CC825D2.3030108@pengutronix.de \
    --to=mkl@pengutronix.de \
    --cc=andrew.chih.howe.khor@intel.com \
    --cc=chripell@fsfe.org \
    --cc=davem@davemloft.net \
    --cc=joel.clark@intel.com \
    --cc=kok.howg.ewe@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=margie.foster@intel.com \
    --cc=masa-korg@dsn.okisemi.com \
    --cc=morinaga526@dsn.okisemi.com \
    --cc=netdev@vger.kernel.org \
    --cc=qi.wang@intel.com \
    --cc=sameo@linux.intel.com \
    --cc=socketcan-core@lists.berlios.de \
    --cc=tomoya-linux@dsn.okisemi.com \
    --cc=wg@grandegger.com \
    --cc=yong.y.wang@intel.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.