Index: ksrc/drivers/can/Kconfig =================================================================== --- ksrc/drivers/can/Kconfig (revision 2335) +++ ksrc/drivers/can/Kconfig (working copy) @@ -49,6 +49,19 @@ config XENO_DRIVERS_CAN_MAX_RECEIVERS The driver maintains a receive filter list per device for fast access. +config XENO_DRIVERS_CAN_BUS_ERR + depends on XENO_DRIVERS_CAN + bool + default n + help + + To avoid unnecessary bus error interrupt flooding, this option enables + bus error interrupts when an application is calling a receive function + on a socket listening on bus errors. After one bus error has occured, + the interrupt will be disabled to allow the application time for error + processing. This option is automatically selected for CAN controllers + supporting bus error interrupts like the SJA1000. + config XENO_DRIVERS_CAN_VIRT depends on XENO_DRIVERS_CAN tristate "Virtual CAN bus driver" Index: ksrc/drivers/can/rtcan_dev.h =================================================================== --- ksrc/drivers/can/rtcan_dev.h (revision 2335) +++ ksrc/drivers/can/rtcan_dev.h (working copy) @@ -118,6 +118,7 @@ struct rtcan_device { int (*do_set_bit_time)(struct rtcan_device *dev, struct can_bittime *bit_time, rtdm_lockctx_t *lock_ctx); + void (*do_enable_bus_err)(struct rtcan_device *dev); /* Reception list head. This list contains all filters which have been * registered via a bind call. */ Index: ksrc/drivers/can/rtcan_raw_dev.c =================================================================== --- ksrc/drivers/can/rtcan_raw_dev.c (revision 2335) +++ ksrc/drivers/can/rtcan_raw_dev.c (working copy) @@ -312,3 +312,33 @@ int rtcan_raw_ioctl_dev(struct rtdm_dev_ return ret; } + +#ifdef CONFIG_XENO_DRIVERS_CAN_BUS_ERR +void __rtcan_raw_enable_bus_err(struct rtcan_socket *sock) +{ + int i, begin, end; + struct rtcan_device *dev; + rtdm_lockctx_t lock_ctx; + int ifindex = atomic_read(&sock->ifindex); + + if (ifindex) { + begin = ifindex; + end = ifindex; + } else { + begin = 1; + end = RTCAN_MAX_DEVICES; + } + + for (i = begin; i <= end; i++) { + if ((dev = rtcan_dev_get_by_index(i)) == NULL) + continue; + + if (dev->do_enable_bus_err) { + rtdm_lock_get_irqsave(&dev->device_lock, lock_ctx); + dev->do_enable_bus_err(dev); + rtdm_lock_put_irqrestore(&dev->device_lock, lock_ctx); + } + rtcan_dev_dereference(dev); + } +} +#endif /* CONFIG_XENO_DRIVERS_CAN_BUS_ERR*/ Index: ksrc/drivers/can/rtcan_raw.c =================================================================== --- ksrc/drivers/can/rtcan_raw.c (revision 2335) +++ ksrc/drivers/can/rtcan_raw.c (working copy) @@ -624,6 +624,7 @@ ssize_t rtcan_raw_recvmsg(struct rtdm_de return -EINVAL; } + rtcan_raw_enable_bus_err(sock); /* Set RX timeout */ timeout = (flags & MSG_DONTWAIT) ? RTDM_TIMEOUT_NONE : sock->rx_timeout; Index: ksrc/drivers/can/rtcan_raw.h =================================================================== --- ksrc/drivers/can/rtcan_raw.h (revision 2335) +++ ksrc/drivers/can/rtcan_raw.h (working copy) @@ -41,6 +41,17 @@ void rtcan_loopback(struct rtcan_device #define rtcan_loopback_pending(dev) (0) #endif /* CONFIG_XENO_DRIVERS_CAN_LOOPBACK */ +#ifdef CONFIG_XENO_DRIVERS_CAN_BUS_ERR +void __rtcan_raw_enable_bus_err(struct rtcan_socket *sock); +static inline void rtcan_raw_enable_bus_err(struct rtcan_socket *sock) +{ + if ((sock->err_mask & CAN_ERR_BUSERROR)) + __rtcan_raw_enable_bus_err(sock); +} +#else +#define rtcan_raw_enable_bus_err(sock) +#endif + int __init rtcan_raw_proto_register(void); void __exit rtcan_raw_proto_unregister(void); Index: ksrc/drivers/can/sja1000/Kconfig =================================================================== --- ksrc/drivers/can/sja1000/Kconfig (revision 2335) +++ ksrc/drivers/can/sja1000/Kconfig (working copy) @@ -1,6 +1,7 @@ config XENO_DRIVERS_CAN_SJA1000 depends on XENO_DRIVERS_CAN tristate "Philips SJA1000 CAN controller" + select XENO_DRIVERS_CAN_BUS_ERR config XENO_DRIVERS_CAN_SJA1000_ISA depends on XENO_DRIVERS_CAN_SJA1000 Index: ksrc/drivers/can/sja1000/rtcan_sja1000.c =================================================================== --- ksrc/drivers/can/sja1000/rtcan_sja1000.c (revision 2335) +++ ksrc/drivers/can/sja1000/rtcan_sja1000.c (working copy) @@ -293,18 +293,21 @@ static int rtcan_sja_interrupt(rtdm_irq_ dev->state = dev->state_before_sleep; /* Error Interrupt? */ - if (irq_source & (SJA_IR_EI | SJA_IR_DOI | SJA_IR_EPI | + if (irq_source & (SJA_IR_EI | SJA_IR_DOI | SJA_IR_EPI | SJA_IR_ALI | SJA_IR_BEI)) { + /* Check error condition and fill error frame */ - rtcan_sja_err_interrupt(dev, chip, &skb, irq_source); + if (!((irq_source & SJA_IR_BEI) && (chip->bus_err_on-- < 2))) { + rtcan_sja_err_interrupt(dev, chip, &skb, irq_source); - if (recv_lock_free) { - recv_lock_free = 0; - rtdm_lock_get(&rtcan_recv_list_lock); - rtdm_lock_get(&rtcan_socket_lock); + if (recv_lock_free) { + recv_lock_free = 0; + rtdm_lock_get(&rtcan_recv_list_lock); + rtdm_lock_get(&rtcan_socket_lock); + } + /* Pass error frame out to the sockets */ + rtcan_rcv(dev, &skb); } - /* Pass error frame out to the sockets */ - rtcan_rcv(dev, &skb); } /* Transmit Interrupt? */ @@ -625,8 +628,16 @@ int rtcan_sja_set_bit_time(struct rtcan_ return 0; } +void rtcan_sja_enable_bus_err(struct rtcan_device *dev) +{ + struct rtcan_sja1000 *chip = (struct rtcan_sja1000 *)dev->priv; - + if (chip->bus_err_on < 2) { + if (chip->bus_err_on < 1) + chip->read_reg(dev, SJA_ECC); + chip->bus_err_on = 2; + } +} /* * Start a transmission to a SJA1000 device @@ -745,8 +756,10 @@ int rtcan_sja1000_register(struct rtcan_ dev->do_set_mode = rtcan_sja_set_mode; dev->do_get_state = rtcan_sja_get_state; dev->do_set_bit_time = rtcan_sja_set_bit_time; + dev->do_enable_bus_err = rtcan_sja_enable_bus_err; + chip->bus_err_on = 1; - ret = rtdm_irq_request(&dev->irq_handle, + ret = rtdm_irq_request(&dev->irq_handle, chip->irq_num, rtcan_sja_interrupt, chip->irq_flags, sja_ctrl_name, dev); if (ret) { Index: ksrc/drivers/can/sja1000/Config.in =================================================================== --- ksrc/drivers/can/sja1000/Config.in (revision 2335) +++ ksrc/drivers/can/sja1000/Config.in (working copy) @@ -4,6 +4,10 @@ dep_tristate 'Philips SJA1000 CAN controller' CONFIG_XENO_DRIVERS_CAN_SJA1000 $CONFIG_XENO_DRIVERS_CAN +if [ "$CONFIG_XENO_DRIVERS_CAN_SJA1000" != "n" ]; then + define_bool CONFIG_XENO_DRIVERS_CAN_BUS_ERR y +fi + dep_tristate ' Standard ISA controllers' CONFIG_XENO_DRIVERS_CAN_SJA1000_ISA $CONFIG_XENO_DRIVERS_CAN_SJA1000 if [ "$CONFIG_XENO_DRIVERS_CAN_SJA1000_ISA" != "n" ]; then int ' Maximum number of controllers' CONFIG_XENO_DRIVERS_CAN_SJA1000_ISA_MAX_DEV 4 Index: ksrc/drivers/can/sja1000/rtcan_sja1000.h =================================================================== --- ksrc/drivers/can/sja1000/rtcan_sja1000.h (revision 2335) +++ ksrc/drivers/can/sja1000/rtcan_sja1000.h (working copy) @@ -30,6 +30,7 @@ struct rtcan_sja1000 { unsigned short irq_flags; unsigned char ocr; unsigned char cdr; + char bus_err_on; }; int rtcan_sja_create_proc(struct rtcan_device* dev);