patch-2.2.7 linux/drivers/net/irda/irtty.c
Next file: linux/drivers/net/irda/pc87108.c
Previous file: linux/drivers/net/irda/irport.c
Back to the patch index
Back to the overall index
- Lines: 668
- Date:
Sat Apr 24 17:49:37 1999
- Orig file:
v2.2.6/linux/drivers/net/irda/irtty.c
- Orig date:
Fri Apr 16 14:47:30 1999
diff -u --recursive --new-file v2.2.6/linux/drivers/net/irda/irtty.c linux/drivers/net/irda/irtty.c
@@ -6,7 +6,7 @@
* Status: Experimental.
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Tue Dec 9 21:18:38 1997
- * Modified at: Tue Apr 6 21:35:25 1999
+ * Modified at: Thu Apr 22 09:20:24 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
* Sources: slip.c by Laurence Culhane, <loz@holmes.demon.co.uk>
* Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
@@ -45,22 +45,22 @@
static struct tty_ldisc irda_ldisc;
-static int irtty_hard_xmit( struct sk_buff *skb, struct device *dev);
-static void irtty_wait_until_sent( struct irda_device *driver);
-static int irtty_is_receiving( struct irda_device *idev);
-static int irtty_net_init( struct device *dev);
+static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev);
+static void irtty_wait_until_sent(struct irda_device *driver);
+static int irtty_is_receiving(struct irda_device *idev);
+static int irtty_net_init(struct device *dev);
static int irtty_net_open(struct device *dev);
static int irtty_net_close(struct device *dev);
-static int irtty_open( struct tty_struct *tty);
-static void irtty_close( struct tty_struct *tty);
-static int irtty_ioctl( struct tty_struct *, void *, int, void *);
-static int irtty_receive_room( struct tty_struct *tty);
-static void irtty_change_speed( struct irda_device *dev, int baud);
-static void irtty_write_wakeup( struct tty_struct *tty);
+static int irtty_open(struct tty_struct *tty);
+static void irtty_close(struct tty_struct *tty);
+static int irtty_ioctl(struct tty_struct *, void *, int, void *);
+static int irtty_receive_room(struct tty_struct *tty);
+static void irtty_change_speed(struct irda_device *dev, int baud);
+static void irtty_write_wakeup(struct tty_struct *tty);
-static void irtty_receive_buf( struct tty_struct *, const unsigned char *,
- char *, int);
+static void irtty_receive_buf(struct tty_struct *, const unsigned char *,
+ char *, int);
char *driver_name = "irtty";
__initfunc(int irtty_init(void))
@@ -73,15 +73,15 @@
return -ENOMEM;
}
- dongles = hashbin_new( HB_LOCAL);
- if ( dongles == NULL) {
- printk( KERN_WARNING
- "IrDA: Can't allocate dongles hashbin!\n");
+ dongles = hashbin_new(HB_LOCAL);
+ if (dongles == NULL) {
+ printk(KERN_WARNING
+ "IrDA: Can't allocate dongles hashbin!\n");
return -ENOMEM;
}
/* Fill in our line protocol discipline, and register it */
- memset( &irda_ldisc, 0, sizeof( irda_ldisc));
+ memset(&irda_ldisc, 0, sizeof( irda_ldisc));
irda_ldisc.magic = TTY_LDISC_MAGIC;
irda_ldisc.name = "irda";
@@ -97,10 +97,10 @@
irda_ldisc.receive_room = irtty_receive_room;
irda_ldisc.write_wakeup = irtty_write_wakeup;
- if (( status = tty_register_ldisc( N_IRDA, &irda_ldisc)) != 0) {
- printk( KERN_ERR
- "IrDA: can't register line discipline (err = %d)\n",
- status);
+ if (( status = tty_register_ldisc(N_IRDA, &irda_ldisc)) != 0) {
+ printk(KERN_ERR
+ "IrDA: can't register line discipline (err = %d)\n",
+ status);
}
return status;
@@ -120,10 +120,10 @@
/*
* Unregister tty line-discipline
*/
- if (( ret = tty_register_ldisc( N_IRDA, NULL))) {
- printk( KERN_ERR
- "IrTTY: can't unregister line discipline (err = %d)\n",
- ret);
+ if ((ret = tty_register_ldisc(N_IRDA, NULL))) {
+ ERROR(__FUNCTION__
+ "(), can't unregister line discipline (err = %d)\n",
+ ret);
}
/*
@@ -131,8 +131,8 @@
* callback to irtty_close(), therefore we do give any deallocation
* function to hashbin_destroy().
*/
- hashbin_delete( irtty, NULL);
- hashbin_delete( dongles, NULL);
+ hashbin_delete(irtty, NULL);
+ hashbin_delete(dongles, NULL);
}
#endif /* MODULE */
@@ -143,47 +143,45 @@
* discipline is called for. Because we are sure the tty line exists,
* we only have to link it to a free IrDA channel.
*/
-static int irtty_open( struct tty_struct *tty)
+static int irtty_open(struct tty_struct *tty)
{
struct irtty_cb *self;
char name[16];
- ASSERT( tty != NULL, return -EEXIST;);
+ ASSERT(tty != NULL, return -EEXIST;);
/* First make sure we're not already connected. */
self = (struct irtty_cb *) tty->disc_data;
- if ( self != NULL && self->magic == IRTTY_MAGIC)
+ if (self != NULL && self->magic == IRTTY_MAGIC)
return -EEXIST;
/*
* Allocate new instance of the driver
*/
- self = kmalloc( sizeof(struct irtty_cb), GFP_KERNEL);
- if ( self == NULL) {
- printk( KERN_ERR "IrDA: Can't allocate memory for "
- "IrDA control block!\n");
+ self = kmalloc(sizeof(struct irtty_cb), GFP_KERNEL);
+ if (self == NULL) {
+ printk(KERN_ERR "IrDA: Can't allocate memory for "
+ "IrDA control block!\n");
return -ENOMEM;
}
- memset( self, 0, sizeof(struct irtty_cb));
+ memset(self, 0, sizeof(struct irtty_cb));
self->tty = tty;
tty->disc_data = self;
/* Give self a name */
- sprintf( name, "%s%d", tty->driver.name,
- MINOR(tty->device) - tty->driver.minor_start +
- tty->driver.name_base);
-
+ sprintf(name, "%s%d", tty->driver.name,
+ MINOR(tty->device) - tty->driver.minor_start +
+ tty->driver.name_base);
+
/* hashbin_insert( irtty, (QUEUE*) self, 0, self->name); */
- hashbin_insert( irtty, (QUEUE*) self, (int) self, NULL);
+ hashbin_insert(irtty, (QUEUE*) self, (int) self, NULL);
- if (tty->driver.flush_buffer) {
+ if (tty->driver.flush_buffer)
tty->driver.flush_buffer(tty);
- }
-
- if (tty->ldisc.flush_buffer) {
+
+ if (tty->ldisc.flush_buffer)
tty->ldisc.flush_buffer(tty);
- }
self->magic = IRTTY_MAGIC;
@@ -198,12 +196,12 @@
* that are not device dependent (such as link disconnect time) so
* this parameter can be set by IrLAP (or the user) instead. DB
*/
- irda_init_max_qos_capabilies( &self->idev.qos);
+ irda_init_max_qos_capabilies(&self->idev.qos);
/* The only value we must override it the baudrate */
self->idev.qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
IR_115200;
- self->idev.qos.min_turn_time.bits = 0x03;
+ self->idev.qos.min_turn_time.bits = 0x0f;
self->idev.flags = IFF_SIR | IFF_PIO;
irda_qos_bits_to_value(&self->idev.qos);
@@ -236,7 +234,7 @@
}
/*
- * Function irtty_close ( tty)
+ * Function irtty_close (tty)
*
* Close down a IrDA channel. This means flushing out any pending queues,
* and then restoring the TTY line discipline to what it was before it got
@@ -272,14 +270,40 @@
MOD_DEC_USE_COUNT;
}
+/*
+ * Function irtty_stop_receiver (irda_device, stop)
+ *
+ *
+ *
+ */
+static void irtty_stop_receiver(struct irda_device *idev, int stop)
+{
+ struct termios old_termios;
+ struct irtty_cb *self;
+ int cflag;
+
+ self = (struct irtty_cb *) idev->priv;
+
+ old_termios = *(self->tty->termios);
+ cflag = self->tty->termios->c_cflag;
+
+ if (stop)
+ cflag &= ~CREAD;
+ else
+ cflag |= CREAD;
+
+ self->tty->termios->c_cflag = cflag;
+ self->tty->driver.set_termios(self->tty, &old_termios);
+}
+
/*
- * Function irtty_change_speed ( self, baud)
+ * Function irtty_change_speed (self, baud)
*
* Change the speed of the serial port. The driver layer must check that
* all transmission has finished using the irtty_wait_until_sent()
* function.
*/
-static void irtty_change_speed( struct irda_device *idev, int baud)
+static void irtty_change_speed(struct irda_device *idev, int baud)
{
struct termios old_termios;
struct irtty_cb *self;
@@ -287,22 +311,22 @@
DEBUG(4,__FUNCTION__ "(), <%ld>\n", jiffies);
- ASSERT( idev != NULL, return;);
- ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
+ ASSERT(idev != NULL, return;);
+ ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
self = (struct irtty_cb *) idev->priv;
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == IRTTY_MAGIC, return;);
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == IRTTY_MAGIC, return;);
old_termios = *(self->tty->termios);
cflag = self->tty->termios->c_cflag;
cflag &= ~CBAUD;
- DEBUG( 4, __FUNCTION__ "(), Setting speed to %d\n", baud);
+ DEBUG(4, __FUNCTION__ "(), Setting speed to %d\n", baud);
- switch( baud) {
+ switch (baud) {
case 1200:
cflag |= B1200;
break;
@@ -331,7 +355,7 @@
}
self->tty->termios->c_cflag = cflag;
- self->tty->driver.set_termios( self->tty, &old_termios);
+ self->tty->driver.set_termios(self->tty, &old_termios);
}
/*
@@ -340,43 +364,42 @@
* Initialize attached dongle. Warning, must be called with a process
* context!
*/
-static void irtty_init_dongle( struct irtty_cb *self, int type)
+static void irtty_init_dongle(struct irtty_cb *self, int type)
{
struct dongle_q *node;
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == IRTTY_MAGIC, return;);
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == IRTTY_MAGIC, return;);
#ifdef CONFIG_KMOD
/* Try to load the module needed */
switch( type) {
case ESI_DONGLE:
- DEBUG( 0, __FUNCTION__ "(), ESI dongle!\n");
- request_module( "esi");
+ MESSAGE("IrDA: Trying to initialize ESI dongle!\n");
+ request_module("esi");
break;
case TEKRAM_DONGLE:
- DEBUG( 0, __FUNCTION__ "(), Tekram dongle!\n");
- request_module( "tekram");
+ MESSAGE("IrDA: Trying to initialize Tekram dongle!\n");
+ request_module("tekram");
break;
case ACTISYS_DONGLE: /* FALLTHROUGH */
case ACTISYS_PLUS_DONGLE:
- DEBUG( 0, __FUNCTION__ "(), ACTiSYS dongle!\n");
- request_module( "actisys");
+ MESSAGE("IrDA: Trying to initialize ACTiSYS dongle!\n");
+ request_module("actisys");
break;
case GIRBIL_DONGLE:
- DEBUG( 0, __FUNCTION__ "(), GIrBIL dongle!\n");
- request_module( "girbil");
+ MESSAGE("IrDA: Trying to initialize GIrBIL dongle!\n");
+ request_module("girbil");
break;
default:
- DEBUG( 0, __FUNCTION__ "(), Unknown dongle type!\n");
+ ERROR("Unknown dongle type!\n");
return;
- break;
}
#endif /* CONFIG_KMOD */
- node = hashbin_find( dongles, type, NULL);
+ node = hashbin_find(dongles, type, NULL);
if ( !node) {
- DEBUG(0, __FUNCTION__ "(), Unable to find requested dongle\n");
+ ERROR("Unable to find requested dongle\n");
return;
}
self->dongle_q = node;
@@ -387,14 +410,14 @@
/*
* Now initialize the dongle!
*/
- node->dongle->open( &self->idev, type);
- node->dongle->qos_init( &self->idev, &self->idev.qos);
+ node->dongle->open(&self->idev, type);
+ node->dongle->qos_init(&self->idev, &self->idev.qos);
/* Reset dongle */
- node->dongle->reset( &self->idev, 0);
+ node->dongle->reset(&self->idev, 0);
/* Set to default baudrate */
- node->dongle->change_speed( &self->idev, 9600);
+ node->dongle->change_speed(&self->idev, 9600);
}
/*
@@ -411,25 +434,25 @@
self = (struct irtty_cb *) tty->disc_data;
- ASSERT( self != NULL, return -ENODEV;);
- ASSERT( self->magic == IRTTY_MAGIC, return -EBADR;);
+ ASSERT(self != NULL, return -ENODEV;);
+ ASSERT(self->magic == IRTTY_MAGIC, return -EBADR;);
- if ( _IOC_DIR(cmd) & _IOC_READ)
+ if (_IOC_DIR(cmd) & _IOC_READ)
err = verify_area( VERIFY_WRITE, (void *) arg, size);
- else if ( _IOC_DIR(cmd) & _IOC_WRITE)
+ else if (_IOC_DIR(cmd) & _IOC_WRITE)
err = verify_area( VERIFY_READ, (void *) arg, size);
- if ( err)
+ if (err)
return err;
switch(cmd) {
case TCGETS:
case TCGETA:
- return n_tty_ioctl( tty, (struct file *) file, cmd,
- (unsigned long) arg);
+ return n_tty_ioctl(tty, (struct file *) file, cmd,
+ (unsigned long) arg);
break;
case IRTTY_IOCTDONGLE:
/* Initialize dongle */
- irtty_init_dongle( self, (int) arg);
+ irtty_init_dongle(self, (int) arg);
break;
default:
return -ENOIOCTLCMD;
@@ -450,8 +473,8 @@
{
struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == IRTTY_MAGIC, return;);
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == IRTTY_MAGIC, return;);
/* Read the characters out of the buffer */
while (count--) {
@@ -461,19 +484,19 @@
if (fp && *fp++) {
DEBUG( 0, "Framing or parity error!\n");
irda_device_set_media_busy( &self->idev, TRUE);
- /* sl->rx_errors++; */
+
cp++;
continue;
}
/* Unwrap and destuff one byte */
- async_unwrap_char( &self->idev, *cp++);
+ async_unwrap_char(&self->idev, *cp++);
}
}
/*
* Function irtty_hard_xmit (skb, dev)
*
- * Transmit skb
+ * Transmit frame
*
*/
static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev)
@@ -482,9 +505,6 @@
struct irda_device *idev;
int actual = 0;
- ASSERT( dev != NULL, return 0;);
- ASSERT( skb != NULL, return 0;);
-
idev = (struct irda_device *) dev->priv;
ASSERT(idev != NULL, return 0;);
@@ -498,10 +518,11 @@
/* Lock transmit buffer */
if (irda_lock((void *) &dev->tbusy) == FALSE)
return -EBUSY;
-
- /*
- * Transfer skb to tx_buff while wrapping, stuffing and making CRC
- */
+
+ /* Init tx buffer*/
+ idev->tx_buff.data = idev->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);
@@ -509,13 +530,14 @@
dev->trans_start = jiffies;
- if ( self->tty->driver.write)
+ if (self->tty->driver.write)
actual = self->tty->driver.write(self->tty, 0,
idev->tx_buff.data,
idev->tx_buff.len);
- idev->tx_buff.offset = actual;
- idev->tx_buff.head = idev->tx_buff.data + actual;
+ /* Hide the part we just transmitted */
+ idev->tx_buff.data += actual;
+ idev->tx_buff.len -= actual;
idev->stats.tx_packets++;
idev->stats.tx_bytes += idev->tx_buff.len;
@@ -524,7 +546,7 @@
* Did we transmit the whole frame? Commented out for now since
* I must check if this optimalization really works. DB.
*/
- if (( idev->tx.count - idev->tx.ptr) <= 0) {
+ if ((idev->tx_buff.len) == 0) {
DEBUG( 4, "irtty_xmit_buf: finished with frame!\n");
self->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
irda_unlock( &self->tbusy);
@@ -541,8 +563,9 @@
* Used by the TTY to find out how much data we can receive at a time
*
*/
-static int irtty_receive_room( struct tty_struct *tty)
+static int irtty_receive_room(struct tty_struct *tty)
{
+ DEBUG(0, __FUNCTION__ "()\n");
return 65536; /* We can handle an infinite amount of data. :-) */
}
@@ -553,47 +576,42 @@
* more packets to send, we send them here.
*
*/
-static void irtty_write_wakeup( struct tty_struct *tty)
+static void irtty_write_wakeup(struct tty_struct *tty)
{
- int actual = 0, count;
struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
struct irda_device *idev;
+ int actual = 0;
/*
* First make sure we're connected.
*/
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == IRTTY_MAGIC, return;);
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == IRTTY_MAGIC, return;);
idev = &self->idev;
- /*
- * Finished with frame?
- */
- if ( idev->tx_buff.offset == idev->tx_buff.len) {
-
+ /* Finished with frame? */
+ if (idev->tx_buff.len > 0) {
+ /* Write data left in transmit buffer */
+ actual = tty->driver.write(tty, 0, idev->tx_buff.data,
+ idev->tx_buff.len);
+
+ idev->tx_buff.data += actual;
+ idev->tx_buff.len -= actual;
+ } else {
/*
* Now serial buffer is almost free & we can start
* transmission of another packet
*/
DEBUG(5, __FUNCTION__ "(), finished with frame!\n");
-
+
tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
idev->netdev.tbusy = 0; /* Unlock */
-
+
/* Tell network layer that we want more frames */
- mark_bh( NET_BH);
-
- return;
+ mark_bh(NET_BH);
}
- /*
- * Write data left in transmit buffer
- */
- count = idev->tx_buff.len - idev->tx_buff.offset;
- actual = tty->driver.write( tty, 0, idev->tx_buff.head, count);
- idev->tx_buff.offset += actual;
- idev->tx_buff.head += actual;
}
/*
@@ -602,9 +620,9 @@
* Return TRUE is we are currently receiving a frame
*
*/
-static int irtty_is_receiving( struct irda_device *idev)
+static int irtty_is_receiving(struct irda_device *idev)
{
- return ( idev->rx_buff.state != OUTSIDE_FRAME);
+ return (idev->rx_buff.state != OUTSIDE_FRAME);
}
/*
@@ -614,20 +632,20 @@
* to change the speed of the serial port. Warning this function must
* be called with a process context!
*/
-static void irtty_wait_until_sent( struct irda_device *idev)
+static void irtty_wait_until_sent(struct irda_device *idev)
{
struct irtty_cb *self = (struct irtty_cb *) idev->priv;
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == IRTTY_MAGIC, return;);
+ ASSERT(self != NULL, return;);
+ ASSERT(self->magic == IRTTY_MAGIC, return;);
- DEBUG( 4, "Chars in buffer %d\n",
- self->tty->driver.chars_in_buffer( self->tty));
+ DEBUG(4, "Chars in buffer %d\n",
+ self->tty->driver.chars_in_buffer(self->tty));
- tty_wait_until_sent( self->tty, 0);
+ tty_wait_until_sent(self->tty, 0);
}
-int irtty_register_dongle( struct dongle *dongle)
+int irtty_register_dongle(struct dongle *dongle)
{
struct dongle_q *new;
@@ -638,12 +656,11 @@
}
/* Make new IrDA dongle */
- new = (struct dongle_q *)kmalloc(sizeof(struct dongle_q), GFP_KERNEL);
- if (new == NULL) {
- return 1;
+ new = (struct dongle_q *) kmalloc(sizeof(struct dongle_q), GFP_KERNEL);
+ if (new == NULL)
+ return -1;
- }
- memset( new, 0, sizeof( struct dongle_q));
+ memset(new, 0, sizeof( struct dongle_q));
new->dongle = dongle;
/* Insert IrDA dongle into hashbin */
@@ -652,16 +669,16 @@
return 0;
}
-void irtty_unregister_dongle( struct dongle *dongle)
+void irtty_unregister_dongle(struct dongle *dongle)
{
struct dongle_q *node;
- node = hashbin_remove( dongles, dongle->type, NULL);
- if ( !node) {
- DEBUG( 0, __FUNCTION__ "(), dongle not found!\n");
+ node = hashbin_remove(dongles, dongle->type, NULL);
+ if (!node) {
+ ERROR(__FUNCTION__ "(), dongle not found!\n");
return;
}
- kfree( node);
+ kfree(node);
}
@@ -696,26 +713,24 @@
set_fs(get_ds());
if (tty->driver.ioctl(tty, NULL, TIOCMSET, (unsigned long) &arg)) {
- DEBUG(0, __FUNCTION__ "(), error!\n");
+ ERROR(__FUNCTION__ "(), error doing ioctl!\n");
}
set_fs(fs);
}
-
-static int irtty_net_init( struct device *dev)
+static int irtty_net_init(struct device *dev)
{
/* Set up to be a normal IrDA network device driver */
- irda_device_setup( dev);
+ irda_device_setup(dev);
/* Insert overrides below this line! */
return 0;
}
-
-static int irtty_net_open( struct device *dev)
+static int irtty_net_open(struct device *dev)
{
- ASSERT( dev != NULL, return -1;);
+ ASSERT(dev != NULL, return -1;);
/* Ready to play! */
dev->tbusy = 0;
@@ -729,7 +744,7 @@
static int irtty_net_close(struct device *dev)
{
- ASSERT( dev != NULL, return -1;);
+ ASSERT(dev != NULL, return -1;);
/* Stop device */
dev->tbusy = 1;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)