* [PATCH] kill old irtty
2003-08-19 0:07 ` Jeff Garzik
@ 2003-08-19 22:58 ` Stephen Hemminger
2003-08-20 4:02 ` David S. Miller
0 siblings, 1 reply; 17+ messages in thread
From: Stephen Hemminger @ 2003-08-19 22:58 UTC (permalink / raw)
To: Jeff Garzik; +Cc: jt, David S. Miller, irda-users, netdev, lists
As suggested by Jean and Jeff, kill the old irtty driver
since it is replaced by irtty-sir
diff -Nru a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
--- a/drivers/net/irda/Kconfig Tue Aug 19 15:54:22 2003
+++ b/drivers/net/irda/Kconfig Tue Aug 19 15:54:22 2003
@@ -68,20 +68,6 @@
comment "Old SIR device drivers"
-config IRTTY_OLD
- tristate "Old IrTTY (broken)"
- depends on IRDA && EXPERIMENTAL
- help
- Say Y here if you want to build support for the IrTTY line
- discipline. If you want to compile it as a module (irtty), say M
- here and read <file:Documentation/modules.txt>. IrTTY makes it
- possible to use Linux's own serial driver for all IrDA ports that
- are 16550 compatible. Most IrDA chips are 16550 compatible so you
- should probably say Y to this option. Using IrTTY will however
- limit the speed of the connection to 115200 bps (IrDA SIR mode).
-
- If unsure, say N.
-
config IRPORT_SIR
tristate "IrPORT (IrDA serial driver)"
depends on IRDA
diff -Nru a/drivers/net/irda/Makefile b/drivers/net/irda/Makefile
--- a/drivers/net/irda/Makefile Tue Aug 19 15:54:22 2003
+++ b/drivers/net/irda/Makefile Tue Aug 19 15:54:22 2003
@@ -5,8 +5,7 @@
# Rewritten to use lists instead of if-statements.
#
-# Old SIR drivers (irtty is broken)
-obj-$(CONFIG_IRTTY_OLD) += irtty.o
+# Old SIR drivers
obj-$(CONFIG_IRPORT_SIR) += irport.o
# FIR drivers
obj-$(CONFIG_USB_IRDA) += irda-usb.o
diff -Nru a/drivers/net/irda/irtty.c b/drivers/net/irda/irtty.c
--- a/drivers/net/irda/irtty.c Tue Aug 19 15:54:22 2003
+++ /dev/null Wed Dec 31 16:00:00 1969
@@ -1,1055 +0,0 @@
-/*********************************************************************
- *
- * Filename: irtty.c
- * Version: 1.1
- * Description: IrDA line discipline implementation
- * Status: Experimental.
- * Author: Dag Brattli <dagb@cs.uit.no>
- * Created at: Tue Dec 9 21:18:38 1997
- * Modified at: Sat Mar 11 07:43:30 2000
- * 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>
- *
- * Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * Neither Dag Brattli nor University of Tromsø admit liability nor
- * provide warranty for any of this software. This material is
- * provided "AS-IS" and at no charge.
- *
- ********************************************************************/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/tty.h>
-#include <linux/init.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/rtnetlink.h>
-
-#include <asm/uaccess.h>
-
-#include <net/irda/irda.h>
-#include <net/irda/irtty.h>
-#include <net/irda/wrapper.h>
-#include <net/irda/irda_device.h>
-
-static int qos_mtt_bits = 0x03; /* 5 ms or more */
-
-/* Network device fuction prototypes */
-static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev);
-static int irtty_net_open(struct net_device *dev);
-static int irtty_net_close(struct net_device *dev);
-static int irtty_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static struct net_device_stats *irtty_net_get_stats(struct net_device *dev);
-
-/* Line discipline function prototypes */
-static int irtty_open(struct tty_struct *tty);
-static void irtty_close(struct tty_struct *tty);
-static int irtty_ioctl(struct tty_struct *, struct file *,
- unsigned int, unsigned long);
-static int irtty_receive_room(struct tty_struct *tty);
-static void irtty_write_wakeup(struct tty_struct *tty);
-static void irtty_receive_buf(struct tty_struct *, const unsigned char *,
- char *, int);
-
-/* IrDA specific function protoctypes */
-static int irtty_is_receiving(struct irtty_cb *self);
-static int irtty_set_dtr_rts(struct net_device *dev, int dtr, int rts);
-static int irtty_raw_write(struct net_device *dev, __u8 *buf, int len);
-static int irtty_raw_read(struct net_device *dev, __u8 *buf, int len);
-static int irtty_set_mode(struct net_device *dev, int mode);
-static int irtty_change_speed(struct irda_task *task);
-
-static struct tty_ldisc irda_ldisc = {
- .owner = THIS_MODULE,
- .magic = TTY_LDISC_MAGIC,
- .name = "irda",
- .open = irtty_open,
- .close = irtty_close,
- .ioctl = irtty_ioctl,
- .receive_buf = irtty_receive_buf,
- .receive_room = irtty_receive_room,
- .write_wakeup = irtty_write_wakeup,
-};
-
-int __init irtty_init(void)
-{
- int status;
-
- if ((status = tty_register_ldisc(N_IRDA, &irda_ldisc)) != 0) {
- ERROR("IrDA: can't register line discipline (err = %d)\n",
- status);
- }
-
- return status;
-}
-
-/*
- * Function irtty_cleanup ( )
- *
- * Called when the irda module is removed. Here we remove all instances
- * of the driver, and the master array.
- */
-static void __exit irtty_cleanup(void)
-{
- int ret;
-
- /* Unregister tty line-discipline */
- if ((ret = tty_register_ldisc(N_IRDA, NULL))) {
- ERROR("%s(), can't unregister line discipline (err = %d)\n",
- __FUNCTION__, ret);
- }
-
-}
-
-/*
- * Function irtty_open(tty)
- *
- * This function is called by the TTY module when the IrDA line
- * 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)
-{
- struct net_device *dev;
- struct irtty_cb *self;
- int err;
-
- IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
- 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)
- return -EEXIST;
-
- /*
- * Allocate new instance of the driver
- */
- dev = alloc_netdev(sizeof(struct irtty_cb), "irda%d",
- irda_device_setup);
- if (dev == NULL) {
- printk(KERN_ERR "IrDA: Can't allocate memory for "
- "IrDA control block!\n");
- return -ENOMEM;
- }
-
- self = dev->priv;
- self->netdev = dev;
- spin_lock_init(&self->lock);
- self->tty = tty;
- tty->disc_data = self;
-
- if (tty->driver->flush_buffer)
- tty->driver->flush_buffer(tty);
- if (tty->ldisc.flush_buffer)
- tty->ldisc.flush_buffer(tty);
- self->magic = IRTTY_MAGIC;
- self->mode = IRDA_IRLAP;
-
- /*
- * Initialize QoS capabilities, we fill in all the stuff that
- * we support. Be careful not to place any restrictions on values
- * 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->qos);
-
- /* The only value we must override it the baudrate */
- self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
- IR_115200;
- self->qos.min_turn_time.bits = qos_mtt_bits;
- self->flags = IFF_SIR | IFF_PIO;
- irda_qos_bits_to_value(&self->qos);
-
- /* 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;
-
- /* Override the network functions we need to use */
- dev->hard_start_xmit = irtty_hard_xmit;
- dev->open = irtty_net_open;
- dev->stop = irtty_net_close;
- dev->get_stats = irtty_net_get_stats;
- dev->do_ioctl = irtty_net_ioctl;
-
- err = register_netdev(dev);
- if (err) {
- ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
- kfree(dev);
- return -1;
- }
-
- MESSAGE("IrDA: Registered device %s\n", dev->name);
-
- return 0;
-}
-
-/*
- * 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
- * hooked to IrDA (which usually is TTY again).
- */
-static void irtty_close(struct tty_struct *tty)
-{
- struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
- unsigned long flags;
-
- IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
-
- /* First make sure we're connected. */
- if (self == NULL || self->tty != tty)
- return;
-
- ASSERT(self->magic == IRTTY_MAGIC, return;);
-
- /* Stop tty */
- tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
- tty->disc_data = 0;
-
- /* We are not using any dongle anymore! */
- if (self->dongle)
- irda_device_dongle_cleanup(self->dongle);
- self->dongle = NULL;
-
- /* Protect access to self->task and self->?x_buff - Jean II */
- spin_lock_irqsave(&self->lock, flags);
-
- /* Remove speed changing task if any */
- if (self->task)
- irda_task_delete(self->task);
-
- self->tty = NULL;
- self->magic = 0;
-
- if (self->tx_buff.head)
- kfree(self->tx_buff.head);
-
- if (self->rx_buff.head)
- kfree(self->rx_buff.head);
- spin_unlock_irqrestore(&self->lock, flags);
-
- /* Remove netdevice */
- unregister_netdev(self->netdev);
-}
-
-/*
- * Function irtty_stop_receiver (self, stop)
- *
- *
- *
- */
-static void irtty_stop_receiver(struct irtty_cb *self, int stop)
-{
- struct termios old_termios;
- int cflag;
-
- old_termios = *(self->tty->termios);
- cflag = self->tty->termios->c_cflag;
-
- if (stop)
- cflag &= ~CREAD;
- else
- cflag |= CREAD;
-
- /* This is unsafe, but currently under discussion - Jean II */
- self->tty->termios->c_cflag = cflag;
- self->tty->driver->set_termios(self->tty, &old_termios);
-}
-
-/*
- * Function irtty_do_change_speed (self, speed)
- *
- * Change the speed of the serial port.
- */
-static void __irtty_change_speed(struct irtty_cb *self, __u32 speed)
-{
- struct termios old_termios;
- int cflag;
-
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRTTY_MAGIC, return;);
-
- old_termios = *(self->tty->termios);
- cflag = self->tty->termios->c_cflag;
-
- cflag &= ~CBAUD;
-
- IRDA_DEBUG(2, "%s(), Setting speed to %d\n", __FUNCTION__, speed);
-
- switch (speed) {
- case 1200:
- cflag |= B1200;
- break;
- case 2400:
- cflag |= B2400;
- break;
- case 4800:
- cflag |= B4800;
- break;
- case 19200:
- cflag |= B19200;
- break;
- case 38400:
- cflag |= B38400;
- break;
- case 57600:
- cflag |= B57600;
- break;
- case 115200:
- cflag |= B115200;
- break;
- case 9600:
- default:
- cflag |= B9600;
- break;
- }
-
- /* This is unsafe, but currently under discussion - Jean II */
- self->tty->termios->c_cflag = cflag;
- self->tty->driver->set_termios(self->tty, &old_termios);
-
- self->io.speed = speed;
-}
-
-/*
- * Function irtty_change_speed (instance, state, param)
- *
- * State machine for changing speed of the device. We do it this way since
- * we cannot use schedule_timeout() when we are in interrupt context
- */
-static int irtty_change_speed(struct irda_task *task)
-{
- struct irtty_cb *self;
- unsigned long flags;
- __u32 speed = (__u32) task->param;
- int ret = 0;
-
- IRDA_DEBUG(2, "%s(), <%ld>\n", __FUNCTION__, jiffies);
-
- self = (struct irtty_cb *) task->instance;
- ASSERT(self != NULL, return -1;);
-
- /* Protect access to self->task - Jean II */
- spin_lock_irqsave(&self->lock, flags);
-
- /* Check if busy */
- if (self->task && self->task != task) {
- IRDA_DEBUG(0, "%s(), busy!\n", __FUNCTION__);
- spin_unlock_irqrestore(&self->lock, flags);
- return MSECS_TO_JIFFIES(10);
- } else
- self->task = task;
- spin_unlock_irqrestore(&self->lock, flags);
-
- switch (task->state) {
- case IRDA_TASK_INIT:
- /*
- * Make sure all data is sent before changing the speed of the
- * serial port.
- */
- if (self->tty->driver->chars_in_buffer(self->tty)) {
- /* Keep state, and try again later */
- ret = MSECS_TO_JIFFIES(10);
- break;
- } else {
- /* Transmit buffer is now empty, but it may still
- * take over 13 ms for the FIFO to become empty, so
- * wait some more to be sure all data is sent
- */
- irda_task_next_state(task, IRDA_TASK_WAIT);
- ret = MSECS_TO_JIFFIES(13);
- }
- case IRDA_TASK_WAIT:
- if (self->dongle)
- irda_task_next_state(task, IRDA_TASK_CHILD_INIT);
- else
- irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
- break;
- case IRDA_TASK_CHILD_INIT:
- /* Go to default speed */
- __irtty_change_speed(self, 9600);
-
- /* Change speed of dongle */
- if (irda_task_execute(self->dongle,
- self->dongle->issue->change_speed,
- NULL, task, (void *) speed))
- {
- /* Dongle need more time to change its speed */
- irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
-
- /* Give dongle 1 sec to finish */
- ret = MSECS_TO_JIFFIES(1000);
- } else
- /* Child finished immediately */
- irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
- break;
- case IRDA_TASK_CHILD_WAIT:
- WARNING("%s(), changing speed of dongle timed out!\n", __FUNCTION__);
- ret = -1;
- break;
- case IRDA_TASK_CHILD_DONE:
- /* Finally we are ready to change the speed */
- __irtty_change_speed(self, speed);
-
- irda_task_next_state(task, IRDA_TASK_DONE);
- self->task = NULL;
- break;
- default:
- ERROR("%s(), unknown state %d\n", __FUNCTION__, task->state);
- irda_task_next_state(task, IRDA_TASK_DONE);
- self->task = NULL;
- ret = -1;
- break;
- }
- return ret;
-}
-
-/*
- * Function irtty_ioctl (tty, file, cmd, arg)
- *
- * The Swiss army knife of system calls :-)
- *
- */
-static int irtty_ioctl(struct tty_struct *tty, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- dongle_t *dongle;
- struct irtty_info info;
- struct irtty_cb *self;
- int size = _IOC_SIZE(cmd);
- int err = 0;
-
- self = (struct irtty_cb *) tty->disc_data;
-
- ASSERT(self != NULL, return -ENODEV;);
- ASSERT(self->magic == IRTTY_MAGIC, return -EBADR;);
-
- if (_IOC_DIR(cmd) & _IOC_READ)
- err = verify_area(VERIFY_WRITE, (void *) arg, size);
- else if (_IOC_DIR(cmd) & _IOC_WRITE)
- err = verify_area(VERIFY_READ, (void *) arg, size);
- if (err)
- return err;
-
- switch (cmd) {
- case TCGETS:
- case TCGETA:
- /* Unsure about locking here, to check - Jean II */
- return n_tty_ioctl(tty, (struct file *) file, cmd, arg);
- break;
- case IRTTY_IOCTDONGLE:
- /* Initialize dongle */
- dongle = irda_device_dongle_init(self->netdev, (int) arg);
- if (!dongle)
- break;
-
- /* Initialize callbacks */
- dongle->set_mode = irtty_set_mode;
- dongle->read = irtty_raw_read;
- dongle->write = irtty_raw_write;
- dongle->set_dtr_rts = irtty_set_dtr_rts;
-
- /* Now initialize the dongle! */
- dongle->issue->open(dongle, &self->qos);
-
- /* Reset dongle */
- irda_task_execute(dongle, dongle->issue->reset, NULL, NULL,
- NULL);
-
- /* Make dongle available to driver only now to avoid
- * race conditions - Jean II */
- self->dongle = dongle;
- break;
- case IRTTY_IOCGET:
- ASSERT(self->netdev != NULL, return -1;);
-
- memset(&info, 0, sizeof(struct irtty_info));
- strncpy(info.name, self->netdev->name, 5);
-
- if (copy_to_user((void *) arg, &info, sizeof(struct irtty_info)))
- return -EFAULT;
- break;
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
-/*
- * Function irtty_receive_buf( tty, cp, count)
- *
- * Handle the 'receiver data ready' interrupt. This function is called
- * by the 'tty_io' module in the kernel when a block of IrDA data has
- * been received, which can now be decapsulated and delivered for
- * further processing
- */
-static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
- char *fp, int count)
-{
- struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
-
- if (!self || !self->netdev) {
- IRDA_DEBUG(0, "%s(), not ready yet!\n", __FUNCTION__);
- return;
- }
-
- // Are we in interrupt context ? What locking is done ? - Jean II
- //spin_lock_irqsave(&self->lock, flags);
-
- /* Read the characters out of the buffer */
- while (count--) {
- /*
- * Characters received with a parity error, etc?
- */
- if (fp && *fp++) {
- IRDA_DEBUG(0, "Framing or parity error!\n");
- irda_device_set_media_busy(self->netdev, TRUE);
-
- cp++;
- continue;
- }
-
- switch (self->mode) {
- case IRDA_IRLAP:
- /* Unwrap and destuff one byte */
- async_unwrap_char(self->netdev, &self->stats,
- &self->rx_buff, *cp++);
- break;
- case IRDA_RAW:
- /* What should we do when the buffer is full? */
- if (self->rx_buff.len == self->rx_buff.truesize)
- self->rx_buff.len = 0;
-
- self->rx_buff.data[self->rx_buff.len++] = *cp++;
- break;
- default:
- break;
- }
- }
- //spin_unlock_irqrestore(&self->lock, flags);
-}
-
-/*
- * Function irtty_change_speed_complete (task)
- *
- * Called when the change speed operation completes
- *
- */
-static int irtty_change_speed_complete(struct irda_task *task)
-{
- struct irtty_cb *self;
-
- IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
-
- self = (struct irtty_cb *) task->instance;
-
- ASSERT(self != NULL, return -1;);
- ASSERT(self->netdev != NULL, return -1;);
-
- /* Finished changing speed, so we are not busy any longer */
- /* Signal network layer so it can try to send the frame */
- netif_wake_queue(self->netdev);
-
- return 0;
-}
-
-/*
- * Function irtty_hard_xmit (skb, dev)
- *
- * Transmit frame
- *
- */
-static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct irtty_cb *self;
- int actual = 0;
- __s32 speed;
- unsigned long flags;
-
- self = (struct irtty_cb *) dev->priv;
- ASSERT(self != NULL, return 0;);
-
- /* Lock transmit buffer
- * this serialise operations, no need to spinlock - Jean II */
- netif_stop_queue(dev);
-
- /* Check if we need to change the speed */
- speed = irda_get_next_speed(skb);
- if ((speed != self->io.speed) && (speed != -1)) {
- /* Check for empty frame */
- if (!skb->len) {
- irda_task_execute(self, irtty_change_speed,
- irtty_change_speed_complete,
- NULL, (void *) speed);
- dev_kfree_skb(skb);
- return 0;
- } else
- self->new_speed = speed;
- }
-
- /* Protect access to self->tx_buff - Jean II */
- spin_lock_irqsave(&self->lock, flags);
-
- /* Init tx buffer*/
- self->tx_buff.data = self->tx_buff.head;
-
- /* Copy skb to tx_buff while wrapping, stuffing and making CRC */
- self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data,
- self->tx_buff.truesize);
-
- self->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
-
- dev->trans_start = jiffies;
- self->stats.tx_bytes += self->tx_buff.len;
-
- if (self->tty->driver->write)
- actual = self->tty->driver->write(self->tty, 0,
- self->tx_buff.data,
- self->tx_buff.len);
- /* Hide the part we just transmitted */
- self->tx_buff.data += actual;
- self->tx_buff.len -= actual;
-
- spin_unlock_irqrestore(&self->lock, flags);
-
- dev_kfree_skb(skb);
-
- return 0;
-}
-
-/*
- * Function irtty_receive_room (tty)
- *
- * 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)
-{
- IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
- return 65536; /* We can handle an infinite amount of data. :-) */
-}
-
-/*
- * Function irtty_write_wakeup (tty)
- *
- * Called by the driver when there's room for more data. If we have
- * more packets to send, we send them here.
- *
- */
-static void irtty_write_wakeup(struct tty_struct *tty)
-{
- struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
- int actual = 0;
- unsigned long flags;
-
- /*
- * First make sure we're connected.
- */
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRTTY_MAGIC, return;);
-
- /* Protected via netif_stop_queue(dev); - Jean II */
-
- /* Protect access to self->tx_buff - Jean II */
- spin_lock_irqsave(&self->lock, flags);
-
- /* Finished with frame? */
- if (self->tx_buff.len > 0) {
- /* Write data left in transmit buffer */
- actual = tty->driver->write(tty, 0, self->tx_buff.data,
- self->tx_buff.len);
-
- self->tx_buff.data += actual;
- self->tx_buff.len -= actual;
- spin_unlock_irqrestore(&self->lock, flags);
- } else {
- /*
- * Now serial buffer is almost free & we can start
- * transmission of another packet
- */
- IRDA_DEBUG(5, "%s(), finished with frame!\n", __FUNCTION__);
-
- self->stats.tx_packets++;
-
- tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
-
- /* Don't change speed with irq off */
- spin_unlock_irqrestore(&self->lock, flags);
-
- if (self->new_speed) {
- IRDA_DEBUG(5, "%s(), Changing speed!\n", __FUNCTION__);
- irda_task_execute(self, irtty_change_speed,
- irtty_change_speed_complete,
- NULL, (void *) self->new_speed);
- self->new_speed = 0;
- } else {
- /* Tell network layer that we want more frames */
- netif_wake_queue(self->netdev);
- }
- }
-}
-
-/*
- * Function irtty_is_receiving (self)
- *
- * Return TRUE is we are currently receiving a frame
- *
- */
-static int irtty_is_receiving(struct irtty_cb *self)
-{
- return (self->rx_buff.state != OUTSIDE_FRAME);
-}
-
-/*
- * Function irtty_set_dtr_rts (tty, dtr, rts)
- *
- * This function can be used by dongles etc. to set or reset the status
- * of the dtr and rts lines
- */
-static int irtty_set_dtr_rts(struct net_device *dev, int dtr, int rts)
-{
- struct irtty_cb *self;
- struct tty_struct *tty;
- //unsigned long flags;
- mm_segment_t fs;
- int arg = 0;
-
- self = (struct irtty_cb *) dev->priv;
- tty = self->tty;
-
- /* Was protected in ioctl handler, but the serial driver doesn't
- * like it. This may need to change. - Jean II */
- //spin_lock_irqsave(&self->lock, flags);
-
-#ifdef TIOCM_OUT2 /* Not defined for ARM */
- arg = TIOCM_OUT2;
-#endif
- if (rts)
- arg |= TIOCM_RTS;
- if (dtr)
- arg |= TIOCM_DTR;
-
- /*
- * The ioctl() function, or actually set_modem_info() in serial.c
- * expects a pointer to the argument in user space. To hack us
- * around this, we use the set_fs() function to fool the routines
- * that check if they are called from user space. We also need
- * to send a pointer to the argument so get_user() gets happy. DB.
- */
-
- fs = get_fs();
- set_fs(get_ds());
-
- /* This is probably unsafe, but currently under discussion - Jean II */
- if (tty->driver->ioctl(tty, NULL, TIOCMSET, (unsigned long) &arg)) {
- IRDA_DEBUG(2, "%s(), error doing ioctl!\n", __FUNCTION__);
- }
- set_fs(fs);
-
- //spin_unlock_irqrestore(&self->lock, flags);
-
- return 0;
-}
-
-/*
- * Function irtty_set_mode (self, status)
- *
- * For the airport dongle, we need support for reading raw characters
- * from the IrDA device. This function switches between those modes.
- * FALSE is the default mode, and will then treat incoming data as IrDA
- * packets.
- */
-int irtty_set_mode(struct net_device *dev, int mode)
-{
- struct irtty_cb *self;
- unsigned long flags;
-
- self = (struct irtty_cb *) dev->priv;
-
- ASSERT(self != NULL, return -1;);
-
- IRDA_DEBUG(2, "%s(), mode=%s\n", __FUNCTION__, infrared_mode[mode]);
-
- /* Protect access to self->rx_buff - Jean II */
- spin_lock_irqsave(&self->lock, flags);
-
- /* save status for driver */
- self->mode = mode;
-
- /* reset the buffer state */
- self->rx_buff.data = self->rx_buff.head;
- self->rx_buff.len = 0;
- self->rx_buff.state = OUTSIDE_FRAME;
-
- spin_unlock_irqrestore(&self->lock, flags);
-
- return 0;
-}
-
-/*
- * Function irtty_raw_read (self, buf, len)
- *
- * Receive incoming data. This function sleeps, so it must only be
- * called with a process context. Timeout is currently defined to be
- * a multiple of 10 ms.
- */
-static int irtty_raw_read(struct net_device *dev, __u8 *buf, int len)
-{
- struct irtty_cb *self;
- int count;
-
- self = (struct irtty_cb *) dev->priv;
-
- ASSERT(self != NULL, return 0;);
- ASSERT(self->magic == IRTTY_MAGIC, return 0;);
-
- return 0;
-#if 0
- buf = self->rx_buff.data;
-
- /* Wait for the requested amount of data to arrive */
- while (len < self->rx_buff.len) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(MSECS_TO_JIFFIES(10));
-
- if (!timeout--)
- break;
- }
-
- count = self->rx_buff.len < len ? self->rx_buff.len : len;
-
- /*
- * Reset the state, this mean that a raw read is sort of a
- * datagram read, and _not_ a stream style read. Be aware of the
- * difference. Implementing it the other way will just be painful ;-)
- */
- self->rx_buff.data = self->rx_buff.head;
- self->rx_buff.len = 0;
- self->rx_buff.state = OUTSIDE_FRAME;
-#endif
- /* Return the amount we were able to get */
- return count;
-}
-
-static int irtty_raw_write(struct net_device *dev, __u8 *buf, int len)
-{
- struct irtty_cb *self;
- int actual = 0;
-
- self = (struct irtty_cb *) dev->priv;
-
- ASSERT(self != NULL, return 0;);
- ASSERT(self->magic == IRTTY_MAGIC, return 0;);
-
- if (self->tty->driver->write)
- actual = self->tty->driver->write(self->tty, 0, buf, len);
-
- return actual;
-}
-
-static int irtty_net_open(struct net_device *dev)
-{
- struct irtty_cb *self = (struct irtty_cb *) dev->priv;
- struct tty_struct *tty = self->tty;
-
- IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
-
- ASSERT(self != NULL, return -1;);
- ASSERT(self->magic == IRTTY_MAGIC, return -1;);
-
- /* Ready to play! */
- netif_start_queue(dev);
-
- /* Make sure we can receive more data */
- irtty_stop_receiver(self, FALSE);
-
- /*
- * Open new IrLAP layer instance, now that everything should be
- * initialized properly
- */
- self->irlap = irlap_open(dev, &self->qos, tty->name);
-
- return 0;
-}
-
-static int irtty_net_close(struct net_device *dev)
-{
- struct irtty_cb *self = (struct irtty_cb *) dev->priv;
-
- IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
-
- ASSERT(self != NULL, return -1;);
- ASSERT(self->magic == IRTTY_MAGIC, return -1;);
-
- /* Make sure we don't receive more data */
- irtty_stop_receiver(self, TRUE);
-
- /* Stop device */
- netif_stop_queue(dev);
-
- /* Stop and remove instance of IrLAP */
- if (self->irlap)
- irlap_close(self->irlap);
- self->irlap = NULL;
-
- return 0;
-}
-
-/*
- * Function irtty_net_ioctl (dev, rq, cmd)
- *
- * Process IOCTL commands for this device
- *
- */
-static int irtty_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
- struct if_irda_req *irq = (struct if_irda_req *) rq;
- struct irtty_cb *self;
- dongle_t *dongle;
- int ret = 0;
-
- ASSERT(dev != NULL, return -1;);
-
- self = dev->priv;
-
- ASSERT(self != NULL, return -1;);
- ASSERT(self->magic == IRTTY_MAGIC, return -1;);
-
- IRDA_DEBUG(3, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
-
- /* Locking :
- * irda_device_dongle_init() can't be locked.
- * irda_task_execute() doesn't need to be locked (but
- * irtty_change_speed() should protect itself).
- * Other calls protect themselves.
- * Jean II
- */
-
- switch (cmd) {
- case SIOCSBANDWIDTH: /* Set bandwidth */
- if (!capable(CAP_NET_ADMIN))
- ret = -EPERM;
- else
- irda_task_execute(self, irtty_change_speed, NULL, NULL,
- (void *) irq->ifr_baudrate);
- break;
- case SIOCSDONGLE: /* Set dongle */
- if (!capable(CAP_NET_ADMIN)) {
- ret = -EPERM;
- break;
- }
-
- /* Initialize dongle */
- dongle = irda_device_dongle_init(dev, irq->ifr_dongle);
- if (!dongle)
- break;
-
- dongle->set_mode = irtty_set_mode;
- dongle->read = irtty_raw_read;
- dongle->write = irtty_raw_write;
- dongle->set_dtr_rts = irtty_set_dtr_rts;
-
- /* Now initialize the dongle!
- * Safe to do unlocked : self->dongle is still NULL. */
- dongle->issue->open(dongle, &self->qos);
-
- /* Reset dongle */
- irda_task_execute(dongle, dongle->issue->reset, NULL, NULL,
- NULL);
-
- /* Make dongle available to driver only now to avoid
- * race conditions - Jean II */
- self->dongle = dongle;
- break;
- case SIOCSMEDIABUSY: /* Set media busy */
- if (!capable(CAP_NET_ADMIN))
- ret = -EPERM;
- else
- irda_device_set_media_busy(self->netdev, TRUE);
- break;
- case SIOCGRECEIVING: /* Check if we are receiving right now */
- irq->ifr_receiving = irtty_is_receiving(self);
- break;
- case SIOCSDTRRTS:
- if (!capable(CAP_NET_ADMIN))
- ret = -EPERM;
- else {
- irtty_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts);
- }
- break;
- case SIOCSMODE:
- if (!capable(CAP_NET_ADMIN))
- ret = -EPERM;
- else {
- irtty_set_mode(dev, irq->ifr_mode);
- }
- break;
- default:
- ret = -EOPNOTSUPP;
- }
-
- return ret;
-}
-
-static struct net_device_stats *irtty_net_get_stats(struct net_device *dev)
-{
- struct irtty_cb *self = (struct irtty_cb *) dev->priv;
-
- return &self->stats;
-}
-
-MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
-MODULE_DESCRIPTION("IrDA TTY device driver");
-MODULE_LICENSE("GPL");
-
-
-MODULE_PARM(qos_mtt_bits, "i");
-MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time");
-
-/*
- * Function init_module (void)
- *
- * Initialize IrTTY module
- *
- */
-module_init(irtty_init);
-
-/*
- * Function cleanup_module (void)
- *
- * Cleanup IrTTY module
- *
- */
-module_exit(irtty_cleanup);
^ permalink raw reply [flat|nested] 17+ messages in thread