From 87fef6c9778e24eb4317b347d6647d5d31d1a57b Mon Sep 17 00:00:00 2001 From: norly Date: Thu, 31 Jan 2019 01:08:15 +0100 Subject: [PATCH] Don't reset on HW fault, but take the interface down. There is currently no interface to try again, other than detaching and re-attaching the line discipline. It wouldn't make much sense either, unless we've run into an unexpected state in the ELM327's firmware. --- module/elmcan.c | 40 +++++++++++++++++++++++++++++++++++----- readme.rst | 2 -- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/module/elmcan.c b/module/elmcan.c index 6ae5297..fee83c5 100644 --- a/module/elmcan.c +++ b/module/elmcan.c @@ -93,6 +93,11 @@ struct elmcan { */ atomic_t refcount; + /* Stop the channel on hardware failure. + * Once this is true, nothing will be sent to the TTY. + */ + bool hw_failure; + /* TTY TX helpers */ struct work_struct tx_work; /* Flushes TTY TX buffer */ unsigned char txbuf[32]; @@ -149,6 +154,10 @@ static void elm327_send(struct elmcan *elm, const void *buf, size_t len) { int actual; + if (elm->hw_failure) { + return; + } + memcpy(elm->txbuf, buf, len); /* Order of next two lines is *very* important. @@ -327,14 +336,18 @@ static inline void elm327_hw_failure(struct elmcan *elm) { struct can_frame frame = {0}; - frame.can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED; + frame.can_id = CAN_ERR_FLAG; frame.can_dlc = CAN_ERR_DLC; + frame.data[5] = 'R'; + frame.data[6] = 'I'; + frame.data[7] = 'P'; elm327_feed_frame_to_netdev(elm, &frame); - pr_err("ELM327 misbehaved. Re-initializing.\n"); + netdev_err(elm->dev, "ELM327 misbehaved. " + "Blocking further communication.\n"); - elm->can.can_stats.restarts++; - elm327_init(elm); + elm->hw_failure = true; + can_bus_off(elm->dev); } @@ -714,6 +727,13 @@ static int elmcan_netdev_open(struct net_device *dev) int err; spin_lock_bh(&elm->lock); + if (elm->hw_failure) { + netdev_err(elm->dev, "Refusing to open interface after " + "a hardware fault has been detected.\n"); + spin_unlock_bh(&elm->lock); + return -EIO; + } + if (elm->tty == NULL) { spin_unlock_bh(&elm->lock); return -ENODEV; @@ -787,6 +807,12 @@ static netdev_tx_t elmcan_netdev_start_xmit(struct sk_buff *skb, struct net_devi * See Documentation/networking/netdevices.txt */ spin_lock(&elm->lock); + + /* We shouldn't get here after a hardware fault: + * can_bus_off() calls netif_carrier_off() + */ + BUG_ON(elm->hw_failure); + if (elm->tty == NULL || elm->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) { spin_unlock(&elm->lock); @@ -933,7 +959,11 @@ static void elmcan_ldisc_tx_worker(struct work_struct *work) ssize_t actual; spin_lock_bh(&elm->lock); - /* First make sure we're connected. */ + if (elm->hw_failure) { + spin_unlock_bh(&elm->lock); + return; + } + if (!elm->tty || !netif_running(elm->dev)) { spin_unlock_bh(&elm->lock); return; diff --git a/readme.rst b/readme.rst index df78721..d9eb5c1 100644 --- a/readme.rst +++ b/readme.rst @@ -260,8 +260,6 @@ incomplete) data frame:: To Do list for future development ---------------------------------- -- No auto-restart in ``elm327_panic()``? - - Stop current function when in ``elm327_panic()`` - DMA capable rx/tx buffers -- 2.30.2