OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [irda/] [irport.c] - Blame information for rev 62

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.