Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

irtty.c

Go to the documentation of this file.
00001 /*********************************************************************
00002  *                
00003  * Filename:      irtty.c
00004  * Version:       1.1
00005  * Description:   IrDA line discipline implementation
00006  * Status:        Experimental.
00007  * Author:        Dag Brattli <dagb@cs.uit.no>
00008  * Created at:    Tue Dec  9 21:18:38 1997
00009  * Modified at:   Tue Apr 25 21:17:49 2000
00010  * Modified by:   Dag Brattli <dagb@cs.uit.no>
00011  * Sources:       slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
00012  *                          Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
00013  * 
00014  *     Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved.
00015  *      
00016  *     This program is free software; you can redistribute it and/or 
00017  *     modify it under the terms of the GNU General Public License as 
00018  *     published by the Free Software Foundation; either version 2 of 
00019  *     the License, or (at your option) any later version.
00020  *  
00021  *     Neither Dag Brattli nor University of Tromsų admit liability nor
00022  *     provide warranty for any of this software. This material is 
00023  *     provided "AS-IS" and at no charge.
00024  *     
00025  ********************************************************************/    
00026 
00027 #include <linux/module.h>
00028 #include <linux/kernel.h>
00029 #include <linux/tty.h>
00030 #include <linux/init.h>
00031 #include <linux/skbuff.h>
00032 #include <linux/if_arp.h>
00033 #include <linux/rtnetlink.h>
00034 
00035 #include <asm/segment.h>
00036 #include <asm/uaccess.h>
00037 #include <asm/termios.h>
00038 
00039 #include <net/irda/irda.h>
00040 #include <net/irda/irtty.h>
00041 #include <net/irda/wrapper.h>
00042 #include <net/irda/timer.h>
00043 #include <net/irda/irda_device.h>
00044 
00045 static hashbin_t *irtty = NULL;
00046 static struct tty_ldisc irda_ldisc;
00047 
00048 static int qos_mtt_bits = 0x03;      /* 5 ms or more */
00049 
00050 /* Network device fuction prototypes */
00051 static int  irtty_hard_xmit(struct sk_buff *skb, struct device *dev);
00052 static int  irtty_net_init(struct device *dev);
00053 static int  irtty_net_open(struct device *dev);
00054 static int  irtty_net_close(struct device *dev);
00055 static int  irtty_net_ioctl(struct device *dev, struct ifreq *rq, int cmd);
00056 static struct net_device_stats *irtty_net_get_stats(struct device *dev);
00057 
00058 /* Line discipline function prototypes */
00059 static int  irtty_open(struct tty_struct *tty);
00060 static void irtty_close(struct tty_struct *tty);
00061 static int  irtty_ioctl(struct tty_struct *, void *, int, void *);
00062 static int  irtty_receive_room(struct tty_struct *tty);
00063 static void irtty_write_wakeup(struct tty_struct *tty);
00064 static void irtty_receive_buf(struct tty_struct *, const unsigned char *, 
00065                               char *, int);
00066 
00067 /* IrDA specific function protoctypes */
00068 static int  irtty_is_receiving(struct irtty_cb *self);
00069 static int  irtty_set_dtr_rts(struct device *dev, int dtr, int rts);
00070 static int  irtty_raw_write(struct device *dev, __u8 *buf, int len);
00071 static int  irtty_raw_read(struct device *dev, __u8 *buf, int len);
00072 static int  irtty_set_mode(struct device *dev, int mode);
00073 static int  irtty_change_speed(struct irda_task *task);
00074 
00075 char *driver_name = "irtty";
00076 
00077 int __init irtty_init(void)
00078 {
00079         int status;
00080         
00081         irtty = hashbin_new( HB_LOCAL);
00082         if ( irtty == NULL) {
00083                 printk( KERN_WARNING "IrDA: Can't allocate irtty hashbin!\n");
00084                 return -ENOMEM;
00085         }
00086 
00087         /* Fill in our line protocol discipline, and register it */
00088         memset(&irda_ldisc, 0, sizeof( irda_ldisc));
00089 
00090         irda_ldisc.magic = TTY_LDISC_MAGIC;
00091         irda_ldisc.name  = "irda";
00092         irda_ldisc.flags = 0;
00093         irda_ldisc.open  = irtty_open;
00094         irda_ldisc.close = irtty_close;
00095         irda_ldisc.read  = NULL;
00096         irda_ldisc.write = NULL;
00097         irda_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *,
00098                                     unsigned int, unsigned long)) irtty_ioctl;
00099         irda_ldisc.poll  = NULL;
00100         irda_ldisc.receive_buf  = irtty_receive_buf;
00101         irda_ldisc.receive_room = irtty_receive_room;
00102         irda_ldisc.write_wakeup = irtty_write_wakeup;
00103         
00104         if ((status = tty_register_ldisc(N_IRDA, &irda_ldisc)) != 0) {
00105                 ERROR("IrDA: can't register line discipline (err = %d)\n", 
00106                       status);
00107         }
00108         
00109         return status;
00110 }
00111 
00112 /* 
00113  *  Function irtty_cleanup ( )
00114  *
00115  *    Called when the irda module is removed. Here we remove all instances
00116  *    of the driver, and the master array.
00117  */
00118 #ifdef MODULE
00119 static void irtty_cleanup(void) 
00120 {
00121         int ret;
00122         
00123         /* Unregister tty line-discipline */
00124         if ((ret = tty_register_ldisc(N_IRDA, NULL))) {
00125                 ERROR(__FUNCTION__ 
00126                       "(), can't unregister line discipline (err = %d)\n",
00127                       ret);
00128         }
00129 
00130         /*
00131          *  The TTY should care of deallocating the instances by using the
00132          *  callback to irtty_close(), therefore we do give any deallocation
00133          *  function to hashbin_destroy().
00134          */
00135         hashbin_delete(irtty, NULL);
00136 }
00137 #endif /* MODULE */
00138 
00139 /* 
00140  *  Function irtty_open(tty)
00141  *
00142  *    This function is called by the TTY module when the IrDA line
00143  *    discipline is called for.  Because we are sure the tty line exists,
00144  *    we only have to link it to a free IrDA channel.  
00145  */
00146 static int irtty_open(struct tty_struct *tty) 
00147 {
00148         struct device *dev;
00149         struct irtty_cb *self;
00150         char name[16];
00151         int err;
00152         
00153         ASSERT(tty != NULL, return -EEXIST;);
00154 
00155         /* First make sure we're not already connected. */
00156         self = (struct irtty_cb *) tty->disc_data;
00157 
00158         if (self != NULL && self->magic == IRTTY_MAGIC)
00159                 return -EEXIST;
00160         
00161         /*
00162          *  Allocate new instance of the driver
00163          */
00164         self = kmalloc(sizeof(struct irtty_cb), GFP_KERNEL);
00165         if (self == NULL) {
00166                 printk(KERN_ERR "IrDA: Can't allocate memory for "
00167                        "IrDA control block!\n");
00168                 return -ENOMEM;
00169         }
00170         memset(self, 0, sizeof(struct irtty_cb));
00171         
00172         self->tty = tty;
00173         tty->disc_data = self;
00174 
00175         /* Give self a name */
00176         sprintf(name, "%s%d", tty->driver.name,
00177                 MINOR(tty->device) - tty->driver.minor_start +
00178                 tty->driver.name_base);
00179 
00180         hashbin_insert(irtty, (queue_t *) self, (int) self, NULL);
00181 
00182         if (tty->driver.flush_buffer)
00183                 tty->driver.flush_buffer(tty);
00184         
00185         if (tty->ldisc.flush_buffer)
00186                 tty->ldisc.flush_buffer(tty);
00187         
00188         self->magic = IRTTY_MAGIC;
00189         self->mode = IRDA_IRLAP;
00190 
00191         /* 
00192          *  Initialize QoS capabilities, we fill in all the stuff that
00193          *  we support. Be careful not to place any restrictions on values
00194          *  that are not device dependent (such as link disconnect time) so
00195          *  this parameter can be set by IrLAP (or the user) instead. DB
00196          */
00197         irda_init_max_qos_capabilies(&self->qos);
00198 
00199         /* The only value we must override it the baudrate */
00200         self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
00201                 IR_115200;
00202         self->qos.min_turn_time.bits = qos_mtt_bits;
00203         self->flags = IFF_SIR | IFF_PIO;
00204         irda_qos_bits_to_value(&self->qos);
00205 
00206         /* Specify how much memory we want */
00207         self->rx_buff.truesize = 4000; 
00208         self->tx_buff.truesize = 4000;
00209 
00210         /* Allocate memory if needed */
00211         if (self->rx_buff.truesize > 0) {
00212                 self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
00213                                                       GFP_KERNEL);
00214                 if (self->rx_buff.head == NULL)
00215                         return -ENOMEM;
00216                 memset(self->rx_buff.head, 0, self->rx_buff.truesize);
00217         }
00218         if (self->tx_buff.truesize > 0) {
00219                 self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
00220                                                       GFP_KERNEL);
00221                 if (self->tx_buff.head == NULL) {
00222                         kfree(self->rx_buff.head);
00223                         return -ENOMEM;
00224                 }
00225                 memset(self->tx_buff.head, 0, self->tx_buff.truesize);
00226         }
00227         
00228         self->rx_buff.in_frame = FALSE;
00229         self->rx_buff.state = OUTSIDE_FRAME;
00230         self->tx_buff.data = self->tx_buff.head;
00231         self->rx_buff.data = self->rx_buff.head;
00232         
00233         if (!(dev = dev_alloc("irda%d", &err))) {
00234                 ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
00235                 return -ENOMEM;
00236         }
00237         /* dev_alloc doesn't clear the struct */
00238         memset(((__u8*)dev)+sizeof(char*),0,sizeof(struct device)-sizeof(char*));
00239 
00240         dev->priv = (void *) self;
00241         self->netdev = dev;
00242 
00243         /* Override the network functions we need to use */
00244         dev->init            = irtty_net_init;
00245         dev->hard_start_xmit = irtty_hard_xmit;
00246         dev->open            = irtty_net_open;
00247         dev->stop            = irtty_net_close;
00248         dev->get_stats       = irtty_net_get_stats;
00249         dev->do_ioctl        = irtty_net_ioctl;
00250 
00251         rtnl_lock();
00252         err = register_netdevice(dev);
00253         rtnl_unlock();
00254         if (err) {
00255                 ERROR(__FUNCTION__ "(), register_netdev() failed!\n");
00256                 return -1;
00257         }
00258 
00259         MESSAGE("IrDA: Registered device %s\n", dev->name);
00260 
00261         MOD_INC_USE_COUNT;
00262 
00263         return 0;
00264 }
00265 
00266 /* 
00267  *  Function irtty_close (tty)
00268  *
00269  *    Close down a IrDA channel. This means flushing out any pending queues,
00270  *    and then restoring the TTY line discipline to what it was before it got
00271  *    hooked to IrDA (which usually is TTY again).  
00272  */
00273 static void irtty_close(struct tty_struct *tty) 
00274 {
00275         struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
00276         
00277         /* First make sure we're connected. */
00278         ASSERT(self != NULL, return;);
00279         ASSERT(self->magic == IRTTY_MAGIC, return;);
00280         
00281         /* Stop tty */
00282         tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
00283         tty->disc_data = 0;
00284         
00285         /* We are not using any dongle anymore! */
00286         if (self->dongle)
00287                 irda_device_dongle_cleanup(self->dongle);
00288         self->dongle = NULL;
00289 
00290         /* Remove netdevice */
00291         if (self->netdev) {
00292                 rtnl_lock();
00293                 unregister_netdevice(self->netdev);
00294                 rtnl_unlock();
00295                 /* Must free the old-style 2.2.x device */
00296                 kfree(self->netdev);
00297         }
00298         
00299         /* Remove speed changing task if any */
00300         if (self->task)
00301                 irda_task_delete(self->task);
00302 
00303         self->tty = NULL;
00304         self->magic = 0;
00305         
00306         self = hashbin_remove(irtty, (int) self, NULL);
00307 
00308         if (self->tx_buff.head)
00309                 kfree(self->tx_buff.head);
00310         
00311         if (self->rx_buff.head)
00312                 kfree(self->rx_buff.head);
00313         
00314         kfree(self);
00315         
00316         MOD_DEC_USE_COUNT;
00317 }
00318 
00319 /*
00320  * Function irtty_stop_receiver (self, stop)
00321  *
00322  *    
00323  *
00324  */
00325 static void irtty_stop_receiver(struct irtty_cb *self, int stop)
00326 {
00327         struct termios old_termios;
00328         int cflag;
00329         
00330         old_termios = *(self->tty->termios);
00331         cflag = self->tty->termios->c_cflag;
00332         
00333         if (stop)
00334                 cflag &= ~CREAD;
00335         else
00336                 cflag |= CREAD;
00337 
00338         self->tty->termios->c_cflag = cflag;
00339         self->tty->driver.set_termios(self->tty, &old_termios);
00340 }
00341 
00342 /* 
00343  *  Function irtty_do_change_speed (self, speed)
00344  *
00345  *    Change the speed of the serial port.
00346  */
00347 static void __irtty_change_speed(struct irtty_cb *self, __u32 speed)
00348 {
00349         struct termios old_termios;
00350         int cflag;
00351 
00352         ASSERT(self != NULL, return;);
00353         ASSERT(self->magic == IRTTY_MAGIC, return;);
00354 
00355         old_termios = *(self->tty->termios);
00356         cflag = self->tty->termios->c_cflag;
00357 
00358         cflag &= ~CBAUD;
00359 
00360         IRDA_DEBUG(2, __FUNCTION__ "(), Setting speed to %d\n", speed);
00361 
00362         switch (speed) {
00363         case 1200:
00364                 cflag |= B1200;
00365                 break;
00366         case 2400:
00367                 cflag |= B2400;
00368                 break;
00369         case 4800:
00370                 cflag |= B4800;
00371                 break;
00372         case 19200:
00373                 cflag |= B19200;
00374                 break;
00375         case 38400:
00376                 cflag |= B38400;
00377                 break;
00378         case 57600:
00379                 cflag |= B57600;
00380                 break;
00381         case 115200:
00382                 cflag |= B115200;
00383                 break;
00384         case 9600:
00385         default:
00386                 cflag |= B9600;
00387                 break;
00388         }       
00389 
00390         self->tty->termios->c_cflag = cflag;
00391         self->tty->driver.set_termios(self->tty, &old_termios);
00392 
00393         self->io.speed = speed;
00394 }
00395 
00396 /*
00397  * Function irtty_change_speed (instance, state, param)
00398  *
00399  *    State machine for changing speed of the device. We do it this way since
00400  *    we cannot use schedule_timeout() when we are in interrupt context
00401  */
00402 static int irtty_change_speed(struct irda_task *task)
00403 {
00404         struct irtty_cb *self;
00405         __u32 speed = (__u32) task->param;
00406         int ret = 0;
00407 
00408         IRDA_DEBUG(2, __FUNCTION__ "(), <%ld>\n", jiffies); 
00409 
00410         self = (struct irtty_cb *) task->instance;
00411         ASSERT(self != NULL, return -1;);
00412 
00413         /* Check if busy */
00414         if (self->task && self->task != task) {
00415                 IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n");
00416                 return MSECS_TO_JIFFIES(10);
00417         } else
00418                 self->task = task;
00419 
00420         switch (task->state) {
00421         case IRDA_TASK_INIT:
00422                 /* 
00423                  * Make sure all data is sent before changing the speed of the
00424                  * serial port.
00425                  */
00426                 if (self->tty->driver.chars_in_buffer(self->tty)) {
00427                         /* Keep state, and try again later */
00428                         ret = MSECS_TO_JIFFIES(10);
00429                         break;
00430                 } else {
00431                         /* Transmit buffer is now empty, but it may still
00432                          * take over 13 ms for the FIFO to become empty, so
00433                          * wait some more to be sure all data is sent
00434                          */
00435                         irda_task_next_state(task, IRDA_TASK_WAIT);
00436                         ret = MSECS_TO_JIFFIES(13);
00437                 }
00438         case IRDA_TASK_WAIT:
00439                 if (self->dongle)
00440                         irda_task_next_state(task, IRDA_TASK_CHILD_INIT);
00441                 else
00442                         irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
00443                 break;
00444         case IRDA_TASK_CHILD_INIT:
00445                 /* Go to default speed */
00446                 __irtty_change_speed(self, 9600);
00447 
00448                 /* Change speed of dongle */
00449                 if (irda_task_execute(self->dongle,
00450                                       self->dongle->issue->change_speed, 
00451                                       NULL, task, (void *) speed))
00452                 {
00453                         /* Dongle need more time to change its speed */
00454                         irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
00455 
00456                         /* Give dongle 1 sec to finish */
00457                         ret = MSECS_TO_JIFFIES(1000);
00458                 } else
00459                         /* Child finished immediately */
00460                         irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
00461                 break;
00462         case IRDA_TASK_CHILD_WAIT:
00463                 WARNING(__FUNCTION__ 
00464                         "(), changing speed of dongle timed out!\n");
00465                 ret = -1;               
00466                 break;
00467         case IRDA_TASK_CHILD_DONE:
00468                 /* Finally we are ready to change the speed */
00469                 __irtty_change_speed(self, speed);
00470                 
00471                 irda_task_next_state(task, IRDA_TASK_DONE);
00472                 self->task = NULL;
00473                 break;
00474         default:
00475                 ERROR(__FUNCTION__ "(), unknown state %d\n", task->state);
00476                 irda_task_next_state(task, IRDA_TASK_DONE);
00477                 self->task = NULL;
00478                 ret = -1;
00479                 break;
00480         }       
00481         return ret;
00482 }
00483 
00484 /*
00485  * Function irtty_ioctl (tty, file, cmd, arg)
00486  *
00487  *     The Swiss army knife of system calls :-)
00488  *
00489  */
00490 static int irtty_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
00491 {
00492         dongle_t *dongle;
00493         struct irtty_info info;
00494         struct irtty_cb *self;
00495         int size = _IOC_SIZE(cmd);
00496         int err = 0;
00497 
00498         self = (struct irtty_cb *) tty->disc_data;
00499 
00500         ASSERT(self != NULL, return -ENODEV;);
00501         ASSERT(self->magic == IRTTY_MAGIC, return -EBADR;);
00502 
00503         if (_IOC_DIR(cmd) & _IOC_READ)
00504                 err = verify_area(VERIFY_WRITE, (void *) arg, size);
00505         else if (_IOC_DIR(cmd) & _IOC_WRITE)
00506                 err = verify_area(VERIFY_READ, (void *) arg, size);
00507         if (err)
00508                 return err;
00509         
00510         switch (cmd) {
00511         case TCGETS:
00512         case TCGETA:
00513                 return n_tty_ioctl(tty, (struct file *) file, cmd, 
00514                                    (unsigned long) arg);
00515                 break;
00516         case IRTTY_IOCTDONGLE:
00517                 /* Initialize dongle */
00518                 dongle = irda_device_dongle_init(self->netdev, (int) arg);
00519                 if (!dongle)
00520                         break;
00521                 
00522                 /* Initialize callbacks */
00523                 dongle->set_mode    = irtty_set_mode;
00524                 dongle->read        = irtty_raw_read;
00525                 dongle->write       = irtty_raw_write;
00526                 dongle->set_dtr_rts = irtty_set_dtr_rts;
00527                 
00528                 /* Bind dongle */
00529                 self->dongle = dongle;
00530                 
00531                 /* Now initialize the dongle!  */
00532                 dongle->issue->open(dongle, &self->qos);
00533                 
00534                 /* Reset dongle */
00535                 irda_task_execute(dongle, dongle->issue->reset, NULL, NULL, 
00536                                   NULL);                
00537                 break;
00538         case IRTTY_IOCGET:
00539                 ASSERT(self->netdev != NULL, return -1;);
00540 
00541                 memset(&info, 0, sizeof(struct irtty_info)); 
00542                 strncpy(info.name, self->netdev->name, 5);
00543 
00544                 if (copy_to_user(arg, &info, sizeof(struct irtty_info)))
00545                         return -EFAULT;
00546                 break;
00547         default:
00548                 return -ENOIOCTLCMD;
00549         }
00550         return 0;
00551 }
00552 
00553 /* 
00554  *  Function irtty_receive_buf( tty, cp, count)
00555  *
00556  *    Handle the 'receiver data ready' interrupt.  This function is called
00557  *    by the 'tty_io' module in the kernel when a block of IrDA data has
00558  *    been received, which can now be decapsulated and delivered for
00559  *    further processing 
00560  */
00561 static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
00562                               char *fp, int count) 
00563 {
00564         struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
00565 
00566         IRDA_DEBUG(2, __FUNCTION__ "(%ld)\n", jiffies);
00567 
00568         if (!self || !self->netdev) {
00569                 IRDA_DEBUG(0, __FUNCTION__ "(), not ready yet!\n");
00570                 return;
00571         }
00572 
00573         /* Read the characters out of the buffer */
00574         while (count--) {
00575                 /* 
00576                  *  Characters received with a parity error, etc?
00577                  */
00578                 if (fp && *fp++) { 
00579                         IRDA_DEBUG(0, "Framing or parity error!\n");
00580                         irda_device_set_media_busy(self->netdev, TRUE);
00581                         
00582                         cp++;
00583                         continue;
00584                 }
00585                 
00586                 switch (self->mode) {
00587                 case IRDA_IRLAP:
00588                         /* Unwrap and destuff one byte */
00589                         async_unwrap_char(self->netdev, &self->stats, 
00590                                           &self->rx_buff, *cp++);
00591                         break;
00592                 case IRDA_RAW:
00593                         /* What should we do when the buffer is full? */
00594                         if (self->rx_buff.len == self->rx_buff.truesize)
00595                                 self->rx_buff.len = 0;
00596                         
00597                         self->rx_buff.data[self->rx_buff.len++] = *cp++;
00598                         break;
00599                 default:
00600                         break;
00601                 }
00602         }
00603 }
00604 
00605 /*
00606  * Function irtty_change_speed_complete (task)
00607  *
00608  *    Called when the change speed operation completes
00609  *
00610  */
00611 static int irtty_change_speed_complete(struct irda_task *task)
00612 {
00613         struct irtty_cb *self;
00614 
00615         IRDA_DEBUG(2, __FUNCTION__ "()\n");
00616 
00617         self = (struct irtty_cb *) task->instance;
00618 
00619         ASSERT(self != NULL, return -1;);
00620         ASSERT(self->netdev != NULL, return -1;);
00621 
00622         /* Finished changing speed, so we are not busy any longer */
00623         self->netdev->tbusy = 0;
00624 
00625         /* Signal network layer so it can try to send the frame */
00626         mark_bh(NET_BH);
00627 
00628         return 0;
00629 }
00630 
00631 /*
00632  * Function irtty_hard_xmit (skb, dev)
00633  *
00634  *    Transmit frame
00635  *
00636  */
00637 static int irtty_hard_xmit(struct sk_buff *skb, struct device *dev)
00638 {
00639         struct irtty_cb *self;
00640         int actual = 0;
00641         __u32 speed;
00642 
00643         self = (struct irtty_cb *) dev->priv;
00644         ASSERT(self != NULL, return 0;);
00645 
00646         /* Lock transmit buffer */
00647         if (irda_lock((void *) &dev->tbusy) == FALSE)
00648                 return -EBUSY;
00649 
00650         /* Check if we need to change the speed */
00651         if ((speed = irda_get_speed(skb)) != self->io.speed)
00652                 self->new_speed = speed;
00653 
00654         /* Init tx buffer*/
00655         self->tx_buff.data = self->tx_buff.head;
00656         
00657         /* Copy skb to tx_buff while wrapping, stuffing and making CRC */
00658         self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, 
00659                                            self->tx_buff.truesize); 
00660 
00661         self->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
00662 
00663         dev->trans_start = jiffies;
00664         self->stats.tx_bytes += self->tx_buff.len;
00665 
00666         if (self->tty->driver.write)
00667                 actual = self->tty->driver.write(self->tty, 0, 
00668                                                  self->tx_buff.data, 
00669                                                  self->tx_buff.len);
00670         /* Hide the part we just transmitted */
00671         self->tx_buff.data += actual;
00672         self->tx_buff.len -= actual;
00673 
00674         dev_kfree_skb(skb);
00675 
00676         return 0;
00677 }
00678 
00679 /*
00680  * Function irtty_receive_room (tty)
00681  *
00682  *    Used by the TTY to find out how much data we can receive at a time
00683  * 
00684 */
00685 static int irtty_receive_room(struct tty_struct *tty) 
00686 {
00687         IRDA_DEBUG(0, __FUNCTION__ "()\n");
00688         return 65536;  /* We can handle an infinite amount of data. :-) */
00689 }
00690 
00691 /*
00692  * Function irtty_write_wakeup (tty)
00693  *
00694  *    Called by the driver when there's room for more data.  If we have
00695  *    more packets to send, we send them here.
00696  *
00697  */
00698 static void irtty_write_wakeup(struct tty_struct *tty) 
00699 {
00700         struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
00701         int actual = 0;
00702         
00703         /* 
00704          *  First make sure we're connected. 
00705          */
00706         ASSERT(self != NULL, return;);
00707         ASSERT(self->magic == IRTTY_MAGIC, return;);
00708 
00709         /* Finished with frame?  */
00710         if (self->tx_buff.len > 0)  {
00711                 /* Write data left in transmit buffer */
00712                 actual = tty->driver.write(tty, 0, self->tx_buff.data, 
00713                                            self->tx_buff.len);
00714 
00715                 self->tx_buff.data += actual;
00716                 self->tx_buff.len  -= actual;
00717         } else {                
00718                 /* 
00719                  *  Now serial buffer is almost free & we can start 
00720                  *  transmission of another packet 
00721                  */
00722                 IRDA_DEBUG(5, __FUNCTION__ "(), finished with frame!\n");
00723                 
00724                 tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
00725 
00726                 if (self->new_speed) {
00727                         IRDA_DEBUG(5, __FUNCTION__ "(), Changing speed!\n");
00728                         irda_task_execute(self, irtty_change_speed, 
00729                                           irtty_change_speed_complete, 
00730                                           NULL, (void *) self->new_speed);
00731                         self->new_speed = 0;
00732                 } else {
00733                         self->netdev->tbusy = 0; /* Unlock */
00734                 
00735                         /* Tell network layer that we want more frames */
00736                         mark_bh(NET_BH);
00737                 }
00738                 self->stats.tx_packets++;
00739         }
00740 }
00741 
00742 /*
00743  * Function irtty_is_receiving (self)
00744  *
00745  *    Return TRUE is we are currently receiving a frame
00746  *
00747  */
00748 static int irtty_is_receiving(struct irtty_cb *self)
00749 {
00750         return (self->rx_buff.state != OUTSIDE_FRAME);
00751 }
00752 
00753 /*
00754  * Function irtty_set_dtr_rts (tty, dtr, rts)
00755  *
00756  *    This function can be used by dongles etc. to set or reset the status
00757  *    of the dtr and rts lines
00758  */
00759 static int irtty_set_dtr_rts(struct device *dev, int dtr, int rts)
00760 {
00761         struct irtty_cb *self;
00762         struct tty_struct *tty;
00763         mm_segment_t fs;
00764         int arg = 0;
00765 
00766         self = (struct irtty_cb *) dev->priv;
00767         tty = self->tty;
00768 
00769 #ifdef TIOCM_OUT2 /* Not defined for ARM */
00770         arg = TIOCM_OUT2;
00771 #endif
00772         if (rts)
00773                 arg |= TIOCM_RTS;
00774         if (dtr)
00775                 arg |= TIOCM_DTR;
00776 
00777         /*
00778          *  The ioctl() function, or actually set_modem_info() in serial.c
00779          *  expects a pointer to the argument in user space. To hack us
00780          *  around this, we use the set_fs() function to fool the routines 
00781          *  that check if they are called from user space. We also need 
00782          *  to send a pointer to the argument so get_user() gets happy. DB.
00783          */
00784 
00785         fs = get_fs();
00786         set_fs(get_ds());
00787         
00788         if (tty->driver.ioctl(tty, NULL, TIOCMSET, (unsigned long) &arg)) { 
00789                 IRDA_DEBUG(2, __FUNCTION__ "(), error doing ioctl!\n");
00790         }
00791         set_fs(fs);
00792 
00793         return 0;
00794 }
00795 
00796 /*
00797  * Function irtty_set_mode (self, status)
00798  *
00799  *    For the airport dongle, we need support for reading raw characters
00800  *    from the IrDA device. This function switches between those modes. 
00801  *    FALSE is the default mode, and will then treat incoming data as IrDA 
00802  *    packets.
00803  */
00804 int irtty_set_mode(struct device *dev, int mode)
00805 {
00806         struct irtty_cb *self;
00807 
00808         self = (struct irtty_cb *) dev->priv;
00809 
00810         ASSERT(self != NULL, return -1;);
00811 
00812         IRDA_DEBUG(2, __FUNCTION__ "(), mode=%s\n", infrared_mode[mode]);
00813         
00814         /* save status for driver */
00815         self->mode = mode;
00816         
00817         /* reset the buffer state */
00818         self->rx_buff.data = self->rx_buff.head;
00819         self->rx_buff.len = 0;
00820         self->rx_buff.state = OUTSIDE_FRAME;
00821 
00822         return 0;
00823 }
00824 
00825 /*
00826  * Function irtty_raw_read (self, buf, len)
00827  *
00828  *    Receive incomming data. This function sleeps, so it must only be
00829  *    called with a process context. Timeout is currently defined to be
00830  *    a multiple of 10 ms.
00831  */
00832 static int irtty_raw_read(struct device *dev, __u8 *buf, int len)
00833 {
00834         struct irtty_cb *self;
00835         int count;
00836 
00837         self = (struct irtty_cb *) dev->priv;
00838 
00839         ASSERT(self != NULL, return 0;);
00840         ASSERT(self->magic == IRTTY_MAGIC, return 0;);
00841 
00842         return 0;
00843 #if 0
00844         buf = self->rx_buff.data;
00845 
00846         /* Wait for the requested amount of data to arrive */
00847         while (len < self->rx_buff.len) {
00848                 current->state = TASK_INTERRUPTIBLE;
00849                 schedule_timeout(MSECS_TO_JIFFIES(10));
00850 
00851                 if (!timeout--)
00852                         break;
00853         }
00854         
00855         count = self->rx_buff.len < len ? self->rx_buff.len : len;
00856 
00857         /* 
00858          * Reset the state, this mean that a raw read is sort of a 
00859          * datagram read, and _not_ a stream style read. Be aware of the
00860          * difference. Implementing it the other way will just be painful ;-)
00861          */
00862         self->rx_buff.data = self->rx_buff.head;
00863         self->rx_buff.len = 0;
00864         self->rx_buff.state = OUTSIDE_FRAME;
00865 #endif
00866         /* Return the amount we were able to get */
00867         return count;
00868 }
00869 
00870 static int irtty_raw_write(struct device *dev, __u8 *buf, int len)
00871 {
00872         struct irtty_cb *self;
00873         int actual = 0;
00874 
00875         self = (struct irtty_cb *) dev->priv;
00876 
00877         ASSERT(self != NULL, return 0;);
00878         ASSERT(self->magic == IRTTY_MAGIC, return 0;);
00879 
00880         if (self->tty->driver.write)
00881                 actual = self->tty->driver.write(self->tty, 0, buf, len);
00882 
00883         return actual;
00884 }
00885 
00886 static int irtty_net_init(struct device *dev)
00887 {
00888         /* Set up to be a normal IrDA network device driver */
00889         irda_device_setup(dev);
00890 
00891         /* Insert overrides below this line! */
00892 
00893         return 0;
00894 }
00895 
00896 static int irtty_net_open(struct device *dev)
00897 {
00898         struct irtty_cb *self = (struct irtty_cb *) dev->priv;
00899 
00900         ASSERT(self != NULL, return -1;);
00901         ASSERT(self->magic == IRTTY_MAGIC, return -1;);
00902 
00903         IRDA_DEBUG(0, __FUNCTION__ "()\n");
00904         
00905         /* Ready to play! */
00906         dev->tbusy = 0;
00907         dev->interrupt = 0;
00908         dev->start = 1;
00909 
00910         /* Make sure we can receive more data */
00911         irtty_stop_receiver(self, FALSE);
00912 
00913         /* 
00914          * Open new IrLAP layer instance, now that everything should be
00915          * initialized properly 
00916          */
00917         self->irlap = irlap_open(dev, &self->qos);
00918 
00919         MOD_INC_USE_COUNT;
00920 
00921         return 0;
00922 }
00923 
00924 static int irtty_net_close(struct device *dev)
00925 {
00926         struct irtty_cb *self = (struct irtty_cb *) dev->priv;
00927 
00928         ASSERT(self != NULL, return -1;);
00929         ASSERT(self->magic == IRTTY_MAGIC, return -1;);
00930 
00931         /* Make sure we don't receive more data */
00932         irtty_stop_receiver(self, TRUE);
00933 
00934         /* Stop device */
00935         dev->tbusy = 1;
00936         dev->start = 0;
00937 
00938         /* Stop and remove instance of IrLAP */
00939         if (self->irlap)
00940                 irlap_close(self->irlap);
00941         self->irlap = NULL;
00942 
00943         MOD_DEC_USE_COUNT;
00944 
00945         return 0;
00946 }
00947 
00948 /*
00949  * Function irtty_net_ioctl (dev, rq, cmd)
00950  *
00951  *    Process IOCTL commands for this device
00952  *
00953  */
00954 static int irtty_net_ioctl(struct device *dev, struct ifreq *rq, int cmd)
00955 {
00956         struct if_irda_req *irq = (struct if_irda_req *) rq;
00957         struct irtty_cb *self;
00958         dongle_t *dongle;
00959         unsigned long flags;
00960         int ret = 0;
00961 
00962         ASSERT(dev != NULL, return -1;);
00963 
00964         self = dev->priv;
00965 
00966         ASSERT(self != NULL, return -1;);
00967         ASSERT(self->magic == IRTTY_MAGIC, return -1;);
00968 
00969         IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
00970         
00971         /* Disable interrupts & save flags */
00972         save_flags(flags);
00973         cli();
00974         
00975         switch (cmd) {
00976         case SIOCSBANDWIDTH: /* Set bandwidth */
00977                 /*
00978                  * This function will also be used by IrLAP to change the
00979                  * speed, so we still must allow for speed change within
00980                  * interrupt context.
00981                  */
00982                 if (!in_interrupt() && !capable(CAP_NET_ADMIN))
00983                         return -EPERM;
00984                 irda_task_execute(self, irtty_change_speed, NULL, NULL, 
00985                                   (void *) irq->ifr_baudrate);
00986                 break;
00987         case SIOCSDONGLE: /* Set dongle */
00988                 if (!capable(CAP_NET_ADMIN))
00989                         return -EPERM;
00990                 /* Initialize dongle */
00991                 dongle = irda_device_dongle_init(dev, irq->ifr_dongle);
00992                 if (!dongle)
00993                         break;
00994                 
00995                 dongle->set_mode    = irtty_set_mode;
00996                 dongle->read        = irtty_raw_read;
00997                 dongle->write       = irtty_raw_write;
00998                 dongle->set_dtr_rts = irtty_set_dtr_rts;
00999                 
01000                 self->dongle = dongle;
01001 
01002                 /* Now initialize the dongle!  */
01003                 dongle->issue->open(dongle, &self->qos);
01004                 
01005                 /* Reset dongle */
01006                 irda_task_execute(dongle, dongle->issue->reset, NULL, NULL, 
01007                                   NULL);        
01008                 break;
01009         case SIOCSMEDIABUSY: /* Set media busy */
01010                 if (!capable(CAP_NET_ADMIN))
01011                         return -EPERM;
01012                 irda_device_set_media_busy(self->netdev, TRUE);
01013                 break;
01014         case SIOCGRECEIVING: /* Check if we are receiving right now */
01015                 irq->ifr_receiving = irtty_is_receiving(self);
01016                 break;
01017         case SIOCSDTRRTS:
01018                 if (!capable(CAP_NET_ADMIN))
01019                         return -EPERM;
01020                 irtty_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts);
01021                 break;
01022         case SIOCSMODE:
01023                 if (!capable(CAP_NET_ADMIN))
01024                         return -EPERM;
01025                 irtty_set_mode(dev, irq->ifr_mode);
01026                 break;
01027         default:
01028                 ret = -EOPNOTSUPP;
01029         }
01030         
01031         restore_flags(flags);
01032         
01033         return ret;
01034 }
01035 
01036 static struct net_device_stats *irtty_net_get_stats(struct device *dev)
01037 {
01038         struct irtty_cb *self = (struct irtty_cb *) dev->priv;
01039 
01040         return &self->stats;
01041 }
01042 
01043 #ifdef MODULE
01044 
01045 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
01046 MODULE_DESCRIPTION("IrDA TTY device driver");
01047 
01048 MODULE_PARM(qos_mtt_bits, "i");
01049 
01050 /*
01051  * Function init_module (void)
01052  *
01053  *    Initialize IrTTY module
01054  *
01055  */
01056 int init_module(void)
01057 {
01058         return irtty_init();
01059 }
01060 
01061 /*
01062  * Function cleanup_module (void)
01063  *
01064  *    Cleanup IrTTY module
01065  *
01066  */
01067 void cleanup_module(void)
01068 {
01069         irtty_cleanup();
01070 }
01071 
01072 #endif /* MODULE */