summaryrefslogtreecommitdiff
path: root/drivers/net/can/slcan/slcan-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/can/slcan/slcan-core.c')
-rw-r--r--drivers/net/can/slcan/slcan-core.c117
1 files changed, 53 insertions, 64 deletions
diff --git a/drivers/net/can/slcan/slcan-core.c b/drivers/net/can/slcan/slcan-core.c
index 54d29a410ad5..dc28e715bbe1 100644
--- a/drivers/net/can/slcan/slcan-core.c
+++ b/drivers/net/can/slcan/slcan-core.c
@@ -67,13 +67,14 @@ MODULE_AUTHOR("Oliver Hartkopp <socketcan@hartkopp.net>");
#define SLCAN_MAGIC 0x53CA
static int maxdev = 10; /* MAX number of SLCAN channels;
- This can be overridden with
- insmod slcan.ko maxdev=nnn */
+ * This can be overridden with
+ * insmod slcan.ko maxdev=nnn
+ */
module_param(maxdev, int, 0);
MODULE_PARM_DESC(maxdev, "Maximum number of slcan interfaces");
/* maximum rx buffer len: extended CAN frame with timestamp */
-#define SLC_MTU (sizeof("T1111222281122334455667788EA5F\r")+1)
+#define SLC_MTU (sizeof("T1111222281122334455667788EA5F\r") + 1)
#define SLC_CMD_LEN 1
#define SLC_SFF_ID_LEN 3
@@ -139,12 +140,11 @@ int slcan_enable_err_rst_on_open(struct net_device *ndev, bool on)
return 0;
}
- /************************************************************************
- * SLCAN ENCAPSULATION FORMAT *
- ************************************************************************/
+/*************************************************************************
+ * SLCAN ENCAPSULATION FORMAT *
+ *************************************************************************/
-/*
- * A CAN frame has a can_id (11 bit standard frame format OR 29 bit extended
+/* A CAN frame has a can_id (11 bit standard frame format OR 29 bit extended
* frame format) a data length code (len) which can be from 0 to 8
* and up to <len> data bytes as payload.
* Additionally a CAN frame may become a remote transmission frame if the
@@ -174,9 +174,9 @@ int slcan_enable_err_rst_on_open(struct net_device *ndev, bool on)
*
*/
- /************************************************************************
- * STANDARD SLCAN DECAPSULATION *
- ************************************************************************/
+/*************************************************************************
+ * STANDARD SLCAN DECAPSULATION *
+ *************************************************************************/
/* Send one completely decapsulated can_frame to the network layer */
static void slc_bump_frame(struct slcan *sl)
@@ -306,19 +306,18 @@ static void slc_bump_state(struct slcan *sl)
return;
skb = alloc_can_err_skb(dev, &cf);
- if (skb) {
- cf->data[6] = txerr;
- cf->data[7] = rxerr;
- } else {
- cf = NULL;
- }
tx_state = txerr >= rxerr ? state : 0;
rx_state = txerr <= rxerr ? state : 0;
can_change_state(dev, cf, tx_state, rx_state);
- if (state == CAN_STATE_BUS_OFF)
+ if (state == CAN_STATE_BUS_OFF) {
can_bus_off(dev);
+ } else if (skb) {
+ cf->can_id |= CAN_ERR_CNT;
+ cf->data[6] = txerr;
+ cf->data[7] = rxerr;
+ }
if (skb)
netif_rx(skb);
@@ -469,26 +468,26 @@ static void slcan_unesc(struct slcan *sl, unsigned char s)
{
if ((s == '\r') || (s == '\a')) { /* CR or BEL ends the pdu */
if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
- (sl->rcount > 4)) {
+ sl->rcount > 4)
slc_bump(sl);
- }
+
sl->rcount = 0;
} else {
if (!test_bit(SLF_ERROR, &sl->flags)) {
if (sl->rcount < SLC_MTU) {
sl->rbuff[sl->rcount++] = s;
return;
- } else {
- sl->dev->stats.rx_over_errors++;
- set_bit(SLF_ERROR, &sl->flags);
}
+
+ sl->dev->stats.rx_over_errors++;
+ set_bit(SLF_ERROR, &sl->flags);
}
}
}
- /************************************************************************
- * STANDARD SLCAN ENCAPSULATION *
- ************************************************************************/
+/*************************************************************************
+ * STANDARD SLCAN ENCAPSULATION *
+ *************************************************************************/
/* Encapsulate one can_frame and stuff into a TTY queue. */
static void slc_encaps(struct slcan *sl, struct can_frame *cf)
@@ -575,7 +574,8 @@ static void slcan_transmit(struct work_struct *work)
}
/* Now serial buffer is almost free & we can start
- * transmission of another packet */
+ * transmission of another packet
+ */
sl->dev->stats.tx_packets++;
clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
spin_unlock_bh(&sl->lock);
@@ -589,8 +589,7 @@ static void slcan_transmit(struct work_struct *work)
spin_unlock_bh(&sl->lock);
}
-/*
- * Called by the driver when there's room for more data.
+/* Called by the driver when there's room for more data.
* Schedule the transmit.
*/
static void slcan_write_wakeup(struct tty_struct *tty)
@@ -618,13 +617,13 @@ static netdev_tx_t slc_xmit(struct sk_buff *skb, struct net_device *dev)
netdev_warn(dev, "xmit: iface is down\n");
goto out;
}
- if (sl->tty == NULL) {
+ if (!sl->tty) {
spin_unlock(&sl->lock);
goto out;
}
netif_stop_queue(sl->dev);
- slc_encaps(sl, (struct can_frame *) skb->data); /* encaps & send */
+ slc_encaps(sl, (struct can_frame *)skb->data); /* encaps & send */
spin_unlock(&sl->lock);
out:
@@ -632,7 +631,6 @@ out:
return NETDEV_TX_OK;
}
-
/******************************************
* Routines looking at netdevice side.
******************************************/
@@ -647,7 +645,7 @@ static int slcan_transmit_cmd(struct slcan *sl, const unsigned char *cmd)
return -ENODEV;
}
- n = snprintf(sl->xbuff, sizeof(sl->xbuff), "%s", cmd);
+ n = scnprintf(sl->xbuff, sizeof(sl->xbuff), "%s", cmd);
set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
actual = sl->tty->ops->write(sl->tty, sl->xbuff, n);
sl->xleft = n - actual;
@@ -689,15 +687,14 @@ static int slc_close(struct net_device *dev)
clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
}
netif_stop_queue(dev);
+ sl->rcount = 0;
+ sl->xleft = 0;
+ spin_unlock_bh(&sl->lock);
close_candev(dev);
sl->can.state = CAN_STATE_STOPPED;
if (sl->can.bittiming.bitrate == CAN_BITRATE_UNKNOWN)
sl->can.bittiming.bitrate = CAN_BITRATE_UNSET;
- sl->rcount = 0;
- sl->xleft = 0;
- spin_unlock_bh(&sl->lock);
-
return 0;
}
@@ -708,7 +705,7 @@ static int slc_open(struct net_device *dev)
unsigned char cmd[SLC_MTU];
int err, s;
- if (sl->tty == NULL)
+ if (!sl->tty)
return -ENODEV;
/* The baud rate is not set with the command
@@ -736,7 +733,6 @@ static int slc_open(struct net_device *dev)
/* The CAN framework has already validate the bitrate value,
* so we can avoid to check if `s' has been properly set.
*/
-
snprintf(cmd, sizeof(cmd), "C\rS%d\r", s);
err = slcan_transmit_cmd(sl, cmd);
if (err) {
@@ -792,23 +788,21 @@ static const struct net_device_ops slc_netdev_ops = {
};
/******************************************
- Routines looking at TTY side.
+ * Routines looking at TTY side.
******************************************/
-/*
- * Handle the 'receiver data ready' interrupt.
+/* Handle the 'receiver data ready' interrupt.
* This function is called by the 'tty_io' module in the kernel when
* a block of SLCAN data has been received, which can now be decapsulated
* and sent on to some IP layer for further processing. This will not
* be re-entered while running but other ldisc functions may be called
* in parallel
*/
-
static void slcan_receive_buf(struct tty_struct *tty,
const unsigned char *cp, const char *fp,
int count)
{
- struct slcan *sl = (struct slcan *) tty->disc_data;
+ struct slcan *sl = (struct slcan *)tty->disc_data;
if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
return;
@@ -838,7 +832,7 @@ static void slc_sync(void)
for (i = 0; i < maxdev; i++) {
dev = slcan_devs[i];
- if (dev == NULL)
+ if (!dev)
break;
sl = netdev_priv(dev);
@@ -858,9 +852,8 @@ static struct slcan *slc_alloc(void)
for (i = 0; i < maxdev; i++) {
dev = slcan_devs[i];
- if (dev == NULL)
+ if (!dev)
break;
-
}
/* Sorry, too many, all slots in use */
@@ -890,8 +883,7 @@ static struct slcan *slc_alloc(void)
return sl;
}
-/*
- * Open the high-level part of the SLCAN channel.
+/* Open the high-level part of the SLCAN channel.
* This function is called by the TTY module when the
* SLCAN line discipline is called for. Because we are
* sure the tty line exists, we only have to link it to
@@ -899,7 +891,6 @@ static struct slcan *slc_alloc(void)
*
* Called in process context serialized from other ldisc calls.
*/
-
static int slcan_open(struct tty_struct *tty)
{
struct slcan *sl;
@@ -908,12 +899,12 @@ static int slcan_open(struct tty_struct *tty)
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if (tty->ops->write == NULL)
+ if (!tty->ops->write)
return -EOPNOTSUPP;
/* RTnetlink lock is misused here to serialize concurrent
- opens of slcan channels. There are better ways, but it is
- the simplest one.
+ * opens of slcan channels. There are better ways, but it is
+ * the simplest one.
*/
rtnl_lock();
@@ -930,7 +921,7 @@ static int slcan_open(struct tty_struct *tty)
/* OK. Find a free SLCAN channel to use. */
err = -ENFILE;
sl = slc_alloc();
- if (sl == NULL)
+ if (!sl)
goto err_exit;
sl->tty = tty;
@@ -974,17 +965,15 @@ err_exit:
return err;
}
-/*
- * Close down a SLCAN channel.
+/* Close down a SLCAN channel.
* This means flushing out any pending queues, and then returning. This
* call is serialized against other ldisc functions.
*
* We also use this method for a hangup event.
*/
-
static void slcan_close(struct tty_struct *tty)
{
- struct slcan *sl = (struct slcan *) tty->disc_data;
+ struct slcan *sl = (struct slcan *)tty->disc_data;
/* First make sure we're connected. */
if (!sl || sl->magic != SLCAN_MAGIC || sl->tty != tty)
@@ -1014,7 +1003,7 @@ static void slcan_hangup(struct tty_struct *tty)
static int slcan_ioctl(struct tty_struct *tty, unsigned int cmd,
unsigned long arg)
{
- struct slcan *sl = (struct slcan *) tty->disc_data;
+ struct slcan *sl = (struct slcan *)tty->disc_data;
unsigned int tmp;
/* First make sure we're connected. */
@@ -1065,7 +1054,7 @@ static int __init slcan_init(void)
/* Fill in our line protocol discipline, and register it */
status = tty_register_ldisc(&slc_ldisc);
if (status) {
- printk(KERN_ERR "slcan: can't register line discipline\n");
+ pr_err("slcan: can't register line discipline\n");
kfree(slcan_devs);
}
return status;
@@ -1079,7 +1068,7 @@ static void __exit slcan_exit(void)
unsigned long timeout = jiffies + HZ;
int busy = 0;
- if (slcan_devs == NULL)
+ if (!slcan_devs)
return;
/* First of all: check for active disciplines and hangup them.
@@ -1104,7 +1093,8 @@ static void __exit slcan_exit(void)
} while (busy && time_before(jiffies, timeout));
/* FIXME: hangup is async so we should wait when doing this second
- phase */
+ * phase
+ */
for (i = 0; i < maxdev; i++) {
dev = slcan_devs[i];
@@ -1112,9 +1102,8 @@ static void __exit slcan_exit(void)
continue;
sl = netdev_priv(dev);
- if (sl->tty) {
+ if (sl->tty)
netdev_err(dev, "tty discipline still running\n");
- }
slc_close(dev);
unregister_candev(dev);