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

Linux Cross Reference
Linux/net/irda/irda_device.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

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