From 174c95d2526afbf974d9134f7f91fca8c4c8b538 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Wed, 10 Aug 2011 05:18:59 +0000 Subject: slcan: ldisc generated skbs are received in softirq context As this discussion pointed out http://marc.info/?l=linux-netdev&m=131257225602375 netdevices that are based on serial line disciplines should use netif_rx_ni() when pushing received socketbuffers into the netdev rx queue. Following commit 614851601c121b1320a35757ab88292d6272f906 ("slip: fix NOHZ local_softirq_pending 08 warning") this patch updates the slcan driver accordingly. Signed-off-by: Oliver Hartkopp CC: Matvejchikov Ilya CC: Alan Cox Signed-off-by: David S. Miller --- drivers/net/can/slcan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/can') diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index f523f1cc5142..4b70b7e8bdeb 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -197,7 +197,7 @@ static void slc_bump(struct slcan *sl) skb->ip_summed = CHECKSUM_UNNECESSARY; memcpy(skb_put(skb, sizeof(struct can_frame)), &cf, sizeof(struct can_frame)); - netif_rx(skb); + netif_rx_ni(skb); sl->dev->stats.rx_packets++; sl->dev->stats.rx_bytes += cf.can_dlc; -- cgit v1.2.2 From 951f2f960e5bbce20309de44626cf11d17847712 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 8 Aug 2011 06:28:50 +0000 Subject: drivers/net/can/sja1000/plx_pci.c: eliminate double free In this code, the failure_cleanup label calls the function plx_pci_del_card, which frees everything in the card->net_dev array. dev is placed in this array immediately after allocation, so the two subsequent jumps to failure_cleanup should not also call free_sja1000dev, but the second one does. If plx_pci_check_sja1000 fails, then free_sja1000dev is also called on dev. Because dev is already in the card->net_dev array, this implies that when plx_pci_del_card is later called, it may get freed again. So that entry is reset to NULL after the free. Finally, if there is a problem with one channel, there will be a hole in the array. card->channels counts the number of channels that have succeeded, and does not keep track of the index of the largest element in the array that is valid. So the loop in plx_pci_del_card is changed to go up to PLX_PCI_MAX_CHAN, which is only 2. Signed-off-by: Julia Lawall Signed-off-by: David S. Miller --- drivers/net/can/sja1000/plx_pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/can') diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c index 231385b8e08f..c7f3d4ea1167 100644 --- a/drivers/net/can/sja1000/plx_pci.c +++ b/drivers/net/can/sja1000/plx_pci.c @@ -408,7 +408,7 @@ static void plx_pci_del_card(struct pci_dev *pdev) struct sja1000_priv *priv; int i = 0; - for (i = 0; i < card->channels; i++) { + for (i = 0; i < PLX_PCI_MAX_CHAN; i++) { dev = card->net_dev[i]; if (!dev) continue; @@ -536,7 +536,6 @@ static int __devinit plx_pci_add_card(struct pci_dev *pdev, if (err) { dev_err(&pdev->dev, "Registering device failed " "(err=%d)\n", err); - free_sja1000dev(dev); goto failure_cleanup; } @@ -549,6 +548,7 @@ static int __devinit plx_pci_add_card(struct pci_dev *pdev, dev_err(&pdev->dev, "Channel #%d not detected\n", i + 1); free_sja1000dev(dev); + card->net_dev[i] = NULL; } } -- cgit v1.2.2 From 6f288cc52f478e6f58d96158e7cd857fedb6d111 Mon Sep 17 00:00:00 2001 From: Abhilash K V Date: Tue, 23 Aug 2011 03:05:48 +0000 Subject: can: ti_hecc: Fix unintialized variable In ti_hecc_xmit(), local variable "data" is not initialized before being used. This initialization got inadvertently removed in the following patch: can: Unify droping of invalid tx skbs and netdev stats Acked-by: Anant Gole Signed-off-by: Abhilash K V Signed-off-by: David S. Miller --- drivers/net/can/ti_hecc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/can') diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index f7bbde9eb2cb..0b19a17d8178 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -503,9 +503,9 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev) spin_unlock_irqrestore(&priv->mbx_lock, flags); /* Prepare mailbox for transmission */ + data = cf->can_dlc | (get_tx_head_prio(priv) << 8); if (cf->can_id & CAN_RTR_FLAG) /* Remote transmission request */ data |= HECC_CANMCF_RTR; - data |= get_tx_head_prio(priv) << 8; hecc_write_mbx(priv, mbxno, HECC_CANMCF, data); if (cf->can_id & CAN_EFF_FLAG) /* Extended frame format */ -- cgit v1.2.2 From 86ad47fff97a9e416aadedfe68909b2d9143dc42 Mon Sep 17 00:00:00 2001 From: Abhilash K V Date: Tue, 23 Aug 2011 03:05:57 +0000 Subject: can: ti_hecc: Fix uninitialized spinlock in probe In ti_hecc_probe(), the spinlock priv->mbx_lock is not inited, causing a spinlock lockup BUG. Acked-by: Anant Gole Signed-off-by: Abhilash K V Signed-off-by: David S. Miller --- drivers/net/can/ti_hecc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/can') diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index 0b19a17d8178..a81249246ece 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -923,6 +923,7 @@ static int ti_hecc_probe(struct platform_device *pdev) priv->can.do_get_state = ti_hecc_get_state; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; + spin_lock_init(&priv->mbx_lock); ndev->irq = irq->start; ndev->flags |= IFF_ECHO; platform_set_drvdata(pdev, ndev); -- cgit v1.2.2 From 34b8686d278f00fb16234e74be44c253d6d6b676 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 16 Sep 2011 07:57:43 +0000 Subject: can: ti_hecc: include linux/io.h This fixes a build breakage for OMAP3 boards. Signed-off-by: Daniel Mack Cc: Wolfgang Grandegger Cc: netdev@vger.kernel.org Acked-by: Wolfgang Grandegger Signed-off-by: David S. Miller --- drivers/net/can/ti_hecc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/can') diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index a81249246ece..2adc294f512a 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include -- cgit v1.2.2 From a3a4bfde8a271df7ee56fcf31b8d907d50e7f216 Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Fri, 7 Oct 2011 09:28:14 +0000 Subject: mscan: too much data copied to CAN frame due to 16 bit accesses Due to the 16 bit access to mscan registers there's too much data copied to the zero initialized CAN frame when having an odd number of bytes to copy. This patch ensures that only the requested bytes are copied by using an 8 bit access for the remaining byte. Reported-by: Andre Naujoks Signed-off-by: Oliver Hartkopp Signed-off-by: Wolfgang Grandegger Signed-off-by: David S. Miller --- drivers/net/can/mscan/mscan.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/net/can') diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c index 92feac68b66e..4cc6f44c2ba2 100644 --- a/drivers/net/can/mscan/mscan.c +++ b/drivers/net/can/mscan/mscan.c @@ -261,11 +261,13 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev) void __iomem *data = ®s->tx.dsr1_0; u16 *payload = (u16 *)frame->data; - /* It is safe to write into dsr[dlc+1] */ - for (i = 0; i < (frame->can_dlc + 1) / 2; i++) { + for (i = 0; i < frame->can_dlc / 2; i++) { out_be16(data, *payload++); data += 2 + _MSCAN_RESERVED_DSR_SIZE; } + /* write remaining byte if necessary */ + if (frame->can_dlc & 1) + out_8(data, frame->data[frame->can_dlc - 1]); } out_8(®s->tx.dlr, frame->can_dlc); @@ -330,10 +332,13 @@ static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame) void __iomem *data = ®s->rx.dsr1_0; u16 *payload = (u16 *)frame->data; - for (i = 0; i < (frame->can_dlc + 1) / 2; i++) { + for (i = 0; i < frame->can_dlc / 2; i++) { *payload++ = in_be16(data); data += 2 + _MSCAN_RESERVED_DSR_SIZE; } + /* read remaining byte if necessary */ + if (frame->can_dlc & 1) + frame->data[frame->can_dlc - 1] = in_8(data); } out_8(®s->canrflg, MSCAN_RXF); -- cgit v1.2.2