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

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
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -1070,9 +1070,6 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)

		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 */
		if (intf & CANINTF_RX0IF) {
			mcp251x_hw_rx(spi, 0);
@@ -1082,6 +1079,18 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
			if (mcp251x_is_2510(spi))
				mcp251x_write_bits(spi, CANINTF,
						   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 */
@@ -1092,6 +1101,9 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id)
				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? */
		if (intf & (CANINTF_ERR | CANINTF_TX))
			clear_intf |= intf & (CANINTF_ERR | CANINTF_TX);
+1 −1
Original line number Diff line number Diff line
@@ -195,7 +195,7 @@ struct __packed ems_cpc_msg {
	__le32 ts_sec;	/* timestamp in seconds */
	__le32 ts_nsec;	/* timestamp in nano seconds */

	union {
	union __packed {
		u8 generic[64];
		struct cpc_can_msg can_msg;
		struct cpc_can_params can_params;
+4 −1
Original line number Diff line number Diff line
@@ -178,7 +178,10 @@ static void j1939_sk_queue_activate_next_locked(struct j1939_session *session)
	if (!first)
		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;
		goto activate_next;
	} else {
+7 −1
Original line number Diff line number Diff line
@@ -260,6 +260,8 @@ static void __j1939_session_drop(struct j1939_session *session)

static void j1939_session_destroy(struct j1939_session *session)
{
	struct sk_buff *skb;

	if (session->transmission) {
		if (session->err)
			j1939_sk_errqueue(session, J1939_ERRQUEUE_TX_ABORT);
@@ -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->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_priv_put(session->priv);
	kfree(session);