From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
patches@lists.linux.dev, Frank Jungclaus <frank.jungclaus@esd.eu>,
Marc Kleine-Budde <mkl@pengutronix.de>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH 5.15 125/272] can/esd_usb2: Rename esd_usb2.c to esd_usb.c
Date: Thu, 20 Aug 2026 16:55:09 +0200 [thread overview]
Message-ID: <20260820145235.013938194@linuxfoundation.org> (raw)
In-Reply-To: <20260820145231.229664293@linuxfoundation.org>
5.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Jungclaus <frank.jungclaus@esd.eu>
[ Upstream commit 5e910bdedc84c1f196863cebdf27c1806449c27c ]
As suggested by Vincent, renaming of esd_usb2.c to esd_usb.c
and according to that, adaption of Kconfig and Makfile, too.
Link: https://lore.kernel.org/all/20220624190517.2299701-2-frank.jungclaus@esd.eu
Signed-off-by: Frank Jungclaus <frank.jungclaus@esd.eu>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Stable-dep-of: c43122fef328 ("can: esd_usb: kill anchored URBs before freeing netdevs")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/can/usb/Kconfig | 15 +++++++++++----
drivers/net/can/usb/Makefile | 2 +-
drivers/net/can/usb/{esd_usb2.c => esd_usb.c} | 0
drivers/net/can/usb/Kconfig | 15
drivers/net/can/usb/Makefile | 2
drivers/net/can/usb/esd_usb.c | 1170 +++++++++++++++++++++++++++++++++++++++++
drivers/net/can/usb/esd_usb2.c | 1170 -----------------------------------------
4 files changed, 1182 insertions(+), 1175 deletions(-)
rename drivers/net/can/usb/{esd_usb2.c => esd_usb.c} (100%)
--- a/drivers/net/can/usb/Kconfig
+++ b/drivers/net/can/usb/Kconfig
@@ -14,11 +14,18 @@ config CAN_EMS_USB
This driver is for the one channel CPC-USB/ARM7 CAN/USB interface
from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
-config CAN_ESD_USB2
- tristate "ESD USB/2 CAN/USB interface"
+config CAN_ESD_USB
+ tristate "esd electronics gmbh CAN/USB interfaces"
help
- This driver supports the CAN-USB/2 interface
- from esd electronic system design gmbh (http://www.esd.eu).
+ This driver adds supports for several CAN/USB interfaces
+ from esd electronics gmbh (https://www.esd.eu).
+
+ The drivers supports the following devices:
+ - esd CAN-USB/2
+ - esd CAN-USB/Micro
+
+ To compile this driver as a module, choose M here: the module
+ will be called esd_usb.
config CAN_ETAS_ES58X
tristate "ETAS ES58X CAN/USB interfaces"
--- a/drivers/net/can/usb/Makefile
+++ b/drivers/net/can/usb/Makefile
@@ -5,7 +5,7 @@
obj-$(CONFIG_CAN_8DEV_USB) += usb_8dev.o
obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o
-obj-$(CONFIG_CAN_ESD_USB2) += esd_usb2.o
+obj-$(CONFIG_CAN_ESD_USB) += esd_usb.o
obj-$(CONFIG_CAN_ETAS_ES58X) += etas_es58x/
obj-$(CONFIG_CAN_GS_USB) += gs_usb.o
obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb/
--- /dev/null
+++ b/drivers/net/can/usb/esd_usb.c
@@ -0,0 +1,1170 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * CAN driver for esd CAN-USB/2 and CAN-USB/Micro
+ *
+ * Copyright (C) 2010-2012 Matthias Fuchs <matthias.fuchs@esd.eu>, esd gmbh
+ */
+#include <linux/signal.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/usb.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+
+MODULE_AUTHOR("Matthias Fuchs <matthias.fuchs@esd.eu>");
+MODULE_DESCRIPTION("CAN driver for esd CAN-USB/2 and CAN-USB/Micro interfaces");
+MODULE_LICENSE("GPL v2");
+
+/* Define these values to match your devices */
+#define USB_ESDGMBH_VENDOR_ID 0x0ab4
+#define USB_CANUSB2_PRODUCT_ID 0x0010
+#define USB_CANUSBM_PRODUCT_ID 0x0011
+
+#define ESD_USB2_CAN_CLOCK 60000000
+#define ESD_USBM_CAN_CLOCK 36000000
+#define ESD_USB2_MAX_NETS 2
+
+/* USB2 commands */
+#define CMD_VERSION 1 /* also used for VERSION_REPLY */
+#define CMD_CAN_RX 2 /* device to host only */
+#define CMD_CAN_TX 3 /* also used for TX_DONE */
+#define CMD_SETBAUD 4 /* also used for SETBAUD_REPLY */
+#define CMD_TS 5 /* also used for TS_REPLY */
+#define CMD_IDADD 6 /* also used for IDADD_REPLY */
+
+/* esd CAN message flags - dlc field */
+#define ESD_RTR 0x10
+
+/* esd CAN message flags - id field */
+#define ESD_EXTID 0x20000000
+#define ESD_EVENT 0x40000000
+#define ESD_IDMASK 0x1fffffff
+
+/* esd CAN event ids used by this driver */
+#define ESD_EV_CAN_ERROR_EXT 2
+
+/* baudrate message flags */
+#define ESD_USB2_UBR 0x80000000
+#define ESD_USB2_LOM 0x40000000
+#define ESD_USB2_NO_BAUDRATE 0x7fffffff
+#define ESD_USB2_TSEG1_MIN 1
+#define ESD_USB2_TSEG1_MAX 16
+#define ESD_USB2_TSEG1_SHIFT 16
+#define ESD_USB2_TSEG2_MIN 1
+#define ESD_USB2_TSEG2_MAX 8
+#define ESD_USB2_TSEG2_SHIFT 20
+#define ESD_USB2_SJW_MAX 4
+#define ESD_USB2_SJW_SHIFT 14
+#define ESD_USBM_SJW_SHIFT 24
+#define ESD_USB2_BRP_MIN 1
+#define ESD_USB2_BRP_MAX 1024
+#define ESD_USB2_BRP_INC 1
+#define ESD_USB2_3_SAMPLES 0x00800000
+
+/* esd IDADD message */
+#define ESD_ID_ENABLE 0x80
+#define ESD_MAX_ID_SEGMENT 64
+
+/* SJA1000 ECC register (emulated by usb2 firmware) */
+#define SJA1000_ECC_SEG 0x1F
+#define SJA1000_ECC_DIR 0x20
+#define SJA1000_ECC_ERR 0x06
+#define SJA1000_ECC_BIT 0x00
+#define SJA1000_ECC_FORM 0x40
+#define SJA1000_ECC_STUFF 0x80
+#define SJA1000_ECC_MASK 0xc0
+
+/* esd bus state event codes */
+#define ESD_BUSSTATE_MASK 0xc0
+#define ESD_BUSSTATE_WARN 0x40
+#define ESD_BUSSTATE_ERRPASSIVE 0x80
+#define ESD_BUSSTATE_BUSOFF 0xc0
+
+#define RX_BUFFER_SIZE 1024
+#define MAX_RX_URBS 4
+#define MAX_TX_URBS 16 /* must be power of 2 */
+
+struct header_msg {
+ u8 len; /* len is always the total message length in 32bit words */
+ u8 cmd;
+ u8 rsvd[2];
+};
+
+struct version_msg {
+ u8 len;
+ u8 cmd;
+ u8 rsvd;
+ u8 flags;
+ __le32 drv_version;
+};
+
+struct version_reply_msg {
+ u8 len;
+ u8 cmd;
+ u8 nets;
+ u8 features;
+ __le32 version;
+ u8 name[16];
+ __le32 rsvd;
+ __le32 ts;
+};
+
+struct rx_msg {
+ u8 len;
+ u8 cmd;
+ u8 net;
+ u8 dlc;
+ __le32 ts;
+ __le32 id; /* upper 3 bits contain flags */
+ u8 data[8];
+};
+
+struct tx_msg {
+ u8 len;
+ u8 cmd;
+ u8 net;
+ u8 dlc;
+ u32 hnd; /* opaque handle, not used by device */
+ __le32 id; /* upper 3 bits contain flags */
+ u8 data[8];
+};
+
+struct tx_done_msg {
+ u8 len;
+ u8 cmd;
+ u8 net;
+ u8 status;
+ u32 hnd; /* opaque handle, not used by device */
+ __le32 ts;
+};
+
+struct id_filter_msg {
+ u8 len;
+ u8 cmd;
+ u8 net;
+ u8 option;
+ __le32 mask[ESD_MAX_ID_SEGMENT + 1];
+};
+
+struct set_baudrate_msg {
+ u8 len;
+ u8 cmd;
+ u8 net;
+ u8 rsvd;
+ __le32 baud;
+};
+
+/* Main message type used between library and application */
+struct __attribute__ ((packed)) esd_usb2_msg {
+ union {
+ struct header_msg hdr;
+ struct version_msg version;
+ struct version_reply_msg version_reply;
+ struct rx_msg rx;
+ struct tx_msg tx;
+ struct tx_done_msg txdone;
+ struct set_baudrate_msg setbaud;
+ struct id_filter_msg filter;
+ } msg;
+};
+
+static struct usb_device_id esd_usb2_table[] = {
+ {USB_DEVICE(USB_ESDGMBH_VENDOR_ID, USB_CANUSB2_PRODUCT_ID)},
+ {USB_DEVICE(USB_ESDGMBH_VENDOR_ID, USB_CANUSBM_PRODUCT_ID)},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, esd_usb2_table);
+
+struct esd_usb2_net_priv;
+
+struct esd_tx_urb_context {
+ struct esd_usb2_net_priv *priv;
+ u32 echo_index;
+ int len; /* CAN payload length */
+};
+
+struct esd_usb2 {
+ struct usb_device *udev;
+ struct esd_usb2_net_priv *nets[ESD_USB2_MAX_NETS];
+
+ struct usb_anchor rx_submitted;
+
+ int net_count;
+ u32 version;
+ int rxinitdone;
+ void *rxbuf[MAX_RX_URBS];
+ dma_addr_t rxbuf_dma[MAX_RX_URBS];
+};
+
+struct esd_usb2_net_priv {
+ struct can_priv can; /* must be the first member */
+
+ atomic_t active_tx_jobs;
+ struct usb_anchor tx_submitted;
+ struct esd_tx_urb_context tx_contexts[MAX_TX_URBS];
+
+ struct esd_usb2 *usb2;
+ struct net_device *netdev;
+ int index;
+ u8 old_state;
+ struct can_berr_counter bec;
+};
+
+static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv,
+ struct esd_usb2_msg *msg)
+{
+ struct net_device_stats *stats = &priv->netdev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ u32 id = le32_to_cpu(msg->msg.rx.id) & ESD_IDMASK;
+
+ if (id == ESD_EV_CAN_ERROR_EXT) {
+ u8 state = msg->msg.rx.data[0];
+ u8 ecc = msg->msg.rx.data[1];
+ u8 rxerr = msg->msg.rx.data[2];
+ u8 txerr = msg->msg.rx.data[3];
+
+ netdev_dbg(priv->netdev,
+ "CAN_ERR_EV_EXT: dlc=%#02x state=%02x ecc=%02x rec=%02x tec=%02x\n",
+ msg->msg.rx.dlc, state, ecc, rxerr, txerr);
+
+ skb = alloc_can_err_skb(priv->netdev, &cf);
+ if (skb == NULL) {
+ stats->rx_dropped++;
+ return;
+ }
+
+ if (state != priv->old_state) {
+ priv->old_state = state;
+
+ switch (state & ESD_BUSSTATE_MASK) {
+ case ESD_BUSSTATE_BUSOFF:
+ priv->can.state = CAN_STATE_BUS_OFF;
+ cf->can_id |= CAN_ERR_BUSOFF;
+ priv->can.can_stats.bus_off++;
+ can_bus_off(priv->netdev);
+ break;
+ case ESD_BUSSTATE_WARN:
+ priv->can.state = CAN_STATE_ERROR_WARNING;
+ priv->can.can_stats.error_warning++;
+ break;
+ case ESD_BUSSTATE_ERRPASSIVE:
+ priv->can.state = CAN_STATE_ERROR_PASSIVE;
+ priv->can.can_stats.error_passive++;
+ break;
+ default:
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+ txerr = 0;
+ rxerr = 0;
+ break;
+ }
+ } else {
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+ switch (ecc & SJA1000_ECC_MASK) {
+ case SJA1000_ECC_BIT:
+ cf->data[2] |= CAN_ERR_PROT_BIT;
+ break;
+ case SJA1000_ECC_FORM:
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ break;
+ case SJA1000_ECC_STUFF:
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ break;
+ default:
+ break;
+ }
+
+ /* Error occurred during transmission? */
+ if (!(ecc & SJA1000_ECC_DIR))
+ cf->data[2] |= CAN_ERR_PROT_TX;
+
+ /* Bit stream position in CAN frame as the error was detected */
+ cf->data[3] = ecc & SJA1000_ECC_SEG;
+
+ if (priv->can.state == CAN_STATE_ERROR_WARNING ||
+ priv->can.state == CAN_STATE_ERROR_PASSIVE) {
+ cf->data[1] = (txerr > rxerr) ?
+ CAN_ERR_CRTL_TX_PASSIVE :
+ CAN_ERR_CRTL_RX_PASSIVE;
+ }
+ cf->data[6] = txerr;
+ cf->data[7] = rxerr;
+ }
+
+ priv->bec.txerr = txerr;
+ priv->bec.rxerr = rxerr;
+
+ netif_rx(skb);
+ }
+}
+
+static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv,
+ struct esd_usb2_msg *msg)
+{
+ struct net_device_stats *stats = &priv->netdev->stats;
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ int i;
+ u32 id;
+
+ if (!netif_device_present(priv->netdev))
+ return;
+
+ id = le32_to_cpu(msg->msg.rx.id);
+
+ if (id & ESD_EVENT) {
+ esd_usb2_rx_event(priv, msg);
+ } else {
+ skb = alloc_can_skb(priv->netdev, &cf);
+ if (skb == NULL) {
+ stats->rx_dropped++;
+ return;
+ }
+
+ cf->can_id = id & ESD_IDMASK;
+ can_frame_set_cc_len(cf, msg->msg.rx.dlc & ~ESD_RTR,
+ priv->can.ctrlmode);
+
+ if (id & ESD_EXTID)
+ cf->can_id |= CAN_EFF_FLAG;
+
+ if (msg->msg.rx.dlc & ESD_RTR) {
+ cf->can_id |= CAN_RTR_FLAG;
+ } else {
+ for (i = 0; i < cf->len; i++)
+ cf->data[i] = msg->msg.rx.data[i];
+ }
+
+ stats->rx_packets++;
+ stats->rx_bytes += cf->len;
+ netif_rx(skb);
+ }
+
+ return;
+}
+
+static void esd_usb2_tx_done_msg(struct esd_usb2_net_priv *priv,
+ struct esd_usb2_msg *msg)
+{
+ struct net_device_stats *stats = &priv->netdev->stats;
+ struct net_device *netdev = priv->netdev;
+ struct esd_tx_urb_context *context;
+
+ if (!netif_device_present(netdev))
+ return;
+
+ context = &priv->tx_contexts[msg->msg.txdone.hnd & (MAX_TX_URBS - 1)];
+
+ if (!msg->msg.txdone.status) {
+ stats->tx_packets++;
+ stats->tx_bytes += context->len;
+ can_get_echo_skb(netdev, context->echo_index, NULL);
+ } else {
+ stats->tx_errors++;
+ can_free_echo_skb(netdev, context->echo_index, NULL);
+ }
+
+ /* Release context */
+ context->echo_index = MAX_TX_URBS;
+ atomic_dec(&priv->active_tx_jobs);
+
+ netif_wake_queue(netdev);
+}
+
+static void esd_usb2_read_bulk_callback(struct urb *urb)
+{
+ struct esd_usb2 *dev = urb->context;
+ int retval;
+ int pos = 0;
+ int i;
+
+ switch (urb->status) {
+ case 0: /* success */
+ break;
+
+ case -ENOENT:
+ case -EPIPE:
+ case -EPROTO:
+ case -ESHUTDOWN:
+ return;
+
+ default:
+ dev_info(dev->udev->dev.parent,
+ "Rx URB aborted (%d)\n", urb->status);
+ goto resubmit_urb;
+ }
+
+ while (pos < urb->actual_length) {
+ struct esd_usb2_msg *msg;
+
+ msg = (struct esd_usb2_msg *)(urb->transfer_buffer + pos);
+
+ switch (msg->msg.hdr.cmd) {
+ case CMD_CAN_RX:
+ if (msg->msg.rx.net >= dev->net_count) {
+ dev_err(dev->udev->dev.parent, "format error\n");
+ break;
+ }
+
+ esd_usb2_rx_can_msg(dev->nets[msg->msg.rx.net], msg);
+ break;
+
+ case CMD_CAN_TX:
+ if (msg->msg.txdone.net >= dev->net_count) {
+ dev_err(dev->udev->dev.parent, "format error\n");
+ break;
+ }
+
+ esd_usb2_tx_done_msg(dev->nets[msg->msg.txdone.net],
+ msg);
+ break;
+ }
+
+ pos += msg->msg.hdr.len << 2;
+
+ if (pos > urb->actual_length) {
+ dev_err(dev->udev->dev.parent, "format error\n");
+ break;
+ }
+ }
+
+resubmit_urb:
+ usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
+ urb->transfer_buffer, RX_BUFFER_SIZE,
+ esd_usb2_read_bulk_callback, dev);
+
+ usb_anchor_urb(urb, &dev->rx_submitted);
+
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+ if (!retval)
+ return;
+
+ usb_unanchor_urb(urb);
+
+ if (retval == -ENODEV) {
+ for (i = 0; i < dev->net_count; i++) {
+ if (dev->nets[i])
+ netif_device_detach(dev->nets[i]->netdev);
+ }
+ } else {
+ dev_err(dev->udev->dev.parent,
+ "failed resubmitting read bulk urb: %d\n", retval);
+ }
+
+ return;
+}
+
+/*
+ * callback for bulk IN urb
+ */
+static void esd_usb2_write_bulk_callback(struct urb *urb)
+{
+ struct esd_tx_urb_context *context = urb->context;
+ struct esd_usb2_net_priv *priv;
+ struct net_device *netdev;
+ size_t size = sizeof(struct esd_usb2_msg);
+
+ WARN_ON(!context);
+
+ priv = context->priv;
+ netdev = priv->netdev;
+
+ /* free up our allocated buffer */
+ usb_free_coherent(urb->dev, size,
+ urb->transfer_buffer, urb->transfer_dma);
+
+ if (!netif_device_present(netdev))
+ return;
+
+ if (urb->status)
+ netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status);
+
+ netif_trans_update(netdev);
+}
+
+static ssize_t firmware_show(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *intf = to_usb_interface(d);
+ struct esd_usb2 *dev = usb_get_intfdata(intf);
+
+ return sprintf(buf, "%d.%d.%d\n",
+ (dev->version >> 12) & 0xf,
+ (dev->version >> 8) & 0xf,
+ dev->version & 0xff);
+}
+static DEVICE_ATTR_RO(firmware);
+
+static ssize_t hardware_show(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *intf = to_usb_interface(d);
+ struct esd_usb2 *dev = usb_get_intfdata(intf);
+
+ return sprintf(buf, "%d.%d.%d\n",
+ (dev->version >> 28) & 0xf,
+ (dev->version >> 24) & 0xf,
+ (dev->version >> 16) & 0xff);
+}
+static DEVICE_ATTR_RO(hardware);
+
+static ssize_t nets_show(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *intf = to_usb_interface(d);
+ struct esd_usb2 *dev = usb_get_intfdata(intf);
+
+ return sprintf(buf, "%d", dev->net_count);
+}
+static DEVICE_ATTR_RO(nets);
+
+static int esd_usb2_send_msg(struct esd_usb2 *dev, struct esd_usb2_msg *msg)
+{
+ int actual_length;
+
+ return usb_bulk_msg(dev->udev,
+ usb_sndbulkpipe(dev->udev, 2),
+ msg,
+ msg->msg.hdr.len << 2,
+ &actual_length,
+ 1000);
+}
+
+static int esd_usb2_wait_msg(struct esd_usb2 *dev,
+ struct esd_usb2_msg *msg)
+{
+ int actual_length;
+
+ return usb_bulk_msg(dev->udev,
+ usb_rcvbulkpipe(dev->udev, 1),
+ msg,
+ sizeof(*msg),
+ &actual_length,
+ 1000);
+}
+
+static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)
+{
+ int i, err = 0;
+
+ if (dev->rxinitdone)
+ return 0;
+
+ for (i = 0; i < MAX_RX_URBS; i++) {
+ struct urb *urb = NULL;
+ u8 *buf = NULL;
+ dma_addr_t buf_dma;
+
+ /* create a URB, and a buffer for it */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ err = -ENOMEM;
+ break;
+ }
+
+ buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL,
+ &buf_dma);
+ if (!buf) {
+ dev_warn(dev->udev->dev.parent,
+ "No memory left for USB buffer\n");
+ err = -ENOMEM;
+ goto freeurb;
+ }
+
+ urb->transfer_dma = buf_dma;
+
+ usb_fill_bulk_urb(urb, dev->udev,
+ usb_rcvbulkpipe(dev->udev, 1),
+ buf, RX_BUFFER_SIZE,
+ esd_usb2_read_bulk_callback, dev);
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ usb_anchor_urb(urb, &dev->rx_submitted);
+
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err) {
+ usb_unanchor_urb(urb);
+ usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf,
+ urb->transfer_dma);
+ goto freeurb;
+ }
+
+ dev->rxbuf[i] = buf;
+ dev->rxbuf_dma[i] = buf_dma;
+
+freeurb:
+ /* Drop reference, USB core will take care of freeing it */
+ usb_free_urb(urb);
+ if (err)
+ break;
+ }
+
+ /* Did we submit any URBs */
+ if (i == 0) {
+ dev_err(dev->udev->dev.parent, "couldn't setup read URBs\n");
+ return err;
+ }
+
+ /* Warn if we've couldn't transmit all the URBs */
+ if (i < MAX_RX_URBS) {
+ dev_warn(dev->udev->dev.parent,
+ "rx performance may be slow\n");
+ }
+
+ dev->rxinitdone = 1;
+ return 0;
+}
+
+/*
+ * Start interface
+ */
+static int esd_usb2_start(struct esd_usb2_net_priv *priv)
+{
+ struct esd_usb2 *dev = priv->usb2;
+ struct net_device *netdev = priv->netdev;
+ struct esd_usb2_msg *msg;
+ int err, i;
+
+ msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ /*
+ * Enable all IDs
+ * The IDADD message takes up to 64 32 bit bitmasks (2048 bits).
+ * Each bit represents one 11 bit CAN identifier. A set bit
+ * enables reception of the corresponding CAN identifier. A cleared
+ * bit disabled this identifier. An additional bitmask value
+ * following the CAN 2.0A bits is used to enable reception of
+ * extended CAN frames. Only the LSB of this final mask is checked
+ * for the complete 29 bit ID range. The IDADD message also allows
+ * filter configuration for an ID subset. In this case you can add
+ * the number of the starting bitmask (0..64) to the filter.option
+ * field followed by only some bitmasks.
+ */
+ msg->msg.hdr.cmd = CMD_IDADD;
+ msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT;
+ msg->msg.filter.net = priv->index;
+ msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */
+ for (i = 0; i < ESD_MAX_ID_SEGMENT; i++)
+ msg->msg.filter.mask[i] = cpu_to_le32(0xffffffff);
+ /* enable 29bit extended IDs */
+ msg->msg.filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001);
+
+ err = esd_usb2_send_msg(dev, msg);
+ if (err)
+ goto out;
+
+ err = esd_usb2_setup_rx_urbs(dev);
+ if (err)
+ goto out;
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+out:
+ if (err == -ENODEV)
+ netif_device_detach(netdev);
+ if (err)
+ netdev_err(netdev, "couldn't start device: %d\n", err);
+
+ kfree(msg);
+ return err;
+}
+
+static void unlink_all_urbs(struct esd_usb2 *dev)
+{
+ struct esd_usb2_net_priv *priv;
+ int i, j;
+
+ usb_kill_anchored_urbs(&dev->rx_submitted);
+
+ for (i = 0; i < MAX_RX_URBS; ++i)
+ usb_free_coherent(dev->udev, RX_BUFFER_SIZE,
+ dev->rxbuf[i], dev->rxbuf_dma[i]);
+
+ for (i = 0; i < dev->net_count; i++) {
+ priv = dev->nets[i];
+ if (priv) {
+ usb_kill_anchored_urbs(&priv->tx_submitted);
+ atomic_set(&priv->active_tx_jobs, 0);
+
+ for (j = 0; j < MAX_TX_URBS; j++)
+ priv->tx_contexts[j].echo_index = MAX_TX_URBS;
+ }
+ }
+}
+
+static int esd_usb2_open(struct net_device *netdev)
+{
+ struct esd_usb2_net_priv *priv = netdev_priv(netdev);
+ int err;
+
+ /* common open */
+ err = open_candev(netdev);
+ if (err)
+ return err;
+
+ /* finally start device */
+ err = esd_usb2_start(priv);
+ if (err) {
+ netdev_warn(netdev, "couldn't start device: %d\n", err);
+ close_candev(netdev);
+ return err;
+ }
+
+ netif_start_queue(netdev);
+
+ return 0;
+}
+
+static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb,
+ struct net_device *netdev)
+{
+ struct esd_usb2_net_priv *priv = netdev_priv(netdev);
+ struct esd_usb2 *dev = priv->usb2;
+ struct esd_tx_urb_context *context = NULL;
+ struct net_device_stats *stats = &netdev->stats;
+ struct can_frame *cf = (struct can_frame *)skb->data;
+ struct esd_usb2_msg *msg;
+ struct urb *urb;
+ u8 *buf;
+ int i, err;
+ int ret = NETDEV_TX_OK;
+ size_t size = sizeof(struct esd_usb2_msg);
+
+ if (can_dropped_invalid_skb(netdev, skb))
+ return NETDEV_TX_OK;
+
+ /* create a URB, and a buffer for it, and copy the data to the URB */
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb) {
+ stats->tx_dropped++;
+ dev_kfree_skb(skb);
+ goto nourbmem;
+ }
+
+ buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC,
+ &urb->transfer_dma);
+ if (!buf) {
+ netdev_err(netdev, "No memory left for USB buffer\n");
+ stats->tx_dropped++;
+ dev_kfree_skb(skb);
+ goto nobufmem;
+ }
+
+ msg = (struct esd_usb2_msg *)buf;
+
+ msg->msg.hdr.len = 3; /* minimal length */
+ msg->msg.hdr.cmd = CMD_CAN_TX;
+ msg->msg.tx.net = priv->index;
+ msg->msg.tx.dlc = can_get_cc_dlc(cf, priv->can.ctrlmode);
+ msg->msg.tx.id = cpu_to_le32(cf->can_id & CAN_ERR_MASK);
+
+ if (cf->can_id & CAN_RTR_FLAG)
+ msg->msg.tx.dlc |= ESD_RTR;
+
+ if (cf->can_id & CAN_EFF_FLAG)
+ msg->msg.tx.id |= cpu_to_le32(ESD_EXTID);
+
+ for (i = 0; i < cf->len; i++)
+ msg->msg.tx.data[i] = cf->data[i];
+
+ msg->msg.hdr.len += (cf->len + 3) >> 2;
+
+ for (i = 0; i < MAX_TX_URBS; i++) {
+ if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) {
+ context = &priv->tx_contexts[i];
+ break;
+ }
+ }
+
+ /*
+ * This may never happen.
+ */
+ if (!context) {
+ netdev_warn(netdev, "couldn't find free context\n");
+ ret = NETDEV_TX_BUSY;
+ goto releasebuf;
+ }
+
+ context->priv = priv;
+ context->echo_index = i;
+ context->len = cf->len;
+
+ /* hnd must not be 0 - MSB is stripped in txdone handling */
+ msg->msg.tx.hnd = 0x80000000 | i; /* returned in TX done message */
+
+ usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf,
+ msg->msg.hdr.len << 2,
+ esd_usb2_write_bulk_callback, context);
+
+ urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ usb_anchor_urb(urb, &priv->tx_submitted);
+
+ can_put_echo_skb(skb, netdev, context->echo_index, 0);
+
+ atomic_inc(&priv->active_tx_jobs);
+
+ /* Slow down tx path */
+ if (atomic_read(&priv->active_tx_jobs) >= MAX_TX_URBS)
+ netif_stop_queue(netdev);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err) {
+ can_free_echo_skb(netdev, context->echo_index, NULL);
+
+ atomic_dec(&priv->active_tx_jobs);
+ usb_unanchor_urb(urb);
+
+ stats->tx_dropped++;
+
+ if (err == -ENODEV)
+ netif_device_detach(netdev);
+ else
+ netdev_warn(netdev, "failed tx_urb %d\n", err);
+
+ goto releasebuf;
+ }
+
+ netif_trans_update(netdev);
+
+ /*
+ * Release our reference to this URB, the USB core will eventually free
+ * it entirely.
+ */
+ usb_free_urb(urb);
+
+ return NETDEV_TX_OK;
+
+releasebuf:
+ usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
+
+nobufmem:
+ usb_free_urb(urb);
+
+nourbmem:
+ return ret;
+}
+
+static int esd_usb2_close(struct net_device *netdev)
+{
+ struct esd_usb2_net_priv *priv = netdev_priv(netdev);
+ struct esd_usb2_msg *msg;
+ int i;
+
+ msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ /* Disable all IDs (see esd_usb2_start()) */
+ msg->msg.hdr.cmd = CMD_IDADD;
+ msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT;
+ msg->msg.filter.net = priv->index;
+ msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */
+ for (i = 0; i <= ESD_MAX_ID_SEGMENT; i++)
+ msg->msg.filter.mask[i] = 0;
+ if (esd_usb2_send_msg(priv->usb2, msg) < 0)
+ netdev_err(netdev, "sending idadd message failed\n");
+
+ /* set CAN controller to reset mode */
+ msg->msg.hdr.len = 2;
+ msg->msg.hdr.cmd = CMD_SETBAUD;
+ msg->msg.setbaud.net = priv->index;
+ msg->msg.setbaud.rsvd = 0;
+ msg->msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE);
+ if (esd_usb2_send_msg(priv->usb2, msg) < 0)
+ netdev_err(netdev, "sending setbaud message failed\n");
+
+ priv->can.state = CAN_STATE_STOPPED;
+
+ netif_stop_queue(netdev);
+
+ close_candev(netdev);
+
+ kfree(msg);
+
+ return 0;
+}
+
+static const struct net_device_ops esd_usb2_netdev_ops = {
+ .ndo_open = esd_usb2_open,
+ .ndo_stop = esd_usb2_close,
+ .ndo_start_xmit = esd_usb2_start_xmit,
+ .ndo_change_mtu = can_change_mtu,
+};
+
+static const struct can_bittiming_const esd_usb2_bittiming_const = {
+ .name = "esd_usb2",
+ .tseg1_min = ESD_USB2_TSEG1_MIN,
+ .tseg1_max = ESD_USB2_TSEG1_MAX,
+ .tseg2_min = ESD_USB2_TSEG2_MIN,
+ .tseg2_max = ESD_USB2_TSEG2_MAX,
+ .sjw_max = ESD_USB2_SJW_MAX,
+ .brp_min = ESD_USB2_BRP_MIN,
+ .brp_max = ESD_USB2_BRP_MAX,
+ .brp_inc = ESD_USB2_BRP_INC,
+};
+
+static int esd_usb2_set_bittiming(struct net_device *netdev)
+{
+ struct esd_usb2_net_priv *priv = netdev_priv(netdev);
+ struct can_bittiming *bt = &priv->can.bittiming;
+ struct esd_usb2_msg *msg;
+ int err;
+ u32 canbtr;
+ int sjw_shift;
+
+ canbtr = ESD_USB2_UBR;
+ if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
+ canbtr |= ESD_USB2_LOM;
+
+ canbtr |= (bt->brp - 1) & (ESD_USB2_BRP_MAX - 1);
+
+ if (le16_to_cpu(priv->usb2->udev->descriptor.idProduct) ==
+ USB_CANUSBM_PRODUCT_ID)
+ sjw_shift = ESD_USBM_SJW_SHIFT;
+ else
+ sjw_shift = ESD_USB2_SJW_SHIFT;
+
+ canbtr |= ((bt->sjw - 1) & (ESD_USB2_SJW_MAX - 1))
+ << sjw_shift;
+ canbtr |= ((bt->prop_seg + bt->phase_seg1 - 1)
+ & (ESD_USB2_TSEG1_MAX - 1))
+ << ESD_USB2_TSEG1_SHIFT;
+ canbtr |= ((bt->phase_seg2 - 1) & (ESD_USB2_TSEG2_MAX - 1))
+ << ESD_USB2_TSEG2_SHIFT;
+ if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+ canbtr |= ESD_USB2_3_SAMPLES;
+
+ msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ msg->msg.hdr.len = 2;
+ msg->msg.hdr.cmd = CMD_SETBAUD;
+ msg->msg.setbaud.net = priv->index;
+ msg->msg.setbaud.rsvd = 0;
+ msg->msg.setbaud.baud = cpu_to_le32(canbtr);
+
+ netdev_info(netdev, "setting BTR=%#x\n", canbtr);
+
+ err = esd_usb2_send_msg(priv->usb2, msg);
+
+ kfree(msg);
+ return err;
+}
+
+static int esd_usb2_get_berr_counter(const struct net_device *netdev,
+ struct can_berr_counter *bec)
+{
+ struct esd_usb2_net_priv *priv = netdev_priv(netdev);
+
+ bec->txerr = priv->bec.txerr;
+ bec->rxerr = priv->bec.rxerr;
+
+ return 0;
+}
+
+static int esd_usb2_set_mode(struct net_device *netdev, enum can_mode mode)
+{
+ switch (mode) {
+ case CAN_MODE_START:
+ netif_wake_queue(netdev);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int esd_usb2_probe_one_net(struct usb_interface *intf, int index)
+{
+ struct esd_usb2 *dev = usb_get_intfdata(intf);
+ struct net_device *netdev;
+ struct esd_usb2_net_priv *priv;
+ int err = 0;
+ int i;
+
+ netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS);
+ if (!netdev) {
+ dev_err(&intf->dev, "couldn't alloc candev\n");
+ err = -ENOMEM;
+ goto done;
+ }
+
+ priv = netdev_priv(netdev);
+
+ init_usb_anchor(&priv->tx_submitted);
+ atomic_set(&priv->active_tx_jobs, 0);
+
+ for (i = 0; i < MAX_TX_URBS; i++)
+ priv->tx_contexts[i].echo_index = MAX_TX_URBS;
+
+ priv->usb2 = dev;
+ priv->netdev = netdev;
+ priv->index = index;
+
+ priv->can.state = CAN_STATE_STOPPED;
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY |
+ CAN_CTRLMODE_CC_LEN8_DLC;
+
+ if (le16_to_cpu(dev->udev->descriptor.idProduct) ==
+ USB_CANUSBM_PRODUCT_ID)
+ priv->can.clock.freq = ESD_USBM_CAN_CLOCK;
+ else {
+ priv->can.clock.freq = ESD_USB2_CAN_CLOCK;
+ priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
+ }
+
+ priv->can.bittiming_const = &esd_usb2_bittiming_const;
+ priv->can.do_set_bittiming = esd_usb2_set_bittiming;
+ priv->can.do_set_mode = esd_usb2_set_mode;
+ priv->can.do_get_berr_counter = esd_usb2_get_berr_counter;
+
+ netdev->flags |= IFF_ECHO; /* we support local echo */
+
+ netdev->netdev_ops = &esd_usb2_netdev_ops;
+
+ SET_NETDEV_DEV(netdev, &intf->dev);
+ netdev->dev_id = index;
+
+ err = register_candev(netdev);
+ if (err) {
+ dev_err(&intf->dev, "couldn't register CAN device: %d\n", err);
+ free_candev(netdev);
+ err = -ENOMEM;
+ goto done;
+ }
+
+ dev->nets[index] = priv;
+ netdev_info(netdev, "device %s registered\n", netdev->name);
+
+done:
+ return err;
+}
+
+/*
+ * probe function for new USB2 devices
+ *
+ * check version information and number of available
+ * CAN interfaces
+ */
+static int esd_usb2_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct esd_usb2 *dev;
+ struct esd_usb2_msg *msg;
+ int i, err;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ err = -ENOMEM;
+ goto done;
+ }
+
+ dev->udev = interface_to_usbdev(intf);
+
+ init_usb_anchor(&dev->rx_submitted);
+
+ usb_set_intfdata(intf, dev);
+
+ msg = kmalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg) {
+ err = -ENOMEM;
+ goto free_msg;
+ }
+
+ /* query number of CAN interfaces (nets) */
+ msg->msg.hdr.cmd = CMD_VERSION;
+ msg->msg.hdr.len = 2;
+ msg->msg.version.rsvd = 0;
+ msg->msg.version.flags = 0;
+ msg->msg.version.drv_version = 0;
+
+ err = esd_usb2_send_msg(dev, msg);
+ if (err < 0) {
+ dev_err(&intf->dev, "sending version message failed\n");
+ goto free_msg;
+ }
+
+ err = esd_usb2_wait_msg(dev, msg);
+ if (err < 0) {
+ dev_err(&intf->dev, "no version message answer\n");
+ goto free_msg;
+ }
+
+ dev->net_count = (int)msg->msg.version_reply.nets;
+ dev->version = le32_to_cpu(msg->msg.version_reply.version);
+
+ if (device_create_file(&intf->dev, &dev_attr_firmware))
+ dev_err(&intf->dev,
+ "Couldn't create device file for firmware\n");
+
+ if (device_create_file(&intf->dev, &dev_attr_hardware))
+ dev_err(&intf->dev,
+ "Couldn't create device file for hardware\n");
+
+ if (device_create_file(&intf->dev, &dev_attr_nets))
+ dev_err(&intf->dev,
+ "Couldn't create device file for nets\n");
+
+ /* do per device probing */
+ for (i = 0; i < dev->net_count; i++)
+ esd_usb2_probe_one_net(intf, i);
+
+free_msg:
+ kfree(msg);
+ if (err)
+ kfree(dev);
+done:
+ return err;
+}
+
+/*
+ * called by the usb core when the device is removed from the system
+ */
+static void esd_usb2_disconnect(struct usb_interface *intf)
+{
+ struct esd_usb2 *dev = usb_get_intfdata(intf);
+ struct net_device *netdev;
+ int i;
+
+ device_remove_file(&intf->dev, &dev_attr_firmware);
+ device_remove_file(&intf->dev, &dev_attr_hardware);
+ device_remove_file(&intf->dev, &dev_attr_nets);
+
+ usb_set_intfdata(intf, NULL);
+
+ if (dev) {
+ for (i = 0; i < dev->net_count; i++) {
+ if (dev->nets[i]) {
+ netdev = dev->nets[i]->netdev;
+ unregister_netdev(netdev);
+ free_candev(netdev);
+ }
+ }
+ unlink_all_urbs(dev);
+ kfree(dev);
+ }
+}
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver esd_usb2_driver = {
+ .name = "esd_usb2",
+ .probe = esd_usb2_probe,
+ .disconnect = esd_usb2_disconnect,
+ .id_table = esd_usb2_table,
+};
+
+module_usb_driver(esd_usb2_driver);
--- a/drivers/net/can/usb/esd_usb2.c
+++ /dev/null
@@ -1,1170 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * CAN driver for esd CAN-USB/2 and CAN-USB/Micro
- *
- * Copyright (C) 2010-2012 Matthias Fuchs <matthias.fuchs@esd.eu>, esd gmbh
- */
-#include <linux/signal.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/usb.h>
-
-#include <linux/can.h>
-#include <linux/can/dev.h>
-#include <linux/can/error.h>
-
-MODULE_AUTHOR("Matthias Fuchs <matthias.fuchs@esd.eu>");
-MODULE_DESCRIPTION("CAN driver for esd CAN-USB/2 and CAN-USB/Micro interfaces");
-MODULE_LICENSE("GPL v2");
-
-/* Define these values to match your devices */
-#define USB_ESDGMBH_VENDOR_ID 0x0ab4
-#define USB_CANUSB2_PRODUCT_ID 0x0010
-#define USB_CANUSBM_PRODUCT_ID 0x0011
-
-#define ESD_USB2_CAN_CLOCK 60000000
-#define ESD_USBM_CAN_CLOCK 36000000
-#define ESD_USB2_MAX_NETS 2
-
-/* USB2 commands */
-#define CMD_VERSION 1 /* also used for VERSION_REPLY */
-#define CMD_CAN_RX 2 /* device to host only */
-#define CMD_CAN_TX 3 /* also used for TX_DONE */
-#define CMD_SETBAUD 4 /* also used for SETBAUD_REPLY */
-#define CMD_TS 5 /* also used for TS_REPLY */
-#define CMD_IDADD 6 /* also used for IDADD_REPLY */
-
-/* esd CAN message flags - dlc field */
-#define ESD_RTR 0x10
-
-/* esd CAN message flags - id field */
-#define ESD_EXTID 0x20000000
-#define ESD_EVENT 0x40000000
-#define ESD_IDMASK 0x1fffffff
-
-/* esd CAN event ids used by this driver */
-#define ESD_EV_CAN_ERROR_EXT 2
-
-/* baudrate message flags */
-#define ESD_USB2_UBR 0x80000000
-#define ESD_USB2_LOM 0x40000000
-#define ESD_USB2_NO_BAUDRATE 0x7fffffff
-#define ESD_USB2_TSEG1_MIN 1
-#define ESD_USB2_TSEG1_MAX 16
-#define ESD_USB2_TSEG1_SHIFT 16
-#define ESD_USB2_TSEG2_MIN 1
-#define ESD_USB2_TSEG2_MAX 8
-#define ESD_USB2_TSEG2_SHIFT 20
-#define ESD_USB2_SJW_MAX 4
-#define ESD_USB2_SJW_SHIFT 14
-#define ESD_USBM_SJW_SHIFT 24
-#define ESD_USB2_BRP_MIN 1
-#define ESD_USB2_BRP_MAX 1024
-#define ESD_USB2_BRP_INC 1
-#define ESD_USB2_3_SAMPLES 0x00800000
-
-/* esd IDADD message */
-#define ESD_ID_ENABLE 0x80
-#define ESD_MAX_ID_SEGMENT 64
-
-/* SJA1000 ECC register (emulated by usb2 firmware) */
-#define SJA1000_ECC_SEG 0x1F
-#define SJA1000_ECC_DIR 0x20
-#define SJA1000_ECC_ERR 0x06
-#define SJA1000_ECC_BIT 0x00
-#define SJA1000_ECC_FORM 0x40
-#define SJA1000_ECC_STUFF 0x80
-#define SJA1000_ECC_MASK 0xc0
-
-/* esd bus state event codes */
-#define ESD_BUSSTATE_MASK 0xc0
-#define ESD_BUSSTATE_WARN 0x40
-#define ESD_BUSSTATE_ERRPASSIVE 0x80
-#define ESD_BUSSTATE_BUSOFF 0xc0
-
-#define RX_BUFFER_SIZE 1024
-#define MAX_RX_URBS 4
-#define MAX_TX_URBS 16 /* must be power of 2 */
-
-struct header_msg {
- u8 len; /* len is always the total message length in 32bit words */
- u8 cmd;
- u8 rsvd[2];
-};
-
-struct version_msg {
- u8 len;
- u8 cmd;
- u8 rsvd;
- u8 flags;
- __le32 drv_version;
-};
-
-struct version_reply_msg {
- u8 len;
- u8 cmd;
- u8 nets;
- u8 features;
- __le32 version;
- u8 name[16];
- __le32 rsvd;
- __le32 ts;
-};
-
-struct rx_msg {
- u8 len;
- u8 cmd;
- u8 net;
- u8 dlc;
- __le32 ts;
- __le32 id; /* upper 3 bits contain flags */
- u8 data[8];
-};
-
-struct tx_msg {
- u8 len;
- u8 cmd;
- u8 net;
- u8 dlc;
- u32 hnd; /* opaque handle, not used by device */
- __le32 id; /* upper 3 bits contain flags */
- u8 data[8];
-};
-
-struct tx_done_msg {
- u8 len;
- u8 cmd;
- u8 net;
- u8 status;
- u32 hnd; /* opaque handle, not used by device */
- __le32 ts;
-};
-
-struct id_filter_msg {
- u8 len;
- u8 cmd;
- u8 net;
- u8 option;
- __le32 mask[ESD_MAX_ID_SEGMENT + 1];
-};
-
-struct set_baudrate_msg {
- u8 len;
- u8 cmd;
- u8 net;
- u8 rsvd;
- __le32 baud;
-};
-
-/* Main message type used between library and application */
-struct __attribute__ ((packed)) esd_usb2_msg {
- union {
- struct header_msg hdr;
- struct version_msg version;
- struct version_reply_msg version_reply;
- struct rx_msg rx;
- struct tx_msg tx;
- struct tx_done_msg txdone;
- struct set_baudrate_msg setbaud;
- struct id_filter_msg filter;
- } msg;
-};
-
-static struct usb_device_id esd_usb2_table[] = {
- {USB_DEVICE(USB_ESDGMBH_VENDOR_ID, USB_CANUSB2_PRODUCT_ID)},
- {USB_DEVICE(USB_ESDGMBH_VENDOR_ID, USB_CANUSBM_PRODUCT_ID)},
- {}
-};
-MODULE_DEVICE_TABLE(usb, esd_usb2_table);
-
-struct esd_usb2_net_priv;
-
-struct esd_tx_urb_context {
- struct esd_usb2_net_priv *priv;
- u32 echo_index;
- int len; /* CAN payload length */
-};
-
-struct esd_usb2 {
- struct usb_device *udev;
- struct esd_usb2_net_priv *nets[ESD_USB2_MAX_NETS];
-
- struct usb_anchor rx_submitted;
-
- int net_count;
- u32 version;
- int rxinitdone;
- void *rxbuf[MAX_RX_URBS];
- dma_addr_t rxbuf_dma[MAX_RX_URBS];
-};
-
-struct esd_usb2_net_priv {
- struct can_priv can; /* must be the first member */
-
- atomic_t active_tx_jobs;
- struct usb_anchor tx_submitted;
- struct esd_tx_urb_context tx_contexts[MAX_TX_URBS];
-
- struct esd_usb2 *usb2;
- struct net_device *netdev;
- int index;
- u8 old_state;
- struct can_berr_counter bec;
-};
-
-static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv,
- struct esd_usb2_msg *msg)
-{
- struct net_device_stats *stats = &priv->netdev->stats;
- struct can_frame *cf;
- struct sk_buff *skb;
- u32 id = le32_to_cpu(msg->msg.rx.id) & ESD_IDMASK;
-
- if (id == ESD_EV_CAN_ERROR_EXT) {
- u8 state = msg->msg.rx.data[0];
- u8 ecc = msg->msg.rx.data[1];
- u8 rxerr = msg->msg.rx.data[2];
- u8 txerr = msg->msg.rx.data[3];
-
- netdev_dbg(priv->netdev,
- "CAN_ERR_EV_EXT: dlc=%#02x state=%02x ecc=%02x rec=%02x tec=%02x\n",
- msg->msg.rx.dlc, state, ecc, rxerr, txerr);
-
- skb = alloc_can_err_skb(priv->netdev, &cf);
- if (skb == NULL) {
- stats->rx_dropped++;
- return;
- }
-
- if (state != priv->old_state) {
- priv->old_state = state;
-
- switch (state & ESD_BUSSTATE_MASK) {
- case ESD_BUSSTATE_BUSOFF:
- priv->can.state = CAN_STATE_BUS_OFF;
- cf->can_id |= CAN_ERR_BUSOFF;
- priv->can.can_stats.bus_off++;
- can_bus_off(priv->netdev);
- break;
- case ESD_BUSSTATE_WARN:
- priv->can.state = CAN_STATE_ERROR_WARNING;
- priv->can.can_stats.error_warning++;
- break;
- case ESD_BUSSTATE_ERRPASSIVE:
- priv->can.state = CAN_STATE_ERROR_PASSIVE;
- priv->can.can_stats.error_passive++;
- break;
- default:
- priv->can.state = CAN_STATE_ERROR_ACTIVE;
- txerr = 0;
- rxerr = 0;
- break;
- }
- } else {
- priv->can.can_stats.bus_error++;
- stats->rx_errors++;
-
- cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
-
- switch (ecc & SJA1000_ECC_MASK) {
- case SJA1000_ECC_BIT:
- cf->data[2] |= CAN_ERR_PROT_BIT;
- break;
- case SJA1000_ECC_FORM:
- cf->data[2] |= CAN_ERR_PROT_FORM;
- break;
- case SJA1000_ECC_STUFF:
- cf->data[2] |= CAN_ERR_PROT_STUFF;
- break;
- default:
- break;
- }
-
- /* Error occurred during transmission? */
- if (!(ecc & SJA1000_ECC_DIR))
- cf->data[2] |= CAN_ERR_PROT_TX;
-
- /* Bit stream position in CAN frame as the error was detected */
- cf->data[3] = ecc & SJA1000_ECC_SEG;
-
- if (priv->can.state == CAN_STATE_ERROR_WARNING ||
- priv->can.state == CAN_STATE_ERROR_PASSIVE) {
- cf->data[1] = (txerr > rxerr) ?
- CAN_ERR_CRTL_TX_PASSIVE :
- CAN_ERR_CRTL_RX_PASSIVE;
- }
- cf->data[6] = txerr;
- cf->data[7] = rxerr;
- }
-
- priv->bec.txerr = txerr;
- priv->bec.rxerr = rxerr;
-
- netif_rx(skb);
- }
-}
-
-static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv,
- struct esd_usb2_msg *msg)
-{
- struct net_device_stats *stats = &priv->netdev->stats;
- struct can_frame *cf;
- struct sk_buff *skb;
- int i;
- u32 id;
-
- if (!netif_device_present(priv->netdev))
- return;
-
- id = le32_to_cpu(msg->msg.rx.id);
-
- if (id & ESD_EVENT) {
- esd_usb2_rx_event(priv, msg);
- } else {
- skb = alloc_can_skb(priv->netdev, &cf);
- if (skb == NULL) {
- stats->rx_dropped++;
- return;
- }
-
- cf->can_id = id & ESD_IDMASK;
- can_frame_set_cc_len(cf, msg->msg.rx.dlc & ~ESD_RTR,
- priv->can.ctrlmode);
-
- if (id & ESD_EXTID)
- cf->can_id |= CAN_EFF_FLAG;
-
- if (msg->msg.rx.dlc & ESD_RTR) {
- cf->can_id |= CAN_RTR_FLAG;
- } else {
- for (i = 0; i < cf->len; i++)
- cf->data[i] = msg->msg.rx.data[i];
- }
-
- stats->rx_packets++;
- stats->rx_bytes += cf->len;
- netif_rx(skb);
- }
-
- return;
-}
-
-static void esd_usb2_tx_done_msg(struct esd_usb2_net_priv *priv,
- struct esd_usb2_msg *msg)
-{
- struct net_device_stats *stats = &priv->netdev->stats;
- struct net_device *netdev = priv->netdev;
- struct esd_tx_urb_context *context;
-
- if (!netif_device_present(netdev))
- return;
-
- context = &priv->tx_contexts[msg->msg.txdone.hnd & (MAX_TX_URBS - 1)];
-
- if (!msg->msg.txdone.status) {
- stats->tx_packets++;
- stats->tx_bytes += context->len;
- can_get_echo_skb(netdev, context->echo_index, NULL);
- } else {
- stats->tx_errors++;
- can_free_echo_skb(netdev, context->echo_index, NULL);
- }
-
- /* Release context */
- context->echo_index = MAX_TX_URBS;
- atomic_dec(&priv->active_tx_jobs);
-
- netif_wake_queue(netdev);
-}
-
-static void esd_usb2_read_bulk_callback(struct urb *urb)
-{
- struct esd_usb2 *dev = urb->context;
- int retval;
- int pos = 0;
- int i;
-
- switch (urb->status) {
- case 0: /* success */
- break;
-
- case -ENOENT:
- case -EPIPE:
- case -EPROTO:
- case -ESHUTDOWN:
- return;
-
- default:
- dev_info(dev->udev->dev.parent,
- "Rx URB aborted (%d)\n", urb->status);
- goto resubmit_urb;
- }
-
- while (pos < urb->actual_length) {
- struct esd_usb2_msg *msg;
-
- msg = (struct esd_usb2_msg *)(urb->transfer_buffer + pos);
-
- switch (msg->msg.hdr.cmd) {
- case CMD_CAN_RX:
- if (msg->msg.rx.net >= dev->net_count) {
- dev_err(dev->udev->dev.parent, "format error\n");
- break;
- }
-
- esd_usb2_rx_can_msg(dev->nets[msg->msg.rx.net], msg);
- break;
-
- case CMD_CAN_TX:
- if (msg->msg.txdone.net >= dev->net_count) {
- dev_err(dev->udev->dev.parent, "format error\n");
- break;
- }
-
- esd_usb2_tx_done_msg(dev->nets[msg->msg.txdone.net],
- msg);
- break;
- }
-
- pos += msg->msg.hdr.len << 2;
-
- if (pos > urb->actual_length) {
- dev_err(dev->udev->dev.parent, "format error\n");
- break;
- }
- }
-
-resubmit_urb:
- usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
- urb->transfer_buffer, RX_BUFFER_SIZE,
- esd_usb2_read_bulk_callback, dev);
-
- usb_anchor_urb(urb, &dev->rx_submitted);
-
- retval = usb_submit_urb(urb, GFP_ATOMIC);
- if (!retval)
- return;
-
- usb_unanchor_urb(urb);
-
- if (retval == -ENODEV) {
- for (i = 0; i < dev->net_count; i++) {
- if (dev->nets[i])
- netif_device_detach(dev->nets[i]->netdev);
- }
- } else {
- dev_err(dev->udev->dev.parent,
- "failed resubmitting read bulk urb: %d\n", retval);
- }
-
- return;
-}
-
-/*
- * callback for bulk IN urb
- */
-static void esd_usb2_write_bulk_callback(struct urb *urb)
-{
- struct esd_tx_urb_context *context = urb->context;
- struct esd_usb2_net_priv *priv;
- struct net_device *netdev;
- size_t size = sizeof(struct esd_usb2_msg);
-
- WARN_ON(!context);
-
- priv = context->priv;
- netdev = priv->netdev;
-
- /* free up our allocated buffer */
- usb_free_coherent(urb->dev, size,
- urb->transfer_buffer, urb->transfer_dma);
-
- if (!netif_device_present(netdev))
- return;
-
- if (urb->status)
- netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status);
-
- netif_trans_update(netdev);
-}
-
-static ssize_t firmware_show(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct usb_interface *intf = to_usb_interface(d);
- struct esd_usb2 *dev = usb_get_intfdata(intf);
-
- return sprintf(buf, "%d.%d.%d\n",
- (dev->version >> 12) & 0xf,
- (dev->version >> 8) & 0xf,
- dev->version & 0xff);
-}
-static DEVICE_ATTR_RO(firmware);
-
-static ssize_t hardware_show(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct usb_interface *intf = to_usb_interface(d);
- struct esd_usb2 *dev = usb_get_intfdata(intf);
-
- return sprintf(buf, "%d.%d.%d\n",
- (dev->version >> 28) & 0xf,
- (dev->version >> 24) & 0xf,
- (dev->version >> 16) & 0xff);
-}
-static DEVICE_ATTR_RO(hardware);
-
-static ssize_t nets_show(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct usb_interface *intf = to_usb_interface(d);
- struct esd_usb2 *dev = usb_get_intfdata(intf);
-
- return sprintf(buf, "%d", dev->net_count);
-}
-static DEVICE_ATTR_RO(nets);
-
-static int esd_usb2_send_msg(struct esd_usb2 *dev, struct esd_usb2_msg *msg)
-{
- int actual_length;
-
- return usb_bulk_msg(dev->udev,
- usb_sndbulkpipe(dev->udev, 2),
- msg,
- msg->msg.hdr.len << 2,
- &actual_length,
- 1000);
-}
-
-static int esd_usb2_wait_msg(struct esd_usb2 *dev,
- struct esd_usb2_msg *msg)
-{
- int actual_length;
-
- return usb_bulk_msg(dev->udev,
- usb_rcvbulkpipe(dev->udev, 1),
- msg,
- sizeof(*msg),
- &actual_length,
- 1000);
-}
-
-static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev)
-{
- int i, err = 0;
-
- if (dev->rxinitdone)
- return 0;
-
- for (i = 0; i < MAX_RX_URBS; i++) {
- struct urb *urb = NULL;
- u8 *buf = NULL;
- dma_addr_t buf_dma;
-
- /* create a URB, and a buffer for it */
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- err = -ENOMEM;
- break;
- }
-
- buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL,
- &buf_dma);
- if (!buf) {
- dev_warn(dev->udev->dev.parent,
- "No memory left for USB buffer\n");
- err = -ENOMEM;
- goto freeurb;
- }
-
- urb->transfer_dma = buf_dma;
-
- usb_fill_bulk_urb(urb, dev->udev,
- usb_rcvbulkpipe(dev->udev, 1),
- buf, RX_BUFFER_SIZE,
- esd_usb2_read_bulk_callback, dev);
- urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- usb_anchor_urb(urb, &dev->rx_submitted);
-
- err = usb_submit_urb(urb, GFP_KERNEL);
- if (err) {
- usb_unanchor_urb(urb);
- usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf,
- urb->transfer_dma);
- goto freeurb;
- }
-
- dev->rxbuf[i] = buf;
- dev->rxbuf_dma[i] = buf_dma;
-
-freeurb:
- /* Drop reference, USB core will take care of freeing it */
- usb_free_urb(urb);
- if (err)
- break;
- }
-
- /* Did we submit any URBs */
- if (i == 0) {
- dev_err(dev->udev->dev.parent, "couldn't setup read URBs\n");
- return err;
- }
-
- /* Warn if we've couldn't transmit all the URBs */
- if (i < MAX_RX_URBS) {
- dev_warn(dev->udev->dev.parent,
- "rx performance may be slow\n");
- }
-
- dev->rxinitdone = 1;
- return 0;
-}
-
-/*
- * Start interface
- */
-static int esd_usb2_start(struct esd_usb2_net_priv *priv)
-{
- struct esd_usb2 *dev = priv->usb2;
- struct net_device *netdev = priv->netdev;
- struct esd_usb2_msg *msg;
- int err, i;
-
- msg = kmalloc(sizeof(*msg), GFP_KERNEL);
- if (!msg) {
- err = -ENOMEM;
- goto out;
- }
-
- /*
- * Enable all IDs
- * The IDADD message takes up to 64 32 bit bitmasks (2048 bits).
- * Each bit represents one 11 bit CAN identifier. A set bit
- * enables reception of the corresponding CAN identifier. A cleared
- * bit disabled this identifier. An additional bitmask value
- * following the CAN 2.0A bits is used to enable reception of
- * extended CAN frames. Only the LSB of this final mask is checked
- * for the complete 29 bit ID range. The IDADD message also allows
- * filter configuration for an ID subset. In this case you can add
- * the number of the starting bitmask (0..64) to the filter.option
- * field followed by only some bitmasks.
- */
- msg->msg.hdr.cmd = CMD_IDADD;
- msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT;
- msg->msg.filter.net = priv->index;
- msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */
- for (i = 0; i < ESD_MAX_ID_SEGMENT; i++)
- msg->msg.filter.mask[i] = cpu_to_le32(0xffffffff);
- /* enable 29bit extended IDs */
- msg->msg.filter.mask[ESD_MAX_ID_SEGMENT] = cpu_to_le32(0x00000001);
-
- err = esd_usb2_send_msg(dev, msg);
- if (err)
- goto out;
-
- err = esd_usb2_setup_rx_urbs(dev);
- if (err)
- goto out;
-
- priv->can.state = CAN_STATE_ERROR_ACTIVE;
-
-out:
- if (err == -ENODEV)
- netif_device_detach(netdev);
- if (err)
- netdev_err(netdev, "couldn't start device: %d\n", err);
-
- kfree(msg);
- return err;
-}
-
-static void unlink_all_urbs(struct esd_usb2 *dev)
-{
- struct esd_usb2_net_priv *priv;
- int i, j;
-
- usb_kill_anchored_urbs(&dev->rx_submitted);
-
- for (i = 0; i < MAX_RX_URBS; ++i)
- usb_free_coherent(dev->udev, RX_BUFFER_SIZE,
- dev->rxbuf[i], dev->rxbuf_dma[i]);
-
- for (i = 0; i < dev->net_count; i++) {
- priv = dev->nets[i];
- if (priv) {
- usb_kill_anchored_urbs(&priv->tx_submitted);
- atomic_set(&priv->active_tx_jobs, 0);
-
- for (j = 0; j < MAX_TX_URBS; j++)
- priv->tx_contexts[j].echo_index = MAX_TX_URBS;
- }
- }
-}
-
-static int esd_usb2_open(struct net_device *netdev)
-{
- struct esd_usb2_net_priv *priv = netdev_priv(netdev);
- int err;
-
- /* common open */
- err = open_candev(netdev);
- if (err)
- return err;
-
- /* finally start device */
- err = esd_usb2_start(priv);
- if (err) {
- netdev_warn(netdev, "couldn't start device: %d\n", err);
- close_candev(netdev);
- return err;
- }
-
- netif_start_queue(netdev);
-
- return 0;
-}
-
-static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb,
- struct net_device *netdev)
-{
- struct esd_usb2_net_priv *priv = netdev_priv(netdev);
- struct esd_usb2 *dev = priv->usb2;
- struct esd_tx_urb_context *context = NULL;
- struct net_device_stats *stats = &netdev->stats;
- struct can_frame *cf = (struct can_frame *)skb->data;
- struct esd_usb2_msg *msg;
- struct urb *urb;
- u8 *buf;
- int i, err;
- int ret = NETDEV_TX_OK;
- size_t size = sizeof(struct esd_usb2_msg);
-
- if (can_dropped_invalid_skb(netdev, skb))
- return NETDEV_TX_OK;
-
- /* create a URB, and a buffer for it, and copy the data to the URB */
- urb = usb_alloc_urb(0, GFP_ATOMIC);
- if (!urb) {
- stats->tx_dropped++;
- dev_kfree_skb(skb);
- goto nourbmem;
- }
-
- buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC,
- &urb->transfer_dma);
- if (!buf) {
- netdev_err(netdev, "No memory left for USB buffer\n");
- stats->tx_dropped++;
- dev_kfree_skb(skb);
- goto nobufmem;
- }
-
- msg = (struct esd_usb2_msg *)buf;
-
- msg->msg.hdr.len = 3; /* minimal length */
- msg->msg.hdr.cmd = CMD_CAN_TX;
- msg->msg.tx.net = priv->index;
- msg->msg.tx.dlc = can_get_cc_dlc(cf, priv->can.ctrlmode);
- msg->msg.tx.id = cpu_to_le32(cf->can_id & CAN_ERR_MASK);
-
- if (cf->can_id & CAN_RTR_FLAG)
- msg->msg.tx.dlc |= ESD_RTR;
-
- if (cf->can_id & CAN_EFF_FLAG)
- msg->msg.tx.id |= cpu_to_le32(ESD_EXTID);
-
- for (i = 0; i < cf->len; i++)
- msg->msg.tx.data[i] = cf->data[i];
-
- msg->msg.hdr.len += (cf->len + 3) >> 2;
-
- for (i = 0; i < MAX_TX_URBS; i++) {
- if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) {
- context = &priv->tx_contexts[i];
- break;
- }
- }
-
- /*
- * This may never happen.
- */
- if (!context) {
- netdev_warn(netdev, "couldn't find free context\n");
- ret = NETDEV_TX_BUSY;
- goto releasebuf;
- }
-
- context->priv = priv;
- context->echo_index = i;
- context->len = cf->len;
-
- /* hnd must not be 0 - MSB is stripped in txdone handling */
- msg->msg.tx.hnd = 0x80000000 | i; /* returned in TX done message */
-
- usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf,
- msg->msg.hdr.len << 2,
- esd_usb2_write_bulk_callback, context);
-
- urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
- usb_anchor_urb(urb, &priv->tx_submitted);
-
- can_put_echo_skb(skb, netdev, context->echo_index, 0);
-
- atomic_inc(&priv->active_tx_jobs);
-
- /* Slow down tx path */
- if (atomic_read(&priv->active_tx_jobs) >= MAX_TX_URBS)
- netif_stop_queue(netdev);
-
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (err) {
- can_free_echo_skb(netdev, context->echo_index, NULL);
-
- atomic_dec(&priv->active_tx_jobs);
- usb_unanchor_urb(urb);
-
- stats->tx_dropped++;
-
- if (err == -ENODEV)
- netif_device_detach(netdev);
- else
- netdev_warn(netdev, "failed tx_urb %d\n", err);
-
- goto releasebuf;
- }
-
- netif_trans_update(netdev);
-
- /*
- * Release our reference to this URB, the USB core will eventually free
- * it entirely.
- */
- usb_free_urb(urb);
-
- return NETDEV_TX_OK;
-
-releasebuf:
- usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
-
-nobufmem:
- usb_free_urb(urb);
-
-nourbmem:
- return ret;
-}
-
-static int esd_usb2_close(struct net_device *netdev)
-{
- struct esd_usb2_net_priv *priv = netdev_priv(netdev);
- struct esd_usb2_msg *msg;
- int i;
-
- msg = kmalloc(sizeof(*msg), GFP_KERNEL);
- if (!msg)
- return -ENOMEM;
-
- /* Disable all IDs (see esd_usb2_start()) */
- msg->msg.hdr.cmd = CMD_IDADD;
- msg->msg.hdr.len = 2 + ESD_MAX_ID_SEGMENT;
- msg->msg.filter.net = priv->index;
- msg->msg.filter.option = ESD_ID_ENABLE; /* start with segment 0 */
- for (i = 0; i <= ESD_MAX_ID_SEGMENT; i++)
- msg->msg.filter.mask[i] = 0;
- if (esd_usb2_send_msg(priv->usb2, msg) < 0)
- netdev_err(netdev, "sending idadd message failed\n");
-
- /* set CAN controller to reset mode */
- msg->msg.hdr.len = 2;
- msg->msg.hdr.cmd = CMD_SETBAUD;
- msg->msg.setbaud.net = priv->index;
- msg->msg.setbaud.rsvd = 0;
- msg->msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE);
- if (esd_usb2_send_msg(priv->usb2, msg) < 0)
- netdev_err(netdev, "sending setbaud message failed\n");
-
- priv->can.state = CAN_STATE_STOPPED;
-
- netif_stop_queue(netdev);
-
- close_candev(netdev);
-
- kfree(msg);
-
- return 0;
-}
-
-static const struct net_device_ops esd_usb2_netdev_ops = {
- .ndo_open = esd_usb2_open,
- .ndo_stop = esd_usb2_close,
- .ndo_start_xmit = esd_usb2_start_xmit,
- .ndo_change_mtu = can_change_mtu,
-};
-
-static const struct can_bittiming_const esd_usb2_bittiming_const = {
- .name = "esd_usb2",
- .tseg1_min = ESD_USB2_TSEG1_MIN,
- .tseg1_max = ESD_USB2_TSEG1_MAX,
- .tseg2_min = ESD_USB2_TSEG2_MIN,
- .tseg2_max = ESD_USB2_TSEG2_MAX,
- .sjw_max = ESD_USB2_SJW_MAX,
- .brp_min = ESD_USB2_BRP_MIN,
- .brp_max = ESD_USB2_BRP_MAX,
- .brp_inc = ESD_USB2_BRP_INC,
-};
-
-static int esd_usb2_set_bittiming(struct net_device *netdev)
-{
- struct esd_usb2_net_priv *priv = netdev_priv(netdev);
- struct can_bittiming *bt = &priv->can.bittiming;
- struct esd_usb2_msg *msg;
- int err;
- u32 canbtr;
- int sjw_shift;
-
- canbtr = ESD_USB2_UBR;
- if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
- canbtr |= ESD_USB2_LOM;
-
- canbtr |= (bt->brp - 1) & (ESD_USB2_BRP_MAX - 1);
-
- if (le16_to_cpu(priv->usb2->udev->descriptor.idProduct) ==
- USB_CANUSBM_PRODUCT_ID)
- sjw_shift = ESD_USBM_SJW_SHIFT;
- else
- sjw_shift = ESD_USB2_SJW_SHIFT;
-
- canbtr |= ((bt->sjw - 1) & (ESD_USB2_SJW_MAX - 1))
- << sjw_shift;
- canbtr |= ((bt->prop_seg + bt->phase_seg1 - 1)
- & (ESD_USB2_TSEG1_MAX - 1))
- << ESD_USB2_TSEG1_SHIFT;
- canbtr |= ((bt->phase_seg2 - 1) & (ESD_USB2_TSEG2_MAX - 1))
- << ESD_USB2_TSEG2_SHIFT;
- if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
- canbtr |= ESD_USB2_3_SAMPLES;
-
- msg = kmalloc(sizeof(*msg), GFP_KERNEL);
- if (!msg)
- return -ENOMEM;
-
- msg->msg.hdr.len = 2;
- msg->msg.hdr.cmd = CMD_SETBAUD;
- msg->msg.setbaud.net = priv->index;
- msg->msg.setbaud.rsvd = 0;
- msg->msg.setbaud.baud = cpu_to_le32(canbtr);
-
- netdev_info(netdev, "setting BTR=%#x\n", canbtr);
-
- err = esd_usb2_send_msg(priv->usb2, msg);
-
- kfree(msg);
- return err;
-}
-
-static int esd_usb2_get_berr_counter(const struct net_device *netdev,
- struct can_berr_counter *bec)
-{
- struct esd_usb2_net_priv *priv = netdev_priv(netdev);
-
- bec->txerr = priv->bec.txerr;
- bec->rxerr = priv->bec.rxerr;
-
- return 0;
-}
-
-static int esd_usb2_set_mode(struct net_device *netdev, enum can_mode mode)
-{
- switch (mode) {
- case CAN_MODE_START:
- netif_wake_queue(netdev);
- break;
-
- default:
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
-static int esd_usb2_probe_one_net(struct usb_interface *intf, int index)
-{
- struct esd_usb2 *dev = usb_get_intfdata(intf);
- struct net_device *netdev;
- struct esd_usb2_net_priv *priv;
- int err = 0;
- int i;
-
- netdev = alloc_candev(sizeof(*priv), MAX_TX_URBS);
- if (!netdev) {
- dev_err(&intf->dev, "couldn't alloc candev\n");
- err = -ENOMEM;
- goto done;
- }
-
- priv = netdev_priv(netdev);
-
- init_usb_anchor(&priv->tx_submitted);
- atomic_set(&priv->active_tx_jobs, 0);
-
- for (i = 0; i < MAX_TX_URBS; i++)
- priv->tx_contexts[i].echo_index = MAX_TX_URBS;
-
- priv->usb2 = dev;
- priv->netdev = netdev;
- priv->index = index;
-
- priv->can.state = CAN_STATE_STOPPED;
- priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY |
- CAN_CTRLMODE_CC_LEN8_DLC;
-
- if (le16_to_cpu(dev->udev->descriptor.idProduct) ==
- USB_CANUSBM_PRODUCT_ID)
- priv->can.clock.freq = ESD_USBM_CAN_CLOCK;
- else {
- priv->can.clock.freq = ESD_USB2_CAN_CLOCK;
- priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
- }
-
- priv->can.bittiming_const = &esd_usb2_bittiming_const;
- priv->can.do_set_bittiming = esd_usb2_set_bittiming;
- priv->can.do_set_mode = esd_usb2_set_mode;
- priv->can.do_get_berr_counter = esd_usb2_get_berr_counter;
-
- netdev->flags |= IFF_ECHO; /* we support local echo */
-
- netdev->netdev_ops = &esd_usb2_netdev_ops;
-
- SET_NETDEV_DEV(netdev, &intf->dev);
- netdev->dev_id = index;
-
- err = register_candev(netdev);
- if (err) {
- dev_err(&intf->dev, "couldn't register CAN device: %d\n", err);
- free_candev(netdev);
- err = -ENOMEM;
- goto done;
- }
-
- dev->nets[index] = priv;
- netdev_info(netdev, "device %s registered\n", netdev->name);
-
-done:
- return err;
-}
-
-/*
- * probe function for new USB2 devices
- *
- * check version information and number of available
- * CAN interfaces
- */
-static int esd_usb2_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct esd_usb2 *dev;
- struct esd_usb2_msg *msg;
- int i, err;
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev) {
- err = -ENOMEM;
- goto done;
- }
-
- dev->udev = interface_to_usbdev(intf);
-
- init_usb_anchor(&dev->rx_submitted);
-
- usb_set_intfdata(intf, dev);
-
- msg = kmalloc(sizeof(*msg), GFP_KERNEL);
- if (!msg) {
- err = -ENOMEM;
- goto free_msg;
- }
-
- /* query number of CAN interfaces (nets) */
- msg->msg.hdr.cmd = CMD_VERSION;
- msg->msg.hdr.len = 2;
- msg->msg.version.rsvd = 0;
- msg->msg.version.flags = 0;
- msg->msg.version.drv_version = 0;
-
- err = esd_usb2_send_msg(dev, msg);
- if (err < 0) {
- dev_err(&intf->dev, "sending version message failed\n");
- goto free_msg;
- }
-
- err = esd_usb2_wait_msg(dev, msg);
- if (err < 0) {
- dev_err(&intf->dev, "no version message answer\n");
- goto free_msg;
- }
-
- dev->net_count = (int)msg->msg.version_reply.nets;
- dev->version = le32_to_cpu(msg->msg.version_reply.version);
-
- if (device_create_file(&intf->dev, &dev_attr_firmware))
- dev_err(&intf->dev,
- "Couldn't create device file for firmware\n");
-
- if (device_create_file(&intf->dev, &dev_attr_hardware))
- dev_err(&intf->dev,
- "Couldn't create device file for hardware\n");
-
- if (device_create_file(&intf->dev, &dev_attr_nets))
- dev_err(&intf->dev,
- "Couldn't create device file for nets\n");
-
- /* do per device probing */
- for (i = 0; i < dev->net_count; i++)
- esd_usb2_probe_one_net(intf, i);
-
-free_msg:
- kfree(msg);
- if (err)
- kfree(dev);
-done:
- return err;
-}
-
-/*
- * called by the usb core when the device is removed from the system
- */
-static void esd_usb2_disconnect(struct usb_interface *intf)
-{
- struct esd_usb2 *dev = usb_get_intfdata(intf);
- struct net_device *netdev;
- int i;
-
- device_remove_file(&intf->dev, &dev_attr_firmware);
- device_remove_file(&intf->dev, &dev_attr_hardware);
- device_remove_file(&intf->dev, &dev_attr_nets);
-
- usb_set_intfdata(intf, NULL);
-
- if (dev) {
- for (i = 0; i < dev->net_count; i++) {
- if (dev->nets[i]) {
- netdev = dev->nets[i]->netdev;
- unregister_netdev(netdev);
- free_candev(netdev);
- }
- }
- unlink_all_urbs(dev);
- kfree(dev);
- }
-}
-
-/* usb specific object needed to register this driver with the usb subsystem */
-static struct usb_driver esd_usb2_driver = {
- .name = "esd_usb2",
- .probe = esd_usb2_probe,
- .disconnect = esd_usb2_disconnect,
- .id_table = esd_usb2_table,
-};
-
-module_usb_driver(esd_usb2_driver);
next prev parent reply other threads:[~2026-08-20 16:32 UTC|newest]
Thread overview: 276+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-20 14:53 [PATCH 5.15 000/272] 5.15.217-rc1 review Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 001/272] f2fs: fix UAF issue in f2fs_merge_page_bio() Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 002/272] media: mtk-vcodec: potential null pointer deference in SCP Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 003/272] media: mediatek: vcodec: Fix a resource leak related to the scp device in FW initialization Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 004/272] fscrypt: use the mount idmap for the owner check in fscrypt_ioctl_set_policy() Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 005/272] ipvs: separate destination availability state Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 006/272] selinux: require every boolean value to be defined Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 007/272] selinux: reject a class permission count below its inherited common Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 008/272] selinux: do not cancel a policy conversion that never started Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 009/272] mptcp: options: reset DSS fields in case of unexpected size Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 010/272] s390/qeth: validate user buffer length in SNMP and ARP query ioctls Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 011/272] ASoC: cs4265: sort the register default table Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 012/272] ASoC: codecs: lpass-wsa-macro: Fix enum kcontrol accesses Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 013/272] powerpc/pseries: pci - logic bug Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 014/272] Input: synaptics-rmi4 - fix F55 transmitter electrode count typo Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 015/272] Input: focaltech - fix array out-of-bounds in focaltech_process_rel_packet Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 016/272] Input: psxpad-spi - set driver data before use Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 017/272] Input: atkbd - skip deactivate for Xiaomi Book Pro 14s internal keyboard Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 018/272] Input: iforce - validate input packet lengths Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 019/272] powerpc/pseries: lparcfg - fix kbuf[] underflow Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 020/272] Input: synaptics-rmi4 - zero report size on F54 work error Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 021/272] Input: synaptics-rmi4 - bound the F54 report size to the allocated buffer Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 022/272] Input: synaptics-rmi4 - block s_input when F54 queue is busy Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 023/272] Input: synaptics-rmi4 - propagate F54 worker errors to V4L2 queue Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 024/272] crypto: qce - fix error path in devm_qce_register_algs Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 025/272] libceph: fix multiple unsafe decodes in decode_locker() Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 026/272] ftrace: Fix off-by-one fentry site disable in ftrace_free_mem() Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 027/272] openrisc: signal: do not restore privileged SR bits on sigreturn Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 028/272] Input: sur40 - fix input device registration ordering Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 029/272] Input: sur40 - fix V4L error path cleanup Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 030/272] libceph: Avoid using invalid osd indices from primary_temp Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 031/272] ceph: fix MDS random selection readiness predicate Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 032/272] libceph: tolerate addrvecs with multiple entries of the same type Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 033/272] mmc: omap_hsmmc: fix busy_timeout overflow in ns conversion on 32-bit Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 034/272] mmc: sdhci: unmap the bounce buffer before device release Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 035/272] mmc: sdhci: make tuning_err a signed int Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 036/272] mmc: atmel-mci: Fix use-after-free in atmci_remove due to race condition Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 037/272] drm/radeon: fix autosuspend cleanup during teardown Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 038/272] s390/vfio_ccw: Fix out of bounds check on CCW array Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 039/272] drm/amdgpu: Reject UVD message with invalid number of h265 refs Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 040/272] drm/amdgpu: validate GEM_CREATE domain combinations Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 041/272] drm/amdgpu: Reject UVD message with dimensions above 4096 Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 042/272] drm/amdgpu: Implement insert_end for VCE 3 Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 043/272] drm/amdgpu: Fix UVD decode image min size calculation Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 044/272] xfs: fix ilock leak on error in xfs_dq_get_next_id Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 045/272] xfs: check v5 superblock features early Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 046/272] net/smc: reject CHID-0 ACCEPT that matches an empty ism_dev slot Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 047/272] mm: do file ownership checks with the proper mount idmap Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 048/272] iommu/amd: Dont split flush for amd_iommu_domain_flush_all() Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 049/272] bpf: Reject BPF_MAP_TYPE_INODE_STORAGE creation if BPF LSM is uninitialized Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 050/272] udmabuf: Do not create malformed scatterlists Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 051/272] dma-buf/udmabuf: skip redundant cpu sync to fix cacheline EEXIST warning Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 052/272] fpga: dfl-afu: validate DMA mapping length in afu_dma_map_region() Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 053/272] Input: mms114 - fix touch indexing for MMS134S and MMS136 Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 054/272] i2c: davinci: Unregister cpufreq notifier on probe failure Greg Kroah-Hartman
2026-08-20 14:53 ` [PATCH 5.15 055/272] Input: mms114 - reject an oversized device packet size Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 056/272] ALSA: hda: conexant: Remove mic bias threshold override Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 057/272] VFS/audit: introduce kern_path_parent() for audit Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 058/272] audit: widen ino fields to u64 Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 059/272] audit: use unsigned int instead of unsigned Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 060/272] audit: fix recursive locking deadlock in audit_dupe_exe() Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 061/272] ALSA: hda: Fix cached processing coefficient verbs Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 062/272] serial: max310x: replace bare use of unsigned with unsigned int (checkpatch) Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 063/272] serial: max310x: implement gpio_chip::get_direction() Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 064/272] rxrpc: serialize kernel accept preallocation with socket teardown Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 065/272] fbcon: Rename struct fbcon_ops to struct fbcon_par Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 066/272] fbcon: Use correct type for vc_resize() return value Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 067/272] tipc: restrict socket queue dumps in enqueue tracepoints Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 068/272] mlxsw: spectrum: On port enslavement to a LAG, join uppers bridges Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 069/272] mlxsw: fix refcount leak in mlxsw_sp_port_lag_join() Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 070/272] vduse: Use fixed 4KB bounce pages for non-4KB page size Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 071/272] vduse: remove unused vaddr parameter of vduse_domain_free_coherent Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 072/272] vduse: take out allocations from vduse_dev_alloc_coherent Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 073/272] VDUSE: avoid leaking information to userspace Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 074/272] octeontx2-af: Fix APR entry mapping based on APR_LMT_CFG Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 075/272] octeontx2: Annotate mmio regions as __iomem Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 076/272] octeontx2-pf: clear stale mailbox IRQ state before request_irq() Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 077/272] octeontx2-vf: " Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 078/272] ASoC: mediatek: mt8183: Check runtime resume during probe Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 079/272] tcp: convert to dev_net_rcu() Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 080/272] net: dst: annotate data-races around dst->input Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 081/272] net: dst: annotate data-races around dst->output Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 082/272] net: dst: add four helpers to annotate data-races around dst->dev Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 083/272] ipv4: adopt dst_dev, skb_dst_dev and skb_dst_dev_net[_rcu] Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 084/272] netfilter: nf_queue: pin bridge device while NFQUEUE holds fake dst Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 085/272] ASoC: mediatek: mt8192-afe-pcm: Convert to devm_pm_runtime_enable() Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 086/272] ASoC: mediatek: mt8192-afe-pcm: Simplify with dev_err_probe() Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 087/272] ASoC: mediatek: Use common mtk_afe_pcm_platform with common probe cb Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 088/272] ASoC: mediatek: mt8192-afe-pcm: Simplify probe() with local dev variable Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 089/272] ASoC: mediatek: mt8192: Check runtime resume during probe Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 090/272] netfilter: nft_set_pipapo: use GFP_KERNEL for insertions Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 091/272] netfilter: nft_set_pipapo: move prove_locking helper around Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 092/272] netfilter: nf_conntrack_sip: remove net variable shadowing Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 093/272] netfilter: nf_conntrack_sip: validate skb_dst() before accessing it Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 094/272] netfilter: nft_set_pipapo: make pipapo_clone helper return NULL Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 095/272] netfilter: nft_set_pipapo: prepare walk function for on-demand clone Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 096/272] netfilter: nft_set_pipapo: merge deactivate helper into caller Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 097/272] netfilter: nft_set_pipapo: prepare pipapo_get helper for on-demand clone Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 098/272] netfilter: nft_set_pipapo: move cloning of match info to insert/removal path Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 099/272] netfilter: nft_set_pipapo: dont leak bad clone into future transaction Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 100/272] remoteproc: qcom: replace kstrdup with kstrndup Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 101/272] remoteproc: qcom: fix sparse warnings Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 102/272] remoteproc: qcom: pas: Adjust the phys addr wrt the mem region Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 103/272] remoteproc: qcom: Fix leak when custom dump_segments addition fails Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 104/272] lsm: use default hook return value in call_int_hook() Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 105/272] lsm: infrastructure management of the sock security Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 106/272] selinux: avoid sk_socket dereference in selinux_sctp_bind_connect() Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 107/272] fs/ntfs3: Make ntfs_update_mftmirr return void Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 108/272] fs/ntfs3: Undo critial modificatins to keep directory consistency Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 109/272] ntfs3: validate split-point offset in indx_insert_into_buffer Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 110/272] 9p: skip nlink update in cacheless mode to fix WARN_ON Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 111/272] mtd: maps: vmu-flash: fix fault in unaligned fixup Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 112/272] net: thunderbolt: Fix frags[] overflow by bounding frame_count Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 113/272] mtd: spi-nor: Fix spi_nor_try_unlock_all() Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 114/272] mtd: spi-nor: swp: Improve locking user experience Greg Kroah-Hartman
2026-08-20 14:54 ` [PATCH 5.15 115/272] dmaengine: dw-edma: Remove unused irq field in struct dw_edma_chip Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 116/272] dmaengine: dw-edma: Detach the private data and chip info structures Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 117/272] dmaengine: dw-edma: Add spinlock to protect DONE_INT_MASK and ABORT_INT_MASK Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 118/272] taskstats: fill_stats_for_tgid: use for_each_thread() Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 119/272] taskstats: retain dead thread stats in TGID queries Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 120/272] smb: client: use kvzalloc() for megabyte buffer in simple fallocate Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 121/272] tpm: tpm_tis_spi: Use wait_woken() in wait_for_tmp_stat() Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 122/272] ksmbd: fix integer overflow in set_file_allocation_info() Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 123/272] i2c: imx: separate atomic, dma and non-dma use case Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 124/272] i2c: imx: fix locked bus on SMBus block-read of 0 (atomic) Greg Kroah-Hartman
2026-08-20 14:55 ` Greg Kroah-Hartman [this message]
2026-08-20 14:55 ` [PATCH 5.15 126/272] can: esd_usb: kill anchored URBs before freeing netdevs Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 127/272] thunderbolt: Remove usage of the deprecated ida_simple_xx() API Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 128/272] thunderbolt: Update property.c function documentation Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 129/272] thunderbolt: Keep XDomain reference during the lifetime of a service Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 130/272] thunderbolt: Remove service debugfs entries during unregister Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 131/272] thunderbolt: Remove XDomain from the bus without holding tb->lock Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 132/272] thunderbolt: Prevent XDomain delayed work use-after-free on disconnect Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 133/272] bpf,fork: wipe ->bpf_storage before bailouts that access it Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 134/272] ovl: use linked upper dentry in copy-up tmpfile Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 135/272] scsi: lpfc: Fix memory leak in lpfc_sli4_driver_resource_setup() Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 136/272] dm-integrity: dont increment hash_offset twice Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 137/272] dm-verity: make error counter atomic Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 138/272] firmware_loader: introduce __free() cleanup hanler Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 139/272] Input: ims-pcu - fix firmware leak in async update Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 140/272] mmc: vub300: fix use-after-free on disconnect Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 141/272] mmc: vub300: rename probe error labels Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 142/272] mmc: vub300: fix use-after-free on probe failure Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 143/272] locking/rt: Fix the incorrect RCU protection in rt_spin_unlock() Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 144/272] net: Add helper function to parse netlink msg of ip_tunnel_encap Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 145/272] net: ipip: require CAP_NET_ADMIN in the device netns for changelink Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 146/272] net: ixp4xx_hss: fix duplicate HDLC netdev allocation Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 147/272] net/sched: act_ct: preserve tc_skb_cb across defragmentation Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 148/272] net: mana: Validate the packet length reported by the NIC Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 149/272] net: ip6_tunnel: require CAP_NET_ADMIN in the device netns for changelink Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 150/272] octeontx2-af: cn10k: restrict VF LMTLINE sharing to its own PF Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 151/272] treewide: rename pinctrl_gpio_direction_output_new() Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 152/272] gpio: tegra: do not call pinctrl for GPIO direction Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 153/272] net/sched: taprio: avoid calling child->ops->dequeue(child) twice Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 154/272] net/sched: sch_taprio: Replace direct dequeue call with peek and qdisc_dequeue_peeked Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 155/272] bootconfig: do not put quotes on cmdline items unless necessary Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 156/272] bootconfig: move xbc_snprint_cmdline() to lib/bootconfig.c Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 157/272] bootconfig: fix NULL-pointer arithmetic in xbc_snprint_cmdline() Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 158/272] espintcp: use sk_msg_free_partial to fix partial send Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 159/272] net: ipa: fix SMEM state handle leaks in SMP2P init Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 160/272] octeontx2-pf: fix SQB pointer leak on init failure Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 161/272] fs/resctrl: Fix double-add of pseudo-locked regions RMID to free list Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 162/272] KVM: x86/mmu: Directly "destroy" PTE list when recycling rmaps Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 163/272] KVM: x86/mmu: Rename pte_list_{destroy,remove}() to show they zap SPTEs Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 164/272] KVM: x86/mmu: Document the "rules" for using host_pfn_mapping_level() Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 165/272] KVM: Rename mmu_notifier_* to mmu_invalidate_* Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 166/272] KVM: x86/mmu: Split out TDP MMU page fault handling Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 167/272] KVM: x86/mmu: Rename __direct_map() to direct_map() Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 168/272] drm/dp/mst: fix buffer overflows in sideband chunk accumulation Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 169/272] usb: gadget: f_tcm: synchronize delayed set_alt with teardown Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 170/272] drm/dp/mst: fix OOB reads in remote DPCD/I2C sideband reply parsers Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 171/272] drm/dp/mst: fix OOB reads on 2-byte fields in " Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 172/272] dma-buf/drivers: make reserving a shared slot mandatory v4 Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 173/272] drm/virtio: use uninterruptible resv lock for plane updates Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 174/272] drm/displayid: fix Tiled Display Topology ID size Greg Kroah-Hartman
2026-08-20 14:55 ` [PATCH 5.15 175/272] drm/tegra: fbdev: Remove offset into framebuffer memory Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 176/272] drm/amdgpu: Fix amdgpu_bo_move() when old_mem and new_mem are both GTT Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 177/272] drm/virtio: Return proper error codes instead of -1 Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 178/272] drm/virtio: bound EDID block reads to the response buffer Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 179/272] media: aspeed: fix missing of_reserved_mem_device_release() on probe failure Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 180/272] drm/i915/vrr: require valid min/max vfreq for VRR Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 181/272] drm/i915/hdcp: check streams[] bounds before overflow Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 182/272] drm/i915/hdcp: require monotonically increasing seq_num_v Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 183/272] media: marvell-cam: fix missing pci_disable_device() on remove Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 184/272] media: i2c: imx219: Drop IMX219_VTS_* macros Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 185/272] media: i2c: imx219: Correct the minimum vblanking value Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 186/272] media: i2c: imx219: Rename VTS to FRM_LENGTH Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 187/272] media: imx219: Fix maximum frame length in lines Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 188/272] wifi: ath6kl: fix use-after-free in aggr_reset_state() Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 189/272] media: v4l: async: Set owner for async sub-devices Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 190/272] media: v4l2-fwnode: Fix subdev owner overwritten in v4l2_async_register_subdev_sensor() Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 191/272] ALSA: seq: close a re-opened queue timer in the destructor Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 192/272] wifi: brcmfmac: drain bus_reset work on device removal Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 193/272] serial: 8250_mid: Remove unneeded test for ->setup() presence Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 194/272] serial: 8250_mid: Fix NULL function pointer dereference on DNV/ICX-D/SNR platforms Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 195/272] wifi: brcmfmac: fix 43752 SDIO FWVID incorrectly labelled as Cypress (CYW) Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 196/272] wifi: brcmfmac: set F2 blocksize to 256 for BCM43752 Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 197/272] sc16is7xx: Properly resume TX after stop Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 198/272] serial: sc16is7xx: Fill in rs485_supported Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 199/272] serial: sc16is7xx: remove obsolete out_thread label Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 200/272] serial: sc16is7xx: fix regression with GPIO configuration Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 201/272] serial: sc16is7xx: implement gpio get_direction() callback Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 202/272] mptcp: cleanup MPJ subflow list handling Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 203/272] mptcp: fix subflow accounting on close Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 204/272] mptcp: decrement subflows counter on failed passive join Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 205/272] sctp: avoid auth_enable sysctl UAF during netns teardown Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 206/272] ceph: avoid fs reclaim while using current->journal_info Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 207/272] libceph: Amend checking to fix `make W=1` build breakage Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 208/272] libceph: bound pg_{temp,upmap,upmap_items} length to CEPH_PG_MAX_SIZE Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 209/272] libceph: add doutc and *_client debug macros support Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 210/272] ceph: rename _to_client() to _to_fs_client() Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 211/272] ceph: print cluster fsid and client global_id in all debug logs Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 212/272] ceph: fix hanging __ceph_get_caps() with stale mds_wanted Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 213/272] libceph: fix two unsafe bare decodes in decode_lockers() Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 214/272] ksmbd: defer destroy_previous_session() until after NTLM authentication Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 215/272] net/sched: serialize qdisc_rtab_list against concurrent get/put Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 216/272] ftrace: Add global mutex to serialize trace_parser access Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 217/272] super: fix emergency thaw deadlock on frozen block devices Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 218/272] ksmbd: rename smb2_get_msg to smb_get_msg Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 219/272] smb/server: fix minimum SMB1 PDU size Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 220/272] smb/server: fix minimum SMB2 " Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 221/272] ksmbd: validate minimum PDU size for transform requests Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 222/272] mm/vmstat: fold stranded per-cpu node stats when a node comes online Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 223/272] ksmbd: conn lock to serialize smb2 negotiate Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 224/272] ksmbd: reject repeated SMB2 NEGOTIATE requests Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 225/272] wifi: libertas_tf: fix use-after-free in lbtf_free_adapter() Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 226/272] igc: remove napi_synchronize() in igc_down() Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 227/272] net: pktgen: fix code style (WARNING: Block comments) Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 228/272] net: pktgen: fix proc entry use-after-free Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 229/272] scsi: sd: sd_zbc: Improve source code documentation Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 230/272] scsi: sd: sd_zbc: Use logical blocks as unit when querying zones Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 231/272] scsi: sd: sd_zbc: Introduce struct zoned_disk_info Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 232/272] scsi: sd: sd_zbc: Return early in sd_zbc_check_zoned_characteristics() Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 233/272] scsi: scsi_debug: Rename zone type constants Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 234/272] scsi: scsi_debug: Fix REPORT ZONES alloc_len underflow OOB write Greg Kroah-Hartman
2026-08-20 14:56 ` [PATCH 5.15 235/272] ice: fix VF interrupts cleanup Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 236/272] ice: fix memory leak in ice_lbtest_prepare_rings() Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 237/272] fsnotify: opt-in for permission events at file open time Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 238/272] fs: dont block write during exec on pre-content watched files Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 239/272] binfmt_misc: restore write access when removing an entry Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 240/272] i2c: imx: Fix slave registration race and error handling Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 241/272] i2c: bcm-iproc: remove printout on handled timeouts Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 242/272] i2c: iproc: reset bus after timeout if START_BUSY is stuck Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 243/272] can: gs_usb: gs_usb_receive_bulk_callback(): resubmit URB on skb allocation failure Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 244/272] jiffies: Define secs_to_jiffies() Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 245/272] ice: wait for reset completion in ice_resume() Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 246/272] drm/amd/pm: fix torn gpu metrics reads Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 247/272] sched/psi: Shut down rtpoll_timer in psi_cgroup_free() Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 248/272] mm/ptdump: always stabilise against page table freeing using init_mm Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 249/272] net: add a couple of helpers for iph tot_len Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 250/272] openvswitch: use skb_ip_totlen in conntrack Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 251/272] net: sched: use skb_ip_totlen and iph_totlen Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 252/272] openvswitch: move key and ovs_cb update out of handle_fragments Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 253/272] net/sched: act_ct: fix sk_buff leak when the header checks reject a packet Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 254/272] net: atlantic: free stranded TX buffers on ring deinit Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 255/272] net/smc: rdma write inline if qp has sufficient inline space Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 256/272] net: smc: fix splice entry lifetime imbalance in smc_rx_splice Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 257/272] arm64: tegra: Add EL2 virtual timer interrupt for Tegra194 Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 258/272] crypto: ccm - Set rfc4309 maxauthsize from child Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 259/272] netfilter: ipset: fix refcount race between list:set GC and swap Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 260/272] netfilter: nf_tables_offload: suppress WARN_ON_ONCE for ENOMEM in abort path Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 261/272] netfilter: flowtable: publish GC-visible tuple last Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 262/272] netfilter: ipset: fix list type element drift bug Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 263/272] net: packet: fix wrong transport_header when sending VLAN-tagged frame Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 264/272] ASoC: xilinx: formatter_pcm: pass aud_drv_data to irq handlers Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 265/272] af_packet: Dont send zero-byte data in tpacket_snd() Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 266/272] net: ethernet: ti: am65-cpsw-nuss: Fix port_id extraction from SRC TAG Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 267/272] net/x25: fix use-after-free of the socket by its timers Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 268/272] binfmt_misc: use exe_file_deny_write_access() for the interpreter clone Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 269/272] udmabuf: Ensure to perform cache synchronisation in begin_cpu_udmabuf() Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 270/272] drm/vmwgfx: Reserve fence slots on buffer objects in cotables Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 271/272] drm/virtio: Unlock reservations on dma_resv_reserve_fences() error Greg Kroah-Hartman
2026-08-20 14:57 ` [PATCH 5.15 272/272] jiffies: Cast to unsigned long in secs_to_jiffies() conversion Greg Kroah-Hartman
2026-08-20 18:01 ` [PATCH 5.15 000/272] 5.15.217-rc1 review Florian Fainelli
2026-08-20 18:24 ` Pavel Machek
2026-08-20 20:24 ` Brett A C Sheffield
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260820145235.013938194@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=frank.jungclaus@esd.eu \
--cc=mkl@pengutronix.de \
--cc=patches@lists.linux.dev \
--cc=sashal@kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.