|
@@ -53,6 +53,7 @@ static LIST_HEAD(gameport_list);
|
|
|
|
|
|
static struct bus_type gameport_bus;
|
|
static struct bus_type gameport_bus;
|
|
|
|
|
|
|
|
+static void gameport_add_driver(struct gameport_driver *drv);
|
|
static void gameport_add_port(struct gameport *gameport);
|
|
static void gameport_add_port(struct gameport *gameport);
|
|
static void gameport_destroy_port(struct gameport *gameport);
|
|
static void gameport_destroy_port(struct gameport *gameport);
|
|
static void gameport_reconnect_port(struct gameport *gameport);
|
|
static void gameport_reconnect_port(struct gameport *gameport);
|
|
@@ -211,8 +212,14 @@ static void gameport_release_driver(struct gameport *gameport)
|
|
|
|
|
|
static void gameport_find_driver(struct gameport *gameport)
|
|
static void gameport_find_driver(struct gameport *gameport)
|
|
{
|
|
{
|
|
|
|
+ int error;
|
|
|
|
+
|
|
down_write(&gameport_bus.subsys.rwsem);
|
|
down_write(&gameport_bus.subsys.rwsem);
|
|
- device_attach(&gameport->dev);
|
|
|
|
|
|
+ error = device_attach(&gameport->dev);
|
|
|
|
+ if (error < 0)
|
|
|
|
+ printk(KERN_WARNING
|
|
|
|
+ "gameport: device_attach() failed for %s (%s), error: %d\n",
|
|
|
|
+ gameport->phys, gameport->name, error);
|
|
up_write(&gameport_bus.subsys.rwsem);
|
|
up_write(&gameport_bus.subsys.rwsem);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -316,7 +323,6 @@ static void gameport_remove_duplicate_events(struct gameport_event *event)
|
|
spin_unlock_irqrestore(&gameport_event_lock, flags);
|
|
spin_unlock_irqrestore(&gameport_event_lock, flags);
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
static struct gameport_event *gameport_get_event(void)
|
|
static struct gameport_event *gameport_get_event(void)
|
|
{
|
|
{
|
|
struct gameport_event *event;
|
|
struct gameport_event *event;
|
|
@@ -342,7 +348,6 @@ static struct gameport_event *gameport_get_event(void)
|
|
static void gameport_handle_event(void)
|
|
static void gameport_handle_event(void)
|
|
{
|
|
{
|
|
struct gameport_event *event;
|
|
struct gameport_event *event;
|
|
- struct gameport_driver *gameport_drv;
|
|
|
|
|
|
|
|
mutex_lock(&gameport_mutex);
|
|
mutex_lock(&gameport_mutex);
|
|
|
|
|
|
@@ -369,8 +374,7 @@ static void gameport_handle_event(void)
|
|
break;
|
|
break;
|
|
|
|
|
|
case GAMEPORT_REGISTER_DRIVER:
|
|
case GAMEPORT_REGISTER_DRIVER:
|
|
- gameport_drv = event->object;
|
|
|
|
- driver_register(&gameport_drv->driver);
|
|
|
|
|
|
+ gameport_add_driver(event->object);
|
|
break;
|
|
break;
|
|
|
|
|
|
default:
|
|
default:
|
|
@@ -532,6 +536,7 @@ static void gameport_init_port(struct gameport *gameport)
|
|
if (gameport->parent)
|
|
if (gameport->parent)
|
|
gameport->dev.parent = &gameport->parent->dev;
|
|
gameport->dev.parent = &gameport->parent->dev;
|
|
|
|
|
|
|
|
+ INIT_LIST_HEAD(&gameport->node);
|
|
spin_lock_init(&gameport->timer_lock);
|
|
spin_lock_init(&gameport->timer_lock);
|
|
init_timer(&gameport->poll_timer);
|
|
init_timer(&gameport->poll_timer);
|
|
gameport->poll_timer.function = gameport_run_poll_handler;
|
|
gameport->poll_timer.function = gameport_run_poll_handler;
|
|
@@ -544,6 +549,8 @@ static void gameport_init_port(struct gameport *gameport)
|
|
*/
|
|
*/
|
|
static void gameport_add_port(struct gameport *gameport)
|
|
static void gameport_add_port(struct gameport *gameport)
|
|
{
|
|
{
|
|
|
|
+ int error;
|
|
|
|
+
|
|
if (gameport->parent)
|
|
if (gameport->parent)
|
|
gameport->parent->child = gameport;
|
|
gameport->parent->child = gameport;
|
|
|
|
|
|
@@ -558,8 +565,13 @@ static void gameport_add_port(struct gameport *gameport)
|
|
printk(KERN_INFO "gameport: %s is %s, speed %dkHz\n",
|
|
printk(KERN_INFO "gameport: %s is %s, speed %dkHz\n",
|
|
gameport->name, gameport->phys, gameport->speed);
|
|
gameport->name, gameport->phys, gameport->speed);
|
|
|
|
|
|
- device_add(&gameport->dev);
|
|
|
|
- gameport->registered = 1;
|
|
|
|
|
|
+ error = device_add(&gameport->dev);
|
|
|
|
+ if (error)
|
|
|
|
+ printk(KERN_ERR
|
|
|
|
+ "gameport: device_add() failed for %s (%s), error: %d\n",
|
|
|
|
+ gameport->phys, gameport->name, error);
|
|
|
|
+ else
|
|
|
|
+ gameport->registered = 1;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -583,10 +595,11 @@ static void gameport_destroy_port(struct gameport *gameport)
|
|
|
|
|
|
if (gameport->registered) {
|
|
if (gameport->registered) {
|
|
device_del(&gameport->dev);
|
|
device_del(&gameport->dev);
|
|
- list_del_init(&gameport->node);
|
|
|
|
gameport->registered = 0;
|
|
gameport->registered = 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ list_del_init(&gameport->node);
|
|
|
|
+
|
|
gameport_remove_pending_events(gameport);
|
|
gameport_remove_pending_events(gameport);
|
|
put_device(&gameport->dev);
|
|
put_device(&gameport->dev);
|
|
}
|
|
}
|
|
@@ -704,11 +717,22 @@ static int gameport_driver_remove(struct device *dev)
|
|
}
|
|
}
|
|
|
|
|
|
static struct bus_type gameport_bus = {
|
|
static struct bus_type gameport_bus = {
|
|
- .name = "gameport",
|
|
|
|
- .probe = gameport_driver_probe,
|
|
|
|
- .remove = gameport_driver_remove,
|
|
|
|
|
|
+ .name = "gameport",
|
|
|
|
+ .probe = gameport_driver_probe,
|
|
|
|
+ .remove = gameport_driver_remove,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static void gameport_add_driver(struct gameport_driver *drv)
|
|
|
|
+{
|
|
|
|
+ int error;
|
|
|
|
+
|
|
|
|
+ error = driver_register(&drv->driver);
|
|
|
|
+ if (error)
|
|
|
|
+ printk(KERN_ERR
|
|
|
|
+ "gameport: driver_register() failed for %s, error: %d\n",
|
|
|
|
+ drv->driver.name, error);
|
|
|
|
+}
|
|
|
|
+
|
|
void __gameport_register_driver(struct gameport_driver *drv, struct module *owner)
|
|
void __gameport_register_driver(struct gameport_driver *drv, struct module *owner)
|
|
{
|
|
{
|
|
drv->driver.bus = &gameport_bus;
|
|
drv->driver.bus = &gameport_bus;
|
|
@@ -778,16 +802,24 @@ void gameport_close(struct gameport *gameport)
|
|
|
|
|
|
static int __init gameport_init(void)
|
|
static int __init gameport_init(void)
|
|
{
|
|
{
|
|
- gameport_task = kthread_run(gameport_thread, NULL, "kgameportd");
|
|
|
|
- if (IS_ERR(gameport_task)) {
|
|
|
|
- printk(KERN_ERR "gameport: Failed to start kgameportd\n");
|
|
|
|
- return PTR_ERR(gameport_task);
|
|
|
|
- }
|
|
|
|
|
|
+ int error;
|
|
|
|
|
|
gameport_bus.dev_attrs = gameport_device_attrs;
|
|
gameport_bus.dev_attrs = gameport_device_attrs;
|
|
gameport_bus.drv_attrs = gameport_driver_attrs;
|
|
gameport_bus.drv_attrs = gameport_driver_attrs;
|
|
gameport_bus.match = gameport_bus_match;
|
|
gameport_bus.match = gameport_bus_match;
|
|
- bus_register(&gameport_bus);
|
|
|
|
|
|
+ error = bus_register(&gameport_bus);
|
|
|
|
+ if (error) {
|
|
|
|
+ printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error);
|
|
|
|
+ return error;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ gameport_task = kthread_run(gameport_thread, NULL, "kgameportd");
|
|
|
|
+ if (IS_ERR(gameport_task)) {
|
|
|
|
+ bus_unregister(&gameport_bus);
|
|
|
|
+ error = PTR_ERR(gameport_task);
|
|
|
|
+ printk(KERN_ERR "gameport: Failed to start kgameportd, error: %d\n", error);
|
|
|
|
+ return error;
|
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|