Re: USB: serial: regression (oops) at module unload in usb-next

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 23 Mar 2012, Johan Hovold wrote:

> I'm afraid I don't have time to debug this further today, but I did a
> quick test removing the if statement above. It didn't oops at unload,
> but instead I got the following warning when the module was reloaded:
> 
> 
> [  291.257618] drivers/usb/serial/usb-serial.c: usb_serial_probe - registering ttyUSB0
> [  291.257830] ------------[ cut here ]------------
> [  291.257854] WARNING: at fs/sysfs/dir.c:481 sysfs_add_one+0x95/0xd0()
> [  291.257883] Hardware name: Vostro 1520
> [  291.257893] sysfs: cannot create duplicate filename '/dev/char/188:0'

Here's a patch for you to try.  On my system I don't get any warnings
or errors while using it with a PL2303.

I no longer remember clearly why I added all that stuff to keep track 
of the port's registration state.  Maybe I was concerned about what 
would happen if someone used sysfs to unbind a port from its driver.  
For most of the serial drivers this wouldn't have any effect, because 
they don't implement the port_probe and port_remove methods.

Alan Stern



 drivers/usb/serial/bus.c        |    5 -----
 drivers/usb/serial/usb-serial.c |   23 ++---------------------
 include/linux/usb/serial.h      |    8 --------
 3 files changed, 2 insertions(+), 34 deletions(-)

Index: usb-3.3/include/linux/usb/serial.h
===================================================================
--- usb-3.3.orig/include/linux/usb/serial.h
+++ usb-3.3/include/linux/usb/serial.h
@@ -28,13 +28,6 @@
 /* parity check flag */
 #define RELEVANT_IFLAG(iflag)	(iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
 
-enum port_dev_state {
-	PORT_UNREGISTERED,
-	PORT_REGISTERING,
-	PORT_REGISTERED,
-	PORT_UNREGISTERING,
-};
-
 /* USB serial flags */
 #define USB_SERIAL_WRITE_BUSY	0
 
@@ -124,7 +117,6 @@ struct usb_serial_port {
 	char			throttle_req;
 	unsigned long		sysrq; /* sysrq timeout */
 	struct device		dev;
-	enum port_dev_state	dev_state;
 };
 #define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev)
 
Index: usb-3.3/drivers/usb/serial/usb-serial.c
===================================================================
--- usb-3.3.orig/drivers/usb/serial/usb-serial.c
+++ usb-3.3/drivers/usb/serial/usb-serial.c
@@ -1074,17 +1074,12 @@ int usb_serial_probe(struct usb_interfac
 		port = serial->port[i];
 		dev_set_name(&port->dev, "ttyUSB%d", port->number);
 		dbg ("%s - registering %s", __func__, dev_name(&port->dev));
-		port->dev_state = PORT_REGISTERING;
 		device_enable_async_suspend(&port->dev);
 
 		retval = device_add(&port->dev);
-		if (retval) {
+		if (retval)
 			dev_err(&port->dev, "Error registering port device, "
 				"continuing\n");
-			port->dev_state = PORT_UNREGISTERED;
-		} else {
-			port->dev_state = PORT_REGISTERED;
-		}
 	}
 
 	usb_serial_console_init(debug, minor);
@@ -1128,22 +1123,8 @@ void usb_serial_disconnect(struct usb_in
 			}
 			kill_traffic(port);
 			cancel_work_sync(&port->work);
-			if (port->dev_state == PORT_REGISTERED) {
-
-				/* Make sure the port is bound so that the
-				 * driver's port_remove method is called.
-				 */
-				if (!port->dev.driver) {
-					int rc;
-
-					port->dev.driver =
-							&serial->type->driver;
-					rc = device_bind_driver(&port->dev);
-				}
-				port->dev_state = PORT_UNREGISTERING;
+			if (device_is_registered(&port->dev))
 				device_del(&port->dev);
-				port->dev_state = PORT_UNREGISTERED;
-			}
 		}
 	}
 	serial->type->disconnect(serial);
Index: usb-3.3/drivers/usb/serial/bus.c
===================================================================
--- usb-3.3.orig/drivers/usb/serial/bus.c
+++ usb-3.3/drivers/usb/serial/bus.c
@@ -60,8 +60,6 @@ static int usb_serial_device_probe(struc
 		retval = -ENODEV;
 		goto exit;
 	}
-	if (port->dev_state != PORT_REGISTERING)
-		goto exit;
 
 	driver = port->serial->type;
 	if (driver->port_probe) {
@@ -98,9 +96,6 @@ static int usb_serial_device_remove(stru
 	if (!port)
 		return -ENODEV;
 
-	if (port->dev_state != PORT_UNREGISTERING)
-		return retval;
-
 	device_remove_file(&port->dev, &dev_attr_port_number);
 
 	driver = port->serial->type;

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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux