~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/net/irda/irtty.c

Version: ~ [ 2.2.5 ] ~ [ 2.4.1 ] ~ [ 2.4.9 ] ~ [ 2.6.17.10 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*********************************************************************
  2  *                
  3  * Filename:      irtty.c
  4  * Version:       1.1
  5  * Description:   IrDA line discipline implementation
  6  * Status:        Experimental.
  7  * Author:        Dag Brattli <dagb@cs.uit.no>
  8  * Created at:    Tue Dec  9 21:18:38 1997
  9  * Modified at:   Sat Mar 11 07:43:30 2000
 10  * Modified by:   Dag Brattli <dagb@cs.uit.no>
 11  * Sources:       slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
 12  *                          Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
 13  * 
 14  *     Copyright (c) 1998-2000 Dag Brattli, All Rights Reserved.
 15  *      
 16  *     This program is free software; you can redistribute it and/or 
 17  *     modify it under the terms of the GNU General Public License as 
 18  *     published by the Free Software Foundation; either version 2 of 
 19  *     the License, or (at your option) any later version.
 20  *  
 21  *     Neither Dag Brattli nor University of Tromsų admit liability nor
 22  *     provide warranty for any of this software. This material is 
 23  *     provided "AS-IS" and at no charge.
 24  *     
 25  ********************************************************************/    
 26 
 27 #include <linux/module.h>
 28 #include <linux/kernel.h>
 29 #include <linux/tty.h>
 30 #include <linux/init.h>
 31 #include <linux/skbuff.h>
 32 #include <linux/if_arp.h>
 33 #include <linux/rtnetlink.h>
 34 
 35 #include <asm/segment.h>
 36 #include <asm/uaccess.h>
 37 
 38 #include <net/irda/irda.h>
 39 #include <net/irda/irtty.h>
 40 #include <net/irda/wrapper.h>
 41 #include <net/irda/timer.h>
 42 #include <net/irda/irda_device.h>
 43 
 44 static hashbin_t *irtty = NULL;
 45 static struct tty_ldisc irda_ldisc;
 46 
 47 static int qos_mtt_bits = 0x03;      /* 5 ms or more */
 48 
 49 /* Network device fuction prototypes */
 50 static int  irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev);
 51 static int  irtty_net_init(struct net_device *dev);
 52 static int  irtty_net_open(struct net_device *dev);
 53 static int  irtty_net_close(struct net_device *dev);
 54 static int  irtty_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 55 static struct net_device_stats *irtty_net_get_stats(struct net_device *dev);
 56 
 57 /* Line discipline function prototypes */
 58 static int  irtty_open(struct tty_struct *tty);
 59 static void irtty_close(struct tty_struct *tty);
 60 static int  irtty_ioctl(struct tty_struct *, void *, int, void *);
 61 static int  irtty_receive_room(struct tty_struct *tty);
 62 static void irtty_write_wakeup(struct tty_struct *tty);
 63 static void irtty_receive_buf(struct tty_struct *, const unsigned char *, 
 64                               char *, int);
 65 
 66 /* IrDA specific function protoctypes */
 67 static int  irtty_is_receiving(struct irtty_cb *self);
 68 static int  irtty_set_dtr_rts(struct net_device *dev, int dtr, int rts);
 69 static int  irtty_raw_write(struct net_device *dev, __u8 *buf, int len);
 70 static int  irtty_raw_read(struct net_device *dev, __u8 *buf, int len);
 71 static int  irtty_set_mode(struct net_device *dev, int mode);
 72 static int  irtty_change_speed(struct irda_task *task);
 73 
 74 char *driver_name = "irtty";
 75 
 76 int __init irtty_init(void)
 77 {
 78         int status;
 79         
 80         irtty = hashbin_new( HB_LOCAL);
 81         if ( irtty == NULL) {
 82                 printk( KERN_WARNING "IrDA: Can't allocate irtty hashbin!\n");
 83                 return -ENOMEM;
 84         }
 85 
 86         /* Fill in our line protocol discipline, and register it */
 87         memset(&irda_ldisc, 0, sizeof( irda_ldisc));
 88 
 89         irda_ldisc.magic = TTY_LDISC_MAGIC;
 90         irda_ldisc.name  = "irda";
 91         irda_ldisc.flags = 0;
 92         irda_ldisc.open  = irtty_open;
 93         irda_ldisc.close = irtty_close;
 94         irda_ldisc.read  = NULL;
 95         irda_ldisc.write = NULL;
 96         irda_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *,
 97                                     unsigned int, unsigned long)) irtty_ioctl;
 98         irda_ldisc.poll  = NULL;
 99         irda_ldisc.receive_buf  = irtty_receive_buf;
100         irda_ldisc.receive_room = irtty_receive_room;
101         irda_ldisc.write_wakeup = irtty_write_wakeup;
102         
103         if ((status = tty_register_ldisc(N_IRDA, &irda_ldisc)) != 0) {
104                 ERROR("IrDA: can't register line discipline (err = %d)\n", 
105                       status);
106         }
107         
108         return status;
109 }
110 
111 /* 
112  *  Function irtty_cleanup ( )
113  *
114  *    Called when the irda module is removed. Here we remove all instances
115  *    of the driver, and the master array.
116  */
117 #ifdef MODULE
118 static void irtty_cleanup(void) 
119 {
120         int ret;
121         
122         /* Unregister tty line-discipline */
123         if ((ret = tty_register_ldisc(N_IRDA, NULL))) {
124                 ERROR(__FUNCTION__ 
125                       "(), can't unregister line discipline (err = %d)\n",
126                       ret);
127         }
128 
129         /*
130          *  The TTY should care of deallocating the instances by using the
131          *  callback to irtty_close(), therefore we do give any deallocation
132          *  function to hashbin_destroy().
133          */
134         hashbin_delete(irtty, NULL);
135 }
136 #endif /* MODULE */
137 
138 /* 
139  *  Function irtty_open(tty)
140  *
141  *    This function is called by the TTY module when the IrDA line
142  *    discipline is called for.  Because we are sure the tty line exists,
143  *    we only have to link it to a free IrDA channel.  
144  */
145 static int irtty_open(struct tty_struct *tty) 
146 {
147         struct net_device *dev;
148         struct irtty_cb *self;
149         char name[16];
150         int err;
151         
152         ASSERT(tty != NULL, return -EEXIST;);
153 
154         /* First make sure we're not already connected. */
155         self = (struct irtty_cb *) tty->disc_data;
156 
157         if (self != NULL && self->magic == IRTTY_MAGIC)
158                 return -EEXIST;
159         
160         /*
161          *  Allocate new instance of the driver
162          */
163         self = kmalloc(sizeof(struct irtty_cb), GFP_KERNEL);
164         if (self == NULL) {
165                 printk(KERN_ERR "IrDA: Can't allocate memory for "
166                        "IrDA control block!\n");
167                 return -ENOMEM;
168         }
169         memset(self, 0, sizeof(struct irtty_cb));
170         
171         self->tty = tty;
172         tty->disc_data = self;
173 
174         /* Give self a name */
175         sprintf(name, "%s%d", tty->driver.name,
176                 MINOR(tty->device) - tty->driver.minor_start +
177                 tty->driver.name_base);
178 
179         hashbin_insert(irtty, (irda_queue_t *) self, (int) self, NULL);
180 
181         if (tty->driver.flush_buffer)
182                 tty->driver.flush_buffer(tty);
183         
184         if (tty->ldisc.flush_buffer)
185                 tty->ldisc.flush_buffer(tty);
186         
187         self->magic = IRTTY_MAGIC;
188         self->mode = IRDA_IRLAP;
189 
190         /* 
191          *  Initialize QoS capabilities, we fill in all the stuff that
192          *  we support. Be careful not to place any restrictions on values
193          *  that are not device dependent (such as link disconnect time) so
194          *  this parameter can be set by IrLAP (or the user) instead. DB
195          */
196         irda_init_max_qos_capabilies(&self->qos);
197 
198         /* The only value we must override it the baudrate */
199         self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
200                 IR_115200;
201         self->qos.min_turn_time.bits = qos_mtt_bits;
202         self->flags = IFF_SIR | IFF_PIO;
203         irda_qos_bits_to_value(&self->qos);
204 
205         /* Specify how much memory we want */
206         self->rx_buff.truesize = 4000; 
207         self->tx_buff.truesize = 4000;
208 
209         /* Allocate memory if needed */
210         if (self->rx_buff.truesize > 0) {
211                 self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
212                                                       GFP_KERNEL);
213                 if (self->rx_buff.head == NULL)
214                         return -ENOMEM;
215                 memset(self->rx_buff.head, 0, self->rx_buff.truesize);
216         }
217         if (self->tx_buff.truesize > 0) {
218                 self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
219                                                       GFP_KERNEL);
220                 if (self->tx_buff.head == NULL) {
221                         kfree(self->rx_buff.head);
222                         return -ENOMEM;
223                 }
224                 memset(self->tx_buff.head, 0, self->tx_buff.truesize);
225         }
226         
227         self->rx_buff.in_frame = FALSE;
228         self->rx_buff.state = OUTSIDE_FRAME;
229         self->tx_buff.data = self->tx_buff.head;
230         self->rx_buff.data = self->rx_buff.head;
231         
232         if (!(dev = dev_alloc("irda%d", &err))) {
233                 ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
234                 return -ENOMEM;
235         }
236 
237         dev->priv = (void *) self;
238         self->netdev = dev;
239 
240         /* Override the network functions we need to use */
241         dev->init            = irtty_net_init;
242         dev->hard_start_xmit = irtty_hard_xmit;
243         dev->open            = irtty_net_open;
244         dev->stop            = irtty_net_close;
245         dev->get_stats       = irtty_net_get_stats;
246         dev->do_ioctl        = irtty_net_ioctl;
247 
248         rtnl_lock();
249         err = register_netdevice(dev);
250         rtnl_unlock();
251         if (err) {
252                 ERROR(__FUNCTION__ "(), register_netdev() failed!\n");
253                 return -1;
254         }
255 
256         MESSAGE("IrDA: Registered device %s\n", dev->name);
257 
258         MOD_INC_USE_COUNT;
259 
260         return 0;
261 }
262 
263 /* 
264  *  Function irtty_close (tty)
265  *
266  *    Close down a IrDA channel. This means flushing out any pending queues,
267  *    and then restoring the TTY line discipline to what it was before it got
268  *    hooked to IrDA (which usually is TTY again).  
269  */
270 static void irtty_close(struct tty_struct *tty) 
271 {
272         struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
273         
274         /* First make sure we're connected. */
275         ASSERT(self != NULL, return;);
276         ASSERT(self->magic == IRTTY_MAGIC, return;);
277         
278         /* Stop tty */
279         tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
280         tty->disc_data = 0;
281         
282         /* Remove netdevice */
283         if (self->netdev) {
284                 rtnl_lock();
285                 unregister_netdevice(self->netdev);
286                 rtnl_unlock();
287         }
288         
289         /* We are not using any dongle anymore! */
290         if (self->dongle)
291                 irda_device_dongle_cleanup(self->dongle);
292         self->dongle = NULL;
293 
294         /* Remove speed changing task if any */
295         if (self->task)
296                 irda_task_delete(self->task);
297 
298         self->tty = NULL;
299         self->magic = 0;
300         
301         self = hashbin_remove(irtty, (int) self, NULL);
302 
303         if (self->tx_buff.head)
304                 kfree(self->tx_buff.head);
305         
306         if (self->rx_buff.head)
307                 kfree(self->rx_buff.head);
308         
309         kfree(self);
310         
311         MOD_DEC_USE_COUNT;
312 }
313 
314 /*
315  * Function irtty_stop_receiver (self, stop)
316  *
317  *    
318  *
319  */
320 static void irtty_stop_receiver(struct irtty_cb *self, int stop)
321 {
322         struct termios old_termios;
323         int cflag;
324 
325         old_termios = *(self->tty->termios);
326         cflag = self->tty->termios->c_cflag;
327         
328         if (stop)
329                 cflag &= ~CREAD;
330         else
331                 cflag |= CREAD;
332 
333         self->tty->termios->c_cflag = cflag;
334         self->tty->driver.set_termios(self->tty, &old_termios);
335 }
336 
337 /* 
338  *  Function irtty_do_change_speed (self, speed)
339  *
340  *    Change the speed of the serial port.
341  */
342 static void __irtty_change_speed(struct irtty_cb *self, __u32 speed)
343 {
344         struct termios old_termios;
345         int cflag;
346 
347         ASSERT(self != NULL, return;);
348         ASSERT(self->magic == IRTTY_MAGIC, return;);
349 
350         old_termios = *(self->tty->termios);
351         cflag = self->tty->termios->c_cflag;
352 
353         cflag &= ~CBAUD;
354 
355         IRDA_DEBUG(2, __FUNCTION__ "(), Setting speed to %d\n", speed);
356 
357         switch (speed) {
358         case 1200:
359                 cflag |= B1200;
360                 break;
361         case 2400:
362                 cflag |= B2400;
363                 break;
364         case 4800:
365                 cflag |= B4800;
366                 break;
367         case 19200:
368                 cflag |= B19200;
369                 break;
370         case 38400:
371                 cflag |= B38400;
372                 break;
373         case 57600:
374                 cflag |= B57600;
375                 break;
376         case 115200:
377                 cflag |= B115200;
378                 break;
379         case 9600:
380         default:
381                 cflag |= B9600;
382                 break;
383         }       
384 
385         self->tty->termios->c_cflag = cflag;
386         self->tty->driver.set_termios(self->tty, &old_termios);
387 
388         self->io.speed = speed;
389 }
390 
391 /*
392  * Function irtty_change_speed (instance, state, param)
393  *
394  *    State machine for changing speed of the device. We do it this way since
395  *    we cannot use schedule_timeout() when we are in interrupt context
396  */
397 static int irtty_change_speed(struct irda_task *task)
398 {
399         struct irtty_cb *self;
400         __u32 speed = (__u32) task->param;
401         int ret = 0;
402 
403         IRDA_DEBUG(2, __FUNCTION__ "(), <%ld>\n", jiffies); 
404 
405         self = (struct irtty_cb *) task->instance;
406         ASSERT(self != NULL, return -1;);
407 
408         /* Check if busy */
409         if (self->task && self->task != task) {
410                 IRDA_DEBUG(0, __FUNCTION__ "(), busy!\n");
411                 return MSECS_TO_JIFFIES(10);
412         } else
413                 self->task = task;
414 
415         switch (task->state) {
416         case IRDA_TASK_INIT:
417                 /* 
418                  * Make sure all data is sent before changing the speed of the
419                  * serial port.
420                  */
421                 if (self->tty->driver.chars_in_buffer(self->tty)) {
422                         /* Keep state, and try again later */
423                         ret = MSECS_TO_JIFFIES(10);
424                         break;
425                 } else {
426                         /* Transmit buffer is now empty, but it may still
427                          * take over 13 ms for the FIFO to become empty, so
428                          * wait some more to be sure all data is sent
429                          */
430                         irda_task_next_state(task, IRDA_TASK_WAIT);
431                         ret = MSECS_TO_JIFFIES(13);
432                 }
433         case IRDA_TASK_WAIT:
434                 if (self->dongle)
435                         irda_task_next_state(task, IRDA_TASK_CHILD_INIT);
436                 else
437                         irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
438                 break;
439         case IRDA_TASK_CHILD_INIT:
440                 /* Go to default speed */
441                 __irtty_change_speed(self, 9600);
442 
443                 /* Change speed of dongle */
444                 if (irda_task_execute(self->dongle,
445                                       self->dongle->issue->change_speed, 
446                                       NULL, task, (void *) speed))
447                 {
448                         /* Dongle need more time to change its speed */
449                         irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
450 
451                         /* Give dongle 1 sec to finish */
452                         ret = MSECS_TO_JIFFIES(1000);
453                 } else
454                         /* Child finished immediately */
455                         irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
456                 break;
457         case IRDA_TASK_CHILD_WAIT:
458                 WARNING(__FUNCTION__ 
459                         "(), changing speed of dongle timed out!\n");
460                 ret = -1;               
461                 break;
462         case IRDA_TASK_CHILD_DONE:
463                 /* Finally we are ready to change the speed */
464                 __irtty_change_speed(self, speed);
465                 
466                 irda_task_next_state(task, IRDA_TASK_DONE);
467                 self->task = NULL;
468                 break;
469         default:
470                 ERROR(__FUNCTION__ "(), unknown state %d\n", task->state);
471                 irda_task_next_state(task, IRDA_TASK_DONE);
472                 self->task = NULL;
473                 ret = -1;
474                 break;
475         }       
476         return ret;
477 }
478 
479 /*
480  * Function irtty_ioctl (tty, file, cmd, arg)
481  *
482  *     The Swiss army knife of system calls :-)
483  *
484  */
485 static int irtty_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
486 {
487         dongle_t *dongle;
488         struct irtty_info info;
489         struct irtty_cb *self;
490         int size = _IOC_SIZE(cmd);
491         int err = 0;
492 
493         self = (struct irtty_cb *) tty->disc_data;
494 
495         ASSERT(self != NULL, return -ENODEV;);
496         ASSERT(self->magic == IRTTY_MAGIC, return -EBADR;);
497 
498         if (_IOC_DIR(cmd) & _IOC_READ)
499                 err = verify_area(VERIFY_WRITE, (void *) arg, size);
500         else if (_IOC_DIR(cmd) & _IOC_WRITE)
501                 err = verify_area(VERIFY_READ, (void *) arg, size);
502         if (err)
503                 return err;
504         
505         switch (cmd) {
506         case TCGETS:
507         case TCGETA:
508                 return n_tty_ioctl(tty, (struct file *) file, cmd, 
509                                    (unsigned long) arg);
510                 break;
511         case IRTTY_IOCTDONGLE:
512                 /* Initialize dongle */
513                 dongle = irda_device_dongle_init(self->netdev, (int) arg);
514                 if (!dongle)
515                         break;
516                 
517                 /* Initialize callbacks */
518                 dongle->set_mode    = irtty_set_mode;
519                 dongle->read        = irtty_raw_read;
520                 dongle->write       = irtty_raw_write;
521                 dongle->set_dtr_rts = irtty_set_dtr_rts;
522                 
523                 /* Bind dongle */
524                 self->dongle = dongle;
525                 
526                 /* Now initialize the dongle!  */
527                 dongle->issue->open(dongle, &self->qos);
528                 
529                 /* Reset dongle */
530                 irda_task_execute(dongle, dongle->issue->reset, NULL, NULL, 
531                                   NULL);                
532                 break;
533         case IRTTY_IOCGET:
534                 ASSERT(self->netdev != NULL, return -1;);
535 
536                 memset(&info, 0, sizeof(struct irtty_info)); 
537                 strncpy(info.name, self->netdev->name, 5);
538 
539                 if (copy_to_user(arg, &info, sizeof(struct irtty_info)))
540                         return -EFAULT;
541                 break;
542         default:
543                 return -ENOIOCTLCMD;
544         }
545         return 0;
546 }
547 
548 /* 
549  *  Function irtty_receive_buf( tty, cp, count)
550  *
551  *    Handle the 'receiver data ready' interrupt.  This function is called
552  *    by the 'tty_io' module in the kernel when a block of IrDA data has
553  *    been received, which can now be decapsulated and delivered for
554  *    further processing 
555  */
556 static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
557                               char *fp, int count) 
558 {
559         struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
560 
561         if (!self || !self->netdev) {
562                 IRDA_DEBUG(0, __FUNCTION__ "(), not ready yet!\n");
563                 return;
564         }
565 
566         /* Read the characters out of the buffer */
567         while (count--) {
568                 /* 
569                  *  Characters received with a parity error, etc?
570                  */
571                 if (fp && *fp++) { 
572                         IRDA_DEBUG(0, "Framing or parity error!\n");
573                         irda_device_set_media_busy(self->netdev, TRUE);
574                         
575                         cp++;
576                         continue;
577                 }
578                 
579                 switch (self->mode) {
580                 case IRDA_IRLAP:
581                         /* Unwrap and destuff one byte */
582                         async_unwrap_char(self->netdev, &self->stats, 
583                                           &self->rx_buff, *cp++);
584                         break;
585                 case IRDA_RAW:
586                         /* What should we do when the buffer is full? */
587                         if (self->rx_buff.len == self->rx_buff.truesize)
588                                 self->rx_buff.len = 0;
589                         
590                         self->rx_buff.data[self->rx_buff.len++] = *cp++;
591                         break;
592                 default:
593                         break;
594                 }
595         }
596 }
597 
598 /*
599  * Function irtty_change_speed_complete (task)
600  *
601  *    Called when the change speed operation completes
602  *
603  */
604 static int irtty_change_speed_complete(struct irda_task *task)
605 {
606         struct irtty_cb *self;
607 
608         IRDA_DEBUG(2, __FUNCTION__ "()\n");
609 
610         self = (struct irtty_cb *) task->instance;
611 
612         ASSERT(self != NULL, return -1;);
613         ASSERT(self->netdev != NULL, return -1;);
614 
615         /* Finished changing speed, so we are not busy any longer */
616         /* Signal network layer so it can try to send the frame */
617         netif_wake_queue(self->netdev);
618         
619         return 0;
620 }
621 
622 /*
623  * Function irtty_hard_xmit (skb, dev)
624  *
625  *    Transmit frame
626  *
627  */
628 static int irtty_hard_xmit(struct sk_buff *skb, struct net_device *dev)
629 {
630         struct irtty_cb *self;
631         int actual = 0;
632         __u32 speed;
633 
634         self = (struct irtty_cb *) dev->priv;
635         ASSERT(self != NULL, return 0;);
636 
637         /* Lock transmit buffer */
638         netif_stop_queue(dev);
639         
640         /* Check if we need to change the speed */
641         if ((speed = irda_get_speed(skb)) != self->io.speed) {
642                 /* Check for empty frame */
643                 if (!skb->len) {
644                         irda_task_execute(self, irtty_change_speed, 
645                                           irtty_change_speed_complete, 
646                                           NULL, (void *) speed);
647                         return 0;
648                 } else
649                         self->new_speed = speed;
650         }
651 
652         /* Init tx buffer*/
653         self->tx_buff.data = self->tx_buff.head;
654         
655         /* Copy skb to tx_buff while wrapping, stuffing and making CRC */
656         self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, 
657                                            self->tx_buff.truesize); 
658 
659         self->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
660 
661         dev->trans_start = jiffies;
662         self->stats.tx_bytes += self->tx_buff.len;
663 
664         if (self->tty->driver.write)
665                 actual = self->tty->driver.write(self->tty, 0, 
666                                                  self->tx_buff.data, 
667                                                  self->tx_buff.len);
668         /* Hide the part we just transmitted */
669         self->tx_buff.data += actual;
670         self->tx_buff.len -= actual;
671 
672         dev_kfree_skb(skb);
673 
674         return 0;
675 }
676 
677 /*
678  * Function irtty_receive_room (tty)
679  *
680  *    Used by the TTY to find out how much data we can receive at a time
681  * 
682 */
683 static int irtty_receive_room(struct tty_struct *tty) 
684 {
685         IRDA_DEBUG(0, __FUNCTION__ "()\n");
686         return 65536;  /* We can handle an infinite amount of data. :-) */
687 }
688 
689 /*
690  * Function irtty_write_wakeup (tty)
691  *
692  *    Called by the driver when there's room for more data.  If we have
693  *    more packets to send, we send them here.
694  *
695  */
696 static void irtty_write_wakeup(struct tty_struct *tty) 
697 {
698         struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
699         int actual = 0;
700         
701         /* 
702          *  First make sure we're connected. 
703          */
704         ASSERT(self != NULL, return;);
705         ASSERT(self->magic == IRTTY_MAGIC, return;);
706 
707         /* Finished with frame?  */
708         if (self->tx_buff.len > 0)  {
709                 /* Write data left in transmit buffer */
710                 actual = tty->driver.write(tty, 0, self->tx_buff.data, 
711                                            self->tx_buff.len);
712 
713                 self->tx_buff.data += actual;
714                 self->tx_buff.len  -= actual;
715 
716                 self->stats.tx_packets++;                     
717         } else {                
718                 /* 
719                  *  Now serial buffer is almost free & we can start 
720                  *  transmission of another packet 
721                  */
722                 IRDA_DEBUG(5, __FUNCTION__ "(), finished with frame!\n");
723                 
724                 tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
725 
726                 if (self->new_speed) {
727                         IRDA_DEBUG(5, __FUNCTION__ "(), Changing speed!\n");
728                         irda_task_execute(self, irtty_change_speed, 
729                                           irtty_change_speed_complete, 
730                                           NULL, (void *) self->new_speed);
731                         self->new_speed = 0;
732                 } else {
733                         /* Tell network layer that we want more frames */
734                         netif_wake_queue(self->netdev);
735                 }
736         }
737 }
738 
739 /*
740  * Function irtty_is_receiving (self)
741  *
742  *    Return TRUE is we are currently receiving a frame
743  *
744  */
745 static int irtty_is_receiving(struct irtty_cb *self)
746 {
747         return (self->rx_buff.state != OUTSIDE_FRAME);
748 }
749 
750 /*
751  * Function irtty_set_dtr_rts (tty, dtr, rts)
752  *
753  *    This function can be used by dongles etc. to set or reset the status
754  *    of the dtr and rts lines
755  */
756 static int irtty_set_dtr_rts(struct net_device *dev, int dtr, int rts)
757 {
758         struct irtty_cb *self;
759         struct tty_struct *tty;
760         mm_segment_t fs;
761         int arg = 0;
762 
763         self = (struct irtty_cb *) dev->priv;
764         tty = self->tty;
765 
766 #ifdef TIOCM_OUT2 /* Not defined for ARM */
767         arg = TIOCM_OUT2;
768 #endif
769         if (rts)
770                 arg |= TIOCM_RTS;
771         if (dtr)
772                 arg |= TIOCM_DTR;
773 
774         /*
775          *  The ioctl() function, or actually set_modem_info() in serial.c
776          *  expects a pointer to the argument in user space. To hack us
777          *  around this, we use the set_fs() function to fool the routines 
778          *  that check if they are called from user space. We also need 
779          *  to send a pointer to the argument so get_user() gets happy. DB.
780          */
781 
782         fs = get_fs();
783         set_fs(get_ds());
784         
785         if (tty->driver.ioctl(tty, NULL, TIOCMSET, (unsigned long) &arg)) { 
786                 IRDA_DEBUG(2, __FUNCTION__ "(), error doing ioctl!\n");
787         }
788         set_fs(fs);
789 
790         return 0;
791 }
792 
793 /*
794  * Function irtty_set_mode (self, status)
795  *
796  *    For the airport dongle, we need support for reading raw characters
797  *    from the IrDA device. This function switches between those modes. 
798  *    FALSE is the default mode, and will then treat incoming data as IrDA 
799  *    packets.
800  */
801 int irtty_set_mode(struct net_device *dev, int mode)
802 {
803         struct irtty_cb *self;
804 
805         self = (struct irtty_cb *) dev->priv;
806 
807         ASSERT(self != NULL, return -1;);
808 
809         IRDA_DEBUG(2, __FUNCTION__ "(), mode=%s\n", infrared_mode[mode]);
810         
811         /* save status for driver */
812         self->mode = mode;
813         
814         /* reset the buffer state */
815         self->rx_buff.data = self->rx_buff.head;
816         self->rx_buff.len = 0;
817         self->rx_buff.state = OUTSIDE_FRAME;
818 
819         return 0;
820 }
821 
822 /*
823  * Function irtty_raw_read (self, buf, len)
824  *
825  *    Receive incomming data. This function sleeps, so it must only be
826  *    called with a process context. Timeout is currently defined to be
827  *    a multiple of 10 ms.
828  */
829 static int irtty_raw_read(struct net_device *dev, __u8 *buf, int len)
830 {
831         struct irtty_cb *self;
832         int count;
833 
834         self = (struct irtty_cb *) dev->priv;
835 
836         ASSERT(self != NULL, return 0;);
837         ASSERT(self->magic == IRTTY_MAGIC, return 0;);
838 
839         return 0;
840 #if 0
841         buf = self->rx_buff.data;
842 
843         /* Wait for the requested amount of data to arrive */
844         while (len < self->rx_buff.len) {
845                 current->state = TASK_INTERRUPTIBLE;
846                 schedule_timeout(MSECS_TO_JIFFIES(10));
847 
848                 if (!timeout--)
849                         break;
850         }
851         
852         count = self->rx_buff.len < len ? self->rx_buff.len : len;
853 
854         /* 
855          * Reset the state, this mean that a raw read is sort of a 
856          * datagram read, and _not_ a stream style read. Be aware of the
857          * difference. Implementing it the other way will just be painful ;-)
858          */
859         self->rx_buff.data = self->rx_buff.head;
860         self->rx_buff.len = 0;
861         self->rx_buff.state = OUTSIDE_FRAME;
862 #endif
863         /* Return the amount we were able to get */
864         return count;
865 }
866 
867 static int irtty_raw_write(struct net_device *dev, __u8 *buf, int len)
868 {
869         struct irtty_cb *self;
870         int actual = 0;
871 
872         self = (struct irtty_cb *) dev->priv;
873 
874         ASSERT(self != NULL, return 0;);
875         ASSERT(self->magic == IRTTY_MAGIC, return 0;);
876 
877         if (self->tty->driver.write)
878                 actual = self->tty->driver.write(self->tty, 0, buf, len);
879 
880         return actual;
881 }
882 
883 static int irtty_net_init(struct net_device *dev)
884 {
885         /* Set up to be a normal IrDA network device driver */
886         irda_device_setup(dev);
887 
888         /* Insert overrides below this line! */
889 
890         return 0;
891 }
892 
893 static int irtty_net_open(struct net_device *dev)
894 {
895         struct irtty_cb *self = (struct irtty_cb *) dev->priv;
896 
897         ASSERT(self != NULL, return -1;);
898         ASSERT(self->magic == IRTTY_MAGIC, return -1;);
899 
900         IRDA_DEBUG(0, __FUNCTION__ "()\n");
901         
902         /* Ready to play! */
903         netif_start_queue(dev);
904         
905         /* Make sure we can receive more data */
906         irtty_stop_receiver(self, FALSE);
907 
908         /* 
909          * Open new IrLAP layer instance, now that everything should be
910          * initialized properly 
911          */
912         self->irlap = irlap_open(dev, &self->qos);
913 
914         MOD_INC_USE_COUNT;
915 
916         return 0;
917 }
918 
919 static int irtty_net_close(struct net_device *dev)
920 {
921         struct irtty_cb *self = (struct irtty_cb *) dev->priv;
922 
923         ASSERT(self != NULL, return -1;);
924         ASSERT(self->magic == IRTTY_MAGIC, return -1;);
925 
926         /* Make sure we don't receive more data */
927         irtty_stop_receiver(self, TRUE);
928 
929         /* Stop device */
930         netif_stop_queue(dev);
931         
932         /* Stop and remove instance of IrLAP */
933         if (self->irlap)
934                 irlap_close(self->irlap);
935         self->irlap = NULL;
936 
937         MOD_DEC_USE_COUNT;
938 
939         return 0;
940 }
941 
942 /*
943  * Function irtty_net_ioctl (dev, rq, cmd)
944  *
945  *    Process IOCTL commands for this device
946  *
947  */
948 static int irtty_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
949 {
950         struct if_irda_req *irq = (struct if_irda_req *) rq;
951         struct irtty_cb *self;
952         dongle_t *dongle;
953         unsigned long flags;
954         int ret = 0;
955 
956         ASSERT(dev != NULL, return -1;);
957 
958         self = dev->priv;
959 
960         ASSERT(self != NULL, return -1;);
961         ASSERT(self->magic == IRTTY_MAGIC, return -1;);
962 
963         IRDA_DEBUG(3, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
964         
965         /* Disable interrupts & save flags */
966         save_flags(flags);
967         cli();
968         
969         switch (cmd) {
970         case SIOCSBANDWIDTH: /* Set bandwidth */
971                 if (!capable(CAP_NET_ADMIN))
972                         return -EPERM;
973                 irda_task_execute(self, irtty_change_speed, NULL, NULL, 
974                                   (void *) irq->ifr_baudrate);
975                 break;
976         case SIOCSDONGLE: /* Set dongle */
977                 if (!capable(CAP_NET_ADMIN))
978                         return -EPERM;
979                 /* Initialize dongle */
980                 dongle = irda_device_dongle_init(dev, irq->ifr_dongle);
981                 if (!dongle)
982                         break;
983                 
984                 dongle->set_mode    = irtty_set_mode;
985                 dongle->read        = irtty_raw_read;
986                 dongle->write       = irtty_raw_write;
987                 dongle->set_dtr_rts = irtty_set_dtr_rts;
988                 
989                 self->dongle = dongle;
990 
991                 /* Now initialize the dongle!  */
992                 dongle->issue->open(dongle, &self->qos);
993                 
994                 /* Reset dongle */
995                 irda_task_execute(dongle, dongle->issue->reset, NULL, NULL, 
996                                   NULL);        
997                 break;
998         case SIOCSMEDIABUSY: /* Set media busy */
999                 if (!capable(CAP_NET_ADMIN))
1000                         return -EPERM;
1001                 irda_device_set_media_busy(self->netdev, TRUE);
1002                 break;
1003         case SIOCGRECEIVING: /* Check if we are receiving right now */
1004                 irq->ifr_receiving = irtty_is_receiving(self);
1005                 break;
1006         case SIOCSDTRRTS:
1007                 if (!capable(CAP_NET_ADMIN))
1008                         return -EPERM;
1009                 irtty_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts);
1010                 break;
1011         case SIOCSMODE:
1012                 if (!capable(CAP_NET_ADMIN))
1013                         return -EPERM;
1014                 irtty_set_mode(dev, irq->ifr_mode);
1015                 break;
1016         default:
1017                 ret = -EOPNOTSUPP;
1018         }
1019         
1020         restore_flags(flags);
1021         
1022         return ret;
1023 }
1024 
1025 static struct net_device_stats *irtty_net_get_stats(struct net_device *dev)
1026 {
1027         struct irtty_cb *self = (struct irtty_cb *) dev->priv;
1028 
1029         return &self->stats;
1030 }
1031 
1032 #ifdef MODULE
1033 
1034 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
1035 MODULE_DESCRIPTION("IrDA TTY device driver");
1036 
1037 MODULE_PARM(qos_mtt_bits, "i");
1038 MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time");
1039 
1040 /*
1041  * Function init_module (void)
1042  *
1043  *    Initialize IrTTY module
1044  *
1045  */
1046 int init_module(void)
1047 {
1048         return irtty_init();
1049 }
1050 
1051 /*
1052  * Function cleanup_module (void)
1053  *
1054  *    Cleanup IrTTY module
1055  *
1056  */
1057 void cleanup_module(void)
1058 {
1059         irtty_cleanup();
1060 }
1061 
1062 #endif /* MODULE */
1063 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.