Commit e7f16495 authored by David S. Miller's avatar David S. Miller

Merge tag 'linux-can-fixes-for-6.0-20220810' of...

Merge tag 'linux-can-fixes-for-6.0-20220810' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can

Marc Kleine-Budde says:

====================
this is a pull request of 4 patches for net/master, with the
whitespace issue fixed.

Fedor Pchelkin contributes 2 fixes for the j1939 CAN protocol.

A patch by me for the ems_usb driver fixes an unaligned access
warning.

Sebastian Würl's patch for the mcp251x driver fixes a race condition
in the receive interrupt.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 996237d9 d80d60b0
...@@ -1070,9 +1070,6 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) ...@@ -1070,9 +1070,6 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
mcp251x_read_2regs(spi, CANINTF, &intf, &eflag); mcp251x_read_2regs(spi, CANINTF, &intf, &eflag);
/* mask out flags we don't care about */
intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR;
/* receive buffer 0 */ /* receive buffer 0 */
if (intf & CANINTF_RX0IF) { if (intf & CANINTF_RX0IF) {
mcp251x_hw_rx(spi, 0); mcp251x_hw_rx(spi, 0);
...@@ -1082,6 +1079,18 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) ...@@ -1082,6 +1079,18 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
if (mcp251x_is_2510(spi)) if (mcp251x_is_2510(spi))
mcp251x_write_bits(spi, CANINTF, mcp251x_write_bits(spi, CANINTF,
CANINTF_RX0IF, 0x00); CANINTF_RX0IF, 0x00);
/* check if buffer 1 is already known to be full, no need to re-read */
if (!(intf & CANINTF_RX1IF)) {
u8 intf1, eflag1;
/* intf needs to be read again to avoid a race condition */
mcp251x_read_2regs(spi, CANINTF, &intf1, &eflag1);
/* combine flags from both operations for error handling */
intf |= intf1;
eflag |= eflag1;
}
} }
/* receive buffer 1 */ /* receive buffer 1 */
...@@ -1092,6 +1101,9 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) ...@@ -1092,6 +1101,9 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
clear_intf |= CANINTF_RX1IF; clear_intf |= CANINTF_RX1IF;
} }
/* mask out flags we don't care about */
intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR;
/* any error or tx interrupt we need to clear? */ /* any error or tx interrupt we need to clear? */
if (intf & (CANINTF_ERR | CANINTF_TX)) if (intf & (CANINTF_ERR | CANINTF_TX))
clear_intf |= intf & (CANINTF_ERR | CANINTF_TX); clear_intf |= intf & (CANINTF_ERR | CANINTF_TX);
......
...@@ -195,7 +195,7 @@ struct __packed ems_cpc_msg { ...@@ -195,7 +195,7 @@ struct __packed ems_cpc_msg {
__le32 ts_sec; /* timestamp in seconds */ __le32 ts_sec; /* timestamp in seconds */
__le32 ts_nsec; /* timestamp in nano seconds */ __le32 ts_nsec; /* timestamp in nano seconds */
union { union __packed {
u8 generic[64]; u8 generic[64];
struct cpc_can_msg can_msg; struct cpc_can_msg can_msg;
struct cpc_can_params can_params; struct cpc_can_params can_params;
......
...@@ -178,7 +178,10 @@ static void j1939_sk_queue_activate_next_locked(struct j1939_session *session) ...@@ -178,7 +178,10 @@ static void j1939_sk_queue_activate_next_locked(struct j1939_session *session)
if (!first) if (!first)
return; return;
if (WARN_ON_ONCE(j1939_session_activate(first))) { if (j1939_session_activate(first)) {
netdev_warn_once(first->priv->ndev,
"%s: 0x%p: Identical session is already activated.\n",
__func__, first);
first->err = -EBUSY; first->err = -EBUSY;
goto activate_next; goto activate_next;
} else { } else {
......
...@@ -260,6 +260,8 @@ static void __j1939_session_drop(struct j1939_session *session) ...@@ -260,6 +260,8 @@ static void __j1939_session_drop(struct j1939_session *session)
static void j1939_session_destroy(struct j1939_session *session) static void j1939_session_destroy(struct j1939_session *session)
{ {
struct sk_buff *skb;
if (session->transmission) { if (session->transmission) {
if (session->err) if (session->err)
j1939_sk_errqueue(session, J1939_ERRQUEUE_TX_ABORT); j1939_sk_errqueue(session, J1939_ERRQUEUE_TX_ABORT);
...@@ -274,7 +276,11 @@ static void j1939_session_destroy(struct j1939_session *session) ...@@ -274,7 +276,11 @@ static void j1939_session_destroy(struct j1939_session *session)
WARN_ON_ONCE(!list_empty(&session->sk_session_queue_entry)); WARN_ON_ONCE(!list_empty(&session->sk_session_queue_entry));
WARN_ON_ONCE(!list_empty(&session->active_session_list_entry)); WARN_ON_ONCE(!list_empty(&session->active_session_list_entry));
skb_queue_purge(&session->skb_queue); while ((skb = skb_dequeue(&session->skb_queue)) != NULL) {
/* drop ref taken in j1939_session_skb_queue() */
skb_unref(skb);
kfree_skb(skb);
}
__j1939_session_drop(session); __j1939_session_drop(session);
j1939_priv_put(session->priv); j1939_priv_put(session->priv);
kfree(session); kfree(session);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment