00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <linux/config.h>
00026 #include <linux/module.h>
00027
00028 #include <linux/init.h>
00029 #include <linux/poll.h>
00030 #include <linux/proc_fs.h>
00031
00032 #include <asm/segment.h>
00033
00034 #include <net/irda/irda.h>
00035 #include <net/irda/irmod.h>
00036 #include <net/irda/irlap.h>
00037 #ifdef CONFIG_IRDA_COMPRESSION
00038 #include <net/irda/irlap_comp.h>
00039 #endif
00040 #include <net/irda/irlmp.h>
00041 #include <net/irda/iriap.h>
00042 #include <net/irda/irias_object.h>
00043 #include <net/irda/irttp.h>
00044 #include <net/irda/irda_device.h>
00045 #include <net/irda/wrapper.h>
00046 #include <net/irda/timer.h>
00047 #include <net/irda/parameters.h>
00048
00049 extern struct proc_dir_entry *proc_irda;
00050
00051 struct irda_cb irda;
00052
00053 #ifdef CONFIG_IRDA_DEBUG
00054 __u32 irda_debug = IRDA_DEBUG_LEVEL;
00055 #endif
00056
00057 extern void irda_proc_register(void);
00058 extern void irda_proc_unregister(void);
00059 extern int irda_sysctl_register(void);
00060 extern void irda_sysctl_unregister(void);
00061
00062 extern void irda_proto_init(struct net_proto *pro);
00063 extern void irda_proto_cleanup(void);
00064
00065 extern int irda_device_init(void);
00066 extern int irlan_init(void);
00067 extern int irlan_client_init(void);
00068 extern int irlan_server_init(void);
00069 extern int ircomm_init(void);
00070 extern int ircomm_tty_init(void);
00071 extern int irlpt_client_init(void);
00072 extern int irlpt_server_init(void);
00073
00074 #ifdef CONFIG_IRDA_COMPRESSION
00075 #ifdef CONFIG_IRDA_DEFLATE
00076 extern irda_deflate_init(void);
00077 #endif
00078 #endif
00079
00080 static int irda_open(struct inode * inode, struct file *file);
00081 static int irda_ioctl(struct inode *inode, struct file *filp,
00082 unsigned int cmd, unsigned long arg);
00083 static int irda_close(struct inode *inode, struct file *file);
00084 static ssize_t irda_read(struct file *file, char *buffer, size_t count,
00085 loff_t *noidea);
00086 static ssize_t irda_write(struct file *file, const char *buffer,
00087 size_t count, loff_t *noidea);
00088 static u_int irda_poll(struct file *file, poll_table *wait);
00089
00090 static struct file_operations irda_fops = {
00091 NULL,
00092 irda_read,
00093 irda_write,
00094 NULL,
00095 irda_poll,
00096 irda_ioctl,
00097 NULL,
00098 irda_open,
00099 NULL,
00100 irda_close,
00101 NULL,
00102 NULL,
00103 };
00104
00105
00106 EXPORT_SYMBOL(irttp_open_tsap);
00107 EXPORT_SYMBOL(irttp_close_tsap);
00108 EXPORT_SYMBOL(irttp_connect_response);
00109 EXPORT_SYMBOL(irttp_data_request);
00110 EXPORT_SYMBOL(irttp_disconnect_request);
00111 EXPORT_SYMBOL(irttp_flow_request);
00112 EXPORT_SYMBOL(irttp_connect_request);
00113 EXPORT_SYMBOL(irttp_udata_request);
00114 EXPORT_SYMBOL(irttp_dup);
00115
00116
00117 #ifdef CONFIG_IRDA_DEBUG
00118 EXPORT_SYMBOL(irda_debug);
00119 #endif
00120 EXPORT_SYMBOL(irda_notify_init);
00121 EXPORT_SYMBOL(irmanager_notify);
00122 EXPORT_SYMBOL(irda_lock);
00123 #ifdef CONFIG_PROC_FS
00124 EXPORT_SYMBOL(proc_irda);
00125 #endif
00126 EXPORT_SYMBOL(irda_param_insert);
00127 EXPORT_SYMBOL(irda_param_extract);
00128 EXPORT_SYMBOL(irda_param_extract_all);
00129 EXPORT_SYMBOL(irda_param_pack);
00130 EXPORT_SYMBOL(irda_param_unpack);
00131
00132
00133 EXPORT_SYMBOL(iriap_open);
00134 EXPORT_SYMBOL(iriap_close);
00135 EXPORT_SYMBOL(iriap_getvaluebyclass_request);
00136 EXPORT_SYMBOL(irias_object_change_attribute);
00137 EXPORT_SYMBOL(irias_add_integer_attrib);
00138 EXPORT_SYMBOL(irias_add_octseq_attrib);
00139 EXPORT_SYMBOL(irias_add_string_attrib);
00140 EXPORT_SYMBOL(irias_insert_object);
00141 EXPORT_SYMBOL(irias_new_object);
00142 EXPORT_SYMBOL(irias_delete_object);
00143 EXPORT_SYMBOL(irias_delete_value);
00144 EXPORT_SYMBOL(irias_find_object);
00145 EXPORT_SYMBOL(irias_find_attrib);
00146 EXPORT_SYMBOL(irias_new_integer_value);
00147 EXPORT_SYMBOL(irias_new_string_value);
00148 EXPORT_SYMBOL(irias_new_octseq_value);
00149
00150
00151 EXPORT_SYMBOL(irlmp_discovery_request);
00152 EXPORT_SYMBOL(irlmp_register_client);
00153 EXPORT_SYMBOL(irlmp_unregister_client);
00154 EXPORT_SYMBOL(irlmp_update_client);
00155 EXPORT_SYMBOL(irlmp_register_service);
00156 EXPORT_SYMBOL(irlmp_unregister_service);
00157 EXPORT_SYMBOL(irlmp_service_to_hint);
00158 EXPORT_SYMBOL(irlmp_data_request);
00159 EXPORT_SYMBOL(irlmp_open_lsap);
00160 EXPORT_SYMBOL(irlmp_close_lsap);
00161 EXPORT_SYMBOL(irlmp_connect_request);
00162 EXPORT_SYMBOL(irlmp_connect_response);
00163 EXPORT_SYMBOL(irlmp_disconnect_request);
00164 EXPORT_SYMBOL(irlmp_get_daddr);
00165 EXPORT_SYMBOL(irlmp_get_saddr);
00166 EXPORT_SYMBOL(irlmp_dup);
00167 EXPORT_SYMBOL(lmp_reasons);
00168
00169
00170 EXPORT_SYMBOL(hashbin_find);
00171 EXPORT_SYMBOL(hashbin_new);
00172 EXPORT_SYMBOL(hashbin_insert);
00173 EXPORT_SYMBOL(hashbin_delete);
00174 EXPORT_SYMBOL(hashbin_remove);
00175 EXPORT_SYMBOL(hashbin_get_next);
00176 EXPORT_SYMBOL(hashbin_get_first);
00177
00178
00179 EXPORT_SYMBOL(irlap_open);
00180 EXPORT_SYMBOL(irlap_close);
00181 #ifdef CONFIG_IRDA_COMPRESSION
00182 EXPORT_SYMBOL(irda_unregister_compressor);
00183 EXPORT_SYMBOL(irda_register_compressor);
00184 #endif
00185 EXPORT_SYMBOL(irda_init_max_qos_capabilies);
00186 EXPORT_SYMBOL(irda_qos_bits_to_value);
00187 EXPORT_SYMBOL(irda_device_setup);
00188 EXPORT_SYMBOL(irda_device_set_media_busy);
00189 EXPORT_SYMBOL(irda_device_txqueue_empty);
00190
00191 EXPORT_SYMBOL(irda_device_dongle_init);
00192 EXPORT_SYMBOL(irda_device_dongle_cleanup);
00193 EXPORT_SYMBOL(irda_device_register_dongle);
00194 EXPORT_SYMBOL(irda_device_unregister_dongle);
00195 EXPORT_SYMBOL(irda_task_execute);
00196 EXPORT_SYMBOL(irda_task_kick);
00197 EXPORT_SYMBOL(irda_task_next_state);
00198 EXPORT_SYMBOL(irda_task_delete);
00199
00200 EXPORT_SYMBOL(async_wrap_skb);
00201 EXPORT_SYMBOL(async_unwrap_char);
00202 EXPORT_SYMBOL(irda_start_timer);
00203 EXPORT_SYMBOL(setup_dma);
00204 EXPORT_SYMBOL(infrared_mode);
00205
00206 #ifdef CONFIG_IRTTY
00207 EXPORT_SYMBOL(irtty_set_dtr_rts);
00208 EXPORT_SYMBOL(irtty_register_dongle);
00209 EXPORT_SYMBOL(irtty_unregister_dongle);
00210 EXPORT_SYMBOL(irtty_set_packet_mode);
00211 #endif
00212
00213 int __init irda_init(void)
00214 {
00215 MESSAGE("IrDA (tm) Protocols for Linux-2.2 (Dag Brattli)\n");
00216
00217 irlmp_init();
00218 irlap_init();
00219
00220 #ifdef MODULE
00221 irda_device_init();
00222 #endif
00223 iriap_init();
00224 irttp_init();
00225
00226 #ifdef CONFIG_PROC_FS
00227 irda_proc_register();
00228 #endif
00229 #ifdef CONFIG_SYSCTL
00230 irda_sysctl_register();
00231 #endif
00232 irda.dev.minor = MISC_DYNAMIC_MINOR;
00233 irda.dev.name = "irda";
00234 irda.dev.fops = &irda_fops;
00235
00236 misc_register(&irda.dev);
00237
00238 irda.in_use = FALSE;
00239
00240
00241
00242
00243 #ifdef CONFIG_IRLAN
00244 irlan_init();
00245 #endif
00246 #ifdef CONFIG_IRCOMM
00247 ircomm_init();
00248 ircomm_tty_init();
00249 #endif
00250
00251 #ifdef CONFIG_IRDA_COMPRESSION
00252 #ifdef CONFIG_IRDA_DEFLATE
00253 irda_deflate_init();
00254 #endif
00255 #endif
00256
00257 return 0;
00258 }
00259
00260 #ifdef MODULE
00261 void irda_cleanup(void)
00262 {
00263 misc_deregister(&irda.dev);
00264
00265 #ifdef CONFIG_SYSCTL
00266 irda_sysctl_unregister();
00267 #endif
00268
00269 #ifdef CONFIG_PROC_FS
00270 irda_proc_unregister();
00271 #endif
00272
00273 irttp_cleanup();
00274 iriap_cleanup();
00275
00276
00277 irda_device_cleanup();
00278 irlap_cleanup();
00279
00280
00281 irlmp_cleanup();
00282 }
00283 #endif
00284
00285
00286
00287
00288
00289
00290
00291 inline int irda_unlock(int *lock)
00292 {
00293 if (!test_and_clear_bit(0, (void *) lock)) {
00294 printk("Trying to unlock already unlocked variable!\n");
00295 return FALSE;
00296 }
00297 return TRUE;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306 void irda_notify_init(notify_t *notify)
00307 {
00308 notify->data_indication = NULL;
00309 notify->udata_indication = NULL;
00310 notify->connect_confirm = NULL;
00311 notify->connect_indication = NULL;
00312 notify->disconnect_indication = NULL;
00313 notify->flow_indication = NULL;
00314 notify->instance = NULL;
00315 strncpy(notify->name, "Unknown", NOTIFY_MAX_NAME);
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 void irda_execute_as_process( void *self, TODO_CALLBACK callback, __u32 param)
00327 {
00328 struct irda_todo *new;
00329 struct irmanager_event event;
00330
00331
00332 if (!irda.in_use)
00333 return;
00334
00335
00336 new = (struct irda_todo *) kmalloc( sizeof(struct irda_todo),
00337 GFP_ATOMIC);
00338 if ( new == NULL) {
00339 return;
00340 }
00341 memset( new, 0, sizeof( struct irda_todo));
00342
00343 new->self = self;
00344 new->callback = callback;
00345 new->param = param;
00346
00347
00348 enqueue_last(&irda.todo_queue, (queue_t *) new);
00349
00350 event.event = EVENT_NEED_PROCESS_CONTEXT;
00351
00352
00353 irmanager_notify(&event);
00354 }
00355
00356
00357
00358
00359
00360
00361
00362 void irmanager_notify( struct irmanager_event *event)
00363 {
00364 struct irda_event *new;
00365
00366 IRDA_DEBUG(4, __FUNCTION__ "()\n");
00367
00368
00369 if (!irda.in_use)
00370 return;
00371
00372
00373 new = (struct irda_event *) kmalloc( sizeof(struct irda_event),
00374 GFP_ATOMIC);
00375 if ( new == NULL) {
00376 return;
00377 }
00378 memset(new, 0, sizeof( struct irda_event));
00379 new->event = *event;
00380
00381
00382 enqueue_last(&irda.event_queue, (queue_t *) new);
00383
00384
00385 wake_up_interruptible(&irda.wait_queue);
00386 }
00387
00388 static int irda_open( struct inode * inode, struct file *file)
00389 {
00390 IRDA_DEBUG( 4, __FUNCTION__ "()\n");
00391
00392 if (irda.in_use) {
00393 IRDA_DEBUG(0, __FUNCTION__
00394 "(), irmanager is already running!\n");
00395 return -1;
00396 }
00397 irda.in_use = TRUE;
00398
00399 MOD_INC_USE_COUNT;
00400
00401 return 0;
00402 }
00403
00404
00405
00406
00407
00408
00409
00410 static int irda_ioctl(struct inode *inode, struct file *filp,
00411 unsigned int cmd, unsigned long arg)
00412 {
00413 struct irda_todo *todo;
00414 int err = 0;
00415 int size = _IOC_SIZE(cmd);
00416
00417 IRDA_DEBUG(4, __FUNCTION__ "()\n");
00418
00419 if (_IOC_DIR(cmd) & _IOC_READ)
00420 err = verify_area( VERIFY_WRITE, (void *) arg, size);
00421 else if (_IOC_DIR(cmd) & _IOC_WRITE)
00422 err = verify_area( VERIFY_READ, (void *) arg, size);
00423 if (err)
00424 return err;
00425
00426 switch (cmd) {
00427 case IRMGR_IOCTNPC:
00428
00429 IRDA_DEBUG(4, __FUNCTION__ "(), got process context!\n");
00430
00431 while ((todo = (struct irda_todo *) dequeue_first(
00432 &irda.todo_queue)) != NULL)
00433 {
00434 todo->callback(todo->self, todo->param);
00435
00436 kfree(todo);
00437 }
00438 break;
00439
00440 default:
00441 return -ENOIOCTLCMD;
00442 }
00443
00444 return 0;
00445 }
00446
00447 static int irda_close(struct inode *inode, struct file *file)
00448 {
00449 IRDA_DEBUG(4, __FUNCTION__ "()\n");
00450
00451 MOD_DEC_USE_COUNT;
00452
00453 irda.in_use = FALSE;
00454
00455 return 0;
00456 }
00457
00458 static ssize_t irda_read(struct file *file, char *buffer, size_t count,
00459 loff_t *noidea)
00460 {
00461 struct irda_event *event;
00462 unsigned long flags;
00463 int len;
00464
00465 IRDA_DEBUG(4, __FUNCTION__ "()\n");
00466
00467
00468 save_flags( flags);
00469 cli();
00470 if ( !irda.event_queue)
00471 interruptible_sleep_on( &irda.wait_queue);
00472 restore_flags(flags);
00473
00474
00475
00476
00477
00478 if (signal_pending( current))
00479 return -ERESTARTSYS;
00480
00481 event = (struct irda_event *) dequeue_first( &irda.event_queue);
00482 if (!event)
00483 return 0;
00484
00485 len = sizeof(struct irmanager_event);
00486 copy_to_user(buffer, &event->event, len);
00487
00488
00489 kfree(event);
00490
00491 return len;
00492 }
00493
00494 static ssize_t irda_write(struct file *file, const char *buffer,
00495 size_t count, loff_t *noidea)
00496 {
00497 IRDA_DEBUG(0, __FUNCTION__ "()\n");
00498
00499 return 0;
00500 }
00501
00502 static u_int irda_poll(struct file *file, poll_table *wait)
00503 {
00504 IRDA_DEBUG(0, __FUNCTION__ "(), Sorry not implemented yet!\n");
00505
00506 return 0;
00507 }
00508
00509 void irda_mod_inc_use_count(void)
00510 {
00511 #ifdef MODULE
00512 MOD_INC_USE_COUNT;
00513 #endif
00514 }
00515
00516 void irda_mod_dec_use_count(void)
00517 {
00518 #ifdef MODULE
00519 MOD_DEC_USE_COUNT;
00520 #endif
00521 }
00522
00523
00524
00525
00526
00527
00528
00529 void irda_proc_modcount(struct inode *inode, int fill)
00530 {
00531 #ifdef MODULE
00532 #ifdef CONFIG_PROC_FS
00533 if (fill)
00534 MOD_INC_USE_COUNT;
00535 else
00536 MOD_DEC_USE_COUNT;
00537 #endif
00538 #endif
00539 }
00540
00541 #ifdef MODULE
00542
00543 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
00544 MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem");
00545 MODULE_PARM(irda_debug, "1l");
00546
00547
00548
00549
00550
00551
00552
00553 int init_module(void)
00554 {
00555 irda_proto_init(NULL);
00556
00557 return 0;
00558 }
00559
00560
00561
00562
00563
00564
00565
00566 void cleanup_module(void)
00567 {
00568 irda_proto_cleanup();
00569 }
00570 #endif