* [PATCH 0/10] Convert gameport to driver model/sysfs @ 2005-02-11 6:58 Dmitry Torokhov 2005-02-11 6:59 ` [PATCH 1/10] Gameport: rename driver to port_data Dmitry Torokhov 2005-02-11 8:11 ` [PATCH 0/10] Convert gameport to driver model/sysfs Vojtech Pavlik 0 siblings, 2 replies; 12+ messages in thread From: Dmitry Torokhov @ 2005-02-11 6:58 UTC (permalink / raw) To: InputML; +Cc: alsa-devel, LKML, Vojtech Pavlik Hi, This series of patches adds a new "gameport" bus to the driver model. It is implemented very similarly to "serio" bus and also allows individual drivers to be manually bound/disconnected from a port by manipulating port's "drvctl" attribute. 01-gameport-renames1.patch - rename gameport->driver to gameport->port_data in preparation to sysfs integration to avoid confusion with real drivers. 02-gameport-renames2.patch - more renames in gameport in preparations to sysfs integration, gameport_dev renamed to gameport_driver, gameport_[un]register_device renamed to gameport_[un]register_driver 03-gameport-connect-mandatory.patch - make connect and disconnect mandatory as these call gameport_open and gameport_close which actually bind driver and port together. 04-gameport-dynalloc-prepare.patch - sysfs/kobjects requires objects be allocated synamically. Prepare to dynamic gameport allocation, create gameport_allocate_port and gameport_free_port; dynamically allocated ports are freed by core upon release. Also add gameport_set_name and gameport_set_phys to ease transition. 05-gameport-dynalloc-input.patch - convert drivers in input/gameport to dynamic gameport allocation. 06-gameport-dynalloc-sound-oss.patch - convert drivers in sound/oss to dynamic gameport allocation. 07-gameport-dynalloc-sound-alsa.patch - convert drivers in sound/pci to dynamic gameport allocation. 08-gameport-drivers-sysfs.patch - add "gameport" bus and have joystick gameport drivers register themselves on this bus. 09-gameport-devices-sysfs.patch - complete gameport sysfs integration. Gameports are registered on the "gameport" bus. 10-gameport-drvdata.patch - Get rid of gameport->private, use driver-specific data in device structure, access through gameport_get/set_drvdata helpers. The changes can also be pulled from my tree (which has Vojtech's input tree as a parent): bk pull bk://dtor.bkbits.net/input I am CC-ing ALSA list as the changes touch quite a few sound drivers. Comments/testing is appreciated. -- Dmitry ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/10] Gameport: rename driver to port_data 2005-02-11 6:58 [PATCH 0/10] Convert gameport to driver model/sysfs Dmitry Torokhov @ 2005-02-11 6:59 ` Dmitry Torokhov 2005-02-11 7:00 ` [PATCH 2/10] Gameport: rename gameport_dev to gameport_driver Dmitry Torokhov 2005-02-11 8:11 ` [PATCH 0/10] Convert gameport to driver model/sysfs Vojtech Pavlik 1 sibling, 1 reply; 12+ messages in thread From: Dmitry Torokhov @ 2005-02-11 6:59 UTC (permalink / raw) To: InputML; +Cc: alsa-devel, LKML, Vojtech Pavlik =================================================================== ChangeSet@1.2149, 2005-02-11 01:09:43-05:00, dtor_core@ameritech.net Input: rename gameport->driver to gameport->port_data in preparation to sysfs integration. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> drivers/input/gameport/lightning.c | 8 ++++---- drivers/input/gameport/vortex.c | 10 +++++----- drivers/input/joystick/a3d.c | 8 ++++---- include/linux/gameport.h | 4 ++-- sound/oss/trident.c | 10 +++++----- sound/pci/au88x0/au88x0_game.c | 15 +++++++-------- 6 files changed, 27 insertions(+), 28 deletions(-) =================================================================== diff -Nru a/drivers/input/gameport/lightning.c b/drivers/input/gameport/lightning.c --- a/drivers/input/gameport/lightning.c 2005-02-11 01:34:39 -05:00 +++ b/drivers/input/gameport/lightning.c 2005-02-11 01:34:39 -05:00 @@ -79,7 +79,7 @@ static int l4_cooked_read(struct gameport *gameport, int *axes, int *buttons) { - struct l4 *l4 = gameport->driver; + struct l4 *l4 = gameport->port_data; unsigned char status; int i, result = -1; @@ -112,7 +112,7 @@ static int l4_open(struct gameport *gameport, int mode) { - struct l4 *l4 = gameport->driver; + struct l4 *l4 = gameport->port_data; if (l4->port != 0 && mode != GAMEPORT_MODE_COOKED) return -1; outb(L4_SELECT_ANALOG, L4_PORT); @@ -190,7 +190,7 @@ { int i, t; int cal[4]; - struct l4 *l4 = gameport->driver; + struct l4 *l4 = gameport->port_data; if (l4_getcal(l4->port, cal)) return -1; @@ -252,7 +252,7 @@ sprintf(l4->phys, "isa%04x/gameport%d", L4_PORT, 4 * i + j); gameport = &l4->gameport; - gameport->driver = l4; + gameport->port_data = l4; gameport->open = l4_open; gameport->cooked_read = l4_cooked_read; gameport->calibrate = l4_calibrate; diff -Nru a/drivers/input/gameport/vortex.c b/drivers/input/gameport/vortex.c --- a/drivers/input/gameport/vortex.c 2005-02-11 01:34:39 -05:00 +++ b/drivers/input/gameport/vortex.c 2005-02-11 01:34:39 -05:00 @@ -62,19 +62,19 @@ static unsigned char vortex_read(struct gameport *gameport) { - struct vortex *vortex = gameport->driver; + struct vortex *vortex = gameport->port_data; return readb(vortex->io + VORTEX_LEG); } static void vortex_trigger(struct gameport *gameport) { - struct vortex *vortex = gameport->driver; + struct vortex *vortex = gameport->port_data; writeb(0xff, vortex->io + VORTEX_LEG); } static int vortex_cooked_read(struct gameport *gameport, int *axes, int *buttons) { - struct vortex *vortex = gameport->driver; + struct vortex *vortex = gameport->port_data; int i; *buttons = (~readb(vortex->base + VORTEX_LEG) >> 4) & 0xf; @@ -89,7 +89,7 @@ static int vortex_open(struct gameport *gameport, int mode) { - struct vortex *vortex = gameport->driver; + struct vortex *vortex = gameport->port_data; switch (mode) { case GAMEPORT_MODE_COOKED: @@ -120,7 +120,7 @@ pci_set_drvdata(dev, vortex); - vortex->gameport.driver = vortex; + vortex->gameport.port_data = vortex; vortex->gameport.fuzz = 64; vortex->gameport.read = vortex_read; diff -Nru a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c --- a/drivers/input/joystick/a3d.c 2005-02-11 01:34:39 -05:00 +++ b/drivers/input/joystick/a3d.c 2005-02-11 01:34:39 -05:00 @@ -197,7 +197,7 @@ static int a3d_adc_cooked_read(struct gameport *gameport, int *axes, int *buttons) { - struct a3d *a3d = gameport->driver; + struct a3d *a3d = gameport->port_data; int i; for (i = 0; i < 4; i++) axes[i] = (a3d->axes[i] < 254) ? a3d->axes[i] : -1; @@ -212,7 +212,7 @@ static int a3d_adc_open(struct gameport *gameport, int mode) { - struct a3d *a3d = gameport->driver; + struct a3d *a3d = gameport->port_data; if (mode != GAMEPORT_MODE_COOKED) return -1; if (!a3d->used++) @@ -226,7 +226,7 @@ static void a3d_adc_close(struct gameport *gameport) { - struct a3d *a3d = gameport->driver; + struct a3d *a3d = gameport->port_data; if (!--a3d->used) del_timer(&a3d->timer); } @@ -336,7 +336,7 @@ a3d->dev.relbit[0] |= BIT(REL_X) | BIT(REL_Y); a3d->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE); - a3d->adc.driver = a3d; + a3d->adc.port_data = a3d; a3d->adc.open = a3d_adc_open; a3d->adc.close = a3d_adc_close; a3d->adc.cooked_read = a3d_adc_cooked_read; diff -Nru a/include/linux/gameport.h b/include/linux/gameport.h --- a/include/linux/gameport.h 2005-02-11 01:34:39 -05:00 +++ b/include/linux/gameport.h 2005-02-11 01:34:39 -05:00 @@ -17,8 +17,8 @@ struct gameport { - void *private; /* Private pointer for joystick drivers */ - void *driver; /* Private pointer for gameport drivers */ + void *private; /* Private pointer for joystick drivers */ + void *port_data; /* Private pointer for gameport drivers */ char *name; char *phys; diff -Nru a/sound/oss/trident.c b/sound/oss/trident.c --- a/sound/oss/trident.c 2005-02-11 01:34:39 -05:00 +++ b/sound/oss/trident.c 2005-02-11 01:34:39 -05:00 @@ -4257,21 +4257,21 @@ static unsigned char trident_game_read(struct gameport *gameport) { - struct trident_card *card = gameport->driver; + struct trident_card *card = gameport->port_data; return inb(TRID_REG(card, T4D_GAME_LEG)); } static void trident_game_trigger(struct gameport *gameport) { - struct trident_card *card = gameport->driver; + struct trident_card *card = gameport->port_data; outb(0xff, TRID_REG(card, T4D_GAME_LEG)); } static int trident_game_cooked_read(struct gameport *gameport, int *axes, int *buttons) { - struct trident_card *card = gameport->driver; + struct trident_card *card = gameport->port_data; int i; *buttons = (~inb(TRID_REG(card, T4D_GAME_LEG)) >> 4) & 0xf; @@ -4288,7 +4288,7 @@ static int trident_game_open(struct gameport *gameport, int mode) { - struct trident_card *card = gameport->driver; + struct trident_card *card = gameport->port_data; switch (mode) { case GAMEPORT_MODE_COOKED: @@ -4368,7 +4368,7 @@ card->banks[BANK_B].addresses = &bank_b_addrs; card->banks[BANK_B].bitmap = 0UL; - card->gameport.driver = card; + card->gameport.port_data = card; card->gameport.fuzz = 64; card->gameport.read = trident_game_read; card->gameport.trigger = trident_game_trigger; diff -Nru a/sound/pci/au88x0/au88x0_game.c b/sound/pci/au88x0/au88x0_game.c --- a/sound/pci/au88x0/au88x0_game.c 2005-02-11 01:34:39 -05:00 +++ b/sound/pci/au88x0/au88x0_game.c 2005-02-11 01:34:39 -05:00 @@ -44,20 +44,20 @@ static unsigned char vortex_game_read(struct gameport *gameport) { - vortex_t *vortex = gameport->driver; + vortex_t *vortex = gameport->port_data; return hwread(vortex->mmio, VORTEX_GAME_LEGACY); } static void vortex_game_trigger(struct gameport *gameport) { - vortex_t *vortex = gameport->driver; + vortex_t *vortex = gameport->port_data; hwwrite(vortex->mmio, VORTEX_GAME_LEGACY, 0xff); } static int vortex_game_cooked_read(struct gameport *gameport, int *axes, int *buttons) { - vortex_t *vortex = gameport->driver; + vortex_t *vortex = gameport->port_data; int i; *buttons = (~hwread(vortex->mmio, VORTEX_GAME_LEGACY) >> 4) & 0xf; @@ -73,7 +73,7 @@ static int vortex_game_open(struct gameport *gameport, int mode) { - vortex_t *vortex = gameport->driver; + vortex_t *vortex = gameport->port_data; switch (mode) { case GAMEPORT_MODE_COOKED: @@ -96,11 +96,10 @@ static int vortex_gameport_register(vortex_t * vortex) { - if ((vortex->gameport = kcalloc(1, sizeof(struct gameport), GFP_KERNEL)) == NULL) { + if ((vortex->gameport = kcalloc(1, sizeof(struct gameport), GFP_KERNEL)) == NULL) return -1; - }; - - vortex->gameport->driver = vortex; + + vortex->gameport->port_data = vortex; vortex->gameport->fuzz = 64; vortex->gameport->read = vortex_game_read; ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/10] Gameport: rename gameport_dev to gameport_driver 2005-02-11 6:59 ` [PATCH 1/10] Gameport: rename driver to port_data Dmitry Torokhov @ 2005-02-11 7:00 ` Dmitry Torokhov 2005-02-11 7:00 ` [PATCH 3/10] Gameport: connect() is mandatory Dmitry Torokhov 0 siblings, 1 reply; 12+ messages in thread From: Dmitry Torokhov @ 2005-02-11 7:00 UTC (permalink / raw) To: InputML; +Cc: alsa-devel, LKML, Vojtech Pavlik =================================================================== ChangeSet@1.2150, 2005-02-11 01:09:59-05:00, dtor_core@ameritech.net Input: more renames in gameport in preparations to sysfs integration - gameport_dev -> gameport_driver - gameport_[un]register_device -> gameport_[un]register_driver Signed-off-by: Dmitry Torokhov <dtor@mail.ru> drivers/input/gameport/gameport.c | 52 ++++++++++++++++++------------------ drivers/input/joystick/a3d.c | 10 +++--- drivers/input/joystick/adi.c | 10 +++--- drivers/input/joystick/analog.c | 18 ++++++------ drivers/input/joystick/cobra.c | 10 +++--- drivers/input/joystick/gf2k.c | 10 +++--- drivers/input/joystick/grip.c | 10 +++--- drivers/input/joystick/grip_mp.c | 10 +++--- drivers/input/joystick/guillemot.c | 10 +++--- drivers/input/joystick/interact.c | 10 +++--- drivers/input/joystick/joydump.c | 12 ++++---- drivers/input/joystick/sidewinder.c | 10 +++--- drivers/input/joystick/tmdc.c | 10 +++--- include/linux/gameport.h | 12 ++++---- 14 files changed, 97 insertions(+), 97 deletions(-) =================================================================== diff -Nru a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c --- a/drivers/input/gameport/gameport.c 2005-02-11 01:34:53 -05:00 +++ b/drivers/input/gameport/gameport.c 2005-02-11 01:34:53 -05:00 @@ -25,15 +25,15 @@ EXPORT_SYMBOL(gameport_register_port); EXPORT_SYMBOL(gameport_unregister_port); -EXPORT_SYMBOL(gameport_register_device); -EXPORT_SYMBOL(gameport_unregister_device); +EXPORT_SYMBOL(gameport_register_driver); +EXPORT_SYMBOL(gameport_unregister_driver); EXPORT_SYMBOL(gameport_open); EXPORT_SYMBOL(gameport_close); EXPORT_SYMBOL(gameport_rescan); EXPORT_SYMBOL(gameport_cooked_read); static LIST_HEAD(gameport_list); -static LIST_HEAD(gameport_dev_list); +static LIST_HEAD(gameport_driver_list); #ifdef __i386__ @@ -100,61 +100,61 @@ #endif } -static void gameport_find_dev(struct gameport *gameport) +static void gameport_find_driver(struct gameport *gameport) { - struct gameport_dev *dev; + struct gameport_driver *drv; - list_for_each_entry(dev, &gameport_dev_list, node) { - if (gameport->dev) + list_for_each_entry(drv, &gameport_driver_list, node) { + if (gameport->drv) break; - if (dev->connect) - dev->connect(gameport, dev); + if (drv->connect) + drv->connect(gameport, drv); } } void gameport_rescan(struct gameport *gameport) { gameport_close(gameport); - gameport_find_dev(gameport); + gameport_find_driver(gameport); } void gameport_register_port(struct gameport *gameport) { list_add_tail(&gameport->node, &gameport_list); gameport->speed = gameport_measure_speed(gameport); - gameport_find_dev(gameport); + gameport_find_driver(gameport); } void gameport_unregister_port(struct gameport *gameport) { list_del_init(&gameport->node); - if (gameport->dev && gameport->dev->disconnect) - gameport->dev->disconnect(gameport); + if (gameport->drv && gameport->drv->disconnect) + gameport->drv->disconnect(gameport); } -void gameport_register_device(struct gameport_dev *dev) +void gameport_register_driver(struct gameport_driver *drv) { struct gameport *gameport; - list_add_tail(&dev->node, &gameport_dev_list); + list_add_tail(&drv->node, &gameport_driver_list); list_for_each_entry(gameport, &gameport_list, node) - if (!gameport->dev && dev->connect) - dev->connect(gameport, dev); + if (!gameport->drv && drv->connect) + drv->connect(gameport, drv); } -void gameport_unregister_device(struct gameport_dev *dev) +void gameport_unregister_driver(struct gameport_driver *drv) { struct gameport *gameport; - list_del_init(&dev->node); + list_del_init(&drv->node); list_for_each_entry(gameport, &gameport_list, node) { - if (gameport->dev == dev && dev->disconnect) - dev->disconnect(gameport); - gameport_find_dev(gameport); + if (gameport->drv == drv && drv->disconnect) + drv->disconnect(gameport); + gameport_find_driver(gameport); } } -int gameport_open(struct gameport *gameport, struct gameport_dev *dev, int mode) +int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode) { if (gameport->open) { if (gameport->open(gameport, mode)) @@ -164,17 +164,17 @@ return -1; } - if (gameport->dev) + if (gameport->drv) return -1; - gameport->dev = dev; + gameport->drv = drv; return 0; } void gameport_close(struct gameport *gameport) { - gameport->dev = NULL; + gameport->drv = NULL; if (gameport->close) gameport->close(gameport); } diff -Nru a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c --- a/drivers/input/joystick/a3d.c 2005-02-11 01:34:53 -05:00 +++ b/drivers/input/joystick/a3d.c 2005-02-11 01:34:53 -05:00 @@ -258,7 +258,7 @@ * a3d_connect() probes for A3D joysticks. */ -static void a3d_connect(struct gameport *gameport, struct gameport_dev *dev) +static void a3d_connect(struct gameport *gameport, struct gameport_driver *drv) { struct a3d *a3d; unsigned char data[A3D_MAX_LENGTH]; @@ -275,7 +275,7 @@ a3d->timer.data = (long) a3d; a3d->timer.function = a3d_timer; - if (gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) + if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) goto fail1; i = a3d_read_packet(gameport, A3D_MAX_LENGTH, data); @@ -385,20 +385,20 @@ kfree(a3d); } -static struct gameport_dev a3d_dev = { +static struct gameport_driver a3d_drv = { .connect = a3d_connect, .disconnect = a3d_disconnect, }; static int __init a3d_init(void) { - gameport_register_device(&a3d_dev); + gameport_register_driver(&a3d_drv); return 0; } static void __exit a3d_exit(void) { - gameport_unregister_device(&a3d_dev); + gameport_unregister_driver(&a3d_drv); } module_init(a3d_init); diff -Nru a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c --- a/drivers/input/joystick/adi.c 2005-02-11 01:34:53 -05:00 +++ b/drivers/input/joystick/adi.c 2005-02-11 01:34:53 -05:00 @@ -475,7 +475,7 @@ * adi_connect() probes for Logitech ADI joysticks. */ -static void adi_connect(struct gameport *gameport, struct gameport_dev *dev) +static void adi_connect(struct gameport *gameport, struct gameport_driver *drv) { struct adi_port *port; int i; @@ -491,7 +491,7 @@ port->timer.data = (long) port; port->timer.function = adi_timer; - if (gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) { + if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) { kfree(port); return; } @@ -544,20 +544,20 @@ * The gameport device structure. */ -static struct gameport_dev adi_dev = { +static struct gameport_driver adi_drv = { .connect = adi_connect, .disconnect = adi_disconnect, }; static int __init adi_init(void) { - gameport_register_device(&adi_dev); + gameport_register_driver(&adi_drv); return 0; } static void __exit adi_exit(void) { - gameport_unregister_device(&adi_dev); + gameport_unregister_driver(&adi_drv); } module_init(adi_init); diff -Nru a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c --- a/drivers/input/joystick/analog.c 2005-02-11 01:34:53 -05:00 +++ b/drivers/input/joystick/analog.c 2005-02-11 01:34:53 -05:00 @@ -587,7 +587,7 @@ return -!(analog[0].mask || analog[1].mask); } -static int analog_init_port(struct gameport *gameport, struct gameport_dev *dev, struct analog_port *port) +static int analog_init_port(struct gameport *gameport, struct gameport_driver *drv, struct analog_port *port) { int i, t, u, v; @@ -597,7 +597,7 @@ port->timer.data = (long) port; port->timer.function = analog_timer; - if (!gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) { + if (!gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) { analog_calibrate_timer(port); @@ -632,7 +632,7 @@ gameport_close(gameport); } - if (!gameport_open(gameport, dev, GAMEPORT_MODE_COOKED)) { + if (!gameport_open(gameport, drv, GAMEPORT_MODE_COOKED)) { for (i = 0; i < ANALOG_INIT_RETRIES; i++) if (!gameport_cooked_read(gameport, port->axes, &port->buttons)) @@ -645,13 +645,13 @@ return 0; } - if (!gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) + if (!gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) return 0; return -1; } -static void analog_connect(struct gameport *gameport, struct gameport_dev *dev) +static void analog_connect(struct gameport *gameport, struct gameport_driver *drv) { struct analog_port *port; int i; @@ -660,7 +660,7 @@ return; memset(port, 0, sizeof(struct analog_port)); - if (analog_init_port(gameport, dev, port)) { + if (analog_init_port(gameport, drv, port)) { kfree(port); return; } @@ -741,7 +741,7 @@ * The gameport device structure. */ -static struct gameport_dev analog_dev = { +static struct gameport_driver analog_drv = { .connect = analog_connect, .disconnect = analog_disconnect, }; @@ -749,13 +749,13 @@ static int __init analog_init(void) { analog_parse_options(); - gameport_register_device(&analog_dev); + gameport_register_driver(&analog_drv); return 0; } static void __exit analog_exit(void) { - gameport_unregister_device(&analog_dev); + gameport_unregister_driver(&analog_drv); } module_init(analog_init); diff -Nru a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c --- a/drivers/input/joystick/cobra.c 2005-02-11 01:34:53 -05:00 +++ b/drivers/input/joystick/cobra.c 2005-02-11 01:34:53 -05:00 @@ -158,7 +158,7 @@ del_timer(&cobra->timer); } -static void cobra_connect(struct gameport *gameport, struct gameport_dev *dev) +static void cobra_connect(struct gameport *gameport, struct gameport_driver *drv) { struct cobra *cobra; unsigned int data[2]; @@ -175,7 +175,7 @@ cobra->timer.data = (long) cobra; cobra->timer.function = cobra_timer; - if (gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) + if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) goto fail1; cobra->exists = cobra_read_packet(gameport, data); @@ -236,20 +236,20 @@ kfree(cobra); } -static struct gameport_dev cobra_dev = { +static struct gameport_driver cobra_drv = { .connect = cobra_connect, .disconnect = cobra_disconnect, }; static int __init cobra_init(void) { - gameport_register_device(&cobra_dev); + gameport_register_driver(&cobra_drv); return 0; } static void __exit cobra_exit(void) { - gameport_unregister_device(&cobra_dev); + gameport_unregister_driver(&cobra_drv); } module_init(cobra_init); diff -Nru a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c --- a/drivers/input/joystick/gf2k.c 2005-02-11 01:34:53 -05:00 +++ b/drivers/input/joystick/gf2k.c 2005-02-11 01:34:53 -05:00 @@ -238,7 +238,7 @@ * gf2k_connect() probes for Genius id joysticks. */ -static void gf2k_connect(struct gameport *gameport, struct gameport_dev *dev) +static void gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) { struct gf2k *gf2k; unsigned char data[GF2K_LENGTH]; @@ -255,7 +255,7 @@ gf2k->timer.data = (long) gf2k; gf2k->timer.function = gf2k_timer; - if (gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) + if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) goto fail1; gf2k_trigger_seq(gameport, gf2k_seq_reset); @@ -346,20 +346,20 @@ kfree(gf2k); } -static struct gameport_dev gf2k_dev = { +static struct gameport_driver gf2k_drv = { .connect = gf2k_connect, .disconnect = gf2k_disconnect, }; static int __init gf2k_init(void) { - gameport_register_device(&gf2k_dev); + gameport_register_driver(&gf2k_drv); return 0; } static void __exit gf2k_exit(void) { - gameport_unregister_device(&gf2k_dev); + gameport_unregister_driver(&gf2k_drv); } module_init(gf2k_init); diff -Nru a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c --- a/drivers/input/joystick/grip.c 2005-02-11 01:34:53 -05:00 +++ b/drivers/input/joystick/grip.c 2005-02-11 01:34:53 -05:00 @@ -298,7 +298,7 @@ del_timer(&grip->timer); } -static void grip_connect(struct gameport *gameport, struct gameport_dev *dev) +static void grip_connect(struct gameport *gameport, struct gameport_driver *drv) { struct grip *grip; unsigned int data[GRIP_LENGTH_XT]; @@ -315,7 +315,7 @@ grip->timer.data = (long) grip; grip->timer.function = grip_timer; - if (gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) + if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) goto fail1; for (i = 0; i < 2; i++) { @@ -409,20 +409,20 @@ kfree(grip); } -static struct gameport_dev grip_dev = { +static struct gameport_driver grip_drv = { .connect = grip_connect, .disconnect = grip_disconnect, }; static int __init grip_init(void) { - gameport_register_device(&grip_dev); + gameport_register_driver(&grip_drv); return 0; } static void __exit grip_exit(void) { - gameport_unregister_device(&grip_dev); + gameport_unregister_driver(&grip_drv); } module_init(grip_init); diff -Nru a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c --- a/drivers/input/joystick/grip_mp.c 2005-02-11 01:34:53 -05:00 +++ b/drivers/input/joystick/grip_mp.c 2005-02-11 01:34:53 -05:00 @@ -616,7 +616,7 @@ mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME); } -static void grip_connect(struct gameport *gameport, struct gameport_dev *dev) +static void grip_connect(struct gameport *gameport, struct gameport_driver *drv) { struct grip_mp *grip; @@ -629,7 +629,7 @@ grip->timer.data = (long) grip; grip->timer.function = grip_timer; - if (gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) + if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) goto fail1; if (!multiport_init(grip)) goto fail2; @@ -654,20 +654,20 @@ kfree(grip); } -static struct gameport_dev grip_dev = { +static struct gameport_driver grip_drv = { .connect = grip_connect, .disconnect = grip_disconnect, }; static int grip_init(void) { - gameport_register_device(&grip_dev); + gameport_register_driver(&grip_drv); return 0; } static void grip_exit(void) { - gameport_unregister_device(&grip_dev); + gameport_unregister_driver(&grip_drv); } module_init(grip_init); diff -Nru a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c --- a/drivers/input/joystick/guillemot.c 2005-02-11 01:34:53 -05:00 +++ b/drivers/input/joystick/guillemot.c 2005-02-11 01:34:53 -05:00 @@ -179,7 +179,7 @@ * guillemot_connect() probes for Guillemot joysticks. */ -static void guillemot_connect(struct gameport *gameport, struct gameport_dev *dev) +static void guillemot_connect(struct gameport *gameport, struct gameport_driver *drv) { struct guillemot *guillemot; u8 data[GUILLEMOT_MAX_LENGTH]; @@ -196,7 +196,7 @@ guillemot->timer.data = (long) guillemot; guillemot->timer.function = guillemot_timer; - if (gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) + if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) goto fail1; i = guillemot_read_packet(gameport, data); @@ -266,20 +266,20 @@ kfree(guillemot); } -static struct gameport_dev guillemot_dev = { +static struct gameport_driver guillemot_drv = { .connect = guillemot_connect, .disconnect = guillemot_disconnect, }; static int __init guillemot_init(void) { - gameport_register_device(&guillemot_dev); + gameport_register_driver(&guillemot_drv); return 0; } static void __exit guillemot_exit(void) { - gameport_unregister_device(&guillemot_dev); + gameport_unregister_driver(&guillemot_drv); } module_init(guillemot_init); diff -Nru a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c --- a/drivers/input/joystick/interact.c 2005-02-11 01:34:53 -05:00 +++ b/drivers/input/joystick/interact.c 2005-02-11 01:34:53 -05:00 @@ -209,7 +209,7 @@ * interact_connect() probes for InterAct joysticks. */ -static void interact_connect(struct gameport *gameport, struct gameport_dev *dev) +static void interact_connect(struct gameport *gameport, struct gameport_driver *drv) { struct interact *interact; __u32 data[3]; @@ -226,7 +226,7 @@ interact->timer.data = (long) interact; interact->timer.function = interact_timer; - if (gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) + if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) goto fail1; i = interact_read_packet(gameport, INTERACT_MAX_LENGTH * 2, data); @@ -294,20 +294,20 @@ kfree(interact); } -static struct gameport_dev interact_dev = { +static struct gameport_driver interact_drv = { .connect = interact_connect, .disconnect = interact_disconnect, }; static int __init interact_init(void) { - gameport_register_device(&interact_dev); + gameport_register_driver(&interact_drv); return 0; } static void __exit interact_exit(void) { - gameport_unregister_device(&interact_dev); + gameport_unregister_driver(&interact_drv); } module_init(interact_init); diff -Nru a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c --- a/drivers/input/joystick/joydump.c 2005-02-11 01:34:53 -05:00 +++ b/drivers/input/joystick/joydump.c 2005-02-11 01:34:53 -05:00 @@ -46,7 +46,7 @@ unsigned char data; }; -static void __devinit joydump_connect(struct gameport *gameport, struct gameport_dev *dev) +static void __devinit joydump_connect(struct gameport *gameport, struct gameport_driver *drv) { struct joydump *buf; /* all entries */ struct joydump *dump, *prev; /* one entry each */ @@ -59,11 +59,11 @@ printk(KERN_INFO "joydump: | Dumping gameport%s.\n", gameport->phys); printk(KERN_INFO "joydump: | Speed: %4d kHz. |\n", gameport->speed); - if (gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) { + if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) { printk(KERN_INFO "joydump: | Raw mode not available - trying cooked. |\n"); - if (gameport_open(gameport, dev, GAMEPORT_MODE_COOKED)) { + if (gameport_open(gameport, drv, GAMEPORT_MODE_COOKED)) { printk(KERN_INFO "joydump: | Cooked not available either. Failing. |\n"); printk(KERN_INFO "joydump: `-------------------- END -------------------'\n"); @@ -147,20 +147,20 @@ gameport_close(gameport); } -static struct gameport_dev joydump_dev = { +static struct gameport_driver joydump_drv = { .connect = joydump_connect, .disconnect = joydump_disconnect, }; static int __init joydump_init(void) { - gameport_register_device(&joydump_dev); + gameport_register_driver(&joydump_drv); return 0; } static void __exit joydump_exit(void) { - gameport_unregister_device(&joydump_dev); + gameport_unregister_driver(&joydump_drv); } module_init(joydump_init); diff -Nru a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c --- a/drivers/input/joystick/sidewinder.c 2005-02-11 01:34:53 -05:00 +++ b/drivers/input/joystick/sidewinder.c 2005-02-11 01:34:53 -05:00 @@ -569,7 +569,7 @@ * sw_connect() probes for SideWinder type joysticks. */ -static void sw_connect(struct gameport *gameport, struct gameport_dev *dev) +static void sw_connect(struct gameport *gameport, struct gameport_driver *drv) { struct sw *sw; int i, j, k, l; @@ -595,7 +595,7 @@ sw->timer.data = (long) sw; sw->timer.function = sw_timer; - if (gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) + if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) goto fail1; dbg("Init 0: Opened %s, io %#x, speed %d", @@ -760,20 +760,20 @@ kfree(sw); } -static struct gameport_dev sw_dev = { +static struct gameport_driver sw_drv = { .connect = sw_connect, .disconnect = sw_disconnect, }; static int __init sw_init(void) { - gameport_register_device(&sw_dev); + gameport_register_driver(&sw_drv); return 0; } static void __exit sw_exit(void) { - gameport_unregister_device(&sw_dev); + gameport_unregister_driver(&sw_drv); } module_init(sw_init); diff -Nru a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c --- a/drivers/input/joystick/tmdc.c 2005-02-11 01:34:53 -05:00 +++ b/drivers/input/joystick/tmdc.c 2005-02-11 01:34:53 -05:00 @@ -242,7 +242,7 @@ * tmdc_probe() probes for ThrustMaster type joysticks. */ -static void tmdc_connect(struct gameport *gameport, struct gameport_dev *dev) +static void tmdc_connect(struct gameport *gameport, struct gameport_driver *drv) { struct models { unsigned char id; @@ -275,7 +275,7 @@ tmdc->timer.data = (long) tmdc; tmdc->timer.function = tmdc_timer; - if (gameport_open(gameport, dev, GAMEPORT_MODE_RAW)) + if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) goto fail1; if (!(tmdc->exists = tmdc_read_packet(gameport, data))) @@ -362,20 +362,20 @@ kfree(tmdc); } -static struct gameport_dev tmdc_dev = { +static struct gameport_driver tmdc_drv = { .connect = tmdc_connect, .disconnect = tmdc_disconnect, }; static int __init tmdc_init(void) { - gameport_register_device(&tmdc_dev); + gameport_register_driver(&tmdc_drv); return 0; } static void __exit tmdc_exit(void) { - gameport_unregister_device(&tmdc_dev); + gameport_unregister_driver(&tmdc_drv); } module_init(tmdc_init); diff -Nru a/include/linux/gameport.h b/include/linux/gameport.h --- a/include/linux/gameport.h 2005-02-11 01:34:53 -05:00 +++ b/include/linux/gameport.h 2005-02-11 01:34:53 -05:00 @@ -35,23 +35,23 @@ int (*open)(struct gameport *, int); void (*close)(struct gameport *); - struct gameport_dev *dev; + struct gameport_driver *drv; struct list_head node; }; -struct gameport_dev { +struct gameport_driver { void *private; char *name; - void (*connect)(struct gameport *, struct gameport_dev *dev); + void (*connect)(struct gameport *, struct gameport_driver *drv); void (*disconnect)(struct gameport *); struct list_head node; }; -int gameport_open(struct gameport *gameport, struct gameport_dev *dev, int mode); +int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode); void gameport_close(struct gameport *gameport); void gameport_rescan(struct gameport *gameport); @@ -63,8 +63,8 @@ static inline void gameport_unregister_port(struct gameport *gameport) { return; } #endif -void gameport_register_device(struct gameport_dev *dev); -void gameport_unregister_device(struct gameport_dev *dev); +void gameport_register_driver(struct gameport_driver *drv); +void gameport_unregister_driver(struct gameport_driver *drv); #define GAMEPORT_MODE_DISABLED 0 #define GAMEPORT_MODE_RAW 1 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 3/10] Gameport: connect() is mandatory 2005-02-11 7:00 ` [PATCH 2/10] Gameport: rename gameport_dev to gameport_driver Dmitry Torokhov @ 2005-02-11 7:00 ` Dmitry Torokhov 2005-02-11 7:01 ` [PATCH 4/10] Gameport: prepare to dynamic allocation Dmitry Torokhov 0 siblings, 1 reply; 12+ messages in thread From: Dmitry Torokhov @ 2005-02-11 7:00 UTC (permalink / raw) To: InputML; +Cc: alsa-devel, LKML, Vojtech Pavlik =================================================================== ChangeSet@1.2151, 2005-02-11 01:18:29-05:00, dtor_core@ameritech.net Input: make connect and disconnect methods mandatory for gameport drivers since that's where gameport_{open|close} are called from to actually bind driver to a port. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> gameport.c | 9 ++++----- 1 files changed, 4 insertions(+), 5 deletions(-) =================================================================== diff -Nru a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c --- a/drivers/input/gameport/gameport.c 2005-02-11 01:35:40 -05:00 +++ b/drivers/input/gameport/gameport.c 2005-02-11 01:35:40 -05:00 @@ -107,8 +107,7 @@ list_for_each_entry(drv, &gameport_driver_list, node) { if (gameport->drv) break; - if (drv->connect) - drv->connect(gameport, drv); + drv->connect(gameport, drv); } } @@ -128,7 +127,7 @@ void gameport_unregister_port(struct gameport *gameport) { list_del_init(&gameport->node); - if (gameport->drv && gameport->drv->disconnect) + if (gameport->drv) gameport->drv->disconnect(gameport); } @@ -138,7 +137,7 @@ list_add_tail(&drv->node, &gameport_driver_list); list_for_each_entry(gameport, &gameport_list, node) - if (!gameport->drv && drv->connect) + if (!gameport->drv) drv->connect(gameport, drv); } @@ -148,7 +147,7 @@ list_del_init(&drv->node); list_for_each_entry(gameport, &gameport_list, node) { - if (gameport->drv == drv && drv->disconnect) + if (gameport->drv == drv) drv->disconnect(gameport); gameport_find_driver(gameport); } ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 4/10] Gameport: prepare to dynamic allocation 2005-02-11 7:00 ` [PATCH 3/10] Gameport: connect() is mandatory Dmitry Torokhov @ 2005-02-11 7:01 ` Dmitry Torokhov 2005-02-11 7:02 ` [PATCH 5/10] Gameport: convert input/gameport " Dmitry Torokhov 0 siblings, 1 reply; 12+ messages in thread From: Dmitry Torokhov @ 2005-02-11 7:01 UTC (permalink / raw) To: InputML; +Cc: alsa-devel, LKML, Vojtech Pavlik =================================================================== ChangeSet@1.2152, 2005-02-11 01:18:48-05:00, dtor_core@ameritech.net Input: prepare for dynamic gameport allocation: - provide functions to allocate and free gameports; - provide functions to properly set name and phys; - dynamically allocated gameports are automatically announced in kernel logs and freed when unregistered. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> drivers/input/gameport/gameport.c | 24 ++++++++++++++++++++++++ include/linux/gameport.h | 38 +++++++++++++++++++++++++++++++------- 2 files changed, 55 insertions(+), 7 deletions(-) =================================================================== diff -Nru a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c --- a/drivers/input/gameport/gameport.c 2005-02-11 01:36:13 -05:00 +++ b/drivers/input/gameport/gameport.c 2005-02-11 01:36:13 -05:00 @@ -31,6 +31,8 @@ EXPORT_SYMBOL(gameport_close); EXPORT_SYMBOL(gameport_rescan); EXPORT_SYMBOL(gameport_cooked_read); +EXPORT_SYMBOL(gameport_set_name); +EXPORT_SYMBOL(gameport_set_phys); static LIST_HEAD(gameport_list); static LIST_HEAD(gameport_driver_list); @@ -117,10 +119,30 @@ gameport_find_driver(gameport); } +void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + gameport->phys = gameport->phys_buf; + vsnprintf(gameport->phys_buf, sizeof(gameport->phys_buf), fmt, args); + va_end(args); +} + void gameport_register_port(struct gameport *gameport) { list_add_tail(&gameport->node, &gameport_list); gameport->speed = gameport_measure_speed(gameport); + + if (gameport->dyn_alloc) { + if (gameport->io) + printk(KERN_INFO "gameport: %s is %s, io %#x, speed %d kHz\n", + gameport->name, gameport->phys, gameport->io, gameport->speed); + else + printk(KERN_INFO "gameport: %s is %s, speed %d kHz\n", + gameport->name, gameport->phys, gameport->speed); + } + gameport_find_driver(gameport); } @@ -129,6 +151,8 @@ list_del_init(&gameport->node); if (gameport->drv) gameport->drv->disconnect(gameport); + if (gameport->dyn_alloc) + kfree(gameport); } void gameport_register_driver(struct gameport_driver *drv) diff -Nru a/include/linux/gameport.h b/include/linux/gameport.h --- a/include/linux/gameport.h 2005-02-11 01:36:13 -05:00 +++ b/include/linux/gameport.h 2005-02-11 01:36:13 -05:00 @@ -12,15 +12,16 @@ #include <asm/io.h> #include <linux/input.h> #include <linux/list.h> - -struct gameport; +#include <linux/device.h> struct gameport { void *private; /* Private pointer for joystick drivers */ void *port_data; /* Private pointer for gameport drivers */ char *name; + char name_buf[32]; char *phys; + char phys_buf[32]; struct input_id id; @@ -36,8 +37,12 @@ void (*close)(struct gameport *); struct gameport_driver *drv; + struct device dev; struct list_head node; + + /* temporary, till sysfs transition is complete */ + int dyn_alloc; }; struct gameport_driver { @@ -55,13 +60,32 @@ void gameport_close(struct gameport *gameport); void gameport_rescan(struct gameport *gameport); -#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) +static inline struct gameport *gameport_allocate_port(void) +{ + struct gameport *gameport = kcalloc(1, sizeof(struct gameport), GFP_KERNEL); + + if (gameport) + gameport->dyn_alloc = 1; + + return gameport; +} + +static inline void gameport_free_port(struct gameport *gameport) +{ + kfree(gameport); +} + +static inline void gameport_set_name(struct gameport *gameport, const char *name) +{ + gameport->name = gameport->name_buf; + strlcpy(gameport->name, name, sizeof(gameport->name_buf)); +} + +void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))); + void gameport_register_port(struct gameport *gameport); void gameport_unregister_port(struct gameport *gameport); -#else -static inline void gameport_register_port(struct gameport *gameport) { return; } -static inline void gameport_unregister_port(struct gameport *gameport) { return; } -#endif void gameport_register_driver(struct gameport_driver *drv); void gameport_unregister_driver(struct gameport_driver *drv); ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 5/10] Gameport: convert input/gameport to dynamic allocation 2005-02-11 7:01 ` [PATCH 4/10] Gameport: prepare to dynamic allocation Dmitry Torokhov @ 2005-02-11 7:02 ` Dmitry Torokhov 2005-02-11 7:02 ` [PATCH 6/10] Gameport: convert sound/oss " Dmitry Torokhov 0 siblings, 1 reply; 12+ messages in thread From: Dmitry Torokhov @ 2005-02-11 7:02 UTC (permalink / raw) To: InputML; +Cc: alsa-devel, LKML, Vojtech Pavlik =================================================================== ChangeSet@1.2153, 2005-02-11 01:19:36-05:00, dtor_core@ameritech.net Input: convert input/gameport to dynamic gameport allocation. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> drivers/input/gameport/cs461x.c | 29 +---- drivers/input/gameport/emu10k1-gp.c | 40 ++++---- drivers/input/gameport/fm801-gp.c | 57 +++++------ drivers/input/gameport/lightning.c | 176 ++++++++++++++++++++++-------------- drivers/input/gameport/ns558.c | 120 +++++++++++------------- drivers/input/gameport/vortex.c | 68 ++++++------- drivers/input/joystick/a3d.c | 59 +++++------- include/linux/gameport.h | 3 8 files changed, 286 insertions(+), 266 deletions(-) =================================================================== diff -Nru a/drivers/input/gameport/cs461x.c b/drivers/input/gameport/cs461x.c --- a/drivers/input/gameport/cs461x.c 2005-02-11 01:38:07 -05:00 +++ b/drivers/input/gameport/cs461x.c 2005-02-11 01:38:07 -05:00 @@ -120,9 +120,6 @@ static unsigned long ba0_addr; static unsigned int __iomem *ba0; -static char phys[32]; -static char name[] = "CS416x Gameport"; - #ifdef CS461X_FULL_MAP static unsigned long ba1_addr; static union ba1_t { @@ -160,10 +157,10 @@ static int cs461x_free(struct pci_dev *pdev) { struct gameport *port = pci_get_drvdata(pdev); - if(port){ + + if (port) gameport_unregister_port(port); - kfree(port); - } + if (ba0) iounmap(ba0); #ifdef CS461X_FULL_MAP if (ba1.name.data0) iounmap(ba1.name.data0); @@ -267,18 +264,17 @@ return -ENOMEM; } #else - if (ba0 == NULL){ + if (ba0 == NULL) { cs461x_free(pdev); return -ENOMEM; } #endif - if (!(port = kmalloc(sizeof(struct gameport), GFP_KERNEL))) { - printk(KERN_ERR "Memory allocation failed.\n"); + if (!(port = gameport_allocate_port())) { + printk(KERN_ERR "cs461x: Memory allocation failed\n"); cs461x_free(pdev); return -ENOMEM; } - memset(port, 0, sizeof(struct gameport)); pci_set_drvdata(pdev, port); @@ -287,21 +283,14 @@ port->read = cs461x_gameport_read; port->cooked_read = cs461x_gameport_cooked_read; - sprintf(phys, "pci%s/gameport0", pci_name(pdev)); - - port->name = name; - port->phys = phys; - port->id.bustype = BUS_PCI; - port->id.vendor = pdev->vendor; - port->id.product = pdev->device; + gameport_set_name(port, "CS416x"); + gameport_set_phys(port, "pci%s/gameport0", pci_name(pdev)); + port->dev.parent = &pdev->dev; cs461x_pokeBA0(BA0_JSIO, 0xFF); // ? cs461x_pokeBA0(BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW); gameport_register_port(port); - - printk(KERN_INFO "gameport: %s on pci%s speed %d kHz\n", - name, pci_name(pdev), port->speed); return 0; } diff -Nru a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c --- a/drivers/input/gameport/emu10k1-gp.c 2005-02-11 01:38:07 -05:00 +++ b/drivers/input/gameport/emu10k1-gp.c 2005-02-11 01:38:07 -05:00 @@ -44,13 +44,13 @@ struct emu { struct pci_dev *dev; - struct gameport gameport; + struct gameport *gameport; + int io; int size; - char phys[32]; }; static struct pci_device_id emu_tbl[] = { - + { 0x1102, 0x7002, PCI_ANY_ID, PCI_ANY_ID }, /* SB Live gameport */ { 0x1102, 0x7003, PCI_ANY_ID, PCI_ANY_ID }, /* Audigy gameport */ { 0x1102, 0x7004, PCI_ANY_ID, PCI_ANY_ID }, /* Dell SB Live */ @@ -64,6 +64,7 @@ { int ioport, iolen; struct emu *emu; + struct gameport *port; if (pci_enable_device(pdev)) return -EBUSY; @@ -74,31 +75,29 @@ if (!request_region(ioport, iolen, "emu10k1-gp")) return -EBUSY; - if (!(emu = kmalloc(sizeof(struct emu), GFP_KERNEL))) { - printk(KERN_ERR "emu10k1-gp: Memory allocation failed.\n"); + emu = kcalloc(1, sizeof(struct emu), GFP_KERNEL); + port = gameport_allocate_port(); + if (!emu || !port) { + printk(KERN_ERR "emu10k1-gp: Memory allocation failed\n"); release_region(ioport, iolen); + kfree(emu); + gameport_free_port(port); return -ENOMEM; } - memset(emu, 0, sizeof(struct emu)); - - sprintf(emu->phys, "pci%s/gameport0", pci_name(pdev)); + emu->io = ioport; emu->size = iolen; emu->dev = pdev; + emu->gameport = port; - emu->gameport.io = ioport; - emu->gameport.name = pci_name(pdev); - emu->gameport.phys = emu->phys; - emu->gameport.id.bustype = BUS_PCI; - emu->gameport.id.vendor = pdev->vendor; - emu->gameport.id.product = pdev->device; + gameport_set_name(port, "EMU10K1"); + gameport_set_phys(port, "pci%s/gameport0", pci_name(pdev)); + port->dev.parent = &pdev->dev; + port->io = ioport; pci_set_drvdata(pdev, emu); - gameport_register_port(&emu->gameport); - - printk(KERN_INFO "gameport: pci%s speed %d kHz\n", - pci_name(pdev), emu->gameport.speed); + gameport_register_port(port); return 0; } @@ -106,8 +105,9 @@ static void __devexit emu_remove(struct pci_dev *pdev) { struct emu *emu = pci_get_drvdata(pdev); - gameport_unregister_port(&emu->gameport); - release_region(emu->gameport.io, emu->size); + + gameport_unregister_port(emu->gameport); + release_region(emu->io, emu->size); kfree(emu); } diff -Nru a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c --- a/drivers/input/gameport/fm801-gp.c 2005-02-11 01:38:07 -05:00 +++ b/drivers/input/gameport/fm801-gp.c 2005-02-11 01:38:07 -05:00 @@ -37,10 +37,8 @@ #define HAVE_COOKED struct fm801_gp { - struct gameport gameport; + struct gameport *gameport; struct resource *res_port; - char phys[32]; - char name[32]; }; #ifdef HAVE_COOKED @@ -83,40 +81,42 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device_id *id) { struct fm801_gp *gp; + struct gameport *port; - if (! (gp = kmalloc(sizeof(*gp), GFP_KERNEL))) { - printk("cannot malloc for fm801-gp\n"); - return -1; + gp = kcalloc(1, sizeof(struct fm801_gp), GFP_KERNEL); + port = gameport_allocate_port(); + if (!gp || !port) { + printk(KERN_ERR "fm801-gp: Memory allocation failed\n"); + kfree(gp); + gameport_free_port(port); + return -ENOMEM; } - memset(gp, 0, sizeof(*gp)); - gp->gameport.open = fm801_gp_open; + pci_enable_device(pci); + + port->open = fm801_gp_open; #ifdef HAVE_COOKED - gp->gameport.cooked_read = fm801_gp_cooked_read; + port->cooked_read = fm801_gp_cooked_read; #endif - - pci_enable_device(pci); - gp->gameport.io = pci_resource_start(pci, 0); - if ((gp->res_port = request_region(gp->gameport.io, 0x10, "FM801 GP")) == NULL) { - printk("unable to grab region 0x%x-0x%x\n", gp->gameport.io, gp->gameport.io + 0x0f); + gameport_set_name(port, "FM801"); + gameport_set_phys(port, "pci%s/gameport0", pci_name(pci)); + port->dev.parent = &pci->dev; + port->io = pci_resource_start(pci, 0); + + gp->gameport = port; + gp->res_port = request_region(port->io, 0x10, "FM801 GP"); + if (!gp->res_port) { kfree(gp); - return -1; + gameport_free_port(port); + printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n", + port->io, port->io + 0x0f); + return -EBUSY; } - gp->gameport.phys = gp->phys; - gp->gameport.name = gp->name; - gp->gameport.id.bustype = BUS_PCI; - gp->gameport.id.vendor = pci->vendor; - gp->gameport.id.product = pci->device; - pci_set_drvdata(pci, gp); - outb(0x60, gp->gameport.io + 0x0d); /* enable joystick 1 and 2 */ - - gameport_register_port(&gp->gameport); - - printk(KERN_INFO "gameport: at pci%s speed %d kHz\n", - pci_name(pci), gp->gameport.speed); + outb(0x60, port->io + 0x0d); /* enable joystick 1 and 2 */ + gameport_register_port(port); return 0; } @@ -124,8 +124,9 @@ static void __devexit fm801_gp_remove(struct pci_dev *pci) { struct fm801_gp *gp = pci_get_drvdata(pci); + if (gp) { - gameport_unregister_port(&gp->gameport); + gameport_unregister_port(gp->gameport); release_resource(gp->res_port); kfree(gp); } diff -Nru a/drivers/input/gameport/lightning.c b/drivers/input/gameport/lightning.c --- a/drivers/input/gameport/lightning.c 2005-02-11 01:38:07 -05:00 +++ b/drivers/input/gameport/lightning.c 2005-02-11 01:38:07 -05:00 @@ -53,13 +53,12 @@ MODULE_DESCRIPTION("PDPI Lightning 4 gamecard driver"); MODULE_LICENSE("GPL"); -static struct l4 { - struct gameport gameport; +struct l4 { + struct gameport *gameport; unsigned char port; - char phys[32]; -} *l4_port[8]; +}; -static char l4_name[] = "PDPI Lightning 4"; +static struct l4 l4_ports[8]; /* * l4_wait_ready() waits for the L4 to become ready. @@ -67,10 +66,10 @@ static int l4_wait_ready(void) { - unsigned int t; - t = L4_TIMEOUT; + unsigned int t = L4_TIMEOUT; + while ((inb(L4_PORT) & L4_BUSY) && t > 0) t--; - return -(t<=0); + return -(t <= 0); } /* @@ -113,6 +112,7 @@ static int l4_open(struct gameport *gameport, int mode) { struct l4 *l4 = gameport->port_data; + if (l4->port != 0 && mode != GAMEPORT_MODE_COOKED) return -1; outb(L4_SELECT_ANALOG, L4_PORT); @@ -129,24 +129,29 @@ outb(L4_SELECT_ANALOG, L4_PORT); outb(L4_SELECT_DIGITAL + (port >> 2), L4_PORT); + if (inb(L4_PORT) & L4_BUSY) + goto out; - if (inb(L4_PORT) & L4_BUSY) goto fail; outb(L4_CMD_GETCAL, L4_PORT); + if (l4_wait_ready()) + goto out; - if (l4_wait_ready()) goto fail; - if (inb(L4_PORT) != L4_SELECT_DIGITAL + (port >> 2)) goto fail; + if (inb(L4_PORT) != L4_SELECT_DIGITAL + (port >> 2)) + goto out; - if (l4_wait_ready()) goto fail; + if (l4_wait_ready()) + goto out; outb(port & 3, L4_PORT); for (i = 0; i < 4; i++) { - if (l4_wait_ready()) goto fail; + if (l4_wait_ready()) + goto out; cal[i] = inb(L4_PORT); } result = 0; -fail: outb(L4_SELECT_ANALOG, L4_PORT); +out: outb(L4_SELECT_ANALOG, L4_PORT); return result; } @@ -160,24 +165,29 @@ outb(L4_SELECT_ANALOG, L4_PORT); outb(L4_SELECT_DIGITAL + (port >> 2), L4_PORT); + if (inb(L4_PORT) & L4_BUSY) + goto out; - if (inb(L4_PORT) & L4_BUSY) goto fail; outb(L4_CMD_SETCAL, L4_PORT); + if (l4_wait_ready()) + goto out; - if (l4_wait_ready()) goto fail; - if (inb(L4_PORT) != L4_SELECT_DIGITAL + (port >> 2)) goto fail; + if (inb(L4_PORT) != L4_SELECT_DIGITAL + (port >> 2)) + goto out; - if (l4_wait_ready()) goto fail; + if (l4_wait_ready()) + goto out; outb(port & 3, L4_PORT); for (i = 0; i < 4; i++) { - if (l4_wait_ready()) goto fail; + if (l4_wait_ready()) + goto out; outb(cal[i], L4_PORT); } result = 0; -fail: outb(L4_SELECT_ANALOG, L4_PORT); +out: outb(L4_SELECT_ANALOG, L4_PORT); return result; } @@ -209,73 +219,102 @@ return 0; } -static int __init l4_init(void) +static int __init l4_create_ports(int card_no) { - int cal[4] = {255,255,255,255}; - int i, j, rev, cards = 0; - struct gameport *gameport; struct l4 *l4; + struct gameport *port; + int i, idx; - if (!request_region(L4_PORT, 1, "lightning")) - return -1; + for (i = 0; i < 4; i++) { - for (i = 0; i < 2; i++) { + idx = card_no * 4 + i; + l4 = &l4_ports[idx]; - outb(L4_SELECT_ANALOG, L4_PORT); - outb(L4_SELECT_DIGITAL + i, L4_PORT); + if (!(l4->gameport = port = gameport_allocate_port())) { + printk(KERN_ERR "lightning: Memory allocation failed\n"); + while (--i >= 0) { + gameport_free_port(l4->gameport); + l4->gameport = NULL; + } + return -ENOMEM; + } + l4->port = idx; - if (inb(L4_PORT) & L4_BUSY) continue; - outb(L4_CMD_ID, L4_PORT); + port->port_data = l4; + port->open = l4_open; + port->cooked_read = l4_cooked_read; + port->calibrate = l4_calibrate; - if (l4_wait_ready()) continue; - if (inb(L4_PORT) != L4_SELECT_DIGITAL + i) continue; + gameport_set_name(port, "PDPI Lightning 4"); + gameport_set_phys(port, "isa%04x/gameport%d", L4_PORT, idx); - if (l4_wait_ready()) continue; - if (inb(L4_PORT) != L4_ID) continue; + if (idx == 0) + port->io = L4_PORT; + } - if (l4_wait_ready()) continue; - rev = inb(L4_PORT); + return 0; +} - if (!rev) continue; +static int __init l4_add_card(int card_no) +{ + int cal[4] = { 255, 255, 255, 255 }; + int i, rev, result; + struct l4 *l4; - if (!(l4_port[i * 4] = kmalloc(sizeof(struct l4) * 4, GFP_KERNEL))) { - printk(KERN_ERR "lightning: Out of memory allocating ports.\n"); - continue; - } - memset(l4_port[i * 4], 0, sizeof(struct l4) * 4); + outb(L4_SELECT_ANALOG, L4_PORT); + outb(L4_SELECT_DIGITAL + card_no, L4_PORT); - for (j = 0; j < 4; j++) { + if (inb(L4_PORT) & L4_BUSY) + return -1; + outb(L4_CMD_ID, L4_PORT); - l4 = l4_port[i * 4 + j] = l4_port[i * 4] + j; - l4->port = i * 4 + j; + if (l4_wait_ready()) + return -1; - sprintf(l4->phys, "isa%04x/gameport%d", L4_PORT, 4 * i + j); + if (inb(L4_PORT) != L4_SELECT_DIGITAL + card_no) + return -1; - gameport = &l4->gameport; - gameport->port_data = l4; - gameport->open = l4_open; - gameport->cooked_read = l4_cooked_read; - gameport->calibrate = l4_calibrate; + if (l4_wait_ready()) + return -1; + if (inb(L4_PORT) != L4_ID) + return -1; - gameport->name = l4_name; - gameport->phys = l4->phys; - gameport->id.bustype = BUS_ISA; + if (l4_wait_ready()) + return -1; + rev = inb(L4_PORT); - if (!i && !j) - gameport->io = L4_PORT; + if (!rev) + return -1; - if (rev > 0x28) /* on 2.9+ the setcal command works correctly */ - l4_setcal(l4->port, cal); + result = l4_create_ports(card_no); + if (result) + return result; - gameport_register_port(gameport); - } + printk(KERN_INFO "gameport: PDPI Lightning 4 %s card v%d.%d at %#x\n", + card_no ? "secondary" : "primary", rev >> 4, rev, L4_PORT); - printk(KERN_INFO "gameport: PDPI Lightning 4 %s card v%d.%d at %#x\n", - i ? "secondary" : "primary", rev >> 4, rev, L4_PORT); + for (i = 0; i < 4; i++) { + l4 = &l4_ports[card_no * 4 + i]; - cards++; + if (rev > 0x28) /* on 2.9+ the setcal command works correctly */ + l4_setcal(l4->port, cal); + gameport_register_port(l4->gameport); } + return 0; +} + +static int __init l4_init(void) +{ + int i, cards = 0; + + if (!request_region(L4_PORT, 1, "lightning")) + return -1; + + for (i = 0; i < 2; i++) + if (l4_add_card(i) == 0) + cards++; + outb(L4_SELECT_ANALOG, L4_PORT); if (!cards) { @@ -289,13 +328,14 @@ static void __exit l4_exit(void) { int i; - int cal[4] = {59, 59, 59, 59}; + int cal[4] = { 59, 59, 59, 59 }; for (i = 0; i < 8; i++) - if (l4_port[i]) { - l4_setcal(l4_port[i]->port, cal); - gameport_unregister_port(&l4_port[i]->gameport); + if (l4_ports[i].gameport) { + l4_setcal(l4_ports[i].port, cal); + gameport_unregister_port(l4_ports[i].gameport); } + outb(L4_SELECT_ANALOG, L4_PORT); release_region(L4_PORT, 1); } diff -Nru a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c --- a/drivers/input/gameport/ns558.c 2005-02-11 01:38:07 -05:00 +++ b/drivers/input/gameport/ns558.c 2005-02-11 01:38:07 -05:00 @@ -49,12 +49,11 @@ struct ns558 { int type; + int io; int size; struct pnp_dev *dev; + struct gameport *gameport; struct list_head node; - struct gameport gameport; - char phys[32]; - char name[32]; }; static LIST_HEAD(ns558_list); @@ -65,18 +64,19 @@ * A joystick must be attached for this to work. */ -static void ns558_isa_probe(int io) +static int ns558_isa_probe(int io) { int i, j, b; unsigned char c, u, v; - struct ns558 *port; + struct ns558 *ns558; + struct gameport *port; /* * No one should be using this address. */ if (!request_region(io, 1, "ns558-isa")) - return; + return -EBUSY; /* * We must not be able to write arbitrary values to the port. @@ -87,8 +87,8 @@ outb(~c & ~3, io); if (~(u = v = inb(io)) & 3) { outb(c, io); - i = 0; - goto out; + release_region(io, 1); + return -ENODEV; } /* * After a trigger, there must be at least some bits changing. @@ -98,8 +98,8 @@ if (u == v) { outb(c, io); - i = 0; - goto out; + release_region(io, 1); + return -ENODEV; } msleep(3); /* @@ -110,8 +110,8 @@ for (i = 0; i < 1000; i++) if ((u ^ inb(io)) & 0xf) { outb(c, io); - i = 0; - goto out; + release_region(io, 1); + return -ENODEV; } /* * And now find the number of mirrors of the port. @@ -119,7 +119,7 @@ for (i = 1; i < 5; i++) { - release_region(io & (-1 << (i-1)), (1 << (i-1))); + release_region(io & (-1 << (i - 1)), (1 << (i - 1))); if (!request_region(io & (-1 << i), (1 << i), "ns558-isa")) break; /* Don't disturb anyone */ @@ -139,34 +139,33 @@ if (i != 4) { if (!request_region(io & (-1 << i), (1 << i), "ns558-isa")) - return; + return -EBUSY; } - if (!(port = kmalloc(sizeof(struct ns558), GFP_KERNEL))) { + ns558 = kcalloc(1, sizeof(struct ns558), GFP_KERNEL); + port = gameport_allocate_port(); + if (!ns558 || !port) { printk(KERN_ERR "ns558: Memory allocation failed.\n"); - goto out; + release_region(io & (-1 << i), (1 << i)); + kfree(ns558); + gameport_free_port(port); + return -ENOMEM; } - memset(port, 0, sizeof(struct ns558)); - - port->size = (1 << i); - port->gameport.io = io; - port->gameport.phys = port->phys; - port->gameport.name = port->name; - port->gameport.id.bustype = BUS_ISA; - sprintf(port->phys, "isa%04x/gameport0", io & (-1 << i)); - sprintf(port->name, "NS558 ISA"); + memset(ns558, 0, sizeof(struct ns558)); + ns558->io = io; + ns558->size = 1 << i; + ns558->gameport = port; + + port->io = io; + gameport_set_name(port, "NS558 ISA Gameport"); + gameport_set_phys(port, "isa%04x/gameport0", io & (-1 << i)); - gameport_register_port(&port->gameport); + gameport_register_port(port); - printk(KERN_INFO "gameport: NS558 ISA at %#x", port->gameport.io); - if (port->size > 1) printk(" size %d", port->size); - printk(" speed %d kHz\n", port->gameport.speed); + list_add(&ns558->node, &ns558_list); - list_add(&port->node, &ns558_list); - return; -out: - release_region(io & (-1 << i), (1 << i)); + return 0; } #ifdef CONFIG_PNP @@ -202,45 +201,42 @@ static int ns558_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *did) { int ioport, iolen; - struct ns558 *port; + struct ns558 *ns558; + struct gameport *port; if (!pnp_port_valid(dev, 0)) { printk(KERN_WARNING "ns558: No i/o ports on a gameport? Weird\n"); return -ENODEV; } - ioport = pnp_port_start(dev,0); - iolen = pnp_port_len(dev,0); + ioport = pnp_port_start(dev, 0); + iolen = pnp_port_len(dev, 0); if (!request_region(ioport, iolen, "ns558-pnp")) return -EBUSY; - if (!(port = kmalloc(sizeof(struct ns558), GFP_KERNEL))) { - printk(KERN_ERR "ns558: Memory allocation failed.\n"); + ns558 = kcalloc(1, sizeof(struct ns558), GFP_KERNEL); + port = gameport_allocate_port(); + if (!ns558 || !port) { + printk(KERN_ERR "ns558: Memory allocation failed\n"); + kfree(ns558); + gameport_free_port(port); return -ENOMEM; } - memset(port, 0, sizeof(struct ns558)); - - port->size = iolen; - port->dev = dev; - - port->gameport.io = ioport; - port->gameport.phys = port->phys; - port->gameport.name = port->name; - port->gameport.id.bustype = BUS_ISAPNP; - port->gameport.id.version = 0x100; - - sprintf(port->phys, "pnp%s/gameport0", dev->dev.bus_id); - sprintf(port->name, "%s", "NS558 PnP Gameport"); - gameport_register_port(&port->gameport); + ns558->io = ioport; + ns558->size = iolen; + ns558->dev = dev; + ns558->gameport = port; + + gameport_set_name(port, "NS558 PnP Gameport"); + gameport_set_phys(port, "pnp%s/gameport0", dev->dev.bus_id); + port->dev.parent = &dev->dev; + port->io = ioport; - printk(KERN_INFO "gameport: NS558 PnP at pnp%s io %#x", - dev->dev.bus_id, port->gameport.io); - if (iolen > 1) printk(" size %d", iolen); - printk(" speed %d kHz\n", port->gameport.speed); + gameport_register_port(port); - list_add_tail(&port->node, &ns558_list); + list_add_tail(&ns558->node, &ns558_list); return 0; } @@ -279,12 +275,12 @@ static void __exit ns558_exit(void) { - struct ns558 *port; + struct ns558 *ns558; - list_for_each_entry(port, &ns558_list, node) { - gameport_unregister_port(&port->gameport); - release_region(port->gameport.io & ~(port->size - 1), port->size); - kfree(port); + list_for_each_entry(ns558, &ns558_list, node) { + gameport_unregister_port(ns558->gameport); + release_region(ns558->io & ~(ns558->size - 1), ns558->size); + kfree(ns558); } if (pnp_registered) diff -Nru a/drivers/input/gameport/vortex.c b/drivers/input/gameport/vortex.c --- a/drivers/input/gameport/vortex.c 2005-02-11 01:38:07 -05:00 +++ b/drivers/input/gameport/vortex.c 2005-02-11 01:38:07 -05:00 @@ -53,11 +53,10 @@ #define VORTEX_DATA_WAIT 20 /* 20 ms */ struct vortex { - struct gameport gameport; + struct gameport *gameport; struct pci_dev *dev; - unsigned char __iomem *base; - unsigned char __iomem *io; - char phys[32]; + unsigned char __iomem *base; + unsigned char __iomem *io; }; static unsigned char vortex_read(struct gameport *gameport) @@ -109,30 +108,17 @@ static int __devinit vortex_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct vortex *vortex; + struct gameport *port; int i; - if (!(vortex = kmalloc(sizeof(struct vortex), GFP_KERNEL))) - return -1; - memset(vortex, 0, sizeof(struct vortex)); - - vortex->dev = dev; - sprintf(vortex->phys, "pci%s/gameport0", pci_name(dev)); - - pci_set_drvdata(dev, vortex); - - vortex->gameport.port_data = vortex; - vortex->gameport.fuzz = 64; - - vortex->gameport.read = vortex_read; - vortex->gameport.trigger = vortex_trigger; - vortex->gameport.cooked_read = vortex_cooked_read; - vortex->gameport.open = vortex_open; - - vortex->gameport.name = pci_name(dev); - vortex->gameport.phys = vortex->phys; - vortex->gameport.id.bustype = BUS_PCI; - vortex->gameport.id.vendor = dev->vendor; - vortex->gameport.id.product = dev->device; + vortex = kcalloc(1, sizeof(struct vortex), GFP_KERNEL); + port = gameport_allocate_port(); + if (!vortex || !port) { + printk(KERN_ERR "vortex: Memory allocation failed.\n"); + kfree(vortex); + gameport_free_port(port); + return -ENOMEM; + } for (i = 0; i < 6; i++) if (~pci_resource_flags(dev, i) & IORESOURCE_IO) @@ -140,14 +126,26 @@ pci_enable_device(dev); + vortex->dev = dev; + vortex->gameport = port; vortex->base = ioremap(pci_resource_start(vortex->dev, i), pci_resource_len(vortex->dev, i)); vortex->io = vortex->base + id->driver_data; - gameport_register_port(&vortex->gameport); + pci_set_drvdata(dev, vortex); + + port->port_data = vortex; + port->fuzz = 64; - printk(KERN_INFO "gameport at pci%s speed %d kHz\n", - pci_name(dev), vortex->gameport.speed); + gameport_set_name(port, "AU88x0"); + gameport_set_phys(port, "pci%s/gameport0", pci_name(dev)); + port->dev.parent = &dev->dev; + port->read = vortex_read; + port->trigger = vortex_trigger; + port->cooked_read = vortex_cooked_read; + port->open = vortex_open; + + gameport_register_port(port); return 0; } @@ -155,15 +153,17 @@ static void __devexit vortex_remove(struct pci_dev *dev) { struct vortex *vortex = pci_get_drvdata(dev); - gameport_unregister_port(&vortex->gameport); + + gameport_unregister_port(vortex->gameport); iounmap(vortex->base); kfree(vortex); } -static struct pci_device_id vortex_id_table[] = -{{ 0x12eb, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x11000 }, - { 0x12eb, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x28800 }, - { 0 }}; +static struct pci_device_id vortex_id_table[] = { + { 0x12eb, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x11000 }, + { 0x12eb, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x28800 }, + { 0 } +}; static struct pci_driver vortex_driver = { .name = "vortex_gameport", diff -Nru a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c --- a/drivers/input/joystick/a3d.c 2005-02-11 01:38:07 -05:00 +++ b/drivers/input/joystick/a3d.c 2005-02-11 01:38:07 -05:00 @@ -55,7 +55,7 @@ struct a3d { struct gameport *gameport; - struct gameport adc; + struct gameport *adc; struct input_dev dev; struct timer_list timer; int axes[4]; @@ -66,7 +66,6 @@ int reads; int bads; char phys[32]; - char adcphys[32]; }; /* @@ -261,6 +260,7 @@ static void a3d_connect(struct gameport *gameport, struct gameport_driver *drv) { struct a3d *a3d; + struct gameport *adc; unsigned char data[A3D_MAX_LENGTH]; int i; @@ -292,7 +292,6 @@ } sprintf(a3d->phys, "%s/input0", gameport->phys); - sprintf(a3d->adcphys, "%s/gameport0", gameport->phys); if (a3d->mode == A3D_MODE_PXL) { @@ -315,16 +314,11 @@ a3d_read(a3d, data); for (i = 0; i < 4; i++) { - if (i < 2) { - a3d->dev.absmin[axes[i]] = 48; - a3d->dev.absmax[axes[i]] = a3d->dev.abs[axes[i]] * 2 - 48; - a3d->dev.absflat[axes[i]] = 8; - } else { - a3d->dev.absmin[axes[i]] = 2; - a3d->dev.absmax[axes[i]] = 253; - } - a3d->dev.absmin[ABS_HAT0X + i] = -1; - a3d->dev.absmax[ABS_HAT0X + i] = 1; + if (i < 2) + input_set_abs_params(&a3d->dev, axes[i], 48, a3d->dev.abs[axes[i]] * 2 - 48, 0, 8); + else + input_set_abs_params(&a3d->dev, axes[i], 2, 253, 0, 0); + input_set_abs_params(&a3d->dev, ABS_HAT0X + i, -1, 1, 0, 0); } } else { @@ -336,23 +330,23 @@ a3d->dev.relbit[0] |= BIT(REL_X) | BIT(REL_Y); a3d->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE); - a3d->adc.port_data = a3d; - a3d->adc.open = a3d_adc_open; - a3d->adc.close = a3d_adc_close; - a3d->adc.cooked_read = a3d_adc_cooked_read; - a3d->adc.fuzz = 1; - - a3d->adc.name = a3d_names[a3d->mode]; - a3d->adc.phys = a3d->adcphys; - a3d->adc.id.bustype = BUS_GAMEPORT; - a3d->adc.id.vendor = GAMEPORT_ID_VENDOR_MADCATZ; - a3d->adc.id.product = a3d->mode; - a3d->adc.id.version = 0x0100; - a3d_read(a3d, data); - gameport_register_port(&a3d->adc); - printk(KERN_INFO "gameport: %s on %s\n", a3d_names[a3d->mode], gameport->phys); + if (!(a3d->adc = adc = gameport_allocate_port())) + printk(KERN_ERR "a3d: Not enough memory for ADC port\n"); + else { + adc->port_data = a3d; + adc->open = a3d_adc_open; + adc->close = a3d_adc_close; + adc->cooked_read = a3d_adc_cooked_read; + adc->fuzz = 1; + + gameport_set_name(adc, a3d_names[a3d->mode]); + gameport_set_phys(adc, "%s/gameport0", gameport->phys); + adc->dev.parent = &gameport->dev; + + gameport_register_port(adc); + } } a3d->dev.private = a3d; @@ -370,17 +364,20 @@ printk(KERN_INFO "input: %s on %s\n", a3d_names[a3d->mode], a3d->phys); return; + fail2: gameport_close(gameport); fail1: kfree(a3d); } static void a3d_disconnect(struct gameport *gameport) { - struct a3d *a3d = gameport->private; + input_unregister_device(&a3d->dev); - if (a3d->mode < A3D_MODE_PXL) - gameport_unregister_port(&a3d->adc); + if (a3d->adc) { + gameport_unregister_port(a3d->adc); + a3d->adc = NULL; + } gameport_close(gameport); kfree(a3d); } diff -Nru a/include/linux/gameport.h b/include/linux/gameport.h --- a/include/linux/gameport.h 2005-02-11 01:38:07 -05:00 +++ b/include/linux/gameport.h 2005-02-11 01:38:07 -05:00 @@ -10,7 +10,6 @@ */ #include <asm/io.h> -#include <linux/input.h> #include <linux/list.h> #include <linux/device.h> @@ -22,8 +21,6 @@ char name_buf[32]; char *phys; char phys_buf[32]; - - struct input_id id; int io; int speed; ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 6/10] Gameport: convert sound/oss to dynamic allocation 2005-02-11 7:02 ` [PATCH 5/10] Gameport: convert input/gameport " Dmitry Torokhov @ 2005-02-11 7:02 ` Dmitry Torokhov 2005-02-11 7:03 ` [PATCH 7/10] Gameport: convert sound/alsa " Dmitry Torokhov 0 siblings, 1 reply; 12+ messages in thread From: Dmitry Torokhov @ 2005-02-11 7:02 UTC (permalink / raw) To: InputML; +Cc: alsa-devel, LKML, Vojtech Pavlik =================================================================== ChangeSet@1.2154, 2005-02-11 01:20:08-05:00, dtor_core@ameritech.net Input: convert sound/oss to dynamic gameport allocation. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> cmpci.c | 100 ++++++++++++++++++++++++++++++++++++++--------------------- es1370.c | 34 ++++++++++++-------- es1371.c | 52 ++++++++++++++++++------------ esssolo1.c | 47 ++++++++++++++++++++------- mad16.c | 47 ++++++++++++++++++--------- sonicvibes.c | 49 +++++++++++++++++++++------- trident.c | 39 +++++++++++++++++------ 7 files changed, 249 insertions(+), 119 deletions(-) =================================================================== diff -Nru a/sound/oss/cmpci.c b/sound/oss/cmpci.c --- a/sound/oss/cmpci.c 2005-02-11 01:38:28 -05:00 +++ b/sound/oss/cmpci.c 2005-02-11 01:38:28 -05:00 @@ -426,7 +426,7 @@ struct address_info mpu_data; #endif #ifdef CONFIG_SOUND_CMPCI_JOYSTICK - struct gameport gameport; + struct gameport *gameport; #endif int chip_version; @@ -468,17 +468,17 @@ static LIST_HEAD(devs); -static int mpuio = 0; -static int fmio = 0; -static int joystick = 0; -static int spdif_inverse = 0; -static int spdif_loop = 0; -static int spdif_out = 0; -static int use_line_as_rear = 0; -static int use_line_as_bass = 0; -static int use_mic_as_bass = 0; -static int mic_boost = 0; -static int hw_copy = 0; +static int mpuio; +static int fmio; +static int joystick; +static int spdif_inverse; +static int spdif_loop; +static int spdif_out; +static int use_line_as_rear; +static int use_line_as_bass; +static int use_mic_as_bass; +static int mic_boost; +static int hw_copy; module_param(mpuio, int, 0); module_param(fmio, int, 0); module_param(joystick, bool, 0); @@ -2984,6 +2984,51 @@ return ChipVersion; } +#ifdef CONFIG_SOUND_CMPCI_JOYSTICK +static int __devinit cm_create_gameport(struct cm_state *s, int io_port) +{ + struct gameport *gp; + + if (!request_region(io_port, CM_EXTENT_GAME, "cmpci GAME")) { + printk(KERN_ERR "cmpci: gameport io ports 0x%#x in use\n", io_port); + return -EBUSY; + } + + if (!(s->gameport = gp = gameport_allocate_port())) { + printk(KERN_ERR "cmpci: can not allocate memory for gameport\n"); + release_region(io_port, CM_EXTENT_GAME); + return -ENOMEM; + } + + gameport_set_name(gp, "C-Media GP"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(s->dev)); + gp->dev.parent = &s->dev->dev; + gp->io = io_port; + + /* enable joystick */ + maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x02); + + gameport_register_port(gp); + + return 0; +} + +static void __devexit cm_free_gameport(struct cm_state *s) +{ + if (s->gameport) { + int gpio = s->gameport->io; + + gameport_unregister_port(s->gameport); + s->gameport = NULL; + maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x02, 0); + release_region(gpio, CM_EXTENT_GAME); + } +} +#else +static inline int cm_create_gameport(struct cm_state *s, int io_port) { return -ENOSYS; } +static inline void cm_free_gameport(struct cm_state *s) { } +#endif + #define echo_option(x)\ if (x) strcat(options, "" #x " ") @@ -3229,22 +3274,11 @@ } skip_mpu: #endif -#ifdef CONFIG_SOUND_CMPCI_JOYSTICK - /* enable joystick */ - if (joystick) { - s->gameport.io = 0x200; - if (!request_region(s->gameport.io, CM_EXTENT_GAME, "cmpci GAME")) { - printk(KERN_ERR "cmpci: gameport io ports in use\n"); - s->gameport.io = 0; - } else { - maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x02); - gameport_register_port(&s->gameport); - } - } else { - maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x02, 0); - s->gameport.io = 0; - } -#endif + /* disable joystick port */ + maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x02, 0); + if (joystick) + cm_create_gameport(s, 0x200); + /* store it in the driver field */ pci_set_drvdata(pcidev, s); /* put it into driver list */ @@ -3278,13 +3312,9 @@ if (!s) return; -#ifdef CONFIG_SOUND_CMPCI_JOYSTICK - if (s->gameport.io) { - gameport_unregister_port(&s->gameport); - release_region(s->gameport.io, CM_EXTENT_GAME); - maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x02, 0); - } -#endif + + cm_free_gameport(s); + #ifdef CONFIG_SOUND_CMPCI_FM if (s->iosynth) { /* disable FM */ diff -Nru a/sound/oss/es1370.c b/sound/oss/es1370.c --- a/sound/oss/es1370.c 2005-02-11 01:38:28 -05:00 +++ b/sound/oss/es1370.c 2005-02-11 01:38:28 -05:00 @@ -384,7 +384,7 @@ unsigned char obuf[MIDIOUTBUF]; } midi; - struct gameport gameport; + struct gameport *gameport; struct semaphore sem; }; @@ -2556,6 +2556,7 @@ static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) { struct es1370_state *s; + struct gameport *gp = NULL; mm_segment_t fs; int i, val, ret; @@ -2604,12 +2605,17 @@ /* note: setting CTRL_SERR_DIS is reported to break * mic bias setting (by Kim.Berts@fisub.mail.abb.com) */ s->ctrl = CTRL_CDC_EN | (DAC2_SRTODIV(8000) << CTRL_SH_PCLKDIV) | (1 << CTRL_SH_WTSRSEL); - s->gameport.io = 0; - if (!request_region(0x200, JOY_EXTENT, "es1370")) + if (!request_region(0x200, JOY_EXTENT, "es1370")) { printk(KERN_ERR "es1370: joystick io port 0x200 in use\n"); - else { + } else if (!(s->gameport = gp = gameport_allocate_port())) { + printk(KERN_ERR "es1370: can not allocate memory for gameport\n"); + release_region(0x200, JOY_EXTENT); + } else { + gameport_set_name(gp, "ESS1370"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(s->dev)); + gp->dev.parent = &s->dev->dev; + gp->io = 0x200; s->ctrl |= CTRL_JYSTK_EN; - s->gameport.io = 0x200; } if (lineout[devindex]) s->ctrl |= CTRL_XCTL0; @@ -2665,9 +2671,10 @@ mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val); } set_fs(fs); + /* register gameport */ - if (s->gameport.io) - gameport_register_port(&s->gameport); + if (gp) + gameport_register_port(gp); /* store it in the driver field */ pci_set_drvdata(pcidev, s); @@ -2689,8 +2696,10 @@ err_dev1: printk(KERN_ERR "es1370: cannot register misc device\n"); free_irq(s->irq, s); - if (s->gameport.io) - release_region(s->gameport.io, JOY_EXTENT); + if (s->gameport) { + release_region(s->gameport->io, JOY_EXTENT); + gameport_free_port(s->gameport); + } err_irq: release_region(s->io, ES1370_EXTENT); err_region: @@ -2709,9 +2718,10 @@ outl(0, s->io+ES1370_REG_SERIAL_CONTROL); /* clear serial interrupts */ synchronize_irq(s->irq); free_irq(s->irq, s); - if (s->gameport.io) { - gameport_unregister_port(&s->gameport); - release_region(s->gameport.io, JOY_EXTENT); + if (s->gameport) { + int gpio = s->gameport->io; + gameport_unregister_port(s->gameport); + release_region(gpio, JOY_EXTENT); } release_region(s->io, ES1370_EXTENT); unregister_sound_dsp(s->dev_audio); diff -Nru a/sound/oss/es1371.c b/sound/oss/es1371.c --- a/sound/oss/es1371.c 2005-02-11 01:38:28 -05:00 +++ b/sound/oss/es1371.c 2005-02-11 01:38:28 -05:00 @@ -453,7 +453,7 @@ unsigned char obuf[MIDIOUTBUF]; } midi; - struct gameport gameport; + struct gameport *gameport; struct semaphore sem; }; @@ -2786,12 +2786,12 @@ { PCI_ANY_ID, PCI_ANY_ID } }; - static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) { struct es1371_state *s; + struct gameport *gp; mm_segment_t fs; - int i, val, res = -1; + int i, gpio, val, res = -1; int idx; unsigned long tmo; signed long tmo2; @@ -2849,8 +2849,8 @@ printk(KERN_ERR PFX "irq %u in use\n", s->irq); goto err_irq; } - printk(KERN_INFO PFX "found es1371 rev %d at io %#lx irq %u joystick %#x\n", - s->rev, s->io, s->irq, s->gameport.io); + printk(KERN_INFO PFX "found es1371 rev %d at io %#lx irq %u\n", + s->rev, s->io, s->irq); /* register devices */ if ((res=(s->dev_audio = register_sound_dsp(&es1371_audio_fops,-1)))<0) goto err_dev1; @@ -2881,16 +2881,23 @@ printk(KERN_INFO PFX "Enabling internal amplifier.\n"); } } - s->gameport.io = 0; - for (i = 0x218; i >= 0x200; i -= 0x08) { - if (request_region(i, JOY_EXTENT, "es1371")) { - s->ctrl |= CTRL_JYSTK_EN | (((i >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT); - s->gameport.io = i; + + for (gpio = 0x218; gpio >= 0x200; gpio -= 0x08) + if (request_region(gpio, JOY_EXTENT, "es1371")) break; - } - } - if (!s->gameport.io) + + if (gpio < 0x200) { printk(KERN_ERR PFX "no free joystick address found\n"); + } else if (!(s->gameport = gp = gameport_allocate_port())) { + printk(KERN_ERR PFX "can not allocate memory for gameport\n"); + release_region(gpio, JOY_EXTENT); + } else { + gameport_set_name(gp, "ESS1371 Gameport"); + gameport_set_phys(gp, "isa%04x/gameport0", gpio); + gp->dev.parent = &s->dev->dev; + gp->io = gpio; + s->ctrl |= CTRL_JYSTK_EN | (((gpio >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT); + } s->sctrl = 0; cssr = 0; @@ -2960,9 +2967,11 @@ set_fs(fs); /* turn on S/PDIF output driver if requested */ outl(cssr, s->io+ES1371_REG_STATUS); + /* register gameport */ - if (s->gameport.io) - gameport_register_port(&s->gameport); + if (s->gameport) + gameport_register_port(s->gameport); + /* store it in the driver field */ pci_set_drvdata(pcidev, s); /* put it into driver list */ @@ -2973,8 +2982,10 @@ return 0; err_gp: - if (s->gameport.io) - release_region(s->gameport.io, JOY_EXTENT); + if (s->gameport) { + release_region(s->gameport->io, JOY_EXTENT); + gameport_free_port(s->gameport); + } #ifdef ES1371_DEBUG if (s->ps) remove_proc_entry("es1371", NULL); @@ -3013,9 +3024,10 @@ outl(0, s->io+ES1371_REG_SERIAL_CONTROL); /* clear serial interrupts */ synchronize_irq(s->irq); free_irq(s->irq, s); - if (s->gameport.io) { - gameport_unregister_port(&s->gameport); - release_region(s->gameport.io, JOY_EXTENT); + if (s->gameport) { + int gpio = s->gameport->io; + gameport_unregister_port(s->gameport); + release_region(gpio, JOY_EXTENT); } release_region(s->io, ES1371_EXTENT); unregister_sound_dsp(s->dev_audio); diff -Nru a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c --- a/sound/oss/esssolo1.c 2005-02-11 01:38:28 -05:00 +++ b/sound/oss/esssolo1.c 2005-02-11 01:38:28 -05:00 @@ -226,7 +226,7 @@ unsigned char obuf[MIDIOUTBUF]; } midi; - struct gameport gameport; + struct gameport *gameport; }; /* --------------------------------------------------------------------- */ @@ -2280,9 +2280,36 @@ return 0; } +static int __devinit solo1_register_gameport(struct solo1_state *s, int io_port) +{ + struct gameport *gp; + + if (!request_region(io_port, GAMEPORT_EXTENT, "ESS Solo1")) { + printk(KERN_ERR "solo1: gameport io ports are in use\n"); + return -EBUSY; + } + + s->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "solo1: can not allocate memory for gameport\n"); + release_region(io_port, GAMEPORT_EXTENT); + return -ENOMEM; + } + + gameport_set_name(gp, "ESS Solo1 Gameport"); + gameport_set_phys(gp, "isa%04x/gameport0", io_port); + gp->dev.parent = &s->dev->dev; + gp->io = io_port; + + gameport_register_port(gp); + + return 0; +} + static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) { struct solo1_state *s; + int gpio; int ret; if ((ret=pci_enable_device(pcidev))) @@ -2323,7 +2350,7 @@ s->vcbase = pci_resource_start(pcidev, 2); s->ddmabase = s->vcbase + DDMABASE_OFFSET; s->mpubase = pci_resource_start(pcidev, 3); - s->gameport.io = pci_resource_start(pcidev, 4); + gpio = pci_resource_start(pcidev, 4); s->irq = pcidev->irq; ret = -EBUSY; if (!request_region(s->iobase, IOBASE_EXTENT, "ESS Solo1")) { @@ -2342,15 +2369,10 @@ printk(KERN_ERR "solo1: io ports in use\n"); goto err_region4; } - if (s->gameport.io && !request_region(s->gameport.io, GAMEPORT_EXTENT, "ESS Solo1")) { - printk(KERN_ERR "solo1: gameport io ports in use\n"); - s->gameport.io = 0; - } if ((ret=request_irq(s->irq,solo1_interrupt,SA_SHIRQ,"ESS Solo1",s))) { printk(KERN_ERR "solo1: irq %u in use\n", s->irq); goto err_irq; } - printk(KERN_INFO "solo1: joystick port at %#x\n", s->gameport.io+1); /* register devices */ if ((s->dev_audio = register_sound_dsp(&solo1_audio_fops, -1)) < 0) { ret = s->dev_audio; @@ -2373,7 +2395,7 @@ goto err; } /* register gameport */ - gameport_register_port(&s->gameport); + solo1_register_gameport(s, gpio); /* store it in the driver field */ pci_set_drvdata(pcidev, s); return 0; @@ -2390,8 +2412,6 @@ printk(KERN_ERR "solo1: initialisation error\n"); free_irq(s->irq, s); err_irq: - if (s->gameport.io) - release_region(s->gameport.io, GAMEPORT_EXTENT); release_region(s->mpubase, MPUBASE_EXTENT); err_region4: release_region(s->ddmabase, DDMABASE_EXTENT); @@ -2417,9 +2437,10 @@ synchronize_irq(s->irq); pci_write_config_word(s->dev, 0x60, 0); /* turn off DDMA controller address space */ free_irq(s->irq, s); - if (s->gameport.io) { - gameport_unregister_port(&s->gameport); - release_region(s->gameport.io, GAMEPORT_EXTENT); + if (s->gameport) { + int gpio = s->gameport->io; + gameport_unregister_port(s->gameport); + release_region(gpio, GAMEPORT_EXTENT); } release_region(s->iobase, IOBASE_EXTENT); release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT); diff -Nru a/sound/oss/mad16.c b/sound/oss/mad16.c --- a/sound/oss/mad16.c 2005-02-11 01:38:28 -05:00 +++ b/sound/oss/mad16.c 2005-02-11 01:38:28 -05:00 @@ -52,7 +52,7 @@ static int mad16_conf; static int mad16_cdsel; -static struct gameport gameport; +static struct gameport *gameport; static DEFINE_SPINLOCK(lock); #define C928 1 @@ -902,7 +902,30 @@ -1, -1, -1, -1 }; -static int __init init_mad16(void) +static int __devinit mad16_register_gameport(int io_port) +{ + if (!request_region(io_port, 1, "mad16 gameport")) { + printk(KERN_ERR "mad16: gameport address 0x%#x already in use\n", io_port); + return -EBUSY; + } + + gameport = gameport_allocate_port(); + if (!gameport) { + printk(KERN_ERR "mad16: can not allocate memory for gameport\n"); + release_region(io_port, 1); + return -ENOMEM; + } + + gameport_set_name(gameport, "MAD16 Gameport"); + gameport_set_phys(gameport, "isa%04x/gameport0", io_port); + gameport->io = io_port; + + gameport_register_port(gameport); + + return 0; +} + +static int __devinit init_mad16(void) { int dmatype = 0; @@ -1027,17 +1050,9 @@ found_mpu = probe_mad16_mpu(&cfg_mpu); - if (joystick == 1) { - /* register gameport */ - if (!request_region(0x201, 1, "mad16 gameport")) - printk(KERN_ERR "mad16: gameport address 0x201 already in use\n"); - else { - printk(KERN_ERR "mad16: gameport enabled at 0x201\n"); - gameport.io = 0x201; - gameport_register_port(&gameport); - } - } - else printk(KERN_ERR "mad16: gameport disabled.\n"); + if (joystick) + mad16_register_gameport(0x201); + return 0; } @@ -1045,10 +1060,10 @@ { if (found_mpu) unload_mad16_mpu(&cfg_mpu); - if (gameport.io) { + if (gameport) { /* the gameport was initialized so we must free it up */ - gameport_unregister_port(&gameport); - gameport.io = 0; + gameport_unregister_port(gameport); + gameport = NULL; release_region(0x201, 1); } unload_mad16(&cfg); diff -Nru a/sound/oss/sonicvibes.c b/sound/oss/sonicvibes.c --- a/sound/oss/sonicvibes.c 2005-02-11 01:38:28 -05:00 +++ b/sound/oss/sonicvibes.c 2005-02-11 01:38:28 -05:00 @@ -365,7 +365,7 @@ unsigned char obuf[MIDIOUTBUF]; } midi; - struct gameport gameport; + struct gameport *gameport; }; /* --------------------------------------------------------------------- */ @@ -2485,12 +2485,39 @@ #define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \ (pci_resource_flags((dev), (num)) & IORESOURCE_IO)) +static int __devinit sv_register_gameport(struct sv_state *s, int io_port) +{ + struct gameport *gp; + + if (!request_region(io_port, SV_EXTENT_GAME, "S3 SonicVibes Gameport")) { + printk(KERN_ERR "sv: gameport io ports are in use\n"); + return -EBUSY; + } + + s->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "sv: can not allocate memory for gameport\n"); + release_region(io_port, SV_EXTENT_GAME); + return -ENOMEM; + } + + gameport_set_name(gp, "S3 SonicVibes Gameport"); + gameport_set_phys(gp, "isa%04x/gameport0", io_port); + gp->dev.parent = &s->dev->dev; + gp->io = io_port; + + gameport_register_port(gp); + + return 0; +} + static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) { static char __initdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller"; struct sv_state *s; mm_segment_t fs; int i, val, ret; + int gpio; char *ddmaname; unsigned ddmanamelen; @@ -2546,11 +2573,11 @@ s->iomidi = pci_resource_start(pcidev, RESOURCE_MIDI); s->iodmaa = pci_resource_start(pcidev, RESOURCE_DDMA); s->iodmac = pci_resource_start(pcidev, RESOURCE_DDMA) + SV_EXTENT_DMA; - s->gameport.io = pci_resource_start(pcidev, RESOURCE_GAME); + gpio = pci_resource_start(pcidev, RESOURCE_GAME); pci_write_config_dword(pcidev, 0x40, s->iodmaa | 9); /* enable and use extended mode */ pci_write_config_dword(pcidev, 0x48, s->iodmac | 9); /* enable */ printk(KERN_DEBUG "sv: io ports: %#lx %#lx %#lx %#lx %#x %#x %#x\n", - s->iosb, s->ioenh, s->iosynth, s->iomidi, s->gameport.io, s->iodmaa, s->iodmac); + s->iosb, s->ioenh, s->iosynth, s->iomidi, gpio, s->iodmaa, s->iodmac); s->irq = pcidev->irq; /* hack */ @@ -2577,10 +2604,7 @@ printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iosynth, s->iosynth+SV_EXTENT_SYNTH-1); goto err_region1; } - if (s->gameport.io && !request_region(s->gameport.io, SV_EXTENT_GAME, "ESS Solo1")) { - printk(KERN_ERR "sv: gameport io ports in use\n"); - s->gameport.io = 0; - } + /* initialize codec registers */ outb(0x80, s->ioenh + SV_CODEC_CONTROL); /* assert reset */ udelay(50); @@ -2639,7 +2663,7 @@ } set_fs(fs); /* register gameport */ - gameport_register_port(&s->gameport); + sv_register_gameport(s, gpio); /* store it in the driver field */ pci_set_drvdata(pcidev, s); /* put it into driver list */ @@ -2659,8 +2683,6 @@ printk(KERN_ERR "sv: cannot register misc device\n"); free_irq(s->irq, s); err_irq: - if (s->gameport.io) - release_region(s->gameport.io, SV_EXTENT_GAME); release_region(s->iosynth, SV_EXTENT_SYNTH); err_region1: release_region(s->iomidi, SV_EXTENT_MIDI); @@ -2689,9 +2711,10 @@ /*outb(0, s->iodmaa + SV_DMA_RESET);*/ /*outb(0, s->iodmac + SV_DMA_RESET);*/ free_irq(s->irq, s); - if (s->gameport.io) { - gameport_unregister_port(&s->gameport); - release_region(s->gameport.io, SV_EXTENT_GAME); + if (s->gameport) { + int gpio = s->gameport->io; + gameport_unregister_port(s->gameport); + release_region(gpio, SV_EXTENT_GAME); } release_region(s->iodmac, SV_EXTENT_DMA); release_region(s->iodmaa, SV_EXTENT_DMA); diff -Nru a/sound/oss/trident.c b/sound/oss/trident.c --- a/sound/oss/trident.c 2005-02-11 01:38:28 -05:00 +++ b/sound/oss/trident.c 2005-02-11 01:38:28 -05:00 @@ -441,7 +441,7 @@ struct timer_list timer; /* Game port support */ - struct gameport gameport; + struct gameport *gameport; }; enum dmabuf_mode { @@ -4305,6 +4305,31 @@ return 0; } +static int __devinit +trident_register_gameport(struct trident_card *card) +{ + struct gameport *gp; + + card->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "trident: can not allocate memory for gameport\n"); + return -ENOMEM; + } + + gameport_set_name(gp, "Trident 4DWave"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(card->pci_dev)); + gp->read = trident_game_read; + gp->trigger = trident_game_trigger; + gp->cooked_read = trident_game_cooked_read; + gp->open = trident_game_open; + gp->fuzz = 64; + gp->port_data = card; + + gameport_register_port(gp); + + return 0; +} + /* install the driver, we do not allocate hardware channel nor DMA buffer */ /* now, they are defered until "ACCESS" time (in prog_dmabuf called by */ /* open/read/write/ioctl/mmap) */ @@ -4368,13 +4393,6 @@ card->banks[BANK_B].addresses = &bank_b_addrs; card->banks[BANK_B].bitmap = 0UL; - card->gameport.port_data = card; - card->gameport.fuzz = 64; - card->gameport.read = trident_game_read; - card->gameport.trigger = trident_game_trigger; - card->gameport.cooked_read = trident_game_cooked_read; - card->gameport.open = trident_game_open; - init_MUTEX(&card->open_sem); spin_lock_init(&card->lock); init_timer(&card->timer); @@ -4508,7 +4526,7 @@ trident_enable_loop_interrupts(card); /* Register gameport */ - gameport_register_port(&card->gameport); + trident_register_gameport(card); out: return rc; @@ -4551,7 +4569,8 @@ } /* Unregister gameport */ - gameport_unregister_port(&card->gameport); + if (card->gameport) + gameport_unregister_port(card->gameport); /* Kill interrupts, and SP/DIF */ trident_disable_loop_interrupts(card); ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 7/10] Gameport: convert sound/alsa to dynamic allocation 2005-02-11 7:02 ` [PATCH 6/10] Gameport: convert sound/oss " Dmitry Torokhov @ 2005-02-11 7:03 ` Dmitry Torokhov 2005-02-11 7:04 ` [PATCH 8/10] Gameport: add "gameport" sysfs bus, add drivers Dmitry Torokhov 0 siblings, 1 reply; 12+ messages in thread From: Dmitry Torokhov @ 2005-02-11 7:03 UTC (permalink / raw) To: InputML; +Cc: alsa-devel, LKML, Vojtech Pavlik =================================================================== ChangeSet@1.2155, 2005-02-11 01:20:30-05:00, dtor_core@ameritech.net Input: convert sound/pci to dynamic gameport allocation. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> include/sound/cs46xx.h | 4 - include/sound/trident.h | 4 - include/sound/ymfpci.h | 14 +-- sound/pci/als4000.c | 111 +++++++++++++++++++---------- sound/pci/au88x0/au88x0.c | 7 - sound/pci/au88x0/au88x0.h | 2 sound/pci/au88x0/au88x0_game.c | 49 ++++++------ sound/pci/azt3328.c | 111 +++++++++++++++++------------ sound/pci/cmipci.c | 104 ++++++++++++++++++--------- sound/pci/cs4281.c | 91 ++++++++++++----------- sound/pci/cs46xx/cs46xx_lib.c | 81 ++++++++++----------- sound/pci/ens1370.c | 122 +++++++++++++++++++++---------- sound/pci/es1938.c | 52 ++++++++++--- sound/pci/es1968.c | 76 ++++++++++++++----- sound/pci/sonicvibes.c | 55 +++++++++++--- sound/pci/trident/trident.c | 2 sound/pci/trident/trident_main.c | 87 ++++++++++------------ sound/pci/via82xx.c | 89 +++++++++++++++++------ sound/pci/ymfpci/ymfpci.c | 149 ++++++++++++++++++++++++--------------- sound/pci/ymfpci/ymfpci_main.c | 9 -- 20 files changed, 761 insertions(+), 458 deletions(-) =================================================================== diff -Nru a/include/sound/cs46xx.h b/include/sound/cs46xx.h --- a/include/sound/cs46xx.h 2005-02-11 01:39:33 -05:00 +++ b/include/sound/cs46xx.h 2005-02-11 01:39:33 -05:00 @@ -1720,7 +1720,7 @@ snd_kcontrol_t *eapd_switch; /* for amplifier hack */ int accept_valid; /* accept mmap valid (for OSS) */ - struct snd_cs46xx_gameport *gameport; + struct gameport *gameport; #ifdef CONFIG_SND_CS46XX_DEBUG_GPIO int current_gpio; @@ -1751,6 +1751,6 @@ int snd_cs46xx_mixer(cs46xx_t *chip); int snd_cs46xx_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rmidi); int snd_cs46xx_start_dsp(cs46xx_t *chip); -void snd_cs46xx_gameport(cs46xx_t *chip); +int snd_cs46xx_gameport(cs46xx_t *chip); #endif /* __SOUND_CS46XX_H */ diff -Nru a/include/sound/trident.h b/include/sound/trident.h --- a/include/sound/trident.h 2005-02-11 01:39:33 -05:00 +++ b/include/sound/trident.h 2005-02-11 01:39:33 -05:00 @@ -448,7 +448,7 @@ spinlock_t reg_lock; - struct snd_trident_gameport *gameport; + struct gameport *gameport; }; int snd_trident_create(snd_card_t * card, @@ -457,7 +457,7 @@ int pcm_spdif_device, int max_wavetable_size, trident_t ** rtrident); -void snd_trident_gameport(trident_t *trident); +int snd_trident_create_gameport(trident_t *trident); int snd_trident_pcm(trident_t * trident, int device, snd_pcm_t **rpcm); int snd_trident_foldback_pcm(trident_t * trident, int device, snd_pcm_t **rpcm); diff -Nru a/include/sound/ymfpci.h b/include/sound/ymfpci.h --- a/include/sound/ymfpci.h 2005-02-11 01:39:33 -05:00 +++ b/include/sound/ymfpci.h 2005-02-11 01:39:33 -05:00 @@ -198,6 +198,10 @@ #define YMFPCI_LEGACY2_IMOD (1 << 15) /* legacy IRQ mode */ /* SIEN:IMOD 0:0 = legacy irq, 0:1 = INTA, 1:0 = serialized IRQ */ +#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) +#define SUPPORT_JOYSTICK +#endif + /* * */ @@ -311,9 +315,8 @@ struct resource *mpu_res; unsigned short old_legacy_ctrl; -#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) - struct resource *joystick_res; - struct gameport gameport; +#ifdef SUPPORT_JOYSTICK + struct gameport *gameport; #endif struct snd_dma_buffer work_ptr; @@ -381,6 +384,7 @@ struct pci_dev *pci, unsigned short old_legacy_ctrl, ymfpci_t ** rcodec); +void snd_ymfpci_free_gameport(ymfpci_t *chip); int snd_ymfpci_pcm(ymfpci_t *chip, int device, snd_pcm_t **rpcm); int snd_ymfpci_pcm2(ymfpci_t *chip, int device, snd_pcm_t **rpcm); @@ -388,9 +392,5 @@ int snd_ymfpci_pcm_4ch(ymfpci_t *chip, int device, snd_pcm_t **rpcm); int snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch); int snd_ymfpci_timer(ymfpci_t *chip, int device); - -#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) -#define SUPPORT_JOYSTICK -#endif #endif /* __SOUND_YMFPCI_H */ diff -Nru a/sound/pci/als4000.c b/sound/pci/als4000.c --- a/sound/pci/als4000.c 2005-02-11 01:39:34 -05:00 +++ b/sound/pci/als4000.c 2005-02-11 01:39:34 -05:00 @@ -104,8 +104,7 @@ struct pci_dev *pci; unsigned long gcr; #ifdef SUPPORT_JOYSTICK - struct gameport gameport; - struct resource *res_joystick; + struct gameport *gameport; #endif } snd_card_als4000_t; @@ -566,21 +565,80 @@ spin_unlock_irq(&chip->reg_lock); } +#ifdef SUPPORT_JOYSTICK +static int __devinit snd_als4000_create_gameport(snd_card_als4000_t *acard, int dev) +{ + struct gameport *gp; + struct resource *r; + int io_port; + + if (joystick_port[dev] == 0) + return -ENODEV; + + if (joystick_port[dev] == 1) { /* auto-detect */ + for (io_port = 0x200; io_port <= 0x218; io_port += 8) { + r = request_region(io_port, 8, "ALS4000 gameport"); + if (r) + break; + } + } else { + io_port = joystick_port[dev]; + r = request_region(io_port, 8, "ALS4000 gameport"); + } + + if (!r) { + printk(KERN_WARNING "als4000: cannot reserve joystick ports\n"); + return -EBUSY; + } + + acard->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "als4000: cannot allocate memory for gameport\n"); + release_resource(r); + kfree_nocheck(r); + return -ENOMEM; + } + + gameport_set_name(gp, "ALS4000 Gameport"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(acard->pci)); + gp->dev.parent = &acard->pci->dev; + gp->io = io_port; + gp->port_data = r; + + /* Enable legacy joystick port */ + snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1); + + gameport_register_port(acard->gameport); + + return 0; +} + +static void snd_als4000_free_gameport(snd_card_als4000_t *acard) +{ + if (acard->gameport) { + struct resource *r = acard->gameport->port_data; + + gameport_unregister_port(acard->gameport); + acard->gameport = NULL; + + snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */ + release_resource(r); + kfree_nocheck(r); + } +} +#else +static inline int snd_als4000_create_gameport(snd_card_als4000_t *acard, int dev) { return -ENOSYS; } +static inline void snd_als4000_free_gameport(snd_card_als4000_t *acard) { } +#endif + static void snd_card_als4000_free( snd_card_t *card ) { snd_card_als4000_t * acard = (snd_card_als4000_t *)card->private_data; + /* make sure that interrupts are disabled */ snd_als4000_gcr_write_addr( acard->gcr, 0x8c, 0); /* free resources */ -#ifdef SUPPORT_JOYSTICK - if (acard->res_joystick) { - if (acard->gameport.io) - gameport_unregister_port(&acard->gameport); - snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */ - release_resource(acard->res_joystick); - kfree_nocheck(acard->res_joystick); - } -#endif + snd_als4000_free_gameport(acard); pci_release_regions(acard->pci); pci_disable_device(acard->pci); } @@ -596,7 +654,6 @@ opl3_t *opl3; unsigned short word; int err; - int joystick = 0; if (dev >= SNDRV_CARDS) return -ENODEV; @@ -640,26 +697,9 @@ acard->gcr = gcr; card->private_free = snd_card_als4000_free; - /* disable all legacy ISA stuff except for joystick */ -#ifdef SUPPORT_JOYSTICK - if (joystick_port[dev] == 1) { - /* auto-detect */ - long p; - for (p = 0x200; p <= 0x218; p += 8) { - if ((acard->res_joystick = request_region(p, 8, "ALS4000 gameport")) != NULL) { - joystick_port[dev] = p; - break; - } - } - } else if (joystick_port[dev] > 0) - acard->res_joystick = request_region(joystick_port[dev], 8, "ALS4000 gameport"); - if (acard->res_joystick) - joystick = joystick_port[dev]; - else - joystick = 0; -#endif - snd_als4000_set_addr(gcr, 0, 0, 0, joystick); - + /* disable all legacy ISA stuff */ + snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); + if ((err = snd_sbdsp_create(card, gcr + 0x10, pci->irq, @@ -711,12 +751,7 @@ } } -#ifdef SUPPORT_JOYSTICK - if (acard->res_joystick) { - acard->gameport.io = joystick; - gameport_register_port(&acard->gameport); - } -#endif + snd_als4000_create_gameport(acard, dev); if ((err = snd_card_register(card)) < 0) { snd_card_free(card); diff -Nru a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c --- a/sound/pci/au88x0/au88x0.c 2005-02-11 01:39:33 -05:00 +++ b/sound/pci/au88x0/au88x0.c 2005-02-11 01:39:33 -05:00 @@ -290,10 +290,9 @@ snd_card_free(card); return err; } - if ((err = vortex_gameport_register(chip)) < 0) { - snd_card_free(card); - return err; - } + + vortex_gameport_register(chip); + #if 0 if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH, sizeof(snd_vortex_synth_arg_t), &wave) < 0 diff -Nru a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h --- a/sound/pci/au88x0/au88x0.h 2005-02-11 01:39:33 -05:00 +++ b/sound/pci/au88x0/au88x0.h 2005-02-11 01:39:33 -05:00 @@ -272,7 +272,7 @@ /* Driver stuff. */ static int __devinit vortex_gameport_register(vortex_t * card); -static int __devexit vortex_gameport_unregister(vortex_t * card); +static void vortex_gameport_unregister(vortex_t * card); #ifndef CHIP_AU8820 static int __devinit vortex_eq_init(vortex_t * vortex); static int __devexit vortex_eq_free(vortex_t * vortex); diff -Nru a/sound/pci/au88x0/au88x0_game.c b/sound/pci/au88x0/au88x0_game.c --- a/sound/pci/au88x0/au88x0_game.c 2005-02-11 01:39:33 -05:00 +++ b/sound/pci/au88x0/au88x0_game.c 2005-02-11 01:39:33 -05:00 @@ -94,39 +94,42 @@ return 0; } -static int vortex_gameport_register(vortex_t * vortex) +static int __devinit vortex_gameport_register(vortex_t * vortex) { - if ((vortex->gameport = kcalloc(1, sizeof(struct gameport), GFP_KERNEL)) == NULL) - return -1; + struct gameport *gp; - vortex->gameport->port_data = vortex; - vortex->gameport->fuzz = 64; + vortex->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "vortex: cannot allocate memory for gameport\n"); + return -ENOMEM; + }; + + gameport_set_name(gp, "AU88x0 Gameport"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(vortex->pci_dev)); + gp->dev.parent = &vortex->pci_dev->dev; + + gp->read = vortex_game_read; + gp->trigger = vortex_game_trigger; + gp->cooked_read = vortex_game_cooked_read; + gp->open = vortex_game_open; + + gp->port_data = vortex; + gp->fuzz = 64; + + gameport_register_port(gp); - vortex->gameport->read = vortex_game_read; - vortex->gameport->trigger = vortex_game_trigger; - vortex->gameport->cooked_read = vortex_game_cooked_read; - vortex->gameport->open = vortex_game_open; - - gameport_register_port((struct gameport *)vortex->gameport); - -/* printk(KERN_INFO "gameport%d: %s at speed %d kHz\n", - vortex->gameport->number, vortex->pci_dev->name, vortex->gameport->speed); -*/ return 0; } -static int vortex_gameport_unregister(vortex_t * vortex) +static void vortex_gameport_unregister(vortex_t * vortex) { - if (vortex->gameport != NULL) { + if (vortex->gameport) { gameport_unregister_port(vortex->gameport); - kfree(vortex->gameport); + vortex->gameport = NULL; } - return 0; } #else - -static inline int vortex_gameport_register(vortex_t * vortex) { return 0; } -static inline int vortex_gameport_unregister(vortex_t * vortex) { return 0; } - +static inline int vortex_gameport_register(vortex_t * vortex) { return -ENOSYS; } +static inline void vortex_gameport_unregister(vortex_t * vortex) { } #endif diff -Nru a/sound/pci/azt3328.c b/sound/pci/azt3328.c --- a/sound/pci/azt3328.c 2005-02-11 01:39:33 -05:00 +++ b/sound/pci/azt3328.c 2005-02-11 01:39:33 -05:00 @@ -160,19 +160,19 @@ #endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ -#ifdef SUPPORT_JOYSTICK -static int joystick[SNDRV_CARDS]; -#endif - module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard."); + +static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ module_param_array(id, charp, NULL, 0444); MODULE_PARM_DESC(id, "ID string for AZF3328 soundcard."); + +static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard."); + #ifdef SUPPORT_JOYSTICK +static int joystick[SNDRV_CARDS]; module_param_array(joystick, bool, NULL, 0444); MODULE_PARM_DESC(joystick, "Enable joystick for AZF3328 soundcard."); #endif @@ -189,8 +189,7 @@ unsigned long mixer_port; #ifdef SUPPORT_JOYSTICK - struct gameport gameport; - struct resource *res_joystick; + struct gameport *gameport; #endif struct pci_dev *pci; @@ -1222,6 +1221,63 @@ /******************************************************************/ +#ifdef SUPPORT_JOYSTICK +static int __devinit snd_azf3328_config_joystick(azf3328_t *chip, int dev) +{ + struct gameport *gp; + struct resource *r; + + if (!joystick[dev]) + return -ENODEV; + + if (!(r = request_region(0x200, 8, "AZF3328 gameport"))) { + printk(KERN_WARNING "azt3328: cannot reserve joystick ports\n"); + return -EBUSY; + } + + chip->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "azt3328: cannot allocate memory for gameport\n"); + release_resource(r); + kfree_nocheck(r); + return -ENOMEM; + } + + gameport_set_name(gp, "AZF3328 Gameport"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); + gp->dev.parent = &chip->pci->dev; + gp->io = 0x200; + gp->port_data = r; + + snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR, + snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) | LEGACY_JOY); + + gameport_register_port(chip->gameport); + + return 0; +} + +static void snd_azf3328_free_joystick(azf3328_t *chip) +{ + if (chip->gameport) { + struct resource *r = chip->gameport->port_data; + + gameport_unregister_port(chip->gameport); + chip->gameport = NULL; + /* disable gameport */ + snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR, + snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY); + release_resource(r); + kfree_nocheck(r); + } +} +#else +static inline int snd_azf3328_config_joystick(azf3328_t *chip, int dev) { return -ENOSYS; } +static inline void snd_azf3328_free_joystick(azf3328_t *chip) { } +#endif + +/******************************************************************/ + static int snd_azf3328_free(azf3328_t *chip) { if (chip->irq < 0) @@ -1236,16 +1292,7 @@ synchronize_irq(chip->irq); __end_hw: -#ifdef SUPPORT_JOYSTICK - if (chip->res_joystick) { - gameport_unregister_port(&chip->gameport); - /* disable gameport */ - snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR, - snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY); - release_resource(chip->res_joystick); - kfree_nocheck(chip->res_joystick); - } -#endif + snd_azf3328_free_joystick(chip); if (chip->irq >= 0) free_irq(chip->irq, (void *)chip); pci_release_regions(chip->pci); @@ -1373,28 +1420,6 @@ return 0; } -#ifdef SUPPORT_JOYSTICK -static void __devinit snd_azf3328_config_joystick(azf3328_t *chip, int joystick) -{ - unsigned char val; - - if (joystick == 1) { - if ((chip->res_joystick = request_region(0x200, 8, "AZF3328 gameport")) != NULL) - chip->gameport.io = 0x200; - } - - val = inb(chip->io2_port + IDX_IO2_LEGACY_ADDR); - if (chip->res_joystick) - val |= LEGACY_JOY; - else - val &= ~LEGACY_JOY; - - outb(val, chip->io2_port + IDX_IO2_LEGACY_ADDR); - if (chip->res_joystick) - gameport_register_port(&chip->gameport); -} -#endif - static int __devinit snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { @@ -1465,9 +1490,9 @@ "azt3328: Feel free to contact hw7oshyuv3001@sneakemail.com for bug reports etc.!\n"); #endif -#ifdef SUPPORT_JOYSTICK - snd_azf3328_config_joystick(chip, joystick[dev]); -#endif + if (snd_azf3328_config_joystick(chip, dev) < 0) + snd_azf3328_io2_write(chip, IDX_IO2_LEGACY_ADDR, + snd_azf3328_io2_read(chip, IDX_IO2_LEGACY_ADDR) & ~LEGACY_JOY); pci_set_drvdata(pci, card); dev++; diff -Nru a/sound/pci/cmipci.c b/sound/pci/cmipci.c --- a/sound/pci/cmipci.c 2005-02-11 01:39:33 -05:00 +++ b/sound/pci/cmipci.c 2005-02-11 01:39:33 -05:00 @@ -471,8 +471,7 @@ snd_rawmidi_t *rmidi; #ifdef SUPPORT_JOYSTICK - struct gameport gameport; - struct resource *res_joystick; + struct gameport *gameport; #endif spinlock_t reg_lock; @@ -2522,6 +2521,71 @@ strcpy(cm->card->driver + strlen(cm->card->driver), "-SWIEC"); } +#ifdef SUPPORT_JOYSTICK +static int __devinit snd_cmipci_create_gameport(cmipci_t *cm, int dev) +{ + static int ports[] = { 0x201, 0x200, 0 }; /* FIXME: majority is 0x201? */ + struct gameport *gp; + struct resource *r = NULL; + int i, io_port = 0; + + if (joystick_port[dev] == 0) + return -ENODEV; + + if (joystick_port[dev] == 1) { /* auto-detect */ + for (i = 0; ports[i]; i++) { + io_port = ports[i]; + r = request_region(io_port, 1, "CMIPCI gameport"); + if (r) + break; + } + } else { + io_port = joystick_port[dev]; + r = request_region(io_port, 1, "CMIPCI gameport"); + } + + if (!r) { + printk(KERN_WARNING "cmipci: cannot reserve joystick ports\n"); + return -EBUSY; + } + + cm->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "cmipci: cannot allocate memory for gameport\n"); + release_resource(r); + kfree_nocheck(r); + return -ENOMEM; + } + gameport_set_name(gp, "C-Media Gameport"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(cm->pci)); + gp->dev.parent = &cm->pci->dev; + gp->io = io_port; + gp->port_data = r; + + snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN); + + gameport_register_port(cm->gameport); + + return 0; +} + +static void snd_cmipci_free_gameport(cmipci_t *cm) +{ + if (cm->gameport) { + struct resource *r = cm->gameport->port_data; + + gameport_unregister_port(cm->gameport); + cm->gameport = NULL; + + snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN); + release_resource(r); + kfree_nocheck(r); + } +} +#else +static inline int snd_cmipci_create_gameport(cmipci_t *cm, int dev) { return -ENOSYS; } +static inline void snd_cmipci_free_gameport(cmipci_t *cm) { } +#endif static int snd_cmipci_free(cmipci_t *cm) { @@ -2541,14 +2605,8 @@ free_irq(cm->irq, (void *)cm); } -#ifdef SUPPORT_JOYSTICK - if (cm->res_joystick) { - gameport_unregister_port(&cm->gameport); - snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN); - release_resource(cm->res_joystick); - kfree_nocheck(cm->res_joystick); - } -#endif + + snd_cmipci_free_gameport(cm); pci_release_regions(cm->pci); pci_disable_device(cm->pci); kfree(cm); @@ -2757,31 +2815,9 @@ snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPDIF48K|CM_SPDF_AC97); #endif /* USE_VAR48KRATE */ -#ifdef SUPPORT_JOYSTICK - if (joystick_port[dev] > 0) { - if (joystick_port[dev] == 1) { /* auto-detect */ - static int ports[] = { 0x201, 0x200, 0 }; /* FIXME: majority is 0x201? */ - int i; - for (i = 0; ports[i]; i++) { - joystick_port[dev] = ports[i]; - cm->res_joystick = request_region(ports[i], 1, "CMIPCI gameport"); - if (cm->res_joystick) - break; - } - } else { - cm->res_joystick = request_region(joystick_port[dev], 1, "CMIPCI gameport"); - } - } - if (cm->res_joystick) { - cm->gameport.io = joystick_port[dev]; - snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN); - gameport_register_port(&cm->gameport); - } else { - if (joystick_port[dev] > 0) - printk(KERN_WARNING "cmipci: cannot reserve joystick ports\n"); + if (snd_cmipci_create_gameport(cm, dev) < 0) snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN); - } -#endif + snd_card_set_dev(card, &pci->dev); *rcmipci = cm; diff -Nru a/sound/pci/cs4281.c b/sound/pci/cs4281.c --- a/sound/pci/cs4281.c 2005-02-11 01:39:34 -05:00 +++ b/sound/pci/cs4281.c 2005-02-11 01:39:34 -05:00 @@ -495,7 +495,7 @@ unsigned int midcr; unsigned int uartm; - struct snd_cs4281_gameport *gameport; + struct gameport *gameport; #ifdef CONFIG_PM u32 suspend_regs[SUSPEND_REGISTERS]; @@ -1238,38 +1238,29 @@ #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) -typedef struct snd_cs4281_gameport { - struct gameport info; - cs4281_t *chip; -} cs4281_gameport_t; - static void snd_cs4281_gameport_trigger(struct gameport *gameport) { - cs4281_gameport_t *gp = (cs4281_gameport_t *)gameport; - cs4281_t *chip; - snd_assert(gp, return); - chip = gp->chip; + cs4281_t *chip = gameport->port_data; + + snd_assert(chip, return); snd_cs4281_pokeBA0(chip, BA0_JSPT, 0xff); } static unsigned char snd_cs4281_gameport_read(struct gameport *gameport) { - cs4281_gameport_t *gp = (cs4281_gameport_t *)gameport; - cs4281_t *chip; - snd_assert(gp, return 0); - chip = gp->chip; + cs4281_t *chip = gameport->port_data; + + snd_assert(chip, return 0); return snd_cs4281_peekBA0(chip, BA0_JSPT); } #ifdef COOKED_MODE static int snd_cs4281_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) { - cs4281_gameport_t *gp = (cs4281_gameport_t *)gameport; - cs4281_t *chip; + cs4281_t *chip = gameport->port_data; unsigned js1, js2, jst; - snd_assert(gp, return 0); - chip = gp->chip; + snd_assert(chip, return 0); js1 = snd_cs4281_peekBA0(chip, BA0_JSC1); js2 = snd_cs4281_peekBA0(chip, BA0_JSC2); @@ -1282,10 +1273,12 @@ axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF; axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF; - for(jst=0;jst<4;++jst) - if(axes[jst]==0xFFFF) axes[jst] = -1; + for (jst = 0; jst < 4; ++jst) + if (axes[jst] == 0xFFFF) axes[jst] = -1; return 0; } +#else +#define snd_cs4281_gameport_cooked_read NULL #endif static int snd_cs4281_gameport_open(struct gameport *gameport, int mode) @@ -1303,31 +1296,43 @@ return 0; } -static void __devinit snd_cs4281_gameport(cs4281_t *chip) +static int __devinit snd_cs4281_create_gameport(cs4281_t *chip) { - cs4281_gameport_t *gp; - gp = kmalloc(sizeof(*gp), GFP_KERNEL); - if (! gp) { - snd_printk(KERN_ERR "cannot allocate gameport area\n"); - return; - } - memset(gp, 0, sizeof(*gp)); - gp->info.open = snd_cs4281_gameport_open; - gp->info.read = snd_cs4281_gameport_read; - gp->info.trigger = snd_cs4281_gameport_trigger; -#ifdef COOKED_MODE - gp->info.cooked_read = snd_cs4281_gameport_cooked_read; -#endif - gp->chip = chip; - chip->gameport = gp; + struct gameport *gp; + + chip->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "cs4281: cannot allocate memory for gameport\n"); + return -ENOMEM; + } + + gameport_set_name(gp, "CS4281 Gameport"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); + gp->dev.parent = &chip->pci->dev; + gp->open = snd_cs4281_gameport_open; + gp->read = snd_cs4281_gameport_read; + gp->trigger = snd_cs4281_gameport_trigger; + gp->cooked_read = snd_cs4281_gameport_cooked_read; + gp->port_data = chip; snd_cs4281_pokeBA0(chip, BA0_JSIO, 0xFF); // ? snd_cs4281_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW); - gameport_register_port(&gp->info); + + gameport_register_port(gp); + + return 0; } +static void snd_cs4281_free_gameport(cs4281_t *chip) +{ + if (chip->gameport) { + gameport_unregister_port(chip->gameport); + chip->gameport = NULL; + } +} #else -#define snd_cs4281_gameport(chip) /*NOP*/ +static inline int snd_cs4281_gameport(cs4281_t *chip) { return -ENOSYS; } +static inline void snd_cs4281_gameport_free(cs4281_t *chip) { } #endif /* CONFIG_GAMEPORT || (MODULE && CONFIG_GAMEPORT_MODULE) */ @@ -1337,12 +1342,8 @@ static int snd_cs4281_free(cs4281_t *chip) { -#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) - if (chip->gameport) { - gameport_unregister_port(&chip->gameport->info); - kfree(chip->gameport); - } -#endif + snd_cs4281_free_gameport(chip); + if (chip->irq >= 0) synchronize_irq(chip->irq); @@ -1990,7 +1991,7 @@ snd_card_free(card); return err; } - snd_cs4281_gameport(chip); + snd_cs4281_create_gameport(chip); strcpy(card->driver, "CS4281"); strcpy(card->shortname, "Cirrus Logic CS4281"); sprintf(card->longname, "%s at 0x%lx, irq %d", diff -Nru a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c --- a/sound/pci/cs46xx/cs46xx_lib.c 2005-02-11 01:39:33 -05:00 +++ b/sound/pci/cs46xx/cs46xx_lib.c 2005-02-11 01:39:33 -05:00 @@ -2690,37 +2690,28 @@ #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) -typedef struct snd_cs46xx_gameport { - struct gameport info; - cs46xx_t *chip; -} cs46xx_gameport_t; - static void snd_cs46xx_gameport_trigger(struct gameport *gameport) { - cs46xx_gameport_t *gp = (cs46xx_gameport_t *)gameport; - cs46xx_t *chip; - snd_assert(gp, return); - chip = gp->chip; + cs46xx_t *chip = gameport->port_data; + + snd_assert(chip, return); snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF); } static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport) { - cs46xx_gameport_t *gp = (cs46xx_gameport_t *)gameport; - cs46xx_t *chip; - snd_assert(gp, return 0); - chip = gp->chip; + cs46xx_t *chip = gameport->port_data; + + snd_assert(chip, return 0); return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io); } static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) { - cs46xx_gameport_t *gp = (cs46xx_gameport_t *)gameport; - cs46xx_t *chip; + cs46xx_t *chip = gameport->port_data; unsigned js1, js2, jst; - - snd_assert(gp, return 0); - chip = gp->chip; + + snd_assert(chip, return 0); js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1); js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2); @@ -2751,33 +2742,44 @@ return 0; } -void __devinit snd_cs46xx_gameport(cs46xx_t *chip) +int __devinit snd_cs46xx_gameport(cs46xx_t *chip) { - cs46xx_gameport_t *gp; - gp = kmalloc(sizeof(*gp), GFP_KERNEL); - if (! gp) { - snd_printk("cannot allocate gameport area\n"); - return; + struct gameport *gp; + + chip->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "cs46xx: cannot allocate memory for gameport\n"); + return -ENOMEM; } - memset(gp, 0, sizeof(*gp)); - gp->info.open = snd_cs46xx_gameport_open; - gp->info.read = snd_cs46xx_gameport_read; - gp->info.trigger = snd_cs46xx_gameport_trigger; - gp->info.cooked_read = snd_cs46xx_gameport_cooked_read; - gp->chip = chip; - chip->gameport = gp; + + gameport_set_name(gp, "CS46xx Gameport"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); + gp->dev.parent = &chip->pci->dev; + gp->port_data = chip; + + gp->open = snd_cs46xx_gameport_open; + gp->read = snd_cs46xx_gameport_read; + gp->trigger = snd_cs46xx_gameport_trigger; + gp->cooked_read = snd_cs46xx_gameport_cooked_read; snd_cs46xx_pokeBA0(chip, BA0_JSIO, 0xFF); // ? snd_cs46xx_pokeBA0(chip, BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW); - gameport_register_port(&gp->info); -} -#else + gameport_register_port(gp); -void __devinit snd_cs46xx_gameport(cs46xx_t *chip) -{ + return 0; } +static inline void snd_cs46xx_remove_gameport(cs46xx_t *chip) +{ + if (chip->gameport) { + gameport_unregister_port(chip->gameport); + chip->gameport = NULL; + } +} +#else +int __devinit snd_cs46xx_gameport(cs46xx_t *chip) { return -ENOSYS; } +static inline void snd_cs46xx_remove_gameport(cs46xx_t *chip) { } #endif /* CONFIG_GAMEPORT */ /* @@ -2893,12 +2895,7 @@ if (chip->active_ctrl) chip->active_ctrl(chip, 1); -#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) - if (chip->gameport) { - gameport_unregister_port(&chip->gameport->info); - kfree(chip->gameport); - } -#endif + snd_cs46xx_remove_gameport(chip); if (chip->amplifier_ctrl) chip->amplifier_ctrl(chip, -chip->amplifier); /* force to off */ diff -Nru a/sound/pci/ens1370.c b/sound/pci/ens1370.c --- a/sound/pci/ens1370.c 2005-02-11 01:39:34 -05:00 +++ b/sound/pci/ens1370.c 2005-02-11 01:39:34 -05:00 @@ -430,7 +430,7 @@ #endif #ifdef SUPPORT_JOYSTICK - struct gameport gameport; + struct gameport *gameport; #endif }; @@ -1734,43 +1734,99 @@ #endif /* CHIP1370 */ #ifdef SUPPORT_JOYSTICK -static int snd_ensoniq_joystick(ensoniq_t *ensoniq, long port) -{ + #ifdef CHIP1371 - if (port == 1) { /* auto-detect */ - for (port = 0x200; port <= 0x218; port += 8) - if (request_region(port, 8, "ens137x: gameport")) +static int __devinit snd_ensoniq_get_joystick_port(int dev) +{ + switch (joystick_port[dev]) { + case 0: /* disabled */ + case 1: /* auto-detect */ + case 0x200: + case 0x208: + case 0x210: + case 0x218: + return joystick_port[dev]; + + default: + printk(KERN_ERR "ens1371: invalid joystick port %#x", joystick_port[dev]); + return 0; + } +} +#else +static inline int snd_ensoniq_get_joystick_port(int dev) +{ + return joystick[dev] ? 0x200 : 0; +} +#endif + +static int __devinit snd_ensoniq_create_gameport(ensoniq_t *ensoniq, int dev) +{ + struct gameport *gp; + int io_port; + + io_port = snd_ensoniq_get_joystick_port(dev); + + switch (io_port) { + case 0: + return -ENOSYS; + + case 1: /* auto_detect */ + for (io_port = 0x200; io_port <= 0x218; io_port += 8) + if (request_region(io_port, 8, "ens137x: gameport")) break; - if (port > 0x218) { - snd_printk("no gameport available\n"); + if (io_port > 0x218) { + printk(KERN_WARNING "ens137x: no gameport ports available\n"); return -EBUSY; } - } else -#endif - { - if (!request_region(port, 8, "ens137x: gameport")) { - snd_printk("gameport io port 0x%03x in use", ensoniq->gameport.io); + break; + + default: + if (!request_region(io_port, 8, "ens137x: gameport")) { + printk(KERN_WARNING "ens137x: gameport io port 0x%#x in use\n", io_port); return -EBUSY; } + break; } - ensoniq->gameport.io = port; + + ensoniq->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "ens137x: cannot allocate memory for gameport\n"); + release_region(io_port, 8); + return -ENOMEM; + } + + gameport_set_name(gp, "ES137x"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(ensoniq->pci)); + gp->dev.parent = &ensoniq->pci->dev; + gp->io = io_port; + ensoniq->ctrl |= ES_JYSTK_EN; #ifdef CHIP1371 ensoniq->ctrl &= ~ES_1371_JOY_ASELM; - ensoniq->ctrl |= ES_1371_JOY_ASEL((ensoniq->gameport.io - 0x200) / 8); + ensoniq->ctrl |= ES_1371_JOY_ASEL((io_port - 0x200) / 8); #endif outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - gameport_register_port(&ensoniq->gameport); + + gameport_register_port(ensoniq->gameport); + return 0; } -static void snd_ensoniq_joystick_free(ensoniq_t *ensoniq) +static void snd_ensoniq_free_gameport(ensoniq_t *ensoniq) { - gameport_unregister_port(&ensoniq->gameport); - ensoniq->ctrl &= ~ES_JYSTK_EN; - outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); - release_region(ensoniq->gameport.io, 8); + if (ensoniq->gameport) { + int port = ensoniq->gameport->io; + + gameport_unregister_port(ensoniq->gameport); + ensoniq->gameport = NULL; + ensoniq->ctrl &= ~ES_JYSTK_EN; + outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); + release_region(port, 8); + } } +#else +static inline int snd_ensoniq_create_gameport(ensoniq_t *ensoniq, long port) { return -ENOSYS; } +static inline void snd_ensoniq_free_gameport(ensoniq_t *ensoniq) { } #endif /* SUPPORT_JOYSTICK */ /* @@ -1810,10 +1866,7 @@ static int snd_ensoniq_free(ensoniq_t *ensoniq) { -#ifdef SUPPORT_JOYSTICK - if (ensoniq->ctrl & ES_JYSTK_EN) - snd_ensoniq_joystick_free(ensoniq); -#endif + snd_ensoniq_free_gameport(ensoniq); if (ensoniq->irq < 0) goto __hw_end; #ifdef CHIP1370 @@ -2313,22 +2366,9 @@ snd_card_free(card); return err; } -#ifdef SUPPORT_JOYSTICK -#ifdef CHIP1371 - switch (joystick_port[dev]) { - case 1: /* auto-detect */ - case 0x200: - case 0x208: - case 0x210: - case 0x218: - snd_ensoniq_joystick(ensoniq, joystick_port[dev]); - break; - } -#else - if (joystick[dev]) - snd_ensoniq_joystick(ensoniq, 0x200); -#endif -#endif /* SUPPORT_JOYSTICK */ + + snd_ensoniq_create_gameport(ensoniq, dev); + strcpy(card->driver, DRIVER_NAME); strcpy(card->shortname, "Ensoniq AudioPCI"); diff -Nru a/sound/pci/es1938.c b/sound/pci/es1938.c --- a/sound/pci/es1938.c 2005-02-11 01:39:33 -05:00 +++ b/sound/pci/es1938.c 2005-02-11 01:39:33 -05:00 @@ -72,6 +72,10 @@ "{ESS,ES1969}," "{TerraTec,128i PCI}}"); +#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) +#define SUPPORT_JOYSTICK 1 +#endif + #ifndef PCI_VENDOR_ID_ESS #define PCI_VENDOR_ID_ESS 0x125d #endif @@ -237,8 +241,8 @@ spinlock_t mixer_lock; snd_info_entry_t *proc_entry; -#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) - struct gameport gameport; +#ifdef SUPPORT_JOYSTICK + struct gameport *gameport; #endif #ifdef CONFIG_PM unsigned char saved_regs[SAVED_REG_SIZE]; @@ -1418,6 +1422,39 @@ } #endif /* CONFIG_PM */ +#ifdef SUPPORT_JOYSTICK +static int __devinit snd_es1938_create_gameport(es1938_t *chip) +{ + struct gameport *gp; + + chip->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "es1938: cannot allocate memory for gameport\n"); + return -ENOMEM; + } + + gameport_set_name(gp, "ES1938"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); + gp->dev.parent = &chip->pci->dev; + gp->io = chip->game_port; + + gameport_register_port(gp); + + return 0; +} + +static void snd_es1938_free_gameport(es1938_t *chip) +{ + if (chip->gameport) { + gameport_unregister_port(chip->gameport); + chip->gameport = NULL; + } +} +#else +static inline int snd_es1938_create_gameport(es1938_t *chip) { return -ENOSYS; } +static inline void snd_es1938_free_gameport(es1938_t *chip) { } +#endif /* SUPPORT_JOYSTICK */ + static int snd_es1938_free(es1938_t *chip) { /* disable irqs */ @@ -1425,10 +1462,8 @@ if (chip->rmidi) snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0); -#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) - if (chip->gameport.io) - gameport_unregister_port(&chip->gameport); -#endif + snd_es1938_free_gameport(chip); + if (chip->irq >= 0) free_irq(chip->irq, (void *)chip); pci_release_regions(chip->pci); @@ -1698,10 +1733,7 @@ snd_es1938_mixer_bits(chip, ESSSB_IREG_MPU401CONTROL, 0x40, 0x40); } -#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) - chip->gameport.io = chip->game_port; - gameport_register_port(&chip->gameport); -#endif + snd_es1938_create_gameport(chip); if ((err = snd_card_register(card)) < 0) { snd_card_free(card); diff -Nru a/sound/pci/es1968.c b/sound/pci/es1968.c --- a/sound/pci/es1968.c 2005-02-11 01:39:34 -05:00 +++ b/sound/pci/es1968.c 2005-02-11 01:39:34 -05:00 @@ -605,8 +605,7 @@ #endif #ifdef SUPPORT_JOYSTICK - struct gameport gameport; - struct resource *res_joystick; + struct gameport *gameport; #endif }; @@ -2450,6 +2449,59 @@ } #endif /* CONFIG_PM */ +#ifdef SUPPORT_JOYSTICK +#define JOYSTICK_ADDR 0x200 +static int __devinit snd_es1968_create_gameport(es1968_t *chip, int dev) +{ + struct gameport *gp; + struct resource *r; + u16 val; + + if (!joystick[dev]) + return -ENODEV; + + r = request_region(JOYSTICK_ADDR, 8, "ES1968 gameport"); + if (!r) + return -EBUSY; + + chip->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "es1968: cannot allocate memory for gameport\n"); + release_resource(r); + kfree_nocheck(r); + return -ENOMEM; + } + + pci_read_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, &val); + pci_write_config_word(chip->pci, ESM_LEGACY_AUDIO_CONTROL, val | 0x04); + + gameport_set_name(gp, "ES1968 Gameport"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); + gp->dev.parent = &chip->pci->dev; + gp->io = JOYSTICK_ADDR; + + gameport_register_port(gp); + + return 0; +} + +static void snd_es1968_free_gameport(es1968_t *chip) +{ + if (chip->gameport) { + struct resource *r = chip->gameport->port_data; + + gameport_unregister_port(chip->gameport); + chip->gameport = NULL; + + release_resource(r); + kfree_nocheck(r); + } +} +#else +static inline int snd_es1968_create_gameport(es1968_t *chip, int dev) { return -ENOSYS; } +static inline void snd_es1968_free_gameport(es1968_t *chip) { } +#endif + static int snd_es1968_free(es1968_t *chip) { if (chip->io_port) { @@ -2460,13 +2512,7 @@ if (chip->irq >= 0) free_irq(chip->irq, (void *)chip); -#ifdef SUPPORT_JOYSTICK - if (chip->res_joystick) { - gameport_unregister_port(&chip->gameport); - release_resource(chip->res_joystick); - kfree_nocheck(chip->res_joystick); - } -#endif + snd_es1968_free_gameport(chip); snd_es1968_set_acpi(chip, ACPI_D3); chip->master_switch = NULL; chip->master_volume = NULL; @@ -2693,17 +2739,7 @@ } } -#ifdef SUPPORT_JOYSTICK -#define JOYSTICK_ADDR 0x200 - if (joystick[dev] && - (chip->res_joystick = request_region(JOYSTICK_ADDR, 8, "ES1968 gameport")) != NULL) { - u16 val; - pci_read_config_word(pci, ESM_LEGACY_AUDIO_CONTROL, &val); - pci_write_config_word(pci, ESM_LEGACY_AUDIO_CONTROL, val | 0x04); - chip->gameport.io = JOYSTICK_ADDR; - gameport_register_port(&chip->gameport); - } -#endif + snd_es1968_create_gameport(chip, dev); snd_es1968_start_irq(chip); diff -Nru a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c --- a/sound/pci/sonicvibes.c 2005-02-11 01:39:33 -05:00 +++ b/sound/pci/sonicvibes.c 2005-02-11 01:39:33 -05:00 @@ -46,6 +46,10 @@ MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{S3,SonicVibes PCI}}"); +#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) +#define SUPPORT_JOYSTICK 1 +#endif + #ifndef PCI_VENDOR_ID_S3 #define PCI_VENDOR_ID_S3 0x5333 #endif @@ -242,8 +246,8 @@ snd_kcontrol_t *master_mute; snd_kcontrol_t *master_volume; -#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) - struct gameport gameport; +#ifdef SUPPORT_JOYSTICK + struct gameport *gameport; #endif }; @@ -1163,15 +1167,47 @@ */ +#ifdef SUPPORT_JOYSTICK static snd_kcontrol_new_t snd_sonicvibes_game_control __devinitdata = SONICVIBES_SINGLE("Joystick Speed", 0, SV_IREG_GAME_PORT, 1, 15, 0); -static int snd_sonicvibes_free(sonicvibes_t *sonic) +static int __devinit snd_sonicvibes_create_gameport(sonicvibes_t *sonic) { -#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) - if (sonic->gameport.io) - gameport_unregister_port(&sonic->gameport); + struct gameport *gp; + + sonic->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "sonicvibes: cannot allocate memory for gameport\n"); + return -ENOMEM; + } + + gameport_set_name(gp, "SonicVibes Gameport"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(sonic->pci)); + gp->dev.parent = &sonic->pci->dev; + gp->io = sonic->game_port; + + gameport_register_port(gp); + + snd_ctl_add(sonic->card, snd_ctl_new1(&snd_sonicvibes_game_control, sonic)); + + return 0; +} + +static void snd_sonicvibes_free_gameport(sonicvibes_t *sonic) +{ + if (sonic->gameport) { + gameport_unregister_port(sonic->gameport); + sonic->gameport = NULL; + } +} +#else +static inline int snd_sonicvibes_create_gameport(sonicvibes_t *sonic) { return -ENOSYS; } +static inline void snd_sonicvibes_free_gameport(sonicvibes_t *sonic) { } #endif + +static int snd_sonicvibes_free(sonicvibes_t *sonic) +{ + snd_sonicvibes_free_gameport(sonic); pci_write_config_dword(sonic->pci, 0x40, sonic->dmaa_port); pci_write_config_dword(sonic->pci, 0x48, sonic->dmac_port); if (sonic->irq >= 0) @@ -1332,7 +1368,6 @@ snd_sonicvibes_debug(sonic); #endif sonic->revision = snd_sonicvibes_in(sonic, SV_IREG_REVISION); - snd_ctl_add(card, snd_ctl_new1(&snd_sonicvibes_game_control, sonic)); if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, sonic, &ops)) < 0) { snd_sonicvibes_free(sonic); @@ -1459,10 +1494,8 @@ snd_card_free(card); return err; } -#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) - sonic->gameport.io = sonic->game_port; - gameport_register_port(&sonic->gameport); -#endif + + snd_sonicvibes_create_gameport(sonic); if ((err = snd_card_register(card)) < 0) { snd_card_free(card); diff -Nru a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c --- a/sound/pci/trident/trident.c 2005-02-11 01:39:33 -05:00 +++ b/sound/pci/trident/trident.c 2005-02-11 01:39:33 -05:00 @@ -157,7 +157,7 @@ } #endif - snd_trident_gameport(trident); + snd_trident_create_gameport(trident); if ((err = snd_card_register(card)) < 0) { snd_card_free(card); diff -Nru a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c --- a/sound/pci/trident/trident_main.c 2005-02-11 01:39:33 -05:00 +++ b/sound/pci/trident/trident_main.c 2005-02-11 01:39:33 -05:00 @@ -3110,37 +3110,28 @@ #if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) -typedef struct snd_trident_gameport { - struct gameport info; - trident_t *chip; -} trident_gameport_t; - static unsigned char snd_trident_gameport_read(struct gameport *gameport) { - trident_gameport_t *gp = (trident_gameport_t *)gameport; - trident_t *chip; - snd_assert(gp, return 0); - chip = gp->chip; + trident_t *chip = gameport->port_data; + + snd_assert(chip, return 0); return inb(TRID_REG(chip, GAMEPORT_LEGACY)); } static void snd_trident_gameport_trigger(struct gameport *gameport) { - trident_gameport_t *gp = (trident_gameport_t *)gameport; - trident_t *chip; - snd_assert(gp, return); - chip = gp->chip; + trident_t *chip = gameport->port_data; + + snd_assert(chip, return 0); outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY)); } static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) { - trident_gameport_t *gp = (trident_gameport_t *)gameport; - trident_t *chip; + trident_t *chip = gameport->port_data; int i; - snd_assert(gp, return 0); - chip = gp->chip; + snd_assert(chip, return 0); *buttons = (~inb(TRID_REG(chip, GAMEPORT_LEGACY)) >> 4) & 0xf; @@ -3154,10 +3145,9 @@ static int snd_trident_gameport_open(struct gameport *gameport, int mode) { - trident_gameport_t *gp = (trident_gameport_t *)gameport; - trident_t *chip; - snd_assert(gp, return -1); - chip = gp->chip; + trident_t *chip = gameport->port_data; + + snd_assert(chip, return 0); switch (mode) { case GAMEPORT_MODE_COOKED: @@ -3173,30 +3163,42 @@ } } -void __devinit snd_trident_gameport(trident_t *chip) +int __devinit snd_trident_create_gameport(trident_t *chip) { - trident_gameport_t *gp; - gp = kmalloc(sizeof(*gp), GFP_KERNEL); - if (! gp) { - snd_printk("cannot allocate gameport area\n"); - return; - } - memset(gp, 0, sizeof(*gp)); - gp->chip = chip; - gp->info.fuzz = 64; - gp->info.read = snd_trident_gameport_read; - gp->info.trigger = snd_trident_gameport_trigger; - gp->info.cooked_read = snd_trident_gameport_cooked_read; - gp->info.open = snd_trident_gameport_open; - chip->gameport = gp; + struct gameport *gp; + + chip->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "trident: cannot allocate memory for gameport\n"); + return -ENOMEM; + } + + gameport_set_name(gp, "Trident 4DWave"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); + gp->dev.parent = &chip->pci->dev; + + gp->port_data = chip; + gp->fuzz = 64; + gp->read = snd_trident_gameport_read; + gp->trigger = snd_trident_gameport_trigger; + gp->cooked_read = snd_trident_gameport_cooked_read; + gp->open = snd_trident_gameport_open; - gameport_register_port(&gp->info); + gameport_register_port(gp); + + return 0; } -#else -void __devinit snd_trident_gameport(trident_t *chip) +static inline void snd_trident_free_gameport(trident_t *chip) { + if (chip->gameport) { + gameport_unregister_port(chip->gameport); + chip->gameport = NULL; + } } +#else +int __devinit snd_trident_create_gameport(trident_t *chip) { return -ENOSYS; } +static inline void snd_trident_free_gameport(trident_t *chip) { } #endif /* CONFIG_GAMEPORT */ /* @@ -3661,12 +3663,7 @@ static int snd_trident_free(trident_t *trident) { -#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) - if (trident->gameport) { - gameport_unregister_port(&trident->gameport->info); - kfree(trident->gameport); - } -#endif + snd_trident_free_gameport(trident); snd_trident_disable_eso(trident); // Disable S/PDIF out if (trident->device == TRIDENT_DEVICE_ID_NX) diff -Nru a/sound/pci/via82xx.c b/sound/pci/via82xx.c --- a/sound/pci/via82xx.c 2005-02-11 01:39:34 -05:00 +++ b/sound/pci/via82xx.c 2005-02-11 01:39:34 -05:00 @@ -394,8 +394,7 @@ snd_info_entry_t *proc_entry; #ifdef SUPPORT_JOYSTICK - struct gameport gameport; - struct resource *res_joystick; + struct gameport *gameport; #endif }; @@ -1635,11 +1634,70 @@ return 0; } +#ifdef SUPPORT_JOYSTICK +#define JOYSTICK_ADDR 0x200 +static int __devinit snd_via686_create_gameport(via82xx_t *chip, int dev, unsigned char *legacy) +{ + struct gameport *gp; + struct resource *r; + + if (!joystick[dev]) + return -ENODEV; + + r = request_region(JOYSTICK_ADDR, 8, "VIA686 gameport"); + if (!r) { + printk(KERN_WARNING "via82xx: cannot reserve joystick port 0x%#x\n", JOYSTICK_ADDR); + return -EBUSY; + } + + chip->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "via82xx: cannot allocate memory for gameport\n"); + release_resource(r); + kfree_nocheck(r); + return -ENOMEM; + } + + gameport_set_name(gp, "VIA686 Gameport"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); + gp->dev.parent = &chip->pci->dev; + gp->io = JOYSTICK_ADDR; + gp->port_data = r; + + /* Enable legacy joystick port */ + *legacy |= VIA_FUNC_ENABLE_GAME; + pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, *legacy); + + gameport_register_port(chip->gameport); + + return 0; +} + +static void snd_via686_free_gameport(via82xx_t *chip) +{ + if (chip->gameport) { + struct resource *r = chip->gameport->port_data; + + gameport_unregister_port(chip->gameport); + chip->gameport = NULL; + release_resource(r); + kfree_nocheck(r); + } +} +#else +static inline int snd_via686_create_gameport(via82xx_t *chip, int dev, unsigned char *legacy) +{ + return -ENOSYS; +} +static inline void snd_via686_free_gameport(via82xx_t *chip) { } +#endif + + /* * */ -static int snd_via8233_init_misc(via82xx_t *chip, int dev) +static int __devinit snd_via8233_init_misc(via82xx_t *chip, int dev) { int i, err, caps; unsigned char val; @@ -1671,7 +1729,7 @@ return 0; } -static int snd_via686_init_misc(via82xx_t *chip, int dev) +static int __devinit snd_via686_init_misc(via82xx_t *chip, int dev) { unsigned char legacy, legacy_cfg; int rev_h = 0; @@ -1718,15 +1776,6 @@ mpu_port[dev] = 0; } -#ifdef SUPPORT_JOYSTICK -#define JOYSTICK_ADDR 0x200 - if (joystick[dev] && - (chip->res_joystick = request_region(JOYSTICK_ADDR, 8, "VIA686 gameport")) != NULL) { - legacy |= VIA_FUNC_ENABLE_GAME; - chip->gameport.io = JOYSTICK_ADDR; - } -#endif - pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy); pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg); if (chip->mpu_res) { @@ -1741,10 +1790,7 @@ pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, legacy); } -#ifdef SUPPORT_JOYSTICK - if (chip->res_joystick) - gameport_register_port(&chip->gameport); -#endif + snd_via686_create_gameport(chip, dev, &legacy); #ifdef CONFIG_PM chip->legacy_saved = legacy; @@ -1973,14 +2019,9 @@ kfree_nocheck(chip->mpu_res); } pci_release_regions(chip->pci); + if (chip->chip_type == TYPE_VIA686) { -#ifdef SUPPORT_JOYSTICK - if (chip->res_joystick) { - gameport_unregister_port(&chip->gameport); - release_resource(chip->res_joystick); - kfree_nocheck(chip->res_joystick); - } -#endif + snd_via686_free_gameport(chip); pci_write_config_byte(chip->pci, VIA_FUNC_ENABLE, chip->old_legacy); pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, chip->old_legacy_cfg); } diff -Nru a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c --- a/sound/pci/ymfpci/ymfpci.c 2005-02-11 01:39:33 -05:00 +++ b/sound/pci/ymfpci/ymfpci.c 2005-02-11 01:39:33 -05:00 @@ -79,6 +79,96 @@ MODULE_DEVICE_TABLE(pci, snd_ymfpci_ids); +#ifdef SUPPORT_JOYSTICK +static int __devinit snd_ymfpci_create_gameport(ymfpci_t *chip, int dev, + int legacy_ctrl, int legacy_ctrl2) +{ + struct gameport *gp; + struct resource *r = NULL; + int io_port = joystick_port[dev]; + + if (!io_port) + return -ENODEV; + + if (chip->pci->device >= 0x0010) { /* YMF 744/754 */ + + if (io_port == 1) { + /* auto-detect */ + if (!(io_port = pci_resource_start(chip->pci, 2))) + return -ENODEV; + } + } else { + if (io_port == 1) { + /* auto-detect */ + for (io_port = 0x201; io_port <= 0x205; io_port++) { + if (io_port == 0x203) + continue; + if ((r = request_region(io_port, 1, "YMFPCI gameport")) != NULL) + break; + } + if (!r) { + printk(KERN_ERR "ymfpci: no gameport ports available\n"); + return -EBUSY; + } + } + switch (io_port) { + case 0x201: legacy_ctrl2 |= 0 << 6; break; + case 0x202: legacy_ctrl2 |= 1 << 6; break; + case 0x204: legacy_ctrl2 |= 2 << 6; break; + case 0x205: legacy_ctrl2 |= 3 << 6; break; + default: + printk(KERN_ERR "ymfpci: invalid joystick port %#x", io_port); + return -EINVAL; + } + } + + if (!r && !(r = request_region(io_port, 1, "YMFPCI gameport"))) { + printk(KERN_ERR "ymfpci: joystick port %#x is in use.\n", io_port); + return -EBUSY; + } + + chip->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR "ymfpci: cannot allocate memory for gameport\n"); + release_resource(r); + kfree_nocheck(r); + return -ENOMEM; + } + + + gameport_set_name(gp, "Yamaha YMF Gameport"); + gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); + gp->dev.parent = &chip->pci->dev; + gp->io = io_port; + + if (chip->pci->device >= 0x0010) /* YMF 744/754 */ + pci_write_config_word(chip->pci, PCIR_DSXG_JOYBASE, io_port); + + pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, legacy_ctrl | YMFPCI_LEGACY_JPEN); + pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY, legacy_ctrl2); + + gameport_register_port(chip->gameport); + + return 0; +} + +void snd_ymfpci_free_gameport(ymfpci_t *chip) +{ + if (chip->gameport) { + struct resource *r = chip->gameport->port_data; + + gameport_unregister_port(chip->gameport); + chip->gameport = NULL; + + release_resource(r); + kfree_nocheck(r); + } +} +#else +static inline int snc_ymfpci_create_gameport(ymfpci_t *chip, int dev, int l, int l2) { return -ENOSYS; } +void snd_ymfpci_free_gameport(ymfpci_t *chip) { } +#endif /* SUPPORT_JOYSTICK */ + static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { @@ -86,9 +176,6 @@ snd_card_t *card; struct resource *fm_res = NULL; struct resource *mpu_res = NULL; -#ifdef SUPPORT_JOYSTICK - struct resource *joystick_res = NULL; -#endif ymfpci_t *chip; opl3_t *opl3; char *str; @@ -138,17 +225,6 @@ legacy_ctrl |= YMFPCI_LEGACY_MEN; pci_write_config_word(pci, PCIR_DSXG_MPU401BASE, mpu_port[dev]); } -#ifdef SUPPORT_JOYSTICK - if (joystick_port[dev] == 1) { - /* auto-detect */ - joystick_port[dev] = pci_resource_start(pci, 2); - } - if (joystick_port[dev] > 0 && - (joystick_res = request_region(joystick_port[dev], 1, "YMFPCI gameport")) != NULL) { - legacy_ctrl |= YMFPCI_LEGACY_JPEN; - pci_write_config_word(pci, PCIR_DSXG_JOYBASE, joystick_port[dev]); - } -#endif } else { switch (fm_port[dev]) { case 0x388: legacy_ctrl2 |= 0; break; @@ -178,34 +254,6 @@ legacy_ctrl2 &= ~YMFPCI_LEGACY2_MPUIO; mpu_port[dev] = 0; } -#ifdef SUPPORT_JOYSTICK - if (joystick_port[dev] == 1) { - /* auto-detect */ - long p; - for (p = 0x201; p <= 0x205; p++) { - if (p == 0x203) continue; - if ((joystick_res = request_region(p, 1, "YMFPCI gameport")) != NULL) - break; - } - if (joystick_res) - joystick_port[dev] = p; - } - switch (joystick_port[dev]) { - case 0x201: legacy_ctrl2 |= 0 << 6; break; - case 0x202: legacy_ctrl2 |= 1 << 6; break; - case 0x204: legacy_ctrl2 |= 2 << 6; break; - case 0x205: legacy_ctrl2 |= 3 << 6; break; - default: joystick_port[dev] = 0; break; - } - if (! joystick_res && joystick_port[dev] > 0) - joystick_res = request_region(joystick_port[dev], 1, "YMFPCI gameport"); - if (joystick_res) { - legacy_ctrl |= YMFPCI_LEGACY_JPEN; - } else { - legacy_ctrl2 &= ~YMFPCI_LEGACY2_JSIO; - joystick_port[dev] = 0; - } -#endif } if (mpu_res) { legacy_ctrl |= YMFPCI_LEGACY_MIEN; @@ -226,19 +274,10 @@ release_resource(fm_res); kfree_nocheck(fm_res); } -#ifdef SUPPORT_JOYSTICK - if (joystick_res) { - release_resource(joystick_res); - kfree_nocheck(joystick_res); - } -#endif return err; } chip->fm_res = fm_res; chip->mpu_res = mpu_res; -#ifdef SUPPORT_JOYSTICK - chip->joystick_res = joystick_res; -#endif strcpy(card->driver, str); sprintf(card->shortname, "Yamaha DS-XG (%s)", str); sprintf(card->longname, "%s at 0x%lx, irq %i", @@ -292,12 +331,8 @@ return err; } } -#ifdef SUPPORT_JOYSTICK - if (chip->joystick_res) { - chip->gameport.io = joystick_port[dev]; - gameport_register_port(&chip->gameport); - } -#endif + + snd_ymfpci_create_gameport(chip, dev, legacy_ctrl, legacy_ctrl2); if ((err = snd_card_register(card)) < 0) { snd_card_free(card); diff -Nru a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c --- a/sound/pci/ymfpci/ymfpci_main.c 2005-02-11 01:39:34 -05:00 +++ b/sound/pci/ymfpci/ymfpci_main.c 2005-02-11 01:39:34 -05:00 @@ -2079,14 +2079,7 @@ release_resource(chip->fm_res); kfree_nocheck(chip->fm_res); } -#ifdef SUPPORT_JOYSTICK - if (chip->joystick_res) { - if (chip->gameport.io) - gameport_unregister_port(&chip->gameport); - release_resource(chip->joystick_res); - kfree_nocheck(chip->joystick_res); - } -#endif + snd_ymfpci_free_gameport(chip); if (chip->reg_area_virt) iounmap(chip->reg_area_virt); if (chip->work_ptr.area) ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 8/10] Gameport: add "gameport" sysfs bus, add drivers 2005-02-11 7:03 ` [PATCH 7/10] Gameport: convert sound/alsa " Dmitry Torokhov @ 2005-02-11 7:04 ` Dmitry Torokhov 2005-02-11 7:04 ` [PATCH 9/10] Gameport: complete sysfs integration Dmitry Torokhov 0 siblings, 1 reply; 12+ messages in thread From: Dmitry Torokhov @ 2005-02-11 7:04 UTC (permalink / raw) To: InputML; +Cc: alsa-devel, LKML, Vojtech Pavlik =================================================================== ChangeSet@1.2156, 2005-02-11 01:21:02-05:00, dtor_core@ameritech.net Input: integrate gameport drivers info dribver model/sysfs, create "gameport" bus. drivers' connect() routines now return error code instead of void. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> drivers/Makefile | 2 drivers/input/gameport/gameport.c | 39 ++++++++++++++++++ drivers/input/joystick/a3d.c | 44 ++++++++++++++------- drivers/input/joystick/adi.c | 63 ++++++++++++++---------------- drivers/input/joystick/analog.c | 52 +++++++++++++++--------- drivers/input/joystick/cobra.c | 42 ++++++++++++-------- drivers/input/joystick/gf2k.c | 42 +++++++++++++------- drivers/input/joystick/grip.c | 61 +++++++++++++---------------- drivers/input/joystick/grip_mp.c | 56 +++++++++++++++++--------- drivers/input/joystick/guillemot.c | 53 ++++++++++++++----------- drivers/input/joystick/interact.c | 32 +++++++++++---- drivers/input/joystick/joydump.c | 20 ++++++--- drivers/input/joystick/sidewinder.c | 75 +++++++++++++++++++++++++----------- drivers/input/joystick/tmdc.c | 53 +++++++++++++------------ include/linux/gameport.h | 6 +- 15 files changed, 407 insertions(+), 233 deletions(-) =================================================================== diff -Nru a/drivers/Makefile b/drivers/Makefile --- a/drivers/Makefile 2005-02-11 01:40:01 -05:00 +++ b/drivers/Makefile 2005-02-11 01:40:01 -05:00 @@ -47,8 +47,8 @@ obj-$(CONFIG_TC) += tc/ obj-$(CONFIG_USB) += usb/ obj-$(CONFIG_USB_GADGET) += usb/gadget/ -obj-$(CONFIG_INPUT) += input/ obj-$(CONFIG_GAMEPORT) += input/gameport/ +obj-$(CONFIG_INPUT) += input/ obj-$(CONFIG_I2O) += message/ obj-$(CONFIG_I2C) += i2c/ obj-$(CONFIG_W1) += w1/ diff -Nru a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c --- a/drivers/input/gameport/gameport.c 2005-02-11 01:40:01 -05:00 +++ b/drivers/input/gameport/gameport.c 2005-02-11 01:40:01 -05:00 @@ -37,6 +37,10 @@ static LIST_HEAD(gameport_list); static LIST_HEAD(gameport_driver_list); +static struct bus_type gameport_bus = { + .name = "gameport", +}; + #ifdef __i386__ #define DELTA(x,y) ((y)-(x)+((y)<(x)?1193182/HZ:0)) @@ -146,6 +150,21 @@ gameport_find_driver(gameport); } +/* + * Gameport driver operations + */ + +static ssize_t gameport_driver_show_description(struct device_driver *drv, char *buf) +{ + struct gameport_driver *driver = to_gameport_driver(drv); + return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)"); +} + +static struct driver_attribute gameport_driver_attrs[] = { + __ATTR(description, S_IRUGO, gameport_driver_show_description, NULL), + __ATTR_NULL +}; + void gameport_unregister_port(struct gameport *gameport) { list_del_init(&gameport->node); @@ -159,6 +178,9 @@ { struct gameport *gameport; + drv->driver.bus = &gameport_bus; + driver_register(&drv->driver); + list_add_tail(&drv->node, &gameport_driver_list); list_for_each_entry(gameport, &gameport_list, node) if (!gameport->drv) @@ -175,6 +197,7 @@ drv->disconnect(gameport); gameport_find_driver(gameport); } + driver_unregister(&drv->driver); } int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode) @@ -201,3 +224,19 @@ if (gameport->close) gameport->close(gameport); } + +static int __init gameport_init(void) +{ + gameport_bus.drv_attrs = gameport_driver_attrs; + bus_register(&gameport_bus); + + return 0; +} + +static void __exit gameport_exit(void) +{ + bus_unregister(&gameport_bus); +} + +module_init(gameport_init); +module_exit(gameport_exit); diff -Nru a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c --- a/drivers/input/joystick/a3d.c 2005-02-11 01:40:01 -05:00 +++ b/drivers/input/joystick/a3d.c 2005-02-11 01:40:01 -05:00 @@ -35,8 +35,10 @@ #include <linux/gameport.h> #include <linux/input.h> +#define DRIVER_DESC "FP-Gaming Assasin 3D joystick driver" + MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); -MODULE_DESCRIPTION("FP-Gaming Assasin 3D joystick driver"); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); #define A3D_MAX_START 400 /* 400 us */ @@ -108,7 +110,9 @@ static int a3d_csum(char *data, int count) { int i, csum = 0; - for (i = 0; i < count - 2; i++) csum += data[i]; + + for (i = 0; i < count - 2; i++) + csum += data[i]; return (csum & 0x3f) != ((data[count - 2] << 3) | data[count - 1]); } @@ -138,7 +142,7 @@ a3d->buttons = ((data[3] << 3) | data[4]) & 0xf; - return; + break; case A3D_MODE_PXL: @@ -168,7 +172,7 @@ input_sync(dev); - return; + break; } } @@ -181,6 +185,7 @@ { struct a3d *a3d = (void *) private; unsigned char data[A3D_MAX_LENGTH]; + a3d->reads++; if (a3d_read_packet(a3d->gameport, a3d->length, data) != a3d->length || data[0] != a3d->mode || a3d_csum(data, a3d->length)) @@ -198,6 +203,7 @@ { struct a3d *a3d = gameport->port_data; int i; + for (i = 0; i < 4; i++) axes[i] = (a3d->axes[i] < 254) ? a3d->axes[i] : -1; *buttons = a3d->buttons; @@ -226,6 +232,7 @@ static void a3d_adc_close(struct gameport *gameport) { struct a3d *a3d = gameport->port_data; + if (!--a3d->used) del_timer(&a3d->timer); } @@ -237,6 +244,7 @@ static int a3d_open(struct input_dev *dev) { struct a3d *a3d = dev->private; + if (!a3d->used++) mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME); return 0; @@ -249,6 +257,7 @@ static void a3d_close(struct input_dev *dev) { struct a3d *a3d = dev->private; + if (!--a3d->used) del_timer(&a3d->timer); } @@ -257,16 +266,16 @@ * a3d_connect() probes for A3D joysticks. */ -static void a3d_connect(struct gameport *gameport, struct gameport_driver *drv) +static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) { struct a3d *a3d; struct gameport *adc; unsigned char data[A3D_MAX_LENGTH]; int i; + int err; - if (!(a3d = kmalloc(sizeof(struct a3d), GFP_KERNEL))) - return; - memset(a3d, 0, sizeof(struct a3d)); + if (!(a3d = kcalloc(1, sizeof(struct a3d), GFP_KERNEL))) + return -ENOMEM; gameport->private = a3d; @@ -275,19 +284,23 @@ a3d->timer.data = (long) a3d; a3d->timer.function = a3d_timer; - if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); + if (err) goto fail1; i = a3d_read_packet(gameport, A3D_MAX_LENGTH, data); - if (!i || a3d_csum(data, i)) + if (!i || a3d_csum(data, i)) { + err = -ENODEV; goto fail2; + } a3d->mode = data[0]; if (!a3d->mode || a3d->mode > 5) { printk(KERN_WARNING "a3d.c: Unknown A3D device detected " "(%s, id=%d), contact <vojtech@ucw.cz>\n", gameport->phys, a3d->mode); + err = -ENODEV; goto fail2; } @@ -363,10 +376,11 @@ input_register_device(&a3d->dev); printk(KERN_INFO "input: %s on %s\n", a3d_names[a3d->mode], a3d->phys); - return; + return 0; fail2: gameport_close(gameport); fail1: kfree(a3d); + return err; } static void a3d_disconnect(struct gameport *gameport) @@ -383,8 +397,12 @@ } static struct gameport_driver a3d_drv = { - .connect = a3d_connect, - .disconnect = a3d_disconnect, + .driver = { + .name = "adc", + }, + .description = DRIVER_DESC, + .connect = a3d_connect, + .disconnect = a3d_disconnect, }; static int __init a3d_init(void) diff -Nru a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c --- a/drivers/input/joystick/adi.c 2005-02-11 01:40:01 -05:00 +++ b/drivers/input/joystick/adi.c 2005-02-11 01:40:01 -05:00 @@ -37,8 +37,10 @@ #include <linux/gameport.h> #include <linux/init.h> +#define DRIVER_DESC "Logitech ADI joystick family driver" + MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); -MODULE_DESCRIPTION("Logitech ADI joystick family driver"); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); /* @@ -439,35 +441,23 @@ { int i, t, x; - if (!adi->length) return; + if (!adi->length) + return; for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++) { t = adi->abs[i]; x = adi->dev.abs[t]; - if (t == ABS_THROTTLE || t == ABS_RUDDER || adi->id == ADI_ID_WGPE) { - if (i < adi->axes10) x = 512; else x = 128; - } - - if (i < adi->axes10) { - adi->dev.absmax[t] = x * 2 - 64; - adi->dev.absmin[t] = 64; - adi->dev.absfuzz[t] = 2; - adi->dev.absflat[t] = 16; - continue; - } - - if (i < adi->axes10 + adi->axes8) { - adi->dev.absmax[t] = x * 2 - 48; - adi->dev.absmin[t] = 48; - adi->dev.absfuzz[t] = 1; - adi->dev.absflat[t] = 16; - continue; - } + if (t == ABS_THROTTLE || t == ABS_RUDDER || adi->id == ADI_ID_WGPE) + x = i < adi->axes10 ? 512 : 128; - adi->dev.absmax[t] = 1; - adi->dev.absmin[t] = -1; + if (i < adi->axes10) + input_set_abs_params(&adi->dev, t, 64, x * 2 - 64, 2, 16); + else if (i < adi->axes10 + adi->axes8) + input_set_abs_params(&adi->dev, t, 48, x * 2 - 48, 1, 16); + else + input_set_abs_params(&adi->dev, t, -1, 1, 0, 0); } } @@ -475,14 +465,14 @@ * adi_connect() probes for Logitech ADI joysticks. */ -static void adi_connect(struct gameport *gameport, struct gameport_driver *drv) +static int adi_connect(struct gameport *gameport, struct gameport_driver *drv) { struct adi_port *port; int i; + int err; - if (!(port = kmalloc(sizeof(struct adi_port), GFP_KERNEL))) - return; - memset(port, 0, sizeof(struct adi_port)); + if (!(port = kcalloc(1, sizeof(struct adi_port), GFP_KERNEL))) + return -ENOMEM; gameport->private = port; @@ -491,9 +481,10 @@ port->timer.data = (long) port; port->timer.function = adi_timer; - if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) { + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); + if (err) { kfree(port); - return; + return err; } adi_init_digital(gameport); @@ -510,7 +501,7 @@ if (!port->adi[0].length && !port->adi[1].length) { gameport_close(gameport); kfree(port); - return; + return -ENODEV; } msleep(ADI_INIT_DELAY); @@ -526,13 +517,15 @@ printk(KERN_INFO "input: %s [%s] on %s\n", port->adi[i].name, port->adi[i].cname, gameport->phys); } + + return 0; } static void adi_disconnect(struct gameport *gameport) { int i; - struct adi_port *port = gameport->private; + for (i = 0; i < 2; i++) if (port->adi[i].length > 0) input_unregister_device(&port->adi[i].dev); @@ -545,8 +538,12 @@ */ static struct gameport_driver adi_drv = { - .connect = adi_connect, - .disconnect = adi_disconnect, + .driver = { + .name = "adi", + }, + .description = DRIVER_DESC, + .connect = adi_connect, + .disconnect = adi_disconnect, }; static int __init adi_init(void) diff -Nru a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c --- a/drivers/input/joystick/analog.c 2005-02-11 01:40:01 -05:00 +++ b/drivers/input/joystick/analog.c 2005-02-11 01:40:01 -05:00 @@ -40,8 +40,10 @@ #include <linux/gameport.h> #include <asm/timex.h> +#define DRIVER_DESC "Analog joystick and gamepad driver" + MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); -MODULE_DESCRIPTION("Analog joystick and gamepad driver"); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); /* @@ -608,7 +610,8 @@ port->fuzz = (port->speed * ANALOG_FUZZ_MAGIC) / port->loop / 1000 + ANALOG_FUZZ_BITS; for (i = 0; i < ANALOG_INIT_RETRIES; i++) { - if (!analog_cooked_read(port)) break; + if (!analog_cooked_read(port)) + break; msleep(ANALOG_MAX_TIME); } @@ -617,11 +620,13 @@ msleep(ANALOG_MAX_TIME); t = gameport_time(gameport, ANALOG_MAX_TIME * 1000); gameport_trigger(gameport); - while ((gameport_read(port->gameport) & port->mask) && (u < t)) u++; + while ((gameport_read(port->gameport) & port->mask) && (u < t)) + u++; udelay(ANALOG_SAITEK_DELAY); t = gameport_time(gameport, ANALOG_SAITEK_TIME); gameport_trigger(gameport); - while ((gameport_read(port->gameport) & port->mask) && (v < t)) v++; + while ((gameport_read(port->gameport) & port->mask) && (v < t)) + v++; if (v < (u >> 1)) { /* FIXME - more than one port */ analog_options[0] |= /* FIXME - more than one port */ @@ -638,49 +643,51 @@ if (!gameport_cooked_read(gameport, port->axes, &port->buttons)) break; for (i = 0; i < 4; i++) - if (port->axes[i] != -1) port->mask |= 1 << i; + if (port->axes[i] != -1) + port->mask |= 1 << i; port->fuzz = gameport->fuzz; port->cooked = 1; return 0; } - if (!gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) - return 0; - - return -1; + return gameport_open(gameport, drv, GAMEPORT_MODE_RAW); } -static void analog_connect(struct gameport *gameport, struct gameport_driver *drv) +static int analog_connect(struct gameport *gameport, struct gameport_driver *drv) { struct analog_port *port; int i; + int err; - if (!(port = kmalloc(sizeof(struct analog_port), GFP_KERNEL))) - return; - memset(port, 0, sizeof(struct analog_port)); + if (!(port = kcalloc(1, sizeof(struct analog_port), GFP_KERNEL))) + return - ENOMEM; - if (analog_init_port(gameport, drv, port)) { + err = analog_init_port(gameport, drv, port); + if (err) { kfree(port); - return; + return err; } - if (analog_init_masks(port)) { + err = analog_init_masks(port); + if (err) { gameport_close(gameport); kfree(port); - return; + return err; } for (i = 0; i < 2; i++) if (port->analog[i].mask) analog_init_device(port, port->analog + i, i); + + return 0; } static void analog_disconnect(struct gameport *gameport) { int i; - struct analog_port *port = gameport->private; + for (i = 0; i < 2; i++) if (port->analog[i].mask) input_unregister_device(&port->analog[i].dev); @@ -742,14 +749,19 @@ */ static struct gameport_driver analog_drv = { - .connect = analog_connect, - .disconnect = analog_disconnect, + .driver = { + .name = "analog", + }, + .description = DRIVER_DESC, + .connect = analog_connect, + .disconnect = analog_disconnect, }; static int __init analog_init(void) { analog_parse_options(); gameport_register_driver(&analog_drv); + return 0; } diff -Nru a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c --- a/drivers/input/joystick/cobra.c 2005-02-11 01:40:01 -05:00 +++ b/drivers/input/joystick/cobra.c 2005-02-11 01:40:01 -05:00 @@ -35,8 +35,10 @@ #include <linux/gameport.h> #include <linux/input.h> +#define DRIVER_DESC "Creative Labs Blaster GamePad Cobra driver" + MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); -MODULE_DESCRIPTION("Creative Labs Blaster GamePad Cobra driver"); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); #define COBRA_MAX_STROBE 45 /* 45 us max wait for first strobe */ @@ -158,15 +160,15 @@ del_timer(&cobra->timer); } -static void cobra_connect(struct gameport *gameport, struct gameport_driver *drv) +static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) { struct cobra *cobra; unsigned int data[2]; int i, j; + int err; - if (!(cobra = kmalloc(sizeof(struct cobra), GFP_KERNEL))) - return; - memset(cobra, 0, sizeof(struct cobra)); + if (!(cobra = kcalloc(1, sizeof(struct cobra), GFP_KERNEL))) + return -ENOMEM; gameport->private = cobra; @@ -175,7 +177,8 @@ cobra->timer.data = (long) cobra; cobra->timer.function = cobra_timer; - if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); + if (err) goto fail1; cobra->exists = cobra_read_packet(gameport, data); @@ -187,8 +190,10 @@ cobra->exists &= ~(1 << i); } - if (!cobra->exists) + if (!cobra->exists) { + err = -ENODEV; goto fail2; + } for (i = 0; i < 2; i++) if ((cobra->exists >> i) & 1) { @@ -207,28 +212,29 @@ cobra->dev[i].id.version = 0x0100; cobra->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - cobra->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y); + + input_set_abs_params(&cobra->dev[i], ABS_X, -1, 1, 0, 0); + input_set_abs_params(&cobra->dev[i], ABS_Y, -1, 1, 0, 0); for (j = 0; cobra_btn[j]; j++) set_bit(cobra_btn[j], cobra->dev[i].keybit); - cobra->dev[i].absmin[ABS_X] = -1; cobra->dev[i].absmax[ABS_X] = 1; - cobra->dev[i].absmin[ABS_Y] = -1; cobra->dev[i].absmax[ABS_Y] = 1; - - input_register_device(cobra->dev + i); + input_register_device(&cobra->dev[i]); printk(KERN_INFO "input: %s on %s\n", cobra_name, gameport->phys); } - return; + return 0; + fail2: gameport_close(gameport); fail1: kfree(cobra); + return err; } static void cobra_disconnect(struct gameport *gameport) { int i; - struct cobra *cobra = gameport->private; + for (i = 0; i < 2; i++) if ((cobra->exists >> i) & 1) input_unregister_device(cobra->dev + i); @@ -237,8 +243,12 @@ } static struct gameport_driver cobra_drv = { - .connect = cobra_connect, - .disconnect = cobra_disconnect, + .driver = { + .name = "cobra", + }, + .description = DRIVER_DESC, + .connect = cobra_connect, + .disconnect = cobra_disconnect, }; static int __init cobra_init(void) diff -Nru a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c --- a/drivers/input/joystick/gf2k.c 2005-02-11 01:40:01 -05:00 +++ b/drivers/input/joystick/gf2k.c 2005-02-11 01:40:01 -05:00 @@ -36,8 +36,10 @@ #include <linux/input.h> #include <linux/gameport.h> +#define DRIVER_DESC "Genius Flight 2000 joystick driver" + MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); -MODULE_DESCRIPTION("Genius Flight 2000 joystick driver"); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); #define GF2K_START 400 /* The time we wait for the first bit [400 us] */ @@ -238,15 +240,14 @@ * gf2k_connect() probes for Genius id joysticks. */ -static void gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) +static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) { struct gf2k *gf2k; unsigned char data[GF2K_LENGTH]; - int i; + int i, err; - if (!(gf2k = kmalloc(sizeof(struct gf2k), GFP_KERNEL))) - return; - memset(gf2k, 0, sizeof(struct gf2k)); + if (!(gf2k = kcalloc(1, sizeof(struct gf2k), GFP_KERNEL))) + return -ENOMEM; gameport->private = gf2k; @@ -255,7 +256,8 @@ gf2k->timer.data = (long) gf2k; gf2k->timer.function = gf2k_timer; - if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); + if (err) goto fail1; gf2k_trigger_seq(gameport, gf2k_seq_reset); @@ -266,16 +268,22 @@ msleep(GF2K_TIMEOUT); - if (gf2k_read_packet(gameport, GF2K_LENGTH, data) < 12) + if (gf2k_read_packet(gameport, GF2K_LENGTH, data) < 12) { + err = -ENODEV; goto fail2; + } - if (!(gf2k->id = GB(7,2,0) | GB(3,3,2) | GB(0,3,5))) + if (!(gf2k->id = GB(7,2,0) | GB(3,3,2) | GB(0,3,5))) { + err = -ENODEV; goto fail2; + } #ifdef RESET_WORKS if ((gf2k->id != (GB(19,2,0) | GB(15,3,2) | GB(12,3,5))) || - (gf2k->id != (GB(31,2,0) | GB(27,3,2) | GB(24,3,5)))) + (gf2k->id != (GB(31,2,0) | GB(27,3,2) | GB(24,3,5)))) { + err = -ENODEV; goto fail2; + } #else gf2k->id = 6; #endif @@ -283,6 +291,7 @@ if (gf2k->id > GF2K_ID_MAX || !gf2k_axes[gf2k->id]) { printk(KERN_WARNING "gf2k.c: Not yet supported joystick on %s. [id: %d type:%s]\n", gameport->phys, gf2k->id, gf2k->id > GF2K_ID_MAX ? "Unknown" : gf2k_names[gf2k->id]); + err = -ENODEV; goto fail2; } @@ -333,22 +342,29 @@ input_register_device(&gf2k->dev); printk(KERN_INFO "input: %s on %s\n", gf2k_names[gf2k->id], gameport->phys); - return; + return 0; + fail2: gameport_close(gameport); fail1: kfree(gf2k); + return err; } static void gf2k_disconnect(struct gameport *gameport) { struct gf2k *gf2k = gameport->private; + input_unregister_device(&gf2k->dev); gameport_close(gameport); kfree(gf2k); } static struct gameport_driver gf2k_drv = { - .connect = gf2k_connect, - .disconnect = gf2k_disconnect, + .driver = { + .name = "gf2k", + }, + .description = DRIVER_DESC, + .connect = gf2k_connect, + .disconnect = gf2k_disconnect, }; static int __init gf2k_init(void) diff -Nru a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c --- a/drivers/input/joystick/grip.c 2005-02-11 01:40:01 -05:00 +++ b/drivers/input/joystick/grip.c 2005-02-11 01:40:01 -05:00 @@ -35,8 +35,10 @@ #include <linux/gameport.h> #include <linux/input.h> +#define DRIVER_DESC "Gravis GrIP protocol joystick driver" + MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); -MODULE_DESCRIPTION("Gravis GrIP protocol joystick driver"); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); #define GRIP_MODE_GPP 1 @@ -298,15 +300,15 @@ del_timer(&grip->timer); } -static void grip_connect(struct gameport *gameport, struct gameport_driver *drv) +static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) { struct grip *grip; unsigned int data[GRIP_LENGTH_XT]; int i, j, t; + int err; - if (!(grip = kmalloc(sizeof(struct grip), GFP_KERNEL))) - return; - memset(grip, 0, sizeof(struct grip)); + if (!(grip = kcalloc(1, sizeof(struct grip), GFP_KERNEL))) + return -ENOMEM; gameport->private = grip; @@ -315,7 +317,8 @@ grip->timer.data = (long) grip; grip->timer.function = grip_timer; - if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); + if (err) goto fail1; for (i = 0; i < 2; i++) { @@ -337,8 +340,10 @@ } } - if (!grip->mode[0] && !grip->mode[1]) + if (!grip->mode[0] && !grip->mode[1]) { + err = -ENODEV; goto fail2; + } for (i = 0; i < 2; i++) if (grip->mode[i]) { @@ -361,47 +366,35 @@ for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) { - set_bit(t, grip->dev[i].absbit); - - if (j < grip_cen[grip->mode[i]]) { - grip->dev[i].absmin[t] = 14; - grip->dev[i].absmax[t] = 52; - grip->dev[i].absfuzz[t] = 1; - grip->dev[i].absflat[t] = 2; - continue; - } - - if (j < grip_anx[grip->mode[i]]) { - grip->dev[i].absmin[t] = 3; - grip->dev[i].absmax[t] = 57; - grip->dev[i].absfuzz[t] = 1; - continue; - } - - grip->dev[i].absmin[t] = -1; - grip->dev[i].absmax[t] = 1; + if (j < grip_cen[grip->mode[i]]) + input_set_abs_params(&grip->dev[i], t, 14, 52, 1, 2); + else if (j < grip_anx[grip->mode[i]]) + input_set_abs_params(&grip->dev[i], t, 3, 57, 1, 0); + else + input_set_abs_params(&grip->dev[i], t, -1, 1, 0, 0); } for (j = 0; (t = grip_btn[grip->mode[i]][j]) >= 0; j++) if (t > 0) set_bit(t, grip->dev[i].keybit); - input_register_device(grip->dev + i); - printk(KERN_INFO "input: %s on %s\n", grip_name[grip->mode[i]], gameport->phys); + input_register_device(grip->dev + i); } - return; + return 0; + fail2: gameport_close(gameport); fail1: kfree(grip); + return err; } static void grip_disconnect(struct gameport *gameport) { + struct grip *grip = gameport->private; int i; - struct grip *grip = gameport->private; for (i = 0; i < 2; i++) if (grip->mode[i]) input_unregister_device(grip->dev + i); @@ -410,8 +403,12 @@ } static struct gameport_driver grip_drv = { - .connect = grip_connect, - .disconnect = grip_disconnect, + .driver = { + .name = "grip", + }, + .description = DRIVER_DESC, + .connect = grip_connect, + .disconnect = grip_disconnect, }; static int __init grip_init(void) diff -Nru a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c --- a/drivers/input/joystick/grip_mp.c 2005-02-11 01:40:01 -05:00 +++ b/drivers/input/joystick/grip_mp.c 2005-02-11 01:40:01 -05:00 @@ -20,8 +20,10 @@ #include <linux/delay.h> #include <linux/proc_fs.h> +#define DRIVER_DESC "Gravis Grip Multiport driver" + MODULE_AUTHOR("Brian Bonnlander"); -MODULE_DESCRIPTION("Gravis Grip Multiport driver"); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); #ifdef GRIP_DEBUG @@ -477,9 +479,9 @@ } if (dig_mode) - dbg("multiport_init(): digital mode achieved.\n"); + dbg("multiport_init(): digital mode activated.\n"); else { - dbg("multiport_init(): unable to achieve digital mode.\n"); + dbg("multiport_init(): unable to activate digital mode.\n"); return 0; } @@ -551,6 +553,7 @@ static int grip_open(struct input_dev *dev) { struct grip_mp *grip = dev->private; + if (!grip->used++) mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME); return 0; @@ -563,6 +566,7 @@ static void grip_close(struct input_dev *dev) { struct grip_mp *grip = dev->private; + if (!--grip->used) del_timer(&grip->timer); } @@ -585,11 +589,8 @@ grip->dev[slot].id.version = 0x0100; grip->dev[slot].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - for (j = 0; (t = grip_abs[grip->mode[slot]][j]) >= 0; j++) { - set_bit(t, grip->dev[slot].absbit); - grip->dev[slot].absmin[t] = -1; - grip->dev[slot].absmax[t] = 1; - } + for (j = 0; (t = grip_abs[grip->mode[slot]][j]) >= 0; j++) + input_set_abs_params(&grip->dev[slot], t, -1, 1, 0, 0); for (j = 0; (t = grip_btn[grip->mode[slot]][j]) >= 0; j++) if (t > 0) @@ -612,41 +613,52 @@ static void grip_timer(unsigned long private) { struct grip_mp *grip = (void*) private; + get_and_report_mp_state(grip); mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME); } -static void grip_connect(struct gameport *gameport, struct gameport_driver *drv) +static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) { struct grip_mp *grip; + int err; + + if (!(grip = kcalloc(1, sizeof(struct grip_mp), GFP_KERNEL))) + return -ENOMEM; - if (!(grip = kmalloc(sizeof(struct grip_mp), GFP_KERNEL))) - return; - memset(grip, 0, sizeof(struct grip_mp)); gameport->private = grip; grip->gameport = gameport; init_timer(&grip->timer); grip->timer.data = (long) grip; grip->timer.function = grip_timer; - if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); + if (err) goto fail1; - if (!multiport_init(grip)) + + if (!multiport_init(grip)) { + err = -ENODEV; goto fail2; - if (!grip->mode[0] && !grip->mode[1] && /* nothing plugged in */ - !grip->mode[2] && !grip->mode[3]) + } + + if (!grip->mode[0] && !grip->mode[1] && !grip->mode[2] && !grip->mode[3]) { + /* nothing plugged in */ + err = -ENODEV; goto fail2; - return; + } + + return 0; fail2: gameport_close(gameport); fail1: kfree(grip); + return err; } static void grip_disconnect(struct gameport *gameport) { int i; - struct grip_mp *grip = gameport->private; + for (i = 0; i < 4; i++) if (grip->registered[i]) input_unregister_device(grip->dev + i); @@ -655,17 +667,21 @@ } static struct gameport_driver grip_drv = { + .driver = { + .name = "grip_mp", + }, + .description = DRIVER_DESC, .connect = grip_connect, .disconnect = grip_disconnect, }; -static int grip_init(void) +static int __init grip_init(void) { gameport_register_driver(&grip_drv); return 0; } -static void grip_exit(void) +static void __exit grip_exit(void) { gameport_unregister_driver(&grip_drv); } diff -Nru a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c --- a/drivers/input/joystick/guillemot.c 2005-02-11 01:40:01 -05:00 +++ b/drivers/input/joystick/guillemot.c 2005-02-11 01:40:01 -05:00 @@ -36,8 +36,10 @@ #include <linux/gameport.h> #include <linux/input.h> +#define DRIVER_DESC "Guillemot Digital joystick driver" + MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); -MODULE_DESCRIPTION("Guillemot Digital joystick driver"); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); #define GUILLEMOT_MAX_START 600 /* 600 us */ @@ -159,6 +161,7 @@ static int guillemot_open(struct input_dev *dev) { struct guillemot *guillemot = dev->private; + if (!guillemot->used++) mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME); return 0; @@ -171,6 +174,7 @@ static void guillemot_close(struct input_dev *dev) { struct guillemot *guillemot = dev->private; + if (!--guillemot->used) del_timer(&guillemot->timer); } @@ -179,15 +183,15 @@ * guillemot_connect() probes for Guillemot joysticks. */ -static void guillemot_connect(struct gameport *gameport, struct gameport_driver *drv) +static int guillemot_connect(struct gameport *gameport, struct gameport_driver *drv) { struct guillemot *guillemot; u8 data[GUILLEMOT_MAX_LENGTH]; int i, t; + int err; - if (!(guillemot = kmalloc(sizeof(struct guillemot), GFP_KERNEL))) - return; - memset(guillemot, 0, sizeof(struct guillemot)); + if (!(guillemot = kcalloc(1, sizeof(struct guillemot), GFP_KERNEL))) + return -ENOMEM; gameport->private = guillemot; @@ -196,13 +200,16 @@ guillemot->timer.data = (long) guillemot; guillemot->timer.function = guillemot_timer; - if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); + if (err) goto fail1; i = guillemot_read_packet(gameport, data); - if (i != GUILLEMOT_MAX_LENGTH * 8 || data[0] != 0x55 || data[16] != 0xaa) + if (i != GUILLEMOT_MAX_LENGTH * 8 || data[0] != 0x55 || data[16] != 0xaa) { + err = -ENODEV; goto fail2; + } for (i = 0; guillemot_type[i].name; i++) if (guillemot_type[i].id == data[11]) @@ -211,6 +218,7 @@ if (!guillemot_type[i].name) { printk(KERN_WARNING "guillemot.c: Unknown joystick on %s. [ %02x%02x:%04x, ver %d.%02d ]\n", gameport->phys, data[12], data[13], data[11], data[14], data[15]); + err = -ENODEV; goto fail2; } @@ -231,19 +239,13 @@ guillemot->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - for (i = 0; (t = guillemot->type->abs[i]) >= 0; i++) { - set_bit(t, guillemot->dev.absbit); - guillemot->dev.absmin[t] = 0; - guillemot->dev.absmax[t] = 255; - } + for (i = 0; (t = guillemot->type->abs[i]) >= 0; i++) + input_set_abs_params(&guillemot->dev, t, 0, 255, 0, 0); - if (guillemot->type->hat) - for (i = 0; i < 2; i++) { - t = ABS_HAT0X + i; - set_bit(t, guillemot->dev.absbit); - guillemot->dev.absmin[t] = -1; - guillemot->dev.absmax[t] = 1; - } + if (guillemot->type->hat) { + input_set_abs_params(&guillemot->dev, ABS_HAT0X, -1, 1, 0, 0); + input_set_abs_params(&guillemot->dev, ABS_HAT0Y, -1, 1, 0, 0); + } for (i = 0; (t = guillemot->type->btn[i]) >= 0; i++) set_bit(t, guillemot->dev.keybit); @@ -252,14 +254,17 @@ printk(KERN_INFO "input: %s ver %d.%02d on %s\n", guillemot->type->name, data[14], data[15], gameport->phys); - return; + return 0; + fail2: gameport_close(gameport); fail1: kfree(guillemot); + return err; } static void guillemot_disconnect(struct gameport *gameport) { struct guillemot *guillemot = gameport->private; + printk(KERN_INFO "guillemot.c: Failed %d reads out of %d on %s\n", guillemot->reads, guillemot->bads, guillemot->phys); input_unregister_device(&guillemot->dev); gameport_close(gameport); @@ -267,8 +272,12 @@ } static struct gameport_driver guillemot_drv = { - .connect = guillemot_connect, - .disconnect = guillemot_disconnect, + .driver = { + .name = "guillemot", + }, + .description = DRIVER_DESC, + .connect = guillemot_connect, + .disconnect = guillemot_disconnect, }; static int __init guillemot_init(void) diff -Nru a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c --- a/drivers/input/joystick/interact.c 2005-02-11 01:40:01 -05:00 +++ b/drivers/input/joystick/interact.c 2005-02-11 01:40:01 -05:00 @@ -39,8 +39,10 @@ #include <linux/gameport.h> #include <linux/input.h> +#define DRIVER_DESC "InterAct digital joystick driver" + MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); -MODULE_DESCRIPTION("InterAct digital joystick driver"); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); #define INTERACT_MAX_START 400 /* 400 us */ @@ -189,6 +191,7 @@ static int interact_open(struct input_dev *dev) { struct interact *interact = dev->private; + if (!interact->used++) mod_timer(&interact->timer, jiffies + INTERACT_REFRESH_TIME); return 0; @@ -201,6 +204,7 @@ static void interact_close(struct input_dev *dev) { struct interact *interact = dev->private; + if (!--interact->used) del_timer(&interact->timer); } @@ -209,15 +213,15 @@ * interact_connect() probes for InterAct joysticks. */ -static void interact_connect(struct gameport *gameport, struct gameport_driver *drv) +static int interact_connect(struct gameport *gameport, struct gameport_driver *drv) { struct interact *interact; __u32 data[3]; int i, t; + int err; - if (!(interact = kmalloc(sizeof(struct interact), GFP_KERNEL))) - return; - memset(interact, 0, sizeof(struct interact)); + if (!(interact = kcalloc(1, sizeof(struct interact), GFP_KERNEL))) + return -ENOMEM; gameport->private = interact; @@ -226,12 +230,14 @@ interact->timer.data = (long) interact; interact->timer.function = interact_timer; - if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); + if (err) goto fail1; i = interact_read_packet(gameport, INTERACT_MAX_LENGTH * 2, data); if (i != 32 || (data[0] >> 24) != 0x0c || (data[1] >> 24) != 0x02) { + err = -ENODEV; goto fail2; } @@ -242,6 +248,7 @@ if (!interact_type[i].length) { printk(KERN_WARNING "interact.c: Unknown joystick on %s. [len %d d0 %08x d1 %08x i2 %08x]\n", gameport->phys, i, data[0], data[1], data[2]); + err = -ENODEV; goto fail2; } @@ -281,22 +288,29 @@ printk(KERN_INFO "input: %s on %s\n", interact_type[interact->type].name, gameport->phys); - return; + return 0; + fail2: gameport_close(gameport); fail1: kfree(interact); + return err; } static void interact_disconnect(struct gameport *gameport) { struct interact *interact = gameport->private; + input_unregister_device(&interact->dev); gameport_close(gameport); kfree(interact); } static struct gameport_driver interact_drv = { - .connect = interact_connect, - .disconnect = interact_disconnect, + .driver = { + .name = "interact", + }, + .description = DRIVER_DESC, + .connect = interact_connect, + .disconnect = interact_disconnect, }; static int __init interact_init(void) diff -Nru a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c --- a/drivers/input/joystick/joydump.c 2005-02-11 01:40:01 -05:00 +++ b/drivers/input/joystick/joydump.c 2005-02-11 01:40:01 -05:00 @@ -35,8 +35,10 @@ #include <linux/delay.h> #include <linux/init.h> +#define DRIVER_DESC "Gameport data dumper module" + MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); -MODULE_DESCRIPTION("Gameport data dumper module"); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); #define BUF_SIZE 256 @@ -46,7 +48,7 @@ unsigned char data; }; -static void __devinit joydump_connect(struct gameport *gameport, struct gameport_driver *drv) +static int joydump_connect(struct gameport *gameport, struct gameport_driver *drv) { struct joydump *buf; /* all entries */ struct joydump *dump, *prev; /* one entry each */ @@ -67,7 +69,7 @@ printk(KERN_INFO "joydump: | Cooked not available either. Failing. |\n"); printk(KERN_INFO "joydump: `-------------------- END -------------------'\n"); - return; + return -ENODEV; } gameport_cooked_read(gameport, axes, &buttons); @@ -140,16 +142,22 @@ jd_end: printk(KERN_INFO "joydump: `-------------------- END -------------------'\n"); + + return 0; } -static void __devexit joydump_disconnect(struct gameport *gameport) +static void joydump_disconnect(struct gameport *gameport) { gameport_close(gameport); } static struct gameport_driver joydump_drv = { - .connect = joydump_connect, - .disconnect = joydump_disconnect, + .driver = { + .name = "joydump", + }, + .description = DRIVER_DESC, + .connect = joydump_connect, + .disconnect = joydump_disconnect, }; static int __init joydump_init(void) diff -Nru a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c --- a/drivers/input/joystick/sidewinder.c 2005-02-11 01:40:01 -05:00 +++ b/drivers/input/joystick/sidewinder.c 2005-02-11 01:40:01 -05:00 @@ -36,8 +36,10 @@ #include <linux/input.h> #include <linux/gameport.h> +#define DRIVER_DESC "Microsoft SideWinder joystick family driver" + MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); -MODULE_DESCRIPTION("Microsoft SideWinder joystick family driver"); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); /* @@ -160,7 +162,8 @@ v = gameport_read(gameport); } while (!(~v & u & 0x10) && (bitout > 0)); /* Wait for first falling edge on clock */ - if (bitout > 0) bitout = strobe; /* Extend time if not timed out */ + if (bitout > 0) + bitout = strobe; /* Extend time if not timed out */ while ((timeout > 0 || bitout > 0) && (i < length)) { @@ -266,6 +269,7 @@ static int sw_parity(__u64 t) { int x = t ^ (t >> 32); + x ^= x >> 16; x ^= x >> 8; x ^= x >> 4; @@ -307,7 +311,8 @@ case SW_ID_3DP: - if (sw_check(GB(0,64)) || (hat = (GB(6,1) << 3) | GB(60,3)) > 8) return -1; + if (sw_check(GB(0,64)) || (hat = (GB(6,1) << 3) | GB(60,3)) > 8) + return -1; input_report_abs(dev, ABS_X, (GB( 3,3) << 7) | GB(16,7)); input_report_abs(dev, ABS_Y, (GB( 0,3) << 7) | GB(24,7)); @@ -331,7 +336,8 @@ for (i = 0; i < sw->number; i ++) { - if (sw_parity(GB(i*15,15))) return -1; + if (sw_parity(GB(i*15,15))) + return -1; input_report_abs(dev + i, ABS_X, GB(i*15+3,1) - GB(i*15+2,1)); input_report_abs(dev + i, ABS_Y, GB(i*15+0,1) - GB(i*15+1,1)); @@ -347,7 +353,8 @@ case SW_ID_PP: case SW_ID_FFP: - if (!sw_parity(GB(0,48)) || (hat = GB(42,4)) > 8) return -1; + if (!sw_parity(GB(0,48)) || (hat = GB(42,4)) > 8) + return -1; input_report_abs(dev, ABS_X, GB( 9,10)); input_report_abs(dev, ABS_Y, GB(19,10)); @@ -366,7 +373,8 @@ case SW_ID_FSP: - if (!sw_parity(GB(0,43)) || (hat = GB(28,4)) > 8) return -1; + if (!sw_parity(GB(0,43)) || (hat = GB(28,4)) > 8) + return -1; input_report_abs(dev, ABS_X, GB( 0,10)); input_report_abs(dev, ABS_Y, GB(16,10)); @@ -389,7 +397,8 @@ case SW_ID_FFW: - if (!sw_parity(GB(0,33))) return -1; + if (!sw_parity(GB(0,33))) + return -1; input_report_abs(dev, ABS_RX, GB( 0,10)); input_report_abs(dev, ABS_RUDDER, GB(10, 6)); @@ -466,7 +475,8 @@ sw->length = 66; } - if (sw->fail < SW_FAIL) return -1; /* Not enough, don't reinitialize yet */ + if (sw->fail < SW_FAIL) + return -1; /* Not enough, don't reinitialize yet */ printk(KERN_WARNING "sidewinder.c: Too many bit errors on %s" " - reinitializing joystick.\n", sw->gameport->phys); @@ -491,13 +501,15 @@ struct sw *sw = (void *) private; sw->reads++; - if (sw_read(sw)) sw->bads++; + if (sw_read(sw)) + sw->bads++; mod_timer(&sw->timer, jiffies + SW_REFRESH); } static int sw_open(struct input_dev *dev) { struct sw *sw = dev->private; + if (!sw->used++) mod_timer(&sw->timer, jiffies + SW_REFRESH); return 0; @@ -506,6 +518,7 @@ static void sw_close(struct input_dev *dev) { struct sw *sw = dev->private; + if (!--sw->used) del_timer(&sw->timer); } @@ -561,7 +574,10 @@ { int i; unsigned char xor = 0; - for (i = 1; i < len; i++) xor |= (buf[i - 1] ^ buf[i]) & 6; + + for (i = 1; i < len; i++) + xor |= (buf[i - 1] ^ buf[i]) & 6; + return !!xor * 2 + 1; } @@ -569,10 +585,11 @@ * sw_connect() probes for SideWinder type joysticks. */ -static void sw_connect(struct gameport *gameport, struct gameport_driver *drv) +static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) { struct sw *sw; int i, j, k, l; + int err; unsigned char *buf = NULL; /* [SW_LENGTH] */ unsigned char *idbuf = NULL; /* [SW_LENGTH] */ unsigned char m = 1; @@ -580,13 +597,13 @@ comment[0] = 0; - if (!(sw = kmalloc(sizeof(struct sw), GFP_KERNEL))) return; - memset(sw, 0, sizeof(struct sw)); - + sw = kcalloc(1, sizeof(struct sw), GFP_KERNEL); buf = kmalloc(SW_LENGTH, GFP_KERNEL); idbuf = kmalloc(SW_LENGTH, GFP_KERNEL); - if (!buf || !idbuf) + if (!sw || !buf || !idbuf) { + err = -ENOMEM; goto fail1; + } gameport->private = sw; @@ -595,7 +612,8 @@ sw->timer.data = (long) sw; sw->timer.function = sw_timer; - if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); + if (err) goto fail1; dbg("Init 0: Opened %s, io %#x, speed %d", @@ -611,7 +629,10 @@ i = sw_read_packet(gameport, buf, SW_LENGTH, 0); /* Retry reading packet */ udelay(SW_TIMEOUT); dbg("Init 1b: Length %d.", i); - if (!i) goto fail2; /* No data -> FAIL */ + if (!i) { /* No data -> FAIL */ + err = -ENODEV; + goto fail2; + } } j = sw_read_packet(gameport, idbuf, SW_LENGTH, i); /* Read ID. This initializes the stick */ @@ -622,7 +643,10 @@ udelay(SW_TIMEOUT); i = sw_read_packet(gameport, buf, SW_LENGTH, 0); /* Retry reading packet */ dbg("Init 2b: Mode %d. Length %d.", m, i); - if (!i) goto fail2; + if (!i) { + err = -ENODEV; + goto fail2; + } udelay(SW_TIMEOUT); j = sw_read_packet(gameport, idbuf, SW_LENGTH, i); /* Retry reading ID */ dbg("Init 2c: ID Length %d.", j); @@ -686,13 +710,14 @@ } } - } while (k && (sw->type == -1)); + } while (k && sw->type == -1); if (sw->type == -1) { printk(KERN_WARNING "sidewinder.c: unknown joystick device detected " "on %s, contact <vojtech@ucw.cz>\n", gameport->phys); sw_print_packet("ID", j * 3, idbuf, 3); sw_print_packet("Data", i * m, buf, m); + err = -ENODEV; goto fail2; } @@ -742,11 +767,13 @@ sw->name, comment, gameport->phys, m, l, k); } - return; + return 0; + fail2: gameport_close(gameport); fail1: kfree(sw); kfree(buf); kfree(idbuf); + return err; } static void sw_disconnect(struct gameport *gameport) @@ -761,8 +788,12 @@ } static struct gameport_driver sw_drv = { - .connect = sw_connect, - .disconnect = sw_disconnect, + .driver = { + .name = "sidewinder", + }, + .description = DRIVER_DESC, + .connect = sw_connect, + .disconnect = sw_disconnect, }; static int __init sw_init(void) diff -Nru a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c --- a/drivers/input/joystick/tmdc.c 2005-02-11 01:40:01 -05:00 +++ b/drivers/input/joystick/tmdc.c 2005-02-11 01:40:01 -05:00 @@ -39,8 +39,10 @@ #include <linux/gameport.h> #include <linux/input.h> +#define DRIVER_DESC "ThrustMaster DirectConnect joystick driver" + MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); -MODULE_DESCRIPTION("ThrustMaster DirectConnect joystick driver"); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); #define TMDC_MAX_START 400 /* 400 us */ @@ -242,9 +244,9 @@ * tmdc_probe() probes for ThrustMaster type joysticks. */ -static void tmdc_connect(struct gameport *gameport, struct gameport_driver *drv) +static int tmdc_connect(struct gameport *gameport, struct gameport_driver *drv) { - struct models { + static struct models { unsigned char id; char *name; char abs; @@ -263,10 +265,10 @@ unsigned char data[2][TMDC_MAX_LENGTH]; struct tmdc *tmdc; int i, j, k, l, m; + int err; - if (!(tmdc = kmalloc(sizeof(struct tmdc), GFP_KERNEL))) - return; - memset(tmdc, 0, sizeof(struct tmdc)); + if (!(tmdc = kcalloc(1, sizeof(struct tmdc), GFP_KERNEL))) + return -ENOMEM; gameport->private = tmdc; @@ -275,11 +277,14 @@ tmdc->timer.data = (long) tmdc; tmdc->timer.function = tmdc_timer; - if (gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); + if (err) goto fail1; - if (!(tmdc->exists = tmdc_read_packet(gameport, data))) + if (!(tmdc->exists = tmdc_read_packet(gameport, data))) { + err = -ENODEV; goto fail2; + } for (j = 0; j < 2; j++) if (tmdc->exists & (1 << j)) { @@ -321,20 +326,13 @@ tmdc->dev[j].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - for (i = 0; i < models[m].abs && i < TMDC_ABS; i++) { - if (tmdc->abs[j][i] < 0) continue; - set_bit(tmdc->abs[j][i], tmdc->dev[j].absbit); - tmdc->dev[j].absmin[tmdc->abs[j][i]] = 8; - tmdc->dev[j].absmax[tmdc->abs[j][i]] = 248; - tmdc->dev[j].absfuzz[tmdc->abs[j][i]] = 2; - tmdc->dev[j].absflat[tmdc->abs[j][i]] = 4; - } + for (i = 0; i < models[m].abs && i < TMDC_ABS; i++) + if (tmdc->abs[j][i] >= 0) + input_set_abs_params(&tmdc->dev[j], tmdc->abs[j][i], 8, 248, 2, 4); + + for (i = 0; i < models[m].hats && i < TMDC_ABS_HAT; i++) + input_set_abs_params(&tmdc->dev[j], tmdc_abs_hat[i], -1, 1, 0, 0); - for (i = 0; i < models[m].hats && i < TMDC_ABS_HAT; i++) { - set_bit(tmdc_abs_hat[i], tmdc->dev[j].absbit); - tmdc->dev[j].absmin[tmdc_abs_hat[i]] = -1; - tmdc->dev[j].absmax[tmdc_abs_hat[i]] = 1; - } for (k = l = 0; k < 4; k++) { for (i = 0; i < models[m].btnc[k] && i < TMDC_BTN; i++) @@ -346,15 +344,18 @@ printk(KERN_INFO "input: %s on %s\n", tmdc->name[j], gameport->phys); } - return; + return 0; + fail2: gameport_close(gameport); fail1: kfree(tmdc); + return err; } static void tmdc_disconnect(struct gameport *gameport) { struct tmdc *tmdc = gameport->private; int i; + for (i = 0; i < 2; i++) if (tmdc->exists & (1 << i)) input_unregister_device(tmdc->dev + i); @@ -363,8 +364,12 @@ } static struct gameport_driver tmdc_drv = { - .connect = tmdc_connect, - .disconnect = tmdc_disconnect, + .driver = { + .name = "tmdc", + }, + .description = DRIVER_DESC, + .connect = tmdc_connect, + .disconnect = tmdc_disconnect, }; static int __init tmdc_init(void) diff -Nru a/include/linux/gameport.h b/include/linux/gameport.h --- a/include/linux/gameport.h 2005-02-11 01:40:01 -05:00 +++ b/include/linux/gameport.h 2005-02-11 01:40:01 -05:00 @@ -45,13 +45,15 @@ struct gameport_driver { void *private; - char *name; + char *description; - void (*connect)(struct gameport *, struct gameport_driver *drv); + int (*connect)(struct gameport *, struct gameport_driver *drv); void (*disconnect)(struct gameport *); + struct device_driver driver; struct list_head node; }; +#define to_gameport_driver(d) container_of(d, struct gameport_driver, driver) int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode); void gameport_close(struct gameport *gameport); ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 9/10] Gameport: complete sysfs integration 2005-02-11 7:04 ` [PATCH 8/10] Gameport: add "gameport" sysfs bus, add drivers Dmitry Torokhov @ 2005-02-11 7:04 ` Dmitry Torokhov 2005-02-11 7:05 ` [PATCH 10/10] Gameport: replace ->private with gameport_get/set_drvdata Dmitry Torokhov 0 siblings, 1 reply; 12+ messages in thread From: Dmitry Torokhov @ 2005-02-11 7:04 UTC (permalink / raw) To: InputML; +Cc: alsa-devel, LKML, Vojtech Pavlik =================================================================== ChangeSet@1.2157, 2005-02-11 01:21:32-05:00, dtor_core@ameritech.net Input: complete gameport sysfs integration, ports are now devices in driver model. Implemented similarly to serio. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> drivers/input/gameport/gameport.c | 586 ++++++++++++++++++++++++++++++++++---- include/linux/gameport.h | 64 ++-- 2 files changed, 579 insertions(+), 71 deletions(-) =================================================================== diff -Nru a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c --- a/drivers/input/gameport/gameport.c 2005-02-11 01:40:19 -05:00 +++ b/drivers/input/gameport/gameport.c 2005-02-11 01:40:19 -05:00 @@ -2,6 +2,7 @@ * Generic gameport layer * * Copyright (c) 1999-2002 Vojtech Pavlik + * Copyright (c) 2005 Dmitry Torokhov */ /* @@ -10,22 +11,27 @@ * the Free Software Foundation. */ -#include <asm/io.h> +#include <linux/stddef.h> #include <linux/module.h> #include <linux/ioport.h> #include <linux/init.h> #include <linux/gameport.h> +#include <linux/wait.h> +#include <linux/completion.h> +#include <linux/sched.h> +#include <linux/smp_lock.h> #include <linux/slab.h> -#include <linux/stddef.h> #include <linux/delay.h> +/*#include <asm/io.h>*/ + MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); MODULE_DESCRIPTION("Generic gameport layer"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(gameport_register_port); +EXPORT_SYMBOL(__gameport_register_port); EXPORT_SYMBOL(gameport_unregister_port); -EXPORT_SYMBOL(gameport_register_driver); +EXPORT_SYMBOL(__gameport_register_driver); EXPORT_SYMBOL(gameport_unregister_driver); EXPORT_SYMBOL(gameport_open); EXPORT_SYMBOL(gameport_close); @@ -34,13 +40,23 @@ EXPORT_SYMBOL(gameport_set_name); EXPORT_SYMBOL(gameport_set_phys); +/* + * gameport_sem protects entire gameport subsystem and is taken + * every time gameport port or driver registrered or unregistered. + */ +static DECLARE_MUTEX(gameport_sem); + static LIST_HEAD(gameport_list); -static LIST_HEAD(gameport_driver_list); static struct bus_type gameport_bus = { .name = "gameport", }; +static void gameport_add_port(struct gameport *gameport); +static void gameport_destroy_port(struct gameport *gameport); +static void gameport_reconnect_port(struct gameport *gameport); +static void gameport_disconnect_port(struct gameport *gameport); + #ifdef __i386__ #define DELTA(x,y) ((y)-(x)+((y)<(x)?1193182/HZ:0)) @@ -106,21 +122,325 @@ #endif } + +/* + * Basic gameport -> driver core mappings + */ + +static void gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv) +{ + down_write(&gameport_bus.subsys.rwsem); + + gameport->dev.driver = &drv->driver; + if (drv->connect(gameport, drv)) { + gameport->dev.driver = NULL; + goto out; + } + device_bind_driver(&gameport->dev); +out: + up_write(&gameport_bus.subsys.rwsem); +} + +static void gameport_release_driver(struct gameport *gameport) +{ + down_write(&gameport_bus.subsys.rwsem); + device_release_driver(&gameport->dev); + up_write(&gameport_bus.subsys.rwsem); +} + static void gameport_find_driver(struct gameport *gameport) { - struct gameport_driver *drv; + down_write(&gameport_bus.subsys.rwsem); + device_attach(&gameport->dev); + up_write(&gameport_bus.subsys.rwsem); +} + + +/* + * Gameport event processing. + */ + +enum gameport_event_type { + GAMEPORT_RESCAN, + GAMEPORT_RECONNECT, + GAMEPORT_REGISTER_PORT, + GAMEPORT_REGISTER_DRIVER, +}; + +struct gameport_event { + enum gameport_event_type type; + void *object; + struct module *owner; + struct list_head node; +}; + +static DEFINE_SPINLOCK(gameport_event_lock); /* protects gameport_event_list */ +static LIST_HEAD(gameport_event_list); +static DECLARE_WAIT_QUEUE_HEAD(gameport_wait); +static DECLARE_COMPLETION(gameport_exited); +static int gameport_pid; + +static void gameport_queue_event(void *object, struct module *owner, + enum gameport_event_type event_type) +{ + unsigned long flags; + struct gameport_event *event; + + spin_lock_irqsave(&gameport_event_lock, flags); - list_for_each_entry(drv, &gameport_driver_list, node) { - if (gameport->drv) + /* + * Scan event list for the other events for the same gameport port, + * starting with the most recent one. If event is the same we + * do not need add new one. If event is of different type we + * need to add this event and should not look further because + * we need to preseve sequence of distinct events. + */ + list_for_each_entry_reverse(event, &gameport_event_list, node) { + if (event->object == object) { + if (event->type == event_type) + goto out; break; - drv->connect(gameport, drv); - } + } + } + + if ((event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC))) { + if (!try_module_get(owner)) { + printk(KERN_WARNING "gameport: Can't get module reference, dropping event %d\n", event_type); + goto out; + } + + event->type = event_type; + event->object = object; + event->owner = owner; + + list_add_tail(&event->node, &gameport_event_list); + wake_up(&gameport_wait); + } else { + printk(KERN_ERR "gameport: Not enough memory to queue event %d\n", event_type); + } +out: + spin_unlock_irqrestore(&gameport_event_lock, flags); } -void gameport_rescan(struct gameport *gameport) +static void gameport_free_event(struct gameport_event *event) { - gameport_close(gameport); - gameport_find_driver(gameport); + module_put(event->owner); + kfree(event); +} + +static void gameport_remove_duplicate_events(struct gameport_event *event) +{ + struct list_head *node, *next; + struct gameport_event *e; + unsigned long flags; + + spin_lock_irqsave(&gameport_event_lock, flags); + + list_for_each_safe(node, next, &gameport_event_list) { + e = list_entry(node, struct gameport_event, node); + if (event->object == e->object) { + /* + * If this event is of different type we should not + * look further - we only suppress duplicate events + * that were sent back-to-back. + */ + if (event->type != e->type) + break; + + list_del_init(node); + gameport_free_event(e); + } + } + + spin_unlock_irqrestore(&gameport_event_lock, flags); +} + + +static struct gameport_event *gameport_get_event(void) +{ + struct gameport_event *event; + struct list_head *node; + unsigned long flags; + + spin_lock_irqsave(&gameport_event_lock, flags); + + if (list_empty(&gameport_event_list)) { + spin_unlock_irqrestore(&gameport_event_lock, flags); + return NULL; + } + + node = gameport_event_list.next; + event = list_entry(node, struct gameport_event, node); + list_del_init(node); + + spin_unlock_irqrestore(&gameport_event_lock, flags); + + return event; +} + +static void gameport_handle_events(void) +{ + struct gameport_event *event; + struct gameport_driver *gameport_drv; + + down(&gameport_sem); + + while ((event = gameport_get_event())) { + + switch (event->type) { + case GAMEPORT_REGISTER_PORT: + gameport_add_port(event->object); + break; + + case GAMEPORT_RECONNECT: + gameport_reconnect_port(event->object); + break; + + case GAMEPORT_RESCAN: + gameport_disconnect_port(event->object); + gameport_find_driver(event->object); + break; + + case GAMEPORT_REGISTER_DRIVER: + gameport_drv = event->object; + driver_register(&gameport_drv->driver); + break; + + default: + break; + } + + gameport_remove_duplicate_events(event); + gameport_free_event(event); + } + + up(&gameport_sem); +} + +/* + * Remove all events that have been submitted for a given gameport port. + */ +static void gameport_remove_pending_events(struct gameport *gameport) +{ + struct list_head *node, *next; + struct gameport_event *event; + unsigned long flags; + + spin_lock_irqsave(&gameport_event_lock, flags); + + list_for_each_safe(node, next, &gameport_event_list) { + event = list_entry(node, struct gameport_event, node); + if (event->object == gameport) { + list_del_init(node); + gameport_free_event(event); + } + } + + spin_unlock_irqrestore(&gameport_event_lock, flags); +} + +/* + * Destroy child gameport port (if any) that has not been fully registered yet. + * + * Note that we rely on the fact that port can have only one child and therefore + * only one child registration request can be pending. Additionally, children + * are registered by driver's connect() handler so there can't be a grandchild + * pending registration together with a child. + */ +static struct gameport *gameport_get_pending_child(struct gameport *parent) +{ + struct gameport_event *event; + struct gameport *gameport, *child = NULL; + unsigned long flags; + + spin_lock_irqsave(&gameport_event_lock, flags); + + list_for_each_entry(event, &gameport_event_list, node) { + if (event->type == GAMEPORT_REGISTER_PORT) { + gameport = event->object; + if (gameport->parent == parent) { + child = gameport; + break; + } + } + } + + spin_unlock_irqrestore(&gameport_event_lock, flags); + return child; +} + +static int gameport_thread(void *nothing) +{ + lock_kernel(); + daemonize("kgameportd"); + allow_signal(SIGTERM); + + do { + gameport_handle_events(); + wait_event_interruptible(gameport_wait, !list_empty(&gameport_event_list)); + try_to_freeze(PF_FREEZE); + } while (!signal_pending(current)); + + printk(KERN_DEBUG "gameport: kgameportd exiting\n"); + + unlock_kernel(); + complete_and_exit(&gameport_exited, 0); +} + + +/* + * Gameport port operations + */ + +static ssize_t gameport_show_description(struct device *dev, char *buf) +{ + struct gameport *gameport = to_gameport_port(dev); + return sprintf(buf, "%s\n", gameport->name); +} + +static ssize_t gameport_rebind_driver(struct device *dev, const char *buf, size_t count) +{ + struct gameport *gameport = to_gameport_port(dev); + struct device_driver *drv; + int retval; + + retval = down_interruptible(&gameport_sem); + if (retval) + return retval; + + retval = count; + if (!strncmp(buf, "none", count)) { + gameport_disconnect_port(gameport); + } else if (!strncmp(buf, "reconnect", count)) { + gameport_reconnect_port(gameport); + } else if (!strncmp(buf, "rescan", count)) { + gameport_disconnect_port(gameport); + gameport_find_driver(gameport); + } else if ((drv = driver_find(buf, &gameport_bus)) != NULL) { + gameport_disconnect_port(gameport); + gameport_bind_driver(gameport, to_gameport_driver(drv)); + put_driver(drv); + } else { + retval = -EINVAL; + } + + up(&gameport_sem); + + return retval; +} + +static struct device_attribute gameport_device_attrs[] = { + __ATTR(description, S_IRUGO, gameport_show_description, NULL), + __ATTR(drvctl, S_IWUSR, NULL, gameport_rebind_driver), + __ATTR_NULL +}; + +static void gameport_release_port(struct device *dev) +{ + struct gameport *gameport = to_gameport_port(dev); + + kfree(gameport); + module_put(THIS_MODULE); } void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) @@ -128,29 +448,162 @@ va_list args; va_start(args, fmt); - gameport->phys = gameport->phys_buf; - vsnprintf(gameport->phys_buf, sizeof(gameport->phys_buf), fmt, args); + vsnprintf(gameport->phys, sizeof(gameport->phys), fmt, args); va_end(args); } -void gameport_register_port(struct gameport *gameport) +/* + * Prepare gameport port for registration. + */ +static void gameport_init_port(struct gameport *gameport) { - list_add_tail(&gameport->node, &gameport_list); + static atomic_t gameport_no = ATOMIC_INIT(0); + + __module_get(THIS_MODULE); + + init_MUTEX(&gameport->drv_sem); + device_initialize(&gameport->dev); + snprintf(gameport->dev.bus_id, sizeof(gameport->dev.bus_id), + "gameport%lu", (unsigned long)atomic_inc_return(&gameport_no) - 1); + gameport->dev.bus = &gameport_bus; + gameport->dev.release = gameport_release_port; + if (gameport->parent) + gameport->dev.parent = &gameport->parent->dev; +} + +/* + * Complete gameport port registration. + * Driver core will attempt to find appropriate driver for the port. + */ +static void gameport_add_port(struct gameport *gameport) +{ + if (gameport->parent) + gameport->parent->child = gameport; + gameport->speed = gameport_measure_speed(gameport); - if (gameport->dyn_alloc) { - if (gameport->io) - printk(KERN_INFO "gameport: %s is %s, io %#x, speed %d kHz\n", - gameport->name, gameport->phys, gameport->io, gameport->speed); - else - printk(KERN_INFO "gameport: %s is %s, speed %d kHz\n", - gameport->name, gameport->phys, gameport->speed); + list_add_tail(&gameport->node, &gameport_list); + + if (gameport->io) + printk(KERN_INFO "gameport: %s is %s, io %#x, speed %dkHz\n", + gameport->name, gameport->phys, gameport->io, gameport->speed); + else + printk(KERN_INFO "gameport: %s is %s, speed %dkHz\n", + gameport->name, gameport->phys, gameport->speed); + + device_add(&gameport->dev); + gameport->registered = 1; +} + +/* + * gameport_destroy_port() completes deregistration process and removes + * port from the system + */ +static void gameport_destroy_port(struct gameport *gameport) +{ + struct gameport *child; + + child = gameport_get_pending_child(gameport); + if (child) { + gameport_remove_pending_events(child); + put_device(&child->dev); } - gameport_find_driver(gameport); + if (gameport->parent) { + gameport->parent->child = NULL; + gameport->parent = NULL; + } + + if (gameport->registered) { + device_del(&gameport->dev); + list_del_init(&gameport->node); + gameport->registered = 0; + } + + gameport_remove_pending_events(gameport); + put_device(&gameport->dev); } /* + * Reconnect gameport port and all its children (re-initialize attached devices) + */ +static void gameport_reconnect_port(struct gameport *gameport) +{ + do { + if (!gameport->drv || !gameport->drv->reconnect || gameport->drv->reconnect(gameport)) { + gameport_disconnect_port(gameport); + gameport_find_driver(gameport); + /* Ok, old children are now gone, we are done */ + break; + } + gameport = gameport->child; + } while (gameport); +} + +/* + * gameport_disconnect_port() unbinds a port from its driver. As a side effect + * all child ports are unbound and destroyed. + */ +static void gameport_disconnect_port(struct gameport *gameport) +{ + struct gameport *s, *parent; + + if (gameport->child) { + /* + * Children ports should be disconnected and destroyed + * first, staring with the leaf one, since we don't want + * to do recursion + */ + for (s = gameport; s->child; s = s->child) + /* empty */; + + do { + parent = s->parent; + + gameport_release_driver(s); + gameport_destroy_port(s); + } while ((s = parent) != gameport); + } + + /* + * Ok, no children left, now disconnect this port + */ + gameport_release_driver(gameport); +} + +void gameport_rescan(struct gameport *gameport) +{ + gameport_queue_event(gameport, NULL, GAMEPORT_RESCAN); +} + +void gameport_reconnect(struct gameport *gameport) +{ + gameport_queue_event(gameport, NULL, GAMEPORT_RECONNECT); +} + +/* + * Submits register request to kgameportd for subsequent execution. + * Note that port registration is always asynchronous. + */ +void __gameport_register_port(struct gameport *gameport, struct module *owner) +{ + gameport_init_port(gameport); + gameport_queue_event(gameport, owner, GAMEPORT_REGISTER_PORT); +} + +/* + * Synchronously unregisters gameport port. + */ +void gameport_unregister_port(struct gameport *gameport) +{ + down(&gameport_sem); + gameport_disconnect_port(gameport); + gameport_destroy_port(gameport); + up(&gameport_sem); +} + + +/* * Gameport driver operations */ @@ -165,69 +618,100 @@ __ATTR_NULL }; -void gameport_unregister_port(struct gameport *gameport) +static int gameport_driver_probe(struct device *dev) { - list_del_init(&gameport->node); - if (gameport->drv) - gameport->drv->disconnect(gameport); - if (gameport->dyn_alloc) - kfree(gameport); + struct gameport *gameport = to_gameport_port(dev); + struct gameport_driver *drv = to_gameport_driver(dev->driver); + + drv->connect(gameport, drv); + return gameport->drv ? 0 : -ENODEV; } -void gameport_register_driver(struct gameport_driver *drv) +static int gameport_driver_remove(struct device *dev) { - struct gameport *gameport; + struct gameport *gameport = to_gameport_port(dev); + struct gameport_driver *drv = to_gameport_driver(dev->driver); - drv->driver.bus = &gameport_bus; - driver_register(&drv->driver); + drv->disconnect(gameport); + return 0; +} - list_add_tail(&drv->node, &gameport_driver_list); - list_for_each_entry(gameport, &gameport_list, node) - if (!gameport->drv) - drv->connect(gameport, drv); +void __gameport_register_driver(struct gameport_driver *drv, struct module *owner) +{ + drv->driver.bus = &gameport_bus; + drv->driver.probe = gameport_driver_probe; + drv->driver.remove = gameport_driver_remove; + gameport_queue_event(drv, owner, GAMEPORT_REGISTER_DRIVER); } void gameport_unregister_driver(struct gameport_driver *drv) { struct gameport *gameport; - list_del_init(&drv->node); + down(&gameport_sem); + drv->ignore = 1; /* so gameport_find_driver ignores it */ + +start_over: list_for_each_entry(gameport, &gameport_list, node) { - if (gameport->drv == drv) - drv->disconnect(gameport); - gameport_find_driver(gameport); + if (gameport->drv == drv) { + gameport_disconnect_port(gameport); + gameport_find_driver(gameport); + /* we could've deleted some ports, restart */ + goto start_over; + } } + driver_unregister(&drv->driver); + up(&gameport_sem); +} + +static int gameport_bus_match(struct device *dev, struct device_driver *drv) +{ + struct gameport_driver *gameport_drv = to_gameport_driver(drv); + + return !gameport_drv->ignore; +} + +static void gameport_set_drv(struct gameport *gameport, struct gameport_driver *drv) +{ + down(&gameport->drv_sem); + gameport->drv = drv; + up(&gameport->drv_sem); } int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode) { + if (gameport->open) { - if (gameport->open(gameport, mode)) + if (gameport->open(gameport, mode)) { return -1; + } } else { if (mode != GAMEPORT_MODE_RAW) return -1; } - if (gameport->drv) - return -1; - - gameport->drv = drv; - + gameport_set_drv(gameport, drv); return 0; } void gameport_close(struct gameport *gameport) { - gameport->drv = NULL; + gameport_set_drv(gameport, NULL); if (gameport->close) gameport->close(gameport); } static int __init gameport_init(void) { + if (!(gameport_pid = kernel_thread(gameport_thread, NULL, CLONE_KERNEL))) { + printk(KERN_ERR "gameport: Failed to start kgameportd\n"); + return -1; + } + + gameport_bus.dev_attrs = gameport_device_attrs; gameport_bus.drv_attrs = gameport_driver_attrs; + gameport_bus.match = gameport_bus_match; bus_register(&gameport_bus); return 0; @@ -236,6 +720,8 @@ static void __exit gameport_exit(void) { bus_unregister(&gameport_bus); + kill_proc(gameport_pid, SIGTERM, 1); + wait_for_completion(&gameport_exited); } module_init(gameport_init); diff -Nru a/include/linux/gameport.h b/include/linux/gameport.h --- a/include/linux/gameport.h 2005-02-11 01:40:19 -05:00 +++ b/include/linux/gameport.h 2005-02-11 01:40:19 -05:00 @@ -17,10 +17,8 @@ void *private; /* Private pointer for joystick drivers */ void *port_data; /* Private pointer for gameport drivers */ - char *name; - char name_buf[32]; - char *phys; - char phys_buf[32]; + char name[32]; + char phys[32]; int io; int speed; @@ -33,14 +31,17 @@ int (*open)(struct gameport *, int); void (*close)(struct gameport *); + struct gameport *parent, *child; + struct gameport_driver *drv; + struct semaphore drv_sem; /* protects serio->drv so attributes can pin driver */ + struct device dev; + unsigned int registered; /* port has been fully registered with driver core */ struct list_head node; - - /* temporary, till sysfs transition is complete */ - int dyn_alloc; }; +#define to_gameport_port(d) container_of(d, struct gameport, dev) struct gameport_driver { @@ -48,10 +49,12 @@ char *description; int (*connect)(struct gameport *, struct gameport_driver *drv); + int (*reconnect)(struct gameport *); void (*disconnect)(struct gameport *); struct device_driver driver; - struct list_head node; + + unsigned int ignore; }; #define to_gameport_driver(d) container_of(d, struct gameport_driver, driver) @@ -59,13 +62,18 @@ void gameport_close(struct gameport *gameport); void gameport_rescan(struct gameport *gameport); +void __gameport_register_port(struct gameport *gameport, struct module *owner); +static inline void gameport_register_port(struct gameport *gameport) +{ + __gameport_register_port(gameport, THIS_MODULE); +} + +void gameport_unregister_port(struct gameport *gameport); + static inline struct gameport *gameport_allocate_port(void) { struct gameport *gameport = kcalloc(1, sizeof(struct gameport), GFP_KERNEL); - if (gameport) - gameport->dyn_alloc = 1; - return gameport; } @@ -76,17 +84,31 @@ static inline void gameport_set_name(struct gameport *gameport, const char *name) { - gameport->name = gameport->name_buf; - strlcpy(gameport->name, name, sizeof(gameport->name_buf)); + strlcpy(gameport->name, name, sizeof(gameport->name)); } void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); -void gameport_register_port(struct gameport *gameport); -void gameport_unregister_port(struct gameport *gameport); +/* + * Use the following fucntions to pin gameport's driver in process context + */ +static inline int gameport_pin_driver(struct gameport *gameport) +{ + return down_interruptible(&gameport->drv_sem); +} + +static inline void gameport_unpin_driver(struct gameport *gameport) +{ + up(&gameport->drv_sem); +} + +void __gameport_register_driver(struct gameport_driver *drv, struct module *owner); +static inline void gameport_register_driver(struct gameport_driver *drv) +{ + __gameport_register_driver(drv, THIS_MODULE); +} -void gameport_register_driver(struct gameport_driver *drv); void gameport_unregister_driver(struct gameport_driver *drv); #define GAMEPORT_MODE_DISABLED 0 @@ -104,7 +126,7 @@ #define GAMEPORT_ID_VENDOR_GRAVIS 0x0009 #define GAMEPORT_ID_VENDOR_GUILLEMOT 0x000a -static __inline__ void gameport_trigger(struct gameport *gameport) +static inline void gameport_trigger(struct gameport *gameport) { if (gameport->trigger) gameport->trigger(gameport); @@ -112,7 +134,7 @@ outb(0xff, gameport->io); } -static __inline__ unsigned char gameport_read(struct gameport *gameport) +static inline unsigned char gameport_read(struct gameport *gameport) { if (gameport->read) return gameport->read(gameport); @@ -120,7 +142,7 @@ return inb(gameport->io); } -static __inline__ int gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) +static inline int gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons) { if (gameport->cooked_read) return gameport->cooked_read(gameport, axes, buttons); @@ -128,7 +150,7 @@ return -1; } -static __inline__ int gameport_calibrate(struct gameport *gameport, int *axes, int *max) +static inline int gameport_calibrate(struct gameport *gameport, int *axes, int *max) { if (gameport->calibrate) return gameport->calibrate(gameport, axes, max); @@ -136,7 +158,7 @@ return -1; } -static __inline__ int gameport_time(struct gameport *gameport, int time) +static inline int gameport_time(struct gameport *gameport, int time) { return (time * gameport->speed) / 1000; } ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 10/10] Gameport: replace ->private with gameport_get/set_drvdata 2005-02-11 7:04 ` [PATCH 9/10] Gameport: complete sysfs integration Dmitry Torokhov @ 2005-02-11 7:05 ` Dmitry Torokhov 0 siblings, 0 replies; 12+ messages in thread From: Dmitry Torokhov @ 2005-02-11 7:05 UTC (permalink / raw) To: InputML; +Cc: alsa-devel, LKML, Vojtech Pavlik =================================================================== ChangeSet@1.2158, 2005-02-11 01:23:40-05:00, dtor_core@ameritech.net Input: remove gameport->private in favor of using driver-specific data in device structure, add gameport_get/set_drvdata to access it. Signed-off-by: Dmitry Torokhov <dtor@mail.ru> drivers/input/joystick/a3d.c | 10 ++++++---- drivers/input/joystick/adi.c | 7 ++++--- drivers/input/joystick/analog.c | 7 +++++-- drivers/input/joystick/cobra.c | 10 ++++++---- drivers/input/joystick/gf2k.c | 10 ++++++---- drivers/input/joystick/grip.c | 10 ++++++---- drivers/input/joystick/grip_mp.c | 9 ++++++--- drivers/input/joystick/guillemot.c | 9 +++++---- drivers/input/joystick/interact.c | 10 ++++++---- drivers/input/joystick/sidewinder.c | 10 ++++++---- drivers/input/joystick/tmdc.c | 10 ++++++---- include/linux/gameport.h | 15 ++++++++++++++- 12 files changed, 76 insertions(+), 41 deletions(-) =================================================================== diff -Nru a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c --- a/drivers/input/joystick/a3d.c 2005-02-11 01:41:08 -05:00 +++ b/drivers/input/joystick/a3d.c 2005-02-11 01:41:08 -05:00 @@ -277,13 +277,13 @@ if (!(a3d = kcalloc(1, sizeof(struct a3d), GFP_KERNEL))) return -ENOMEM; - gameport->private = a3d; - a3d->gameport = gameport; init_timer(&a3d->timer); a3d->timer.data = (long) a3d; a3d->timer.function = a3d_timer; + gameport_set_drvdata(gameport, a3d); + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); if (err) goto fail1; @@ -379,13 +379,14 @@ return 0; fail2: gameport_close(gameport); -fail1: kfree(a3d); +fail1: gameport_set_drvdata(gameport, NULL); + kfree(a3d); return err; } static void a3d_disconnect(struct gameport *gameport) { - struct a3d *a3d = gameport->private; + struct a3d *a3d = gameport_get_drvdata(gameport); input_unregister_device(&a3d->dev); if (a3d->adc) { @@ -393,6 +394,7 @@ a3d->adc = NULL; } gameport_close(gameport); + gameport_set_drvdata(gameport, NULL); kfree(a3d); } diff -Nru a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c --- a/drivers/input/joystick/adi.c 2005-02-11 01:41:08 -05:00 +++ b/drivers/input/joystick/adi.c 2005-02-11 01:41:08 -05:00 @@ -474,13 +474,13 @@ if (!(port = kcalloc(1, sizeof(struct adi_port), GFP_KERNEL))) return -ENOMEM; - gameport->private = port; - port->gameport = gameport; init_timer(&port->timer); port->timer.data = (long) port; port->timer.function = adi_timer; + gameport_set_drvdata(gameport, port); + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); if (err) { kfree(port); @@ -524,12 +524,13 @@ static void adi_disconnect(struct gameport *gameport) { int i; - struct adi_port *port = gameport->private; + struct adi_port *port = gameport_get_drvdata(gameport); for (i = 0; i < 2; i++) if (port->adi[i].length > 0) input_unregister_device(&port->adi[i].dev); gameport_close(gameport); + gameport_set_drvdata(gameport, NULL); kfree(port); } diff -Nru a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c --- a/drivers/input/joystick/analog.c 2005-02-11 01:41:08 -05:00 +++ b/drivers/input/joystick/analog.c 2005-02-11 01:41:08 -05:00 @@ -593,12 +593,13 @@ { int i, t, u, v; - gameport->private = port; port->gameport = gameport; init_timer(&port->timer); port->timer.data = (long) port; port->timer.function = analog_timer; + gameport_set_drvdata(gameport, port); + if (!gameport_open(gameport, drv, GAMEPORT_MODE_RAW)) { analog_calibrate_timer(port); @@ -672,6 +673,7 @@ err = analog_init_masks(port); if (err) { gameport_close(gameport); + gameport_set_drvdata(gameport, NULL); kfree(port); return err; } @@ -686,12 +688,13 @@ static void analog_disconnect(struct gameport *gameport) { int i; - struct analog_port *port = gameport->private; + struct analog_port *port = gameport_get_drvdata(gameport); for (i = 0; i < 2; i++) if (port->analog[i].mask) input_unregister_device(&port->analog[i].dev); gameport_close(gameport); + gameport_set_drvdata(gameport, NULL); printk(KERN_INFO "analog.c: %d out of %d reads (%d%%) on %s failed\n", port->bads, port->reads, port->reads ? (port->bads * 100 / port->reads) : 0, port->gameport->phys); diff -Nru a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c --- a/drivers/input/joystick/cobra.c 2005-02-11 01:41:08 -05:00 +++ b/drivers/input/joystick/cobra.c 2005-02-11 01:41:08 -05:00 @@ -170,13 +170,13 @@ if (!(cobra = kcalloc(1, sizeof(struct cobra), GFP_KERNEL))) return -ENOMEM; - gameport->private = cobra; - cobra->gameport = gameport; init_timer(&cobra->timer); cobra->timer.data = (long) cobra; cobra->timer.function = cobra_timer; + gameport_set_drvdata(gameport, cobra); + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); if (err) goto fail1; @@ -226,19 +226,21 @@ return 0; fail2: gameport_close(gameport); -fail1: kfree(cobra); +fail1: gameport_set_drvdata(gameport, NULL); + kfree(cobra); return err; } static void cobra_disconnect(struct gameport *gameport) { + struct cobra *cobra = gameport_get_drvdata(gameport); int i; - struct cobra *cobra = gameport->private; for (i = 0; i < 2; i++) if ((cobra->exists >> i) & 1) input_unregister_device(cobra->dev + i); gameport_close(gameport); + gameport_set_drvdata(gameport, NULL); kfree(cobra); } diff -Nru a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c --- a/drivers/input/joystick/gf2k.c 2005-02-11 01:41:08 -05:00 +++ b/drivers/input/joystick/gf2k.c 2005-02-11 01:41:08 -05:00 @@ -249,13 +249,13 @@ if (!(gf2k = kcalloc(1, sizeof(struct gf2k), GFP_KERNEL))) return -ENOMEM; - gameport->private = gf2k; - gf2k->gameport = gameport; init_timer(&gf2k->timer); gf2k->timer.data = (long) gf2k; gf2k->timer.function = gf2k_timer; + gameport_set_drvdata(gameport, gf2k); + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); if (err) goto fail1; @@ -345,16 +345,18 @@ return 0; fail2: gameport_close(gameport); -fail1: kfree(gf2k); +fail1: gameport_set_drvdata(gameport, NULL); + kfree(gf2k); return err; } static void gf2k_disconnect(struct gameport *gameport) { - struct gf2k *gf2k = gameport->private; + struct gf2k *gf2k = gameport_get_drvdata(gameport); input_unregister_device(&gf2k->dev); gameport_close(gameport); + gameport_set_drvdata(gameport, NULL); kfree(gf2k); } diff -Nru a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c --- a/drivers/input/joystick/grip.c 2005-02-11 01:41:08 -05:00 +++ b/drivers/input/joystick/grip.c 2005-02-11 01:41:08 -05:00 @@ -310,13 +310,13 @@ if (!(grip = kcalloc(1, sizeof(struct grip), GFP_KERNEL))) return -ENOMEM; - gameport->private = grip; - grip->gameport = gameport; init_timer(&grip->timer); grip->timer.data = (long) grip; grip->timer.function = grip_timer; + gameport_set_drvdata(gameport, grip); + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); if (err) goto fail1; @@ -386,19 +386,21 @@ return 0; fail2: gameport_close(gameport); -fail1: kfree(grip); +fail1: gameport_set_drvdata(gameport, NULL); + kfree(grip); return err; } static void grip_disconnect(struct gameport *gameport) { - struct grip *grip = gameport->private; + struct grip *grip = gameport_get_drvdata(gameport); int i; for (i = 0; i < 2; i++) if (grip->mode[i]) input_unregister_device(grip->dev + i); gameport_close(gameport); + gameport_set_drvdata(gameport, NULL); kfree(grip); } diff -Nru a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c --- a/drivers/input/joystick/grip_mp.c 2005-02-11 01:41:08 -05:00 +++ b/drivers/input/joystick/grip_mp.c 2005-02-11 01:41:08 -05:00 @@ -626,12 +626,13 @@ if (!(grip = kcalloc(1, sizeof(struct grip_mp), GFP_KERNEL))) return -ENOMEM; - gameport->private = grip; grip->gameport = gameport; init_timer(&grip->timer); grip->timer.data = (long) grip; grip->timer.function = grip_timer; + gameport_set_drvdata(gameport, grip); + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); if (err) goto fail1; @@ -650,19 +651,21 @@ return 0; fail2: gameport_close(gameport); -fail1: kfree(grip); +fail1: gameport_set_drvdata(gameport, NULL); + kfree(grip); return err; } static void grip_disconnect(struct gameport *gameport) { + struct grip_mp *grip = gameport_get_drvdata(gameport); int i; - struct grip_mp *grip = gameport->private; for (i = 0; i < 4; i++) if (grip->registered[i]) input_unregister_device(grip->dev + i); gameport_close(gameport); + gameport_set_drvdata(gameport, NULL); kfree(grip); } diff -Nru a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c --- a/drivers/input/joystick/guillemot.c 2005-02-11 01:41:08 -05:00 +++ b/drivers/input/joystick/guillemot.c 2005-02-11 01:41:08 -05:00 @@ -193,13 +193,13 @@ if (!(guillemot = kcalloc(1, sizeof(struct guillemot), GFP_KERNEL))) return -ENOMEM; - gameport->private = guillemot; - guillemot->gameport = gameport; init_timer(&guillemot->timer); guillemot->timer.data = (long) guillemot; guillemot->timer.function = guillemot_timer; + gameport_set_drvdata(gameport, guillemot); + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); if (err) goto fail1; @@ -257,13 +257,14 @@ return 0; fail2: gameport_close(gameport); -fail1: kfree(guillemot); +fail1: gameport_set_drvdata(gameport, NULL); + kfree(guillemot); return err; } static void guillemot_disconnect(struct gameport *gameport) { - struct guillemot *guillemot = gameport->private; + struct guillemot *guillemot = gameport_get_drvdata(gameport); printk(KERN_INFO "guillemot.c: Failed %d reads out of %d on %s\n", guillemot->reads, guillemot->bads, guillemot->phys); input_unregister_device(&guillemot->dev); diff -Nru a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c --- a/drivers/input/joystick/interact.c 2005-02-11 01:41:08 -05:00 +++ b/drivers/input/joystick/interact.c 2005-02-11 01:41:08 -05:00 @@ -223,13 +223,13 @@ if (!(interact = kcalloc(1, sizeof(struct interact), GFP_KERNEL))) return -ENOMEM; - gameport->private = interact; - interact->gameport = gameport; init_timer(&interact->timer); interact->timer.data = (long) interact; interact->timer.function = interact_timer; + gameport_set_drvdata(gameport, interact); + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); if (err) goto fail1; @@ -291,16 +291,18 @@ return 0; fail2: gameport_close(gameport); -fail1: kfree(interact); +fail1: gameport_set_drvdata(gameport, NULL); + kfree(interact); return err; } static void interact_disconnect(struct gameport *gameport) { - struct interact *interact = gameport->private; + struct interact *interact = gameport_get_drvdata(gameport); input_unregister_device(&interact->dev); gameport_close(gameport); + gameport_set_drvdata(gameport, NULL); kfree(interact); } diff -Nru a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c --- a/drivers/input/joystick/sidewinder.c 2005-02-11 01:41:08 -05:00 +++ b/drivers/input/joystick/sidewinder.c 2005-02-11 01:41:08 -05:00 @@ -605,13 +605,13 @@ goto fail1; } - gameport->private = sw; - sw->gameport = gameport; init_timer(&sw->timer); sw->timer.data = (long) sw; sw->timer.function = sw_timer; + gameport_set_drvdata(gameport, sw); + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); if (err) goto fail1; @@ -770,7 +770,8 @@ return 0; fail2: gameport_close(gameport); -fail1: kfree(sw); +fail1: gameport_set_drvdata(gameport, NULL); + kfree(sw); kfree(buf); kfree(idbuf); return err; @@ -778,12 +779,13 @@ static void sw_disconnect(struct gameport *gameport) { + struct sw *sw = gameport_get_drvdata(gameport); int i; - struct sw *sw = gameport->private; for (i = 0; i < sw->number; i++) input_unregister_device(sw->dev + i); gameport_close(gameport); + gameport_set_drvdata(gameport, NULL); kfree(sw); } diff -Nru a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c --- a/drivers/input/joystick/tmdc.c 2005-02-11 01:41:08 -05:00 +++ b/drivers/input/joystick/tmdc.c 2005-02-11 01:41:08 -05:00 @@ -270,13 +270,13 @@ if (!(tmdc = kcalloc(1, sizeof(struct tmdc), GFP_KERNEL))) return -ENOMEM; - gameport->private = tmdc; - tmdc->gameport = gameport; init_timer(&tmdc->timer); tmdc->timer.data = (long) tmdc; tmdc->timer.function = tmdc_timer; + gameport_set_drvdata(gameport, tmdc); + err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW); if (err) goto fail1; @@ -347,19 +347,21 @@ return 0; fail2: gameport_close(gameport); -fail1: kfree(tmdc); +fail1: gameport_set_drvdata(gameport, NULL); + kfree(tmdc); return err; } static void tmdc_disconnect(struct gameport *gameport) { - struct tmdc *tmdc = gameport->private; + struct tmdc *tmdc = gameport_get_drvdata(gameport); int i; for (i = 0; i < 2; i++) if (tmdc->exists & (1 << i)) input_unregister_device(tmdc->dev + i); gameport_close(gameport); + gameport_set_drvdata(gameport, NULL); kfree(tmdc); } diff -Nru a/include/linux/gameport.h b/include/linux/gameport.h --- a/include/linux/gameport.h 2005-02-11 01:41:08 -05:00 +++ b/include/linux/gameport.h 2005-02-11 01:41:08 -05:00 @@ -15,7 +15,6 @@ struct gameport { - void *private; /* Private pointer for joystick drivers */ void *port_data; /* Private pointer for gameport drivers */ char name[32]; char phys[32]; @@ -89,6 +88,20 @@ void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); + +/* + * Use the following fucntions to manipulate gameport's per-port + * driver-specific data. + */ +static inline void *gameport_get_drvdata(struct gameport *gameport) +{ + return dev_get_drvdata(&gameport->dev); +} + +static inline void gameport_set_drvdata(struct gameport *gameport, void *data) +{ + dev_set_drvdata(&gameport->dev, data); +} /* * Use the following fucntions to pin gameport's driver in process context ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 0/10] Convert gameport to driver model/sysfs 2005-02-11 6:58 [PATCH 0/10] Convert gameport to driver model/sysfs Dmitry Torokhov 2005-02-11 6:59 ` [PATCH 1/10] Gameport: rename driver to port_data Dmitry Torokhov @ 2005-02-11 8:11 ` Vojtech Pavlik 1 sibling, 0 replies; 12+ messages in thread From: Vojtech Pavlik @ 2005-02-11 8:11 UTC (permalink / raw) To: Dmitry Torokhov; +Cc: InputML, alsa-devel, LKML On Fri, Feb 11, 2005 at 01:58:47AM -0500, Dmitry Torokhov wrote: > This series of patches adds a new "gameport" bus to the driver model. > It is implemented very similarly to "serio" bus and also allows > individual drivers to be manually bound/disconnected from a port > by manipulating port's "drvctl" attribute. Good work! I'm pulling it into my tree. And test. > The changes can also be pulled from my tree (which has Vojtech's > input tree as a parent): > > bk pull bk://dtor.bkbits.net/input > > I am CC-ing ALSA list as the changes touch quite a few sound drivers. > > Comments/testing is appreciated. -- Vojtech Pavlik SuSE Labs, SuSE CR ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2005-02-11 8:11 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-02-11 6:58 [PATCH 0/10] Convert gameport to driver model/sysfs Dmitry Torokhov 2005-02-11 6:59 ` [PATCH 1/10] Gameport: rename driver to port_data Dmitry Torokhov 2005-02-11 7:00 ` [PATCH 2/10] Gameport: rename gameport_dev to gameport_driver Dmitry Torokhov 2005-02-11 7:00 ` [PATCH 3/10] Gameport: connect() is mandatory Dmitry Torokhov 2005-02-11 7:01 ` [PATCH 4/10] Gameport: prepare to dynamic allocation Dmitry Torokhov 2005-02-11 7:02 ` [PATCH 5/10] Gameport: convert input/gameport " Dmitry Torokhov 2005-02-11 7:02 ` [PATCH 6/10] Gameport: convert sound/oss " Dmitry Torokhov 2005-02-11 7:03 ` [PATCH 7/10] Gameport: convert sound/alsa " Dmitry Torokhov 2005-02-11 7:04 ` [PATCH 8/10] Gameport: add "gameport" sysfs bus, add drivers Dmitry Torokhov 2005-02-11 7:04 ` [PATCH 9/10] Gameport: complete sysfs integration Dmitry Torokhov 2005-02-11 7:05 ` [PATCH 10/10] Gameport: replace ->private with gameport_get/set_drvdata Dmitry Torokhov 2005-02-11 8:11 ` [PATCH 0/10] Convert gameport to driver model/sysfs Vojtech Pavlik
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox