Index: linux-2.6-working/arch/arm/Kconfig =================================================================== --- linux-2.6-working.orig/arch/arm/Kconfig 2006-01-19 17:41:46.000000000 +0000 +++ linux-2.6-working/arch/arm/Kconfig 2006-01-24 11:17:08.000000000 +0000 @@ -784,6 +784,8 @@ source "drivers/mmc/Kconfig" +source "drivers/can/Kconfig" + endmenu source "fs/Kconfig" Index: linux-2.6-working/drivers/Kconfig =================================================================== --- linux-2.6-working.orig/drivers/Kconfig 2006-01-19 17:41:46.000000000 +0000 +++ linux-2.6-working/drivers/Kconfig 2006-01-19 17:42:31.000000000 +0000 @@ -68,4 +68,6 @@ source "drivers/sn/Kconfig" +source "drivers/can/Kconfig" + endmenu Index: linux-2.6-working/drivers/Makefile =================================================================== --- linux-2.6-working.orig/drivers/Makefile 2006-01-19 17:41:46.000000000 +0000 +++ linux-2.6-working/drivers/Makefile 2006-01-19 17:42:31.000000000 +0000 @@ -72,3 +72,4 @@ obj-y += firmware/ obj-$(CONFIG_CRYPTO) += crypto/ obj-$(CONFIG_SUPERH) += sh/ +obj-$(CONFIG_CAN) += can/ Index: linux-2.6-working/drivers/can/Kconfig =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6-working/drivers/can/Kconfig 2006-01-24 11:17:13.000000000 +0000 @@ -0,0 +1,17 @@ +menu "CAN support" + +config CAN + tristate "CAN support" + depends on NET + help + Controller Area Network (CAN) is a serial bus network used in + industrial and automotive control and monitoring applications. + +config CAN_DEBUG + boolean "Debug support for CAN drivers" + depends on CAN && DEBUG_KERNEL + help + Say "yes" to enable debug messaging (like dev_dbg and pr_debug), + sysfs, and debugfs support in CAN controller drivers. + +endmenu Index: linux-2.6-working/drivers/can/Makefile =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6-working/drivers/can/Makefile 2006-01-24 11:17:13.000000000 +0000 @@ -0,0 +1,5 @@ +ifeq ($(CONFIG_CAN_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif + +obj-$(CONFIG_CAN) += can.o Index: linux-2.6-working/drivers/can/can.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6-working/drivers/can/can.c 2006-01-24 11:17:36.000000000 +0000 @@ -0,0 +1,148 @@ +/* + * Controller Area Network (CAN) infrastructure. + * + * Copyright (C) 2006 Arcom Control Systems Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include + + +ssize_t can_bit_rate_show(struct class_device *cdev, char *buf) +{ + struct can_device *can = to_can_device(cdev); + return sprintf(buf, "%d\n", can->get_bit_rate(can)); +} + +ssize_t can_bit_rate_store(struct class_device *cdev, const char *buf, size_t count) +{ + struct can_device *can = to_can_device(cdev); + int bit_rate; + + if (netif_running(&can->ndev)) + return -EBUSY; + + bit_rate = simple_strtoul(buf, NULL, 0); + can->set_bit_rate(can, bit_rate); + + return count; +} + +CLASS_DEVICE_ATTR(bit_rate, 0644, can_bit_rate_show, can_bit_rate_store); + + +static struct net_device_stats *can_get_stats(struct net_device *netdev) +{ + struct can_device *can = netdev->priv; + + return &can->stats; +} + +static void can_device_release(struct class_device *cdev) +{ + struct can_device *can = to_can_device(cdev); + + class_device_remove_file(&can->cdev, &class_device_attr_bit_rate); + + unregister_netdev(&can->ndev); + + kfree(can); +} + +static struct class can_device_class = { + .name = "can", + .owner = THIS_MODULE, + .release = can_device_release, +}; + +struct can_device * __init_or_module +can_device_alloc(struct device *dev, unsigned size) +{ + struct can_device *can; + + if (!dev) + return NULL; + + can = kzalloc(size + sizeof(struct can_device), SLAB_KERNEL); + if (!can) + return NULL; + + class_device_initialize(&can->cdev); + can->cdev.class = &can_device_class; + can->cdev.dev = get_device(dev); + can_device_set_devdata(can, &can[1]); + + return can; +} +EXPORT_SYMBOL_GPL(can_device_alloc); + +int __init_or_module can_device_register(struct can_device *can) +{ + struct device *dev = can->cdev.dev; + int ret; + + /* Network device initialization */ + SET_NETDEV_DEV(&can->ndev, dev); + strcpy(can->ndev.name, "can%d"); + can->ndev.get_stats = can_get_stats; + can->ndev.flags = IFF_NOARP | IFF_MULTICAST; + can->ndev.mtu = sizeof(struct can_frame); + can->ndev.tx_queue_len = 10; + can->ndev.priv = can; + + ret = register_netdev(&can->ndev); + if (ret < 0) { + dev_err(dev, "network device registration failed (ret = %d)\n", ret); + goto error_net; + } + + /* Use the network interface name as the class device id. */ + strcpy(can->cdev.class_id, can->ndev.name); + ret = class_device_add(&can->cdev); + if (ret < 0) + goto error_class; + + class_device_create_file(&can->cdev, &class_device_attr_bit_rate); + + return 0; + + error_class: + unregister_netdev(&can->ndev); + error_net: + return ret; +} +EXPORT_SYMBOL_GPL(can_device_register); + +void can_device_unregister(struct can_device *can) +{ + class_device_unregister(&can->cdev); + can->cdev.dev = NULL; +} +EXPORT_SYMBOL_GPL(can_device_unregister); + +static int __init can_init(void) +{ + int ret; + + ret = class_register(&can_device_class); + if (ret < 0) + goto error; + return 0; + + error: + return ret; +} + +subsys_initcall(can_init); + +MODULE_DESCRIPTION("CAN infrastructure"); +MODULE_LICENSE("GPL"); Index: linux-2.6-working/include/linux/can/can.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6-working/include/linux/can/can.h 2006-01-24 11:17:36.000000000 +0000 @@ -0,0 +1,107 @@ +/* + * Controller Area Network (CAN) infrastructure. + * + * Copyright (C) 2006 Arcom Control Systems Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#ifndef __LINUX_CAN_CAN_H +#define __LINUX_CAN_CAN_H + +#define CAN_FRAME_MAX_DATA_LEN 8 + +/** + * struct can_frame_header - Extended CAN frame header fields + * @id: 11 bit standard ID + * @srr: Substitute Remote Request bit + * @ide: Extended frame bit + * @eid: 18 bit extended ID + * @rtr: Remote Transmit Request bit + * @rb1: Reserved Bit 1 + * @rb0: Reserved Bit 0 + * @dlc: 4 bit Data Length Code + * + * For a standard frame ensure that ide == 0 and fill in only id, rtr and dlc. + * + * srs, rb1, and rb0 are unused and should be set to zero. + * + * Note: The memory layout does not correspond to the on-the-wire format for a + * CAN frame header. + */ +struct can_frame_header { + unsigned id:11; + unsigned srs:1; + unsigned ide:1; + unsigned eid:18; + unsigned rtr:1; + unsigned rb1:1; + unsigned rb0:1; + unsigned dlc:4; +}; + +/** + * struct can_frame - CAN frame header fields and data + * @header: CAN frame header + * @data: 8 bytes of data + * + * User space transmits and receives struct can_frame's via the network device + * socket interface. + * + * Note: The memory layout does not correspond to the on-the-wire format for a + * CAN frame. + */ +struct can_frame { + struct can_frame_header header; + uint8_t data[CAN_FRAME_MAX_DATA_LEN]; +}; + +#ifdef __KERNEL__ + +/** + * struct can_device - CAN controller class device + * @cdev: the class device + * @set_bit_rate: driver operation to set the CAN bus bit rate, may return + * -EINVAL if the requested bit rate isn't possible. This is only called + * if the network device is down. + * @get_bit_rate: driver operation to get the current CAN bus bit rate. + * @ndev: the network device + * @stats: the network device statistics + * + * The CAN controller driver must provide ndev.open, ndev.stop and + * ndev.hard_start_xmit before registering the CAN device. + */ +struct can_device { + struct class_device cdev; + + int (*set_bit_rate)(struct can_device *can, int bit_rate); + int (*get_bit_rate)(struct can_device *can); + + struct net_device ndev; + struct net_device_stats stats; +}; + +struct can_device * can_device_alloc(struct device *dev, unsigned size); +int can_device_register(struct can_device *can); +void can_device_unregister(struct can_device *can); + +static inline void *can_device_get_devdata(struct can_device *can) +{ + return class_get_devdata(&can->cdev); +} + +static inline void can_device_set_devdata(struct can_device *can, void *data) +{ + class_set_devdata(&can->cdev, data); +} + +static inline struct can_device *to_can_device(struct class_device *cdev) +{ + return cdev ? container_of(cdev, struct can_device, cdev) : NULL; +} + +#endif /* __KERNEL__ */ + +#endif /* !__LINUX_CAN_CAN_H */ Index: linux-2.6-working/Documentation/can/can-summary =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6-working/Documentation/can/can-summary 2006-01-24 11:18:16.000000000 +0000 @@ -0,0 +1,44 @@ +Controller Area Network (CAN) support +===================================== + +Overview +-------- + +Controller Area Network (CAN) is a serial bus network commonly used in +automotive and industrial control applications. + +CAN is (exclusively) a broadcast network, each node selects which frames to +receive based on the ID (or extended ID) in the frame header. + +Two frame formats are specified in the CAN 2.0B specification: standard and +extended. Standard frames have an 11 bit ID; extended an 29 bit ID (split +into 11 bit standard ID the 18 bit extended ID). All frames have a Remote +Transmit Request bit which may be set to request a remote node to transmit a +response. Frames may have up to 8 octets of payload data. + + +User space interface +-------------------- + +CAN frames are transmitted and received using a packet(7) socket bind(2)'ed to +the CAN network device. + +Since a CAN frame is not a whole number of octets the CAN frame is +encapsulated in a 'struct can_frame' which includes fields for the header and +the payload. Note that the in-memory layout of 'struct can_frame' does not +correspond to the on-the-wire format of the CAN frame. + +/sys/class/can/can?/bit_rate may be used to set/query the bit rate of the CAN +bus. + + +Todo +---- + +- a user-space interface that doesn't require root or CAP_NET_RAW and that + isn't a security risk. i.e., you shouldn't be able to open a non-CAN network + interface and send raw CAN frames down it. + +- hardware message filtering? + +- report bus errors to user-space (e.g., bus-passive and bus-off modes).