Skip to contentSkip to conversation

sir-dev raw mode fix

PATCH New Jean Tourrilhes 1 participant 1 message Jan 8, 2004 Network drivers

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 sir-dev raw mode fix

irXXX_sirdev_rawmode.diff :
~~~~~~~~~~~~~~~~~~~~~~~~~
<Apply *after* irXXX_sirdev_txlock.diff patch> <Patch from Martin Diehl>
o [CORRECT] Fix sir-dev 'raw' mode for sir dongles that need it

drivers/net/irda/sir-dev.h +1 -0
diff -urp linux-2.6.0-test9-bk22/drivers/net/irda/sir-dev.h v2.6.0-md/drivers/net/irda/sir-dev.h
@@ -179,6 +179,7 @@ struct sir_dev {
 
 	struct sir_fsm fsm;
 	atomic_t enable_rx;
+	int raw_tx;
 	spinlock_t tx_lock;
 
 	u32 new_speed;
drivers/net/irda/sir_dev.c +32 -7
diff -urp linux-2.6.0-test9-bk22/drivers/net/irda/sir_dev.c v2.6.0-md/drivers/net/irda/sir_dev.c
@@ -31,7 +31,9 @@ void sirdev_enable_rx(struct sir_dev *de
 
 	/* flush rx-buffer - should also help in case of problems with echo cancelation */
 	dev->rx_buff.data = dev->rx_buff.head;
-	dev->tx_buff.len = 0;
+	dev->rx_buff.len = 0;
+	dev->rx_buff.in_frame = FALSE;
+	dev->rx_buff.state = OUTSIDE_FRAME;
 	atomic_set(&dev->enable_rx, 1);
 }
 
@@ -78,8 +80,17 @@ int sirdev_raw_write(struct sir_dev *dev
 
 	dev->tx_buff.data = dev->tx_buff.head;
 	memcpy(dev->tx_buff.data, buf, len);	
+	dev->tx_buff.len = len;
 
 	ret = dev->drv->do_write(dev, dev->tx_buff.data, dev->tx_buff.len);
+	if (ret > 0) {
+		IRDA_DEBUG(3, "%s(), raw-tx started\n", __FUNCTION__);
+
+		dev->tx_buff.data += ret;
+		dev->tx_buff.len -= ret;
+		dev->raw_tx = 1;
+		ret = len;		/* all data is going to be sent */
+	}
 	spin_unlock_irqrestore(&dev->tx_lock, flags);
 	return ret;
 }
@@ -95,13 +106,13 @@ int sirdev_raw_read(struct sir_dev *dev,
 
 	count = (len < dev->rx_buff.len) ? len : dev->rx_buff.len;
 
-	if (count > 0)
-		memcpy(buf, dev->rx_buff.head, count);
+	if (count > 0) {
+		memcpy(buf, dev->rx_buff.data, count);
+		dev->rx_buff.data += count;
+		dev->rx_buff.len -= count;
+	}
 
-	/* forget trailing stuff */
-	dev->rx_buff.data = dev->rx_buff.head;
-	dev->rx_buff.len = 0;
-	dev->rx_buff.state = OUTSIDE_FRAME;
+	/* remaining stuff gets flushed when re-enabling normal rx */
 
 	return count;
 }
@@ -150,6 +161,19 @@ void sirdev_write_complete(struct sir_de
 		}
 	}
 
+	if (unlikely(dev->raw_tx != 0)) {
+		/* in raw mode we are just done now after the buffer was sent
+		 * completely. Since this was requested by some dongle driver
+		 * running under the control of the irda-thread we must take
+		 * care here not to re-enable the queue. The queue will be
+		 * restarted when the irda-thread has completed the request.
+		 */
+
+		IRDA_DEBUG(3, "%s(), raw-tx done\n", __FUNCTION__);
+		dev->raw_tx = 0;
+		return;
+	}
+
 	/* we have finished now sending this skb.
 	 * update statistics and free the skb.
 	 * finally we check and trigger a pending speed change, if any.
@@ -482,6 +506,7 @@ static int sirdev_open(struct net_device
 		goto errout_free;
 
 	sirdev_enable_rx(dev);
+	dev->raw_tx = 0;
 
 	netif_start_queue(ndev);
 	dev->irlap = irlap_open(ndev, &dev->qos, dev->hwname);