patch-2.3.6 linux/net/irda/irda_device.c

Next file: linux/net/irda/irlan/irlan_client.c
Previous file: linux/net/irda/ircomm/irvtd_driver.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.5/linux/net/irda/irda_device.c linux/net/irda/irda_device.c
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Wed Sep  2 20:22:08 1998
- * Modified at:   Mon May 10 23:02:47 1999
+ * Modified at:   Tue Jun  1 09:05:13 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Modified at:   Fri May 28  3:11 CST 1999
  * Modified by:   Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
@@ -105,6 +105,12 @@
 #ifdef CONFIG_NSC_FIR
 	pc87108_init();
 #endif
+#ifdef CONFIG_TOSHIBA_FIR
+	toshoboe_init();
+#endif
+#ifdef CONFIG_SMC_IRCC_FIR
+	ircc_init();
+#endif
 #ifdef CONFIG_ESI_DONGLE
 	esi_init();
 #endif
@@ -117,6 +123,10 @@
 #ifdef CONFIG_GIRBIL_DONGLE
 	girbil_init();
 #endif
+#ifdef CONFIG_GIRBIL_DONGLE
+	litelink_init();
+#endif
+
 	return 0;
 }
 
@@ -169,6 +179,8 @@
 	/* Initialize timers */
 	init_timer(&self->media_busy_timer);	
 
+	self->lock = SPIN_LOCK_UNLOCKED;
+
 	/* A pointer to the low level implementation */
 	self->priv = priv;
 
@@ -200,7 +212,7 @@
 	/* Open network device */
 	dev_open(&self->netdev);
 
-	MESSAGE("IrDA: Registred device %s\n", self->name);
+	MESSAGE("IrDA: Registered device %s\n", self->name);
 
 	irda_device_set_media_busy(self, FALSE);
 
@@ -307,6 +319,8 @@
  */
 static void __irda_device_change_speed(struct irda_device *self, int speed)
 {
+	int n = 0;
+
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRDA_DEVICE_MAGIC, return;);
 	
@@ -314,22 +328,37 @@
 	 *  Is is possible to change speed yet? Wait until the last byte 
 	 *  has been transmitted.
 	 */
-	if (self->wait_until_sent) {
-		self->wait_until_sent(self);
-		
-		if (self->dongle)
-			self->dongle->change_speed(self, speed);
-		
-		if (self->change_speed) {
-			self->change_speed(self, speed);
-			
-			/* Update the QoS value only */
-			self->qos.baud_rate.value = speed;
+	if (!self->wait_until_sent) {
+		ERROR("IrDA: wait_until_sent() "
+		      "has not implemented by the IrDA device driver!\n");
+		return;
+	}
+
+	/* Make sure all transmitted data has actually been sent */
+	self->wait_until_sent(self);
+
+	/* Make sure nobody tries to transmit during the speed change */
+	while (irda_lock((void *) &self->netdev.tbusy) == FALSE) {
+		WARNING(__FUNCTION__ "(), device locked!\n");
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(MSECS_TO_JIFFIES(10));
+
+		if (n++ > 10) {
+			WARNING(__FUNCTION__ "(), breaking loop!\n");
+			break;
 		}
-	} else {
-		WARNING("IrDA: wait_until_sent() "
-			"has not implemented by the IrDA device driver!\n");
 	}
+	
+	if (self->dongle)
+		self->dongle->change_speed(self, speed);
+	
+	if (self->change_speed) {
+		self->change_speed(self, speed);
+		
+		/* Update the QoS value only */
+		self->qos.baud_rate.value = speed;
+	}
+	self->netdev.tbusy = FALSE;
 }
 
 /*
@@ -340,8 +369,6 @@
  */
 inline void irda_device_change_speed(struct irda_device *self, int speed)
 {
-	DEBUG(4, __FUNCTION__ "()\n");
-
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRDA_DEVICE_MAGIC, return;);
 
@@ -352,27 +379,27 @@
 
 inline int irda_device_is_media_busy( struct irda_device *self)
 {
-	ASSERT( self != NULL, return FALSE;);
-	ASSERT( self->magic == IRDA_DEVICE_MAGIC, return FALSE;);
+	ASSERT(self != NULL, return FALSE;);
+	ASSERT(self->magic == IRDA_DEVICE_MAGIC, return FALSE;);
 	
 	return self->media_busy;
 }
 
 inline int irda_device_is_receiving( struct irda_device *self)
 {
-	ASSERT( self != NULL, return FALSE;);
-	ASSERT( self->magic == IRDA_DEVICE_MAGIC, return FALSE;);
+	ASSERT(self != NULL, return FALSE;);
+	ASSERT(self->magic == IRDA_DEVICE_MAGIC, return FALSE;);
 
-	if ( self->is_receiving)
-		return self->is_receiving( self);
+	if (self->is_receiving)
+		return self->is_receiving(self);
 	else
 		return FALSE;
 }
 
-inline struct qos_info *irda_device_get_qos( struct irda_device *self)
+inline struct qos_info *irda_device_get_qos(struct irda_device *self)
 {
-	ASSERT( self != NULL, return NULL;);
-	ASSERT( self->magic == IRDA_DEVICE_MAGIC, return NULL;);
+	ASSERT(self != NULL, return NULL;);
+	ASSERT(self->magic == IRDA_DEVICE_MAGIC, return NULL;);
 
 	return &self->qos;
 }
@@ -394,8 +421,6 @@
 {
 	struct irda_device *self;
 
-	DEBUG(4, __FUNCTION__ "()\n");
-
 	ASSERT(dev != NULL, return -1;);
 
 	self = (struct irda_device *) dev->priv;
@@ -467,6 +492,8 @@
      return 0;  
 }
 
+
+#define SIOCSDONGLE     SIOCDEVPRIVATE
 static int irda_device_net_ioctl(struct device *dev, /* ioctl device */
 				 struct ifreq *rq,   /* Data passed */
 				 int	cmd)	     /* Ioctl number */
@@ -577,6 +604,10 @@
 #endif 
 		break;
 #endif
+	case SIOCSDONGLE: /* Set dongle */
+		/* Initialize dongle */
+		irda_device_init_dongle(self, (int) rq->ifr_data);
+		break;
 	default:
 		ret = -EOPNOTSUPP;
 	}
@@ -652,6 +683,11 @@
 		ERROR("IrDA: Unable to find requested dongle\n");
 		return;
 	}
+	
+	/* Check if we're already using a dongle */
+	if (self->dongle) {
+		self->dongle->close(self);
+	}
 
 	/* Set the dongle to be used by this driver */
 	self->dongle = node->dongle;
@@ -661,7 +697,7 @@
 	node->dongle->qos_init(self, &self->qos);
 	
 	/* Reset dongle */
-	node->dongle->reset(self, 0);
+	node->dongle->reset(self);
 
 	/* Set to default baudrate */
 	irda_device_change_speed(self, 9600);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)