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

Linux Cross Reference
Linux/drivers/net/irda/irport.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:      irport.c
  4  * Version:       1.0
  5  * Description:   Half duplex serial port SIR driver for IrDA. 
  6  * Status:        Experimental.
  7  * Author:        Dag Brattli <dagb@cs.uit.no>
  8  * Created at:    Sun Aug  3 13:49:59 1997
  9  * Modified at:   Fri Jan 28 20:22:38 2000
 10  * Modified by:   Dag Brattli <dagb@cs.uit.no>
 11  * Sources:       serial.c by Linus Torvalds 
 12  * 
 13  *     Copyright (c) 1997, 1998, 1999-2000 Dag Brattli, All Rights Reserved.
 14  *     
 15  *     This program is free software; you can redistribute it and/or 
 16  *     modify it under the terms of the GNU General Public License as 
 17  *     published by the Free Software Foundation; either version 2 of 
 18  *     the License, or (at your option) any later version.
 19  * 
 20  *     This program is distributed in the hope that it will be useful,
 21  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 22  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 23  *     GNU General Public License for more details.
 24  * 
 25  *     You should have received a copy of the GNU General Public License 
 26  *     along with this program; if not, write to the Free Software 
 27  *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
 28  *     MA 02111-1307 USA
 29  *
 30  *     This driver is ment to be a small half duplex serial driver to be
 31  *     used for IR-chipsets that has a UART (16550) compatibility mode. 
 32  *     Eventually it will replace irtty, because of irtty has some 
 33  *     problems that is hard to get around when we don't have control
 34  *     over the serial driver. This driver may also be used by FIR 
 35  *     drivers to handle SIR mode for them.
 36  *
 37  ********************************************************************/
 38 
 39 #include <linux/module.h>
 40 
 41 #include <linux/kernel.h>
 42 #include <linux/types.h>
 43 #include <linux/ioport.h>
 44 #include <linux/slab.h>
 45 #include <linux/string.h>
 46 #include <linux/skbuff.h>
 47 #include <linux/serial_reg.h>
 48 #include <linux/errno.h>
 49 #include <linux/init.h>
 50 #include <linux/spinlock.h>
 51 #include <linux/rtnetlink.h>
 52 
 53 #include <asm/system.h>
 54 #include <asm/bitops.h>
 55 #include <asm/io.h>
 56 
 57 #include <net/irda/irda.h>
 58 #include <net/irda/irmod.h>
 59 #include <net/irda/wrapper.h>
 60 #include <net/irda/irport.h>
 61 
 62 #define IO_EXTENT 8
 63 
 64 /* 
 65  * Currently you'll need to set these values using insmod like this:
 66  * insmod irport io=0x3e8 irq=11
 67  */
 68 static unsigned int io[]  = { ~0, ~0, ~0, ~0 };
 69 static unsigned int irq[] = { 0, 0, 0, 0 };
 70 
 71 static unsigned int qos_mtt_bits = 0x03;
 72 
 73 static struct irport_cb *dev_self[] = { NULL, NULL, NULL, NULL};
 74 static char *driver_name = "irport";
 75 
 76 static void irport_write_wakeup(struct irport_cb *self);
 77 static int  irport_write(int iobase, int fifo_size, __u8 *buf, int len);
 78 static void irport_receive(struct irport_cb *self);
 79 
 80 static int  irport_net_init(struct net_device *dev);
 81 static int  irport_net_ioctl(struct net_device *dev, struct ifreq *rq, 
 82                              int cmd);
 83 static int  irport_is_receiving(struct irport_cb *self);
 84 static int  irport_set_dtr_rts(struct net_device *dev, int dtr, int rts);
 85 static int  irport_raw_write(struct net_device *dev, __u8 *buf, int len);
 86 static struct net_device_stats *irport_net_get_stats(struct net_device *dev);
 87 static int irport_change_speed_complete(struct irda_task *task);
 88 static void irport_timeout(struct net_device *dev);
 89 
 90 EXPORT_SYMBOL(irport_open);
 91 EXPORT_SYMBOL(irport_close);
 92 EXPORT_SYMBOL(irport_start);
 93 EXPORT_SYMBOL(irport_stop);
 94 EXPORT_SYMBOL(irport_interrupt);
 95 EXPORT_SYMBOL(irport_hard_xmit);
 96 EXPORT_SYMBOL(irport_timeout);
 97 EXPORT_SYMBOL(irport_change_speed);
 98 EXPORT_SYMBOL(irport_net_open);
 99 EXPORT_SYMBOL(irport_net_close);
100 
101 int __init irport_init(void)
102 {
103         int i;
104 
105         for (i=0; (io[i] < 2000) && (i < 4); i++) {
106                 int ioaddr = io[i];
107                 if (check_region(ioaddr, IO_EXTENT))
108                         continue;
109                 if (irport_open(i, io[i], irq[i]) != NULL)
110                         return 0;
111         }
112         /* 
113          * Maybe something failed, but we can still be usable for FIR drivers 
114          */
115         return 0;
116 }
117 
118 /*
119  * Function irport_cleanup ()
120  *
121  *    Close all configured ports
122  *
123  */
124 #ifdef MODULE
125 static void irport_cleanup(void)
126 {
127         int i;
128 
129         IRDA_DEBUG( 4, __FUNCTION__ "()\n");
130 
131         for (i=0; i < 4; i++) {
132                 if (dev_self[i])
133                         irport_close(dev_self[i]);
134         }
135 }
136 #endif /* MODULE */
137 
138 struct irport_cb *
139 irport_open(int i, unsigned int iobase, unsigned int irq)
140 {
141         struct net_device *dev;
142         struct irport_cb *self;
143         int ret;
144         int err;
145 
146         IRDA_DEBUG(0, __FUNCTION__ "()\n");
147 
148         /*
149          *  Allocate new instance of the driver
150          */
151         self = kmalloc(sizeof(struct irport_cb), GFP_KERNEL);
152         if (!self) {
153                 ERROR(__FUNCTION__ "(), can't allocate memory for "
154                       "control block!\n");
155                 return NULL;
156         }
157         memset(self, 0, sizeof(struct irport_cb));
158         spin_lock_init(&self->lock);
159 
160         /* Need to store self somewhere */
161         dev_self[i] = self;
162         self->priv = self;
163         self->index = i;
164 
165         /* Initialize IO */
166         self->io.sir_base  = iobase;
167         self->io.sir_ext   = IO_EXTENT;
168         self->io.irq       = irq;
169         self->io.fifo_size = 16;
170 
171         /* Lock the port that we need */
172         ret = check_region(self->io.sir_base, self->io.sir_ext);
173         if (ret < 0) { 
174                 IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
175                            self->io.sir_base);
176                 return NULL;
177         }
178         request_region(self->io.sir_base, self->io.sir_ext, driver_name);
179 
180         /* Initialize QoS for this device */
181         irda_init_max_qos_capabilies(&self->qos);
182         
183         self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
184                 IR_115200;
185 
186         self->qos.min_turn_time.bits = qos_mtt_bits;
187         irda_qos_bits_to_value(&self->qos);
188         
189         self->flags = IFF_SIR|IFF_PIO;
190 
191         /* Specify how much memory we want */
192         self->rx_buff.truesize = 4000; 
193         self->tx_buff.truesize = 4000;
194         
195         /* Allocate memory if needed */
196         if (self->rx_buff.truesize > 0) {
197                 self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
198                                                       GFP_KERNEL);
199                 if (self->rx_buff.head == NULL)
200                         return NULL;
201                 memset(self->rx_buff.head, 0, self->rx_buff.truesize);
202         }
203         if (self->tx_buff.truesize > 0) {
204                 self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
205                                                       GFP_KERNEL);
206                 if (self->tx_buff.head == NULL) {
207                         kfree(self->rx_buff.head);
208                         return NULL;
209                 }
210                 memset(self->tx_buff.head, 0, self->tx_buff.truesize);
211         }       
212         self->rx_buff.in_frame = FALSE;
213         self->rx_buff.state = OUTSIDE_FRAME;
214         self->tx_buff.data = self->tx_buff.head;
215         self->rx_buff.data = self->rx_buff.head;
216         self->mode = IRDA_IRLAP;
217 
218         if (!(dev = dev_alloc("irda%d", &err))) {
219                 ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
220                 return NULL;
221         }
222         self->netdev = dev;
223 
224         /* May be overridden by piggyback drivers */
225         dev->priv = (void *) self;
226         self->interrupt    = irport_interrupt;
227         self->change_speed = irport_change_speed;
228 
229         /* Override the network functions we need to use */
230         dev->init            = irport_net_init;
231         dev->hard_start_xmit = irport_hard_xmit;
232         dev->tx_timeout      = irport_timeout;
233         dev->watchdog_timeo  = HZ;  /* Allow time enough for speed change */
234         dev->open            = irport_net_open;
235         dev->stop            = irport_net_close;
236         dev->get_stats       = irport_net_get_stats;
237         dev->do_ioctl        = irport_net_ioctl;
238 
239         /* Make ifconfig display some details */
240         dev->base_addr = iobase;
241         dev->irq = irq;
242 
243         rtnl_lock();
244         err = register_netdevice(dev);
245         rtnl_unlock();
246         if (err) {
247                 ERROR(__FUNCTION__ "(), register_netdev() failed!\n");
248                 return NULL;
249         }
250         MESSAGE("IrDA: Registered device %s\n", dev->name);
251 
252         return self;
253 }
254 
255 int irport_close(struct irport_cb *self)
256 {
257         ASSERT(self != NULL, return -1;);
258 
259         /* We are not using any dongle anymore! */
260         if (self->dongle)
261                 irda_device_dongle_cleanup(self->dongle);
262         self->dongle = NULL;
263         
264         /* Remove netdevice */
265         if (self->netdev) {
266                 rtnl_lock();
267                 unregister_netdevice(self->netdev);
268                 rtnl_unlock();
269         }
270 
271         /* Release the IO-port that this driver is using */
272         IRDA_DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", 
273                    self->io.sir_base);
274         release_region(self->io.sir_base, self->io.sir_ext);
275 
276         if (self->tx_buff.head)
277                 kfree(self->tx_buff.head);
278         
279         if (self->rx_buff.head)
280                 kfree(self->rx_buff.head);
281         
282         /* Remove ourselves */
283         dev_self[self->index] = NULL;
284         kfree(self);
285         
286         return 0;
287 }
288 
289 void irport_start(struct irport_cb *self)
290 {
291         unsigned long flags;
292         int iobase;
293 
294         iobase = self->io.sir_base;
295 
296         irport_stop(self);
297         
298         spin_lock_irqsave(&self->lock, flags);
299 
300         /* Initialize UART */
301         outb(UART_LCR_WLEN8, iobase+UART_LCR);  /* Reset DLAB */
302         outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase+UART_MCR);
303         
304         /* Turn on interrups */
305         outb(UART_IER_RLSI | UART_IER_RDI |UART_IER_THRI, iobase+UART_IER);
306 
307         spin_unlock_irqrestore(&self->lock, flags);
308 }
309 
310 void irport_stop(struct irport_cb *self)
311 {
312         unsigned long flags;
313         int iobase;
314 
315         iobase = self->io.sir_base;
316 
317         spin_lock_irqsave(&self->lock, flags);
318 
319         /* Reset UART */
320         outb(0, iobase+UART_MCR);
321         
322         /* Turn off interrupts */
323         outb(0, iobase+UART_IER);
324 
325         spin_unlock_irqrestore(&self->lock, flags);
326 }
327 
328 /*
329  * Function irport_probe (void)
330  *
331  *    Start IO port 
332  *
333  */
334 int irport_probe(int iobase)
335 {
336         IRDA_DEBUG(4, __FUNCTION__ "(), iobase=%#x\n", iobase);
337 
338         return 0;
339 }
340 
341 /*
342  * Function irport_change_speed (self, speed)
343  *
344  *    Set speed of IrDA port to specified baudrate
345  *
346  */
347 void irport_change_speed(void *priv, __u32 speed)
348 {
349         struct irport_cb *self = (struct irport_cb *) priv;
350         unsigned long flags;
351         int iobase; 
352         int fcr;    /* FIFO control reg */
353         int lcr;    /* Line control reg */
354         int divisor;
355 
356         IRDA_DEBUG(0, __FUNCTION__ "(), Setting speed to: %d\n", speed);
357 
358         ASSERT(self != NULL, return;);
359 
360         iobase = self->io.sir_base;
361         
362         /* Update accounting for new speed */
363         self->io.speed = speed;
364 
365         spin_lock_irqsave(&self->lock, flags);
366 
367         /* Turn off interrupts */
368         outb(0, iobase+UART_IER); 
369 
370         divisor = SPEED_MAX/speed;
371         
372         fcr = UART_FCR_ENABLE_FIFO;
373 
374         /* 
375          * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
376          * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
377          * about this timeout since it will always be fast enough. 
378          */
379         if (self->io.speed < 38400)
380                 fcr |= UART_FCR_TRIGGER_1;
381         else 
382                 fcr |= UART_FCR_TRIGGER_14;
383         
384         /* IrDA ports use 8N1 */
385         lcr = UART_LCR_WLEN8;
386         
387         outb(UART_LCR_DLAB | lcr, iobase+UART_LCR); /* Set DLAB */
388         outb(divisor & 0xff,      iobase+UART_DLL); /* Set speed */
389         outb(divisor >> 8,        iobase+UART_DLM);
390         outb(lcr,                 iobase+UART_LCR); /* Set 8N1  */
391         outb(fcr,                 iobase+UART_FCR); /* Enable FIFO's */
392 
393         /* Turn on interrups */
394         outb(/*UART_IER_RLSI|*/UART_IER_RDI/*|UART_IER_THRI*/, iobase+UART_IER);
395 
396         spin_unlock_irqrestore(&self->lock, flags);
397 }
398 
399 /*
400  * Function __irport_change_speed (instance, state, param)
401  *
402  *    State machine for changing speed of the device. We do it this way since
403  *    we cannot use schedule_timeout() when we are in interrupt context
404  */
405 int __irport_change_speed(struct irda_task *task)
406 {
407         struct irport_cb *self;
408         __u32 speed = (__u32) task->param;
409         int ret = 0;
410 
411         IRDA_DEBUG(2, __FUNCTION__ "(), <%ld>\n", jiffies); 
412 
413         self = (struct irport_cb *) task->instance;
414 
415         ASSERT(self != NULL, return -1;);
416 
417         switch (task->state) {
418         case IRDA_TASK_INIT:
419         case IRDA_TASK_WAIT:
420                 /* Are we ready to change speed yet? */
421                 if (self->tx_buff.len > 0) {
422                         task->state = IRDA_TASK_WAIT;
423 
424                         /* Try again later */
425                         ret = MSECS_TO_JIFFIES(20);
426                         break;
427                 }
428 
429                 if (self->dongle)
430                         irda_task_next_state(task, IRDA_TASK_CHILD_INIT);
431                 else
432                         irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
433                 break;
434         case IRDA_TASK_CHILD_INIT:
435                 /* Go to default speed */
436                 self->change_speed(self->priv, 9600);
437 
438                 /* Change speed of dongle */
439                 if (irda_task_execute(self->dongle,
440                                       self->dongle->issue->change_speed, 
441                                       NULL, task, (void *) speed))
442                 {
443                         /* Dongle need more time to change its speed */
444                         irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
445 
446                         /* Give dongle 1 sec to finish */
447                         ret = MSECS_TO_JIFFIES(1000);
448                 } else
449                         /* Child finished immediately */
450                         irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
451                 break;
452         case IRDA_TASK_CHILD_WAIT:
453                 WARNING(__FUNCTION__ 
454                         "(), changing speed of dongle timed out!\n");
455                 ret = -1;               
456                 break;
457         case IRDA_TASK_CHILD_DONE:
458                 /* Finally we are ready to change the speed */
459                 self->change_speed(self->priv, speed);
460                 
461                 irda_task_next_state(task, IRDA_TASK_DONE);
462                 break;
463         default:
464                 ERROR(__FUNCTION__ "(), unknown state %d\n", task->state);
465                 irda_task_next_state(task, IRDA_TASK_DONE);
466                 ret = -1;
467                 break;
468         }       
469         return ret;
470 }
471 
472 /*
473  * Function irport_write_wakeup (tty)
474  *
475  *    Called by the driver when there's room for more data.  If we have
476  *    more packets to send, we send them here.
477  *
478  */
479 static void irport_write_wakeup(struct irport_cb *self)
480 {
481         int actual = 0;
482         int iobase;
483         int fcr;
484 
485         ASSERT(self != NULL, return;);
486 
487         IRDA_DEBUG(4, __FUNCTION__ "()\n");
488 
489         iobase = self->io.sir_base;
490 
491         /* Finished with frame?  */
492         if (self->tx_buff.len > 0)  {
493                 /* Write data left in transmit buffer */
494                 actual = irport_write(iobase, self->io.fifo_size, 
495                                       self->tx_buff.data, self->tx_buff.len);
496                 self->tx_buff.data += actual;
497                 self->tx_buff.len  -= actual;
498         } else {
499                 /* 
500                  *  Now serial buffer is almost free & we can start 
501                  *  transmission of another packet. But first we must check
502                  *  if we need to change the speed of the hardware
503                  */
504                 if (self->new_speed) {
505                         IRDA_DEBUG(5, __FUNCTION__ "(), Changing speed!\n");
506                         irda_task_execute(self, __irport_change_speed, 
507                                           irport_change_speed_complete, 
508                                           NULL, (void *) self->new_speed);
509                         self->new_speed = 0;
510                 } else {
511                         /* Tell network layer that we want more frames */
512                         netif_wake_queue(self->netdev);
513                 }
514                 self->stats.tx_packets++;
515 
516                 /* 
517                  * Reset Rx FIFO to make sure that all reflected transmit data
518                  * is discarded. This is needed for half duplex operation
519                  */
520                 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR;
521                 if (self->io.speed < 38400)
522                         fcr |= UART_FCR_TRIGGER_1;
523                 else 
524                         fcr |= UART_FCR_TRIGGER_14;
525 
526                 outb(fcr, iobase+UART_FCR);
527 
528                 /* Turn on receive interrupts */
529                 outb(UART_IER_RDI, iobase+UART_IER);
530         }
531 }
532 
533 /*
534  * Function irport_write (driver)
535  *
536  *    Fill Tx FIFO with transmit data
537  *
538  */
539 static int irport_write(int iobase, int fifo_size, __u8 *buf, int len)
540 {
541         int actual = 0;
542 
543         /* Tx FIFO should be empty! */
544         if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
545                 IRDA_DEBUG(0, __FUNCTION__ "(), failed, fifo not empty!\n");
546                 return 0;
547         }
548         
549         /* Fill FIFO with current frame */
550         while ((fifo_size-- > 0) && (actual < len)) {
551                 /* Transmit next byte */
552                 outb(buf[actual], iobase+UART_TX);
553 
554                 actual++;
555         }
556         
557         return actual;
558 }
559 
560 /*
561  * Function irport_change_speed_complete (task)
562  *
563  *    Called when the change speed operation completes
564  *
565  */
566 static int irport_change_speed_complete(struct irda_task *task)
567 {
568         struct irport_cb *self;
569 
570         IRDA_DEBUG(0, __FUNCTION__ "()\n");
571 
572         self = (struct irport_cb *) task->instance;
573 
574         ASSERT(self != NULL, return -1;);
575         ASSERT(self->netdev != NULL, return -1;);
576 
577         /* Finished changing speed, so we are not busy any longer */
578         /* Signal network layer so it can try to send the frame */
579 
580         netif_wake_queue(self->netdev);
581         
582         return 0;
583 }
584 
585 /*
586  * Function irport_timeout (struct net_device *dev)
587  *
588  *    The networking layer thinks we timed out.
589  *
590  */
591 
592 static void irport_timeout(struct net_device *dev)
593 {
594         struct irport_cb *self;
595         int iobase;
596 
597         self = (struct irport_cb *) dev->priv;
598         iobase = self->io.sir_base;
599         
600         WARNING("%s: transmit timed out\n", dev->name);
601         irport_start(self);
602         self->change_speed(self->priv, self->io.speed);
603         dev->trans_start = jiffies;
604         netif_wake_queue(dev);
605 }
606  
607 /*
608  * Function irport_hard_start_xmit (struct sk_buff *skb, struct net_device *dev)
609  *
610  *    Transmits the current frame until FIFO is full, then
611  *    waits until the next transmitt interrupt, and continues until the
612  *    frame is transmitted.
613  */
614 int irport_hard_xmit(struct sk_buff *skb, struct net_device *dev)
615 {
616         struct irport_cb *self;
617         unsigned long flags;
618         int iobase;
619         s32 speed;
620 
621         IRDA_DEBUG(0, __FUNCTION__ "()\n");
622 
623         ASSERT(dev != NULL, return 0;);
624         
625         self = (struct irport_cb *) dev->priv;
626         ASSERT(self != NULL, return 0;);
627 
628         iobase = self->io.sir_base;
629 
630         netif_stop_queue(dev);
631         
632         /* Check if we need to change the speed */
633         speed = irda_get_next_speed(skb);
634         if ((speed != self->io.speed) && (speed != -1)) {
635                 /* Check for empty frame */
636                 if (!skb->len) {
637                         irda_task_execute(self, __irport_change_speed, 
638                                           irport_change_speed_complete, 
639                                           NULL, (void *) speed);
640                         dev_kfree_skb(skb);
641                         return 0;
642                 } else
643                         self->new_speed = speed;
644         }
645 
646         spin_lock_irqsave(&self->lock, flags);
647 
648         /* Init tx buffer */
649         self->tx_buff.data = self->tx_buff.head;
650 
651         /* Copy skb to tx_buff while wrapping, stuffing and making CRC */
652         self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, 
653                                            self->tx_buff.truesize);
654         
655         self->stats.tx_bytes += self->tx_buff.len;
656 
657         /* Turn on transmit finished interrupt. Will fire immediately!  */
658         outb(UART_IER_THRI, iobase+UART_IER); 
659 
660         spin_unlock_irqrestore(&self->lock, flags);
661 
662         dev_kfree_skb(skb);
663         
664         return 0;
665 }
666         
667 /*
668  * Function irport_receive (self)
669  *
670  *    Receive one frame from the infrared port
671  *
672  */
673 static void irport_receive(struct irport_cb *self) 
674 {
675         int boguscount = 0;
676         int iobase;
677 
678         ASSERT(self != NULL, return;);
679 
680         iobase = self->io.sir_base;
681 
682         /*  
683          * Receive all characters in Rx FIFO, unwrap and unstuff them. 
684          * async_unwrap_char will deliver all found frames  
685          */
686         do {
687                 async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, 
688                                   inb(iobase+UART_RX));
689 
690                 /* Make sure we don't stay here to long */
691                 if (boguscount++ > 32) {
692                         IRDA_DEBUG(2,__FUNCTION__ "(), breaking!\n");
693                         break;
694                 }
695         } while (inb(iobase+UART_LSR) & UART_LSR_DR);   
696 }
697 
698 /*
699  * Function irport_interrupt (irq, dev_id, regs)
700  *
701  *    Interrupt handler
702  */
703 void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs) 
704 {
705         struct net_device *dev = (struct net_device *) dev_id;
706         struct irport_cb *self;
707         int boguscount = 0;
708         int iobase;
709         int iir, lsr;
710 
711         if (!dev) {
712                 WARNING(__FUNCTION__ "() irq %d for unknown device.\n", irq);
713                 return;
714         }
715         self = (struct irport_cb *) dev->priv;
716 
717         spin_lock(&self->lock);
718 
719         iobase = self->io.sir_base;
720 
721         iir = inb(iobase+UART_IIR) & UART_IIR_ID;
722         while (iir) {
723                 /* Clear interrupt */
724                 lsr = inb(iobase+UART_LSR);
725 
726                 IRDA_DEBUG(4, __FUNCTION__ 
727                            "(), iir=%02x, lsr=%02x, iobase=%#x\n", 
728                            iir, lsr, iobase);
729 
730                 switch (iir) {
731                 case UART_IIR_RLSI:
732                         IRDA_DEBUG(2, __FUNCTION__ "(), RLSI\n");
733                         break;
734                 case UART_IIR_RDI:
735                         /* Receive interrupt */
736                         irport_receive(self);
737                         break;
738                 case UART_IIR_THRI:
739                         if (lsr & UART_LSR_THRE)
740                                 /* Transmitter ready for data */
741                                 irport_write_wakeup(self);
742                         break;
743                 default:
744                         IRDA_DEBUG(0, __FUNCTION__ "(), unhandled IIR=%#x\n", iir);
745                         break;
746                 } 
747                 
748                 /* Make sure we don't stay here to long */
749                 if (boguscount++ > 100)
750                         break;
751 
752                 iir = inb(iobase + UART_IIR) & UART_IIR_ID;
753         }
754         spin_unlock(&self->lock);
755 }
756 
757 static int irport_net_init(struct net_device *dev)
758 {
759         /* Set up to be a normal IrDA network device driver */
760         irda_device_setup(dev);
761 
762         /* Insert overrides below this line! */
763 
764         return 0;
765 }
766 
767 /*
768  * Function irport_net_open (dev)
769  *
770  *    Network device is taken up. Usually this is done by "ifconfig irda0 up" 
771  *   
772  */
773 int irport_net_open(struct net_device *dev)
774 {
775         struct irport_cb *self;
776         int iobase;
777 
778         IRDA_DEBUG(0, __FUNCTION__ "()\n");
779         
780         ASSERT(dev != NULL, return -1;);
781         self = (struct irport_cb *) dev->priv;
782 
783         iobase = self->io.sir_base;
784 
785         if (request_irq(self->io.irq, self->interrupt, 0, dev->name, 
786                         (void *) dev)) {
787                 IRDA_DEBUG(0, __FUNCTION__ "(), unable to allocate irq=%d\n",
788                            self->io.irq);
789                 return -EAGAIN;
790         }
791 
792         irport_start(self);
793 
794 
795         /* 
796          * Open new IrLAP layer instance, now that everything should be
797          * initialized properly 
798          */
799         self->irlap = irlap_open(dev, &self->qos);
800 
801         /* FIXME: change speed of dongle */
802         /* Ready to play! */
803 
804         netif_start_queue(dev);
805         
806         MOD_INC_USE_COUNT;
807 
808         return 0;
809 }
810 
811 /*
812  * Function irport_net_close (self)
813  *
814  *    Network device is taken down. Usually this is done by 
815  *    "ifconfig irda0 down" 
816  */
817 int irport_net_close(struct net_device *dev)
818 {
819         struct irport_cb *self;
820         int iobase;
821 
822         IRDA_DEBUG(4, __FUNCTION__ "()\n");
823 
824         ASSERT(dev != NULL, return -1;);
825         self = (struct irport_cb *) dev->priv;
826 
827         ASSERT(self != NULL, return -1;);
828 
829         iobase = self->io.sir_base;
830 
831         /* Stop device */
832         netif_stop_queue(dev);
833         
834         /* Stop and remove instance of IrLAP */
835         if (self->irlap)
836                 irlap_close(self->irlap);
837         self->irlap = NULL;
838 
839         irport_stop(self);
840 
841         free_irq(self->io.irq, dev);
842 
843         MOD_DEC_USE_COUNT;
844 
845         return 0;
846 }
847 
848 /*
849  * Function irport_wait_until_sent (self)
850  *
851  *    Delay exectution until finished transmitting
852  *
853  */
854 #if 0
855 void irport_wait_until_sent(struct irport_cb *self)
856 {
857         int iobase;
858 
859         iobase = self->io.sir_base;
860 
861         /* Wait until Tx FIFO is empty */
862         while (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
863                 IRDA_DEBUG(2, __FUNCTION__ "(), waiting!\n");
864                 current->state = TASK_INTERRUPTIBLE;
865                 schedule_timeout(MSECS_TO_JIFFIES(60));
866         }
867 }
868 #endif
869 
870 /*
871  * Function irport_is_receiving (self)
872  *
873  *    Returns true is we are currently receiving data
874  *
875  */
876 static int irport_is_receiving(struct irport_cb *self)
877 {
878         return (self->rx_buff.state != OUTSIDE_FRAME);
879 }
880 
881 /*
882  * Function irport_set_dtr_rts (tty, dtr, rts)
883  *
884  *    This function can be used by dongles etc. to set or reset the status
885  *    of the dtr and rts lines
886  */
887 static int irport_set_dtr_rts(struct net_device *dev, int dtr, int rts)
888 {
889         struct irport_cb *self = dev->priv;
890         int iobase;
891 
892         ASSERT(self != NULL, return -1;);
893 
894         iobase = self->io.sir_base;
895 
896         if (dtr)
897                 dtr = UART_MCR_DTR;
898         if (rts)
899                 rts = UART_MCR_RTS;
900 
901         outb(dtr|rts|UART_MCR_OUT2, iobase+UART_MCR);
902 
903         return 0;
904 }
905 
906 static int irport_raw_write(struct net_device *dev, __u8 *buf, int len)
907 {
908         struct irport_cb *self = (struct irport_cb *) dev->priv;
909         int actual = 0;
910         int iobase;
911 
912         ASSERT(self != NULL, return -1;);
913 
914         iobase = self->io.sir_base;
915 
916         /* Tx FIFO should be empty! */
917         if (!(inb(iobase+UART_LSR) & UART_LSR_THRE)) {
918                 IRDA_DEBUG( 0, __FUNCTION__ "(), failed, fifo not empty!\n");
919                 return -1;
920         }
921         
922         /* Fill FIFO with current frame */
923         while (actual < len) {
924                 /* Transmit next byte */
925                 outb(buf[actual], iobase+UART_TX);
926                 actual++;
927         }
928 
929         return actual;
930 }
931 
932 /*
933  * Function irport_net_ioctl (dev, rq, cmd)
934  *
935  *    Process IOCTL commands for this device
936  *
937  */
938 static int irport_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
939 {
940         struct if_irda_req *irq = (struct if_irda_req *) rq;
941         struct irport_cb *self;
942         dongle_t *dongle;
943         unsigned long flags;
944         int ret = 0;
945 
946         ASSERT(dev != NULL, return -1;);
947 
948         self = dev->priv;
949 
950         ASSERT(self != NULL, return -1;);
951 
952         IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
953         
954         /* Disable interrupts & save flags */
955         save_flags(flags);
956         cli();
957         
958         switch (cmd) {
959         case SIOCSBANDWIDTH: /* Set bandwidth */
960                 if (!capable(CAP_NET_ADMIN))
961                         ret = -EPERM;
962                 else
963                         irda_task_execute(self, __irport_change_speed, NULL, 
964                                           NULL, (void *) irq->ifr_baudrate);
965                 break;
966         case SIOCSDONGLE: /* Set dongle */
967                 if (!capable(CAP_NET_ADMIN)) {
968                         ret = -EPERM;
969                         break;
970                 }
971 
972                 /* Initialize dongle */
973                 dongle = irda_device_dongle_init(dev, irq->ifr_dongle);
974                 if (!dongle)
975                         break;
976                 
977                 dongle->set_mode    = NULL;
978                 dongle->read        = NULL;
979                 dongle->write       = irport_raw_write;
980                 dongle->set_dtr_rts = irport_set_dtr_rts;
981                 
982                 self->dongle = dongle;
983 
984                 /* Now initialize the dongle!  */
985                 dongle->issue->open(dongle, &self->qos);
986                 
987                 /* Reset dongle */
988                 irda_task_execute(dongle, dongle->issue->reset, NULL, NULL, 
989                                   NULL);        
990                 break;
991         case SIOCSMEDIABUSY: /* Set media busy */
992                 if (!capable(CAP_NET_ADMIN)) {
993                         ret = -EPERM;
994                         break;
995                 }
996 
997                 irda_device_set_media_busy(self->netdev, TRUE);
998                 break;
999         case SIOCGRECEIVING: /* Check if we are receiving right now */
1000                 irq->ifr_receiving = irport_is_receiving(self);
1001                 break;
1002         case SIOCSDTRRTS:
1003                 if (!capable(CAP_NET_ADMIN)) {
1004                         ret = -EPERM;
1005                         break;
1006                 }
1007 
1008                 irport_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts);
1009                 break;
1010         default:
1011                 ret = -EOPNOTSUPP;
1012         }
1013         
1014         restore_flags(flags);
1015         
1016         return ret;
1017 }
1018 
1019 static struct net_device_stats *irport_net_get_stats(struct net_device *dev)
1020 {
1021         struct irport_cb *self = (struct irport_cb *) dev->priv;
1022         
1023         return &self->stats;
1024 }
1025 
1026 #ifdef MODULE
1027 MODULE_PARM(io, "1-4i");
1028 MODULE_PARM_DESC(io, "Base I/O addresses");
1029 MODULE_PARM(irq, "1-4i");
1030 MODULE_PARM_DESC(irq, "IRQ lines");
1031 
1032 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
1033 MODULE_DESCRIPTION("Half duplex serial driver for IrDA SIR mode");
1034 
1035 void cleanup_module(void)
1036 {
1037         irport_cleanup();
1038 }
1039 
1040 int init_module(void)
1041 {
1042         return irport_init();
1043 }
1044 #endif /* MODULE */
1045 
1046 

~ [ 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.