Import 2.3.25pre1
[davej-history.git] / net / irda / irmod.c
blob7a2fa169a5bb5d2e282b91cf3bf78262de8af5f0
1 /*********************************************************************
2 *
3 * Filename: irmod.c
4 * Version: 0.8
5 * Description: IrDA module code and some other stuff
6 * Status: Experimental.
7 * Author: Dag Brattli <dagb@cs.uit.no>
8 * Created at: Mon Dec 15 13:55:39 1997
9 * Modified at: Mon Oct 18 14:54:35 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
12 * Copyright (c) 1997, 1999 Dag Brattli, All Rights Reserved.
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.
19 * Neither Dag Brattli nor University of Tromsø admit liability nor
20 * provide warranty for any of this software. This material is
21 * provided "AS-IS" and at no charge.
23 ********************************************************************/
25 #include <linux/config.h>
26 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/poll.h>
30 #include <linux/proc_fs.h>
32 #include <asm/segment.h>
34 #include <net/irda/irda.h>
35 #include <net/irda/irmod.h>
36 #include <net/irda/irlap.h>
37 #ifdef CONFIG_IRDA_COMPRESSION
38 #include <net/irda/irlap_comp.h>
39 #endif /* CONFIG_IRDA_COMPRESSION */
40 #include <net/irda/irlmp.h>
41 #include <net/irda/iriap.h>
42 #include <net/irda/irias_object.h>
43 #include <net/irda/irttp.h>
44 #include <net/irda/irda_device.h>
45 #include <net/irda/wrapper.h>
46 #include <net/irda/timer.h>
47 #include <net/irda/parameters.h>
49 extern struct proc_dir_entry *proc_irda;
51 struct irda_cb irda; /* One global instance */
53 #ifdef CONFIG_IRDA_DEBUG
54 __u32 irda_debug = IRDA_DEBUG_LEVEL;
55 #endif
57 extern void irda_proc_register(void);
58 extern void irda_proc_unregister(void);
59 extern int irda_sysctl_register(void);
60 extern void irda_sysctl_unregister(void);
62 extern void irda_proto_init(struct net_proto *pro);
63 extern void irda_proto_cleanup(void);
65 extern int irda_device_init(void);
66 extern int irlan_init(void);
67 extern int irlan_client_init(void);
68 extern int irlan_server_init(void);
69 extern int ircomm_init(void);
70 extern int ircomm_tty_init(void);
71 extern int irlpt_client_init(void);
72 extern int irlpt_server_init(void);
74 #ifdef CONFIG_IRDA_COMPRESSION
75 #ifdef CONFIG_IRDA_DEFLATE
76 extern irda_deflate_init();
77 #endif /* CONFIG_IRDA_DEFLATE */
78 #endif /* CONFIG_IRDA_COMPRESSION */
80 static int irda_open(struct inode * inode, struct file *file);
81 static int irda_ioctl(struct inode *inode, struct file *filp,
82 unsigned int cmd, unsigned long arg);
83 static int irda_close(struct inode *inode, struct file *file);
84 static ssize_t irda_read(struct file *file, char *buffer, size_t count,
85 loff_t *noidea);
86 static ssize_t irda_write(struct file *file, const char *buffer,
87 size_t count, loff_t *noidea);
88 static u_int irda_poll(struct file *file, poll_table *wait);
90 static struct file_operations irda_fops = {
91 NULL, /* seek */
92 irda_read, /* read */
93 irda_write, /* write */
94 NULL, /* readdir */
95 irda_poll, /* poll */
96 irda_ioctl, /* ioctl */
97 NULL, /* mmap */
98 irda_open,
99 NULL,
100 irda_close,
101 NULL,
102 NULL, /* fasync */
105 /* IrTTP */
106 EXPORT_SYMBOL(irttp_open_tsap);
107 EXPORT_SYMBOL(irttp_close_tsap);
108 EXPORT_SYMBOL(irttp_connect_response);
109 EXPORT_SYMBOL(irttp_data_request);
110 EXPORT_SYMBOL(irttp_disconnect_request);
111 EXPORT_SYMBOL(irttp_flow_request);
112 EXPORT_SYMBOL(irttp_connect_request);
113 EXPORT_SYMBOL(irttp_udata_request);
114 EXPORT_SYMBOL(irttp_dup);
116 /* Main IrDA module */
117 #ifdef CONFIG_IRDA_DEBUG
118 EXPORT_SYMBOL(irda_debug);
119 #endif
120 EXPORT_SYMBOL(irda_notify_init);
121 EXPORT_SYMBOL(irmanager_notify);
122 EXPORT_SYMBOL(irda_lock);
123 #ifdef CONFIG_PROC_FS
124 EXPORT_SYMBOL(proc_irda);
125 #endif
126 EXPORT_SYMBOL(irda_param_insert);
127 EXPORT_SYMBOL(irda_param_extract);
128 EXPORT_SYMBOL(irda_param_extract_all);
129 EXPORT_SYMBOL(irda_param_pack);
130 EXPORT_SYMBOL(irda_param_unpack);
132 /* IrIAP/IrIAS */
133 EXPORT_SYMBOL(iriap_getvaluebyclass_request);
134 EXPORT_SYMBOL(irias_object_change_attribute);
135 EXPORT_SYMBOL(irias_add_integer_attrib);
136 EXPORT_SYMBOL(irias_add_octseq_attrib);
137 EXPORT_SYMBOL(irias_add_string_attrib);
138 EXPORT_SYMBOL(irias_insert_object);
139 EXPORT_SYMBOL(irias_new_object);
140 EXPORT_SYMBOL(irias_delete_object);
141 EXPORT_SYMBOL(irias_find_object);
142 EXPORT_SYMBOL(irias_find_attrib);
143 EXPORT_SYMBOL(irias_new_integer_value);
144 EXPORT_SYMBOL(irias_new_string_value);
145 EXPORT_SYMBOL(irias_new_octseq_value);
147 /* IrLMP */
148 EXPORT_SYMBOL(irlmp_discovery_request);
149 EXPORT_SYMBOL(irlmp_register_client);
150 EXPORT_SYMBOL(irlmp_unregister_client);
151 EXPORT_SYMBOL(irlmp_update_client);
152 EXPORT_SYMBOL(irlmp_register_service);
153 EXPORT_SYMBOL(irlmp_unregister_service);
154 EXPORT_SYMBOL(irlmp_service_to_hint);
155 EXPORT_SYMBOL(irlmp_data_request);
156 EXPORT_SYMBOL(irlmp_open_lsap);
157 EXPORT_SYMBOL(irlmp_close_lsap);
158 EXPORT_SYMBOL(irlmp_connect_request);
159 EXPORT_SYMBOL(irlmp_connect_response);
160 EXPORT_SYMBOL(irlmp_disconnect_request);
161 EXPORT_SYMBOL(irlmp_get_daddr);
162 EXPORT_SYMBOL(irlmp_get_saddr);
163 EXPORT_SYMBOL(irlmp_dup);
164 EXPORT_SYMBOL(lmp_reasons);
166 /* Queue */
167 EXPORT_SYMBOL(hashbin_find);
168 EXPORT_SYMBOL(hashbin_new);
169 EXPORT_SYMBOL(hashbin_insert);
170 EXPORT_SYMBOL(hashbin_delete);
171 EXPORT_SYMBOL(hashbin_remove);
172 EXPORT_SYMBOL(hashbin_get_next);
173 EXPORT_SYMBOL(hashbin_get_first);
175 /* IrLAP */
176 EXPORT_SYMBOL(irlap_open);
177 EXPORT_SYMBOL(irlap_close);
178 #ifdef CONFIG_IRDA_COMPRESSION
179 EXPORT_SYMBOL(irda_unregister_compressor);
180 EXPORT_SYMBOL(irda_register_compressor);
181 #endif /* CONFIG_IRDA_COMPRESSION */
182 EXPORT_SYMBOL(irda_init_max_qos_capabilies);
183 EXPORT_SYMBOL(irda_qos_bits_to_value);
184 EXPORT_SYMBOL(irda_device_setup);
185 EXPORT_SYMBOL(irda_device_set_media_busy);
186 EXPORT_SYMBOL(irda_device_txqueue_empty);
188 EXPORT_SYMBOL(irda_device_dongle_init);
189 EXPORT_SYMBOL(irda_device_dongle_cleanup);
190 EXPORT_SYMBOL(irda_device_register_dongle);
191 EXPORT_SYMBOL(irda_device_unregister_dongle);
192 EXPORT_SYMBOL(irda_task_execute);
193 EXPORT_SYMBOL(irda_task_kick);
194 EXPORT_SYMBOL(irda_task_next_state);
196 EXPORT_SYMBOL(async_wrap_skb);
197 EXPORT_SYMBOL(async_unwrap_char);
198 EXPORT_SYMBOL(irda_start_timer);
199 EXPORT_SYMBOL(setup_dma);
200 EXPORT_SYMBOL(infrared_mode);
202 #ifdef CONFIG_IRTTY
203 EXPORT_SYMBOL(irtty_set_dtr_rts);
204 EXPORT_SYMBOL(irtty_register_dongle);
205 EXPORT_SYMBOL(irtty_unregister_dongle);
206 EXPORT_SYMBOL(irtty_set_packet_mode);
207 #endif
209 int __init irda_init(void)
211 MESSAGE("IrDA (tm) Protocols for Linux-2.3 (Dag Brattli)\n");
213 irlmp_init();
214 irlap_init();
216 #ifdef MODULE
217 irda_device_init(); /* Called by init/main.c when non-modular */
218 #endif
220 iriap_init();
221 irttp_init();
223 #ifdef CONFIG_PROC_FS
224 irda_proc_register();
225 #endif
226 #ifdef CONFIG_SYSCTL
227 irda_sysctl_register();
228 #endif
229 init_waitqueue_head(&irda.wait_queue);
230 irda.dev.minor = MISC_DYNAMIC_MINOR;
231 irda.dev.name = "irda";
232 irda.dev.fops = &irda_fops;
234 misc_register(&irda.dev);
236 irda.in_use = FALSE;
238 init_waitqueue_head(&irda.wait_queue);
241 * Initialize modules that got compiled into the kernel
243 #ifdef CONFIG_IRLAN
244 irlan_init();
245 #endif
246 #ifdef CONFIG_IRCOMM
247 ircomm_init();
248 ircomm_tty_init();
249 #endif
251 #ifdef CONFIG_IRDA_COMPRESSION
252 #ifdef CONFIG_IRDA_DEFLATE
253 irda_deflate_init();
254 #endif /* CONFIG_IRDA_DEFLATE */
255 #endif /* CONFIG_IRDA_COMPRESSION */
257 return 0;
260 #ifdef MODULE
261 void irda_cleanup(void)
263 misc_deregister(&irda.dev);
265 #ifdef CONFIG_SYSCTL
266 irda_sysctl_unregister();
267 #endif
269 #ifdef CONFIG_PROC_FS
270 irda_proc_unregister();
271 #endif
272 /* Remove higher layers */
273 irttp_cleanup();
274 iriap_cleanup();
276 /* Remove lower layers */
277 irda_device_cleanup();
278 irlap_cleanup(); /* Must be done before irlmp_cleanup()! DB */
280 /* Remove middle layer */
281 irlmp_cleanup();
283 #endif /* MODULE */
286 * Function irda_unlock (lock)
288 * Unlock variable. Returns false if lock is already unlocked
291 inline int irda_unlock(int *lock)
293 if (!test_and_clear_bit(0, (void *) lock)) {
294 printk("Trying to unlock already unlocked variable!\n");
295 return FALSE;
297 return TRUE;
301 * Function irda_notify_init (notify)
303 * Used for initializing the notify structure
306 void irda_notify_init(notify_t *notify)
308 notify->data_indication = NULL;
309 notify->udata_indication = NULL;
310 notify->connect_confirm = NULL;
311 notify->connect_indication = NULL;
312 notify->disconnect_indication = NULL;
313 notify->flow_indication = NULL;
314 notify->instance = NULL;
315 strncpy(notify->name, "Unknown", NOTIFY_MAX_NAME);
319 * Function irda_execute_as_process (self, callback, param)
321 * If a layer needs to have a function executed with a process context,
322 * then it can register the function here, and the function will then
323 * be executed as fast as possible.
326 void irda_execute_as_process( void *self, TODO_CALLBACK callback, __u32 param)
328 struct irda_todo *new;
329 struct irmanager_event event;
331 /* Make sure irmanager is running */
332 if ( !irda.in_use) {
333 printk( KERN_ERR "irmanager is not running!\n");
334 return;
337 /* Make new todo event */
338 new = (struct irda_todo *) kmalloc( sizeof(struct irda_todo),
339 GFP_ATOMIC);
340 if ( new == NULL) {
341 return;
343 memset( new, 0, sizeof( struct irda_todo));
345 new->self = self;
346 new->callback = callback;
347 new->param = param;
349 /* Queue todo */
350 enqueue_last(&irda.todo_queue, (queue_t *) new);
352 event.event = EVENT_NEED_PROCESS_CONTEXT;
354 /* Notify the user space manager */
355 irmanager_notify(&event);
359 * Function irmanger_notify (event)
361 * Send an event to the user space manager
364 void irmanager_notify( struct irmanager_event *event)
366 struct irda_event *new;
368 IRDA_DEBUG(4, __FUNCTION__ "()\n");
370 /* Make sure irmanager is running */
371 if (!irda.in_use) {
372 printk( KERN_ERR "irmanager is not running!\n");
373 return;
376 /* Make new IrDA Event */
377 new = (struct irda_event *) kmalloc( sizeof(struct irda_event),
378 GFP_ATOMIC);
379 if ( new == NULL) {
380 return;
382 memset(new, 0, sizeof( struct irda_event));
383 new->event = *event;
385 /* Queue event */
386 enqueue_last(&irda.event_queue, (queue_t *) new);
388 /* Wake up irmanager sleeping on read */
389 wake_up_interruptible(&irda.wait_queue);
392 static int irda_open( struct inode * inode, struct file *file)
394 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
396 if ( irda.in_use) {
397 IRDA_DEBUG( 0, __FUNCTION__ "(), irmanager is already running!\n");
398 return -1;
400 irda.in_use = TRUE;
402 MOD_INC_USE_COUNT;
404 return 0;
408 * Function irda_ioctl (inode, filp, cmd, arg)
410 * Ioctl, used by irmanager to ...
413 static int irda_ioctl( struct inode *inode, struct file *filp,
414 unsigned int cmd, unsigned long arg)
416 struct irda_todo *todo;
417 int err = 0;
418 int size = _IOC_SIZE(cmd);
420 IRDA_DEBUG(4, __FUNCTION__ "()\n");
422 if ( _IOC_DIR(cmd) & _IOC_READ)
423 err = verify_area( VERIFY_WRITE, (void *) arg, size);
424 else if ( _IOC_DIR(cmd) & _IOC_WRITE)
425 err = verify_area( VERIFY_READ, (void *) arg, size);
426 if ( err)
427 return err;
429 switch( cmd) {
430 case IRMGR_IOCTNPC:
431 /* Got process context! */
432 IRDA_DEBUG(4, __FUNCTION__ "(), got process context!\n");
434 while ((todo = (struct irda_todo *) dequeue_first(
435 &irda.todo_queue)) != NULL)
437 todo->callback(todo->self, todo->param);
439 kfree(todo);
441 break;
443 default:
444 return -ENOIOCTLCMD;
447 return 0;
450 static int irda_close(struct inode *inode, struct file *file)
452 IRDA_DEBUG(4, __FUNCTION__ "()\n");
454 MOD_DEC_USE_COUNT;
456 irda.in_use = FALSE;
458 return 0;
461 static ssize_t irda_read(struct file *file, char *buffer, size_t count,
462 loff_t *noidea)
464 struct irda_event *event;
465 unsigned long flags;
466 int len;
468 IRDA_DEBUG(4, __FUNCTION__ "()\n");
470 /* * Go to sleep and wait for event if there is no event to be read! */
471 save_flags( flags);
472 cli();
473 if ( !irda.event_queue)
474 interruptible_sleep_on( &irda.wait_queue);
475 restore_flags(flags);
478 * Ensure proper reaction to signals, and screen out
479 * blocked signals (page 112. linux device drivers)
481 if (signal_pending( current))
482 return -ERESTARTSYS;
484 event = (struct irda_event *) dequeue_first( &irda.event_queue);
485 if (!event)
486 return 0;
488 len = sizeof(struct irmanager_event);
489 copy_to_user(buffer, &event->event, len);
491 /* Finished with event */
492 kfree(event);
494 return len;
497 static ssize_t irda_write(struct file *file, const char *buffer,
498 size_t count, loff_t *noidea)
500 IRDA_DEBUG(0, __FUNCTION__ "()\n");
502 return 0;
505 static u_int irda_poll(struct file *file, poll_table *wait)
507 IRDA_DEBUG(0, __FUNCTION__ "(), Sorry not implemented yet!\n");
509 return 0;
512 void irda_mod_inc_use_count(void)
514 #ifdef MODULE
515 MOD_INC_USE_COUNT;
516 #endif
519 void irda_mod_dec_use_count(void)
521 #ifdef MODULE
522 MOD_DEC_USE_COUNT;
523 #endif
527 * Function irda_proc_modcount (inode, fill)
529 * Use by the proc file system functions to prevent the irda module
530 * being removed while the use is standing in the net/irda directory
532 void irda_proc_modcount(struct inode *inode, int fill)
534 #ifdef MODULE
535 #ifdef CONFIG_PROC_FS
536 if (fill)
537 MOD_INC_USE_COUNT;
538 else
539 MOD_DEC_USE_COUNT;
540 #endif /* CONFIG_PROC_FS */
541 #endif /* MODULE */
544 #ifdef MODULE
546 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
547 MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem");
548 MODULE_PARM(irda_debug, "1l");
551 * Function init_module (void)
553 * Initialize the irda module
556 int init_module(void)
558 irda_proto_init(NULL);
560 return 0;
564 * Function cleanup_module (void)
566 * Cleanup the irda module
569 void cleanup_module(void)
571 irda_proto_cleanup();
573 #endif /* MODULE */