patch-2.3.24 linux/drivers/net/irda/irport.c

Next file: linux/drivers/net/irda/irtty.c
Previous file: linux/drivers/net/irda/girbil.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.23/linux/drivers/net/irda/irport.c linux/drivers/net/irda/irport.c
@@ -6,7 +6,7 @@
  * Status:	  Experimental.
  * Author:	  Dag Brattli <dagb@cs.uit.no>
  * Created at:	  Sun Aug  3 13:49:59 1997
- * Modified at:   Tue Aug 31 13:54:27 1999
+ * Modified at:   Wed Oct 20 00:07:42 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:	  serial.c by Linus Torvalds 
  * 
@@ -48,6 +48,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <linux/rtnetlink.h>
 
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -69,22 +70,22 @@
 
 static unsigned int qos_mtt_bits = 0x03;
 
-static struct irda_device *dev_self[] = { NULL, NULL, NULL, NULL};
+static struct irport_cb *dev_self[] = { NULL, NULL, NULL, NULL};
 static char *driver_name = "irport";
 
 static int irport_open(int i, unsigned int iobase, unsigned int irq);
-static int irport_close(struct irda_device *idev);
+static int irport_close(struct irport_cb *self);
 
-static void irport_write_wakeup(struct irda_device *idev);
+static void irport_write_wakeup(struct irport_cb *self);
 static int  irport_write(int iobase, int fifo_size, __u8 *buf, int len);
-static void irport_receive(struct irda_device *idev);
+static void irport_receive(struct irport_cb *self);
 
 static int  irport_net_init(struct net_device *dev);
 static int  irport_net_open(struct net_device *dev);
 static int  irport_net_close(struct net_device *dev);
-static int  irport_is_receiving(struct irda_device *idev);
-static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts);
-static int  irport_raw_write(struct irda_device *idev, __u8 *buf, int len);
+static int  irport_is_receiving(struct irport_cb *self);
+static void irport_set_dtr_rts(struct net_device *dev, int dtr, int rts);
+static int  irport_raw_write(struct net_device *dev, __u8 *buf, int len);
 
 int __init irport_init(void)
 {
@@ -114,7 +115,7 @@
 {
  	int i;
 
-        DEBUG( 4, __FUNCTION__ "()\n");
+        IRDA_DEBUG( 4, __FUNCTION__ "()\n");
 
 	for (i=0; i < 4; i++) {
  		if (dev_self[i])
@@ -125,108 +126,154 @@
 
 static int irport_open(int i, unsigned int iobase, unsigned int irq)
 {
-	struct irda_device *idev;
+	struct net_device *dev;
+	struct irport_cb *self;
 	int ret;
+	int err;
 
-	DEBUG( 0, __FUNCTION__ "()\n");
-
-/* 	if (irport_probe(iobase, irq) == -1) */
-/* 		return -1; */
+	IRDA_DEBUG(0, __FUNCTION__ "()\n");
 
 	/*
 	 *  Allocate new instance of the driver
 	 */
-	idev = kmalloc(sizeof(struct irda_device), GFP_KERNEL);
-	if (idev == NULL) {
-		printk( KERN_ERR "IrDA: Can't allocate memory for "
-			"IrDA control block!\n");
+	self = kmalloc(sizeof(struct irport_cb), GFP_KERNEL);
+	if (!self) {
+		ERROR(__FUNCTION__ "(), can't allocate memory for "
+		      "control block!\n");
 		return -ENOMEM;
 	}
-	memset(idev, 0, sizeof(struct irda_device));
+	memset(self, 0, sizeof(struct irport_cb));
    
+	spin_lock_init(&self->lock);
+
 	/* Need to store self somewhere */
-	dev_self[i] = idev;
+	dev_self[i] = self;
 
 	/* Initialize IO */
-	idev->io.iobase2   = iobase;
-        idev->io.irq2      = irq;
-        idev->io.io_ext    = IO_EXTENT;
-        idev->io.fifo_size = 16;
-
-	idev->netdev.base_addr = iobase;
-	idev->netdev.irq = irq;
+	self->io.iobase2   = iobase;
+        self->io.irq2      = irq;
+        self->io.io_ext    = IO_EXTENT;
+        self->io.fifo_size = 16;
 
 	/* Lock the port that we need */
-	ret = check_region(idev->io.iobase2, idev->io.io_ext);
+	ret = check_region(self->io.iobase2, self->io.io_ext);
 	if (ret < 0) { 
-		DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
-		      idev->io.iobase2);
-		/* irport_cleanup(self->idev);  */
+		IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
+		      self->io.iobase2);
+		/* irport_cleanup(self->self);  */
 		return -ENODEV;
 	}
-	request_region(idev->io.iobase2, idev->io.io_ext, idev->name);
+	request_region(self->io.iobase2, self->io.io_ext, driver_name);
 
 	/* Initialize QoS for this device */
-	irda_init_max_qos_capabilies(&idev->qos);
+	irda_init_max_qos_capabilies(&self->qos);
 	
-	idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
+	self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
 		IR_115200;
 
-	idev->qos.min_turn_time.bits = qos_mtt_bits;
-	irda_qos_bits_to_value(&idev->qos);
+	self->qos.min_turn_time.bits = qos_mtt_bits;
+	irda_qos_bits_to_value(&self->qos);
 	
-	idev->flags = IFF_SIR|IFF_PIO;
+	self->flags = IFF_SIR|IFF_PIO;
+
+	/* Specify how much memory we want */
+	self->rx_buff.truesize = 4000; 
+	self->tx_buff.truesize = 4000;
+	
+	/* Allocate memory if needed */
+	if (self->rx_buff.truesize > 0) {
+		self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
+						      GFP_KERNEL);
+		if (self->rx_buff.head == NULL)
+			return -ENOMEM;
+		memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+	}
+	if (self->tx_buff.truesize > 0) {
+		self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
+						      GFP_KERNEL);
+		if (self->tx_buff.head == NULL) {
+			kfree(self->rx_buff.head);
+			return -ENOMEM;
+		}
+		memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+	}	
+	self->rx_buff.in_frame = FALSE;
+	self->rx_buff.state = OUTSIDE_FRAME;
+	self->tx_buff.data = self->tx_buff.head;
+	self->rx_buff.data = self->rx_buff.head;
+	self->mode = IRDA_IRLAP;
 
-	/* Specify which buffer allocation policy we need */
-	idev->rx_buff.flags = GFP_KERNEL;
-	idev->tx_buff.flags = GFP_KERNEL;
-
-	idev->rx_buff.truesize = 4000; 
-	idev->tx_buff.truesize = 4000;
-	
-	/* Initialize callbacks */
-	idev->change_speed    = irport_change_speed;
-	idev->wait_until_sent = irport_wait_until_sent;
-        idev->is_receiving    = irport_is_receiving;
-	idev->set_dtr_rts     = irport_set_dtr_rts;
-	idev->raw_write       = irport_raw_write;
+	if (!(dev = dev_alloc("irda%d", &err))) {
+		ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
+		return -ENOMEM;
+	}
+	/* dev_alloc doesn't clear the struct, so lets do a little hack */
+	memset(((__u8*)dev)+sizeof(char*),0,sizeof(struct net_device)-sizeof(char*));
+
+ 	dev->priv = (void *) self;
+	self->netdev = dev;
 
 	/* Override the network functions we need to use */
-	idev->netdev.init            = irport_net_init;
-	idev->netdev.hard_start_xmit = irport_hard_xmit;
-	idev->netdev.open            = irport_net_open;
-	idev->netdev.stop            = irport_net_close;
+	dev->init            = irport_net_init;
+	dev->hard_start_xmit = irport_hard_xmit;
+	dev->open            = irport_net_open;
+	dev->stop            = irport_net_close;
+
+	/* Make ifconfig display some details */
+	dev->base_addr = iobase;
+	dev->irq = irq;
+
+	rtnl_lock();
+	err = register_netdevice(dev);
+	rtnl_unlock();
+	if (err) {
+		ERROR(__FUNCTION__ "(), register_netdev() failed!\n");
+		return -1;
+	}
+	MESSAGE("IrDA: Registered device %s\n", dev->name);
 
-	/* Open the IrDA device */
-	irda_device_open(idev, driver_name, NULL);
-	
 	return 0;
 }
 
-static int irport_close(struct irda_device *idev)
+static int irport_close(struct irport_cb *self)
 {
-	ASSERT(idev != NULL, return -1;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+	ASSERT(self != NULL, return -1;);
 
-	/* Release the IO-port that this driver is using */
-	DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", 
-	      idev->io.iobase2);
-	release_region(idev->io.iobase2, idev->io.io_ext);
+	/* We are not using any dongle anymore! */
+	if (self->dongle)
+		irda_device_dongle_cleanup(self->dongle);
+	self->dongle = NULL;
+	
+	/* Remove netdevice */
+	if (self->netdev) {
+		rtnl_lock();
+		unregister_netdevice(self->netdev);
+		rtnl_unlock();
+	}
 
-	irda_device_close(idev);
+	/* Release the IO-port that this driver is using */
+	IRDA_DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", 
+	      self->io.iobase2);
+	release_region(self->io.iobase2, self->io.io_ext);
 
-	kfree(idev);
+	if (self->tx_buff.head)
+		kfree(self->tx_buff.head);
+	
+	if (self->rx_buff.head)
+		kfree(self->rx_buff.head);
+	
+	kfree(self);
 
 	return 0;
 }
 
-void irport_start(struct irda_device *idev, int iobase)
+void irport_start(struct irport_cb *self, int iobase)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&idev->lock, flags);
+	spin_lock_irqsave(&self->lock, flags);
 
-	irport_stop(idev, iobase);
+	irport_stop(self, iobase);
 
 	/* Initialize UART */
 	outb(UART_LCR_WLEN8, iobase+UART_LCR);  /* Reset DLAB */
@@ -235,14 +282,14 @@
 	/* Turn on interrups */
 	outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, iobase+UART_IER);
 
-	spin_unlock_irqrestore(&idev->lock, flags);
+	spin_unlock_irqrestore(&self->lock, flags);
 }
 
-void irport_stop(struct irda_device *idev, int iobase)
+void irport_stop(struct irport_cb *self, int iobase)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&idev->lock, flags);
+	spin_lock_irqsave(&self->lock, flags);
 
 	/* Reset UART */
 	outb(0, iobase+UART_MCR);
@@ -250,7 +297,7 @@
 	/* Turn off interrupts */
 	outb(0, iobase+UART_IER);
 
-	spin_unlock_irqrestore(&idev->lock, flags);
+	spin_unlock_irqrestore(&self->lock, flags);
 }
 
 /*
@@ -261,18 +308,18 @@
  */
 int irport_probe(int iobase)
 {
-	DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase);
+	IRDA_DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase);
 
 	return 0;
 }
 
 /*
- * Function irport_change_speed (idev, speed)
+ * Function irport_change_speed (self, speed)
  *
  *    Set speed of IrDA port to specified baudrate
  *
  */
-void irport_change_speed(struct irda_device *idev, __u32 speed)
+void irport_change_speed(struct irport_cb *self, __u32 speed)
 {
 	unsigned long flags;
 	int iobase; 
@@ -280,17 +327,16 @@
 	int lcr;    /* Line control reg */
 	int divisor;
 
-	DEBUG(2, __FUNCTION__ "(), Setting speed to: %d\n", speed);
+	IRDA_DEBUG(2, __FUNCTION__ "(), Setting speed to: %d\n", speed);
 
-	ASSERT(idev != NULL, return;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
+	ASSERT(self != NULL, return;);
 
-	iobase = idev->io.iobase2;
+	iobase = self->io.iobase2;
 	
 	/* Update accounting for new speed */
-	idev->io.baudrate = speed;
+	self->io.speed = speed;
 
-	spin_lock_irqsave(&idev->lock, flags);
+	spin_lock_irqsave(&self->lock, flags);
 
 	/* Turn off interrupts */
 	outb(0, iobase+UART_IER); 
@@ -304,7 +350,7 @@
 	 * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
 	 * about this timeout since it will always be fast enough. 
 	 */
-	if (idev->io.baudrate < 38400)
+	if (self->io.speed < 38400)
 		fcr |= UART_FCR_TRIGGER_1;
 	else 
 		fcr |= UART_FCR_TRIGGER_14;
@@ -321,7 +367,7 @@
 	/* Turn on interrups */
 	outb(/*UART_IER_RLSI|*/UART_IER_RDI/*|UART_IER_THRI*/, iobase+UART_IER);
 
-	spin_unlock_irqrestore(&idev->lock, flags);
+	spin_unlock_irqrestore(&self->lock, flags);
 }
 
 /*
@@ -331,39 +377,38 @@
  *    more packets to send, we send them here.
  *
  */
-static void irport_write_wakeup(struct irda_device *idev)
+static void irport_write_wakeup(struct irport_cb *self)
 {
 	int actual = 0;
 	int iobase;
 	int fcr;
 
-	ASSERT(idev != NULL, return;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
+	ASSERT(self != NULL, return;);
 
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	/* Finished with frame?  */
-	if (idev->tx_buff.len > 0)  {
+	if (self->tx_buff.len > 0)  {
 		/* Write data left in transmit buffer */
-		actual = irport_write(idev->io.iobase2, idev->io.fifo_size, 
-				      idev->tx_buff.data, idev->tx_buff.len);
-		idev->tx_buff.data += actual;
-		idev->tx_buff.len  -= actual;
+		actual = irport_write(self->io.iobase2, self->io.fifo_size, 
+				      self->tx_buff.data, self->tx_buff.len);
+		self->tx_buff.data += actual;
+		self->tx_buff.len  -= actual;
 	} else {
-		iobase = idev->io.iobase2;
+		iobase = self->io.iobase2;
 		/* 
 		 *  Now serial buffer is almost free & we can start 
 		 *  transmission of another packet 
 		 */
-		idev->netdev.tbusy = 0; /* Unlock */
-		idev->stats.tx_packets++;
+		self->netdev->tbusy = 0; /* Unlock */
+		self->stats.tx_packets++;
 
 		/* Schedule network layer, so we can get some more frames */
 		mark_bh(NET_BH);
 
 		fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR;
 
-		if (idev->io.baudrate < 38400)
+		if (self->io.speed < 38400)
 			fcr |= UART_FCR_TRIGGER_1;
 		else 
 			fcr |= UART_FCR_TRIGGER_14;
@@ -391,7 +436,7 @@
 
 	/* Tx FIFO should be empty! */
 	if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
-		DEBUG(0, __FUNCTION__ "(), failed, fifo not empty!\n");
+		IRDA_DEBUG(0, __FUNCTION__ "(), failed, fifo not empty!\n");
 		return -1;
 	}
         
@@ -415,19 +460,19 @@
  */
 int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct irda_device *idev;
+	struct irport_cb *self;
 	unsigned long flags;
 	int actual = 0;
 	int iobase;
+	__u32 speed;
 
 	ASSERT(dev != NULL, return 0;);
 	
-	idev = (struct irda_device *) dev->priv;
+	self = (struct irport_cb *) dev->priv;
 
-	ASSERT(idev != NULL, return 0;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+	ASSERT(self != NULL, return 0;);
 
-	iobase = idev->io.iobase2;
+	iobase = self->io.iobase2;
 
 	/* Lock transmit buffer */
 	if (irda_lock((void *) &dev->tbusy) == FALSE) {
@@ -436,28 +481,32 @@
 			return -EBUSY;
 
 		WARNING("%s: transmit timed out\n", dev->name);
-		irport_start(idev, iobase);
-		irport_change_speed(idev, idev->io.baudrate);
+		irport_start(self, iobase);
+		irport_change_speed(self, self->io.speed );
 
 		dev->trans_start = jiffies;
 	}
 
-	spin_lock_irqsave(&idev->lock, flags);
+	/* Check if we need to change the speed */
+	if ((speed = irda_get_speed(skb)) != self->io.speed)
+		irport_change_speed(self, speed);
+
+	spin_lock_irqsave(&self->lock, flags);
 
 	/* Init tx buffer */
-	idev->tx_buff.data = idev->tx_buff.head;
+	self->tx_buff.data = self->tx_buff.head;
 
         /* Copy skb to tx_buff while wrapping, stuffing and making CRC */
-	idev->tx_buff.len = async_wrap_skb(skb, idev->tx_buff.data, 
-					   idev->tx_buff.truesize);
+	self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, 
+					   self->tx_buff.truesize);
 	
-	idev->tx_buff.data += actual;
-	idev->tx_buff.len  -= actual;
+	self->tx_buff.data += actual;
+	self->tx_buff.len  -= actual;
 
 	/* Turn on transmit finished interrupt. Will fire immediately!  */
 	outb(UART_IER_THRI, iobase+UART_IER); 
 
-	spin_unlock_irqrestore(&idev->lock, flags);
+	spin_unlock_irqrestore(&self->lock, flags);
 
 	dev_kfree_skb(skb);
 	
@@ -465,30 +514,31 @@
 }
         
 /*
- * Function irport_receive (idev)
+ * Function irport_receive (self)
  *
  *    Receive one frame from the infrared port
  *
  */
-static void irport_receive(struct irda_device *idev) 
+static void irport_receive(struct irport_cb *self) 
 {
 	int boguscount = 0;
 	int iobase;
 
-	ASSERT(idev != NULL, return;);
+	ASSERT(self != NULL, return;);
 
-	iobase = idev->io.iobase2;
+	iobase = self->io.iobase2;
 
 	/*  
 	 * Receive all characters in Rx FIFO, unwrap and unstuff them. 
          * async_unwrap_char will deliver all found frames  
 	 */
 	do {
-		async_unwrap_char(idev, inb(iobase+UART_RX));
+		async_unwrap_char(self->netdev, &self->rx_buff, 
+				  inb(iobase+UART_RX));
 
 		/* Make sure we don't stay here to long */
 		if (boguscount++ > 32) {
-			DEBUG(2,__FUNCTION__ "(), breaking!\n");
+			IRDA_DEBUG(2,__FUNCTION__ "(), breaking!\n");
 			break;
 		}
 	} while (inb(iobase+UART_LSR) & UART_LSR_DR);	
@@ -501,45 +551,47 @@
  */
 void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs) 
 {
-	struct irda_device *idev = (struct irda_device *) dev_id;
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct irport_cb *self;
+	int boguscount = 0;
 	int iobase;
 	int iir, lsr;
-	int boguscount = 0;
 
-	if (!idev) {
+	if (!dev) {
 		WARNING(__FUNCTION__ "() irq %d for unknown device.\n", irq);
 		return;
 	}
+	self = (struct irport_cb *) dev->priv;
 
-	spin_lock(&idev->lock);
+	spin_lock(&self->lock);
 
-	idev->netdev.interrupt = 1;
+	dev->interrupt = 1;
 
-	iobase = idev->io.iobase2;
+	iobase = self->io.iobase2;
 
 	iir = inb(iobase+UART_IIR) & UART_IIR_ID;
 	while (iir) {
 		/* Clear interrupt */
 		lsr = inb(iobase+UART_LSR);
 
-		DEBUG(4, __FUNCTION__ "(), iir=%02x, lsr=%02x, iobase=%#x\n", 
+		IRDA_DEBUG(4, __FUNCTION__ "(), iir=%02x, lsr=%02x, iobase=%#x\n", 
 		      iir, lsr, iobase);
 
 		switch (iir) {
 		case UART_IIR_RLSI:
-			DEBUG(2, __FUNCTION__ "(), RLSI\n");
+			IRDA_DEBUG(2, __FUNCTION__ "(), RLSI\n");
 			break;
 		case UART_IIR_RDI:
 			/* Receive interrupt */
-			irport_receive(idev);
+			irport_receive(self);
 			break;
 		case UART_IIR_THRI:
 			if (lsr & UART_LSR_THRE)
 				/* Transmitter ready for data */
-				irport_write_wakeup(idev);
+				irport_write_wakeup(self);
 			break;
 		default:
-			DEBUG(0, __FUNCTION__ "(), unhandled IIR=%#x\n", iir);
+			IRDA_DEBUG(0, __FUNCTION__ "(), unhandled IIR=%#x\n", iir);
 			break;
 		} 
 		
@@ -549,9 +601,9 @@
 
  	        iir = inb(iobase + UART_IIR) & UART_IIR_ID;
 	}
-	idev->netdev.interrupt = 0;
+	dev->interrupt = 0;
 
-	spin_unlock(&idev->lock);
+	spin_unlock(&self->lock);
 }
 
 static int irport_net_init(struct net_device *dev)
@@ -572,24 +624,32 @@
  */
 static int irport_net_open(struct net_device *dev)
 {
-	struct irda_device *idev;
+	struct irport_cb *self;
 	int iobase;
 
 	ASSERT(dev != NULL, return -1;);
-	idev = (struct irda_device *) dev->priv;
+	self = (struct irport_cb *) dev->priv;
 
-	iobase = idev->io.iobase2;
+	iobase = self->io.iobase2;
 
-	if (request_irq(idev->io.irq2, irport_interrupt, 0, idev->name, 
-			(void *) idev))
+	if (request_irq(self->io.irq2, irport_interrupt, 0, dev->name, 
+			(void *) dev))
 		return -EAGAIN;
 
-	irport_start(idev, iobase);
-	irda_device_net_open(dev);
+	irport_start(self, iobase);
 
-	/* Change speed to make sure dongles follow us again */
-	if (idev->change_speed)
-		idev->change_speed(idev, 9600);
+	/* Ready to play! */
+	dev->tbusy = 0;
+	dev->interrupt = 0;
+	dev->start = 1;
+
+	/* 
+	 * Open new IrLAP layer instance, now that everything should be
+	 * initialized properly 
+	 */
+	self->irlap = irlap_open(dev, &self->qos);
+
+	/* FIXME: change speed of dongle */
 
 	MOD_INC_USE_COUNT;
 
@@ -597,30 +657,37 @@
 }
 
 /*
- * Function irport_net_close (idev)
+ * Function irport_net_close (self)
  *
  *    
  *
  */
 static int irport_net_close(struct net_device *dev)
 {
-	struct irda_device *idev;
+	struct irport_cb *self;
 	int iobase;
 
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(dev != NULL, return -1;);
-	idev = (struct irda_device *) dev->priv;
+	self = (struct irport_cb *) dev->priv;
+
+	ASSERT(self != NULL, return -1;);
 
-	ASSERT(idev != NULL, return -1;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;)
+	iobase = self->io.iobase2;
 
-	iobase = idev->io.iobase2;
+	/* Stop device */
+	dev->tbusy = 1;
+	dev->start = 0;
 
-	irda_device_net_close(dev);
-	irport_stop(idev, iobase);
+	/* Stop and remove instance of IrLAP */
+	if (self->irlap)
+		irlap_close(self->irlap);
+	self->irlap = NULL;
 
-	free_irq(idev->io.irq2, idev);
+	irport_stop(self, iobase);
+
+	free_irq(self->io.irq2, dev);
 
 	MOD_DEC_USE_COUNT;
 
@@ -628,34 +695,36 @@
 }
 
 /*
- * Function irport_wait_until_sent (idev)
+ * Function irport_wait_until_sent (self)
  *
  *    Delay exectution until finished transmitting
  *
  */
-void irport_wait_until_sent(struct irda_device *idev)
+#if 0
+void irport_wait_until_sent(struct irport_cb *self)
 {
 	int iobase;
 
-	iobase = idev->io.iobase2;
+	iobase = self->io.iobase2;
 
 	/* Wait until Tx FIFO is empty */
 	while (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
-		DEBUG(2, __FUNCTION__ "(), waiting!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), waiting!\n");
 		current->state = TASK_INTERRUPTIBLE;
 		schedule_timeout(MSECS_TO_JIFFIES(60));
 	}
 }
+#endif
 
 /*
- * Function irport_is_receiving (idev)
+ * Function irport_is_receiving (self)
  *
  *    Returns true is we are currently receiving data
  *
  */
-static int irport_is_receiving(struct irda_device *idev)
+static int irport_is_receiving(struct irport_cb *self)
 {
-	return (idev->rx_buff.state != OUTSIDE_FRAME);
+	return (self->rx_buff.state != OUTSIDE_FRAME);
 }
 
 /*
@@ -664,14 +733,14 @@
  *    This function can be used by dongles etc. to set or reset the status
  *    of the dtr and rts lines
  */
-static void irport_set_dtr_rts(struct irda_device *idev, int dtr, int rts)
+static void irport_set_dtr_rts(struct net_device *dev, int dtr, int rts)
 {
+	struct irport_cb *self = dev->priv;
 	int iobase;
 
-	ASSERT(idev != NULL, return;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
+	ASSERT(self != NULL, return;);
 
-	iobase = idev->io.iobase2;
+	iobase = self->io.iobase2;
 
 	if (dtr)
 		dtr = UART_MCR_DTR;
@@ -681,19 +750,19 @@
 	outb(dtr|rts|UART_MCR_OUT2, iobase+UART_MCR);
 }
 
-static int irport_raw_write(struct irda_device *idev, __u8 *buf, int len)
+static int irport_raw_write(struct net_device *dev, __u8 *buf, int len)
 {
-	int iobase;
+	struct irport_cb *self = (struct irport_cb *) dev->priv;
 	int actual = 0;
+	int iobase;
 
-	ASSERT(idev != NULL, return -1;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+	ASSERT(self != NULL, return -1;);
 
-	iobase = idev->io.iobase2;
+	iobase = self->io.iobase2;
 
 	/* Tx FIFO should be empty! */
 	if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
-		DEBUG( 0, __FUNCTION__ "(), failed, fifo not empty!\n");
+		IRDA_DEBUG( 0, __FUNCTION__ "(), failed, fifo not empty!\n");
 		return -1;
 	}
         
@@ -708,33 +777,20 @@
 }
 
 #ifdef MODULE
-
 MODULE_PARM(io, "1-4i");
 MODULE_PARM(irq, "1-4i");
 
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
 MODULE_DESCRIPTION("Half duplex serial driver for IrDA SIR mode");
 
-/*
- * Function cleanup_module (void)
- *
- *    
- *
- */
 void cleanup_module(void)
 {
 	irport_cleanup();
 }
 
-/*
- * Function init_module (void)
- *
- *    
- */
 int init_module(void)
 {
 	return irport_init();
 }
-
 #endif /* MODULE */
 

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