From: Adrian M. <ad...@mc...> - 2002-03-14 18:27:47
|
--- /home/Adrian/sounddc/purupuru.c Wed Mar 13 23:39:57 2002 +++ ./purupuru.c Thu Mar 14 18:25:54 2002 @@ -19,8 +19,11 @@ /* * First posted 18 Feburary 2002 * - * Multiple device support fixed 7 March 2003 - */ + * Multiple device support fixed 7 March 2002 + * + * Hot plugging bug fixed 14 March 2002 + * +*/ #include <linux/kernel.h> #include <linux/slab.h> @@ -36,9 +39,9 @@ #include <linux/interrupt.h> #define PURU_MINOR_BASE 64 -#define PPP_VERSION 1 +#define PPP_VERSION 2 -/*#define _DEBUG_ */ +/*#define _DEBUG_*/ #ifdef _DEBUG_ #define DEBGM(fmt, args...) (printk(KERN_ERR fmt, ##args)) @@ -57,6 +60,7 @@ /* may be more than one puru puru attached */ LIST_HEAD(devices_list); +static int use_count = 0; struct dc_puru_effect { int length_of_time; @@ -71,6 +75,7 @@ int minor; atomic_t active; int timeleft; + }; @@ -111,7 +116,8 @@ puru->dev.event = NULL; puru->dev.idbus = BUS_MAPLE; input_register_device(&puru->dev); - input_register_handler(&purupuru_handler); + if (use_count == 0) input_register_handler(&purupuru_handler); + use_count++; return 0; @@ -121,9 +127,10 @@ { struct dc_purupuru *puru = d->private_data; input_unregister_device(&puru->dev); - /* Remove this device from list */ - list_del(&puru->list); - kfree(puru); + DEBGM("In dc_purupuru_disconnect\n"); + use_count--; + if (use_count < 0) use_count = 0; + if (use_count == 0) input_unregister_handler(&purupuru_handler); } @@ -410,13 +417,17 @@ /* tasklet_enable(&switchoff_tasklet); */ /* Is this a Puru Puru device? */ - if (dev->open != dc_puru_open) + if (dev->open != dc_puru_open) { + DEBGM("Attempted to connect non-PP device\n"); return NULL; + } /* Have we already added this device? */ list_for_each(lst, &devices_list) { device = list_entry(lst, struct dc_purupuru, list); if (device->minor == (PURU_MINOR_BASE + dev->number)) { - return NULL; + DEBGM + ("Attempting to connect already connected PP\n"); + return device->dev.handle; } } @@ -439,6 +450,7 @@ struct dc_purupuru *dcp = dev->private; dcp->minor = handler->minor; list_add_tail(&dcp->list, &devices_list); + return handle; @@ -454,13 +466,15 @@ list_for_each_safe(ptr, nxt, &devices_list) { device = list_entry(ptr, struct dc_purupuru, list); if (device->minor == handle->handler->minor) { + DEBGM("Disconnection: removing from list\n"); list_del(&device->list); - kfree(device); } } input_close_device(handle); kfree(handle); + kfree(device); + } static struct input_handler purupuru_handler = { @@ -475,9 +489,9 @@ { maple_register_driver(&dc_purupuru_driver); - printk("Puru Puru Pack driver for Dreamcast Linux version 0.1\n"); + printk("Puru Puru Pack driver for Dreamcast Linux version 0.2\n"); /* tasklet_disable(&switchoff_tasklet); */ - + return 0; } @@ -488,7 +502,7 @@ struct dc_puru_effect *effect; maple_unregister_driver(&dc_purupuru_driver); - input_unregister_handler(&purupuru_handler); + if (!list_empty(&effects_list)) { list_for_each_safe(ptr, nxt, &effects_list) { |