Skip to contentSkip to conversation

Patch to option HSO driver to the kernel

RFC Applied Greg KH 14 participants 54 messages Apr 14, 2008 – Apr 21, 2008 21 messages not in the archive

Subsystems (4)
lore
Share & tools
lore

Greg KH

author
#0 lore raw

RFC 1/1 Patch to option HSO driver to the kernel

Hi all,

Here's a patch that I have cleaned up for context only from Option that is a USB serial / network device all in one.

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

Filip, can you send me some better information for the Kconfig text talking about what devices this driver is for, and any other information you wish to show there?

thanks,

greg k-h

-----------
Subject: USB: add option hso driver

This driver is for a number of different Option devices.

TODO:
- review tty layer interface
- review USB interfaces
- remove proc files and move to debugfs
- review network interfaces
- add better changelog information

Cc Andrew Bird <ajb-5+cxppFmGx6/3pe1ocb+s/[email protected]>
Cc Alan Cox <alan-qBU/[email protected]>
Cc Filip Aben <[email protected]>
Cc Paulius Zaleckas <[email protected]>
---
 drivers/net/usb/Kconfig  |   10 
 drivers/net/usb/Makefile |    1 
 drivers/net/usb/hso.c    | 3349 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 3360 insertions(+)
 create mode 100644 drivers/net/usb/hso.c
drivers/net/usb/Kconfig +10 -0
@@ -154,6 +154,16 @@ config USB_NET_AX8817X
 	  This driver creates an interface named "ethX", where X depends on
 	  what other networking devices you have in use.
 
+config USB_HSO
+	tristate "Option USB High Speed Mobile Devices"
+	depends on USB
+	default n
+	help
+	  Choose this option if you have an Option High Speed Mobile
+	  device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called hso.
 
 config USB_NET_CDCETHER
 	tristate "CDC Ethernet support (smart devices such as cable modems)"
drivers/net/usb/Makefile +1 -0
@@ -6,6 +6,7 @@ obj-$(CONFIG_USB_CATC)		+= catc.o
 obj-$(CONFIG_USB_KAWETH)	+= kaweth.o
 obj-$(CONFIG_USB_PEGASUS)	+= pegasus.o
 obj-$(CONFIG_USB_RTL8150)	+= rtl8150.o
+obj-$(CONFIG_USB_HSO)		+= hso.o
 obj-$(CONFIG_USB_NET_AX8817X)	+= asix.o
 obj-$(CONFIG_USB_NET_CDCETHER)	+= cdc_ether.o
 obj-$(CONFIG_USB_NET_DM9601)	+= dm9601.o
drivers/net/usb/hso.c new file +3349 -0

2,977 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

Part of the diff is not shown here. View the raw message.

A message that is not in the archive (sent off-list or not yet received): [email protected]

#2 lore raw

I will be the first to admit that I'm picking a nit here, but...

drivers/net/usb/Kconfig config USB_NET_AX8817X

Quoted 8 lines · Greg KH

Subject: USB: add option hso driver

drivers/net/usb/Kconfig +4 -0
+config USB_HSO
+	tristate "Option USB High Speed Mobile Devices"
 
+ * Driver for Option High Speed Mobile Devices.
 
+#define MOD_DESCRIPTION			"USB High Speed Option driver"

Would it be possible to pick one of "High Speed Option" and "Option... High Speed" and then be consistent with the acronym of "hso" or "ohs"? Or maybe call it "option_hs" or something even more clear?

Mixing them just makes it more difficult for people to use grep and google.

Matt

Signature · 7 lines
Matthew Dharm                              Home: [email protected] 
Maintainer, Linux USB Mass Storage Driver

DP: And judging from the scores, Stef has the sma...  
T:  LET'S NOT GO THERE!
					-- Dust Puppy and Tanya
User Friendly, 12/11/1997
#3 lore raw

Hi Matthew,
I'd prefer the keep it as just 'hso' and change the textual description if
necessary. I think module names are just arbitrary, and should not necessarily reflect the original usage too well, otherwise you end up with a situation like with the 'option' module. That module is now used for many devices from differing manufacturers and it doesn't really make much sense to load the option module to service a device from Novatel, Sierra Wireless or Huawei.

Just my two pence,

Andrew

Quoted 19 lines · Matthew Dharm

I will be the first to admit that I'm picking a nit here, but...

drivers/net/usb/Kconfig config USB_NET_AX8817X

Quoted 8 lines · Greg KH

Subject: USB: add option hso driver

drivers/net/usb/Kconfig +4 -0
+config USB_HSO
+	tristate "Option USB High Speed Mobile Devices"
 
+ * Driver for Option High Speed Mobile Devices.
 
+#define MOD_DESCRIPTION			"USB High Speed Option driver"

Would it be possible to pick one of "High Speed Option" and "Option... High Speed" and then be consistent with the acronym of "hso" or "ohs"? Or maybe call it "option_hs" or something even more clear?

Mixing them just makes it more difficult for people to use grep and google.

Matt

#4 lore raw
Quoted 8 lines · Andrew Bird (Sphere Systems)

Hi Matthew,
I'd prefer the keep it as just 'hso' and change the textual description if
necessary. I think module names are just arbitrary, and should not necessarily reflect the original usage too well, otherwise you end up with a situation like with the 'option' module. That module is now used for many devices from differing manufacturers and it doesn't really make much sense to load the option module to service a device from Novatel, Sierra Wireless or Huawei.

Ok, that's fine with me, what should we use for the text in the driver and the Kconfig entry?

thanks,

greg k-h

A message that is not in the archive (sent off-list or not yet received): [email protected]

#6 lore raw

"
This driver is used for Option HSDPA/HSUPA cards that support downlink speeds of 7.2Mbps or greater.
"

How does that sound ?

Regards,

Filip-

Quoted 10 lines · Greg KH
Quoted 8 lines · Andrew Bird (Sphere Systems)

Hi Matthew,
I'd prefer the keep it as just 'hso' and change the textual description if
necessary. I think module names are just arbitrary, and should not necessarily reflect the original usage too well, otherwise you end up with a situation like with the 'option' module. That module is now used for many devices from differing manufacturers and it doesn't really make much sense to load the option module to service a device from Novatel, Sierra Wireless or Huawei.

Quoted 7 lines

Ok, that's fine with me, what should we use for the text in the driver and the Kconfig entry?

thanks,

greg k-h

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#7 lore raw
Quoted 7 lines · Filip Aben

"
This driver is used for Option HSDPA/HSUPA cards that support downlink speeds of 7.2Mbps or greater.
"

How does that sound ?

Sounds good, I've updated the Kconfig entry with it.

thanks,

greg k-h

#8 lore raw
In reply to a message not in the archive
Quoted 2 lines · Greg KH

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

In attached patch I have rewrote MAC address generation to simple call to random_ether_addr instead of some mysterious pointer parsing :)

Paulius

ldp/usb-add-option-hso-driver.patch +7 -13
index 429f9c9..7360e04 100644
@@ -56,7 +56,7 @@ Signed-off-by: Greg Kroah-Hartman <[email protected]>
  obj-$(CONFIG_USB_NET_DM9601)	+= dm9601.o
 --- /dev/null
 +++ b/drivers/net/usb/hso.c
-@@ -0,0 +1,3349 @@
+@@ -0,0 +1,3343 @@
 +/******************************************************************************
 + *
 + * Driver for Option High Speed Mobile Devices.
@@ -1523,7 +1523,7 @@ Signed-off-by: Greg Kroah-Hartman <[email protected]>
 +	return 0;
 +}
 +
-+/* Toggles radioon or off ( used by ioctl ) */
++/* Toggles radio on or off ( used by ioctl ) */
 +static int hso_set_radio(struct hso_device *hso_dev, int enabled)
 +{
 +	if (!hso_dev)
@@ -2350,7 +2350,7 @@ Signed-off-by: Greg Kroah-Hartman <[email protected]>
 +	spin_lock_init(&serial->serial_lock);
 +	serial->num_rx_urbs = num_urbs;
 +
-+	/* RX , allocate urb and initialize */
++	/* RX, allocate urb and initialize */
 +
 +	/* prepare our RX buffer */
 +	serial->rx_data_length = rx_size;
@@ -2370,7 +2370,7 @@ Signed-off-by: Greg Kroah-Hartman <[email protected]>
 +		}
 +	}
 +
-+	/* TX , allocate urb and initialize */
++	/* TX, allocate urb and initialize */
 +	serial->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
 +	if (!serial->tx_urb) {
 +		dev_err(dev, "Could not allocate urb?\n");
@@ -3190,14 +3190,8 @@ Signed-off-by: Greg Kroah-Hartman <[email protected]>
 +	unsigned char buffer[13];
 +	unsigned char checkserial[7] = "Serial";
 +
-+	/* we can't fail, therefor we use a default macaddress (constructed
-+	 * from the pointer of our struct) */
-+	mac_addr[0] = 0x00;
-+	mac_addr[1] = 0x03;
-+	mac_addr[2] = (unsigned char)(((unsigned long)odev) & 0xFF);
-+	mac_addr[3] = (unsigned char)((((unsigned long)odev) >> 8) & 0xFF);
-+	mac_addr[4] = (unsigned char)((((unsigned long)odev) >> 16) & 0xFF);
-+	mac_addr[5] = (unsigned char)((((unsigned long)odev) >> 24) & 0xFF);
++	/* we can't fail, therefor we use a random macaddress */
++	random_ether_addr(mac_addr);
 +	dummy_mac[0] = 0xFA;
 +	dummy_mac[1] = mac_addr[1];
 +	dummy_mac[2] = mac_addr[2];
@@ -3233,7 +3227,7 @@ Signed-off-by: Greg Kroah-Hartman <[email protected]>
 +		}
 +	} else {
 +		dev_err(&odev->parent->usb->dev, "Attempting to get MAC "
-+			"address failed: using default\n");
++			"address failed: using random\n");
 +	}
 +
 +	/* Now copy it over to our network device structure */
#9 lore raw

Am Dienstag, 15. April 2008 01:20:51 schrieb Paulius Zaleckas:

Quoted 6 lines
Quoted 2 lines · Greg KH

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

In attached patch I have rewrote MAC address generation to simple call to random_ether_addr instead of some mysterious pointer parsing :)

Could you please generate a kernel patch, not a patch against a patch? I have difficulties dealing with that.

Regards
Oliver
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 200804151010.33688.oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org

#11 lore raw
Quoted 2 lines · Oliver Neukum

Could you please generate a kernel patch, not a patch against a patch? I have difficulties dealing with that.

OK. Here it goes.

Paulius

drivers/net/usb/hso.c +6 -12
@@ -1464,7 +1464,7 @@ static int hso_set_suspend(struct hso_de
 	return 0;
 }
 
-/* Toggles radioon or off ( used by ioctl ) */
+/* Toggles radio on or off ( used by ioctl ) */
 static int hso_set_radio(struct hso_device *hso_dev, int enabled)
 {
 	if (!hso_dev)
@@ -2291,7 +2291,7 @@ static int hso_serial_common_create(stru
 	spin_lock_init(&serial->serial_lock);
 	serial->num_rx_urbs = num_urbs;
 
-	/* RX , allocate urb and initialize */
+	/* RX, allocate urb and initialize */
 
 	/* prepare our RX buffer */
 	serial->rx_data_length = rx_size;
@@ -2311,7 +2311,7 @@ static int hso_serial_common_create(stru
 		}
 	}
 
-	/* TX , allocate urb and initialize */
+	/* TX, allocate urb and initialize */
 	serial->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!serial->tx_urb) {
 		dev_err(dev, "Could not allocate urb?\n");
@@ -3131,14 +3131,8 @@ static void set_ethernet_addr(struct hso
 	unsigned char buffer[13];
 	unsigned char checkserial[7] = "Serial";
 
-	/* we can't fail, therefor we use a default macaddress (constructed
-	 * from the pointer of our struct) */
-	mac_addr[0] = 0x00;
-	mac_addr[1] = 0x03;
-	mac_addr[2] = (unsigned char)(((unsigned long)odev) & 0xFF);
-	mac_addr[3] = (unsigned char)((((unsigned long)odev) >> 8) & 0xFF);
-	mac_addr[4] = (unsigned char)((((unsigned long)odev) >> 16) & 0xFF);
-	mac_addr[5] = (unsigned char)((((unsigned long)odev) >> 24) & 0xFF);
+	/* we can't fail, therefor we use a random macaddress */
+	random_ether_addr(mac_addr);
 	dummy_mac[0] = 0xFA;
 	dummy_mac[1] = mac_addr[1];
 	dummy_mac[2] = mac_addr[2];
@@ -3174,7 +3168,7 @@ static void set_ethernet_addr(struct hso
 		}
 	} else {
 		dev_err(&odev->parent->usb->dev, "Attempting to get MAC "
-			"address failed: using default\n");
+			"address failed: using random\n");
 	}
 
 	/* Now copy it over to our network device structure */

A message that is not in the archive (sent off-list or not yet received): [email protected]

author
#13 lore raw
Quoted 5 lines · Paulius Zaleckas
Quoted 2 lines · Oliver Neukum

Could you please generate a kernel patch, not a patch against a patch? I have difficulties dealing with that.

OK. Here it goes.

Thanks, I've merged these changes in.

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#14 lore raw
In reply to a message not in the archive

Am Montag, 14. April 2008 23:32:39 schrieb Greg KH:

Quoted 7 lines

Hi all,

Here's a patch that I have cleaned up for context only from Option that is a USB serial / network device all in one.

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

Hi,

this patch against Greg's version with Pauliaus patch applied

- uses correct CDC includes and constants
- fixes a race between disconnect and open
- fixes a race between probe and open
- corrects incorrect uses of GFP_KERNEL
- adds some error handling in open
- fixes races in access to urb->status

There's still a race condition in the write path left and the autosuspend handling is broken in extremely interesting ways. The next patch will fix these and I am still doing further reviews.

Regards
Oliver

---

drivers/net/usb/hso.c +59 -76
@@ -60,6 +60,7 @@
 #include <linux/ip.h>
 #include <linux/proc_fs.h>
 #include <linux/uaccess.h>
+#include <linux/usb/cdc.h>
 #include <net/arp.h>
 #include <asm/byteorder.h>
 
@@ -94,25 +95,10 @@
 
 #define	HSO_NET_TX_TIMEOUT		(HZ*10)
 
-#define SEND_ENCAPSULATED_COMMAND	0x00
-#define GET_ENCAPSULATED_RESPONSE	0x01
-
 /* Serial port defines and structs. */
 #define HSO_THRESHOLD_THROTTLE		(7*1024)
 #define HSO_THRESHOLD_UNTHROTTLE	(2*1024)
 
-/* These definitions used in the Ethernet Packet Filtering requests */
-/* See CDC Spec Table 62 */
-#define MODE_FLAG_PROMISCUOUS		(1<<0)
-#define MODE_FLAG_ALL_MULTICAST		(1<<1)
-#define MODE_FLAG_DIRECTED		(1<<2)
-#define MODE_FLAG_BROADCAST		(1<<3)
-#define MODE_FLAG_MULTICAST		(1<<4)
-
-/* CDC Spec class requests - CDC Spec Table 46 */
-#define SET_ETHERNET_MULTICAST_FILTER	0x40
-#define SET_ETHERNET_PACKET_FILTER	0x43
-
 #define HSO_SERIAL_FLAG_THROTTLED	0
 #define HSO_SERIAL_FLAG_TX_SENT		1
 #define HSO_SERIAL_FLAG_RX_SENT		2
@@ -262,6 +248,7 @@ struct hso_device {
 
 	struct device *dev;
 	struct kref ref;
+	struct mutex mutex;
 
 	/* TODO: Not sure about the ones below */
 	struct proc_dir_entry *ourproc;
@@ -339,7 +326,7 @@ static struct usb_endpoint_descriptor *h
 						  int type, int dir);
 static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports);
 static void hso_free_interface(struct usb_interface *intf);
-static int hso_start_serial_device(struct hso_device *hso_dev);
+static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags);
 static int hso_stop_serial_device(struct hso_device *hso_dev);
 static int hso_start_net_device(struct hso_device *hso_dev);
 static void hso_free_shared_int(struct hso_shared_int *shared_int);
@@ -655,12 +642,12 @@ static int hso_net_open(struct net_devic
 
 	hso_start_net_device(odev->parent);
 
-	/* Tell the kernel we are ready to start receiving from it */
-	netif_start_queue(net);
-
 	/* We are up and running. */
 	set_bit(HSO_NET_RUNNING, &odev->flags);
 
+	/* Tell the kernel we are ready to start receiving from it */
+	netif_start_queue(net);
+
 	return 0;
 }
 
@@ -669,10 +656,10 @@ static int hso_net_close(struct net_devi
 {
 	struct hso_net *odev = netdev_priv(net);
 
-	/* no longer running */
-	clear_bit(HSO_NET_RUNNING, &odev->flags);
 	/* we don't need the queue anymore */
 	netif_stop_queue(net);
+	/* no longer running */
+	clear_bit(HSO_NET_RUNNING, &odev->flags);
 
 	hso_stop_net_device(odev->parent);
 
@@ -834,34 +821,34 @@ static void hso_net_set_multicast(struct
 	if (net->flags & IFF_PROMISC) {
 		/* Unconditionally log net taps. */
 		D1("%s: Promiscuous mode enabled", net->name);
-		odev->mode_flags = MODE_FLAG_ALL_MULTICAST |
-				   MODE_FLAG_DIRECTED |
-				   MODE_FLAG_BROADCAST |
-				   MODE_FLAG_MULTICAST |
-				   MODE_FLAG_PROMISCUOUS;
+		odev->mode_flags = USB_CDC_PACKET_TYPE_ALL_MULTICAST |
+				   USB_CDC_PACKET_TYPE_DIRECTED |
+				   USB_CDC_PACKET_TYPE_BROADCAST |
+				   USB_CDC_PACKET_TYPE_MULTICAST |
+				   USB_CDC_PACKET_TYPE_PROMISCUOUS;
 	} else if (net->mc_count > odev->wNumberMCFilters) {
 		/* Too many to filter perfectly -- accept all multicasts. */
 		D1("%s: too many MC filters for hardware, using allmulti",
 		   net->name);
-		odev->mode_flags = MODE_FLAG_ALL_MULTICAST |
-				   MODE_FLAG_DIRECTED |
-				   MODE_FLAG_BROADCAST |
-				   MODE_FLAG_MULTICAST;
+		odev->mode_flags = USB_CDC_PACKET_TYPE_ALL_MULTICAST |
+				   USB_CDC_PACKET_TYPE_DIRECTED |
+				   USB_CDC_PACKET_TYPE_BROADCAST |
+				   USB_CDC_PACKET_TYPE_MULTICAST;
 	} else if (net->flags & IFF_ALLMULTI) {
 		/* Filter in software */
 		D1("%s: using allmulti", net->name);
-		odev->mode_flags = MODE_FLAG_ALL_MULTICAST |
-				   MODE_FLAG_DIRECTED |
-				   MODE_FLAG_BROADCAST |
-				   MODE_FLAG_MULTICAST;
+		odev->mode_flags = USB_CDC_PACKET_TYPE_ALL_MULTICAST |
+				   USB_CDC_PACKET_TYPE_DIRECTED |
+				   USB_CDC_PACKET_TYPE_BROADCAST |
+				   USB_CDC_PACKET_TYPE_MULTICAST;
 	} else {
 		/* do multicast filtering in hardware */
 		struct dev_mc_list *mclist;
 		D1("%s: set multicast filters", net->name);
-		odev->mode_flags = MODE_FLAG_ALL_MULTICAST |
-				   MODE_FLAG_DIRECTED |
-				   MODE_FLAG_BROADCAST |
-				   MODE_FLAG_MULTICAST;
+		odev->mode_flags = USB_CDC_PACKET_TYPE_ALL_MULTICAST |
+				   USB_CDC_PACKET_TYPE_DIRECTED |
+				   USB_CDC_PACKET_TYPE_BROADCAST |
+				   USB_CDC_PACKET_TYPE_MULTICAST;
 		buf = kmalloc(6 * net->mc_count, GFP_ATOMIC);
 		if (!buf) {
 			dev_err(&net->dev, "No memory to allocate?");
@@ -885,7 +872,6 @@ static void read_bulk_callback(struct ur
 	struct hso_net *odev = urb->context;
 	struct net_device *net = NULL;
 	int result = 0;
-	unsigned long flags = 0;
 	int status = urb->status;
 
 	/* is al ok?  (Filip: Who's Al ?) */
@@ -923,11 +909,11 @@ static void read_bulk_callback(struct ur
 	if (urb->actual_length) {
 		/* Handle the IP stream, add header and push it onto network
 		 * stack if the packet is complete. */
-		spin_lock_irqsave(&odev->net_lock, flags);
+		spin_lock(&odev->net_lock);
 		packetizeRx(odev, urb->transfer_buffer, urb->actual_length,
 			    (urb->transfer_buffer_length >
 			     urb->actual_length) ? 1 : 0);
-		spin_unlock_irqrestore(&odev->net_lock, flags);
+		spin_unlock(&odev->net_lock);
 	}
 
 	/* We are done with this URB, resubmit it. Prep the USB to wait for
@@ -1198,8 +1184,7 @@ static void _hso_serial_set_termios(stru
 static int hso_serial_open(struct tty_struct *tty, struct file *filp)
 {
 	struct hso_serial *serial = get_serial_by_index(tty->index);
-	int result = 0;
-	unsigned long flags;
+	int result;
 
 	/* sanity check */
 	if (serial == NULL || serial->magic != HSO_SERIAL_MAGIC) {
@@ -1208,12 +1193,12 @@ static int hso_serial_open(struct tty_st
 		return -ENODEV;
 	}
 
-	usb_autopm_get_interface(serial->parent->interface);
+	mutex_lock(&serial->parent->mutex);
+	result = usb_autopm_get_interface(serial->parent->interface);
+	if (result < 0)
+		goto err_out;
 
 	D1("Opening %d", serial->minor);
-	/* lock it down */
-	spin_lock_irqsave(&serial->serial_lock, flags);
-
 	kref_get(&serial->parent->ref);
 
 	/* setup */
@@ -1227,7 +1212,7 @@ static int hso_serial_open(struct tty_st
 		serial->flags = 0;
 		/* Force default termio settings */
 		_hso_serial_set_termios(tty, NULL);
-		result = hso_start_serial_device(serial->parent);
+		result = hso_start_serial_device(serial->parent, GFP_KERNEL);
 		if (result) {
 			hso_stop_serial_device(serial->parent);
 			serial->open_count--;
@@ -1237,13 +1222,13 @@ static int hso_serial_open(struct tty_st
 		D1("Port was already open");
 	}
 
-	spin_unlock_irqrestore(&serial->serial_lock, flags);
-
 	usb_autopm_put_interface(serial->parent->interface);
 
 	/* done */
 	if (result)
 		hso_serial_tiocmset(tty, NULL, TIOCM_RTS | TIOCM_DTR, 0);
+err_out:
+	mutex_unlock(&serial->parent->mutex);
 	return result;
 }
 
@@ -1251,7 +1236,6 @@ static int hso_serial_open(struct tty_st
 static void hso_serial_close(struct tty_struct *tty, struct file *filp)
 {
 	struct hso_serial *serial = tty->driver_data;
-	unsigned long flags;
 	u8 usb_gone;
 
 	D1("Closing serial port");
@@ -1262,6 +1246,7 @@ static void hso_serial_close(struct tty_
 		return;
 	}
 
+	mutex_lock(&serial->parent->mutex);
 	usb_gone = test_bit(HSO_SERIAL_USB_GONE, &serial->flags);
 
 	if (!usb_gone)
@@ -1269,7 +1254,6 @@ static void hso_serial_close(struct tty_
 
 	/* reset the rts and dtr */
 	/* do the actual close */
-	spin_lock_irqsave(&serial->serial_lock, flags);
 	serial->open_count--;
 	if (serial->open_count <= 0) {
 		kref_put(&serial->parent->ref, hso_serial_ref_free);
@@ -1281,11 +1265,9 @@ static void hso_serial_close(struct tty_
 		if (!usb_gone)
 			hso_stop_serial_device(serial->parent);
 	}
-	if (serial->open_count < 0)
-		serial->open_count = 0;
-	spin_unlock_irqrestore(&serial->serial_lock, flags);
 	if (!usb_gone)
 		usb_autopm_put_interface(serial->parent->interface);
+	mutex_unlock(&serial->parent->mutex);
 }
 
 /* close the requested serial port */
@@ -1639,24 +1621,24 @@ static int mux_device_request(struct hso
 	ctrl_req->wIndex = hso_port_to_mux(port);
 	ctrl_req->wLength = size;
 
-	if (type == GET_ENCAPSULATED_RESPONSE) {
+	if (type == USB_CDC_GET_ENCAPSULATED_RESPONSE) {
 		/* Reading command */
 		ctrl_req->bRequestType = USB_DIR_IN |
 					 USB_TYPE_OPTION_VENDOR |
 					 USB_RECIP_INTERFACE;
-		ctrl_req->bRequest = GET_ENCAPSULATED_RESPONSE;
+		ctrl_req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE;
 		pipe = usb_rcvctrlpipe(serial->parent->usb, 0);
 	} else {
 		/* Writing command */
 		ctrl_req->bRequestType = USB_DIR_OUT |
 					 USB_TYPE_OPTION_VENDOR |
 					 USB_RECIP_INTERFACE;
-		ctrl_req->bRequest = SEND_ENCAPSULATED_COMMAND;
+		ctrl_req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND;
 		pipe = usb_sndctrlpipe(serial->parent->usb, 0);
 	}
 	/* syslog */
 	D2("%s command (%02x) len: %d, port: %d",
-	   type == GET_ENCAPSULATED_RESPONSE ? "Read" : "Write",
+	   type == USB_CDC_GET_ENCAPSULATED_RESPONSE ? "Read" : "Write",
 	   ctrl_req->bRequestType, ctrl_req->wLength, port);
 
 	/* Load ctrl urb */
@@ -1696,7 +1678,7 @@ static int hso_mux_serial_read(struct hs
 		return 0;
 	}
 	return mux_device_request(serial,
-				  GET_ENCAPSULATED_RESPONSE,
+				  USB_CDC_GET_ENCAPSULATED_RESPONSE,
 				  serial->parent->port_spec & HSO_PORT_MASK,
 				  serial->rx_urb[0],
 				  &serial->ctrl_req_rx,
@@ -1759,7 +1741,7 @@ static int hso_mux_serial_write_data(str
 		return -EINVAL;
 
 	return mux_device_request(serial,
-				  SEND_ENCAPSULATED_COMMAND,
+				  USB_CDC_SEND_ENCAPSULATED_COMMAND,
 				  serial->parent->port_spec & HSO_PORT_MASK,
 				  serial->tx_urb,
 				  &serial->ctrl_req_tx,
@@ -2145,20 +2127,17 @@ static int hso_stop_net_device(struct hs
 		return -ENODEV;
 
 	for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) {
-		if (hso_net->mux_bulk_rx_urb_pool[i]
-		    && (hso_net->mux_bulk_rx_urb_pool[i]->status ==
-			-EINPROGRESS))
-			usb_unlink_urb(hso_net->mux_bulk_rx_urb_pool[i]);
+		if (hso_net->mux_bulk_rx_urb_pool[i])
+			usb_kill_urb(hso_net->mux_bulk_rx_urb_pool[i]);
 
 	}
-	if (hso_net->mux_bulk_tx_urb
-	    && (hso_net->mux_bulk_tx_urb->status == -EINPROGRESS))
-		usb_unlink_urb(hso_net->mux_bulk_tx_urb);
+	if (hso_net->mux_bulk_tx_urb)
+		usb_kill_urb(hso_net->mux_bulk_tx_urb);
 
 	return 0;
 }
 
-static int hso_start_serial_device(struct hso_device *hso_dev)
+static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags)
 {
 	int i, result = 0;
 	struct hso_serial *serial = dev2ser(hso_dev);
@@ -2180,7 +2159,7 @@ static int hso_start_serial_device(struc
 					  serial->rx_data_length,
 					  hso_std_serial_read_bulk_callback,
 					  serial);
-			result = usb_submit_urb(serial->rx_urb[i], GFP_KERNEL);
+			result = usb_submit_urb(serial->rx_urb[i], flags);
 			if (result) {
 				dev_warn(&serial->parent->usb->dev,
 					 "Failed to submit urb - res %d\n",
@@ -2361,6 +2340,7 @@ static struct hso_device *hso_create_dev
 	hso_dev->usb = interface_to_usbdev(intf);
 	hso_dev->interface = intf;
 	kref_init(&hso_dev->ref);
+	mutex_init(&hso_dev->mutex);
 
 	INIT_WORK(&hso_dev->async_get_intf, async_get_intf);
 	INIT_WORK(&hso_dev->async_put_intf, async_put_intf);
@@ -2959,7 +2939,7 @@ static int hso_resume(struct usb_interfa
 		if (serial_table[i] && (serial_table[i]->interface == iface)) {
 			if (dev2ser(serial_table[i])->open_count) {
 				result =
-				    hso_start_serial_device(serial_table[i]);
+				    hso_start_serial_device(serial_table[i], GFP_NOIO);
 				hso_kick_transmit(dev2ser(serial_table[i]));
 				if (result)
 					goto out;
@@ -2999,15 +2979,18 @@ static void hso_serial_ref_free(struct k
 
 static void hso_free_interface(struct usb_interface *interface)
 {
+	struct hso_serial *hso_dev;
 	int i;
 
 	for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
 		if (serial_table[i]
 		    && (serial_table[i]->interface == interface)) {
-			if (dev2ser(serial_table[i])->tty)
-				tty_hangup(dev2ser(serial_table[i])->tty);
-			set_bit(HSO_SERIAL_USB_GONE,
-				&dev2ser(serial_table[i])->flags);
+			hso_dev = dev2ser(serial_table[i]);
+			if (hso_dev->tty)
+				tty_hangup(hso_dev->tty);
+			mutex_lock(&hso_dev->parent->mutex);
+			set_bit(HSO_SERIAL_USB_GONE, &hso_dev->flags);
+			mutex_unlock(&hso_dev->parent->mutex);
 			kref_put(&serial_table[i]->ref, hso_serial_ref_free);
 		}
 	}
@@ -3069,7 +3052,7 @@ static int hso_get_mux_ports(struct usb_
 static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int,
 				   struct usb_device *usb, gfp_t gfp)
 {
-	int result = 0;
+	int result;
 
 	usb_fill_int_urb(shared_int->shared_intr_urb, usb,
 			 usb_rcvintpipe(usb,

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 200804151344.42085.oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org

author
#16 lore raw
Quoted 20 lines · Oliver Neukum

Am Montag, 14. April 2008 23:32:39 schrieb Greg KH:

Quoted 7 lines

Hi all,

Here's a patch that I have cleaned up for context only from Option that is a USB serial / network device all in one.

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

Hi,

this patch against Greg's version with Pauliaus patch applied

- uses correct CDC includes and constants
- fixes a race between disconnect and open
- fixes a race between probe and open
- corrects incorrect uses of GFP_KERNEL
- adds some error handling in open
- fixes races in access to urb->status

Quoted 3 lines

There's still a race condition in the write path left and the autosuspend handling is broken in extremely interesting ways. The next patch will fix these and I am still doing further reviews.

Thanks a lot for these changes, I've applied them to the driver.

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#17 lore raw
In reply to a message not in the archive

Am Montag, 14. April 2008 23:32:39 schrieb Greg KH:

Quoted 7 lines

Hi all,

Here's a patch that I have cleaned up for context only from Option that is a USB serial / network device all in one.

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

This incremental patch fixes a race where write can mess with an URB while it isn't yet returned.

Regards
Oliver

---

drivers/net/usb/hso.c renamed from drivers/net/usb/hso.c.alt +15 -4
@@ -220,6 +220,7 @@ struct hso_serial {
 	unsigned long flags;
 	u8 rts_state;
 	u8 dtr_state;
+	int tx_urb_used:1;
 
 	/* from usb_serial_port */
 	struct tty_struct *tty;
@@ -1521,12 +1522,13 @@ static void hso_kick_transmit(struct hso
 {
 	u8 *temp = NULL;
 	unsigned long flags;
+	int res;
 
 	spin_lock_irqsave(&serial->serial_lock, flags);
 	if (!serial->tx_buffer_count)
 		goto out;
 
-	if (serial->tx_urb->status == -EINPROGRESS)
+	if (serial->tx_urb_used)
 		goto out;
 
 	/* Wakeup USB interface if necessary */
@@ -1540,10 +1542,13 @@ static void hso_kick_transmit(struct hso
 	serial->tx_data_count = serial->tx_buffer_count;
 	serial->tx_buffer_count = 0;
 
-out:
 	/* If temp is set, it means we switched buffers */
-	if (temp && serial->write_data)
-		serial->write_data(serial);
+	if (temp && serial->write_data) {
+		res = serial->write_data(serial);
+		if (res >= 0)
+			serial->tx_urb_used = 1;
+	}
+out:
 	spin_unlock_irqrestore(&serial->serial_lock, flags);
 }
 
@@ -1783,6 +1788,9 @@ static void ctrl_callback(struct urb *ur
 	if (!serial)
 		return;
 
+	spin_lock(&serial->serial_lock);
+	serial->tx_urb_used = 0;
+	spin_unlock(&serial->serial_lock);
 	if (status) {
 		log_usb_status(status, __func__);
 		return;
@@ -1914,6 +1922,9 @@ static void hso_std_serial_write_bulk_ca
 		return;
 	}
 
+	spin_lock(&serial->serial_lock);
+	serial->tx_urb_used = 0;
+	spin_unlock(&serial->serial_lock);
 	if (status) {
 		log_usb_status(status, __func__);
 		return;

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 200804151506.21856.oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org

author
#19 lore raw

drivers/net/usb/hso.c struct hso_serial { · line 223

Quoted 7 lines · Oliver Neukum
drivers/net/usb/hso.c renamed from drivers/net/usb/hso.c.alt +1 -0
@@ -220,6 +220,7 @@ struct hso_serial {
 	unsigned long flags;
 	u8 rts_state;
 	u8 dtr_state;
+	int tx_urb_used:1;

Bitfields should be "unsigned", I've changed this so sparse does not complain.

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

Applied
#20 lore raw
In reply to Oliver Neukum
Quoted 9 lines · Oliver Neukum

Am Montag, 14. April 2008 23:32:39 schrieb Greg KH:

Quoted 7 lines

Hi all,

Here's a patch that I have cleaned up for context only from Option that is a USB serial / network device all in one.

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

Quoted 7 lines

This incremental patch fixes a race where write can mess with an URB while it isn't yet returned.

Regards
Oliver

Applied to the driver, thanks.

greg k-h

#21 lore raw
In reply to a message not in the archive

Am Montag, 14. April 2008 23:32:39 schrieb Greg KH:

Quoted 7 lines

Hi all,

Here's a patch that I have cleaned up for context only from Option that is a USB serial / network device all in one.

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

The driver implements an ioctl to disable autosuspend. This seems unnecessary to me, as you can do that via sysfs, too. Is this included to work around permission problems? Can somebody explain?

Regards
Oliver

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#22 lore raw
Quoted 9 lines · Oliver Neukum

Am Montag, 14. April 2008 23:32:39 schrieb Greg KH:

Quoted 7 lines

Hi all,

Here's a patch that I have cleaned up for context only from Option that is a USB serial / network device all in one.

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

Quoted 6 lines

The driver implements an ioctl to disable autosuspend. This seems unnecessary to me, as you can do that via sysfs, too. Is this included to work around permission problems? Can somebody explain?

Regards
Oliver

This is added to support card firmware upgraders who will need to disable suspend, even on (embedded) systems that don't have sysfs mounted.

Regards,

Filip-

#23 lore raw

Am Dienstag, 15. April 2008 16:12:22 schrieb Filip Aben:

Quoted 15 lines · Oliver Neukum
Quoted 13 lines

Am Montag, 14. April 2008 23:32:39 schrieb Greg KH:

Quoted 7 lines

Hi all,

Here's a patch that I have cleaned up for context only from Option that is a USB serial / network device all in one.

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

The driver implements an ioctl to disable autosuspend. This seems unnecessary to me, as you can do that via sysfs, too. Is this included to work around permission problems? Can somebody explain?

Quoted 6 lines
Quoted 2 lines

Regards
Oliver

This is added to support card firmware upgraders who will need to disable suspend, even on (embedded) systems that don't have sysfs mounted.

How do they enable autosuspend without sysfs?

Regards
Oliver

#24 lore raw
Quoted 16 lines · Oliver Neukum

Am Dienstag, 15. April 2008 16:12:22 schrieb Filip Aben:

Quoted 15 lines · Oliver Neukum
Quoted 13 lines

Am Montag, 14. April 2008 23:32:39 schrieb Greg KH:

Quoted 7 lines

Hi all,

Here's a patch that I have cleaned up for context only from Option that is a USB serial / network device all in one.

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

The driver implements an ioctl to disable autosuspend. This seems unnecessary to me, as you can do that via sysfs, too. Is this included to work around permission problems? Can somebody explain?

Quoted 8 lines
Quoted 6 lines
Quoted 2 lines

Regards
Oliver

This is added to support card firmware upgraders who will need to disable suspend, even on (embedded) systems that don't have sysfs mounted.

How do they enable autosuspend without sysfs?

Good point. No idea. I suppose it's easier to rely on something that will always work, rather then making assumptions about suspend based on whether sysfs is mounted or not.

( Wasn't there a kernel recently that had autosuspend enabled by default ? )

Regards,

Filip-

author
#25 lore raw
Quoted 25 lines · Filip Aben
Quoted 23 lines · Oliver Neukum

Am Dienstag, 15. April 2008 16:12:22 schrieb Filip Aben:

Quoted 21 lines · Oliver Neukum
Quoted 9 lines

Am Montag, 14. April 2008 23:32:39 schrieb Greg KH:

Quoted 7 lines

Hi all,

Here's a patch that I have cleaned up for context only from Option that is a USB serial / network device all in one.

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

Quoted 6 lines

The driver implements an ioctl to disable autosuspend. This seems unnecessary to me, as you can do that via sysfs, too. Is this included to work around permission problems? Can somebody explain?

Regards
Oliver

This is added to support card firmware upgraders who will need to disable suspend, even on (embedded) systems that don't have sysfs mounted.

Quoted 5 lines
Quoted 1 line

How do they enable autosuspend without sysfs?

Good point. No idea. I suppose it's easier to rely on something that will always work, rather then making assumptions about suspend based on whether sysfs is mounted or not.

Like I always like to point out, my _phone_ has sysfs mounted, I really doubt any 2.6 embedded system would not have it mounted these days, it is very useful for things like this.

So I'll go delete that "special" ioctl, that's not a good thing to do, use the common interfaces that all USB devices rely on instead, don't do something different for just one type of USB device.

I'm also a bit concerned about the special "set radio" ioctl as well. Filip, what uses that ioctl? If it's really necessary, can't a sysfs file do the same thing?

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): [email protected]

#27 lore raw
Quoted 32 lines · Greg KH
Quoted 25 lines · Filip Aben
Quoted 23 lines · Oliver Neukum

Am Dienstag, 15. April 2008 16:12:22 schrieb Filip Aben:

Quoted 21 lines · Oliver Neukum
Quoted 9 lines

Am Montag, 14. April 2008 23:32:39 schrieb Greg KH:

Quoted 7 lines

Hi all,

Here's a patch that I have cleaned up for context only from Option that is a USB serial / network device all in one.

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

Quoted 6 lines

The driver implements an ioctl to disable autosuspend. This seems unnecessary to me, as you can do that via sysfs, too. Is this included to work around permission problems? Can somebody explain?

Regards
Oliver

This is added to support card firmware upgraders who will need to disable suspend, even on (embedded) systems that don't have sysfs mounted.

Quoted 5 lines
Quoted 1 line

How do they enable autosuspend without sysfs?

Good point. No idea. I suppose it's easier to rely on something that will always work, rather then making assumptions about suspend based on whether sysfs is mounted or not.

Quoted 7 lines

Like I always like to point out, my _phone_ has sysfs mounted, I really doubt any 2.6 embedded system would not have it mounted these days, it is very useful for things like this.

So I'll go delete that "special" ioctl, that's not a good thing to do, use the common interfaces that all USB devices rely on instead, don't do something different for just one type of USB device.

Fair enough.

Quoted 4 lines

I'm also a bit concerned about the special "set radio" ioctl as well. Filip, what uses that ioctl? If it's really necessary, can't a sysfs file do the same thing?

Currently I don't think anybody uses it for Linux. I added it because our non-Linux drivers had this functionality. It's used for example by our connection managers/tools to disable the RF-part when the laptop goes to sleep ( but keeps the USB bus powered&suspended ). This is a requirement for quite some operators.
But yes, I suppose the same could be done through sysfs.

Regards,

Filip-
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#28 lore raw

Am Dienstag, 15. April 2008 18:24:48 schrieb Filip Aben:

Quoted 10 lines
Quoted 3 lines

I'm also a bit concerned about the special "set radio" ioctl as well. Filip, what uses that ioctl?  If it's really necessary, can't a sysfs file do the same thing?

Currently I don't think anybody uses it for Linux. I added it because our non-Linux drivers had this functionality. It's used for example by our connection managers/tools to disable the RF-part when the laptop goes to sleep ( but keeps the USB bus powered&suspended ). This is a requirement for quite some operators.
But yes, I suppose the same could be done through sysfs.

No, the correct way to do this is to support rfkill. I'll have a look at that.

Regards
Oliver

#29 lore raw
In reply to Greg KH

Am Dienstag, 15. April 2008 17:34:08 schrieb Greg KH:

Quoted 3 lines

So I'll go delete that "special" ioctl, that's not a good thing to do, use the common interfaces that all USB devices rely on instead, don't do something different for just one type of USB device.

Do you have a new unified patch? I'd work against that, lest we get merge troubles.

Regards
Oliver

A message that is not in the archive (sent off-list or not yet received): 200804152046.44018.oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org

author
#31 lore raw
Quoted 7 lines · Oliver Neukum

Am Dienstag, 15. April 2008 17:34:08 schrieb Greg KH:

Quoted 3 lines

So I'll go delete that "special" ioctl, that's not a good thing to do, use the common interfaces that all USB devices rely on instead, don't do something different for just one type of USB device.

Do you have a new unified patch? I'd work against that, lest we get merge troubles.

Good idea :)

Here it is.

thanks,

greg k-h

----------------

Subject: USB: add option hso driver

This driver is for a number of different Option devices. Originally written by Option and Andrew Bird, but cleaned up massivly for acceptance into mainline by me (Greg).

TODO:
- remove proc files and move to debugfs
- review network interfaces
- add better changelog information

Many thanks to the following for their help in cleaning up the driver by providing feedback and patches to it:
- Paulius Zaleckas <[email protected]>
- Oliver Neukum <[email protected]>
- Alan Cox <alan-qBU/[email protected]>

Cc Andrew Bird <ajb-5+cxppFmGx6/3pe1ocb+s/[email protected]>
Cc Alan Cox <alan-qBU/[email protected]>
Cc Filip Aben <[email protected]>
Cc Paulius Zaleckas <[email protected]>
Cc Oliver Neukum <[email protected]>
---
 drivers/net/usb/Kconfig  |   10 
 drivers/net/usb/Makefile |    1 
 drivers/net/usb/hso.c    | 3246 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 3257 insertions(+)
 create mode 100644 drivers/net/usb/hso.c
drivers/net/usb/Kconfig +10 -0
@@ -154,6 +154,16 @@ config USB_NET_AX8817X
 	  This driver creates an interface named "ethX", where X depends on
 	  what other networking devices you have in use.
 
+config USB_HSO
+	tristate "Option USB High Speed Mobile Devices"
+	depends on USB
+	default n
+	help
+	  Choose this option if you have an Option HSDPA/HSUPA card.
+	  These cards support downlink speeds of 7.2Mbps or greater.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called hso.
 
 config USB_NET_CDCETHER
 	tristate "CDC Ethernet support (smart devices such as cable modems)"
drivers/net/usb/Makefile +1 -0
@@ -6,6 +6,7 @@ obj-$(CONFIG_USB_CATC)		+= catc.o
 obj-$(CONFIG_USB_KAWETH)	+= kaweth.o
 obj-$(CONFIG_USB_PEGASUS)	+= pegasus.o
 obj-$(CONFIG_USB_RTL8150)	+= rtl8150.o
+obj-$(CONFIG_USB_HSO)		+= hso.o
 obj-$(CONFIG_USB_NET_AX8817X)	+= asix.o
 obj-$(CONFIG_USB_NET_CDCETHER)	+= cdc_ether.o
 obj-$(CONFIG_USB_NET_DM9601)	+= dm9601.o
drivers/net/usb/hso.c new file +3246 -0

2,977 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

Part of the diff is not shown here. View the raw message.

#32 lore raw
Quoted 21 lines · On Tue, 15 Apr 2008 12:00:30 -0700 Greg KH <[email protected]> wrote:
Quoted 7 lines · Oliver Neukum

Am Dienstag, 15. April 2008 17:34:08 schrieb Greg KH:

Quoted 3 lines

So I'll go delete that "special" ioctl, that's not a good thing to do, use the common interfaces that all USB devices rely on instead, don't do something different for just one type of USB device.

Do you have a new unified patch? I'd work against that, lest we get merge troubles.

Good idea :)

Here it is.

thanks,

greg k-h

----------------

Subject: USB: add option hso driver

Quoted 8 lines

This driver is for a number of different Option devices. Originally written by Option and Andrew Bird, but cleaned up massivly for acceptance into mainline by me (Greg).

TODO:
- remove proc files and move to debugfs
- review network interfaces
- add better changelog information

More work left:

- Use netif_msg_ for the message level rather than module parameter
- net_device_stats are now available in dev->stats
- use ethtool_ops rather than ioctl

#33 lore raw
Quoted 10 lines · Stephen Hemminger
Quoted 4 lines

TODO:
- remove proc files and move to debugfs
- review network interfaces
- add better changelog information

More work left:

- Use netif_msg_ for the message level rather than module parameter
- net_device_stats are now available in dev->stats
- use ethtool_ops rather than ioctl

Thanks, I've added them to the TODO list.

greg k-h

#34 lore raw
In reply to Greg KH

Am Dienstag, 15. April 2008 21:00:30 schrieb Greg KH:

Quoted 6 lines
Quoted 2 lines

Do you have a new unified patch? I'd work against that, lest we get merge troubles.

Good idea :)

Here it is.

Against that one.

Change GFP_KERNEL used in interrupt and resume() to GFP_ATOMIC, respectively GFP_NOIO

---

drivers/net/usb/hso.c +4 -4
@@ -1663,7 +1663,7 @@ static void intr_callback(struct urb *ur
 		}
 	}
 	/* Resubmit interrupt urb */
-	hso_mux_submit_intr_urb(shared_int, urb->dev, GFP_KERNEL);
+	hso_mux_submit_intr_urb(shared_int, urb->dev, GFP_ATOMIC);
 }
 
 /* called for writing to muxed serial port */
@@ -1694,7 +1694,7 @@ static int hso_std_serial_write_data(str
 			  serial->tx_data, serial->tx_data_count,
 			  hso_std_serial_write_bulk_callback, serial);
 
-	result = usb_submit_urb(serial->tx_urb, GFP_KERNEL);
+	result = usb_submit_urb(serial->tx_urb, GFP_ATOMIC);
 	if (result) {
 		dev_warn(&serial->parent->usb->dev,
 			 "Failed to submit urb - res %d\n", result);
@@ -2040,7 +2040,7 @@ static int hso_start_net_device(struct h
 
 		/* Put it out there so the device can send us stuff */
 		result = usb_submit_urb(hso_net->mux_bulk_rx_urb_pool[i],
-					GFP_KERNEL);
+					GFP_NOIO);
 		if (result)
 			dev_warn(&hso_dev->usb->dev,
 				"%s failed mux_bulk_rx_urb[%d] %d\n", __func__,
@@ -2104,7 +2104,7 @@ static int hso_start_serial_device(struc
 		if (!serial->shared_int->use_count) {
 			result =
 			    hso_mux_submit_intr_urb(serial->shared_int,
-						    hso_dev->usb, GFP_KERNEL);
+						    hso_dev->usb, GFP_ATOMIC);
 		}
 		serial->shared_int->use_count++;
 		spin_unlock_bh(&serial->shared_int->shared_int_lock);

A message that is not in the archive (sent off-list or not yet received): 200804152217.25451.oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org

author
#36 lore raw
Quoted 6 lines · Oliver Neukum

Am Dienstag, 15. April 2008 21:00:30 schrieb Greg KH:

Quoted 5 lines
Quoted 2 lines

Do you have a new unified patch? I'd work against that, lest we get merge troubles.

Good idea :)

Quoted 8 lines
Quoted 1 line

Here it is.

Against that one.

Change GFP_KERNEL used in interrupt and resume() to GFP_ATOMIC, respectively GFP_NOIO

Thanks, now applied.

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#37 lore raw
In reply to Greg KH

Am Dienstag, 15. April 2008 21:00:30 schrieb Greg KH:

Quoted 6 lines · Oliver Neukum
Quoted 5 lines

Am Dienstag, 15. April 2008 17:34:08 schrieb Greg KH:

Quoted 3 lines

So I'll go delete that "special" ioctl, that's not a good thing to do, use the common interfaces that all USB devices rely on instead, don't do something different for just one type of USB device.

Quoted 6 lines
Quoted 2 lines

Do you have a new unified patch? I'd work against that, lest we get merge troubles.

Good idea :)

Here it is.

Another one.

As autosuspend is by default disabled, it makes no sense to have a module parameter disabling it. Just don't enable it.

Regards
Oliver

---

drivers/net/usb/hso.c renamed from drivers/net/usb/hso.c.alt +0 -14
@@ -400,7 +400,6 @@ static int debug;
 static int procfs = 1;
 static int tty_major;
 static int disable_net;
-static int enable_autopm;
 
 /* driver info */
 static const char driver_name[] = "hso";
@@ -555,9 +554,6 @@ static int hso_proc_options(char *buf, c
 	len +=
 	    snprintf(buf + len, count - len, "tty_major: 0x%02x\n", tty_major);
 	len +=
-	    snprintf(buf + len, count - len, "enable_autopm: 0x%02x\n",
-		     enable_autopm);
-	len +=
 	    snprintf(buf + len, count - len, "disable_net: 0x%02x\n",
 		     disable_net);
 	return len;
@@ -2718,11 +2714,6 @@ static int hso_probe(struct usb_interfac
 	/* save our data pointer in this device */
 	usb_set_intfdata(interface, hso_dev);
 
-	if (enable_autopm == 0) {
-		usb_autopm_get_interface(hso_dev->interface);
-		hso_dev->suspend_disabled = 1;
-	}
-
 	/* done */
 	return 0;
 
@@ -3213,8 +3204,3 @@ module_param(tty_major, int, S_IRUGO | S
 /* set the major tty number (eg: insmod hso.ko tty_major=245) */
 MODULE_PARM_DESC(disable_net, "Disable the network interface");
 module_param(disable_net, int, S_IRUGO | S_IWUSR);
-
-/* enable autosuspend (default disabled) (eg: insmod hso.ko enable_autopm=1) */
-MODULE_PARM_DESC(enable_autopm,
-		 "Enable the auto power managment (autosuspend)");
-module_param(enable_autopm, int, S_IRUGO | S_IWUSR);
Applied
#38 lore raw
Quoted 10 lines · Oliver Neukum

Am Dienstag, 15. April 2008 21:00:30 schrieb Greg KH:

Quoted 9 lines · Oliver Neukum
Quoted 7 lines

Am Dienstag, 15. April 2008 17:34:08 schrieb Greg KH:

Quoted 3 lines

So I'll go delete that "special" ioctl, that's not a good thing to do, use the common interfaces that all USB devices rely on instead, don't do something different for just one type of USB device.

Do you have a new unified patch? I'd work against that, lest we get merge troubles.

Quoted 8 lines
Quoted 3 lines

Good idea :)

Here it is.

Another one.

As autosuspend is by default disabled, it makes no sense to have a module parameter disabling it. Just don't enable it.

Applied, thanks.

greg k-h

#39 lore raw
In reply to a message not in the archive

Reworked MAC address generation from USB serial number Now it is very similar to the one done in the cdc_ether.c

Filip: Does the dummy MAC address have to start with 0xFA?

drivers/net/usb/hso.c +7 -24
@@ -345,7 +345,6 @@ static int hso_get_activity(struct hso_d
 /* convert a character representing a hex value to a number */
 static unsigned char hex2dec(unsigned char digit)
 {
-
 	if ((digit >= '0') && (digit <= '9'))
 		return (digit - '0');
 	/* Map all characters to 0-15 */
@@ -353,7 +352,7 @@ static unsigned char hex2dec(unsigned ch
 		return (digit - 'a' + 10) % 16;
 	if ((digit >= 'A') && (digit <= 'Z'))
 		return (digit - 'A' + 10) % 16;
-	return 16;
+	return 0;
 }
 
 #define SIOCSETRADIO   (SIOCDEVPRIVATE+4)
@@ -3032,7 +3031,6 @@ static void set_ethernet_addr(struct hso
 	int i = 0;
 	int len = 0;
 	unsigned char buffer[13];
-	unsigned char checkserial[7] = "Serial";
 
 	/* we can't fail, therefor we use a random macaddress */
 	random_ether_addr(mac_addr);
@@ -3048,26 +3046,11 @@ static void set_ethernet_addr(struct hso
 	len = usb_string(odev->parent->usb,
 			 odev->parent->usb->descriptor.iSerialNumber,
 			 buffer, 13);
-	if (len != 12) {
-		/* some devices don't have the serial filled in, checking ... */
-		for (i = 0; i < 6; i++) {
-			if (buffer[i] != checkserial[i]) {
-				/* Fill in the mac_addr */
-				for (i = 2; i < 6; i++) {
-					if ((16 == buffer[2 * i]) ||
-					    (16 == buffer[2 * i + 1])) {
-						dev_err(&odev->parent->usb->dev,
-							"Bad value in MAC "
-							"address i:%d\n", i);
-					} else {
-						mac_addr[i] =
-						    (hex2dec(buffer[2 * i]) <<
-						     4) + hex2dec(buffer[2 * i +
-									 1]);
-					}
-				}
-				break;
-			}
+	if (len != 12 && strcmp("Serial", buffer)) {
+		/* Fill in the mac_addr */
+		for (i = 1; i < 6; i++) {
+			mac_addr[i] = (hex2dec(buffer[2 * i]) << 4) +
+				       hex2dec(buffer[2 * i + 1]);
 		}
 	} else {
 		dev_err(&odev->parent->usb->dev, "Attempting to get MAC "
@@ -3236,7 +3219,7 @@ module_param(debug, int, S_IRUGO | S_IWU
 MODULE_PARM_DESC(tty_major, "Set the major tty number");
 module_param(tty_major, int, S_IRUGO | S_IWUSR);
 
-/* set the major tty number (eg: insmod hso.ko tty_major=245) */
+/* disable network interface (eg: insmod hso.ko disable_net=1) */
 MODULE_PARM_DESC(disable_net, "Disable the network interface");
 module_param(disable_net, int, S_IRUGO | S_IWUSR);
 

A message that is not in the archive (sent off-list or not yet received): [email protected]

#41 lore raw
Quoted 5 lines · Paulius Zaleckas

Reworked MAC address generation from USB serial number Now it is very similar to the one done in the cdc_ether.c

Filip: Does the dummy MAC address have to start with 0xFA?

Hopefully fixed last bug in MAC address generation. Patch against latest Greg unified patch. Don't use my previous patch.

drivers/net/usb/hso.c +8 -23
@@ -315,7 +315,6 @@ static int hso_get_activity(struct hso_d
 /* convert a character representing a hex value to a number */
 static unsigned char hex2dec(unsigned char digit)
 {
-
 	if ((digit >= '0') && (digit <= '9'))
 		return (digit - '0');
 	/* Map all characters to 0-15 */
@@ -323,7 +322,7 @@ static unsigned char hex2dec(unsigned ch
 		return (digit - 'a' + 10) % 16;
 	if ((digit >= 'A') && (digit <= 'Z'))
 		return (digit - 'A' + 10) % 16;
-	return 16;
+	return 0;
 }
 
 #define SIOCSETRADIO   (SIOCDEVPRIVATE+4)
@@ -2308,7 +2307,6 @@ static void set_ethernet_addr(struct hso
 	int i = 0;
 	int len = 0;
 	unsigned char buffer[13];
-	unsigned char checkserial[7] = "Serial";
 
 	/* we can't fail, therefor we use a random macaddress */
 	random_ether_addr(mac_addr);
@@ -2324,27 +2322,14 @@ static void set_ethernet_addr(struct hso
 	len = usb_string(odev->parent->usb,
 			 odev->parent->usb->descriptor.iSerialNumber,
 			 buffer, 13);
-	if (len != 12) {
-		/* some devices don't have the serial filled in, checking ... */
+	if (len != 12 && strcmp("Serial", buffer)) {
+		/* Fill in the mac_addr */
 		for (i = 0; i < 6; i++) {
-			if (buffer[i] != checkserial[i]) {
-				/* Fill in the mac_addr */
-				for (i = 2; i < 6; i++) {
-					if ((16 == buffer[2 * i]) ||
-					    (16 == buffer[2 * i + 1])) {
-						dev_err(&odev->parent->usb->dev,
-							"Bad value in MAC "
-							"address i:%d\n", i);
-					} else {
-						mac_addr[i] =
-						    (hex2dec(buffer[2 * i]) <<
-						     4) + hex2dec(buffer[2 * i +
-									 1]);
-					}
-				}
-				break;
-			}
+			mac_addr[i] = (hex2dec(buffer[2 * i]) << 4) +
+				       hex2dec(buffer[2 * i + 1]);
 		}
+		mac_addr[0] &= 0xfe;	/* clear multicast bit */
+		mac_addr[0] |= 0x02;	/* set local assignment bit (IEEE802) */
 	} else {
 		dev_err(&odev->parent->usb->dev, "Attempting to get MAC "
 			"address failed: using random\n");
@@ -3200,7 +3185,7 @@ module_param(debug, int, S_IRUGO | S_IWU
 MODULE_PARM_DESC(tty_major, "Set the major tty number");
 module_param(tty_major, int, S_IRUGO | S_IWUSR);
 
-/* set the major tty number (eg: insmod hso.ko tty_major=245) */
+/* disable network interface (eg: insmod hso.ko disable_net=1) */
 MODULE_PARM_DESC(disable_net, "Disable the network interface");
 module_param(disable_net, int, S_IRUGO | S_IWUSR);
 

A message that is not in the archive (sent off-list or not yet received): [email protected]

#43 lore raw
Quoted 11 lines · Paulius Zaleckas
Quoted 5 lines · Paulius Zaleckas

Reworked MAC address generation from USB serial number Now it is very similar to the one done in the cdc_ether.c

Filip: Does the dummy MAC address have to start with 0xFA?

Hopefully fixed last bug in MAC address generation. Patch against latest Greg unified patch. Don't use my previous patch.

Incremental patch. Converted ethtool ioctl to ethtool_ops.

Paulius

drivers/net/usb/hso.c +13 -50
@@ -853,61 +853,24 @@ static int hso_net_start_xmit(struct sk_
 	return result;
 }
 
-static int hso_net_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
+static void hso_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
 {
 	struct hso_net *odev = netdev_priv(net);
-	u32 usercmd = 0;
 	char tmp[40];
 
-	switch (cmd) {
-	case SIOCETHTOOL:
-		/* net specific */
-		if (copy_from_user(&usercmd, rq->ifr_data, sizeof(usercmd)))
-			return -EFAULT;
-
-		switch (usercmd) {
-		case ETHTOOL_GDRVINFO:
-			{
-			/* get driver info */
-			struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
-			strncpy(info.driver, driver_name, ETHTOOL_BUSINFO_LEN);
-			strncpy(info.version, DRIVER_VERSION,
-				ETHTOOL_BUSINFO_LEN);
-			sprintf(tmp, "usb%d:%d",
-				odev->parent->usb->bus->busnum,
-				odev->parent->usb->devnum);
-			strncpy(info.bus_info, tmp, ETHTOOL_BUSINFO_LEN);
-			sprintf(tmp, "%s %x.%x", driver_name,
-				((odev->bcdCDC & 0xff00) >> 8),
-				(odev->bcdCDC & 0x00ff));
-			strncpy(info.fw_version, tmp, ETHTOOL_BUSINFO_LEN);
-			if (copy_to_user(rq->ifr_data, &info, sizeof(info)))
-				return -EFAULT;
-
-			return 0;
-			}
-		case ETHTOOL_GLINK:
-			{
-			/* get link status */
-			struct ethtool_value edata = { ETHTOOL_GLINK };
-
-			edata.data = netif_carrier_ok(net);
-			if (copy_to_user(rq->ifr_data, &edata, sizeof(edata)))
-				return -EFAULT;
-
-			return 0;
-			}
-		default:
-			dev_warn(&net->dev, "Got unsupported ioctl: %x\n",
-				 usercmd);
-			/* the ethtool user space tool relies on this */
-			return -EOPNOTSUPP;
-		}
-	default:
-		return -ENOTTY;	/* per ioctl man page */
-	}
+	strncpy(info->driver, driver_name, ETHTOOL_BUSINFO_LEN);
+	strncpy(info->version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
+	usb_make_path(odev->parent->usb, info->bus_info, sizeof info->bus_info);
+	sprintf(tmp, "%s %x.%x", driver_name, ((odev->bcdCDC & 0xff00) >> 8),
+		(odev->bcdCDC & 0x00ff));
+	strncpy(info->fw_version, tmp, ETHTOOL_BUSINFO_LEN);
 }
 
+static struct ethtool_ops ops = {
+	.get_drvinfo = hso_get_drvinfo,
+	.get_link = ethtool_op_get_link
+};
+
 static struct net_device_stats *hso_net_get_stats(struct net_device *net)
 {
 	return &((struct hso_net *)netdev_priv(net))->stats;
@@ -2281,7 +2244,6 @@ static void hso_net_init(struct net_devi
 	net->open = hso_net_open;
 	net->stop = hso_net_close;
 	net->hard_start_xmit = hso_net_start_xmit;
-	net->do_ioctl = hso_net_ioctl;
 	net->get_stats = hso_net_get_stats;
 	net->tx_timeout = hso_net_tx_timeout;
 	net->watchdog_timeo = HSO_NET_TX_TIMEOUT;
@@ -2289,6 +2251,7 @@ static void hso_net_init(struct net_devi
 	net->flags |= IFF_NOARP;
 	net->mtu = DEFAULT_MTU - 14;
 	net->tx_queue_len = 10;
+	SET_ETHTOOL_OPS(net, &ops);
 	hso_net->skb_rx_buf = NULL;
 	hso_net->rx_parse_state = WAIT_IP;
 	hso_net->wMaxSegmentSize = DEFAULT_MTU;

A message that is not in the archive (sent off-list or not yet received): [email protected]

#45 lore raw

Am Mittwoch, 16. April 2008 13:54:09 schrieb Paulius Zaleckas:

Quoted 1 line

Incremental patch. Converted ethtool ioctl to ethtool_ops.

You were faster. We need to coordinate. Which changes are you doing now?

Regards
Oliver

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 200804161403.20955.oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org

#47 lore raw
Quoted 6 lines · Oliver Neukum

Am Mittwoch, 16. April 2008 13:54:09 schrieb Paulius Zaleckas:

Quoted 1 line

Incremental patch. Converted ethtool ioctl to ethtool_ops.

You were faster. We need to coordinate. Which changes are you doing now?

Actually I am tuning my newly added hso_get_drvinfo... Instead of writing to tmp buffer to write directly to fw_version.

Should I post incremental patch or replacement?

I always get crash when closing serial terminal application. I will post dump in couple minutes.

Paulius

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): [email protected]

#49 lore raw

Am Mittwoch, 16. April 2008 14:12:06 schrieb Paulius Zaleckas:

Quoted 2 lines

I always get crash when closing serial terminal application. I will post dump in couple minutes.

Does this fix it?

Regards
Oliver

---

drivers/net/usb/hso.c renamed from drivers/net/usb/hso.c.alt3 +11 -11
@@ -156,7 +156,7 @@ struct hso_shared_int {
 	struct usb_device *usb;
 	int use_count;
 	int ref_count;
-	spinlock_t shared_int_lock;
+	struct mutex shared_int_lock;
 };
 
 struct hso_net {
@@ -2040,14 +2040,14 @@ static int hso_start_serial_device(struc
 			}
 		}
 	} else {
-		spin_lock_bh(&serial->shared_int->shared_int_lock);
+		mutex_lock(&serial->shared_int->shared_int_lock);
 		if (!serial->shared_int->use_count) {
 			result =
 			    hso_mux_submit_intr_urb(serial->shared_int,
-						    hso_dev->usb, GFP_ATOMIC);
+						    hso_dev->usb, flags);
 		}
 		serial->shared_int->use_count++;
-		spin_unlock_bh(&serial->shared_int->shared_int_lock);
+		mutex_unlock(&serial->shared_int->shared_int_lock);
 	}
 
 	return result;
@@ -2070,7 +2070,7 @@ static int hso_stop_serial_device(struct
 		usb_kill_urb(serial->rx_urb[i]);
 
 	if (serial->shared_int) {
-		spin_lock_bh(&serial->shared_int->shared_int_lock);
+		mutex_lock(&serial->shared_int->shared_int_lock);
 		if (serial->shared_int->use_count &&
 		    (--serial->shared_int->use_count == 0)) {
 			struct urb *urb;
@@ -2079,7 +2079,7 @@ static int hso_stop_serial_device(struct
 			if (urb)
 				usb_kill_urb(urb);
 		}
-		spin_unlock_bh(&serial->shared_int->shared_int_lock);
+		mutex_unlock(&serial->shared_int->shared_int_lock);
 	}
 
 	return 0;
@@ -2352,10 +2352,10 @@ static void hso_free_serial_device(struc
 	hso_serial_common_free(serial);
 
 	if (serial->shared_int) {
-		spin_lock_bh(&serial->shared_int->shared_int_lock);
+		mutex_lock(&serial->shared_int->shared_int_lock);
 		if (--serial->shared_int->ref_count == 0)
 			hso_free_shared_int(serial->shared_int);
-		spin_unlock_bh(&serial->shared_int->shared_int_lock);
+		mutex_unlock(&serial->shared_int->shared_int_lock);
 	}
 	kfree(serial);
 	hso_free_device(hso_dev);
@@ -2468,9 +2468,9 @@ struct hso_device *hso_create_mux_serial
 	serial->write_data = hso_mux_serial_write_data;
 
 	serial->shared_int = mux;
-	spin_lock_bh(&serial->shared_int->shared_int_lock);
+	mutex_lock(&serial->shared_int->shared_int_lock);
 	serial->shared_int->ref_count++;
-	spin_unlock_bh(&serial->shared_int->shared_int_lock);
+	mutex_unlock(&serial->shared_int->shared_int_lock);
 
 	/* and record this serial */
 	set_serial_by_index(serial->minor, serial);
@@ -2535,7 +2535,7 @@ struct hso_shared_int *hso_create_shared
 		goto exit;
 	}
 
-	spin_lock_init(&mux->shared_int_lock);
+	mutex_init(&mux->shared_int_lock);
 
 	return mux;
 

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 200804161543.23584.oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org

#51 lore raw
Quoted 6 lines · Oliver Neukum

Am Mittwoch, 16. April 2008 14:12:06 schrieb Paulius Zaleckas:

Quoted 2 lines

I always get crash when closing serial terminal application. I will post dump in couple minutes.

Does this fix it?

Yes, it does! Thank you.

Paulius

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#52 lore raw

Am Mittwoch, 16. April 2008 15:55:02 schrieb Paulius Zaleckas:

Quoted 9 lines
Quoted 6 lines · Oliver Neukum

Am Mittwoch, 16. April 2008 14:12:06 schrieb Paulius Zaleckas:

Quoted 2 lines

I always get crash when closing serial terminal application. I will post dump in couple minutes.

Does this fix it?

Yes, it does! Thank you.

Hi,

can you test this one as well. The method used to determine whether a device is asleep is racy. This introduces a private test.

Regards
Oliver

---

drivers/net/usb/hso.c renamed from drivers/net/usb/hso.c.alt2 +24 -2
@@ -242,6 +242,7 @@ struct hso_device {
 	u8 is_active;
 	u8 suspend_disabled;
 	u8 usb_gone;
+	u8 sleeping;
 	struct work_struct async_get_intf;
 	struct work_struct async_put_intf;
 
@@ -252,6 +253,7 @@ struct hso_device {
 	struct device *dev;
 	struct kref ref;
 	struct mutex mutex;
+	spinlock_t lock;
 
 	/* TODO: Not sure about the ones below */
 	struct proc_dir_entry *ourproc;
@@ -2184,6 +2186,7 @@ static struct hso_device *hso_create_dev
 	hso_dev->interface = intf;
 	kref_init(&hso_dev->ref);
 	mutex_init(&hso_dev->mutex);
+	spin_lock_init(&hso_dev->lock);
 
 	INIT_WORK(&hso_dev->async_get_intf, async_get_intf);
 	INIT_WORK(&hso_dev->async_put_intf, async_put_intf);
@@ -2757,12 +2760,16 @@ static void async_put_intf(struct work_s
 
 static int hso_get_activity(struct hso_device *hso_dev)
 {
-	if (hso_dev->usb->state == USB_STATE_SUSPENDED) {
+	unsigned long flags;
+
+	spin_lock_irqsave(&hso_dev->lock, flags);
+	if (hso_dev->sleeping) {
 		if (!hso_dev->is_active) {
 			hso_dev->is_active = 1;
 			schedule_work(&hso_dev->async_get_intf);
 		}
 	}
+	spin_unlock_irqrestore(&hso_dev->lock, flags);
 
 	if (hso_dev->usb->state != USB_STATE_CONFIGURED)
 		return -EAGAIN;
@@ -2774,22 +2781,32 @@ static int hso_get_activity(struct hso_d
 
 static int hso_put_activity(struct hso_device *hso_dev)
 {
-	if (hso_dev->usb->state != USB_STATE_SUSPENDED) {
+	unsigned long flags;
+
+	spin_lock_irqsave(&hso_dev->lock, flags);
+	if (hso_dev->sleeping) {
 		if (hso_dev->is_active) {
 			hso_dev->is_active = 0;
 			schedule_work(&hso_dev->async_put_intf);
+			spin_unlock_irqrestore(&hso_dev->lock, flags);
 			return -EAGAIN;
 		}
 	}
 	hso_dev->is_active = 0;
+	spin_unlock_irqrestore(&hso_dev->lock, flags);
 	return 0;
 }
 
 /* called by kernel when we need to suspend device */
 static int hso_suspend(struct usb_interface *iface, pm_message_t message)
 {
+	struct hso_device *hso_dev = usb_get_intfdata(iface);
 	int i, result = 0;
 
+	spin_lock_irq(&hso_dev->lock);
+	hso_dev->sleeping = 1;
+	spin_unlock_irq(&hso_dev->lock);
+
 	/* Stop all serial ports */
 	for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
 		if (serial_table[i] && (serial_table[i]->interface == iface)) {
@@ -2816,9 +2833,14 @@ out:
 /* called by kernel when we need to resume device */
 static int hso_resume(struct usb_interface *iface)
 {
+	struct hso_device *hso_dev = usb_get_intfdata(iface);
 	int i, result = 0;
 	struct hso_net *hso_net;
 
+	spin_lock_irq(&hso_dev->lock);
+	hso_dev->sleeping = 0;
+	spin_unlock_irq(&hso_dev->lock);
+
 	/* Start all serial ports */
 	for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) {
 		if (serial_table[i] && (serial_table[i]->interface == iface)) {

A message that is not in the archive (sent off-list or not yet received): 200804171632.12972.oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org

#54 lore raw
Quoted 2 lines · Oliver Neukum

can you test this one as well. The method used to determine whether a device is asleep is racy. This introduces a private test.

Stupid question :) How to test it? How can I force it to suspend? I have never used any suspend on my PC :)

Paulius

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): [email protected]

#56 lore raw

read Documentation/usb/power-management.txt

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Paulius Zaleckas
Sent: Thursday, April 17, 2008 2:47 PM
To: [email protected]
Cc: [email protected]
Subject: Re: [RFC] Patch to option HSO driver to the kernel

Quoted 2 lines · Oliver Neukum

can you test this one as well. The method used to determine whether a device is asleep is racy. This introduces a private test.

Stupid question :) How to test it? How can I force it to suspend? I have never used any suspend on my PC :)

Paulius

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#57 lore raw
In reply to a message not in the archive

Am Donnerstag, 17. April 2008 23:47:27 schrieb Paulius Zaleckas:

Quoted 6 lines
Quoted 2 lines · Oliver Neukum

can you test this one as well. The method used to determine whether a device is asleep is racy. This introduces a private test.

Stupid question :) How to test it? How can I force it to suspend? I have never used any suspend on my PC :)

This is runtime power management. It can save energy on any computer. You compile your kernel with CONFIG_USB_SUSPEND and to see something in syslog with CONFIG_USB_DEBUG.
Plug in the device, locate its sysfs directory, cd into it and do echo "auto" >power/level

After a few seconds of idleness the device and the hub it's connected to (if it's the only device at that hub) should suspend. You'll get a message about it in the kernel log.

Regards
Oliver
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#58 lore raw
In reply to a message not in the archive
Quoted 8 lines · Oliver Neukum

Hi,

can you test this one as well. The method used to determine whether a device is asleep is racy. This introduces a private test.

Regards
Oliver

By setting level "auto" it didn't suspend... When I tried to set "suspend" to the level I got crash:

hub 1-1.3:1.0: suspend error -16

Unable to handle kernel NULL pointer dereference at 000000000000004a RIP:
 [<ffffffff811ce082>] usb_kill_urb+0x28/0xf5
PGD 20c36067 PUD 2228e067 PMD 0
Oops: 0000 [1] SMP
CPU 0
Modules linked in: hso(U) rfkill i915 drm autofs4 fuse sunrpc loop dm_multipath ipv6 snd_hda_intel parport_pc pcspkr parport e100 snd_seq_dummy r8169 mii i2c_i801 snd_seq_oss i2c_core snd_seq_midi_event snd_seq iTCO_wdt iTCO_vendor_support ftdi_sio snd_seq_device usbserial usblp snd_pcm_oss snd_mixer_oss snd_pcm snd_timer snd_page_alloc snd_hwdep snd soundcore button sr_mod sg cdrom dm_snapshot dm_zero dm_mirror dm_mod pata_acpi ata_generic ata_piix libata sd_mod scsi_mod ext3 jbd mbcache uhci_hcd ohci_hcd ehci_hcd
Pid: 2920, comm: bash Not tainted 2.6.24.4-64.fc8debug #1
RIP: 0010:[<ffffffff811ce082>]  [<ffffffff811ce082>] usb_kill_urb+0x28/0xf5
RSP: 0018:ffff81001fd8dd88  EFLAGS: 00010202
RAX: 0000000000000000 RBX: 0000000000000002 RCX: ffffffff88323780
RDX: ffff81001fd8dfd8 RSI: 000000000000021e RDI: ffffffff813868d6
RBP: ffff810032c37b78 R08: 000000011fd88848 R09: 0000000000000000
R10: ffff81001fd8dd68 R11: 0000000000000028 R12: 0000000000000002
R13: ffff810037f38000 R14: 0000000000000002 R15: 0000000000000001
FS:  00002aaaaaac7f50(0000) GS:ffffffff81407000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 000000000000004a CR3: 00000000124f4000 CR4: 00000000000006a0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process bash (pid: 2920, threadinfo ffff81001fd8c000, task ffff81001fd88000)
Stack:  0000000000000246 ffff81003319d248 ffff81002d486e98 0000000000000246
 ffff81003319d250 ffff81003319d248 ffff81003319d250 ffff810032c37b68
 ffff810032c37b78 ffffffff8831ce54 0000000000000002 ffff81003d0f99b0
Call Trace:
 [<ffffffff8831ce54>] :hso:hso_stop_serial_device+0x4b/0x9b
 [<ffffffff8831cf13>] :hso:hso_suspend+0x26/0x67
 [<ffffffff811d0887>] usb_suspend_both+0xd7/0x27d
 [<ffffffff811d0a60>] usb_external_suspend_device+0x33/0x45
 [<ffffffff811d36b4>] set_level+0x125/0x189
 [<ffffffff810ee242>] sysfs_write_file+0xd7/0x115
 [<ffffffff810aa62f>] vfs_write+0xc6/0x16f
 [<ffffffff810aabec>] sys_write+0x45/0x6e
 [<ffffffff8100c053>] tracesys+0xd5/0xda


Code: 48 83 7b 48 00 0f 84 bb 00 00 00 48 83 7b 50 00 0f 84 b0 00
RIP  [<ffffffff811ce082>] usb_kill_urb+0x28/0xf5
 RSP <ffff81001fd8dd88>
CR2: 000000000000004a
---[ end trace e19a70acc4bb0aa4 ]---

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#59 lore raw

Am Freitag, 18. April 2008 17:18:29 schrieb Paulius Zaleckas:

Quoted 5 lines
Quoted 3 lines · Oliver Neukum

Hi,

Quoted 8 lines
Quoted 5 lines

can you test this one as well. The method used to determine whether a device is asleep is racy. This introduces a private test.

Regards
Oliver

By setting level "auto" it didn't suspend... When I tried to set "suspend" to the level I got crash:

Does this fix it?

Regards
Oliver

---

drivers/net/usb/hso.c renamed from drivers/net/usb/hso.c.alt3 +1 -1
@@ -2052,7 +2052,7 @@
 	}
 
 	if (serial->tx_urb)
-		usb_kill_urb(serial->rx_urb[i]);
+		usb_kill_urb(serial->tx_urb);
 
 	if (serial->shared_int) {
 		mutex_lock(&serial->shared_int->shared_int_lock);
#60 lore raw
Quoted 7 lines · Oliver Neukum

Am Freitag, 18. April 2008 17:18:29 schrieb Paulius Zaleckas:

Quoted 6 lines
Quoted 5 lines · Oliver Neukum

Hi,

can you test this one as well. The method used to determine whether a device is asleep is racy. This introduces a private test.

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

Regards
Oliver

By setting level "auto" it didn't suspend... When I tried to set "suspend" to the level I got crash:

Does this fix it?

Looks like it fixed this crash.
I don't see anything on dmesg and /var/log/messages when I do echo "suspend" > power/level, but that is IMO another story.

Paulius

A message that is not in the archive (sent off-list or not yet received): [email protected]

#62 lore raw

Am Montag, 21. April 2008 14:38:48 schrieb Paulius Zaleckas:

Quoted 10 lines
Quoted 9 lines · Oliver Neukum

Am Freitag, 18. April 2008 17:18:29 schrieb Paulius Zaleckas:

Quoted 8 lines
Quoted 7 lines · Oliver Neukum

Hi,

can you test this one as well. The method used to determine whether a device is asleep is racy. This introduces a private test.

Regards
Oliver

Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

By setting level "auto" it didn't suspend... When I tried to set "suspend" to the level I got crash:

Does this fix it?

Looks like it fixed this crash.
I don't see anything on dmesg and /var/log/messages when I do echo "suspend" > power/level, but that is IMO another story.

Did you compile with CONFIG_USB_DEBUG? Do you load usbcore from initrd? In that case you need to rebuild your initrd.

Regards
Oliver
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 200804211450.27093.oliver-GvhC2dPhHPQdnm+yROfE0A@public.gmane.org

#64 lore raw
Quoted 13 lines · Oliver Neukum

Am Montag, 21. April 2008 14:38:48 schrieb Paulius Zaleckas:

Quoted 12 lines
Quoted 11 lines · Oliver Neukum

Am Freitag, 18. April 2008 17:18:29 schrieb Paulius Zaleckas:

Quoted 10 lines
Quoted 7 lines · Oliver Neukum

Hi,

can you test this one as well. The method used to determine whether a device is asleep is racy. This introduces a private test.

Regards
Oliver

By setting level "auto" it didn't suspend... When I tried to set "suspend" to the level I got crash:

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

Does this fix it?

Looks like it fixed this crash.
I don't see anything on dmesg and /var/log/messages when I do echo "suspend" > power/level, but that is IMO another story.

Did you compile with CONFIG_USB_DEBUG? Do you load usbcore from initrd? In that case you need to rebuild your initrd.

Actually I am using 2.6.24.4-64.fc8debug kernel.
I failed to start my 2.6.25 compiled kernel, because of some mkinitrd incompatibilities with LVM (I hate that day when I installed Fedora on LVM partition :))
According to fedora config CONFIG_USB_DEBUG is enabled. Couldn't find usbcore on initrd image...

Paulius

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

Applied
#65 lore raw
In reply to Oliver Neukum
Quoted 10 lines · Oliver Neukum

Am Mittwoch, 16. April 2008 14:12:06 schrieb Paulius Zaleckas:

Quoted 2 lines

I always get crash when closing serial terminal application. I will post dump in couple minutes.

Does this fix it?

Regards
Oliver

Applied, thanks.

greg k-h

#66 lore raw
In reply to a message not in the archive
Quoted 8 lines · Paulius Zaleckas
Quoted 7 lines · Paulius Zaleckas
Quoted 5 lines · Paulius Zaleckas

Reworked MAC address generation from USB serial number Now it is very similar to the one done in the cdc_ether.c

Filip: Does the dummy MAC address have to start with 0xFA?

Quoted 9 lines
Quoted 4 lines

Hopefully fixed last bug in MAC address generation. Patch against latest Greg unified patch. Don't use my previous patch.

Incremental patch. Converted ethtool ioctl to ethtool_ops.

Paulius

Updated patch with the following change:
In function hso_get_drvinfo instead of writing to tmp buffer write directly to fw_version.

Paulius

drivers/net/usb/hso.c +12 -51
@@ -853,61 +853,22 @@ static int hso_net_start_xmit(struct sk_
 	return result;
 }
 
-static int hso_net_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
+static void hso_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
 {
 	struct hso_net *odev = netdev_priv(net);
-	u32 usercmd = 0;
-	char tmp[40];
 
-	switch (cmd) {
-	case SIOCETHTOOL:
-		/* net specific */
-		if (copy_from_user(&usercmd, rq->ifr_data, sizeof(usercmd)))
-			return -EFAULT;
-
-		switch (usercmd) {
-		case ETHTOOL_GDRVINFO:
-			{
-			/* get driver info */
-			struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
-			strncpy(info.driver, driver_name, ETHTOOL_BUSINFO_LEN);
-			strncpy(info.version, DRIVER_VERSION,
-				ETHTOOL_BUSINFO_LEN);
-			sprintf(tmp, "usb%d:%d",
-				odev->parent->usb->bus->busnum,
-				odev->parent->usb->devnum);
-			strncpy(info.bus_info, tmp, ETHTOOL_BUSINFO_LEN);
-			sprintf(tmp, "%s %x.%x", driver_name,
-				((odev->bcdCDC & 0xff00) >> 8),
-				(odev->bcdCDC & 0x00ff));
-			strncpy(info.fw_version, tmp, ETHTOOL_BUSINFO_LEN);
-			if (copy_to_user(rq->ifr_data, &info, sizeof(info)))
-				return -EFAULT;
-
-			return 0;
-			}
-		case ETHTOOL_GLINK:
-			{
-			/* get link status */
-			struct ethtool_value edata = { ETHTOOL_GLINK };
-
-			edata.data = netif_carrier_ok(net);
-			if (copy_to_user(rq->ifr_data, &edata, sizeof(edata)))
-				return -EFAULT;
-
-			return 0;
-			}
-		default:
-			dev_warn(&net->dev, "Got unsupported ioctl: %x\n",
-				 usercmd);
-			/* the ethtool user space tool relies on this */
-			return -EOPNOTSUPP;
-		}
-	default:
-		return -ENOTTY;	/* per ioctl man page */
-	}
+	strncpy(info->driver, driver_name, ETHTOOL_BUSINFO_LEN);
+	strncpy(info->version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
+	usb_make_path(odev->parent->usb, info->bus_info, sizeof info->bus_info);
+	snprintf(info->fw_version, ETHTOOL_BUSINFO_LEN, "%s %x.%x", driver_name,
+		 ((odev->bcdCDC & 0xff00) >> 8), (odev->bcdCDC & 0x00ff));
 }
 
+static struct ethtool_ops ops = {
+	.get_drvinfo = hso_get_drvinfo,
+	.get_link = ethtool_op_get_link
+};
+
 static struct net_device_stats *hso_net_get_stats(struct net_device *net)
 {
 	return &((struct hso_net *)netdev_priv(net))->stats;
@@ -2281,7 +2242,6 @@ static void hso_net_init(struct net_devi
 	net->open = hso_net_open;
 	net->stop = hso_net_close;
 	net->hard_start_xmit = hso_net_start_xmit;
-	net->do_ioctl = hso_net_ioctl;
 	net->get_stats = hso_net_get_stats;
 	net->tx_timeout = hso_net_tx_timeout;
 	net->watchdog_timeo = HSO_NET_TX_TIMEOUT;
@@ -2289,6 +2249,7 @@ static void hso_net_init(struct net_devi
 	net->flags |= IFF_NOARP;
 	net->mtu = DEFAULT_MTU - 14;
 	net->tx_queue_len = 10;
+	SET_ETHTOOL_OPS(net, &ops);
 	hso_net->skb_rx_buf = NULL;
 	hso_net->rx_parse_state = WAIT_IP;
 	hso_net->wMaxSegmentSize = DEFAULT_MTU;
#67 lore raw
In reply to a message not in the archive

With the latest patch I always get BUG when closing my serial terminal application. I have two different modems (GTM378 and GTM380) plugged at USB hub. Here is the dump:

BUG: sleeping function called from invalid context at drivers/usb/core/urb.c:542

in_atomic():1, irqs_disabled():0
Pid: 30031, comm: gtkterm Not tainted 2.6.24.4-64.fc8 #1

Call Trace:
 [<ffffffff811b5e40>] usb_kill_urb+0x1a/0xf1
 [<ffffffff81268512>] mutex_lock+0x1e/0x2f
 [<ffffffff810ab2a2>] fasync_helper+0x4a/0xcd
 [<ffffffff88308f57>] :hso:hso_stop_serial_device+0x85/0x99
 [<ffffffff8830971f>] :hso:hso_serial_close+0xea/0x110
 [<ffffffff8117bf26>] release_dev+0x212/0x618
 [<ffffffff8108ec31>] free_pages_and_swap_cache+0x73/0x8f
 [<ffffffff8117c33d>] tty_release+0x11/0x1a
 [<ffffffff810a152c>] __fput+0xc2/0x18f
 [<ffffffff8109ed3f>] filp_close+0x5d/0x65
 [<ffffffff8109ff0f>] sys_close+0x8d/0xca
 [<ffffffff8100c005>] tracesys+0xd5/0xda

BUG: scheduling while atomic: gtkterm/30031/0x10000100

Pid: 30031, comm: gtkterm Not tainted 2.6.24.4-64.fc8 #1

Call Trace:
 [<ffffffff812677a2>] schedule+0x91/0x706
 [<ffffffff81032f45>] __cond_resched+0x2d/0x55
 [<ffffffff81267f0f>] cond_resched+0x2e/0x39
 [<ffffffff811b5e45>] usb_kill_urb+0x1f/0xf1
 [<ffffffff81268512>] mutex_lock+0x1e/0x2f
 [<ffffffff810ab2a2>] fasync_helper+0x4a/0xcd
 [<ffffffff88308f57>] :hso:hso_stop_serial_device+0x85/0x99
 [<ffffffff8830971f>] :hso:hso_serial_close+0xea/0x110
 [<ffffffff8117bf26>] release_dev+0x212/0x618
 [<ffffffff8108ec31>] free_pages_and_swap_cache+0x73/0x8f
 [<ffffffff8117c33d>] tty_release+0x11/0x1a
 [<ffffffff810a152c>] __fput+0xc2/0x18f
 [<ffffffff8109ed3f>] filp_close+0x5d/0x65
 [<ffffffff8109ff0f>] sys_close+0x8d/0xca
 [<ffffffff8100c005>] tracesys+0xd5/0xda

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#68 lore raw
In reply to Greg KH

Just some obvious things to reduce the source code hopping for the review and to reduce the source code size.

Regards,
Oliver

drivers/net/usb/hso.c line 71

Quoted 7 lines
drivers/net/usb/hso.c new file +6 -0
+
+#define DRIVER_VERSION			"1.2"
+#define MOD_AUTHOR			"Option Wireless"
+#define MOD_DESCRIPTION			"USB High Speed Option driver"
+#define MOD_LICENSE			"GPL"
+

Please move the MODULE_OWNER(), MODULE_LICENSE(), etc. macros from the end of this file directly to this point.

Quoted 51 lines
drivers/net/usb/hso.c new file +50 -0
+/*****************************************************************************/
+/* Prototypes                                                                */
+/*****************************************************************************/
+/* Network interface functions */
+static int hso_net_open(struct net_device *net);
+static int hso_net_close(struct net_device *net);
+static int hso_net_start_xmit(struct sk_buff *skb, struct net_device *net);
+static int hso_net_ioctl(struct net_device *net, struct ifreq *rq, int cmd);
+static struct net_device_stats *hso_net_get_stats(struct net_device *net);
+static void hso_net_tx_timeout(struct net_device *net);
+static void hso_net_set_multicast(struct net_device *net);
+static void read_bulk_callback(struct urb *urb);
+static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
+			unsigned int count, unsigned char is_eop);
+static void write_bulk_callback(struct urb *urb);
+/* Serial driver functions */
+static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file,
+			       unsigned int set, unsigned int clear);
+static void ctrl_callback(struct urb *urb);
+static void put_rxbuf_data(struct urb *urb, struct hso_serial *serial);
+static void hso_std_serial_read_bulk_callback(struct urb *urb);
+static void hso_std_serial_write_bulk_callback(struct urb *urb);
+static void _hso_serial_set_termios(struct tty_struct *tty,
+				    struct ktermios *old);
+static void hso_kick_transmit(struct hso_serial *serial);
+/* Base driver functions */
+static int hso_probe(struct usb_interface *interface,
+		     const struct usb_device_id *id);
+static void hso_disconnect(struct usb_interface *interface);
+/* Helper functions */
+static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int,
+				   struct usb_device *usb, gfp_t gfp);
+static void hso_net_init(struct net_device *net);
+static void set_ethernet_addr(struct hso_net *odev);
+static struct hso_serial *get_serial_by_index(unsigned index);
+static struct hso_serial *get_serial_by_shared_int_and_type(
+					struct hso_shared_int *shared_int,
+					int mux);
+static int get_free_serial_index(void);
+static void set_serial_by_index(unsigned index, struct hso_serial *serial);
+static int remove_net_device(struct hso_device *hso_dev);
+static int add_net_device(struct hso_device *hso_dev);
+static void log_usb_status(int status, const char *function);
+static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf,
+						  int type, int dir);
+static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports);
+static void hso_free_interface(struct usb_interface *intf);
+static int hso_start_serial_device(struct hso_device *hso_dev);
+static int hso_stop_serial_device(struct hso_device *hso_dev);
+static int hso_start_net_device(struct hso_device *hso_dev);

drivers/net/usb/hso.c line 354

Quoted 10 lines
drivers/net/usb/hso.c new file +10 -0
+static void hso_free_shared_int(struct hso_shared_int *shared_int);
+static int hso_stop_net_device(struct hso_device *hso_dev);
+static void hso_serial_ref_free(struct kref *ref);
+static int hso_suspend(struct usb_interface *iface, pm_message_t message);
+static int hso_resume(struct usb_interface *iface);
+static void async_get_intf(struct work_struct *data);
+static void async_put_intf(struct work_struct *data);
+static int hso_put_activity(struct hso_device *hso_dev);
+static int hso_get_activity(struct hso_device *hso_dev);
+

This is a real forward declaration hell. Please try to reorder the functions in the code to make this as obsolte as possible.

Quoted 9 lines
drivers/net/usb/hso.c new file +8 -0
+/*****************************************************************************/
+/* Helping functions                                                         */
+/*****************************************************************************/
+
+/* convert a character representing a hex value to a number */
+static unsigned char hex2dec(unsigned char digit)
+{
+

drivers/net/usb/hso.c line 372

Quoted 10 lines
drivers/net/usb/hso.c new file +10 -0
+	if ((digit >= '0') && (digit <= '9'))
+		return (digit - '0');
+	/* Map all characters to 0-15 */
+	if ((digit >= 'a') && (digit <= 'z'))
+		return (digit - 'a' + 10) % 16;
+	if ((digit >= 'A') && (digit <= 'Z'))
+		return (digit - 'A' + 10) % 16;
+	return 16;
+}
+

Shouldn't this already be somewhere else in the kernel?

drivers/net/usb/hso.c line 417

Quoted 9 lines
drivers/net/usb/hso.c new file +8 -0
+
+/* module parameters */
+static int debug;
+static int procfs = 1;
+static int tty_major;
+static int disable_net;
+static int enable_autopm;
+

please move the module_param() stuff and MODULE_PARM_DESC() from the end of the file right to this place.

drivers/net/usb/hso.c line 586

Quoted 9 lines
drivers/net/usb/hso.c new file +8 -0
+static int hso_proc_port_info(char *buf, char **start, off_t offset, int count,
+			      int *eof, void *data)
+{
+	int len = 0;
+	struct hso_device *hso_dev = (struct hso_device *)data;
+	char *port_name = NULL;
+
+	D1("count: %d", count);

This debug macro looks like it is from the very beginning of the implementation. Remove it.

Quoted 13 lines
drivers/net/usb/hso.c new file +12 -0
+
+static void hso_serial_throttle(struct tty_struct *tty)
+{
+	D1(" ");
+}
+
+static void hso_serial_unthrottle(struct tty_struct *tty)
+{
+	D1(" ");
+}
+
+static void hso_serial_break(struct tty_struct *tty, int break_state)

drivers/net/usb/hso.c line 1531

Quoted 10 lines
drivers/net/usb/hso.c new file +10 -0
+{
+	D1(" ");
+}
+
+static int hso_serial_read_proc(char *page, char **start, off_t off, int count,
+				int *eof, void *data)
+{
+	return 0;
+}
+

???

drivers/net/usb/hso.c line 1536

Quoted 7 lines
drivers/net/usb/hso.c new file +5 -0
+static void hso_serial_hangup(struct tty_struct *tty)
+{
+	D1("hang up");
+}
+

Should all these functions be removed (and therefor not set in hso_serial_ops) ??

Quoted 22 lines
drivers/net/usb/hso.c new file +21 -0
+
+/* Base driver functions */
+
+/* operations setup of the serial interface */
+static struct tty_operations hso_serial_ops = {
+	.open = hso_serial_open,
+	.close = hso_serial_close,
+	.write = hso_serial_write,
+	.write_room = hso_serial_write_room,
+	.ioctl = hso_serial_ioctl,
+	.set_termios = hso_serial_set_termios,
+	.throttle = hso_serial_throttle,
+	.unthrottle = hso_serial_unthrottle,
+	.break_ctl = hso_serial_break,
+	.chars_in_buffer = hso_serial_chars_in_buffer,
+	.read_proc = hso_serial_read_proc,
+	.hangup = hso_serial_hangup,
+	.tiocmget = hso_serial_tiocmget,
+	.tiocmset = hso_serial_tiocmset,
+};
+

A message that is not in the archive (sent off-list or not yet received): [email protected]

author
#70 lore raw
Quoted 6 lines · Oliver Hartkopp

Just some obvious things to reduce the source code hopping for the review and to reduce the source code size.

Regards,
Oliver

Quoted 10 lines

drivers/net/usb/hso.c line 71

Quoted 7 lines
drivers/net/usb/hso.c new file +6 -0
+
+#define DRIVER_VERSION			"1.2"
+#define MOD_AUTHOR			"Option Wireless"
+#define MOD_DESCRIPTION			"USB High Speed Option driver"
+#define MOD_LICENSE			"GPL"
+

Please move the MODULE_OWNER(), MODULE_LICENSE(), etc. macros from the end of this file directly to this point.

Does that really matter?

Quoted 7 lines

drivers/net/usb/hso.c line 297

Quoted 4 lines
drivers/net/usb/hso.c new file +3 -0
+/*****************************************************************************/
+/* Prototypes                                                                */
+/*****************************************************************************/

This is a real forward declaration hell. Please try to reorder the functions in the code to make this as obsolte as possible.

I've already stripped down a lot of them, will work on the remaining ones, I wanted to get the code out for review first.

Quoted 13 lines
Quoted 13 lines
drivers/net/usb/hso.c new file +13 -0
+/*****************************************************************************/
+/* Helping functions                                                         */
+/*****************************************************************************/
+
+/* convert a character representing a hex value to a number */
+static unsigned char hex2dec(unsigned char digit)
+{
+
+	if ((digit >= '0') && (digit <= '9'))
+		return (digit - '0');
+	/* Map all characters to 0-15 */
+	if ((digit >= 'a') && (digit <= 'z'))
+		return (digit - 'a' + 10) % 16;
Quoted 8 lines

drivers/net/usb/hso.c line 372

Quoted 6 lines
drivers/net/usb/hso.c new file +5 -0
+	if ((digit >= 'A') && (digit <= 'Z'))
+		return (digit - 'A' + 10) % 16;
+	return 16;
+}
+

Shouldn't this already be somewhere else in the kernel?

Do you know where?

Quoted 4 lines
Quoted 4 lines
drivers/net/usb/hso.c new file +4 -0
+
+/* module parameters */
+static int debug;
+static int procfs = 1;
Quoted 8 lines

drivers/net/usb/hso.c line 417

Quoted 5 lines
drivers/net/usb/hso.c new file +4 -0
+static int tty_major;
+static int disable_net;
+static int enable_autopm;
+

please move the module_param() stuff and MODULE_PARM_DESC() from the end of the file right to this place.

Does it really matter?

Quoted 4 lines
Quoted 4 lines
drivers/net/usb/hso.c new file +4 -0
+static int hso_proc_port_info(char *buf, char **start, off_t offset, int count,
+			      int *eof, void *data)
+{
+	int len = 0;
Quoted 8 lines

drivers/net/usb/hso.c line 586

Quoted 5 lines
drivers/net/usb/hso.c new file +4 -0
+	struct hso_device *hso_dev = (struct hso_device *)data;
+	char *port_name = NULL;
+
+	D1("count: %d", count);

This debug macro looks like it is from the very beginning of the implementation. Remove it.

Why?

Quoted 17 lines
Quoted 17 lines
drivers/net/usb/hso.c new file +17 -0
+
+static void hso_serial_throttle(struct tty_struct *tty)
+{
+	D1(" ");
+}
+
+static void hso_serial_unthrottle(struct tty_struct *tty)
+{
+	D1(" ");
+}
+
+static void hso_serial_break(struct tty_struct *tty, int break_state)
+{
+	D1(" ");
+}
+
+static int hso_serial_read_proc(char *page, char **start, off_t off, int count,
Quoted 8 lines

drivers/net/usb/hso.c line 1531

Quoted 6 lines
drivers/net/usb/hso.c new file +5 -0
+				int *eof, void *data)
+{
+	return 0;
+}
+

???

Already been pointed out that they can be removed.

Quoted 10 lines

drivers/net/usb/hso.c line 1536

Quoted 7 lines
drivers/net/usb/hso.c new file +5 -0
+static void hso_serial_hangup(struct tty_struct *tty)
+{
+	D1("hang up");
+}
+

Should all these functions be removed (and therefor not set in hso_serial_ops) ??

Yes.

thanks for the review.

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): [email protected]

#72 lore raw
Quoted 21 lines · Greg KH
Quoted 7 lines · Oliver Hartkopp

Just some obvious things to reduce the source code hopping for the review and to reduce the source code size.

Regards,
Oliver

Quoted 11 lines

drivers/net/usb/hso.c line 71

Quoted 8 lines
drivers/net/usb/hso.c new file +6 -0
+
+#define DRIVER_VERSION			"1.2"
+#define MOD_AUTHOR			"Option Wireless"
+#define MOD_DESCRIPTION			"USB High Speed Option driver"
+#define MOD_LICENSE			"GPL"
+

Please move the MODULE_OWNER(), MODULE_LICENSE(), etc. macros from the end of this file directly to this point.

Quoted 3 lines

Does that really matter?

Not for the compiler :)

But when you are able to put things together that helps to understand the code much better (at least for me). I'm not a wizard so when it helps me to find code belonging together it probably helps other people also.

Quoted 9 lines
Quoted 8 lines

drivers/net/usb/hso.c line 297

Quoted 5 lines
drivers/net/usb/hso.c new file +3 -0
+/*****************************************************************************/
+/* Prototypes                                                                */
+/*****************************************************************************/

This is a real forward declaration hell. Please try to reorder the functions in the code to make this as obsolte as possible.

Quoted 4 lines

I've already stripped down a lot of them, will work on the remaining ones, I wanted to get the code out for review first.

Ok.

Quoted 23 lines
Quoted 13 lines
Quoted 13 lines
drivers/net/usb/hso.c new file +13 -0
+/*****************************************************************************/
+/* Helping functions                                                         */
+/*****************************************************************************/
+
+/* convert a character representing a hex value to a number */
+static unsigned char hex2dec(unsigned char digit)
+{
+
+	if ((digit >= '0') && (digit <= '9'))
+		return (digit - '0');
+	/* Map all characters to 0-15 */
+	if ((digit >= 'a') && (digit <= 'z'))
+		return (digit - 'a' + 10) % 16;
Quoted 9 lines

drivers/net/usb/hso.c line 372

Quoted 7 lines
drivers/net/usb/hso.c new file +5 -0
+	if ((digit >= 'A') && (digit <= 'Z'))
+		return (digit - 'A' + 10) % 16;
+	return 16;
+}
+

Shouldn't this already be somewhere else in the kernel?

Quoted 3 lines

Do you know where?

Hm - i found one by grep after 'hex2' in drivers/net/cxgb3/t3_hw.c :

static unsigned int hex2int(unsigned char c) {
return isdigit(c) ? c - '0' : toupper(c) - 'A' + 10; }

But nothing in lib/* ...

Quoted 14 lines
Quoted 4 lines
Quoted 4 lines
drivers/net/usb/hso.c new file +4 -0
+
+/* module parameters */
+static int debug;
+static int procfs = 1;
Quoted 9 lines

drivers/net/usb/hso.c line 417

Quoted 6 lines
drivers/net/usb/hso.c new file +4 -0
+static int tty_major;
+static int disable_net;
+static int enable_autopm;
+

please move the module_param() stuff and MODULE_PARM_DESC() from the end of the file right to this place.

Quoted 3 lines

Does it really matter?

Same as stated above. If you would put the MODULE_PARM_DESC() right here the formerly defined variables are documented in one go without any /* comments */ and you just know the meaning for the rest of the review.

Quoted 14 lines
Quoted 4 lines
Quoted 4 lines
drivers/net/usb/hso.c new file +4 -0
+static int hso_proc_port_info(char *buf, char **start, off_t offset, int count,
+			      int *eof, void *data)
+{
+	int len = 0;
Quoted 9 lines

drivers/net/usb/hso.c line 586

Quoted 6 lines
drivers/net/usb/hso.c new file +4 -0
+	struct hso_device *hso_dev = (struct hso_device *)data;
+	char *port_name = NULL;
+
+	D1("count: %d", count);

This debug macro looks like it is from the very beginning of the implementation. Remove it.

Quoted 2 lines

Why?

Why not? If it is not really needed it should be omitted.

In general i'm a friend of debug-code, but when i touches the mainline kernel IMO one should reconsider if all the debug code remains necessary.

Quoted 13 lines
Quoted 12 lines

drivers/net/usb/hso.c line 1531

Quoted 10 lines
drivers/net/usb/hso.c new file +7 -0
+
+static int hso_serial_read_proc(char *page, char **start, off_t off, int count,
+				int *eof, void *data)
+{
+	return 0;
+}
+

???

Quoted 2 lines

Already been pointed out that they can be removed.

Sorry. Didn't catch that.

Regards,
Oliver

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#73 lore raw
In reply to Greg KH

Am Montag, 14. April 2008 23:32:39 schrieb Greg KH:

Quoted 7 lines

Hi all,

Here's a patch that I have cleaned up for context only from Option that is a USB serial / network device all in one.

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

This patch removes a creative abuse of in_interrupt(). Locking is always done with a mutex now. No need for atomic operations.

---

drivers/net/usb/hso.c renamed from drivers/net/usb/hso.c.alt2 +6 -18
@@ -2201,21 +2201,13 @@ static int hso_stop_serial_device(struct
 		return -ENODEV;
 
 	for (i = 0; i < serial->num_rx_urbs; i++) {
-		if (serial->rx_urb[i]
-		    && (serial->rx_urb[i]->status == -EINPROGRESS)) {
-			if (in_interrupt())
-				usb_unlink_urb(serial->rx_urb[i]);
-			else
+		if (serial->rx_urb[i])
 				usb_kill_urb(serial->rx_urb[i]);
-		}
 	}
 
-	if (serial->tx_urb && (serial->tx_urb->status == -EINPROGRESS)) {
-		if (in_interrupt())
-			usb_unlink_urb(serial->tx_urb);
-		else
-			usb_kill_urb(serial->rx_urb[i]);
-	}
+	if (serial->tx_urb)
+		usb_kill_urb(serial->rx_urb[i]);
+
 	if (serial->shared_int) {
 		spin_lock_bh(&serial->shared_int->shared_int_lock);
 		if (serial->shared_int->use_count &&
@@ -2223,12 +2215,8 @@ static int hso_stop_serial_device(struct
 			struct urb *urb;
 
 			urb = serial->shared_int->shared_intr_urb;
-			if ((urb) && (urb->status == -EINPROGRESS)) {
-				if (in_interrupt())
-					usb_unlink_urb(urb);
-				else
-					usb_kill_urb(urb);
-			}
+			if (urb)
+				usb_kill_urb(urb);
 		}
 		spin_unlock_bh(&serial->shared_int->shared_int_lock);
 	}
#74 lore raw
Quoted 6 lines · Oliver Neukum

Am Montag, 14. April 2008 23:32:39 schrieb Greg KH:

Quoted 5 lines

Hi all,

Here's a patch that I have cleaned up for context only from Option that is a USB serial / network device all in one.

Quoted 7 lines
Quoted 2 lines

I'd like to see this go into 2.6.26, so any review comments by anyone who wishes to review any portion of this would be greatly apprecited.

This patch removes a creative abuse of in_interrupt(). Locking is always done with a mutex now. No need for atomic operations.

Very nice, thanks for the change, applied.

greg k-h