[U-Boot] [PATCH] add u-boot sja1000/can support

Wolfgang Denk wd at denx.de
Mon Oct 26 22:56:44 CET 2009


Dear "miaofng",

In message <200910241217470153391 at gmail.com> you wrote:
> From 1f6aaba856fbf484c442eb33cf220774d57fba8d Mon Sep 17 00:00:00 2001
> From: miaofng <miaofng at gmail.com>
> Date: Fri, 23 Oct 2009 17:06:50 +0800
> Subject: [PATCH] [can] add u-boot sja1000/can support
> 
> Signed-off-by: miaofng <miaofng at gmail.com>

Please provide a real name here and in all Copyright entries.

...
> diff --git a/drivers/can/can_core.c b/drivers/can/can_core.c
> new file mode 100755
> index 0000000..a723e8a
> --- /dev/null
> +++ b/drivers/can/can_core.c
> @@ -0,0 +1,266 @@
> +/*
> + * Copyright (C) 2009 miaofng<miaofng at gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the version 2 of the GNU General Public License
> + * as published by the Free Software Foundation
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> + */
> +
> +#include <common.h>
> +#include <can.h>
> +#include <malloc.h>
> +
> +#define can_debug printf

Why not
	#define can_debug debug
?

And why not use plain debug() in the first place?

> +#define can_error printf

What is this good for? I don't see "can_error" used anywhere?


> +#ifdef CONFIG_CMD_CAN
> +#ifndef CONFIG_CAN_DEV_MAX
> +#define CONFIG_CAN_DEV_MAX	8
> +#endif
> +
> +static struct can_device *can_devs[CONFIG_CAN_DEV_MAX];
> +#endif
> +
> +static inline struct can_device* index_to_cdev(int index)
> +{
> +	return (index<CONFIG_CAN_DEV_MAX)? can_devs[index]:0;
> +}
> +
> +static inline int cdev_to_index(struct can_device *dev)
> +{
> +	return (dev)?dev->index:-1;
> +}
> +
> +static void canif_tx(struct can_device *dev)
> +{
> +	struct can_frame *cf;
> +	int len;
> +
> +	len = buf_pop(&dev->tbuf, (char*)&cf, sizeof(cf));
> +	if(len == sizeof(cf)) {
> +		dev->start_xmit(cf, dev);
> +		free(cf);
> +	}
> +}

This look like Linux code to me which is somewhat out of place in a
U-Boot context?

> +void canif_rx(struct can_frame *cf, struct can_device *dev)
> +{
> +	int len;
> +
> +	//error frame?

Please do not use any C++ comments. [Fix globally]

> +	if(cf->can_id&CAN_ERR_FLAG)
> +	{

Incorrect brace style. Please fix globally.

> +		//error frame, drop it
> +		free(cf);
> +		return;
> +	}
> +
> +	//soft id filter?
> +
> +	//store to cirbuf
> +	if(dev->rbuf.size == dev->rbuf.totalsize) {
> +		can_debug("CAN: rx buffer is full\n");
> +		dev->stats.rx_dropped ++;
> +		free(cf);
> +		return;
> +	}
> +
> +	buf_push(&dev->rbuf, (char*)&cf, sizeof(cf));
> +}
> +
> +void canif_wake_queue(struct can_device *dev)
> +{
> +	canif_start_queue(dev);
> +	canif_tx(dev);
> +}

Are you sure we could need this in U-Boot? Keep in mind that U-Bootis
strictly single-tasking.

> +int can_init(void)
> +{
> +#ifdef CONFIG_CMD_CAN
> +	int index;
> +	for(index = 0; index < CONFIG_CAN_DEV_MAX; index ++) can_devs[index] = 0;

Incorrect indentation.

> +	board_can_init();
> +#endif
> +	return 0;
> +}

No can_init() should be performed at all (and thus not compiled
either) if CONFIG_CMD_CAN is not defined.

> +/*
> + * Register the CAN network device
> + */
> + #ifndef CONFIG_CAN_BUF_TX_SZ
> + #define CONFIG_CAN_BUF_TX_SZ (8*sizeof(void*))
> + #endif
> +
> + #ifndef CONFIG_CAN_BUF_RX_SZ
> + #define CONFIG_CAN_BUF_RX_SZ (8*sizeof(void*))
> + #endif

Please don't do this right in the middle of a source file. Move to
header.

> +int register_candev(struct can_device *dev)
> +{
> +	int ret;
> +	int index;
> +
> +	//insert into the list
> +	dev->index = -1;
> +	for(index =0; index < CONFIG_CAN_DEV_MAX; index ++)
> +	{
> +		if(!can_devs[index]) {
> +			can_devs[index] = dev;
> +			dev->index = index;
> +			break;
> +		}
> +	}
> +	if( dev->index < 0)
> +		can_debug("CAN: too many can devices\n");
> +
> +	//allocate circbuf for tx and rx
> +	ret = buf_init(&dev->tbuf, CONFIG_CAN_BUF_TX_SZ);
> +	if(ret != 1) {
> +		can_debug("CAN: cann't init cirbuf of tx\n");
> +		can_devs[index] = 0;
> +		return -1;
> +	}
> +	ret = buf_init(&dev->rbuf, CONFIG_CAN_BUF_RX_SZ);
> +	if(ret != 1) {
> +		can_debug("CAN: cann't init cirbuf of rx\n");
> +		can_devs[index] = 0;
> +		buf_free(&dev->tbuf);
> +		return -1;
> +	}
> +	dev->qstatus = CAN_QUEUE_INIT;
> +
> +	//success
> +	printf("CAN:   %s @index %d\n", dev->name, dev->index);
> +	return 0;
> +}

Looks like overkill to me, and doesn;t seem to fit into U-Boot design
rules. Please see http://www.denx.de/wiki/U-Boot/DesignPrinciples

> +/*
> + * Unregister the CAN network device
> + */
> +void unregister_candev(struct can_device *dev)
> +{
> +	int index = cdev_to_index(dev);
> +
> +	if(index < 0) {
> +		can_debug("CAN: invalid para\n");
> +		return;
> +	}
> +
> +	//close the dev first
> +	can_close((int)dev);
> +
> +	//release tx/rx buffer
> +	buf_free(&dev->tbuf);
> +	buf_free(&dev->rbuf);
> +
> +	//remove from the list
> +	can_devs[index] = 0;
> +}

Ditto.

> +//api
> +int can_setbrg(int brg, int index)
> +{
> +	struct can_device *dev = index_to_cdev(index);
> +
> +	if(!dev) {
> +		can_debug("CAN: invalid para\n");
> +		return -1;
> +	}
> +
> +	if( dev->state != CAN_STATE_STOPPED) {
> +		can_debug("CAN: invalid dev status<%d>\n", dev->state);
> +		return -1;
> +	}
> +
> +	if(dev->setbrg)
> +		return dev->setbrg(brg, dev);
> +
> +	can_debug("CAN: op not supported by the dev\n");
> +	return -1;
> +}

These error messages should be that, i. e. error messages, no debug.
And they could be a bit more self-explanatory. "op not supported" -
what's an "op"? Ans which "op" is not supported? Etc.

> +int can_open(int index)
> +{
> +	struct can_device *dev = index_to_cdev(index);
> +
> +	if(!dev) {
> +		can_debug("CAN: invalid para\n");
> +		return 0;
> +	}
> +
> +	if(dev->state != CAN_STATE_STOPPED) {
> +		can_debug("CAN: invalid dev status<%d>\n", dev->state);
> +		return 0;
> +	}
> +
> +	if(dev && dev->open) dev->open(dev);
> +	return (int)dev;
> +}
> +
> +void can_close(int dev_id)
> +{
> +	struct can_device *dev = (struct can_device*) dev_id;
> +	struct can_frame *cf;
> +
> +	if(!dev) {
> +		can_debug("CAN: invalid para\n");
> +		return;
> +	}
> +
> +	//can device close
> +	if(dev->close) dev->close(dev);
> +
> +	//tbuf,rbuf dump
> +	while(buf_pop(&dev->tbuf, (char*)&cf, sizeof(cf)) ) free(cf);
> +	while(buf_pop(&dev->rbuf, (char*)&cf, sizeof(cf)) ) free(cf);
> +}

Do we need this? In a single-threaded contxt?

> +//non block write
> +int can_send(struct can_frame *cf, int dev_id)
> +{
...
> +//non block read
> +struct can_frame* can_recv(int dev_id)
> +{
...

Please explain how you think this fits into U-Boot context, which is
single-threaded by design.

> diff --git a/include/candev.h b/include/candev.h
> new file mode 100755
> index 0000000..0e0dee7
> --- /dev/null
> +++ b/include/candev.h
...
> +/*
> + * netdev.h - definitions an prototypes for network devices
> + */

Inappropriate comment, it seems?

> diff --git a/lib_arm/board.c b/lib_arm/board.c
> old mode 100644
> new mode 100755
> index 5e3d7f6..aa11dd3
> --- a/lib_arm/board.c
> +++ b/lib_arm/board.c
> @@ -356,6 +356,8 @@ void start_armboot (void)
>  	serial_initialize();
>  #endif
>  
> +	can_init();
> +
>  	/* IP Address */
>  	gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

Such a change would have to go into a separate patch.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
365 Days of drinking Lo-Cal beer.                       = 1 Lite-year


More information about the U-Boot mailing list