* [RFC net-next 0/3] cleanup of usbnet descriptor allocation
@ 2026-02-10 15:11 Oliver Neukum
2026-02-10 15:11 ` [RFC net-next 1/3] net: usb: divorce private data and cdc state in usbnet Oliver Neukum
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Oliver Neukum @ 2026-02-10 15:11 UTC (permalink / raw)
To: netdev, hayeswang, bjorn, o.rempel
Currently the driver has an array of long[5]. That may or may not be
enough, so a secondary pointer was added.
That is quite complex. This series adds a field to driver_info, by
which mini drivers tell usbnet how much space they need. This allows
basically unlimited allocations.
This is the first draft.
^ permalink raw reply [flat|nested] 13+ messages in thread
* [RFC net-next 1/3] net: usb: divorce private data and cdc state in usbnet
2026-02-10 15:11 [RFC net-next 0/3] cleanup of usbnet descriptor allocation Oliver Neukum
@ 2026-02-10 15:11 ` Oliver Neukum
2026-02-10 16:27 ` Bjørn Mork
` (2 more replies)
2026-02-10 15:11 ` [RFC net-next 2/3] net: usb: usbnet: switch to dynamic allocation of private data Oliver Neukum
2026-02-10 15:11 ` [RFC net-next 3/3] net: usb: usbnet: remove driver_priv Oliver Neukum
2 siblings, 3 replies; 13+ messages in thread
From: Oliver Neukum @ 2026-02-10 15:11 UTC (permalink / raw)
To: netdev, hayeswang, bjorn, o.rempel; +Cc: Oliver Neukum
This allows use of cdc helpers together with private dara.
Signed-off-by: Oliver Neukum <oneukum@suse.com>
---
drivers/net/usb/asix_common.c | 4 +--
drivers/net/usb/asix_devices.c | 18 +++++-----
drivers/net/usb/ax88172a.c | 2 +-
drivers/net/usb/ax88179_178a.c | 2 +-
drivers/net/usb/cdc_ether.c | 12 ++-----
drivers/net/usb/cdc_mbim.c | 18 +++++-----
drivers/net/usb/cdc_ncm.c | 58 ++++++++++++++++----------------
drivers/net/usb/cx82310_eth.c | 6 ++--
drivers/net/usb/dm9601.c | 2 +-
drivers/net/usb/huawei_cdc_ncm.c | 10 +++---
drivers/net/usb/mcs7830.c | 2 +-
drivers/net/usb/net1080.c | 2 +-
drivers/net/usb/qmi_wwan.c | 33 +++++++++---------
drivers/net/usb/rndis_host.c | 6 ++--
drivers/net/usb/sierra_net.c | 7 ++--
drivers/net/usb/smsc75xx.c | 40 +++++++++++-----------
drivers/net/usb/sr9700.c | 1 +
drivers/net/usb/sr9800.c | 10 +++---
include/linux/usb/usbnet.h | 27 ++++++++-------
19 files changed, 125 insertions(+), 135 deletions(-)
diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c
index 4f03f4e57655..d97a1920cb6e 100644
--- a/drivers/net/usb/asix_common.c
+++ b/drivers/net/usb/asix_common.c
@@ -441,7 +441,7 @@ int asix_write_gpio(struct usbnet *dev, u16 value, int sleep, int in_pm)
void asix_set_multicast(struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = (struct asix_data *)&dev->private;
u16 rx_ctl = AX_DEFAULT_RX_CTL;
if (net->flags & IFF_PROMISC) {
@@ -734,7 +734,7 @@ int asix_set_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom,
int asix_set_mac_address(struct net_device *net, void *p)
{
struct usbnet *dev = netdev_priv(net);
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = (struct asix_data *)&dev->private;
struct sockaddr *addr = p;
if (netif_running(net))
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
index 7eb6e86adb16..5100e0b31f1f 100644
--- a/drivers/net/usb/asix_devices.c
+++ b/drivers/net/usb/asix_devices.c
@@ -118,7 +118,7 @@ static const struct ethtool_ops ax88172_ethtool_ops = {
static void ax88172_set_multicast(struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = (struct asix_data *)&dev->private;
u8 rx_ctl = 0x8c;
if (net->flags & IFF_PROMISC) {
@@ -129,7 +129,7 @@ static void ax88172_set_multicast(struct net_device *net)
} else if (netdev_mc_empty(net)) {
/* just broadcast and directed */
} else {
- /* We use the 20 byte dev->data
+ /* We use the 20 byte dev->private
* for our 8 byte filter buffer
* to avoid allocating memory that
* is tricky to free later */
@@ -331,7 +331,7 @@ static const struct ethtool_ops ax88772_ethtool_ops = {
static int ax88772_reset(struct usbnet *dev)
{
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = (struct asix_data *)&dev->private;
struct asix_common_private *priv = dev->driver_priv;
int ret;
@@ -361,7 +361,7 @@ static int ax88772_reset(struct usbnet *dev)
static int ax88772_hw_reset(struct usbnet *dev, int in_pm)
{
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = (struct asix_data *)&dev->private;
struct asix_common_private *priv = dev->driver_priv;
u16 rx_ctl;
int ret;
@@ -455,7 +455,7 @@ static int ax88772_hw_reset(struct usbnet *dev, int in_pm)
static int ax88772a_hw_reset(struct usbnet *dev, int in_pm)
{
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = (struct asix_data *)&dev->private;
struct asix_common_private *priv = dev->driver_priv;
u16 rx_ctl, phy14h, phy15h, phy16h;
int ret;
@@ -987,7 +987,7 @@ static const struct ethtool_ops ax88178_ethtool_ops = {
static int marvell_phy_init(struct usbnet *dev)
{
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = (struct asix_data *)&dev->private;
u16 reg;
netdev_dbg(dev->net, "marvell_phy_init()\n");
@@ -1018,7 +1018,7 @@ static int marvell_phy_init(struct usbnet *dev)
static int rtl8211cl_phy_init(struct usbnet *dev)
{
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = (struct asix_data *)&dev->private;
netdev_dbg(dev->net, "rtl8211cl_phy_init()\n");
@@ -1065,7 +1065,7 @@ static int marvell_led_status(struct usbnet *dev, u16 speed)
static int ax88178_reset(struct usbnet *dev)
{
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = (struct asix_data *)&dev->private;
int ret;
__le16 eeprom;
u8 status;
@@ -1163,7 +1163,7 @@ static int ax88178_link_reset(struct usbnet *dev)
{
u16 mode;
struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = (struct asix_data *)&dev->private;
u32 speed;
netdev_dbg(dev->net, "ax88178_link_reset()\n");
diff --git a/drivers/net/usb/ax88172a.c b/drivers/net/usb/ax88172a.c
index 3100fbe153c0..1694d6ca2b7b 100644
--- a/drivers/net/usb/ax88172a.c
+++ b/drivers/net/usb/ax88172a.c
@@ -260,7 +260,7 @@ static void ax88172a_unbind(struct usbnet *dev, struct usb_interface *intf)
static int ax88172a_reset(struct usbnet *dev)
{
- struct asix_data *data = (struct asix_data *)&dev->data;
+ struct asix_data *data = (struct asix_data *)&dev->private;
struct ax88172a_private *priv = dev->driver_priv;
int ret;
u16 rx_ctl;
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index 0e9ae89b840e..df7e3f1c3672 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -868,7 +868,7 @@ static void ax88179_set_multicast(struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
struct ax88179_data *data = dev->driver_priv;
- u8 *m_filter = ((u8 *)dev->data);
+ u8 *m_filter = ((u8 *)dev->private);
data->rxctl = (AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_CTL_IPE);
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 505a653d9482..dafc2462be98 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -85,16 +85,13 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
u8 *buf = intf->cur_altsetting->extra;
int len = intf->cur_altsetting->extralen;
struct usb_interface_descriptor *d;
- struct cdc_state *info = (void *) &dev->data;
+ struct cdc_state *info = &dev->cdc;
int status;
int rndis;
bool android_rndis_quirk = false;
struct usb_driver *driver = driver_of(intf);
struct usb_cdc_parsed_header header;
- if (sizeof(dev->data) < sizeof(*info))
- return -EDOM;
-
/* expect strict spec conformance for the descriptors, but
* cope with firmware which stores them in the wrong place
*/
@@ -330,7 +327,7 @@ EXPORT_SYMBOL_GPL(usbnet_ether_cdc_bind);
void usbnet_cdc_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct cdc_state *info = (void *) &dev->data;
+ struct cdc_state *info = &dev->cdc;
struct usb_driver *driver = driver_of(intf);
/* combined interface - nothing to do */
@@ -368,10 +365,7 @@ EXPORT_SYMBOL_GPL(usbnet_cdc_unbind);
int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
{
int status;
- struct cdc_state *info = (void *) &dev->data;
-
- BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data)
- < sizeof(struct cdc_state)));
+ struct cdc_state *info = &dev->cdc;
status = usbnet_ether_cdc_bind(dev, intf);
if (status < 0)
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index dbf01210b0e7..f08f0fc3a8c1 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -43,7 +43,7 @@ enum cdc_mbim_flags {
/* using a counter to merge subdriver requests with our own into a combined state */
static int cdc_mbim_manage_power(struct usbnet *dev, int on)
{
- struct cdc_mbim_state *info = (void *)&dev->data;
+ struct cdc_mbim_state *info = (void *)&dev->private;
int rv = 0;
dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__, atomic_read(&info->pmcount), on);
@@ -72,7 +72,7 @@ static int cdc_mbim_wdm_manage_power(struct usb_interface *intf, int status)
static int cdc_mbim_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
{
struct usbnet *dev = netdev_priv(netdev);
- struct cdc_mbim_state *info = (void *)&dev->data;
+ struct cdc_mbim_state *info = (void *)&dev->private;
/* creation of this VLAN is a request to tag IP session 0 */
if (vid == MBIM_IPS0_VID)
@@ -86,7 +86,7 @@ static int cdc_mbim_rx_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
static int cdc_mbim_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
{
struct usbnet *dev = netdev_priv(netdev);
- struct cdc_mbim_state *info = (void *)&dev->data;
+ struct cdc_mbim_state *info = (void *)&dev->private;
/* this is a request for an untagged IP session 0 */
if (vid == MBIM_IPS0_VID)
@@ -143,7 +143,7 @@ static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf)
struct usb_driver *subdriver = ERR_PTR(-ENODEV);
int ret = -ENODEV;
u8 data_altsetting = 1;
- struct cdc_mbim_state *info = (void *)&dev->data;
+ struct cdc_mbim_state *info = (void *)&dev->private;
/* should we change control altsetting on a NCM/MBIM function? */
if (cdc_ncm_select_altsetting(intf) == CDC_NCM_COMM_ALTSETTING_MBIM) {
@@ -195,7 +195,7 @@ static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf)
static void cdc_mbim_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct cdc_mbim_state *info = (void *)&dev->data;
+ struct cdc_mbim_state *info = (void *)&dev->private;
struct cdc_ncm_ctx *ctx = info->ctx;
/* disconnect subdriver from control interface */
@@ -221,7 +221,7 @@ static bool is_ip_proto(__be16 proto)
static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
struct sk_buff *skb_out;
- struct cdc_mbim_state *info = (void *)&dev->data;
+ struct cdc_mbim_state *info = (void *)&dev->private;
struct cdc_ncm_ctx *ctx = info->ctx;
__le32 sign = cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN);
u16 tci = 0;
@@ -411,7 +411,7 @@ static struct sk_buff *cdc_mbim_process_dgram(struct usbnet *dev, u8 *buf, size_
static int cdc_mbim_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
{
struct sk_buff *skb;
- struct cdc_mbim_state *info = (void *)&dev->data;
+ struct cdc_mbim_state *info = (void *)&dev->private;
struct cdc_ncm_ctx *ctx = info->ctx;
int len;
int nframes;
@@ -506,7 +506,7 @@ static int cdc_mbim_suspend(struct usb_interface *intf, pm_message_t message)
{
int ret = -ENODEV;
struct usbnet *dev = usb_get_intfdata(intf);
- struct cdc_mbim_state *info = (void *)&dev->data;
+ struct cdc_mbim_state *info = (void *)&dev->private;
struct cdc_ncm_ctx *ctx = info->ctx;
if (!ctx)
@@ -534,7 +534,7 @@ static int cdc_mbim_resume(struct usb_interface *intf)
{
int ret = 0;
struct usbnet *dev = usb_get_intfdata(intf);
- struct cdc_mbim_state *info = (void *)&dev->data;
+ struct cdc_mbim_state *info = (void *)&dev->private;
struct cdc_ncm_ctx *ctx = info->ctx;
bool callsub = (intf == ctx->control && info->subdriver && info->subdriver->resume);
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 5d123df0a866..d0d13b2d52e6 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -107,7 +107,7 @@ static void cdc_ncm_get_ethtool_stats(struct net_device *netdev,
u64 *data)
{
struct usbnet *dev = netdev_priv(netdev);
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
int i;
char *p = NULL;
@@ -149,7 +149,7 @@ static const struct ethtool_ops cdc_ncm_ethtool_ops = {
static u32 cdc_ncm_check_rx_max(struct usbnet *dev, u32 new_rx)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
u32 val, max, min;
/* clamp new_rx to sane values */
@@ -172,7 +172,7 @@ static u32 cdc_ncm_check_rx_max(struct usbnet *dev, u32 new_rx)
static u32 cdc_ncm_check_tx_max(struct usbnet *dev, u32 new_tx)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
u32 val, max, min;
/* clamp new_tx to sane values */
@@ -202,7 +202,7 @@ static ssize_t min_tx_pkt_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
return sprintf(buf, "%u\n", ctx->min_tx_pkt);
}
@@ -211,7 +211,7 @@ static ssize_t rx_max_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
return sprintf(buf, "%u\n", ctx->rx_max);
}
@@ -220,7 +220,7 @@ static ssize_t tx_max_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
return sprintf(buf, "%u\n", ctx->tx_max);
}
@@ -229,7 +229,7 @@ static ssize_t tx_timer_usecs_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
return sprintf(buf, "%u\n", ctx->timer_interval / (u32)NSEC_PER_USEC);
}
@@ -239,7 +239,7 @@ static ssize_t min_tx_pkt_store(struct device *d,
const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
unsigned long val;
/* no need to restrict values - anything from 0 to infinity is OK */
@@ -255,7 +255,7 @@ static ssize_t rx_max_store(struct device *d,
const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
unsigned long val;
if (kstrtoul(buf, 0, &val) || cdc_ncm_check_rx_max(dev, val) != val)
@@ -270,7 +270,7 @@ static ssize_t tx_max_store(struct device *d,
const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
unsigned long val;
if (kstrtoul(buf, 0, &val) || cdc_ncm_check_tx_max(dev, val) != val)
@@ -285,7 +285,7 @@ static ssize_t tx_timer_usecs_store(struct device *d,
const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
ssize_t ret;
unsigned long val;
@@ -311,7 +311,7 @@ static DEVICE_ATTR_RW(tx_timer_usecs);
static ssize_t ndp_to_end_show(struct device *d, struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
return sprintf(buf, "%c\n", ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END ? 'Y' : 'N');
}
@@ -319,7 +319,7 @@ static ssize_t ndp_to_end_show(struct device *d, struct device_attribute *attr,
static ssize_t ndp_to_end_store(struct device *d, struct device_attribute *attr, const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
bool enable;
if (kstrtobool(buf, &enable))
@@ -361,7 +361,7 @@ static DEVICE_ATTR_RW(ndp_to_end);
static ssize_t cdc_ncm_show_##name(struct device *d, struct device_attribute *attr, char *buf) \
{ \
struct usbnet *dev = netdev_priv(to_net_dev(d)); \
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0]; \
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0]; \
return sprintf(buf, format "\n", tocpu(ctx->ncm_parm.name)); \
} \
static DEVICE_ATTR(name, 0444, cdc_ncm_show_##name, NULL)
@@ -404,7 +404,7 @@ static const struct attribute_group cdc_ncm_sysfs_attr_group = {
/* handle rx_max and tx_max changes */
static void cdc_ncm_update_rxtx_max(struct usbnet *dev, u32 new_rx, u32 new_tx)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
u32 val;
@@ -476,7 +476,7 @@ static void cdc_ncm_update_rxtx_max(struct usbnet *dev, u32 new_rx, u32 new_tx)
/* helpers for NCM and MBIM differences */
static u8 cdc_ncm_flags(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
if (cdc_ncm_comm_intf_is_mbim(dev->intf->cur_altsetting) && ctx->mbim_desc)
return ctx->mbim_desc->bmNetworkCapabilities;
@@ -501,7 +501,7 @@ static u32 cdc_ncm_min_dgram_size(struct usbnet *dev)
static u32 cdc_ncm_max_dgram_size(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
if (cdc_ncm_comm_intf_is_mbim(dev->intf->cur_altsetting) && ctx->mbim_desc)
return le16_to_cpu(ctx->mbim_desc->wMaxSegmentSize);
@@ -515,7 +515,7 @@ static u32 cdc_ncm_max_dgram_size(struct usbnet *dev)
*/
static int cdc_ncm_init(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
int err;
@@ -608,7 +608,7 @@ static int cdc_ncm_init(struct usbnet *dev)
/* set a new max datagram size */
static void cdc_ncm_set_dgram_size(struct usbnet *dev, int new_size)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
__le16 max_datagram_size;
u16 mbim_mtu;
@@ -656,7 +656,7 @@ static void cdc_ncm_set_dgram_size(struct usbnet *dev, int new_size)
static void cdc_ncm_fix_modulus(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
u32 val;
/*
@@ -700,7 +700,7 @@ static void cdc_ncm_fix_modulus(struct usbnet *dev)
static int cdc_ncm_setup(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
u32 def_rx, def_tx;
/* be conservative when selecting initial buffer size to
@@ -839,7 +839,7 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
spin_lock_init(&ctx->mtx);
/* store ctx pointer in device data field */
- dev->data[0] = (unsigned long)ctx;
+ dev->private[0] = (unsigned long)ctx;
/* only the control interface can be successfully probed */
ctx->control = intf;
@@ -988,8 +988,8 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
if (ctx->data != ctx->control)
usb_driver_release_interface(driver, ctx->data);
error:
- cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]);
- dev->data[0] = 0;
+ cdc_ncm_free((struct cdc_ncm_ctx *)dev->private[0]);
+ dev->private[0] = 0;
dev_info(&intf->dev, "bind() failure\n");
return -ENODEV;
}
@@ -997,7 +997,7 @@ EXPORT_SYMBOL_GPL(cdc_ncm_bind_common);
void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
struct usb_driver *driver = driver_of(intf);
if (ctx == NULL)
@@ -1203,7 +1203,7 @@ static struct usb_cdc_ncm_ndp32 *cdc_ncm_ndp32(struct cdc_ncm_ctx *ctx, struct s
struct sk_buff *
cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
union {
struct usb_cdc_ncm_nth16 *nth16;
struct usb_cdc_ncm_nth32 *nth32;
@@ -1523,7 +1523,7 @@ struct sk_buff *
cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
struct sk_buff *skb_out;
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
/*
* The Ethernet API we are using does not support transmitting
@@ -1725,7 +1725,7 @@ EXPORT_SYMBOL_GPL(cdc_ncm_rx_verify_ndp32);
int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
{
struct sk_buff *skb;
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
unsigned int len;
int nframes;
int x;
@@ -1904,7 +1904,7 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
static void cdc_ncm_update_filter(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
if (ctx->filtering_supported)
usbnet_cdc_update_filter(dev);
diff --git a/drivers/net/usb/cx82310_eth.c b/drivers/net/usb/cx82310_eth.c
index 79a47e2fd437..ebbaee0575a8 100644
--- a/drivers/net/usb/cx82310_eth.c
+++ b/drivers/net/usb/cx82310_eth.c
@@ -134,9 +134,9 @@ static void cx82310_reenable_work(struct work_struct *work)
cx82310_enable_ethernet(priv->dev);
}
-#define partial_len data[0] /* length of partial packet data */
-#define partial_rem data[1] /* remaining (missing) data length */
-#define partial_data data[2] /* partial packet data */
+#define partial_len private[0] /* length of partial packet data */
+#define partial_rem private[1] /* remaining (missing) data length */
+#define partial_data private[2] /* partial packet data */
static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf)
{
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index c8e0f8868210..ad2b21ac2326 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -276,7 +276,7 @@ static void dm9601_set_multicast(struct net_device *net)
struct usbnet *dev = netdev_priv(net);
/* We use the 20 byte dev->data for our 8 byte filter buffer
* to avoid allocating memory that is tricky to free later */
- u8 *hashes = (u8 *) & dev->data;
+ u8 *hashes = (u8 *) & dev->private;
u8 rx_ctl = 0x31;
memset(hashes, 0x00, DM_MCAST_SIZE);
diff --git a/drivers/net/usb/huawei_cdc_ncm.c b/drivers/net/usb/huawei_cdc_ncm.c
index 849b77330bf2..a10066ab13ad 100644
--- a/drivers/net/usb/huawei_cdc_ncm.c
+++ b/drivers/net/usb/huawei_cdc_ncm.c
@@ -36,7 +36,7 @@ struct huawei_cdc_ncm_state {
static int huawei_cdc_ncm_manage_power(struct usbnet *usbnet_dev, int on)
{
- struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->data;
+ struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->private;
int rv;
if ((on && atomic_add_return(1, &drvstate->pmcount) == 1) ||
@@ -68,7 +68,7 @@ static int huawei_cdc_ncm_bind(struct usbnet *usbnet_dev,
struct cdc_ncm_ctx *ctx;
struct usb_driver *subdriver = ERR_PTR(-ENODEV);
int ret;
- struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->data;
+ struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->private;
int drvflags = 0;
/* altsetting should always be 1 for NCM devices - so we hard-coded
@@ -116,7 +116,7 @@ static int huawei_cdc_ncm_bind(struct usbnet *usbnet_dev,
static void huawei_cdc_ncm_unbind(struct usbnet *usbnet_dev,
struct usb_interface *intf)
{
- struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->data;
+ struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->private;
struct cdc_ncm_ctx *ctx = drvstate->ctx;
if (drvstate->subdriver && drvstate->subdriver->disconnect)
@@ -131,7 +131,7 @@ static int huawei_cdc_ncm_suspend(struct usb_interface *intf,
{
int ret = 0;
struct usbnet *usbnet_dev = usb_get_intfdata(intf);
- struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->data;
+ struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->private;
struct cdc_ncm_ctx *ctx = drvstate->ctx;
if (ctx == NULL) {
@@ -158,7 +158,7 @@ static int huawei_cdc_ncm_resume(struct usb_interface *intf)
{
int ret = 0;
struct usbnet *usbnet_dev = usb_get_intfdata(intf);
- struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->data;
+ struct huawei_cdc_ncm_state *drvstate = (void *)&usbnet_dev->private;
bool callsub;
struct cdc_ncm_ctx *ctx = drvstate->ctx;
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c
index d6698f30218d..b30fa2856f9e 100644
--- a/drivers/net/usb/mcs7830.c
+++ b/drivers/net/usb/mcs7830.c
@@ -327,7 +327,7 @@ static void mcs7830_mdio_write(struct net_device *netdev, int phy_id,
static inline struct mcs7830_data *mcs7830_get_data(struct usbnet *dev)
{
- return (struct mcs7830_data *)&dev->data;
+ return (struct mcs7830_data *)&dev->private;
}
static void mcs7830_hif_update_multicast_hash(struct usbnet *dev)
diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c
index 5d4a1fd2b524..344dc770620f 100644
--- a/drivers/net/usb/net1080.c
+++ b/drivers/net/usb/net1080.c
@@ -26,7 +26,7 @@
* Used in (some) LapLink cables
*/
-#define frame_errors data[1]
+#define frame_errors private[1]
/*
* NetChip framing of ethernet packets, supporting additional error
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index 3a4985b582cb..19a62622aa79 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -306,7 +306,7 @@ static void qmimux_unregister_device(struct net_device *dev,
static void qmi_wwan_netdev_setup(struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
- struct qmi_wwan_state *info = (void *)&dev->data;
+ struct qmi_wwan_state *info = (void *)&dev->private;
if (info->flags & QMI_WWAN_FLAG_RAWIP) {
net->header_ops = NULL; /* No header */
@@ -332,7 +332,7 @@ static void qmi_wwan_netdev_setup(struct net_device *net)
static ssize_t raw_ip_show(struct device *d, struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct qmi_wwan_state *info = (void *)&dev->data;
+ struct qmi_wwan_state *info = (void *)&dev->private;
return sprintf(buf, "%c\n", info->flags & QMI_WWAN_FLAG_RAWIP ? 'Y' : 'N');
}
@@ -340,7 +340,7 @@ static ssize_t raw_ip_show(struct device *d, struct device_attribute *attr, char
static ssize_t raw_ip_store(struct device *d, struct device_attribute *attr, const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct qmi_wwan_state *info = (void *)&dev->data;
+ struct qmi_wwan_state *info = (void *)&dev->private;
bool enable;
int ret;
@@ -409,7 +409,7 @@ static ssize_t add_mux_show(struct device *d, struct device_attribute *attr, cha
static ssize_t add_mux_store(struct device *d, struct device_attribute *attr, const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct qmi_wwan_state *info = (void *)&dev->data;
+ struct qmi_wwan_state *info = (void *)&dev->private;
u8 mux_id;
int ret;
@@ -447,7 +447,7 @@ static ssize_t del_mux_show(struct device *d, struct device_attribute *attr, cha
static ssize_t del_mux_store(struct device *d, struct device_attribute *attr, const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct qmi_wwan_state *info = (void *)&dev->data;
+ struct qmi_wwan_state *info = (void *)&dev->private;
struct net_device *del_dev;
u8 mux_id;
int ret = 0;
@@ -480,7 +480,7 @@ static ssize_t pass_through_show(struct device *d,
struct usbnet *dev = netdev_priv(to_net_dev(d));
struct qmi_wwan_state *info;
- info = (void *)&dev->data;
+ info = (void *)&dev->private;
return sprintf(buf, "%c\n",
info->flags & QMI_WWAN_FLAG_PASS_THROUGH ? 'Y' : 'N');
}
@@ -496,7 +496,7 @@ static ssize_t pass_through_store(struct device *d,
if (kstrtobool(buf, &enable))
return -EINVAL;
- info = (void *)&dev->data;
+ info = (void *)&dev->private;
/* no change? */
if (enable == (info->flags & QMI_WWAN_FLAG_PASS_THROUGH))
@@ -562,7 +562,7 @@ static const u8 buggy_fw_addr[ETH_ALEN] = {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00};
*/
static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
- struct qmi_wwan_state *info = (void *)&dev->data;
+ struct qmi_wwan_state *info = (void *)&dev->private;
bool rawip = info->flags & QMI_WWAN_FLAG_RAWIP;
__be16 proto;
@@ -653,7 +653,7 @@ static const struct net_device_ops qmi_wwan_netdev_ops = {
*/
static int qmi_wwan_manage_power(struct usbnet *dev, int on)
{
- struct qmi_wwan_state *info = (void *)&dev->data;
+ struct qmi_wwan_state *info = (void *)&dev->private;
int rv;
dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__,
@@ -687,7 +687,7 @@ static int qmi_wwan_register_subdriver(struct usbnet *dev)
{
int rv;
struct usb_driver *subdriver = NULL;
- struct qmi_wwan_state *info = (void *)&dev->data;
+ struct qmi_wwan_state *info = (void *)&dev->private;
/* collect bulk endpoints */
rv = usbnet_get_endpoints(dev, info->data);
@@ -750,12 +750,9 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
struct usb_cdc_union_desc *cdc_union;
struct usb_cdc_ether_desc *cdc_ether;
struct usb_driver *driver = driver_of(intf);
- struct qmi_wwan_state *info = (void *)&dev->data;
+ struct qmi_wwan_state *info = (void *)&dev->private;
struct usb_cdc_parsed_header hdr;
- BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) <
- sizeof(struct qmi_wwan_state)));
-
/* set up initial state */
info->control = intf;
info->data = intf;
@@ -848,7 +845,7 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
static void qmi_wwan_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct qmi_wwan_state *info = (void *)&dev->data;
+ struct qmi_wwan_state *info = (void *)&dev->private;
struct usb_driver *driver = driver_of(intf);
struct usb_interface *other;
@@ -887,7 +884,7 @@ static void qmi_wwan_unbind(struct usbnet *dev, struct usb_interface *intf)
static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct qmi_wwan_state *info = (void *)&dev->data;
+ struct qmi_wwan_state *info = (void *)&dev->private;
int ret;
/* Both usbnet_suspend() and subdriver->suspend() MUST return 0
@@ -910,7 +907,7 @@ static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message)
static int qmi_wwan_resume(struct usb_interface *intf)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct qmi_wwan_state *info = (void *)&dev->data;
+ struct qmi_wwan_state *info = (void *)&dev->private;
int ret = 0;
bool callsub = (intf == info->control && info->subdriver &&
info->subdriver->resume);
@@ -1584,7 +1581,7 @@ static void qmi_wwan_disconnect(struct usb_interface *intf)
/* called twice if separate control and data intf */
if (!dev)
return;
- info = (void *)&dev->data;
+ info = (void *)&dev->private;
if (info->flags & QMI_WWAN_FLAG_MUX) {
if (!rtnl_trylock()) {
restart_syscall();
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index 7b3739b29c8f..6aed29dfa021 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -57,7 +57,7 @@ EXPORT_SYMBOL_GPL(rndis_status);
static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
int buflen)
{
- struct cdc_state *info = (void *)&dev->data;
+ struct cdc_state *info = &dev->cdc;
struct device *udev = &info->control->dev;
if (dev->driver_info->indication) {
@@ -90,7 +90,7 @@ static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
*/
int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
{
- struct cdc_state *info = (void *) &dev->data;
+ struct cdc_state *info = &dev->cdc;
struct usb_cdc_notification notification;
int master_ifnum;
int retval;
@@ -290,7 +290,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
{
int retval;
struct net_device *net = dev->net;
- struct cdc_state *info = (void *) &dev->data;
+ struct cdc_state *info = &dev->cdc;
union {
void *buf;
struct rndis_msg_hdr *header;
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
index 3ca60ebdd468..beb56bf6b96b 100644
--- a/drivers/net/usb/sierra_net.c
+++ b/drivers/net/usb/sierra_net.c
@@ -190,14 +190,14 @@ static const struct net_device_ops sierra_net_device_ops = {
/* get private data associated with passed in usbnet device */
static inline struct sierra_net_data *sierra_net_get_private(struct usbnet *dev)
{
- return (struct sierra_net_data *)dev->data[0];
+ return (struct sierra_net_data *)dev->private[0];
}
/* set private data associated with passed in usbnet device */
static inline void sierra_net_set_private(struct usbnet *dev,
struct sierra_net_data *priv)
{
- dev->data[0] = (unsigned long)priv;
+ dev->private[0] = (unsigned long)priv;
}
/* is packet IPv4/IPv6 */
@@ -855,9 +855,6 @@ static struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev,
u16 len;
bool need_tail;
- BUILD_BUG_ON(sizeof_field(struct usbnet, data)
- < sizeof(struct cdc_state));
-
dev_dbg(&dev->udev->dev, "%s", __func__);
if (priv->link_up && check_ethip_packet(skb, dev) && is_ip(skb)) {
/* enough head room as is? */
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index 1a61a8bcf5d3..a28d30a1da4a 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -453,7 +453,7 @@ static int smsc75xx_dataport_wait_not_busy(struct usbnet *dev)
static int smsc75xx_dataport_write(struct usbnet *dev, u32 ram_select, u32 addr,
u32 length, u32 *buf)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->private);
u32 dp_sel;
int i, ret;
@@ -537,7 +537,7 @@ static void smsc75xx_deferred_multicast_write(struct work_struct *param)
static void smsc75xx_set_multicast(struct net_device *netdev)
{
struct usbnet *dev = netdev_priv(netdev);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->private);
unsigned long flags;
int i;
@@ -701,7 +701,7 @@ static void smsc75xx_ethtool_get_wol(struct net_device *net,
struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = netdev_priv(net);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->private);
wolinfo->supported = SUPPORTED_WAKE;
wolinfo->wolopts = pdata->wolopts;
@@ -711,7 +711,7 @@ static int smsc75xx_ethtool_set_wol(struct net_device *net,
struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = netdev_priv(net);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->private);
int ret;
if (wolinfo->wolopts & ~SUPPORTED_WAKE)
@@ -931,7 +931,7 @@ static int smsc75xx_set_features(struct net_device *netdev,
netdev_features_t features)
{
struct usbnet *dev = netdev_priv(netdev);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->private);
unsigned long flags;
int ret;
@@ -1037,7 +1037,7 @@ static int smsc75xx_phy_gig_workaround(struct usbnet *dev)
static int smsc75xx_reset(struct usbnet *dev)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->private);
u32 buf;
int ret = 0, timeout;
@@ -1449,13 +1449,13 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
netdev_warn(dev->net, "usbnet_get_endpoints failed: %d\n", ret);
return ret;
}
-
- dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc75xx_priv),
- GFP_KERNEL);
-
- pdata = (struct smsc75xx_priv *)(dev->data[0]);
+//FIXME
+ pdata = (struct smsc75xx_priv *)kzalloc(sizeof(struct smsc75xx_priv),
+ GFP_KERNEL);
if (!pdata)
return -ENOMEM;
+ dev->private[0] = (unsigned long)pdata;
+
pdata->dev = dev;
@@ -1500,18 +1500,18 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
cancel_work_sync(&pdata->set_multicast);
free_pdata:
kfree(pdata);
- dev->data[0] = 0;
+ memset(dev->private, 0, sizeof(dev->private));
return ret;
}
static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->private);
if (pdata) {
cancel_work_sync(&pdata->set_multicast);
netif_dbg(dev, ifdown, dev->net, "free pdata\n");
kfree(pdata);
- dev->data[0] = 0;
+ memset(dev->private, 0, sizeof(dev->private));
}
}
@@ -1562,7 +1562,7 @@ static int smsc75xx_write_wuff(struct usbnet *dev, int filter, u32 wuf_cfg,
static int smsc75xx_enter_suspend0(struct usbnet *dev)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->private);
u32 val;
int ret;
@@ -1588,7 +1588,7 @@ static int smsc75xx_enter_suspend0(struct usbnet *dev)
static int smsc75xx_enter_suspend1(struct usbnet *dev)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->private);
u32 val;
int ret;
@@ -1624,7 +1624,7 @@ static int smsc75xx_enter_suspend1(struct usbnet *dev)
static int smsc75xx_enter_suspend2(struct usbnet *dev)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->private);
u32 val;
int ret;
@@ -1650,7 +1650,7 @@ static int smsc75xx_enter_suspend2(struct usbnet *dev)
static int smsc75xx_enter_suspend3(struct usbnet *dev)
{
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->private);
u32 val;
int ret;
@@ -1785,7 +1785,7 @@ static int smsc75xx_autosuspend(struct usbnet *dev, u32 link_up)
static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->private);
u32 val, link_up;
int ret;
@@ -2086,7 +2086,7 @@ static int smsc75xx_suspend(struct usb_interface *intf, pm_message_t message)
static int smsc75xx_resume(struct usb_interface *intf)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+ struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->private);
u8 suspend_flags = pdata->suspend_flags;
int ret;
u32 val;
diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c
index 937e6fef3ac6..cf68064bf7cc 100644
--- a/drivers/net/usb/sr9700.c
+++ b/drivers/net/usb/sr9700.c
@@ -230,6 +230,7 @@ static const struct ethtool_ops sr9700_ethtool_ops = {
static void sr9700_set_multicast(struct net_device *netdev)
{
struct usbnet *dev = netdev_priv(netdev);
+
/* rx_ctl setting : enable, disable_long, disable_crc */
u8 rx_ctl = RCR_RXEN | RCR_DIS_CRC | RCR_DIS_LONG;
diff --git a/drivers/net/usb/sr9800.c b/drivers/net/usb/sr9800.c
index 6fd33a5b2279..4dad51e2bf53 100644
--- a/drivers/net/usb/sr9800.c
+++ b/drivers/net/usb/sr9800.c
@@ -295,7 +295,7 @@ static int sr_write_gpio(struct usbnet *dev, u16 value, int sleep)
static void sr_set_multicast(struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
- struct sr_data *data = (struct sr_data *)&dev->data;
+ struct sr_data *data = (struct sr_data *)&dev->private;
u16 rx_ctl = SR_DEFAULT_RX_CTL;
if (net->flags & IFF_PROMISC) {
@@ -438,7 +438,7 @@ sr_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
static int sr_get_eeprom_len(struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
- struct sr_data *data = (struct sr_data *)&dev->data;
+ struct sr_data *data = (struct sr_data *)&dev->private;
return data->eeprom_len;
}
@@ -472,7 +472,7 @@ static int sr_get_eeprom(struct net_device *net,
static int sr_set_mac_address(struct net_device *net, void *p)
{
struct usbnet *dev = netdev_priv(net);
- struct sr_data *data = (struct sr_data *)&dev->data;
+ struct sr_data *data = (struct sr_data *)&dev->private;
struct sockaddr *addr = p;
if (netif_running(net))
@@ -574,7 +574,7 @@ static int sr9800_set_default_mode(struct usbnet *dev)
static int sr9800_reset(struct usbnet *dev)
{
- struct sr_data *data = (struct sr_data *)&dev->data;
+ struct sr_data *data = (struct sr_data *)&dev->private;
int ret, embd_phy;
u16 rx_ctl;
@@ -705,7 +705,7 @@ static int sr9800_phy_powerup(struct usbnet *dev)
static int sr9800_bind(struct usbnet *dev, struct usb_interface *intf)
{
- struct sr_data *data = (struct sr_data *)&dev->data;
+ struct sr_data *data = (struct sr_data *)&dev->private;
u16 led01_mux, led23_mux;
int ret, embd_phy;
u8 addr[ETH_ALEN];
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 602de719454a..94be042b7a35 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -16,6 +16,18 @@
#include <linux/usb.h>
#include <linux/spinlock.h>
+/* Drivers that reuse some of the standard USB CDC infrastructure
+ * (notably, using multiple interfaces according to the CDC
+ * union descriptor) get some helper code.
+ */
+struct cdc_state {
+ struct usb_cdc_header_desc *header;
+ struct usb_cdc_union_desc *u;
+ struct usb_cdc_ether_desc *ether;
+ struct usb_interface *control;
+ struct usb_interface *data;
+};
+
/* interface from usbnet core to each USB networking link we handle */
struct usbnet {
/* housekeeping */
@@ -41,7 +53,7 @@ struct usbnet {
/* protocol/interface state */
struct net_device *net;
int msg_enable;
- unsigned long data[5];
+ struct cdc_state cdc; /* too common to leave out*/
u32 xid;
u32 hard_mtu; /* count any extra framing */
size_t rx_urb_size; /* size for rx urbs */
@@ -84,6 +96,7 @@ struct usbnet {
* that must be broken
*/
# define EVENT_UNPLUG 31
+ unsigned long private[5];
};
static inline bool usbnet_going_away(struct usbnet *ubn)
@@ -206,18 +219,6 @@ extern int usbnet_write_cmd_nopm(struct usbnet *dev, u8 cmd, u8 reqtype,
extern int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype,
u16 value, u16 index, const void *data, u16 size);
-/* Drivers that reuse some of the standard USB CDC infrastructure
- * (notably, using multiple interfaces according to the CDC
- * union descriptor) get some helper code.
- */
-struct cdc_state {
- struct usb_cdc_header_desc *header;
- struct usb_cdc_union_desc *u;
- struct usb_cdc_ether_desc *ether;
- struct usb_interface *control;
- struct usb_interface *data;
-};
-
extern void usbnet_cdc_update_filter(struct usbnet *dev);
extern int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *);
extern int usbnet_ether_cdc_bind(struct usbnet *dev, struct usb_interface *intf);
--
2.53.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [RFC net-next 2/3] net: usb: usbnet: switch to dynamic allocation of private data
2026-02-10 15:11 [RFC net-next 0/3] cleanup of usbnet descriptor allocation Oliver Neukum
2026-02-10 15:11 ` [RFC net-next 1/3] net: usb: divorce private data and cdc state in usbnet Oliver Neukum
@ 2026-02-10 15:11 ` Oliver Neukum
2026-02-17 18:47 ` Andrew Lunn
2026-02-10 15:11 ` [RFC net-next 3/3] net: usb: usbnet: remove driver_priv Oliver Neukum
2 siblings, 1 reply; 13+ messages in thread
From: Oliver Neukum @ 2026-02-10 15:11 UTC (permalink / raw)
To: netdev, hayeswang, bjorn, o.rempel; +Cc: Oliver Neukum, Oliver Neukum
usbnet used an unsigned long[5] scratchpad space for private
use of subdrivers. That is inelegant and not enough space
for some drivers. Switch to letting drivers specify how much
room they need in their driver_info.
Signed-off-by: Oliver Neukum <oneukum@suse.de>
---
drivers/net/usb/ax88172a.c | 1 +
drivers/net/usb/cdc_mbim.c | 4 ++
drivers/net/usb/cdc_ncm.c | 82 +++++++++++++++++-------------------
drivers/net/usb/sierra_net.c | 21 +++------
drivers/net/usb/smsc75xx.c | 4 +-
drivers/net/usb/usbnet.c | 2 +-
include/linux/usb/usbnet.h | 5 ++-
7 files changed, 56 insertions(+), 63 deletions(-)
diff --git a/drivers/net/usb/ax88172a.c b/drivers/net/usb/ax88172a.c
index 1694d6ca2b7b..34884805730d 100644
--- a/drivers/net/usb/ax88172a.c
+++ b/drivers/net/usb/ax88172a.c
@@ -355,4 +355,5 @@ const struct driver_info ax88172a_info = {
FLAG_MULTI_PACKET,
.rx_fixup = ax88172a_rx_fixup,
.tx_fixup = asix_tx_fixup,
+ .required_room = sizeof(struct ax88172a_private),
};
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index f08f0fc3a8c1..08ea101feb6a 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -557,6 +557,7 @@ static const struct driver_info cdc_mbim_info = {
.manage_power = cdc_mbim_manage_power,
.rx_fixup = cdc_mbim_rx_fixup,
.tx_fixup = cdc_mbim_tx_fixup,
+ .required_room = sizeof(struct cdc_mbim_state),
};
/* MBIM and NCM devices should not need a ZLP after NTBs with
@@ -581,6 +582,7 @@ static const struct driver_info cdc_mbim_info_zlp = {
.manage_power = cdc_mbim_manage_power,
.rx_fixup = cdc_mbim_rx_fixup,
.tx_fixup = cdc_mbim_tx_fixup,
+ .required_room = sizeof(struct cdc_mbim_state),
};
/* The spefication explicitly allows NDPs to be placed anywhere in the
@@ -601,6 +603,7 @@ static const struct driver_info cdc_mbim_info_ndp_to_end = {
.rx_fixup = cdc_mbim_rx_fixup,
.tx_fixup = cdc_mbim_tx_fixup,
.data = CDC_NCM_FLAG_NDP_TO_END,
+ .required_room = sizeof(struct cdc_mbim_state),
};
/* Some modems (e.g. Telit LE922A6) do not work properly with altsetting
@@ -616,6 +619,7 @@ static const struct driver_info cdc_mbim_info_avoid_altsetting_toggle = {
.rx_fixup = cdc_mbim_rx_fixup,
.tx_fixup = cdc_mbim_tx_fixup,
.data = CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE,
+ .required_room = sizeof(struct cdc_mbim_state),
};
static const struct usb_device_id mbim_devs[] = {
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index d0d13b2d52e6..7a14900b64c4 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -107,7 +107,7 @@ static void cdc_ncm_get_ethtool_stats(struct net_device *netdev,
u64 *data)
{
struct usbnet *dev = netdev_priv(netdev);
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
int i;
char *p = NULL;
@@ -149,7 +149,7 @@ static const struct ethtool_ops cdc_ncm_ethtool_ops = {
static u32 cdc_ncm_check_rx_max(struct usbnet *dev, u32 new_rx)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
u32 val, max, min;
/* clamp new_rx to sane values */
@@ -172,7 +172,7 @@ static u32 cdc_ncm_check_rx_max(struct usbnet *dev, u32 new_rx)
static u32 cdc_ncm_check_tx_max(struct usbnet *dev, u32 new_tx)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
u32 val, max, min;
/* clamp new_tx to sane values */
@@ -202,7 +202,7 @@ static ssize_t min_tx_pkt_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
return sprintf(buf, "%u\n", ctx->min_tx_pkt);
}
@@ -211,7 +211,7 @@ static ssize_t rx_max_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
return sprintf(buf, "%u\n", ctx->rx_max);
}
@@ -220,7 +220,7 @@ static ssize_t tx_max_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
return sprintf(buf, "%u\n", ctx->tx_max);
}
@@ -229,7 +229,7 @@ static ssize_t tx_timer_usecs_show(struct device *d,
struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
return sprintf(buf, "%u\n", ctx->timer_interval / (u32)NSEC_PER_USEC);
}
@@ -239,7 +239,7 @@ static ssize_t min_tx_pkt_store(struct device *d,
const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
unsigned long val;
/* no need to restrict values - anything from 0 to infinity is OK */
@@ -255,7 +255,7 @@ static ssize_t rx_max_store(struct device *d,
const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
unsigned long val;
if (kstrtoul(buf, 0, &val) || cdc_ncm_check_rx_max(dev, val) != val)
@@ -270,7 +270,7 @@ static ssize_t tx_max_store(struct device *d,
const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
unsigned long val;
if (kstrtoul(buf, 0, &val) || cdc_ncm_check_tx_max(dev, val) != val)
@@ -285,7 +285,7 @@ static ssize_t tx_timer_usecs_store(struct device *d,
const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
ssize_t ret;
unsigned long val;
@@ -311,7 +311,7 @@ static DEVICE_ATTR_RW(tx_timer_usecs);
static ssize_t ndp_to_end_show(struct device *d, struct device_attribute *attr, char *buf)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
return sprintf(buf, "%c\n", ctx->drvflags & CDC_NCM_FLAG_NDP_TO_END ? 'Y' : 'N');
}
@@ -319,7 +319,7 @@ static ssize_t ndp_to_end_show(struct device *d, struct device_attribute *attr,
static ssize_t ndp_to_end_store(struct device *d, struct device_attribute *attr, const char *buf, size_t len)
{
struct usbnet *dev = netdev_priv(to_net_dev(d));
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
bool enable;
if (kstrtobool(buf, &enable))
@@ -361,7 +361,7 @@ static DEVICE_ATTR_RW(ndp_to_end);
static ssize_t cdc_ncm_show_##name(struct device *d, struct device_attribute *attr, char *buf) \
{ \
struct usbnet *dev = netdev_priv(to_net_dev(d)); \
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0]; \
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private; \
return sprintf(buf, format "\n", tocpu(ctx->ncm_parm.name)); \
} \
static DEVICE_ATTR(name, 0444, cdc_ncm_show_##name, NULL)
@@ -404,7 +404,7 @@ static const struct attribute_group cdc_ncm_sysfs_attr_group = {
/* handle rx_max and tx_max changes */
static void cdc_ncm_update_rxtx_max(struct usbnet *dev, u32 new_rx, u32 new_tx)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
u32 val;
@@ -476,7 +476,7 @@ static void cdc_ncm_update_rxtx_max(struct usbnet *dev, u32 new_rx, u32 new_tx)
/* helpers for NCM and MBIM differences */
static u8 cdc_ncm_flags(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
if (cdc_ncm_comm_intf_is_mbim(dev->intf->cur_altsetting) && ctx->mbim_desc)
return ctx->mbim_desc->bmNetworkCapabilities;
@@ -501,7 +501,7 @@ static u32 cdc_ncm_min_dgram_size(struct usbnet *dev)
static u32 cdc_ncm_max_dgram_size(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
if (cdc_ncm_comm_intf_is_mbim(dev->intf->cur_altsetting) && ctx->mbim_desc)
return le16_to_cpu(ctx->mbim_desc->wMaxSegmentSize);
@@ -515,7 +515,7 @@ static u32 cdc_ncm_max_dgram_size(struct usbnet *dev)
*/
static int cdc_ncm_init(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
int err;
@@ -608,7 +608,7 @@ static int cdc_ncm_init(struct usbnet *dev)
/* set a new max datagram size */
static void cdc_ncm_set_dgram_size(struct usbnet *dev, int new_size)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
u8 iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber;
__le16 max_datagram_size;
u16 mbim_mtu;
@@ -656,7 +656,7 @@ static void cdc_ncm_set_dgram_size(struct usbnet *dev, int new_size)
static void cdc_ncm_fix_modulus(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
u32 val;
/*
@@ -700,7 +700,7 @@ static void cdc_ncm_fix_modulus(struct usbnet *dev)
static int cdc_ncm_setup(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
u32 def_rx, def_tx;
/* be conservative when selecting initial buffer size to
@@ -769,9 +769,6 @@ cdc_ncm_find_endpoints(struct usbnet *dev, struct usb_interface *intf)
static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
{
- if (ctx == NULL)
- return;
-
if (ctx->tx_rem_skb != NULL) {
dev_kfree_skb_any(ctx->tx_rem_skb);
ctx->tx_rem_skb = NULL;
@@ -782,12 +779,13 @@ static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
ctx->tx_curr_skb = NULL;
}
- if (ctx->is_ndp16)
+ if (ctx->is_ndp16) {
kfree(ctx->delayed_ndp16);
- else
+ ctx->delayed_ndp16 = NULL;
+ } else {
kfree(ctx->delayed_ndp32);
-
- kfree(ctx);
+ ctx->delayed_ndp32 = NULL;
+ }
}
/* we need to override the usbnet change_mtu ndo for two reasons:
@@ -819,7 +817,7 @@ static const struct net_device_ops cdc_ncm_netdev_ops = {
int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting, int drvflags)
{
- struct cdc_ncm_ctx *ctx;
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
struct usb_driver *driver;
u8 *buf;
int len;
@@ -827,10 +825,6 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
u8 iface_no;
struct usb_cdc_parsed_header hdr;
- ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return -ENOMEM;
-
ctx->dev = dev;
hrtimer_setup(&ctx->tx_timer, &cdc_ncm_tx_timer_cb, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
@@ -838,9 +832,6 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
atomic_set(&ctx->stop, 0);
spin_lock_init(&ctx->mtx);
- /* store ctx pointer in device data field */
- dev->private[0] = (unsigned long)ctx;
-
/* only the control interface can be successfully probed */
ctx->control = intf;
@@ -988,8 +979,7 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
if (ctx->data != ctx->control)
usb_driver_release_interface(driver, ctx->data);
error:
- cdc_ncm_free((struct cdc_ncm_ctx *)dev->private[0]);
- dev->private[0] = 0;
+ cdc_ncm_free((struct cdc_ncm_ctx *)dev->private);
dev_info(&intf->dev, "bind() failure\n");
return -ENODEV;
}
@@ -997,7 +987,7 @@ EXPORT_SYMBOL_GPL(cdc_ncm_bind_common);
void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
struct usb_driver *driver = driver_of(intf);
if (ctx == NULL)
@@ -1203,7 +1193,7 @@ static struct usb_cdc_ncm_ndp32 *cdc_ncm_ndp32(struct cdc_ncm_ctx *ctx, struct s
struct sk_buff *
cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
union {
struct usb_cdc_ncm_nth16 *nth16;
struct usb_cdc_ncm_nth32 *nth32;
@@ -1523,7 +1513,7 @@ struct sk_buff *
cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
{
struct sk_buff *skb_out;
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
/*
* The Ethernet API we are using does not support transmitting
@@ -1725,7 +1715,7 @@ EXPORT_SYMBOL_GPL(cdc_ncm_rx_verify_ndp32);
int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
{
struct sk_buff *skb;
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
unsigned int len;
int nframes;
int x;
@@ -1904,7 +1894,7 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
static void cdc_ncm_update_filter(struct usbnet *dev)
{
- struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
+ struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
if (ctx->filtering_supported)
usbnet_cdc_update_filter(dev);
@@ -1921,6 +1911,7 @@ static const struct driver_info cdc_ncm_info = {
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
.set_rx_mode = cdc_ncm_update_filter,
+ .required_room = sizeof(struct cdc_ncm_ctx),
};
/* Same as cdc_ncm_info, but with FLAG_SEND_ZLP */
@@ -1935,6 +1926,7 @@ static const struct driver_info cdc_ncm_zlp_info = {
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
.set_rx_mode = cdc_ncm_update_filter,
+ .required_room = sizeof(struct cdc_ncm_ctx),
};
/* Same as cdc_ncm_info, but with FLAG_SEND_ZLP */
@@ -1949,6 +1941,7 @@ static const struct driver_info apple_tethering_interface_info = {
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
.set_rx_mode = usbnet_cdc_update_filter,
+ .required_room = sizeof(struct cdc_ncm_ctx),
};
/* Same as apple_tethering_interface_info, but without FLAG_LINK_INTR */
@@ -1963,6 +1956,7 @@ static const struct driver_info apple_private_interface_info = {
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
.set_rx_mode = usbnet_cdc_update_filter,
+ .required_room = sizeof(struct cdc_ncm_ctx),
};
/* Same as cdc_ncm_info, but with FLAG_WWAN */
@@ -1977,6 +1971,7 @@ static const struct driver_info wwan_info = {
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
.set_rx_mode = cdc_ncm_update_filter,
+ .required_room = sizeof(struct cdc_ncm_ctx),
};
/* Same as wwan_info, but with FLAG_NOARP */
@@ -1991,6 +1986,7 @@ static const struct driver_info wwan_noarp_info = {
.rx_fixup = cdc_ncm_rx_fixup,
.tx_fixup = cdc_ncm_tx_fixup,
.set_rx_mode = cdc_ncm_update_filter,
+ .required_room = sizeof(struct cdc_ncm_ctx),
};
static const struct usb_device_id cdc_devs[] = {
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c
index beb56bf6b96b..7b15b89aa62b 100644
--- a/drivers/net/usb/sierra_net.c
+++ b/drivers/net/usb/sierra_net.c
@@ -190,14 +190,7 @@ static const struct net_device_ops sierra_net_device_ops = {
/* get private data associated with passed in usbnet device */
static inline struct sierra_net_data *sierra_net_get_private(struct usbnet *dev)
{
- return (struct sierra_net_data *)dev->private[0];
-}
-
-/* set private data associated with passed in usbnet device */
-static inline void sierra_net_set_private(struct usbnet *dev,
- struct sierra_net_data *priv)
-{
- dev->private[0] = (unsigned long)priv;
+ return (struct sierra_net_data *)dev->private;
}
/* is packet IPv4/IPv6 */
@@ -653,7 +646,7 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
u8 numendpoints;
u16 fwattr = 0;
int status;
- struct sierra_net_data *priv;
+ struct sierra_net_data *priv = (struct sierra_net_data *)dev->private;
static const u8 sync_tmplate[sizeof(priv->sync_msg)] = {
0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00};
static const u8 shdwn_tmplate[sizeof(priv->shdwn_msg)] = {
@@ -682,11 +675,8 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
dev_err(&dev->udev->dev, "No status endpoint found");
return -ENODEV;
}
- /* Initialize sierra private data */
- priv = kzalloc(sizeof *priv, GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
+ /* Initialize sierra private data */
priv->usbnet = dev;
priv->ifnum = ifacenum;
dev->net->netdev_ops = &sierra_net_device_ops;
@@ -718,8 +708,6 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
dev->net->ethtool_ops = &sierra_net_ethtool_ops;
netif_carrier_off(dev->net);
- sierra_net_set_private(dev, priv);
-
priv->kevent_flags = 0;
/* Use the shared workqueue */
@@ -764,7 +752,7 @@ static void sierra_net_unbind(struct usbnet *dev, struct usb_interface *intf)
usbnet_status_stop(dev);
- sierra_net_set_private(dev, NULL);
+ memset(dev->private, 0, sizeof(struct sierra_net_data));
kfree(priv);
}
@@ -905,6 +893,7 @@ static const struct driver_info sierra_net_info_direct_ip = {
.status = sierra_net_status,
.rx_fixup = sierra_net_rx_fixup,
.tx_fixup = sierra_net_tx_fixup,
+ .required_room = sizeof(struct sierra_net_data),
};
static int
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index a28d30a1da4a..46cd806954de 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -1500,7 +1500,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
cancel_work_sync(&pdata->set_multicast);
free_pdata:
kfree(pdata);
- memset(dev->private, 0, sizeof(dev->private));
+ memset(dev->private, 0, sizeof(struct smsc75xx_priv *));
return ret;
}
@@ -1511,7 +1511,7 @@ static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)
cancel_work_sync(&pdata->set_multicast);
netif_dbg(dev, ifdown, dev->net, "free pdata\n");
kfree(pdata);
- memset(dev->private, 0, sizeof(dev->private));
+ memset(dev->private, 0, sizeof(struct smsc75xx_priv *));
}
}
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 974c6204cef9..e1733a3612c6 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1756,7 +1756,7 @@ usbnet_probe(struct usb_interface *udev, const struct usb_device_id *prod)
status = -ENOMEM;
// set up our own records
- net = alloc_etherdev(sizeof(*dev));
+ net = alloc_etherdev(sizeof(*dev) + info->required_room);
if (!net)
goto out;
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 94be042b7a35..ba45a3e2be6a 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -96,7 +96,7 @@ struct usbnet {
* that must be broken
*/
# define EVENT_UNPLUG 31
- unsigned long private[5];
+ DECLARE_FLEX_ARRAY(u8, private);
};
static inline bool usbnet_going_away(struct usbnet *ubn)
@@ -146,6 +146,9 @@ struct driver_info {
#define FLAG_RX_ASSEMBLE 0x4000 /* rx packets may span >1 frames */
#define FLAG_NOARP 0x8000 /* device can't do ARP */
+ /* tells us how much private space is need in the descriptor */
+ unsigned int required_room;
+
/* init device ... can sleep, or cause probe() failure */
int (*bind)(struct usbnet *, struct usb_interface *);
--
2.53.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [RFC net-next 3/3] net: usb: usbnet: remove driver_priv
2026-02-10 15:11 [RFC net-next 0/3] cleanup of usbnet descriptor allocation Oliver Neukum
2026-02-10 15:11 ` [RFC net-next 1/3] net: usb: divorce private data and cdc state in usbnet Oliver Neukum
2026-02-10 15:11 ` [RFC net-next 2/3] net: usb: usbnet: switch to dynamic allocation of private data Oliver Neukum
@ 2026-02-10 15:11 ` Oliver Neukum
2 siblings, 0 replies; 13+ messages in thread
From: Oliver Neukum @ 2026-02-10 15:11 UTC (permalink / raw)
To: netdev, hayeswang, bjorn, o.rempel; +Cc: Oliver Neukum
With dynamic private area allocation there is no point in keeping
a second mechanism.
Signed-off-by: Oliver Neukum <oneukum@suse.com>
---
drivers/net/usb/aqc111.c | 45 ++++++++++----------
drivers/net/usb/asix.h | 2 +-
drivers/net/usb/asix_common.c | 2 +-
drivers/net/usb/asix_devices.c | 76 +++++++++++++++-------------------
drivers/net/usb/ax88172a.c | 26 ++++--------
drivers/net/usb/ax88179_178a.c | 54 +++++++++++++-----------
drivers/net/usb/cx82310_eth.c | 56 +++++++++++--------------
drivers/net/usb/lg-vl600.c | 15 ++-----
drivers/net/usb/smsc95xx.c | 60 ++++++++++++---------------
include/linux/usb/usbnet.h | 1 -
10 files changed, 149 insertions(+), 188 deletions(-)
diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index 0722050dbe32..0ff4ca58fbc5 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -201,7 +201,7 @@ static void aqc111_get_drvinfo(struct net_device *net,
struct ethtool_drvinfo *info)
{
struct usbnet *dev = netdev_priv(net);
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
/* Inherit standard device info */
usbnet_get_drvinfo(net, info);
@@ -215,7 +215,7 @@ static void aqc111_get_wol(struct net_device *net,
struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = netdev_priv(net);
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
wolinfo->supported = WAKE_MAGIC;
wolinfo->wolopts = 0;
@@ -228,7 +228,7 @@ static int aqc111_set_wol(struct net_device *net,
struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = netdev_priv(net);
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
if (wolinfo->wolopts & ~WAKE_MAGIC)
return -EINVAL;
@@ -267,7 +267,7 @@ static int aqc111_get_link_ksettings(struct net_device *net,
struct ethtool_link_ksettings *elk)
{
struct usbnet *dev = netdev_priv(net);
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
enum usb_device_speed usb_speed = dev->udev->speed;
u32 speed = SPEED_UNKNOWN;
@@ -320,7 +320,7 @@ static int aqc111_get_link_ksettings(struct net_device *net,
static void aqc111_set_phy_speed(struct usbnet *dev, u8 autoneg, u16 speed)
{
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
aqc111_data->phy_cfg &= ~AQ_ADV_MASK;
aqc111_data->phy_cfg |= AQ_PAUSE;
@@ -369,7 +369,7 @@ static int aqc111_set_link_ksettings(struct net_device *net,
const struct ethtool_link_ksettings *elk)
{
struct usbnet *dev = netdev_priv(net);
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
enum usb_device_speed usb_speed = dev->udev->speed;
u8 autoneg = elk->base.autoneg;
u32 speed = elk->base.speed;
@@ -529,7 +529,7 @@ static int aqc111_vlan_rx_add_vid(struct net_device *net, __be16 proto, u16 vid)
static void aqc111_set_rx_mode(struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
int mc_count = 0;
mc_count = netdev_mc_count(net);
@@ -567,7 +567,7 @@ static int aqc111_set_features(struct net_device *net,
netdev_features_t features)
{
struct usbnet *dev = netdev_priv(net);
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
netdev_features_t changed = net->features ^ features;
u16 reg16 = 0;
u8 reg8 = 0;
@@ -703,13 +703,6 @@ static int aqc111_bind(struct usbnet *dev, struct usb_interface *intf)
return ret;
}
- aqc111_data = kzalloc(sizeof(*aqc111_data), GFP_KERNEL);
- if (!aqc111_data)
- return -ENOMEM;
-
- /* store aqc111_data pointer in device data field */
- dev->driver_priv = aqc111_data;
-
/* Init the MAC address */
ret = aqc111_read_perm_mac(dev);
if (ret)
@@ -746,13 +739,12 @@ static int aqc111_bind(struct usbnet *dev, struct usb_interface *intf)
return 0;
out:
- kfree(aqc111_data);
return ret;
}
static void aqc111_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
u16 reg16;
/* Force bz */
@@ -775,7 +767,7 @@ static void aqc111_unbind(struct usbnet *dev, struct usb_interface *intf)
static void aqc111_status(struct usbnet *dev, struct urb *urb)
{
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
u64 *event_data = NULL;
int link = 0;
@@ -900,7 +892,7 @@ static void aqc111_configure_csum_offload(struct usbnet *dev)
static int aqc111_link_reset(struct usbnet *dev)
{
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
u16 reg16 = 0;
u8 reg8 = 0;
@@ -989,7 +981,7 @@ static int aqc111_link_reset(struct usbnet *dev)
static int aqc111_reset(struct usbnet *dev)
{
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
u8 reg8 = 0;
dev->rx_urb_size = URB_SIZE;
@@ -1033,7 +1025,7 @@ static int aqc111_reset(struct usbnet *dev)
static int aqc111_stop(struct usbnet *dev)
{
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
u16 reg16 = 0;
aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
@@ -1071,7 +1063,7 @@ static void aqc111_rx_checksum(struct sk_buff *skb, u64 pkt_desc)
static int aqc111_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
struct sk_buff *new_skb = NULL;
u32 pkt_total_offset = 0;
u64 *pkt_desc_ptr = NULL;
@@ -1251,6 +1243,7 @@ static const struct driver_info aqc111_info = {
FLAG_AVOID_UNLINK_URBS | FLAG_MULTI_PACKET,
.rx_fixup = aqc111_rx_fixup,
.tx_fixup = aqc111_tx_fixup,
+ .required_room = sizeof(struct aqc111_data),
};
#define ASIX111_DESC \
@@ -1268,6 +1261,7 @@ static const struct driver_info asix111_info = {
FLAG_AVOID_UNLINK_URBS | FLAG_MULTI_PACKET,
.rx_fixup = aqc111_rx_fixup,
.tx_fixup = aqc111_tx_fixup,
+ .required_room = sizeof(struct aqc111_data),
};
#undef ASIX111_DESC
@@ -1287,6 +1281,7 @@ static const struct driver_info asix112_info = {
FLAG_AVOID_UNLINK_URBS | FLAG_MULTI_PACKET,
.rx_fixup = aqc111_rx_fixup,
.tx_fixup = aqc111_tx_fixup,
+ .required_room = sizeof(struct aqc111_data),
};
#undef ASIX112_DESC
@@ -1303,6 +1298,7 @@ static const struct driver_info trendnet_info = {
FLAG_AVOID_UNLINK_URBS | FLAG_MULTI_PACKET,
.rx_fixup = aqc111_rx_fixup,
.tx_fixup = aqc111_tx_fixup,
+ .required_room = sizeof(struct aqc111_data),
};
static const struct driver_info qnap_info = {
@@ -1317,12 +1313,13 @@ static const struct driver_info qnap_info = {
FLAG_AVOID_UNLINK_URBS | FLAG_MULTI_PACKET,
.rx_fixup = aqc111_rx_fixup,
.tx_fixup = aqc111_tx_fixup,
+ .required_room = sizeof(struct aqc111_data),
};
static int aqc111_suspend(struct usb_interface *intf, pm_message_t message)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
u16 temp_rx_ctrl = 0x00;
u16 reg16;
u8 reg8;
@@ -1418,7 +1415,7 @@ static int aqc111_suspend(struct usb_interface *intf, pm_message_t message)
static int aqc111_resume(struct usb_interface *intf)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct aqc111_data *aqc111_data = dev->driver_priv;
+ struct aqc111_data *aqc111_data = (struct aqc111_data *)dev->private;
u16 reg16;
u8 reg8;
diff --git a/drivers/net/usb/asix.h b/drivers/net/usb/asix.h
index cf97bc3d388b..9bcfeada7175 100644
--- a/drivers/net/usb/asix.h
+++ b/drivers/net/usb/asix.h
@@ -159,7 +159,6 @@
#define AX_EMBD_PHY_ADDR 0x10
-/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
struct asix_data {
u8 multi_filter[AX_MCAST_FILTER_SIZE];
u8 mac_addr[ETH_ALEN];
@@ -182,6 +181,7 @@ struct asix_common_private {
u16 presvd_phy_advertise;
u16 presvd_phy_bmcr;
struct asix_rx_fixup_info rx_fixup_info;
+ struct asix_data asix_data;
struct mii_bus *mdio;
struct phy_device *phydev;
struct phy_device *phydev_int;
diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c
index d97a1920cb6e..f10cdd7dba5e 100644
--- a/drivers/net/usb/asix_common.c
+++ b/drivers/net/usb/asix_common.c
@@ -241,7 +241,7 @@ int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
int asix_rx_fixup_common(struct usbnet *dev, struct sk_buff *skb)
{
- struct asix_common_private *dp = dev->driver_priv;
+ struct asix_common_private *dp = (struct asix_common_private *)dev->private;
struct asix_rx_fixup_info *rx = &dp->rx_fixup_info;
return asix_rx_fixup_internal(dev, skb, rx);
diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
index 5100e0b31f1f..e21ed81bc6e4 100644
--- a/drivers/net/usb/asix_devices.c
+++ b/drivers/net/usb/asix_devices.c
@@ -118,7 +118,8 @@ static const struct ethtool_ops ax88172_ethtool_ops = {
static void ax88172_set_multicast(struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
- struct asix_data *data = (struct asix_data *)&dev->private;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
+ struct asix_data *data = &priv->asix_data;
u8 rx_ctl = 0x8c;
if (net->flags & IFF_PROMISC) {
@@ -129,10 +130,6 @@ static void ax88172_set_multicast(struct net_device *net)
} else if (netdev_mc_empty(net)) {
/* just broadcast and directed */
} else {
- /* We use the 20 byte dev->private
- * for our 8 byte filter buffer
- * to avoid allocating memory that
- * is tricky to free later */
struct netdev_hw_addr *ha;
u32 crc_bits;
@@ -295,7 +292,7 @@ static void ax88772_ethtool_get_pauseparam(struct net_device *ndev,
struct ethtool_pauseparam *pause)
{
struct usbnet *dev = netdev_priv(ndev);
- struct asix_common_private *priv = dev->driver_priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
phylink_ethtool_get_pauseparam(priv->phylink, pause);
}
@@ -304,7 +301,7 @@ static int ax88772_ethtool_set_pauseparam(struct net_device *ndev,
struct ethtool_pauseparam *pause)
{
struct usbnet *dev = netdev_priv(ndev);
- struct asix_common_private *priv = dev->driver_priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
return phylink_ethtool_set_pauseparam(priv->phylink, pause);
}
@@ -331,8 +328,8 @@ static const struct ethtool_ops ax88772_ethtool_ops = {
static int ax88772_reset(struct usbnet *dev)
{
- struct asix_data *data = (struct asix_data *)&dev->private;
- struct asix_common_private *priv = dev->driver_priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
+ struct asix_data *data = &priv->asix_data;
int ret;
/* Rewrite MAC address */
@@ -361,8 +358,8 @@ static int ax88772_reset(struct usbnet *dev)
static int ax88772_hw_reset(struct usbnet *dev, int in_pm)
{
- struct asix_data *data = (struct asix_data *)&dev->private;
- struct asix_common_private *priv = dev->driver_priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
+ struct asix_data *data = &priv->asix_data;
u16 rx_ctl;
int ret;
@@ -455,8 +452,8 @@ static int ax88772_hw_reset(struct usbnet *dev, int in_pm)
static int ax88772a_hw_reset(struct usbnet *dev, int in_pm)
{
- struct asix_data *data = (struct asix_data *)&dev->private;
- struct asix_common_private *priv = dev->driver_priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
+ struct asix_data *data = &priv->asix_data;
u16 rx_ctl, phy14h, phy15h, phy16h;
int ret;
@@ -595,7 +592,7 @@ static const struct net_device_ops ax88772_netdev_ops = {
static void ax88772_suspend(struct usbnet *dev)
{
- struct asix_common_private *priv = dev->driver_priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
u16 medium;
if (netif_running(dev->net)) {
@@ -631,9 +628,9 @@ static void ax88772_suspend(struct usbnet *dev)
static int asix_suspend(struct usb_interface *intf, pm_message_t message)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct asix_common_private *priv = dev->driver_priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
- if (priv && priv->suspend)
+ if (priv->suspend)
priv->suspend(dev);
return usbnet_suspend(intf, message);
@@ -641,7 +638,7 @@ static int asix_suspend(struct usb_interface *intf, pm_message_t message)
static void ax88772_resume(struct usbnet *dev)
{
- struct asix_common_private *priv = dev->driver_priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
int i;
for (i = 0; i < 3; i++)
@@ -658,7 +655,7 @@ static void ax88772_resume(struct usbnet *dev)
static int asix_resume(struct usb_interface *intf)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct asix_common_private *priv = dev->driver_priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
if (priv && priv->resume)
priv->resume(dev);
@@ -668,7 +665,7 @@ static int asix_resume(struct usb_interface *intf)
static int ax88772_init_mdio(struct usbnet *dev)
{
- struct asix_common_private *priv = dev->driver_priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
int ret;
priv->mdio = mdiobus_alloc();
@@ -702,7 +699,7 @@ static void ax88772_mdio_unregister(struct asix_common_private *priv)
static int ax88772_init_phy(struct usbnet *dev)
{
- struct asix_common_private *priv = dev->driver_priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
int ret;
priv->phydev = mdiobus_get_phy(priv->mdio, priv->phy_addr);
@@ -796,7 +793,7 @@ static const struct phylink_mac_ops ax88772_phylink_mac_ops = {
static int ax88772_phylink_setup(struct usbnet *dev)
{
- struct asix_common_private *priv = dev->driver_priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
phy_interface_t phy_if_mode;
struct phylink *phylink;
@@ -826,16 +823,10 @@ static int ax88772_phylink_setup(struct usbnet *dev)
static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
{
- struct asix_common_private *priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
u8 buf[ETH_ALEN] = {0};
int ret, i;
- priv = devm_kzalloc(&dev->udev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- dev->driver_priv = priv;
-
ret = usbnet_get_endpoints(dev, intf);
if (ret)
return ret;
@@ -943,7 +934,7 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
static int ax88772_stop(struct usbnet *dev)
{
- struct asix_common_private *priv = dev->driver_priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
phylink_stop(priv->phylink);
@@ -952,22 +943,23 @@ static int ax88772_stop(struct usbnet *dev)
static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct asix_common_private *priv = dev->driver_priv;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
rtnl_lock();
phylink_disconnect_phy(priv->phylink);
rtnl_unlock();
phylink_destroy(priv->phylink);
ax88772_mdio_unregister(priv);
- asix_rx_fixup_common_free(dev->driver_priv);
+ asix_rx_fixup_common_free(priv);
/* Drop the PM usage ref taken in bind() */
pm_runtime_put(&intf->dev);
}
static void ax88178_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- asix_rx_fixup_common_free(dev->driver_priv);
- kfree(dev->driver_priv);
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
+
+ asix_rx_fixup_common_free(priv);
}
static const struct ethtool_ops ax88178_ethtool_ops = {
@@ -987,7 +979,8 @@ static const struct ethtool_ops ax88178_ethtool_ops = {
static int marvell_phy_init(struct usbnet *dev)
{
- struct asix_data *data = (struct asix_data *)&dev->private;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
+ struct asix_data *data = &priv->asix_data;
u16 reg;
netdev_dbg(dev->net, "marvell_phy_init()\n");
@@ -1018,7 +1011,8 @@ static int marvell_phy_init(struct usbnet *dev)
static int rtl8211cl_phy_init(struct usbnet *dev)
{
- struct asix_data *data = (struct asix_data *)&dev->private;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
+ struct asix_data *data = &priv->asix_data;
netdev_dbg(dev->net, "rtl8211cl_phy_init()\n");
@@ -1065,7 +1059,8 @@ static int marvell_led_status(struct usbnet *dev, u16 speed)
static int ax88178_reset(struct usbnet *dev)
{
- struct asix_data *data = (struct asix_data *)&dev->private;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
+ struct asix_data *data = &priv->asix_data;
int ret;
__le16 eeprom;
u8 status;
@@ -1161,9 +1156,10 @@ static int ax88178_reset(struct usbnet *dev)
static int ax88178_link_reset(struct usbnet *dev)
{
- u16 mode;
+ struct asix_common_private *priv = (struct asix_common_private *)dev->private;
struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
- struct asix_data *data = (struct asix_data *)&dev->private;
+ struct asix_data *data = &priv->asix_data;
+ u16 mode;
u32 speed;
netdev_dbg(dev->net, "ax88178_link_reset()\n");
@@ -1314,10 +1310,6 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf)
dev->rx_urb_size = 2048;
}
- dev->driver_priv = kzalloc(sizeof(struct asix_common_private), GFP_KERNEL);
- if (!dev->driver_priv)
- return -ENOMEM;
-
return 0;
}
diff --git a/drivers/net/usb/ax88172a.c b/drivers/net/usb/ax88172a.c
index 34884805730d..b7f7dd57e4c5 100644
--- a/drivers/net/usb/ax88172a.c
+++ b/drivers/net/usb/ax88172a.c
@@ -30,7 +30,7 @@ static void ax88172a_adjust_link(struct net_device *netdev)
{
struct phy_device *phydev = netdev->phydev;
struct usbnet *dev = netdev_priv(netdev);
- struct ax88172a_private *priv = dev->driver_priv;
+ struct ax88172a_private *priv = (struct ax88172a_private *)dev->private;
u16 mode = 0;
if (phydev->link) {
@@ -60,7 +60,7 @@ static void ax88172a_status(struct usbnet *dev, struct urb *urb)
/* use phylib infrastructure */
static int ax88172a_init_mdio(struct usbnet *dev)
{
- struct ax88172a_private *priv = dev->driver_priv;
+ struct ax88172a_private *priv = (struct ax88172a_private *)dev->private;
int ret;
priv->mdio = mdiobus_alloc();
@@ -93,7 +93,7 @@ static int ax88172a_init_mdio(struct usbnet *dev)
static void ax88172a_remove_mdio(struct usbnet *dev)
{
- struct ax88172a_private *priv = dev->driver_priv;
+ struct ax88172a_private *priv = (struct ax88172a_private *)dev->private;
netdev_info(dev->net, "deregistering mdio bus %s\n", priv->mdio->id);
mdiobus_unregister(priv->mdio);
@@ -159,18 +159,12 @@ static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf)
{
int ret;
u8 buf[ETH_ALEN];
- struct ax88172a_private *priv;
+ struct ax88172a_private *priv = (struct ax88172a_private *)dev->private;
ret = usbnet_get_endpoints(dev, intf);
if (ret)
return ret;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- dev->driver_priv = priv;
-
/* Get the MAC address */
ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf, 0);
if (ret < ETH_ALEN) {
@@ -230,13 +224,12 @@ static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf)
return 0;
free:
- kfree(priv);
return ret;
}
static int ax88172a_stop(struct usbnet *dev)
-{
- struct ax88172a_private *priv = dev->driver_priv;
+ {
+ struct ax88172a_private *priv = (struct ax88172a_private *)dev->private;
netdev_dbg(dev->net, "Stopping interface\n");
@@ -252,16 +245,13 @@ static int ax88172a_stop(struct usbnet *dev)
static void ax88172a_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct ax88172a_private *priv = dev->driver_priv;
-
ax88172a_remove_mdio(dev);
- kfree(priv);
}
static int ax88172a_reset(struct usbnet *dev)
{
+ struct ax88172a_private *priv = (struct ax88172a_private *)dev->private;
struct asix_data *data = (struct asix_data *)&dev->private;
- struct ax88172a_private *priv = dev->driver_priv;
int ret;
u16 rx_ctl;
@@ -338,7 +328,7 @@ static int ax88172a_reset(struct usbnet *dev)
static int ax88172a_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
- struct ax88172a_private *dp = dev->driver_priv;
+ struct ax88172a_private *dp = (struct ax88172a_private *)dev->private;
struct asix_rx_fixup_info *rx = &dp->rx_fixup_info;
return asix_rx_fixup_internal(dev, skb, rx);
diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c
index df7e3f1c3672..cc88f8faaca1 100644
--- a/drivers/net/usb/ax88179_178a.c
+++ b/drivers/net/usb/ax88179_178a.c
@@ -173,6 +173,7 @@ struct ax88179_data {
u8 in_pm;
u32 wol_supported;
u32 wolopts;
+ u8 m_filter[8];
u8 disconnecting;
};
@@ -192,14 +193,14 @@ static const struct {
static void ax88179_set_pm_mode(struct usbnet *dev, bool pm_mode)
{
- struct ax88179_data *ax179_data = dev->driver_priv;
+ struct ax88179_data *ax179_data = (struct ax88179_data *)dev->private;
ax179_data->in_pm = pm_mode;
}
static int ax88179_in_pm(struct usbnet *dev)
{
- struct ax88179_data *ax179_data = dev->driver_priv;
+ struct ax88179_data *ax179_data = (struct ax88179_data *)dev->private;
return ax179_data->in_pm;
}
@@ -209,7 +210,7 @@ static int __ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
{
int ret;
int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16);
- struct ax88179_data *ax179_data = dev->driver_priv;
+ struct ax88179_data *ax179_data = (struct ax88179_data *)dev->private;
BUG_ON(!dev);
@@ -233,7 +234,7 @@ static int __ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
{
int ret;
int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16);
- struct ax88179_data *ax179_data = dev->driver_priv;
+ struct ax88179_data *ax179_data = (struct ax88179_data *)dev->private;
BUG_ON(!dev);
@@ -406,7 +407,7 @@ ax88179_phy_write_mmd_indirect(struct usbnet *dev, u16 prtad, u16 devad,
static int ax88179_suspend(struct usb_interface *intf, pm_message_t message)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct ax88179_data *priv = dev->driver_priv;
+ struct ax88179_data *priv = (struct ax88179_data *)dev->private;
u16 tmp16;
u8 tmp8;
@@ -504,7 +505,7 @@ static void ax88179_disconnect(struct usb_interface *intf)
if (!dev)
return;
- ax179_data = dev->driver_priv;
+ ax179_data = (struct ax88179_data *)dev->private;
ax179_data->disconnecting = 1;
usbnet_disconnect(intf);
@@ -514,7 +515,7 @@ static void
ax88179_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = netdev_priv(net);
- struct ax88179_data *priv = dev->driver_priv;
+ struct ax88179_data *priv = (struct ax88179_data *)dev->private;
wolinfo->supported = priv->wol_supported;
wolinfo->wolopts = priv->wolopts;
@@ -524,7 +525,7 @@ static int
ax88179_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = netdev_priv(net);
- struct ax88179_data *priv = dev->driver_priv;
+ struct ax88179_data *priv = (struct ax88179_data *)dev->private;
if (wolinfo->wolopts & ~(priv->wol_supported))
return -EINVAL;
@@ -708,7 +709,7 @@ ax88179_ethtool_set_eee(struct usbnet *dev, struct ethtool_keee *data)
static int ax88179_chk_eee(struct usbnet *dev)
{
struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
- struct ax88179_data *priv = dev->driver_priv;
+ struct ax88179_data *priv = (struct ax88179_data *)dev->private;
mii_ethtool_gset(&dev->mii, &ecmd);
@@ -811,7 +812,7 @@ static void ax88179_enable_eee(struct usbnet *dev)
static int ax88179_get_eee(struct net_device *net, struct ethtool_keee *edata)
{
struct usbnet *dev = netdev_priv(net);
- struct ax88179_data *priv = dev->driver_priv;
+ struct ax88179_data *priv = (struct ax88179_data *)dev->private;
edata->eee_enabled = priv->eee_enabled;
edata->eee_active = priv->eee_active;
@@ -822,7 +823,7 @@ static int ax88179_get_eee(struct net_device *net, struct ethtool_keee *edata)
static int ax88179_set_eee(struct net_device *net, struct ethtool_keee *edata)
{
struct usbnet *dev = netdev_priv(net);
- struct ax88179_data *priv = dev->driver_priv;
+ struct ax88179_data *priv = (struct ax88179_data *)dev->private;
int ret;
priv->eee_enabled = edata->eee_enabled;
@@ -867,8 +868,8 @@ static const struct ethtool_ops ax88179_ethtool_ops = {
static void ax88179_set_multicast(struct net_device *net)
{
struct usbnet *dev = netdev_priv(net);
- struct ax88179_data *data = dev->driver_priv;
- u8 *m_filter = ((u8 *)dev->private);
+ struct ax88179_data *data = (struct ax88179_data *)dev->private;
+ u8 *m_filter = data->m_filter;
data->rxctl = (AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_CTL_IPE);
@@ -1280,19 +1281,12 @@ static void ax88179_get_mac_addr(struct usbnet *dev)
static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
{
- struct ax88179_data *ax179_data;
int ret;
ret = usbnet_get_endpoints(dev, intf);
if (ret < 0)
return ret;
- ax179_data = kzalloc(sizeof(*ax179_data), GFP_KERNEL);
- if (!ax179_data)
- return -ENOMEM;
-
- dev->driver_priv = ax179_data;
-
dev->net->netdev_ops = &ax88179_netdev_ops;
dev->net->ethtool_ops = &ax88179_ethtool_ops;
dev->net->needed_headroom = 8;
@@ -1321,7 +1315,6 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf)
static void ax88179_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct ax88179_data *ax179_data = dev->driver_priv;
u16 tmp16;
/* Configure RX control register => stop operation */
@@ -1334,8 +1327,6 @@ static void ax88179_unbind(struct usbnet *dev, struct usb_interface *intf)
/* Power down ethernet PHY */
tmp16 = 0;
ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16);
-
- kfree(ax179_data);
}
static void
@@ -1507,7 +1498,7 @@ ax88179_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
static int ax88179_link_reset(struct usbnet *dev)
{
- struct ax88179_data *ax179_data = dev->driver_priv;
+ struct ax88179_data *ax179_data = (struct ax88179_data *)dev->private;
u8 tmp[5], link_sts;
u16 mode, tmp16, delay = HZ / 10;
u32 tmp32 = 0x40000000;
@@ -1585,7 +1576,7 @@ static int ax88179_reset(struct usbnet *dev)
u8 buf[5];
u16 *tmp16;
u8 *tmp;
- struct ax88179_data *ax179_data = dev->driver_priv;
+ struct ax88179_data *ax179_data = (struct ax88179_data *)dev->private;
struct ethtool_keee eee_data;
tmp16 = (u16 *)buf;
@@ -1718,6 +1709,7 @@ static const struct driver_info ax88179_info = {
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
+ .required_room = sizeof(struct ax88179_data),
};
static const struct driver_info ax88178a_info = {
@@ -1731,6 +1723,7 @@ static const struct driver_info ax88178a_info = {
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
+ .required_room = sizeof(struct ax88179_data),
};
static const struct driver_info cypress_GX3_info = {
@@ -1744,6 +1737,7 @@ static const struct driver_info cypress_GX3_info = {
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
+ .required_room = sizeof(struct ax88179_data),
};
static const struct driver_info dlink_dub1312_info = {
@@ -1757,6 +1751,7 @@ static const struct driver_info dlink_dub1312_info = {
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
+ .required_room = sizeof(struct ax88179_data),
};
static const struct driver_info sitecom_info = {
@@ -1770,6 +1765,7 @@ static const struct driver_info sitecom_info = {
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
+ .required_room = sizeof(struct ax88179_data),
};
static const struct driver_info samsung_info = {
@@ -1783,6 +1779,7 @@ static const struct driver_info samsung_info = {
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
+ .required_room = sizeof(struct ax88179_data),
};
static const struct driver_info lenovo_info = {
@@ -1796,6 +1793,7 @@ static const struct driver_info lenovo_info = {
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
+ .required_room = sizeof(struct ax88179_data),
};
static const struct driver_info belkin_info = {
@@ -1809,6 +1807,7 @@ static const struct driver_info belkin_info = {
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
+ .required_room = sizeof(struct ax88179_data),
};
static const struct driver_info toshiba_info = {
@@ -1822,6 +1821,7 @@ static const struct driver_info toshiba_info = {
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
+ .required_room = sizeof(struct ax88179_data),
};
static const struct driver_info mct_info = {
@@ -1835,6 +1835,7 @@ static const struct driver_info mct_info = {
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
+ .required_room = sizeof(struct ax88179_data),
};
static const struct driver_info at_umc2000_info = {
@@ -1848,6 +1849,7 @@ static const struct driver_info at_umc2000_info = {
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
+ .required_room = sizeof(struct ax88179_data),
};
static const struct driver_info at_umc200_info = {
@@ -1861,6 +1863,7 @@ static const struct driver_info at_umc200_info = {
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
+ .required_room = sizeof(struct ax88179_data),
};
static const struct driver_info at_umc2000sp_info = {
@@ -1874,6 +1877,7 @@ static const struct driver_info at_umc2000sp_info = {
.flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup,
.tx_fixup = ax88179_tx_fixup,
+ .required_room = sizeof(struct ax88179_data),
};
static const struct usb_device_id products[] = {
diff --git a/drivers/net/usb/cx82310_eth.c b/drivers/net/usb/cx82310_eth.c
index ebbaee0575a8..05ba7c00a943 100644
--- a/drivers/net/usb/cx82310_eth.c
+++ b/drivers/net/usb/cx82310_eth.c
@@ -43,6 +43,10 @@ enum cx82310_status {
struct cx82310_priv {
struct work_struct reenable_work;
struct usbnet *dev;
+
+ unsigned int partial_len; /* length of partial packet data */
+ unsigned int partial_rem; /* remaining (missing) data length */
+ u8 *partial_data; /* partial packet data */
};
/*
@@ -134,10 +138,6 @@ static void cx82310_reenable_work(struct work_struct *work)
cx82310_enable_ethernet(priv->dev);
}
-#define partial_len private[0] /* length of partial packet data */
-#define partial_rem private[1] /* remaining (missing) data length */
-#define partial_data private[2] /* partial packet data */
-
static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf)
{
int ret;
@@ -145,7 +145,7 @@ static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf)
struct usb_device *udev = dev->udev;
u8 link[3];
int timeout = 50;
- struct cx82310_priv *priv;
+ struct cx82310_priv *priv = (struct cx82310_priv*)dev->private;
u8 addr[ETH_ALEN];
/* avoid ADSL modems - continue only if iProduct is "USB NET CARD" */
@@ -169,16 +169,10 @@ static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf)
/* we can receive URBs up to 4KB from the device */
dev->rx_urb_size = 4096;
- dev->partial_data = (unsigned long) kmalloc(dev->hard_mtu, GFP_KERNEL);
- if (!dev->partial_data)
+ priv->partial_data = kmalloc(dev->hard_mtu, GFP_KERNEL);
+ if (!priv->partial_data)
return -ENOMEM;
- priv = kzalloc(sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- ret = -ENOMEM;
- goto err_partial;
- }
- dev->driver_priv = priv;
INIT_WORK(&priv->reenable_work, cx82310_reenable_work);
priv->dev = dev;
@@ -217,19 +211,16 @@ static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf)
return 0;
err:
- kfree(dev->driver_priv);
-err_partial:
- kfree((void *)dev->partial_data);
+ kfree(priv->partial_data);
return ret;
}
static void cx82310_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct cx82310_priv *priv = dev->driver_priv;
+ struct cx82310_priv *priv = (struct cx82310_priv*)dev->private;
- kfree((void *)dev->partial_data);
+ kfree(priv->partial_data);
cancel_work_sync(&priv->reenable_work);
- kfree(dev->driver_priv);
}
/*
@@ -244,25 +235,25 @@ static int cx82310_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
int len;
struct sk_buff *skb2;
- struct cx82310_priv *priv = dev->driver_priv;
+ struct cx82310_priv *priv = (struct cx82310_priv*)dev->private;
/*
* If the last skb ended with an incomplete packet, this skb contains
* end of that packet at the beginning.
*/
- if (dev->partial_rem) {
- len = dev->partial_len + dev->partial_rem;
+ if (priv->partial_rem) {
+ len = priv->partial_len + priv->partial_rem;
skb2 = alloc_skb(len, GFP_ATOMIC);
if (!skb2)
return 0;
skb_put(skb2, len);
- memcpy(skb2->data, (void *)dev->partial_data,
- dev->partial_len);
- memcpy(skb2->data + dev->partial_len, skb->data,
- dev->partial_rem);
+ memcpy(skb2->data, (void *)priv->partial_data,
+ priv->partial_len);
+ memcpy(skb2->data + priv->partial_len, skb->data,
+ priv->partial_rem);
usbnet_skb_return(dev, skb2);
- skb_pull(skb, (dev->partial_rem + 1) & ~1);
- dev->partial_rem = 0;
+ skb_pull(skb, (priv->partial_rem + 1) & ~1);
+ priv->partial_rem = 0;
if (skb->len < 2)
return 1;
}
@@ -289,10 +280,10 @@ static int cx82310_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
/* incomplete packet, save it for the next skb */
if (len > skb->len) {
- dev->partial_len = skb->len;
- dev->partial_rem = len - skb->len;
- memcpy((void *)dev->partial_data, skb->data,
- dev->partial_len);
+ priv->partial_len = skb->len;
+ priv->partial_rem = len - skb->len;
+ memcpy((void *)priv->partial_data, skb->data,
+ priv->partial_len);
skb_pull(skb, skb->len);
break;
}
@@ -338,6 +329,7 @@ static const struct driver_info cx82310_info = {
.unbind = cx82310_unbind,
.rx_fixup = cx82310_rx_fixup,
.tx_fixup = cx82310_tx_fixup,
+ .required_room = sizeof(struct cx82310_priv),
};
#define USB_DEVICE_CLASS(vend, prod, cl, sc, pr) \
diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c
index b2495fa80171..ed6dff959245 100644
--- a/drivers/net/usb/lg-vl600.c
+++ b/drivers/net/usb/lg-vl600.c
@@ -56,18 +56,10 @@ struct vl600_state {
static int vl600_bind(struct usbnet *dev, struct usb_interface *intf)
{
int ret;
- struct vl600_state *s = kzalloc(sizeof(struct vl600_state), GFP_KERNEL);
-
- if (!s)
- return -ENOMEM;
ret = usbnet_cdc_bind(dev, intf);
- if (ret) {
- kfree(s);
+ if (ret)
return ret;
- }
-
- dev->driver_priv = s;
/* ARP packets don't go through, but they're also of no use. The
* subnet has only two hosts anyway: us and the gateway / DHCP
@@ -85,7 +77,7 @@ static int vl600_bind(struct usbnet *dev, struct usb_interface *intf)
static void vl600_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct vl600_state *s = dev->driver_priv;
+ struct vl600_state *s = (struct vl600_state *)dev->private;
dev_kfree_skb(s->current_rx_buf);
kfree(s);
@@ -101,7 +93,7 @@ static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
int packet_len, count;
struct sk_buff *buf = skb;
struct sk_buff *clone;
- struct vl600_state *s = dev->driver_priv;
+ struct vl600_state *s = (struct vl600_state *)dev->private;
/* Frame lengths are generally 4B multiplies but every couple of
* hours there's an odd number of bytes sized yet correct frame,
@@ -306,6 +298,7 @@ static const struct driver_info vl600_info = {
.status = usbnet_cdc_status,
.rx_fixup = vl600_rx_fixup,
.tx_fixup = vl600_tx_fixup,
+ .required_room = sizeof(struct vl600_state),
};
static const struct usb_device_id products[] = {
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 7ecf98d97493..a99d4363fd3f 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -84,7 +84,7 @@ MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
u32 *data)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
u32 buf;
int ret;
int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16);
@@ -115,7 +115,7 @@ static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
static int __must_check smsc95xx_write_reg(struct usbnet *dev, u32 index,
u32 data)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
u32 buf;
int ret;
int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16);
@@ -265,7 +265,7 @@ static int smsc95xx_mdiobus_reset(struct mii_bus *bus)
int ret;
dev = bus->priv;
- pdata = dev->driver_priv;
+ pdata = (struct smsc95xx_priv *)dev->private;
if (pdata->is_internal_phy)
return 0;
@@ -481,7 +481,7 @@ static unsigned int smsc95xx_hash(char addr[ETH_ALEN])
static void smsc95xx_set_multicast(struct net_device *netdev)
{
struct usbnet *dev = netdev_priv(netdev);
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
unsigned long flags;
int ret;
@@ -539,7 +539,7 @@ static void smsc95xx_set_multicast(struct net_device *netdev)
static int smsc95xx_phy_update_flowcontrol(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
u32 flow = 0, afc_cfg;
int ret = smsc95xx_read_reg(dev, AFC_CFG, &afc_cfg);
@@ -584,7 +584,7 @@ static int smsc95xx_phy_update_flowcontrol(struct usbnet *dev)
static void smsc95xx_mac_update_fullduplex(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
unsigned long flags;
int ret;
@@ -613,7 +613,7 @@ static void smsc95xx_mac_update_fullduplex(struct usbnet *dev)
static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
unsigned long flags;
u32 intdata;
@@ -730,7 +730,7 @@ static void smsc95xx_ethtool_get_wol(struct net_device *net,
struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = netdev_priv(net);
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
wolinfo->supported = SUPPORTED_WAKE;
wolinfo->wolopts = pdata->wolopts;
@@ -740,7 +740,7 @@ static int smsc95xx_ethtool_set_wol(struct net_device *net,
struct ethtool_wolinfo *wolinfo)
{
struct usbnet *dev = netdev_priv(net);
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
int ret;
if (wolinfo->wolopts & ~SUPPORTED_WAKE)
@@ -788,7 +788,7 @@ static void smsc95xx_get_pauseparam(struct net_device *ndev,
struct usbnet *dev;
dev = netdev_priv(ndev);
- pdata = dev->driver_priv;
+ pdata = (struct smsc95xx_priv *)dev->private;
pause->autoneg = pdata->pause_autoneg;
pause->rx_pause = pdata->pause_rx;
@@ -804,7 +804,7 @@ static int smsc95xx_set_pauseparam(struct net_device *ndev,
struct usbnet *dev;
dev = netdev_priv(ndev);
- pdata = dev->driver_priv;
+ pdata = (struct smsc95xx_priv *)dev->private;
phydev = ndev->phydev;
if (!phydev)
@@ -898,7 +898,7 @@ static int smsc95xx_set_mac_address(struct usbnet *dev)
/* starts the TX path */
static int smsc95xx_start_tx_path(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
unsigned long flags;
int ret;
@@ -918,7 +918,7 @@ static int smsc95xx_start_tx_path(struct usbnet *dev)
/* Starts the Receive path */
static int smsc95xx_start_rx_path(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
unsigned long flags;
spin_lock_irqsave(&pdata->mac_cr_lock, flags);
@@ -930,7 +930,7 @@ static int smsc95xx_start_rx_path(struct usbnet *dev)
static int smsc95xx_reset(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
u32 read_buf, burst_cap;
int ret = 0, timeout;
@@ -1146,7 +1146,7 @@ static void smsc95xx_handle_link_change(struct net_device *net)
static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
{
- struct smsc95xx_priv *pdata;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
char usb_path[64];
int ret, phy_irq;
u32 val;
@@ -1157,12 +1157,6 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
return ret;
}
- pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
- return -ENOMEM;
-
- dev->driver_priv = pdata;
-
spin_lock_init(&pdata->mac_cr_lock);
/* LAN95xx devices do not alter the computed checksum of 0 to 0xffff.
@@ -1316,7 +1310,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
phy_disconnect(dev->net->phydev);
mdiobus_unregister(pdata->mdiobus);
@@ -1325,7 +1319,6 @@ static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf)
irq_domain_remove(pdata->irqdomain);
irq_domain_free_fwnode(pdata->irqfwnode);
netif_dbg(dev, ifdown, dev->net, "free pdata\n");
- kfree(pdata);
}
static int smsc95xx_start_phy(struct usbnet *dev)
@@ -1350,7 +1343,7 @@ static u32 smsc_crc(const u8 *buffer, size_t len, int filter)
static int smsc95xx_link_ok(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
int ret;
/* first, a dummy read, needed to latch some MII phys */
@@ -1367,7 +1360,7 @@ static int smsc95xx_link_ok(struct usbnet *dev)
static int smsc95xx_enter_suspend0(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
u32 val;
int ret;
@@ -1406,7 +1399,7 @@ static int smsc95xx_enter_suspend0(struct usbnet *dev)
static int smsc95xx_enter_suspend1(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
int ret, phy_id = pdata->phydev->mdio.addr;
u32 val;
@@ -1453,7 +1446,7 @@ static int smsc95xx_enter_suspend1(struct usbnet *dev)
static int smsc95xx_enter_suspend2(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
u32 val;
int ret;
@@ -1475,7 +1468,7 @@ static int smsc95xx_enter_suspend2(struct usbnet *dev)
static int smsc95xx_enter_suspend3(struct usbnet *dev)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
u32 val;
int ret;
@@ -1514,7 +1507,7 @@ static int smsc95xx_enter_suspend3(struct usbnet *dev)
static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
if (!netif_running(dev->net)) {
/* interface is ifconfig down so fully power down hw */
@@ -1544,7 +1537,7 @@ static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up)
static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
u32 val, link_up;
int ret;
@@ -1805,7 +1798,7 @@ static int smsc95xx_resume(struct usb_interface *intf)
u32 val;
BUG_ON(!dev);
- pdata = dev->driver_priv;
+ pdata = (struct smsc95xx_priv *)dev->private;
suspend_flags = pdata->suspend_flags;
netdev_dbg(dev->net, "resume suspend_flags=0x%02x\n", suspend_flags);
@@ -1854,7 +1847,7 @@ static int smsc95xx_resume(struct usb_interface *intf)
static int smsc95xx_reset_resume(struct usb_interface *intf)
{
struct usbnet *dev = usb_get_intfdata(intf);
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
int ret;
pdata->pm_task = current;
@@ -2038,7 +2031,7 @@ static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
static int smsc95xx_manage_power(struct usbnet *dev, int on)
{
- struct smsc95xx_priv *pdata = dev->driver_priv;
+ struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)dev->private;
dev->intf->needs_remote_wakeup = on;
@@ -2068,6 +2061,7 @@ static const struct driver_info smsc95xx_info = {
.status = smsc95xx_status,
.manage_power = smsc95xx_manage_power,
.flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,
+ .required_room = sizeof(struct smsc95xx_priv),
};
static const struct usb_device_id products[] = {
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index ba45a3e2be6a..ec90a12eb26c 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -35,7 +35,6 @@ struct usbnet {
struct usb_interface *intf;
const struct driver_info *driver_info;
const char *driver_name;
- void *driver_priv;
wait_queue_head_t wait;
struct mutex phy_mutex;
unsigned char suspend_count;
--
2.53.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [RFC net-next 1/3] net: usb: divorce private data and cdc state in usbnet
2026-02-10 15:11 ` [RFC net-next 1/3] net: usb: divorce private data and cdc state in usbnet Oliver Neukum
@ 2026-02-10 16:27 ` Bjørn Mork
2026-02-10 17:11 ` Oliver Neukum
2026-02-17 18:23 ` Andrew Lunn
2026-02-17 18:31 ` Andrew Lunn
2 siblings, 1 reply; 13+ messages in thread
From: Bjørn Mork @ 2026-02-10 16:27 UTC (permalink / raw)
To: Oliver Neukum; +Cc: netdev, hayeswang, o.rempel
Oliver Neukum <oneukum@suse.com> writes:
> --- a/include/linux/usb/usbnet.h
> +++ b/include/linux/usb/usbnet.h
> @@ -16,6 +16,18 @@
> #include <linux/usb.h>
> #include <linux/spinlock.h>
>
> +/* Drivers that reuse some of the standard USB CDC infrastructure
> + * (notably, using multiple interfaces according to the CDC
> + * union descriptor) get some helper code.
> + */
> +struct cdc_state {
> + struct usb_cdc_header_desc *header;
> + struct usb_cdc_union_desc *u;
> + struct usb_cdc_ether_desc *ether;
> + struct usb_interface *control;
> + struct usb_interface *data;
> +};
> +
> /* interface from usbnet core to each USB networking link we handle */
> struct usbnet {
> /* housekeeping */
> @@ -41,7 +53,7 @@ struct usbnet {
> /* protocol/interface state */
> struct net_device *net;
> int msg_enable;
> - unsigned long data[5];
> + struct cdc_state cdc; /* too common to leave out*/
> u32 xid;
> u32 hard_mtu; /* count any extra framing */
> size_t rx_urb_size; /* size for rx urbs */
> @@ -84,6 +96,7 @@ struct usbnet {
> * that must be broken
> */
> # define EVENT_UNPLUG 31
> + unsigned long private[5];
> };
>
> static inline bool usbnet_going_away(struct usbnet *ubn)
I like the idea. Nice to get rid of those extra allocations for drivers
needing more than 5 pointers.
But I don't understand why you make struct cdc_state special. That's
just confusing.
I know I intentionally made the "control" and "data" fields of
"struct qmi_wwan_state" position and name compatible with
"struct cdc_state". Maybe not very important. But adds to the
confusion if we end up with a double set of those fields.
Or should the qmi_wwan driver split out the
struct usb_interface *control;
struct usb_interface *data;
part of its private data and put those into "cdc", allowing us to reduce
"struct qmi_wwan_state" from 5 to 3 longs? I don't think that's a very
good idea...
Let's keep this a single private minidriver allocation. Making it
flexible is nice.
Bjørn
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC net-next 1/3] net: usb: divorce private data and cdc state in usbnet
2026-02-10 16:27 ` Bjørn Mork
@ 2026-02-10 17:11 ` Oliver Neukum
0 siblings, 0 replies; 13+ messages in thread
From: Oliver Neukum @ 2026-02-10 17:11 UTC (permalink / raw)
To: Bjørn Mork; +Cc: netdev, hayeswang, o.rempel
Hi,
On 10.02.26 17:27, Bjørn Mork wrote:
> Oliver Neukum <oneukum@suse.com> writes:
>
> But I don't understand why you make struct cdc_state special. That's
> just confusing.
Because technically it is a layering violation to put cdc stuff
into usbnet. I want to do so that I can remove the exported symbols
from the cdc_X drivers and put them cleanly into usbnet.
That is the medium term plan.
> I know I intentionally made the "control" and "data" fields of
> "struct qmi_wwan_state" position and name compatible with
> "struct cdc_state". Maybe not very important. But adds to the
> confusion if we end up with a double set of those fields.
>
> Or should the qmi_wwan driver split out the
> struct usb_interface *control;
> struct usb_interface *data;
>
> part of its private data and put those into "cdc", allowing us to reduce
> "struct qmi_wwan_state" from 5 to 3 longs? I don't think that's a very
> good idea...
Well, QMI is not CDC. No use pretending.
But we could put them into struct usbnet as primary and secondary
Regards
Oliver
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC net-next 1/3] net: usb: divorce private data and cdc state in usbnet
2026-02-10 15:11 ` [RFC net-next 1/3] net: usb: divorce private data and cdc state in usbnet Oliver Neukum
2026-02-10 16:27 ` Bjørn Mork
@ 2026-02-17 18:23 ` Andrew Lunn
2026-02-18 9:53 ` Oliver Neukum
2026-02-17 18:31 ` Andrew Lunn
2 siblings, 1 reply; 13+ messages in thread
From: Andrew Lunn @ 2026-02-17 18:23 UTC (permalink / raw)
To: Oliver Neukum; +Cc: netdev, hayeswang, bjorn, o.rempel
> @@ -41,7 +53,7 @@ struct usbnet {
> /* protocol/interface state */
> struct net_device *net;
> int msg_enable;
> - unsigned long data[5];
> + struct cdc_state cdc; /* too common to leave out*/
> u32 xid;
> u32 hard_mtu; /* count any extra framing */
> size_t rx_urb_size; /* size for rx urbs */
> @@ -84,6 +96,7 @@ struct usbnet {
> * that must be broken
> */
> # define EVENT_UNPLUG 31
> + unsigned long private[5];
private would normally be a void *, since the core has no idea what
type is should be, it is specific to the driver. For this patch, could
you make it a void *, and set the pointer to a block of memory
equivalent to 5 unsigned longs.
You can then remove all the casts in the drivers, making the code look
normal for handling private memory.
Andrew
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC net-next 1/3] net: usb: divorce private data and cdc state in usbnet
2026-02-10 15:11 ` [RFC net-next 1/3] net: usb: divorce private data and cdc state in usbnet Oliver Neukum
2026-02-10 16:27 ` Bjørn Mork
2026-02-17 18:23 ` Andrew Lunn
@ 2026-02-17 18:31 ` Andrew Lunn
2 siblings, 0 replies; 13+ messages in thread
From: Andrew Lunn @ 2026-02-17 18:31 UTC (permalink / raw)
To: Oliver Neukum; +Cc: netdev, hayeswang, bjorn, o.rempel
On Tue, Feb 10, 2026 at 04:11:12PM +0100, Oliver Neukum wrote:
> This allows use of cdc helpers together with private dara.
>
> Signed-off-by: Oliver Neukum <oneukum@suse.com>
> ---
> drivers/net/usb/asix_common.c | 4 +--
> drivers/net/usb/asix_devices.c | 18 +++++-----
> drivers/net/usb/ax88172a.c | 2 +-
> drivers/net/usb/ax88179_178a.c | 2 +-
> drivers/net/usb/cdc_ether.c | 12 ++-----
> drivers/net/usb/cdc_mbim.c | 18 +++++-----
> drivers/net/usb/cdc_ncm.c | 58 ++++++++++++++++----------------
> drivers/net/usb/cx82310_eth.c | 6 ++--
> drivers/net/usb/dm9601.c | 2 +-
> drivers/net/usb/huawei_cdc_ncm.c | 10 +++---
> drivers/net/usb/mcs7830.c | 2 +-
> drivers/net/usb/net1080.c | 2 +-
> drivers/net/usb/qmi_wwan.c | 33 +++++++++---------
> drivers/net/usb/rndis_host.c | 6 ++--
> drivers/net/usb/sierra_net.c | 7 ++--
> drivers/net/usb/smsc75xx.c | 40 +++++++++++-----------
> drivers/net/usb/sr9700.c | 1 +
> drivers/net/usb/sr9800.c | 10 +++---
> include/linux/usb/usbnet.h | 27 ++++++++-------
> 19 files changed, 125 insertions(+), 135 deletions(-)
>
> diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c
> index 4f03f4e57655..d97a1920cb6e 100644
> --- a/drivers/net/usb/asix_common.c
> +++ b/drivers/net/usb/asix_common.c
> @@ -441,7 +441,7 @@ int asix_write_gpio(struct usbnet *dev, u16 value, int sleep, int in_pm)
> void asix_set_multicast(struct net_device *net)
> {
> struct usbnet *dev = netdev_priv(net);
> - struct asix_data *data = (struct asix_data *)&dev->data;
> + struct asix_data *data = (struct asix_data *)&dev->private;
Would it make sense to add a usbnet_priv() macro? It is a common thing
to see: mux_chip_priv(), iio_priv(), pci_host_bridge_priv(),
shost_priv() etc.
Andrew
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC net-next 2/3] net: usb: usbnet: switch to dynamic allocation of private data
2026-02-10 15:11 ` [RFC net-next 2/3] net: usb: usbnet: switch to dynamic allocation of private data Oliver Neukum
@ 2026-02-17 18:47 ` Andrew Lunn
2026-02-18 10:06 ` Oliver Neukum
0 siblings, 1 reply; 13+ messages in thread
From: Andrew Lunn @ 2026-02-17 18:47 UTC (permalink / raw)
To: Oliver Neukum; +Cc: netdev, hayeswang, bjorn, o.rempel, Oliver Neukum
On Tue, Feb 10, 2026 at 04:11:13PM +0100, Oliver Neukum wrote:
> usbnet used an unsigned long[5] scratchpad space for private
> use of subdrivers. That is inelegant and not enough space
> for some drivers. Switch to letting drivers specify how much
> room they need in their driver_info.
>
> Signed-off-by: Oliver Neukum <oneukum@suse.de>
> ---
> drivers/net/usb/ax88172a.c | 1 +
> drivers/net/usb/cdc_mbim.c | 4 ++
> drivers/net/usb/cdc_ncm.c | 82 +++++++++++++++++-------------------
> drivers/net/usb/sierra_net.c | 21 +++------
> drivers/net/usb/smsc75xx.c | 4 +-
> drivers/net/usb/usbnet.c | 2 +-
> include/linux/usb/usbnet.h | 5 ++-
> 7 files changed, 56 insertions(+), 63 deletions(-)
>
> diff --git a/drivers/net/usb/ax88172a.c b/drivers/net/usb/ax88172a.c
> index 1694d6ca2b7b..34884805730d 100644
> --- a/drivers/net/usb/ax88172a.c
> +++ b/drivers/net/usb/ax88172a.c
> @@ -355,4 +355,5 @@ const struct driver_info ax88172a_info = {
> FLAG_MULTI_PACKET,
> .rx_fixup = ax88172a_rx_fixup,
> .tx_fixup = asix_tx_fixup,
> + .required_room = sizeof(struct ax88172a_private),
A change like this makes sense, given the commit message.
> @@ -107,7 +107,7 @@ static void cdc_ncm_get_ethtool_stats(struct net_device *netdev,
> u64 *data)
> {
> struct usbnet *dev = netdev_priv(netdev);
> - struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
> + struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
But it is not clear why changes like this belong on this patch. Can
they be moved into another patch with a good commit message?
> static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
> {
> - if (ctx == NULL)
> - return;
> -
Maybe a patch of its own?
> if (ctx->tx_rem_skb != NULL) {
> dev_kfree_skb_any(ctx->tx_rem_skb);
> ctx->tx_rem_skb = NULL;
> @@ -782,12 +779,13 @@ static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
> ctx->tx_curr_skb = NULL;
> }
>
> - if (ctx->is_ndp16)
> + if (ctx->is_ndp16) {
> kfree(ctx->delayed_ndp16);
> - else
> + ctx->delayed_ndp16 = NULL;
> + } else {
> kfree(ctx->delayed_ndp32);
> -
> - kfree(ctx);
> + ctx->delayed_ndp32 = NULL;
> + }
Another patch, with an commit message explaining why this is needed.
> --- a/drivers/net/usb/sierra_net.c
> +++ b/drivers/net/usb/sierra_net.c
> @@ -190,14 +190,7 @@ static const struct net_device_ops sierra_net_device_ops = {
> /* get private data associated with passed in usbnet device */
> static inline struct sierra_net_data *sierra_net_get_private(struct usbnet *dev)
> {
> - return (struct sierra_net_data *)dev->private[0];
> -}
> -
> -/* set private data associated with passed in usbnet device */
> -static inline void sierra_net_set_private(struct usbnet *dev,
> - struct sierra_net_data *priv)
> -{
> - dev->private[0] = (unsigned long)priv;
> + return (struct sierra_net_data *)dev->private;
> }
>
> /* is packet IPv4/IPv6 */
> @@ -653,7 +646,7 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
> u8 numendpoints;
> u16 fwattr = 0;
> int status;
> - struct sierra_net_data *priv;
> + struct sierra_net_data *priv = (struct sierra_net_data *)dev->private;
> static const u8 sync_tmplate[sizeof(priv->sync_msg)] = {
> 0x00, 0x00, SIERRA_NET_HIP_MSYNC_ID, 0x00};
> static const u8 shdwn_tmplate[sizeof(priv->shdwn_msg)] = {
> @@ -682,11 +675,8 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf)
> dev_err(&dev->udev->dev, "No status endpoint found");
> return -ENODEV;
> }
> - /* Initialize sierra private data */
> - priv = kzalloc(sizeof *priv, GFP_KERNEL);
> - if (!priv)
> - return -ENOMEM;
Removing the sierra drivers own memory management should be a separate
patch.
> @@ -1500,7 +1500,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
> cancel_work_sync(&pdata->set_multicast);
> free_pdata:
> kfree(pdata);
> - memset(dev->private, 0, sizeof(dev->private));
> + memset(dev->private, 0, sizeof(struct smsc75xx_priv *));
> return ret;
> }
>
> @@ -1511,7 +1511,7 @@ static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)
> cancel_work_sync(&pdata->set_multicast);
> netif_dbg(dev, ifdown, dev->net, "free pdata\n");
> kfree(pdata);
> - memset(dev->private, 0, sizeof(dev->private));
> + memset(dev->private, 0, sizeof(struct smsc75xx_priv *));
These also might need investigating. Why is it necessary to memset
this memory? Has the life cycle of the memory changed? Can these be
removed? Again, a separate patch, with a good commit message
explaining why?
I think the general idea is good, it just needs breaking up into
smaller patches with good commit messages, and you should try to make
it look more normal, void *, little wrappers, no casts, etc.
Andrew
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC net-next 1/3] net: usb: divorce private data and cdc state in usbnet
2026-02-17 18:23 ` Andrew Lunn
@ 2026-02-18 9:53 ` Oliver Neukum
0 siblings, 0 replies; 13+ messages in thread
From: Oliver Neukum @ 2026-02-18 9:53 UTC (permalink / raw)
To: Andrew Lunn; +Cc: netdev, hayeswang, bjorn, o.rempel
On 17.02.26 19:23, Andrew Lunn wrote:
>> + unsigned long private[5];
>
> private would normally be a void *, since the core has no idea what
> type is should be, it is specific to the driver. For this patch, could
> you make it a void *, and set the pointer to a block of memory
> equivalent to 5 unsigned longs.
>
> You can then remove all the casts in the drivers, making the code look
> normal for handling private memory.
Hi,
understood.
Regards
Oliver
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC net-next 2/3] net: usb: usbnet: switch to dynamic allocation of private data
2026-02-17 18:47 ` Andrew Lunn
@ 2026-02-18 10:06 ` Oliver Neukum
2026-02-18 14:01 ` Andrew Lunn
0 siblings, 1 reply; 13+ messages in thread
From: Oliver Neukum @ 2026-02-18 10:06 UTC (permalink / raw)
To: Andrew Lunn; +Cc: netdev, hayeswang, bjorn, o.rempel, Oliver Neukum
Hi,
thank you for these reviews.
On 17.02.26 19:47, Andrew Lunn wrote:
> On Tue, Feb 10, 2026 at 04:11:13PM +0100, Oliver Neukum wrote:
>
>> @@ -107,7 +107,7 @@ static void cdc_ncm_get_ethtool_stats(struct net_device *netdev,
>> u64 *data)
>> {
>> struct usbnet *dev = netdev_priv(netdev);
>> - struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
>> + struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
>
> But it is not clear why changes like this belong on this patch. Can
> they be moved into another patch with a good commit message?
I don't think so. dev->private[0] is an unsigned long
dev->private is unsigned long *
This driver uses the provided scratchpad to store a pointer.
If you want me to leave these lines unchanged I'd need to add
a required_room member of "sizeof(void *)" to the driver_info
of this driver, which really makes no sense.
>> static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
>> {
>> - if (ctx == NULL)
>> - return;
>> -
>
> Maybe a patch of its own?
Roger
>> if (ctx->tx_rem_skb != NULL) {
>> dev_kfree_skb_any(ctx->tx_rem_skb);
>> ctx->tx_rem_skb = NULL;
>> @@ -782,12 +779,13 @@ static void cdc_ncm_free(struct cdc_ncm_ctx *ctx)
>> ctx->tx_curr_skb = NULL;
>> }
>>
>> - if (ctx->is_ndp16)
>> + if (ctx->is_ndp16) {
>> kfree(ctx->delayed_ndp16);
>> - else
>> + ctx->delayed_ndp16 = NULL;
>> + } else {
>> kfree(ctx->delayed_ndp32);
>> -
>> - kfree(ctx);
>> + ctx->delayed_ndp32 = NULL;
>> + }
>
> Another patch, with an commit message explaining why this is needed.
This removes a kfree freeing what is now a part of another data structure.
>> - /* Initialize sierra private data */
>> - priv = kzalloc(sizeof *priv, GFP_KERNEL);
>> - if (!priv)
>> - return -ENOMEM;
>
> Removing the sierra drivers own memory management should be a separate
> patch.
Roger
>> @@ -1511,7 +1511,7 @@ static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)
>> cancel_work_sync(&pdata->set_multicast);
>> netif_dbg(dev, ifdown, dev->net, "free pdata\n");
>> kfree(pdata);
>> - memset(dev->private, 0, sizeof(dev->private));
>> + memset(dev->private, 0, sizeof(struct smsc75xx_priv *));
>
> These also might need investigating. Why is it necessary to memset
> this memory? Has the life cycle of the memory changed? Can these be
> removed? Again, a separate patch, with a good commit message
> explaining why?
Well, now I need you to kind of make up your mind.
Should I limit this patch to necessary changes or do a big change?
The current code does a memset. I agree that this should be looked at.
But I cannot just leave it. "sizeof(dev->private)" takes the size
of a flexarray.
> I think the general idea is good, it just needs breaking up into
> smaller patches with good commit messages, and you should try to make
> it look more normal, void *, little wrappers, no casts, etc.
I shall try.
Regards
Oliver
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC net-next 2/3] net: usb: usbnet: switch to dynamic allocation of private data
2026-02-18 10:06 ` Oliver Neukum
@ 2026-02-18 14:01 ` Andrew Lunn
2026-02-19 9:07 ` Oliver Neukum
0 siblings, 1 reply; 13+ messages in thread
From: Andrew Lunn @ 2026-02-18 14:01 UTC (permalink / raw)
To: Oliver Neukum; +Cc: netdev, hayeswang, bjorn, o.rempel, Oliver Neukum
> > > @@ -107,7 +107,7 @@ static void cdc_ncm_get_ethtool_stats(struct net_device *netdev,
> > > u64 *data)
> > > {
> > > struct usbnet *dev = netdev_priv(netdev);
> > > - struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private[0];
> > > + struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->private;
> >
> > But it is not clear why changes like this belong on this patch. Can
> > they be moved into another patch with a good commit message?
>
> I don't think so. dev->private[0] is an unsigned long
> dev->private is unsigned long *
>
> This driver uses the provided scratchpad to store a pointer.
> If you want me to leave these lines unchanged I'd need to add
> a required_room member of "sizeof(void *)" to the driver_info
> of this driver, which really makes no sense.
I'm not asking for it to be left unchanged. I'm asking, can this
change be done as a different patch? With a commit message which
explains the change.
Adding usbnet_priv() might help here. Look at netdev_priv().
struct net_device has
u8 priv[] ____cacheline_aligned
__counted_by(priv_len);
so it is not that different to what struct usbnet has, just u8 vs
unsigned long.
static inline void *netdev_priv(const struct net_device *dev)
{
return (void *)dev->priv;
}
usbnet_priv() could do something similar. The initial version would
return the address of the unsigned long [5] as a void *. You can have
one patch which then converts all "simple" users to using
usbnet_priv(). And a second patch, with a good commit message,
converting these dev->private[0]. At this point, you have not actually
changed anything with the memory allocation, you have just added an
access wrapper. You can then change to dynamically allocating the
memory of a requested size, and update the wrapper to suit.
Doing it like this should make it possible to break the change up into
smaller, more obviously correct patches.
> > > @@ -1511,7 +1511,7 @@ static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)
> > > cancel_work_sync(&pdata->set_multicast);
> > > netif_dbg(dev, ifdown, dev->net, "free pdata\n");
> > > kfree(pdata);
> > > - memset(dev->private, 0, sizeof(dev->private));
> > > + memset(dev->private, 0, sizeof(struct smsc75xx_priv *));
> >
> > These also might need investigating. Why is it necessary to memset
> > this memory? Has the life cycle of the memory changed? Can these be
> > removed? Again, a separate patch, with a good commit message
> > explaining why?
>
> Well, now I need you to kind of make up your mind.
The assumption is, dev->private as unsigned long [5] is big enough to
hold a struct smsc75xx_priv. This is true before or after the change
to dynamically allocating the memory. So this memset change could
happen before you change to dynamically allocating the memory. So you
could make this an patch, with a commit message something like:
dev->private will soon change from being a fix sized array to
dynamically allocated memory of requested size. This means
sizeof(dev->priv) will no longer work. However, it is known that it
will always be big enough to contain a struct smsc75xx_priv. So it
is safe to just memset the size of struct smsc75xx_priv.
A two line patch, with a commit message like this is quick and simple
to review, since it is obviously correct.
Andrew
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [RFC net-next 2/3] net: usb: usbnet: switch to dynamic allocation of private data
2026-02-18 14:01 ` Andrew Lunn
@ 2026-02-19 9:07 ` Oliver Neukum
0 siblings, 0 replies; 13+ messages in thread
From: Oliver Neukum @ 2026-02-19 9:07 UTC (permalink / raw)
To: Andrew Lunn, Oliver Neukum; +Cc: netdev, hayeswang, bjorn, o.rempel
On 18.02.26 15:01, Andrew Lunn wrote:
> usbnet_priv() could do something similar. The initial version would
> return the address of the unsigned long [5] as a void *.
Thank you. That was the detail unclear to me. Yes, I will rework the patch set.
Regards
Oliver
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-02-19 9:08 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-10 15:11 [RFC net-next 0/3] cleanup of usbnet descriptor allocation Oliver Neukum
2026-02-10 15:11 ` [RFC net-next 1/3] net: usb: divorce private data and cdc state in usbnet Oliver Neukum
2026-02-10 16:27 ` Bjørn Mork
2026-02-10 17:11 ` Oliver Neukum
2026-02-17 18:23 ` Andrew Lunn
2026-02-18 9:53 ` Oliver Neukum
2026-02-17 18:31 ` Andrew Lunn
2026-02-10 15:11 ` [RFC net-next 2/3] net: usb: usbnet: switch to dynamic allocation of private data Oliver Neukum
2026-02-17 18:47 ` Andrew Lunn
2026-02-18 10:06 ` Oliver Neukum
2026-02-18 14:01 ` Andrew Lunn
2026-02-19 9:07 ` Oliver Neukum
2026-02-10 15:11 ` [RFC net-next 3/3] net: usb: usbnet: remove driver_priv Oliver Neukum
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox