<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;"># This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.614   -&gt; 1.615  
#	drivers/usb/bluetooth.c	1.16    -&gt; 1.17   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/08/29	greg@kroah.com	1.615
# USB: updated the bluetooth driver to the latest version
# --------------------------------------------
#
diff -Nru a/drivers/usb/bluetooth.c b/drivers/usb/bluetooth.c
--- a/drivers/usb/bluetooth.c	Thu Aug 29 13:55:04 2002
+++ b/drivers/usb/bluetooth.c	Thu Aug 29 13:55:04 2002
@@ -4,8 +4,12 @@
  * Copyright (c) 2000, 2001 Greg Kroah-Hartman	&lt;greg@kroah.com&gt;
  * Copyright (c) 2000 Mark Douglas Corner	&lt;mcorner@umich.edu&gt;
  *
- * USB Bluetooth driver, based on the Bluetooth Spec version 1.0B
+ * USB Bluetooth TTY driver, based on the Bluetooth Spec version 1.0B
  * 
+ * (2001/11/30) Version 0.13 gkh
+ *	- added locking patch from Masoodur Rahman &lt;rmasoodu@in.ibm.com&gt;
+ *	- removed active variable, as open_count will do.
+ *
  * (2001/07/09) Version 0.12 gkh
  *	- removed in_interrupt() call, as it doesn't make sense to do 
  *	  that anymore.
@@ -100,17 +104,14 @@
 
 
 #include &lt;linux/kernel.h&gt;
-#include &lt;linux/sched.h&gt;
-#include &lt;linux/signal.h&gt;
 #include &lt;linux/errno.h&gt;
-#include &lt;linux/poll.h&gt;
 #include &lt;linux/init.h&gt;
 #include &lt;linux/slab.h&gt;
-#include &lt;linux/fcntl.h&gt;
 #include &lt;linux/tty.h&gt;
 #include &lt;linux/tty_driver.h&gt;
 #include &lt;linux/tty_flip.h&gt;
 #include &lt;linux/module.h&gt;
+#include &lt;asm/uaccess.h&gt;
 
 #define DEBUG
 #include &lt;linux/usb.h&gt;
@@ -118,7 +119,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.12"
+#define DRIVER_VERSION "v0.13"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman, Mark Douglas Corner"
 #define DRIVER_DESC "USB Bluetooth tty driver"
 
@@ -170,8 +171,8 @@
 	struct tty_struct *	tty;		/* the coresponding tty for this port */
 
 	unsigned char		minor;		/* the starting minor number for this device */
-	char			active;		/* someone has this device open */
 	int			throttle;	/* throttled by tty layer */
+	int			open_count;
 	
 	__u8			control_out_bInterfaceNum;
 	struct urb *		control_urb_pool[NUM_CONTROL_URBS];
@@ -200,6 +201,7 @@
 	unsigned char		int_buffer[EVENT_BUFFER_SIZE];
 	unsigned int		bulk_packet_pos;
 	unsigned char		bulk_buffer[ACL_BUFFER_SIZE];	/* 64k preallocated, fix? */
+	struct semaphore	lock;
 };
 
 
@@ -232,10 +234,10 @@
 MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids);
 
 static struct usb_driver usb_bluetooth_driver = {
-	name:		"bluetooth",
-	probe:		usb_bluetooth_probe,
-	disconnect:	usb_bluetooth_disconnect,
-	id_table:	usb_bluetooth_ids,
+	.name =		"bluetty",
+	.probe =	usb_bluetooth_probe,
+	.disconnect =	usb_bluetooth_disconnect,
+	.id_table =	usb_bluetooth_ids,
 };
 
 static int			bluetooth_refcount;
@@ -320,7 +322,7 @@
 	}
 	memcpy (urb-&gt;transfer_buffer, buf, len);
 
-	dr-&gt;bRequestType = BLUETOOTH_CONTROL_REQUEST_TYPE;
+	dr-&gt;bRequestType= BLUETOOTH_CONTROL_REQUEST_TYPE;
 	dr-&gt;bRequest = request;
 	dr-&gt;wValue = cpu_to_le16((u16) value);
 	dr-&gt;wIndex = cpu_to_le16((u16) bluetooth-&gt;control_out_bInterfaceNum);
@@ -361,43 +363,46 @@
 		return -ENODEV;
 	}
 
-	if (bluetooth-&gt;active) {
-		dbg ("%s - device already open", __FUNCTION__);
-		return -EINVAL;
-	}
-
-	/* set up our structure making the tty driver remember our object, and us it */
-	tty-&gt;driver_data = bluetooth;
-	bluetooth-&gt;tty = tty;
-
-	/* force low_latency on so that our tty_push actually forces the data through, 
-	 * otherwise it is scheduled, and with high data rates (like with OHCI) data
-	 * can get lost. */
-	bluetooth-&gt;tty-&gt;low_latency = 1;
+	down (&amp;bluetooth-&gt;lock);
+ 
+	++bluetooth-&gt;open_count;
+	if (bluetooth-&gt;open_count == 1) {
+		/* set up our structure making the tty driver remember our object, and us it */
+		tty-&gt;driver_data = bluetooth;
+		bluetooth-&gt;tty = tty;
+
+		/* force low_latency on so that our tty_push actually forces the data through, 
+		 * otherwise it is scheduled, and with high data rates (like with OHCI) data
+		 * can get lost. */
+		bluetooth-&gt;tty-&gt;low_latency = 1;
 	
-	bluetooth-&gt;active = 1;
-
-	/* Reset the packet position counters */
-	bluetooth-&gt;int_packet_pos = 0;
-	bluetooth-&gt;bulk_packet_pos = 0;
+		/* Reset the packet position counters */
+		bluetooth-&gt;int_packet_pos = 0;
+		bluetooth-&gt;bulk_packet_pos = 0;
 
 #ifndef BTBUGGYHARDWARE
-	/* Start reading from the device */
-	FILL_BULK_URB(bluetooth-&gt;read_urb, bluetooth-&gt;dev, 
-		      usb_rcvbulkpipe(bluetooth-&gt;dev, bluetooth-&gt;bulk_in_endpointAddress),
-		      bluetooth-&gt;bulk_in_buffer, bluetooth-&gt;bulk_in_buffer_size, 
-		      bluetooth_read_bulk_callback, bluetooth);
-	result = usb_submit_urb(bluetooth-&gt;read_urb);
-	if (result)
-		dbg("%s - usb_submit_urb(read bulk) failed with status %d", __FUNCTION__, result);
+		/* Start reading from the device */
+		FILL_BULK_URB (bluetooth-&gt;read_urb, bluetooth-&gt;dev, 
+			       usb_rcvbulkpipe(bluetooth-&gt;dev, bluetooth-&gt;bulk_in_endpointAddress),
+			       bluetooth-&gt;bulk_in_buffer,
+			       bluetooth-&gt;bulk_in_buffer_size,
+			       bluetooth_read_bulk_callback, bluetooth);
+		result = usb_submit_urb(bluetooth-&gt;read_urb);
+		if (result)
+			dbg("%s - usb_submit_urb(read bulk) failed with status %d", __FUNCTION__, result);
 #endif
-	FILL_INT_URB(bluetooth-&gt;interrupt_in_urb, bluetooth-&gt;dev, 
-		     usb_rcvintpipe(bluetooth-&gt;dev, bluetooth-&gt;interrupt_in_endpointAddress),
-		     bluetooth-&gt;interrupt_in_buffer, bluetooth-&gt;interrupt_in_buffer_size, 
-		     bluetooth_int_callback, bluetooth, bluetooth-&gt;interrupt_in_interval);
-	result = usb_submit_urb(bluetooth-&gt;interrupt_in_urb);
-	if (result)
-		dbg("%s - usb_submit_urb(interrupt in) failed with status %d", __FUNCTION__, result);
+		FILL_INT_URB (bluetooth-&gt;interrupt_in_urb, bluetooth-&gt;dev, 
+			      usb_rcvintpipe(bluetooth-&gt;dev, bluetooth-&gt;interrupt_in_endpointAddress),
+			      bluetooth-&gt;interrupt_in_buffer,
+			      bluetooth-&gt;interrupt_in_buffer_size,
+			      bluetooth_int_callback, bluetooth,
+			      bluetooth-&gt;interrupt_in_interval);
+		result = usb_submit_urb(bluetooth-&gt;interrupt_in_urb);
+		if (result)
+			dbg("%s - usb_submit_urb(interrupt in) failed with status %d", __FUNCTION__, result);
+	}
+	
+	up(&amp;bluetooth-&gt;lock);
 
 	return 0;
 }
@@ -414,18 +419,24 @@
 
 	dbg("%s", __FUNCTION__);
 
-	if (!bluetooth-&gt;active) {
+	if (!bluetooth-&gt;open_count) {
 		dbg ("%s - device not opened", __FUNCTION__);
 		return;
 	}
 
-	/* shutdown any bulk reads and writes that might be going on */
-	for (i = 0; i &lt; NUM_BULK_URBS; ++i)
-		usb_unlink_urb (bluetooth-&gt;write_urb_pool[i]);
-	usb_unlink_urb (bluetooth-&gt;read_urb);
-	usb_unlink_urb (bluetooth-&gt;interrupt_in_urb);
-
-	bluetooth-&gt;active = 0;
+	down (&amp;bluetooth-&gt;lock);
+ 
+	--bluetooth-&gt;open_count;
+	if (bluetooth-&gt;open_count &lt;= 0) {
+		bluetooth-&gt;open_count = 0;
+
+		/* shutdown any bulk reads and writes that might be going on */
+		for (i = 0; i &lt; NUM_BULK_URBS; ++i)
+			usb_unlink_urb (bluetooth-&gt;write_urb_pool[i]);
+		usb_unlink_urb (bluetooth-&gt;read_urb);
+		usb_unlink_urb (bluetooth-&gt;interrupt_in_urb);
+	}
+	up(&amp;bluetooth-&gt;lock);
 }
 
 
@@ -447,7 +458,7 @@
 
 	dbg("%s - %d byte(s)", __FUNCTION__, count);
 
-	if (!bluetooth-&gt;active) {
+	if (!bluetooth-&gt;open_count) {
 		dbg ("%s - device not opened", __FUNCTION__);
 		return -EINVAL;
 	}
@@ -476,7 +487,10 @@
 			retval = -ENOMEM;
 			goto exit;
 		}
-		copy_from_user (temp_buffer, buf, count);
+		if (copy_from_user (temp_buffer, buf, count)) {
+			retval = -EFAULT;
+			goto exit;
+		}
 		current_buffer = temp_buffer;
 	} else {
 		current_buffer = buf;
@@ -572,7 +586,7 @@
 
 	dbg("%s", __FUNCTION__);
 
-	if (!bluetooth-&gt;active) {
+	if (!bluetooth-&gt;open_count) {
 		dbg ("%s - device not open", __FUNCTION__);
 		return -EINVAL;
 	}
@@ -598,7 +612,7 @@
 		return -ENODEV;
 	}
 
-	if (!bluetooth-&gt;active) {
+	if (!bluetooth-&gt;open_count) {
 		dbg ("%s - device not open", __FUNCTION__);
 		return -EINVAL;
 	}
@@ -624,7 +638,7 @@
 
 	dbg("%s", __FUNCTION__);
 
-	if (!bluetooth-&gt;active) {
+	if (!bluetooth-&gt;open_count) {
 		dbg ("%s - device not open", __FUNCTION__);
 		return;
 	}
@@ -645,7 +659,7 @@
 
 	dbg("%s", __FUNCTION__);
 
-	if (!bluetooth-&gt;active) {
+	if (!bluetooth-&gt;open_count) {
 		dbg ("%s - device not open", __FUNCTION__);
 		return;
 	}
@@ -664,7 +678,7 @@
 
 	dbg("%s - cmd 0x%.4x", __FUNCTION__, cmd);
 
-	if (!bluetooth-&gt;active) {
+	if (!bluetooth-&gt;open_count) {
 		dbg ("%s - device not open", __FUNCTION__);
 		return -ENODEV;
 	}
@@ -684,7 +698,7 @@
 
 	dbg("%s", __FUNCTION__);
 
-	if (!bluetooth-&gt;active) {
+	if (!bluetooth-&gt;open_count) {
 		dbg ("%s - device not open", __FUNCTION__);
 		return;
 	}
@@ -706,7 +720,7 @@
 
 	dbg("%s", __FUNCTION__);
 
-	if (!bluetooth-&gt;active) {
+	if (!bluetooth-&gt;open_count) {
 		dbg ("%s - device not open", __FUNCTION__);
 		return;
 	}
@@ -731,7 +745,7 @@
 
 	dbg("%s", __FUNCTION__);
 
-	if (!bluetooth-&gt;active) {
+	if (!bluetooth-&gt;open_count) {
 		dbg ("%s - device not open", __FUNCTION__);
 		return;
 	}
@@ -961,7 +975,7 @@
 	}	
 
 exit:
-	if (!bluetooth || !bluetooth-&gt;active)
+	if (!bluetooth || !bluetooth-&gt;open_count)
 		return;
 
 	FILL_BULK_URB(bluetooth-&gt;read_urb, bluetooth-&gt;dev, 
@@ -1102,6 +1116,7 @@
 	bluetooth-&gt;minor = minor;
 	bluetooth-&gt;tqueue.routine = bluetooth_softint;
 	bluetooth-&gt;tqueue.data = bluetooth;
+	init_MUTEX(&amp;bluetooth-&gt;lock);
 
 	/* record the interface number for the control out */
 	bluetooth-&gt;control_out_bInterfaceNum = control_out_endpoint;
@@ -1216,10 +1231,10 @@
 	int i;
 
 	if (bluetooth) {
-		if ((bluetooth-&gt;active) &amp;&amp; (bluetooth-&gt;tty))
+		if ((bluetooth-&gt;open_count) &amp;&amp; (bluetooth-&gt;tty))
 			tty_hangup(bluetooth-&gt;tty);
 
-		bluetooth-&gt;active = 0;
+		bluetooth-&gt;open_count = 0;
 
 		if (bluetooth-&gt;read_urb) {
 			usb_unlink_urb (bluetooth-&gt;read_urb);
@@ -1270,30 +1285,30 @@
 
 
 static struct tty_driver bluetooth_tty_driver = {
-	magic:			TTY_DRIVER_MAGIC,
-	driver_name:		"usb-bluetooth",
-	name:			"usb/ttub/%d",
-	major:			BLUETOOTH_TTY_MAJOR,
-	minor_start:		0,
-	num:			BLUETOOTH_TTY_MINORS,
-	type:			TTY_DRIVER_TYPE_SERIAL,
-	subtype:		SERIAL_TYPE_NORMAL,
-	flags:			TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
-
-	refcount:		&amp;bluetooth_refcount,
-	table:			bluetooth_tty,
-	termios:		bluetooth_termios,
-	termios_locked:		bluetooth_termios_locked,
-
-	open:			bluetooth_open,
-	close:			bluetooth_close,
-	write:			bluetooth_write,
-	write_room:		bluetooth_write_room,
-	ioctl:			bluetooth_ioctl,
-	set_termios:		bluetooth_set_termios,
-	throttle:		bluetooth_throttle,
-	unthrottle:		bluetooth_unthrottle,
-	chars_in_buffer:	bluetooth_chars_in_buffer,
+	.magic =		TTY_DRIVER_MAGIC,
+	.driver_name =		"usb-bluetooth",
+	.name =			"usb/ttub/%d",
+	.major =		BLUETOOTH_TTY_MAJOR,
+	.minor_start =		0,
+	.num =			BLUETOOTH_TTY_MINORS,
+	.type =			TTY_DRIVER_TYPE_SERIAL,
+	.subtype =		SERIAL_TYPE_NORMAL,
+	.flags =		TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
+
+	.refcount =		&amp;bluetooth_refcount,
+	.table =		bluetooth_tty,
+	.termios =		bluetooth_termios,
+	.termios_locked =	bluetooth_termios_locked,
+
+	.open =			bluetooth_open,
+	.close =		bluetooth_close,
+	.write =		bluetooth_write,
+	.write_room =		bluetooth_write_room,
+	.ioctl =		bluetooth_ioctl,
+	.set_termios =		bluetooth_set_termios,
+	.throttle =		bluetooth_throttle,
+	.unthrottle =		bluetooth_unthrottle,
+	.chars_in_buffer =	bluetooth_chars_in_buffer,
 };
 
 
</pre></body></html>