--- /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) {
|