[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-usb-devel
Subject:    [linux-usb-devel] [bk patch for 2.5] fix module counts for usb serial drivers
From:       ganesh () vxindia ! veritas ! com (V Ganesh)
Date:       2002-03-28 13:39:25
[Download RAW message or body]

hi greg,
	the following patch fixes the problem with decrementing module
counts for usbserial drivers when a disconnect occurs. I know you've got
this in the pipeline, so feel free to ignore this patch. I got a bit tired
of having to reboot due to unloadable modules.
	it's a pretty simple fix - diff makes it look much uglier than it
actually is.

thanks,
ganesh

# This is a BitKeeper generated patch for the following project:
# Project Name: greg k-h's linux 2.5 USB kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.422   -> 1.423  
#	drivers/usb/serial/usbserial.c	1.24    -> 1.25   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/03/29	ganesh@tuxtop.vxindia.veritas.com	1.423
# Module count of a serial converter driver is currently not
# decremented if a disconnect happens while the tty is held open.
# The fix is to close the device in usb_serial_disconnect() so that
# module refcounts are properly updated.
# --------------------------------------------
#
diff -Nru a/drivers/usb/serial/usbserial.c b/drivers/usb/serial/usbserial.c
--- a/drivers/usb/serial/usbserial.c	Fri Mar 29 05:30:33 2002
+++ b/drivers/usb/serial/usbserial.c	Fri Mar 29 05:30:33 2002
@@ -552,43 +552,45 @@
 	return retval;
 }
 
-static void serial_close(struct tty_struct *tty, struct file * filp)
+static void __serial_close(struct usb_serial_port *port, struct file *filp)
 {
-	struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
-	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
-
-	if (!serial)
-		return;
-
-	down (&port->sem);
-
-	dbg(__FUNCTION__ " - port %d", port->number);
-
-	if (tty->driver_data == NULL) {
-		/* disconnect beat us to the punch here, so handle it gracefully */
-		goto exit;
-	}
 	if (!port->open_count) {
 		dbg (__FUNCTION__ " - port not opened");
-		goto exit_no_mod_dec;
+		return;
 	}
 
 	--port->open_count;
 	if (port->open_count <= 0) {
 		/* only call the device specific close if this 
 		 * port is being closed by the last owner */
-		if (serial->type->close)
-			serial->type->close(port, filp);
+		if (port->serial->type->close)
+			port->serial->type->close(port, filp);
 		else
 			generic_close(port, filp);
 		port->open_count = 0;
 	}
 
-exit:
-	if (serial->type->owner)
-		__MOD_DEC_USE_COUNT(serial->type->owner);
+	if (port->serial->type->owner)
+		__MOD_DEC_USE_COUNT(port->serial->type->owner);
+}
+
+static void serial_close(struct tty_struct *tty, struct file * filp)
+{
+	struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
+	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
+
+	if (!serial)
+		return;
+
+	down (&port->sem);
+
+	dbg(__FUNCTION__ " - port %d", port->number);
+
+	/* if disconnect beat us to the punch here, there's nothing to do */
+	if (tty->driver_data) {
+		__serial_close(port, filp);
+	}
 
-exit_no_mod_dec:
 	up (&port->sem);
 }
 
@@ -1355,10 +1357,15 @@
 	if (serial) {
 		/* fail all future close/read/write/ioctl/etc calls */
 		for (i = 0; i < serial->num_ports; ++i) {
-			down (&serial->port[i].sem);
-			if (serial->port[i].tty != NULL)
-				serial->port[i].tty->driver_data = NULL;
-			up (&serial->port[i].sem);
+			port = &serial->port[i];
+			down (&port->sem);
+			if (port->tty != NULL) {
+				while (port->open_count > 0) {
+					__serial_close(port, NULL);
+				}
+				port->tty->driver_data = NULL;
+			}
+			up (&port->sem);
 		}
 
 		serial->dev = NULL;
This BitKeeper patch contains the following changesets:
+
## Wrapped with gzip_uu ##


begin 664 bkpatch4395
M'XL(`-FNHSP``ZU6;5/;1A#^+/V*33)-L8-DO5BV9<8,"="6*0&&X$]-1W/2
MG2T-LDX]G7B9./^]>SK;&+!)VH0QUOEN]]G79T]O8%PQ,32FI&!5:KZ!/W@E
MAX:L[R0O[9N[K*`9L6^8R"2I[(3/4.22<Q3II'S&.EJO<\O%=:>N8LNS`TO]
MR(JIB:(71"8IH'HU-%S;7^W(^Y(-C<OCW\>G[R]-<S2"PY044_:)21B-S/CZ
M@-8LMZ\%)ZG-Q72^.IY[CN.ZKA<X?M!S@[DW\/WNW.TY,<4E]?KA).Z%)B4W
M&;7B@Y(D,<MSNT#-1QB>XWL]SPD\QYO[03#HFD?@VEW/!\?K.'['"\$)AEXX
M#/QWN/`=T*$>;$\-O'/!<LP/\./N'YH)?.2TSADDO"XD\`D0P$IE),>=`JU*
M)H"*#%>059#40K!"YO=0<(G*E"6"S7"'4<B4+LTJU"M8(B$E9<F*"F[3#/%E
MBO_R7H&D+*?`\<Q&A"O<GV1W:E]R2')>:5G*;K*$058`UCO2+D4/Z#LMJ#@*
M$N7%3(<@V*2)H@(B&)0"30CTM"XI0?]L\T_P^T'HFA</76!:__'/-!WBF/L;
M<J^35*GV[&AWU5*O[.2A(%TG=`=SMSOPO#D-)UW6&_A>W(VI[[C?+OYWF%$M
M-_#\(`S\N8-U[S>-_[+>9C;\C)#,J6#3`XWY_?XKZ*[CS'M>SPD;RGC!CS#&
M]\'R>C^-,^\IQ88G,*F+1&:\@&C9H4T#8W-BT^/\P6:5)$,.J(Z>UMB9?(+J
MCV5M.%%D*6C.JH86FHO5+B0DS[7N@H%+=%X@2DXJN2`,*C]0L5KR05,::2G8
M/W4F%`42>&9>,:_*9B4RA<"M4*052"#4I5O"0@A)KM'9D@MI[5=LM@#>QE0=
MQS,PY/N$BR2+T;2.`S$49M4$A'$+%N,1QYF3J)FS"O%)A)@Q@MIJ>*F9M#*M
M*-\0X!PL<=M\D,$7W^#"_Y@)1T$0@&N>Z$<EB<P2N.'9LPQ64M0X&M<2I>*%
MMOK>A<7I1,W+-GZ7+87<!Q=OC:#O-Q::AV$()FM1[.'^P`$/]P<N/@P#J[VS
M+(O"M_;5'6CM-^9;*&!L/=W13C1V&^`^^`HX!,\QMP+SVX()!1Q%'\^/HJ/C
MPVC\Z3@Z/!^?7;V@L&=^-3\_RM2F/.&%$2V6;5P_R9!VU?QB&B^E%4:P->TM
M9<':U_T0X35!]C:`07OQ',&4R6CM8)&R*/IM?'9X=7)^%D48V6>=K5=:J+56
M+3RA&#_LO%U11\O3>+JSC@*OP6JH`+_0U[L+HA7U+&Y2APJ=MB+VVFT;,Z)\
M5J12`Z/$R92"8M"N)M*OE;JR4WQA4B*40[NCW7R:@19\::KYJ!Z/6L/XBMT1
MNMB'1ZX?#*!KGKA^SX5PV5Z8J+?+HJO??V5_[ZFS#;$;ZRVKW@]>C>!L?'JJ
MO3`,_?*P.%?#,=*<WP=G*;+9UP:DP4=WC57?/XT6M+E&L)&KRR<>KEXFDY0E
5UU4]&_F#28!W76S^"T"8]2'6"@``
`
end

_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic