import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / net / irda / irda_device.c
1 /*********************************************************************
2  *                
3  * Filename:      irda_device.c
4  * Version:       0.9
5  * Description:   Utility functions used by the device drivers
6  * Status:        Experimental.
7  * Author:        Dag Brattli <dagb@cs.uit.no>
8  * Created at:    Sat Oct  9 09:22:27 1999
9  * Modified at:   Sun Jan 23 17:41:24 2000
10  * Modified by:   Dag Brattli <dagb@cs.uit.no>
11  * 
12  *     Copyright (c) 1999-2000 Dag Brattli, All Rights Reserved.
13  *     Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
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  ********************************************************************/
31
32 #include <linux/config.h>
33 #include <linux/string.h>
34 #include <linux/proc_fs.h>
35 #include <linux/skbuff.h>
36 #include <linux/if.h>
37 #include <linux/if_ether.h>
38 #include <linux/if_arp.h>
39 #include <linux/netdevice.h>
40 #include <linux/init.h>
41 #include <linux/tty.h>
42 #include <linux/kmod.h>
43 #include <linux/wireless.h>
44 #include <linux/spinlock.h>
45
46 #include <asm/ioctls.h>
47 #include <asm/segment.h>
48 #include <asm/uaccess.h>
49 #include <asm/dma.h>
50 #include <asm/io.h>
51
52 #include <net/pkt_sched.h>
53
54 #include <net/irda/irda_device.h>
55 #include <net/irda/irlap.h>
56 #include <net/irda/timer.h>
57 #include <net/irda/wrapper.h>
58
59 extern int irtty_init(void);
60 extern int nsc_ircc_init(void);
61 extern int ircc_init(void);
62 extern int toshoboe_init(void);
63 extern int litelink_init(void);
64 extern int w83977af_init(void);
65 extern int esi_init(void);
66 extern int tekram_init(void);
67 extern int actisys_init(void);
68 extern int girbil_init(void);
69 extern int sa1100_irda_init(void);
70 extern int ep7211_ir_init(void);
71
72 static void __irda_task_delete(struct irda_task *task);
73
74 static hashbin_t *dongles = NULL;
75 static hashbin_t *tasks = NULL;
76
77 const char *infrared_mode[] = {
78         "IRDA_IRLAP",
79         "IRDA_RAW",
80         "SHARP_ASK",
81         "TV_REMOTE",
82 };
83
84 #ifdef CONFIG_IRDA_DEBUG
85 static const char *task_state[] = {
86         "IRDA_TASK_INIT",
87         "IRDA_TASK_DONE", 
88         "IRDA_TASK_WAIT",
89         "IRDA_TASK_WAIT1",
90         "IRDA_TASK_WAIT2",
91         "IRDA_TASK_WAIT3",
92         "IRDA_TASK_CHILD_INIT",
93         "IRDA_TASK_CHILD_WAIT",
94         "IRDA_TASK_CHILD_DONE",
95 };
96 #endif  /* CONFIG_IRDA_DEBUG */
97
98 static void irda_task_timer_expired(void *data);
99
100 #ifdef CONFIG_PROC_FS
101 int irda_device_proc_read(char *buf, char **start, off_t offset, int len, 
102                           int unused);
103
104 #endif /* CONFIG_PROC_FS */
105
106 int __init irda_device_init( void)
107 {
108         dongles = hashbin_new(HB_GLOBAL);
109         if (dongles == NULL) {
110                 printk(KERN_WARNING 
111                        "IrDA: Can't allocate dongles hashbin!\n");
112                 return -ENOMEM;
113         }
114
115         tasks = hashbin_new(HB_GLOBAL);
116         if (tasks == NULL) {
117                 printk(KERN_WARNING 
118                        "IrDA: Can't allocate tasks hashbin!\n");
119                 return -ENOMEM;
120         }
121
122         /* 
123          * Call the init function of the device drivers that has not been
124          * compiled as a module 
125          */
126 #ifdef CONFIG_IRTTY_SIR
127         irtty_init();
128 #endif
129 #ifdef CONFIG_WINBOND_FIR
130         w83977af_init();
131 #endif
132 #ifdef CONFIG_SA1100_FIR
133         sa1100_irda_init();
134 #endif
135 #ifdef CONFIG_NSC_FIR
136         nsc_ircc_init();
137 #endif
138 #ifdef CONFIG_TOSHIBA_FIR
139         toshoboe_init();
140 #endif
141 #ifdef CONFIG_SMC_IRCC_FIR
142         ircc_init();
143 #endif
144 #ifdef CONFIG_ESI_DONGLE
145         esi_init();
146 #endif
147 #ifdef CONFIG_TEKRAM_DONGLE
148         tekram_init();
149 #endif
150 #ifdef CONFIG_ACTISYS_DONGLE
151         actisys_init();
152 #endif
153 #ifdef CONFIG_GIRBIL_DONGLE
154         girbil_init();
155 #endif
156 #ifdef CONFIG_LITELINK_DONGLE
157         litelink_init();
158 #endif
159 #ifdef CONFIG_OLD_BELKIN
160         old_belkin_init();
161 #endif
162 #ifdef CONFIG_EP7211_IR
163         ep7211_ir_init();
164 #endif
165         return 0;
166 }
167
168 void irda_device_cleanup(void)
169 {
170         IRDA_DEBUG(4, __FUNCTION__ "()\n");
171
172         hashbin_delete(tasks, (FREE_FUNC) __irda_task_delete);
173         hashbin_delete(dongles, NULL);
174 }
175
176 /*
177  * Function irda_device_set_media_busy (self, status)
178  *
179  *    Called when we have detected that another station is transmiting
180  *    in contention mode.
181  */
182 void irda_device_set_media_busy(struct net_device *dev, int status) 
183 {
184         struct irlap_cb *self;
185
186         IRDA_DEBUG(4, __FUNCTION__ "(%s)\n", status ? "TRUE" : "FALSE");
187
188         self = (struct irlap_cb *) dev->atalk_ptr;
189
190         ASSERT(self != NULL, return;);
191         ASSERT(self->magic == LAP_MAGIC, return;);
192
193         if (status) {
194                 self->media_busy = TRUE;
195                 if (status == SMALL)
196                         irlap_start_mbusy_timer(self, SMALLBUSY_TIMEOUT);
197                 else
198                         irlap_start_mbusy_timer(self, MEDIABUSY_TIMEOUT);
199                 IRDA_DEBUG( 4, "Media busy!\n");
200         } else {
201                 self->media_busy = FALSE;
202                 irlap_stop_mbusy_timer(self);
203         }
204 }
205
206 int irda_device_set_dtr_rts(struct net_device *dev, int dtr, int rts)
207 {       
208         struct if_irda_req req;
209         int ret;
210
211         IRDA_DEBUG(2, __FUNCTION__ "()\n");
212
213         if (!dev->do_ioctl) {
214                 ERROR(__FUNCTION__ "(), do_ioctl not impl. by "
215                       "device driver\n");
216                 return -1;
217         }
218
219         req.ifr_dtr = dtr;
220         req.ifr_rts = rts;
221
222         ret = dev->do_ioctl(dev, (struct ifreq *) &req, SIOCSDTRRTS);
223
224         return ret;
225 }
226
227 int irda_device_change_speed(struct net_device *dev, __u32 speed)
228 {       
229         struct if_irda_req req;
230         int ret;
231
232         IRDA_DEBUG(2, __FUNCTION__ "()\n");
233
234         if (!dev->do_ioctl) {
235                 ERROR(__FUNCTION__ "(), do_ioctl not impl. by "
236                       "device driver\n");
237                 return -1;
238         }
239
240         req.ifr_baudrate = speed;
241
242         ret = dev->do_ioctl(dev, (struct ifreq *) &req, SIOCSBANDWIDTH);
243
244         return ret;
245 }
246
247 /*
248  * Function irda_device_is_receiving (dev)
249  *
250  *    Check if the device driver is currently receiving data
251  *
252  */
253 int irda_device_is_receiving(struct net_device *dev)
254 {
255         struct if_irda_req req;
256         int ret;
257
258         IRDA_DEBUG(2, __FUNCTION__ "()\n");
259
260         if (!dev->do_ioctl) {
261                 ERROR(__FUNCTION__ "(), do_ioctl not impl. by "
262                       "device driver\n");
263                 return -1;
264         }
265
266         ret = dev->do_ioctl(dev, (struct ifreq *) &req, SIOCGRECEIVING);
267         if (ret < 0)
268                 return ret;
269
270         return req.ifr_receiving;
271 }
272
273 void irda_task_next_state(struct irda_task *task, IRDA_TASK_STATE state)
274 {
275         IRDA_DEBUG(2, __FUNCTION__ "(), state = %s\n", task_state[state]);
276
277         task->state = state;
278 }
279
280 static void __irda_task_delete(struct irda_task *task)
281 {
282         del_timer(&task->timer);
283         
284         kfree(task);
285 }
286
287 void irda_task_delete(struct irda_task *task)
288 {
289         /* Unregister task */
290         hashbin_remove(tasks, (int) task, NULL);
291
292         __irda_task_delete(task);
293 }
294
295 /*
296  * Function irda_task_kick (task)
297  *
298  *    Tries to execute a task possible multiple times until the task is either
299  *    finished, or askes for a timeout. When a task is finished, we do post
300  *    processing, and notify the parent task, that is waiting for this task
301  *    to complete.
302  */
303 int irda_task_kick(struct irda_task *task)
304 {
305         int finished = TRUE;
306         int count = 0;
307         int timeout;
308
309         IRDA_DEBUG(2, __FUNCTION__ "()\n");
310
311         ASSERT(task != NULL, return -1;);
312         ASSERT(task->magic == IRDA_TASK_MAGIC, return -1;);
313
314         /* Execute task until it's finished, or askes for a timeout */
315         do {
316                 timeout = task->function(task);
317                 if (count++ > 100) {
318                         ERROR(__FUNCTION__ "(), error in task handler!\n");
319                         irda_task_delete(task);
320                         return TRUE;
321                 }                       
322         } while ((timeout == 0) && (task->state != IRDA_TASK_DONE));
323
324         if (timeout < 0) {
325                 ERROR(__FUNCTION__ "(), Error executing task!\n");
326                 irda_task_delete(task);
327                 return TRUE;
328         }
329
330         /* Check if we are finished */
331         if (task->state == IRDA_TASK_DONE) {
332                 del_timer(&task->timer);
333
334                 /* Do post processing */
335                 if (task->finished)
336                         task->finished(task);
337
338                 /* Notify parent */
339                 if (task->parent) {
340                         /* Check if parent is waiting for us to complete */
341                         if (task->parent->state == IRDA_TASK_CHILD_WAIT) {
342                                 task->parent->state = IRDA_TASK_CHILD_DONE;
343
344                                 /* Stop timer now that we are here */
345                                 del_timer(&task->parent->timer);
346
347                                 /* Kick parent task */
348                                 irda_task_kick(task->parent);
349                         }
350                 }               
351                 irda_task_delete(task);
352         } else if (timeout > 0) {
353                 irda_start_timer(&task->timer, timeout, (void *) task, 
354                                  irda_task_timer_expired);
355                 finished = FALSE;
356         } else {
357                 IRDA_DEBUG(0, __FUNCTION__ 
358                            "(), not finished, and no timeout!\n");
359                 finished = FALSE;
360         }
361
362         return finished;
363 }
364
365 /*
366  * Function irda_task_execute (instance, function, finished)
367  *
368  *    This function registers and tries to execute tasks that may take some
369  *    time to complete. We do it this hairy way since we may have been
370  *    called from interrupt context, so it's not possible to use
371  *    schedule_timeout() 
372  * Two important notes :
373  *      o Make sure you irda_task_delete(task); in case you delete the
374  *        calling instance.
375  *      o No real need to lock when calling this function, but you may
376  *        want to lock within the task handler.
377  * Jean II
378  */
379 struct irda_task *irda_task_execute(void *instance, 
380                                     IRDA_TASK_CALLBACK function, 
381                                     IRDA_TASK_CALLBACK finished, 
382                                     struct irda_task *parent, void *param)
383 {
384         struct irda_task *task;
385         int ret;
386
387         IRDA_DEBUG(2, __FUNCTION__ "()\n");
388
389         task = kmalloc(sizeof(struct irda_task), GFP_ATOMIC);
390         if (!task)
391                 return NULL;
392
393         task->state    = IRDA_TASK_INIT;
394         task->instance = instance;
395         task->function = function;
396         task->finished = finished;
397         task->parent   = parent;
398         task->param    = param; 
399         task->magic    = IRDA_TASK_MAGIC;
400
401         init_timer(&task->timer);
402
403         /* Register task */
404         hashbin_insert(tasks, (irda_queue_t *) task, (int) task, NULL);
405
406         /* No time to waste, so lets get going! */
407         ret = irda_task_kick(task);
408         if (ret)
409                 return NULL;
410         else
411                 return task;
412 }
413
414 /*
415  * Function irda_task_timer_expired (data)
416  *
417  *    Task time has expired. We now try to execute task (again), and restart
418  *    the timer if the task has not finished yet
419  */
420 static void irda_task_timer_expired(void *data)
421 {
422         struct irda_task *task;
423
424         IRDA_DEBUG(2, __FUNCTION__ "()\n");
425
426         task = (struct irda_task *) data;
427
428         irda_task_kick(task);
429 }
430
431 /*
432  * Function irda_device_setup (dev)
433  *
434  *    This function should be used by low level device drivers in a similar way
435  *    as ether_setup() is used by normal network device drivers
436  */
437 int irda_device_setup(struct net_device *dev) 
438 {
439         ASSERT(dev != NULL, return -1;);
440
441         dev->hard_header_len = 0;
442         dev->addr_len        = 0;
443
444         dev->features        |= NETIF_F_DYNALLOC;
445         /* dev->destructor      = irda_device_destructor; */
446
447         dev->type            = ARPHRD_IRDA;
448         dev->tx_queue_len    = 8; /* Window size + 1 s-frame */
449  
450         memset(dev->broadcast, 0xff, 4);
451
452         dev->mtu = 2048;
453         dev->flags = IFF_NOARP;
454         return 0;
455 }
456
457 /*
458  * Function irda_device_txqueue_empty (dev)
459  *
460  *    Check if there is still some frames in the transmit queue for this
461  *    device. Maybe we should use: q->q.qlen == 0.
462  *
463  */
464 int irda_device_txqueue_empty(struct net_device *dev)
465 {
466         if (skb_queue_len(&dev->qdisc->q))
467                 return FALSE;
468
469         return TRUE;
470 }
471
472 /*
473  * Function irda_device_init_dongle (self, type, qos)
474  *
475  *    Initialize attached dongle.
476  *
477  * Important : request_module require us to call this function with
478  * a process context and irq enabled. - Jean II
479  */
480 dongle_t *irda_device_dongle_init(struct net_device *dev, int type)
481 {
482         struct dongle_reg *reg;
483         dongle_t *dongle;
484
485         ASSERT(dev != NULL, return NULL;);
486
487 #ifdef CONFIG_KMOD
488         {
489         char modname[32];
490         ASSERT(!in_interrupt(), return NULL;);
491         /* Try to load the module needed */
492         sprintf(modname, "irda-dongle-%d", type);
493         request_module(modname);
494         }
495 #endif /* CONFIG_KMOD */
496
497         if (!(reg = hashbin_find(dongles, type, NULL))) {
498                 ERROR("IrDA: Unable to find requested dongle\n");
499                 return NULL;
500         }
501
502         /* Allocate dongle info for this instance */
503         dongle = kmalloc(sizeof(dongle_t), GFP_KERNEL);
504         if (!dongle)
505                 return NULL;
506
507         memset(dongle, 0, sizeof(dongle_t));
508
509         /* Bind the registration info to this particular instance */
510         dongle->issue = reg;
511         dongle->dev = dev;
512
513         return dongle;
514 }
515
516 /*
517  * Function irda_device_dongle_cleanup (dongle)
518  *
519  *    
520  *
521  */
522 int irda_device_dongle_cleanup(dongle_t *dongle)
523 {
524         ASSERT(dongle != NULL, return -1;);
525
526         dongle->issue->close(dongle);
527
528         kfree(dongle);
529
530         return 0;
531 }
532
533 /*
534  * Function irda_device_register_dongle (dongle)
535  *
536  *    
537  *
538  */
539 int irda_device_register_dongle(struct dongle_reg *new)
540 {
541         /* Check if this dongle has been registred before */
542         if (hashbin_find(dongles, new->type, NULL)) {
543                 MESSAGE(__FUNCTION__ "(), Dongle already registered\n");
544                 return 0;
545         }
546         
547         /* Insert IrDA dongle into hashbin */
548         hashbin_insert(dongles, (irda_queue_t *) new, new->type, NULL);
549         
550         return 0;
551 }
552
553 /*
554  * Function irda_device_unregister_dongle (dongle)
555  *
556  *    Unregister dongle, and remove dongle from list of registred dongles
557  *
558  */
559 void irda_device_unregister_dongle(struct dongle_reg *dongle)
560 {
561         struct dongle *node;
562
563         node = hashbin_remove(dongles, dongle->type, NULL);
564         if (!node) {
565                 ERROR(__FUNCTION__ "(), dongle not found!\n");
566                 return;
567         }
568 }
569
570 /*
571  * Function irda_device_set_mode (self, mode)
572  *
573  *    Set the Infrared device driver into mode where it sends and receives
574  *    data without using IrLAP framing. Check out the particular device
575  *    driver to find out which modes it support.
576  */
577 int irda_device_set_mode(struct net_device* dev, int mode)
578 {       
579         struct if_irda_req req;
580         int ret;
581
582         IRDA_DEBUG(0, __FUNCTION__ "()\n");
583
584         if (!dev->do_ioctl) {
585                 ERROR(__FUNCTION__ "(), set_raw_mode not impl. by "
586                       "device driver\n");
587                 return -1;
588         }
589         
590         req.ifr_mode = mode;
591
592         ret = dev->do_ioctl(dev, (struct ifreq *) &req, SIOCSMODE);
593         
594         return ret;
595 }
596
597 /*
598  * Function setup_dma (idev, buffer, count, mode)
599  *
600  *    Setup the DMA channel. Commonly used by ISA FIR drivers
601  *
602  */
603 void setup_dma(int channel, char *buffer, int count, int mode)
604 {
605         unsigned long flags;
606         
607         flags = claim_dma_lock();
608         
609         disable_dma(channel);
610         clear_dma_ff(channel);
611         set_dma_mode(channel, mode);
612         set_dma_addr(channel, virt_to_bus(buffer));
613         set_dma_count(channel, count);
614         enable_dma(channel);
615
616         release_dma_lock(flags);
617 }