Skip to contentSkip to conversation

USB: async platform_data support for usb and usbnet

RFC PATCH New Andy Green 1 participant 4 messages Mar 12, 2011

Subsystems (4)
lore
Share & tools
lore

Andy Green

author
#0 lore raw

cover USB: async platform_data support for usb and usbnet

The following series allows usb probe to benefit from the proposed async platform_data API described here

http://marc.info/?l=linux-kernel&m=129996915023642&w=2

It causes the usb host core system to bind to any registered async platform data that matches the device path of the device automatically, and in addition adds platform data to usbnet and causes it to take notice of the plaform data settings during init, allowing override of usb%d vs eth%d naming convention and actual MAC address from the board definition file.

---

Andy Green (3):
USBNET: Use usbnet platform data if it is present
USBNET: Introduce usbnet platform data
USB HOST CORE:probed devices collect any platform_data waiting for them

 drivers/net/usb/usbnet.c   |   23 +++++++++++++++++------
 drivers/usb/core/usb.c     |    3 +++
 include/linux/usb/usbnet.h |    8 ++++++++
 3 files changed, 28 insertions(+), 6 deletions(-)
Signature · 1 line
Signature
author
#1 lore raw

RFC PATCH 1/3 USB HOST CORE:probed devices collect any platform_data waiting for them

This causes all usb devices created during USB probe to check with the aysnc platform_data api to see if they should get tagged with waiting platform data based on their device path.

---

 drivers/usb/core/usb.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
drivers/usb/core/usb.c +3 -0
index 079cb57..03d9049 100644
@@ -36,6 +36,7 @@
 #include <linux/mutex.h>
 #include <linux/workqueue.h>
 #include <linux/debugfs.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <linux/scatterlist.h>
@@ -444,6 +445,8 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
 	dev->parent = parent;
 	INIT_LIST_HEAD(&dev->filelist);
 
+	platform_async_platform_data_attach(&dev->dev);
+
 #ifdef	CONFIG_PM
 	pm_runtime_set_autosuspend_delay(&dev->dev,
 			usb_autosuspend_delay * 1000);
author
#2 lore raw

RFC PATCH 2/3 USBNET: Introduce usbnet platform data

In reply to Andy Green

This defines optional platform_data for usbnet. It allows you to force eth%d name usage based on board-level knowledge that it is soldered to a board and wired to an RJ45 on the board, and to set the MAC address to a specific value from board definition file.

---

 include/linux/usb/usbnet.h |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)
include/linux/usb/usbnet.h +8 -0
index 44842c8..ad6ad94 100644
@@ -195,6 +195,14 @@ struct skb_data {	/* skb->cb is one of these */
 	size_t			length;
 };
 
+#define USBNET_PLATDATA_FLAG__FORCE_ETH_IFNAME BIT(0)
+#define USBNET_PLATDATA_FLAG__USE_MAC BIT(1)
+
+struct usbnet_platform_data {
+	u8 mac[ETH_ALEN];
+	u32 flags;
+};
+
 extern int usbnet_open(struct net_device *net);
 extern int usbnet_stop(struct net_device *net);
 extern netdev_tx_t usbnet_start_xmit(struct sk_buff *skb,
author
#3 lore raw

RFC PATCH 3/3 USBNET: Use usbnet platform data if it is present

In reply to Andy Green

This enables usbnet to actually use the two features it now supports via platform_data, if that has been set up by the board definition file.

---

 drivers/net/usb/usbnet.c |   23 +++++++++++++++++------
 1 files changed, 17 insertions(+), 6 deletions(-)
drivers/net/usb/usbnet.c +17 -6
index 95c41d5..5a5da74 100644
@@ -1293,6 +1293,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 	int				status;
 	const char			*name;
 	struct usb_driver 	*driver = to_usb_driver(udev->dev.driver);
+	struct usbnet_platform_data	*pdata;
 
 	/* usbnet already took usb runtime pm, so have to enable the feature
 	 * for usb interface, otherwise usb_autopm_get_interface may return
@@ -1313,6 +1314,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 	interface = udev->cur_altsetting;
 
 	usb_get_dev (xdev);
+	pdata = xdev->dev.platform_data;
 
 	status = -ENOMEM;
 
@@ -1348,7 +1350,10 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 
 	dev->net = net;
 	strcpy (net->name, "usb%d");
-	memcpy (net->dev_addr, node_id, sizeof node_id);
+	if (pdata && pdata->flags & USBNET_PLATDATA_FLAG__USE_MAC)
+		memcpy(net->dev_addr, pdata->mac, sizeof pdata->mac);
+	else
+		memcpy(net->dev_addr, node_id, sizeof node_id);
 
 	/* rx and tx sides can use different message sizes;
 	 * bind() should set rx_urb_size in that case.
@@ -1372,11 +1377,17 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 		if (status < 0)
 			goto out1;
 
-		// heuristic:  "usb%d" for links we know are two-host,
-		// else "eth%d" when there's reasonable doubt.  userspace
-		// can rename the link if it knows better.
-		if ((dev->driver_info->flags & FLAG_ETHER) != 0 &&
-		    (net->dev_addr [0] & 0x02) == 0)
+		/*
+		 * heuristic:  "usb%d" for links we know are two-host,
+		 * else "eth%d" when there's reasonable doubt.  userspace
+		 * can rename the link if it knows better.  Async
+		 * platform_data can also override this if it knows better
+		 * based on knowledge of what this link is wired up to.
+		 */
+		if ((((dev->driver_info->flags & FLAG_ETHER) != 0 &&
+		    (net->dev_addr[0] & 0x02) == 0)) ||
+		    (pdata && pdata->flags &
+					USBNET_PLATDATA_FLAG__FORCE_ETH_IFNAME))
 			strcpy (net->name, "eth%d");
 		/* WLAN devices should always be named "wlan%d" */
 		if ((dev->driver_info->flags & FLAG_WLAN) != 0)