1 /*********************************************************************
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: Tue Jan 19 23:34:18 1999
10 * Modified by: Dag Brattli <dagb@cs.uit.no>
12 * Copyright (c) 1997 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>
27 #include <linux/init.h>
28 #include <asm/segment.h>
29 #include <linux/poll.h>
31 #include <net/irda/irda.h>
32 #include <net/irda/irlmp.h>
33 #include <net/irda/iriap.h>
34 #include <net/irda/irttp.h>
36 struct irda_cb irda
; /* One global instance */
38 #ifdef CONFIG_IRDA_DEBUG
39 __u32 irda_debug
= IRDA_DEBUG
;
42 extern void irda_proc_register(void);
43 extern void irda_proc_unregister(void);
44 extern int irda_sysctl_register(void);
45 extern void irda_sysctl_unregister(void);
47 extern void irda_proto_init(struct net_proto
*pro
);
48 extern void irda_proto_cleanup(void);
50 extern int irda_device_init(void);
51 extern int irobex_init(void);
52 extern int irlan_init(void);
53 extern int irlan_client_init(void);
54 extern int irlan_server_init(void);
55 extern int ircomm_init(void);
56 extern int irvtd_init(void);
57 extern int irlpt_client_init(void);
58 extern int irlpt_server_init(void);
60 static int irda_open( struct inode
* inode
, struct file
*file
);
61 static int irda_ioctl( struct inode
*inode
, struct file
*filp
,
62 unsigned int cmd
, unsigned long arg
);
63 static int irda_close( struct inode
*inode
, struct file
*file
);
64 static ssize_t
irda_read( struct file
*file
, char *buffer
, size_t count
,
66 static ssize_t
irda_write( struct file
*file
, const char *buffer
,
67 size_t count
, loff_t
*noidea
);
68 static u_int
irda_poll( struct file
*file
, poll_table
*wait
);
70 static struct file_operations irda_fops
= {
73 irda_write
, /* write */
76 irda_ioctl
, /* ioctl */
85 __initfunc(int irda_init(void))
87 printk( KERN_INFO
"Linux Support for the IrDA (tm) protocols (Dag Brattli)\n");
99 irda_sysctl_register();
102 irda
.dev
.minor
= MISC_DYNAMIC_MINOR
;
103 irda
.dev
.name
= "irda";
104 irda
.dev
.fops
= &irda_fops
;
106 misc_register( &irda
.dev
);
111 * Initialize modules that got compiled into the kernel
116 #ifdef CONFIG_IRLAN_CLIENT
119 #ifdef CONFIG_IRLAN_SERVER
130 #ifdef CONFIG_IRLPT_CLIENT
134 #ifdef CONFIG_IRLPT_SERVER
141 void irda_cleanup(void)
143 misc_deregister( &irda
.dev
);
146 irda_sysctl_unregister();
149 #ifdef CONFIG_PROC_FS
150 irda_proc_unregister();
153 /* Remove higher layers */
157 /* Remove lower layers */
158 irda_device_cleanup();
159 irlap_cleanup(); /* Must be done before irlmp_cleanup()! DB */
161 /* Remove middle layer */
166 * Function irda_lock (lock)
168 * Lock variable. Returns false if the lock is already set.
171 inline int irda_lock( int *lock
) {
172 if ( test_and_set_bit( 0, (void *) lock
)) {
173 printk("Trying to lock, already locked variable!\n");
180 * Function irda_unlock (lock)
182 * Unlock variable. Returns false if lock is already unlocked
185 inline int irda_unlock( int *lock
) {
186 if ( !test_and_clear_bit( 0, (void *) lock
)) {
187 printk("Trying to unlock already unlocked variable!\n");
194 * Function irda_notify_init (notify)
196 * Used for initializing the notify structure
199 void irda_notify_init( struct notify_t
*notify
)
202 notify
->data_indication
= NULL
;
203 notify
->udata_indication
= NULL
;
204 notify
->connect_confirm
= NULL
;
205 notify
->connect_indication
= NULL
;
206 notify
->disconnect_indication
= NULL
;
207 notify
->flow_indication
= NULL
;
208 notify
->instance
= NULL
;
209 strncpy( notify
->name
, "Unknown", NOTIFY_MAX_NAME
);
213 * Function irda_execute_as_process (self, callback, param)
215 * If a layer needs to have a function executed with a process context,
216 * then it can register the function here, and the function will then
217 * be executed as fast as possible.
220 void irda_execute_as_process( void *self
, TODO_CALLBACK callback
, __u32 param
)
222 struct irda_todo
*new;
223 struct irmanager_event event
;
225 /* Make sure irmanager is running */
227 printk( KERN_ERR
"irmanager is not running!\n");
231 /* Make new todo event */
232 new = (struct irda_todo
*) kmalloc( sizeof(struct irda_todo
),
237 memset( new, 0, sizeof( struct irda_todo
));
240 new->callback
= callback
;
244 enqueue_last( &irda
.todo_queue
, (QUEUE
*) new);
246 event
.event
= EVENT_NEED_PROCESS_CONTEXT
;
248 /* Notify the user space manager */
249 irmanager_notify( &event
);
253 * Function irmanger_notify (event)
255 * Send an event to the user space manager
258 void irmanager_notify( struct irmanager_event
*event
)
260 struct irda_event
*new;
262 DEBUG( 4, __FUNCTION__
"()\n");
264 /* Make sure irmanager is running */
266 printk( KERN_ERR
"irmanager is not running!\n");
270 /* Make new IrDA Event */
271 new = (struct irda_event
*) kmalloc( sizeof(struct irda_event
),
276 memset( new, 0, sizeof( struct irda_event
));
280 enqueue_last( &irda
.event_queue
, (QUEUE
*) new);
282 /* Wake up irmanager sleeping on read */
283 wake_up_interruptible( &irda
.wait_queue
);
286 static int irda_open( struct inode
* inode
, struct file
*file
)
288 DEBUG( 4, __FUNCTION__
"()\n");
291 DEBUG( 0, __FUNCTION__
"(), irmanager is already running!\n");
302 * Function irda_ioctl (inode, filp, cmd, arg)
304 * Ioctl, used by irmanager to ...
307 static int irda_ioctl( struct inode
*inode
, struct file
*filp
,
308 unsigned int cmd
, unsigned long arg
)
310 struct irda_todo
*todo
;
312 int size
= _IOC_SIZE(cmd
);
314 DEBUG( 4, __FUNCTION__
"()\n");
316 if ( _IOC_DIR(cmd
) & _IOC_READ
)
317 err
= verify_area( VERIFY_WRITE
, (void *) arg
, size
);
318 else if ( _IOC_DIR(cmd
) & _IOC_WRITE
)
319 err
= verify_area( VERIFY_READ
, (void *) arg
, size
);
325 /* Got process context! */
326 DEBUG( 4, __FUNCTION__
"(), got process context!\n");
328 while (( todo
= (struct irda_todo
*) dequeue_first(
329 &irda
.todo_queue
)) != NULL
)
331 todo
->callback( todo
->self
, todo
->param
);
344 static int irda_close( struct inode
*inode
, struct file
*file
)
346 DEBUG( 4, __FUNCTION__
"()\n");
355 static ssize_t
irda_read( struct file
*file
, char *buffer
, size_t count
,
358 struct irda_event
*event
;
362 DEBUG( 4, __FUNCTION__
"()\n");
364 /* * Go to sleep and wait for event if there is no event to be read! */
367 if ( !irda
.event_queue
)
368 interruptible_sleep_on( &irda
.wait_queue
);
369 restore_flags(flags
);
372 * Ensure proper reaction to signals, and screen out
373 * blocked signals (page 112. linux device drivers)
375 if ( signal_pending( current
))
378 event
= (struct irda_event
*) dequeue_first( &irda
.event_queue
);
380 len
= sizeof(struct irmanager_event
);
381 copy_to_user( buffer
, &event
->event
, len
);
383 /* Finished with event */
389 static ssize_t
irda_write( struct file
*file
, const char *buffer
,
390 size_t count
, loff_t
*noidea
)
392 DEBUG( 0, __FUNCTION__
"()\n");
397 static u_int
irda_poll( struct file
*file
, poll_table
*wait
)
399 DEBUG( 0, __FUNCTION__
"(), Sorry not implemented yet!\n");
406 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
407 MODULE_DESCRIPTION("The Linux IrDA protocol subsystem");
410 * Function init_module (void)
412 * Initialize the irda module
415 int init_module(void)
417 irda_proto_init(NULL
);
423 * Function cleanup_module (void)
425 * Cleanup the irda module
428 void cleanup_module(void)
430 irda_proto_cleanup();