diff -u b/drivers/char/keyboard.c b/drivers/char/keyboard.c --- b/drivers/char/keyboard.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/char/keyboard.c 2005-02-22 18:34:50 -08:00 @@ -929,7 +929,7 @@ #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\ defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC32) ||\ defined(CONFIG_SPARC64) || defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\ - (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC)) + (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_RPC)) #define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\ ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001)) diff -u b/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c --- b/drivers/input/gameport/gameport.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/gameport/gameport.c 2005-02-22 18:34:49 -08:00 @@ -39,8 +39,6 @@ EXPORT_SYMBOL(gameport_cooked_read); EXPORT_SYMBOL(gameport_set_name); EXPORT_SYMBOL(gameport_set_phys); -EXPORT_SYMBOL(gameport_start_polling); -EXPORT_SYMBOL(gameport_stop_polling); /* * gameport_sem protects entire gameport subsystem and is taken @@ -124,37 +122,6 @@ #endif } -void gameport_start_polling(struct gameport *gameport) -{ - spin_lock(&gameport->timer_lock); - - if (!gameport->poll_cnt++) { - BUG_ON(!gameport->poll_handler); - BUG_ON(!gameport->poll_interval); - mod_timer(&gameport->poll_timer, jiffies + msecs_to_jiffies(gameport->poll_interval)); - } - - spin_unlock(&gameport->timer_lock); -} - -void gameport_stop_polling(struct gameport *gameport) -{ - spin_lock(&gameport->timer_lock); - - if (!--gameport->poll_cnt) - del_timer(&gameport->poll_timer); - - spin_unlock(&gameport->timer_lock); -} - -static void gameport_run_poll_handler(unsigned long d) -{ - struct gameport *gameport = (struct gameport *)d; - - gameport->poll_handler(gameport); - if (gameport->poll_cnt) - mod_timer(&gameport->poll_timer, jiffies + msecs_to_jiffies(gameport->poll_interval)); -} /* * Basic gameport -> driver core mappings @@ -498,14 +465,10 @@ 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; - - spin_lock_init(&gameport->timer_lock); - init_timer(&gameport->poll_timer); - gameport->poll_timer.function = gameport_run_poll_handler; - gameport->poll_timer.data = (unsigned long)gameport; } /* @@ -734,9 +697,6 @@ void gameport_close(struct gameport *gameport) { - del_timer_sync(&gameport->poll_timer); - gameport->poll_handler = NULL; - gameport->poll_interval = 0; gameport_set_drv(gameport, NULL); if (gameport->close) gameport->close(gameport); diff -u b/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c --- b/drivers/input/joystick/a3d.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/joystick/a3d.c 2005-02-22 18:34:49 -08:00 @@ -45,6 +45,7 @@ #define A3D_MAX_STROBE 60 /* 40 us */ #define A3D_DELAY_READ 3 /* 3 ms */ #define A3D_MAX_LENGTH 40 /* 40*3 bits */ +#define A3D_REFRESH_TIME HZ/50 /* 20 ms */ #define A3D_MODE_A3D 1 /* Assassin 3D */ #define A3D_MODE_PAN 2 /* Panther */ @@ -58,10 +59,12 @@ struct gameport *gameport; struct gameport *adc; struct input_dev dev; + struct timer_list timer; int axes[4]; int buttons; int mode; int length; + int used; int reads; int bads; char phys[32]; @@ -175,20 +178,19 @@ /* - * a3d_poll() reads and analyzes A3D joystick data. + * a3d_timer() reads and analyzes A3D joystick data. */ -static void a3d_poll(struct gameport *gameport) +static void a3d_timer(unsigned long private) { - struct a3d *a3d = gameport_get_drvdata(gameport); + 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)) - a3d->bads++; - else - a3d_read(a3d, data); + if (a3d_read_packet(a3d->gameport, a3d->length, data) != a3d->length + || data[0] != a3d->mode || a3d_csum(data, a3d->length)) + a3d->bads++; else a3d_read(a3d, data); + mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME); } /* @@ -216,11 +218,10 @@ static int a3d_adc_open(struct gameport *gameport, int mode) { struct a3d *a3d = gameport->port_data; - if (mode != GAMEPORT_MODE_COOKED) return -1; - - gameport_start_polling(a3d->gameport); + if (!a3d->used++) + mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME); return 0; } @@ -232,7 +233,8 @@ { struct a3d *a3d = gameport->port_data; - gameport_stop_polling(a3d->gameport); + if (!--a3d->used) + del_timer(&a3d->timer); } /* @@ -243,7 +245,8 @@ { struct a3d *a3d = dev->private; - gameport_start_polling(a3d->gameport); + if (!a3d->used++) + mod_timer(&a3d->timer, jiffies + A3D_REFRESH_TIME); return 0; } @@ -255,7 +258,8 @@ { struct a3d *a3d = dev->private; - gameport_stop_polling(a3d->gameport); + if (!--a3d->used) + del_timer(&a3d->timer); } /* @@ -274,6 +278,9 @@ return -ENOMEM; a3d->gameport = gameport; + init_timer(&a3d->timer); + a3d->timer.data = (long) a3d; + a3d->timer.function = a3d_timer; gameport_set_drvdata(gameport, a3d); @@ -297,9 +304,6 @@ goto fail2; } - gameport_set_poll_handler(gameport, a3d_poll); - gameport_set_poll_interval(gameport, 20); - sprintf(a3d->phys, "%s/input0", gameport->phys); if (a3d->mode == A3D_MODE_PXL) { diff -u b/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c --- b/drivers/input/joystick/adi.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/joystick/adi.c 2005-02-22 18:34:49 -08:00 @@ -49,6 +49,7 @@ #define ADI_MAX_START 200 /* Trigger to packet timeout [200us] */ #define ADI_MAX_STROBE 40 /* Single bit timeout [40us] */ +#define ADI_REFRESH_TIME HZ/50 /* How often to poll the joystick [20 ms] */ #define ADI_INIT_DELAY 10 /* Delay after init packet [10ms] */ #define ADI_DATA_DELAY 4 /* Delay after data packet [4ms] */ @@ -128,9 +129,11 @@ struct adi_port { struct gameport *gameport; + struct timer_list timer; struct adi adi[2]; int bad; int reads; + int used; }; /* @@ -274,15 +277,15 @@ } /* - * adi_poll() repeatedly polls the Logitech joysticks. + * adi_timer() repeatedly polls the Logitech joysticks. */ -static void adi_poll(struct gameport *gameport) +static void adi_timer(unsigned long data) { - struct adi_port *port = gameport_get_drvdata(gameport); - + struct adi_port *port = (void *) data; port->bad -= adi_read(port); port->reads++; + mod_timer(&port->timer, jiffies + ADI_REFRESH_TIME); } /* @@ -292,8 +295,8 @@ static int adi_open(struct input_dev *dev) { struct adi_port *port = dev->private; - - gameport_start_polling(port->gameport); + if (!port->used++) + mod_timer(&port->timer, jiffies + ADI_REFRESH_TIME); return 0; } @@ -304,8 +307,8 @@ static void adi_close(struct input_dev *dev) { struct adi_port *port = dev->private; - - gameport_stop_polling(port->gameport); + if (!--port->used) + del_timer(&port->timer); } /* @@ -472,6 +475,9 @@ return -ENOMEM; port->gameport = gameport; + init_timer(&port->timer); + port->timer.data = (long) port; + port->timer.function = adi_timer; gameport_set_drvdata(gameport, port); @@ -498,9 +504,6 @@ return -ENODEV; } - gameport_set_poll_handler(gameport, adi_poll); - gameport_set_poll_interval(gameport, 20); - msleep(ADI_INIT_DELAY); if (adi_read(port)) { msleep(ADI_DATA_DELAY); diff -u b/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c --- b/drivers/input/joystick/analog.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/joystick/analog.c 2005-02-22 18:34:50 -08:00 @@ -90,6 +90,7 @@ #define ANALOG_MAX_TIME 3 /* 3 ms */ #define ANALOG_LOOP_TIME 2000 /* 2 * loop */ +#define ANALOG_REFRESH_TIME HZ/100 /* 10 ms */ #define ANALOG_SAITEK_DELAY 200 /* 200 us */ #define ANALOG_SAITEK_TIME 2000 /* 2000 us */ #define ANALOG_AXIS_TIME 2 /* 2 * refresh */ @@ -120,6 +121,7 @@ struct analog_port { struct gameport *gameport; + struct timer_list timer; struct analog analog[2]; unsigned char mask; char saitek; @@ -132,6 +134,7 @@ int axes[4]; int buttons; int initial[4]; + int used; int axtime; }; @@ -304,12 +307,12 @@ } /* - * analog_poll() repeatedly polls the Analog joysticks. + * analog_timer() repeatedly polls the Analog joysticks. */ -static void analog_poll(struct gameport *gameport) +static void analog_timer(unsigned long data) { - struct analog_port *port = gameport_get_drvdata(gameport); + struct analog_port *port = (void *) data; int i; char saitek = !!(port->analog[0].mask & ANALOG_SAITEK); @@ -335,6 +338,8 @@ for (i = 0; i < 2; i++) if (port->analog[i].mask) analog_decode(port->analog + i, port->axes, port->initial, port->buttons); + + mod_timer(&port->timer, jiffies + ANALOG_REFRESH_TIME); } /* @@ -344,8 +349,8 @@ static int analog_open(struct input_dev *dev) { struct analog_port *port = dev->private; - - gameport_start_polling(port->gameport); + if (!port->used++) + mod_timer(&port->timer, jiffies + ANALOG_REFRESH_TIME); return 0; } @@ -356,8 +361,8 @@ static void analog_close(struct input_dev *dev) { struct analog_port *port = dev->private; - - gameport_stop_polling(port->gameport); + if (!--port->used) + del_timer(&port->timer); } /* @@ -589,6 +594,9 @@ int i, t, u, v; port->gameport = gameport; + init_timer(&port->timer); + port->timer.data = (long) port; + port->timer.function = analog_timer; gameport_set_drvdata(gameport, port); @@ -670,9 +678,6 @@ return err; } - gameport_set_poll_handler(gameport, analog_poll); - gameport_set_poll_interval(gameport, 10); - for (i = 0; i < 2; i++) if (port->analog[i].mask) analog_init_device(port, port->analog + i, i); diff -u b/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c --- b/drivers/input/joystick/cobra.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/joystick/cobra.c 2005-02-22 18:34:49 -08:00 @@ -42,6 +42,7 @@ MODULE_LICENSE("GPL"); #define COBRA_MAX_STROBE 45 /* 45 us max wait for first strobe */ +#define COBRA_REFRESH_TIME HZ/50 /* 20 ms between reads */ #define COBRA_LENGTH 36 static char* cobra_name = "Creative Labs Blaster GamePad Cobra"; @@ -50,7 +51,9 @@ struct cobra { struct gameport *gameport; + struct timer_list timer; struct input_dev dev[2]; + int used; int reads; int bads; unsigned char exists; @@ -111,19 +114,18 @@ return ret; } -static void cobra_poll(struct gameport *gameport) +static void cobra_timer(unsigned long private) { - struct cobra *cobra = gameport_get_drvdata(gameport); + struct cobra *cobra = (void *) private; struct input_dev *dev; unsigned int data[2]; int i, j, r; cobra->reads++; - if ((r = cobra_read_packet(gameport, data)) != cobra->exists) { + if ((r = cobra_read_packet(cobra->gameport, data)) != cobra->exists) cobra->bads++; - return; - } + else for (i = 0; i < 2; i++) if (cobra->exists & r & (1 << i)) { @@ -139,21 +141,23 @@ input_sync(dev); } + + mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME); } static int cobra_open(struct input_dev *dev) { struct cobra *cobra = dev->private; - - gameport_start_polling(cobra->gameport); + if (!cobra->used++) + mod_timer(&cobra->timer, jiffies + COBRA_REFRESH_TIME); return 0; } static void cobra_close(struct input_dev *dev) { struct cobra *cobra = dev->private; - - gameport_stop_polling(cobra->gameport); + if (!--cobra->used) + del_timer(&cobra->timer); } static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) @@ -167,6 +171,9 @@ return -ENOMEM; cobra->gameport = gameport; + init_timer(&cobra->timer); + cobra->timer.data = (long) cobra; + cobra->timer.function = cobra_timer; gameport_set_drvdata(gameport, cobra); @@ -189,7 +196,4 @@ } - gameport_set_poll_handler(gameport, cobra_poll); - gameport_set_poll_interval(gameport, 20); - for (i = 0; i < 2; i++) if ((cobra->exists >> i) & 1) { diff -u b/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c --- b/drivers/input/joystick/gf2k.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/joystick/gf2k.c 2005-02-22 18:34:49 -08:00 @@ -46,6 +46,7 @@ #define GF2K_STROBE 40 /* The time we wait for the first bit [40 us] */ #define GF2K_TIMEOUT 4 /* Wait for everything to settle [4 ms] */ #define GF2K_LENGTH 80 /* Max number of triplets in a packet */ +#define GF2K_REFRESH HZ/50 /* Time between joystick polls [20 ms] */ /* * Genius joystick ids ... @@ -81,9 +82,11 @@ struct gf2k { struct gameport *gameport; + struct timer_list timer; struct input_dev dev; int reads; int bads; + int used; unsigned char id; unsigned char length; char phys[32]; @@ -201,35 +204,36 @@ } /* - * gf2k_poll() reads and analyzes Genius joystick data. + * gf2k_timer() reads and analyzes Genius joystick data. */ -static void gf2k_poll(struct gameport *gameport) +static void gf2k_timer(unsigned long private) { - struct gf2k *gf2k = gameport_get_drvdata(gameport); + struct gf2k *gf2k = (void *) private; unsigned char data[GF2K_LENGTH]; gf2k->reads++; - if (gf2k_read_packet(gf2k->gameport, gf2k_length[gf2k->id], data) < gf2k_length[gf2k->id]) + if (gf2k_read_packet(gf2k->gameport, gf2k_length[gf2k->id], data) < gf2k_length[gf2k->id]) { gf2k->bads++; - else - gf2k_read(gf2k, data); + } else gf2k_read(gf2k, data); + + mod_timer(&gf2k->timer, jiffies + GF2K_REFRESH); } static int gf2k_open(struct input_dev *dev) { struct gf2k *gf2k = dev->private; - - gameport_start_polling(gf2k->gameport); + if (!gf2k->used++) + mod_timer(&gf2k->timer, jiffies + GF2K_REFRESH); return 0; } static void gf2k_close(struct input_dev *dev) { struct gf2k *gf2k = dev->private; - - gameport_stop_polling(gf2k->gameport); + if (!--gf2k->used) + del_timer(&gf2k->timer); } /* @@ -246,6 +250,9 @@ return -ENOMEM; gf2k->gameport = gameport; + init_timer(&gf2k->timer); + gf2k->timer.data = (long) gf2k; + gf2k->timer.function = gf2k_timer; gameport_set_drvdata(gameport, gf2k); @@ -288,9 +295,6 @@ goto fail2; } - gameport_set_poll_handler(gameport, gf2k_poll); - gameport_set_poll_interval(gameport, 20); - sprintf(gf2k->phys, "%s/input0", gameport->phys); gf2k->length = gf2k_lens[gf2k->id]; diff -u b/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c --- b/drivers/input/joystick/grip.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/joystick/grip.c 2005-02-22 18:34:49 -08:00 @@ -53,10 +53,14 @@ #define GRIP_MAX_CHUNKS_XT 10 #define GRIP_MAX_BITS_XT 30 +#define GRIP_REFRESH_TIME HZ/50 /* 20 ms */ + struct grip { struct gameport *gameport; + struct timer_list timer; struct input_dev dev[2]; unsigned char mode[2]; + int used; int reads; int bads; char phys[2][32]; @@ -181,9 +185,9 @@ * grip_timer() repeatedly polls the joysticks and generates events. */ -static void grip_poll(struct gameport *gameport) +static void grip_timer(unsigned long private) { - struct grip *grip = gameport_get_drvdata(gameport); + struct grip *grip = (void*) private; unsigned int data[GRIP_LENGTH_XT]; struct input_dev *dev; int i, j; @@ -277,21 +281,23 @@ input_sync(dev); } + + mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME); } static int grip_open(struct input_dev *dev) { struct grip *grip = dev->private; - - gameport_start_polling(grip->gameport); + if (!grip->used++) + mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME); return 0; } static void grip_close(struct input_dev *dev) { struct grip *grip = dev->private; - - gameport_stop_polling(grip->gameport); + if (!--grip->used) + del_timer(&grip->timer); } static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) @@ -305,6 +311,9 @@ return -ENOMEM; grip->gameport = gameport; + init_timer(&grip->timer); + grip->timer.data = (long) grip; + grip->timer.function = grip_timer; gameport_set_drvdata(gameport, grip); @@ -337,7 +346,4 @@ } - gameport_set_poll_handler(gameport, grip_poll); - gameport_set_poll_interval(gameport, 20); - for (i = 0; i < 2; i++) if (grip->mode[i]) { diff -u b/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c --- b/drivers/input/joystick/grip_mp.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/joystick/grip_mp.c 2005-02-22 18:34:50 -08:00 @@ -38,9 +38,11 @@ struct grip_mp { struct gameport *gameport; + struct timer_list timer; struct input_dev dev[4]; int mode[4]; int registered[4]; + int used; int reads; int bads; @@ -79,6 +81,7 @@ */ #define GRIP_INIT_DELAY 2000 /* 2 ms */ +#define GRIP_REFRESH_TIME HZ/50 /* 20 ms */ #define GRIP_MODE_NONE 0 #define GRIP_MODE_RESET 1 @@ -523,9 +526,8 @@ * Get the multiport state. */ -static void grip_poll(struct gameport *gameport) +static void get_and_report_mp_state(struct grip_mp *grip) { - struct grip_mp *grip = gameport_get_drvdata(gameport); int i, npkts, flags; for (npkts = 0; npkts < 4; npkts++) { @@ -552,7 +554,8 @@ { struct grip_mp *grip = dev->private; - gameport_start_polling(grip->gameport); + if (!grip->used++) + mod_timer(&grip->timer, jiffies + GRIP_REFRESH_TIME); return 0; } @@ -564,7 +567,8 @@ { struct grip_mp *grip = dev->private; - gameport_start_polling(grip->gameport); + if (!--grip->used) + del_timer(&grip->timer); } /* @@ -602,6 +606,18 @@ grip_name[grip->mode[slot]], slot); } +/* + * Repeatedly polls the multiport and generates events. + */ + +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 int grip_connect(struct gameport *gameport, struct gameport_driver *drv) { struct grip_mp *grip; @@ -611,6 +627,9 @@ return -ENOMEM; grip->gameport = gameport; + init_timer(&grip->timer); + grip->timer.data = (long) grip; + grip->timer.function = grip_timer; gameport_set_drvdata(gameport, grip); @@ -618,9 +637,6 @@ if (err) goto fail1; - gameport_set_poll_handler(gameport, grip_poll); - gameport_set_poll_interval(gameport, 20); - if (!multiport_init(grip)) { err = -ENODEV; goto fail2; diff -u b/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c --- b/drivers/input/joystick/guillemot.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/joystick/guillemot.c 2005-02-22 18:34:49 -08:00 @@ -45,6 +45,7 @@ #define GUILLEMOT_MAX_START 600 /* 600 us */ #define GUILLEMOT_MAX_STROBE 60 /* 60 us */ #define GUILLEMOT_MAX_LENGTH 17 /* 17 bytes */ +#define GUILLEMOT_REFRESH_TIME HZ/50 /* 20 ms */ static short guillemot_abs_pad[] = { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, -1 }; @@ -68,6 +69,8 @@ struct guillemot { struct gameport *gameport; struct input_dev dev; + struct timer_list timer; + int used; int bads; int reads; struct guillemot_type *type; @@ -117,12 +120,12 @@ } /* - * guillemot_poll() reads and analyzes Guillemot joystick data. + * guillemot_timer() reads and analyzes Guillemot joystick data. */ -static void guillemot_poll(struct gameport *gameport) +static void guillemot_timer(unsigned long private) { - struct guillemot *guillemot = gameport_get_drvdata(gameport); + struct guillemot *guillemot = (struct guillemot *) private; struct input_dev *dev = &guillemot->dev; u8 data[GUILLEMOT_MAX_LENGTH]; int i; @@ -147,6 +150,8 @@ } input_sync(dev); + + mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME); } /* @@ -157,7 +162,8 @@ { struct guillemot *guillemot = dev->private; - gameport_start_polling(guillemot->gameport); + if (!guillemot->used++) + mod_timer(&guillemot->timer, jiffies + GUILLEMOT_REFRESH_TIME); return 0; } @@ -169,7 +175,8 @@ { struct guillemot *guillemot = dev->private; - gameport_stop_polling(guillemot->gameport); + if (!--guillemot->used) + del_timer(&guillemot->timer); } /* @@ -187,6 +194,9 @@ return -ENOMEM; guillemot->gameport = gameport; + init_timer(&guillemot->timer); + guillemot->timer.data = (long) guillemot; + guillemot->timer.function = guillemot_timer; gameport_set_drvdata(gameport, guillemot); @@ -212,9 +222,6 @@ goto fail2; } - gameport_set_poll_handler(gameport, guillemot_poll); - gameport_set_poll_interval(gameport, 20); - sprintf(guillemot->phys, "%s/input0", gameport->phys); guillemot->type = guillemot_type + i; diff -u b/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c --- b/drivers/input/joystick/interact.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/joystick/interact.c 2005-02-22 18:34:49 -08:00 @@ -48,6 +48,7 @@ #define INTERACT_MAX_START 400 /* 400 us */ #define INTERACT_MAX_STROBE 40 /* 40 us */ #define INTERACT_MAX_LENGTH 32 /* 32 bits */ +#define INTERACT_REFRESH_TIME HZ/50 /* 20 ms */ #define INTERACT_TYPE_HHFX 0 /* HammerHead/FX */ #define INTERACT_TYPE_PP8D 1 /* ProPad 8 */ @@ -55,6 +56,8 @@ struct interact { struct gameport *gameport; struct input_dev dev; + struct timer_list timer; + int used; int bads; int reads; unsigned char type; @@ -124,12 +127,12 @@ } /* - * interact_poll() reads and analyzes InterAct joystick data. + * interact_timer() reads and analyzes InterAct joystick data. */ -static void interact_poll(struct gameport *gameport) +static void interact_timer(unsigned long private) { - struct interact *interact = gameport_get_drvdata(gameport); + struct interact *interact = (struct interact *) private; struct input_dev *dev = &interact->dev; u32 data[3]; int i; @@ -176,6 +179,9 @@ } input_sync(dev); + + mod_timer(&interact->timer, jiffies + INTERACT_REFRESH_TIME); + } /* @@ -186,7 +192,8 @@ { struct interact *interact = dev->private; - gameport_start_polling(interact->gameport); + if (!interact->used++) + mod_timer(&interact->timer, jiffies + INTERACT_REFRESH_TIME); return 0; } @@ -198,7 +205,8 @@ { struct interact *interact = dev->private; - gameport_stop_polling(interact->gameport); + if (!--interact->used) + del_timer(&interact->timer); } /* @@ -216,6 +224,9 @@ return -ENOMEM; interact->gameport = gameport; + init_timer(&interact->timer); + interact->timer.data = (long) interact; + interact->timer.function = interact_timer; gameport_set_drvdata(gameport, interact); @@ -241,9 +252,6 @@ goto fail2; } - gameport_set_poll_handler(gameport, interact_poll); - gameport_set_poll_interval(gameport, 20); - sprintf(interact->phys, "%s/input0", gameport->phys); interact->type = i; diff -u b/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c --- b/drivers/input/joystick/tmdc.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/joystick/tmdc.c 2005-02-22 18:34:49 -08:00 @@ -48,6 +48,7 @@ #define TMDC_MAX_START 400 /* 400 us */ #define TMDC_MAX_STROBE 45 /* 45 us */ #define TMDC_MAX_LENGTH 13 +#define TMDC_REFRESH_TIME HZ/50 /* 20 ms */ #define TMDC_MODE_M3DI 1 #define TMDC_MODE_3DRP 3 @@ -93,6 +94,7 @@ struct tmdc { struct gameport *gameport; + struct timer_list timer; struct input_dev dev[2]; char name[2][64]; char phys[2][32]; @@ -102,6 +104,7 @@ unsigned char absc[2]; unsigned char btnc[2][4]; unsigned char btno[2][4]; + int used; int reads; int bads; unsigned char exists; @@ -157,13 +160,13 @@ } /* - * tmdc_poll() reads and analyzes ThrustMaster joystick data. + * tmdc_read() reads and analyzes ThrustMaster joystick data. */ -static void tmdc_poll(struct gameport *gameport) +static void tmdc_timer(unsigned long private) { unsigned char data[2][TMDC_MAX_LENGTH]; - struct tmdc *tmdc = gameport_get_drvdata(gameport); + struct tmdc *tmdc = (void *) private; struct input_dev *dev; unsigned char r, bad = 0; int i, j, k, l; @@ -218,21 +221,23 @@ } tmdc->bads += bad; + + mod_timer(&tmdc->timer, jiffies + TMDC_REFRESH_TIME); } static int tmdc_open(struct input_dev *dev) { struct tmdc *tmdc = dev->private; - - gameport_start_polling(tmdc->gameport); + if (!tmdc->used++) + mod_timer(&tmdc->timer, jiffies + TMDC_REFRESH_TIME); return 0; } static void tmdc_close(struct input_dev *dev) { struct tmdc *tmdc = dev->private; - - gameport_stop_polling(tmdc->gameport); + if (!--tmdc->used) + del_timer(&tmdc->timer); } /* @@ -266,6 +271,9 @@ return -ENOMEM; tmdc->gameport = gameport; + init_timer(&tmdc->timer); + tmdc->timer.data = (long) tmdc; + tmdc->timer.function = tmdc_timer; gameport_set_drvdata(gameport, tmdc); @@ -279,7 +287,4 @@ } - gameport_set_poll_handler(gameport, tmdc_poll); - gameport_set_poll_interval(gameport, 20); - for (j = 0; j < 2; j++) if (tmdc->exists & (1 << j)) { diff -u b/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c --- b/drivers/input/mouse/alps.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/mouse/alps.c 2005-02-22 18:34:49 -08:00 @@ -212,10 +212,9 @@ return PSMOUSE_GOOD_DATA; } -static int alps_get_model(struct psmouse *psmouse, int *version) +static int alps_get_model(struct psmouse *psmouse) { struct ps2dev *ps2dev = &psmouse->ps2dev; - unsigned char rates[] = { 0, 10, 20, 40, 60, 80, 100, 200 }; unsigned char param[4]; int i; @@ -253,9 +252,6 @@ dbg("E7 report: %2.2x %2.2x %2.2x", param[0], param[1], param[2]); - for (i = 0; i < ARRAY_SIZE(rates) && param[2] != rates[i]; i++); - *version = (param[0] << 8) | (i << 4) | (param[1] & 0x0f); - for (i = 0; i < ARRAY_SIZE(alps_model_data); i++) if (!memcmp(param, alps_model_data[i].signature, sizeof(alps_model_data[i].signature))) return alps_model_data[i].model; @@ -353,9 +349,8 @@ { struct alps_data *priv = psmouse->private; unsigned char param[4]; - int version; - if ((priv->model = alps_get_model(psmouse, &version)) < 0) + if ((priv->model = alps_get_model(psmouse)) < 0) return -1; if (priv->model == ALPS_MODEL_DUALPOINT && alps_passthrough_mode(psmouse, 1)) @@ -388,14 +383,13 @@ { struct alps_data *priv; unsigned char param[4]; - int version; psmouse->private = priv = kmalloc(sizeof(struct alps_data), GFP_KERNEL); if (!priv) goto init_fail; memset(priv, 0, sizeof(struct alps_data)); - if ((priv->model = alps_get_model(psmouse, &version)) < 0) + if ((priv->model = alps_get_model(psmouse)) < 0) goto init_fail; printk(KERN_INFO "ALPS Touchpad (%s) detected\n", @@ -453,15 +447,12 @@ int alps_detect(struct psmouse *psmouse, int set_properties) { - int version; - - if (alps_get_model(psmouse, &version) < 0) + if (alps_get_model(psmouse) < 0) return -1; if (set_properties) { psmouse->vendor = "ALPS"; psmouse->name = "TouchPad"; - psmouse->model = version; } return 0; } diff -u b/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c --- b/drivers/input/mouse/psmouse-base.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/mouse/psmouse-base.c 2005-02-22 18:34:49 -08:00 @@ -423,7 +423,7 @@ * upsets the thinkingmouse). */ - if (max_proto > PSMOUSE_IMEX && thinking_detect(psmouse, set_properties) == 0) + if (max_proto > PSMOUSE_PS2 && thinking_detect(psmouse, set_properties) == 0) return PSMOUSE_THINKPS; /* reverted: --- b/drivers/input/mouse/psmouse.h 2005-02-22 18:43:15 -08:00 +++ a/drivers/input/mouse/psmouse.h 2005-02-22 18:43:15 -08:00 @@ -44,7 +44,7 @@ unsigned char pktcnt; unsigned char pktsize; unsigned char type; + unsigned char model; - unsigned int model; unsigned long last; unsigned long out_of_sync; enum psmouse_state state; diff -u b/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c --- b/drivers/input/serio/parkbd.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/serio/parkbd.c 2005-02-22 18:34:49 -08:00 @@ -16,23 +16,23 @@ * * Parallel port Keyboard port * - * +5V --------------------- +5V (4) + * +5V --------------------- +5V * * ______ * +5V -------|______|--. * | - * ACK (10) ------------| - * |--- KBD CLOCK (5) - * STROBE (1) ---|<|----' + * ACK -----------------| + * |--- KBD CLOCK + * STROBE -------|<|----' * * ______ * +5V -------|______|--. * | - * BUSY (11) -----------| - * |--- KBD DATA (1) - * AUTOFD (14) --|<|----' + * BUSY ----------------| + * |--- KBD DATA + * AUTOFD -------|<|----' * - * GND (18-25) ------------- GND (3) + * GND --------------------- GND * * The diodes can be fairly any type, and the resistors should be somewhere * around 5 kOhm, but the adapter will likely work without the resistors, diff -u b/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c --- b/drivers/input/touchscreen/elo.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/touchscreen/elo.c 2005-02-22 18:34:50 -08:00 @@ -80,7 +80,7 @@ input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]); input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]); input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]); - input_report_key(dev, BTN_TOUCH, elo->data[2] & 3); + input_report_key(dev, BTN_TOUCH, elo->data[8] || elo->data[7]); input_sync(dev); } elo->idx = 0; @@ -129,7 +129,7 @@ case 5: if ((data & 0xf0) == 0) { input_report_abs(dev, ABS_PRESSURE, elo->data[5]); - input_report_key(dev, BTN_TOUCH, elo->data[5]); + input_report_key(dev, BTN_TOUCH, !!elo->data[5]); } input_sync(dev); elo->idx = 0; diff -u b/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c --- b/drivers/input/touchscreen/mk712.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/input/touchscreen/mk712.c 2005-02-22 18:34:50 -08:00 @@ -161,7 +161,7 @@ static struct input_dev mk712_dev = { .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, - .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, + .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_TOUCH) }, .absbit = { BIT(ABS_X) | BIT(ABS_Y) }, .open = mk712_open, .close = mk712_close, reverted: --- b/drivers/usb/input/ati_remote.c 2005-02-22 18:43:15 -08:00 +++ a/drivers/usb/input/ati_remote.c 2005-02-22 18:43:15 -08:00 @@ -174,6 +174,7 @@ dma_addr_t outbuf_dma; int open; /* open counter */ + int present; /* device plugged in? */ unsigned char old_data[2]; /* Detect duplicate events */ unsigned long old_jiffies; @@ -251,8 +252,8 @@ {KIND_FILTERED, 0xdd, 0x18, EV_KEY, KEY_KPENTER, 1}, /* "check" */ {KIND_FILTERED, 0xdb, 0x16, EV_KEY, KEY_MENU, 1}, /* "menu" */ {KIND_FILTERED, 0xc7, 0x02, EV_KEY, KEY_POWER, 1}, /* Power */ + {KIND_FILTERED, 0xc8, 0x03, EV_KEY, KEY_PROG1, 1}, /* TV */ + {KIND_FILTERED, 0xc9, 0x04, EV_KEY, KEY_PROG2, 1}, /* DVD */ - {KIND_FILTERED, 0xc8, 0x03, EV_KEY, KEY_TV, 1}, /* TV */ - {KIND_FILTERED, 0xc9, 0x04, EV_KEY, KEY_DVD, 1}, /* DVD */ {KIND_FILTERED, 0xca, 0x05, EV_KEY, KEY_WWW, 1}, /* WEB */ {KIND_FILTERED, 0xcb, 0x06, EV_KEY, KEY_BOOKMARKS, 1}, /* "book" */ {KIND_FILTERED, 0xcc, 0x07, EV_KEY, KEY_EDIT, 1}, /* "hand" */ @@ -262,14 +263,14 @@ {KIND_FILTERED, 0xe4, 0x1f, EV_KEY, KEY_RIGHT, 1}, /* right */ {KIND_FILTERED, 0xe7, 0x22, EV_KEY, KEY_DOWN, 1}, /* down */ {KIND_FILTERED, 0xdf, 0x1a, EV_KEY, KEY_UP, 1}, /* up */ + {KIND_FILTERED, 0xe3, 0x1e, EV_KEY, KEY_ENTER, 1}, /* "OK" */ - {KIND_FILTERED, 0xe3, 0x1e, EV_KEY, KEY_OK, 1}, /* "OK" */ {KIND_FILTERED, 0xce, 0x09, EV_KEY, KEY_VOLUMEDOWN, 1}, /* VOL + */ {KIND_FILTERED, 0xcd, 0x08, EV_KEY, KEY_VOLUMEUP, 1}, /* VOL - */ {KIND_FILTERED, 0xcf, 0x0a, EV_KEY, KEY_MUTE, 1}, /* MUTE */ + {KIND_FILTERED, 0xd1, 0x0c, EV_KEY, KEY_CHANNELUP, 1}, /* CH + */ + {KIND_FILTERED, 0xd0, 0x0b, EV_KEY, KEY_CHANNELDOWN, 1},/* CH - */ - {KIND_FILTERED, 0xd0, 0x0b, EV_KEY, KEY_CHANNELUP, 1}, /* CH + */ - {KIND_FILTERED, 0xd1, 0x0c, EV_KEY, KEY_CHANNELDOWN, 1},/* CH - */ {KIND_FILTERED, 0xec, 0x27, EV_KEY, KEY_RECORD, 1}, /* ( o) red */ + {KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_PLAYCD, 1}, /* ( >) */ - {KIND_FILTERED, 0xea, 0x25, EV_KEY, KEY_PLAY, 1}, /* ( >) */ {KIND_FILTERED, 0xe9, 0x24, EV_KEY, KEY_REWIND, 1}, /* (<<) */ {KIND_FILTERED, 0xeb, 0x26, EV_KEY, KEY_FORWARD, 1}, /* (>>) */ {KIND_FILTERED, 0xed, 0x28, EV_KEY, KEY_STOP, 1}, /* ([]) */ @@ -355,8 +356,19 @@ { struct ati_remote *ati_remote = inputdev->private; + if (ati_remote == NULL) { + err("ati_remote: %s: object is NULL!\n", __FUNCTION__); + return; + } + + if (ati_remote->open <= 0) + dev_dbg(&ati_remote->interface->dev, "%s: Not open.\n", __FUNCTION__); + else + --ati_remote->open; + + /* If still present, disconnect will call delete. */ + if (!ati_remote->present && !ati_remote->open) + ati_remote_delete(ati_remote); - if (!--ati_remote->open) - usb_kill_urb(ati_remote->irq_urb); } /* @@ -800,6 +812,7 @@ ati_remote->name, path); usb_set_intfdata(interface, ati_remote); + ati_remote->present = 1; error: if (buf) @@ -827,7 +840,12 @@ return; } + /* Mark device as unplugged */ + ati_remote->present = 0; + + /* If device is still open, ati_remote_close will call delete. */ + if (!ati_remote->open) + ati_remote_delete(ati_remote); - ati_remote_delete(ati_remote); up(&disconnect_sem); } diff -u b/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c --- b/drivers/usb/input/hid-core.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/usb/input/hid-core.c 2005-02-22 18:34:49 -08:00 @@ -1007,21 +1007,63 @@ return 0; } +int hid_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field) +{ + struct hid_report_enum *report_enum = hid->report_enum + HID_OUTPUT_REPORT; + struct list_head *list = report_enum->report_list.next; + int i, j; + + while (list != &report_enum->report_list) { + struct hid_report *report = (struct hid_report *) list; + list = list->next; + for (i = 0; i < report->maxfield; i++) { + *field = report->field[i]; + for (j = 0; j < (*field)->maxusage; j++) + if ((*field)->usage[j].type == type && (*field)->usage[j].code == code) + return j; + } + } + return -1; +} + /* * Find a report with a specified HID usage. */ -struct hid_report *hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, int type) +int hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, struct hid_report **report, int type) { - struct hid_report *report; - int i; + struct hid_report_enum *report_enum = hid->report_enum + type; + struct list_head *list = report_enum->report_list.next; + int i, j; + + while (list != &report_enum->report_list) { + *report = (struct hid_report *) list; + list = list->next; + for (i = 0; i < (*report)->maxfield; i++) { + struct hid_field *field = (*report)->field[i]; + for (j = 0; j < field->maxusage; j++) + if (field->logical == wanted_usage) + return j; + } + } + return -1; +} + +#if 0 +static int hid_find_field_in_report(struct hid_report *report, __u32 wanted_usage, struct hid_field **field) +{ + int i, j; - list_for_each_entry(report, &hid->report_enum[type].report_list, list) - for (i = 0; i < report->maxfield; i++) - if (report->field[i]->logical == wanted_usage) - return report; - return NULL; + for (i = 0; i < report->maxfield; i++) { + *field = report->field[i]; + for (j = 0; j < (*field)->maxusage; j++) + if ((*field)->usage[j].hid == wanted_usage) + return j; + } + + return -1; } +#endif static int hid_submit_out(struct hid_device *hid) { @@ -1294,19 +1336,47 @@ void hid_init_reports(struct hid_device *hid) { + struct hid_report_enum *report_enum; struct hid_report *report; - int err, ret; + struct list_head *list; + int err, ret, size; + + /* + * The Set_Idle request is supposed to affect only the + * "Interrupt In" pipe. Unfortunately, buggy devices such as + * the BTC keyboard (ID 046e:5303) the request also affects + * Get_Report requests on the control pipe. In the worst + * case, if the device was put on idle for an indefinite + * amount of time (as we do below) and there are no input + * events to report, the Get_Report requests will just hang + * until we get a USB timeout. To avoid this, we temporarily + * establish a minimal idle time of 1ms. This shouldn't hurt + * bugfree devices and will cause a worst-case extra delay of + * 1ms for buggy ones. + */ + usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0), + HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (1 << 8), + hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); - list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) { - int size = ((report->size - 1) >> 3) + 1 + hid->report_enum[HID_INPUT_REPORT].numbered; + report_enum = hid->report_enum + HID_INPUT_REPORT; + list = report_enum->report_list.next; + while (list != &report_enum->report_list) { + report = (struct hid_report *) list; + size = ((report->size - 1) >> 3) + 1 + report_enum->numbered; if (size > HID_BUFFER_SIZE) size = HID_BUFFER_SIZE; if (size > hid->urbin->transfer_buffer_length) hid->urbin->transfer_buffer_length = size; hid_submit_report(hid, report, USB_DIR_IN); + list = list->next; } - list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) + report_enum = hid->report_enum + HID_FEATURE_REPORT; + list = report_enum->report_list.next; + while (list != &report_enum->report_list) { + report = (struct hid_report *) list; hid_submit_report(hid, report, USB_DIR_IN); + list = list->next; + } err = 0; ret = hid_wait_io(hid); @@ -1322,9 +1392,15 @@ if (err) warn("timeout initializing reports\n"); - usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0), - HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, - hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); + report_enum = hid->report_enum + HID_INPUT_REPORT; + list = report_enum->report_list.next; + while (list != &report_enum->report_list) { + report = (struct hid_report *) list; + usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0), + HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, report->id, + hid->ifnum, NULL, 0, HZ * USB_CTRL_SET_TIMEOUT); + list = list->next; + } } #define USB_VENDOR_ID_WACOM 0x056a @@ -1429,9 +1505,6 @@ #define USB_VENDOR_ID_CHICONY 0x04f2 #define USB_DEVICE_ID_CHICONY_USBHUB_KB 0x0100 -#define USB_VENDOR_ID_BTC 0x046e -#define USB_DEVICE_ID_BTC_KEYBOARD 0x5303 - /* * Alphabetically sorted blacklist by quirk type. @@ -1509,7 +1582,6 @@ { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, - { USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_KEYBOARD, HID_QUIRK_NOGET}, { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_USBHUB_KB, HID_QUIRK_NOGET}, { USB_VENDOR_ID_TANGTOP, USB_DEVICE_ID_TANGTOP_USBPS2, HID_QUIRK_NOGET }, @@ -1753,7 +1825,7 @@ hid_free_device(hid); } -static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) +static int hid_probe (struct usb_interface *intf, const struct usb_device_id *id) { struct hid_device *hid; char path[64]; reverted: --- b/drivers/usb/input/hid-input.c 2005-02-22 18:43:15 -08:00 +++ a/drivers/usb/input/hid-input.c 2005-02-22 18:43:15 -08:00 @@ -483,26 +483,10 @@ } } -static int hid_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field) -{ - struct hid_report *report; - int i, j; - - list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) { - for (i = 0; i < report->maxfield; i++) { - *field = report->field[i]; - for (j = 0; j < (*field)->maxusage; j++) - if ((*field)->usage[j].type == type && (*field)->usage[j].code == code) - return j; - } - } - return -1; -} - static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { struct hid_device *hid = dev->private; + struct hid_field *field = NULL; - struct hid_field *field; int offset; if (type == EV_FF) @@ -543,7 +527,9 @@ int hidinput_connect(struct hid_device *hid) { struct usb_device *dev = hid->dev; + struct hid_report_enum *report_enum; struct hid_report *report; + struct list_head *list; struct hid_input *hidinput = NULL; int i, j, k; @@ -558,11 +544,16 @@ if (i == hid->maxcollection) return -1; + for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) { + report_enum = hid->report_enum + k; + list = report_enum->report_list.next; + while (list != &report_enum->report_list) { + report = (struct hid_report *) list; - for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) - list_for_each_entry(report, &hid->report_enum[k].report_list, list) { + if (!report->maxfield) { + list = list->next; - if (!report->maxfield) continue; + } if (!hidinput) { hidinput = kmalloc(sizeof(*hidinput), GFP_KERNEL); @@ -607,7 +598,10 @@ input_register_device(&hidinput->input); hidinput = NULL; } + + list = list->next; } + } /* This only gets called when we are a single-input (most of the * time). IOW, not a HID_QUIRK_MULTI_INPUT. The hid_ff_init() is @@ -625,7 +619,7 @@ struct list_head *lh, *next; struct hid_input *hidinput; + list_for_each_safe (lh, next, &hid->inputs) { - list_for_each_safe(lh, next, &hid->inputs) { hidinput = list_entry(lh, struct hid_input, list); input_unregister_device(&hidinput->input); list_del(&hidinput->list); reverted: --- b/drivers/usb/input/hid.h 2005-02-22 18:43:15 -08:00 +++ a/drivers/usb/input/hid.h 2005-02-22 18:43:15 -08:00 @@ -484,10 +484,11 @@ int hid_open(struct hid_device *); void hid_close(struct hid_device *); +int hid_find_field(struct hid_device *, unsigned int, unsigned int, struct hid_field **); int hid_set_field(struct hid_field *, unsigned, __s32); void hid_submit_report(struct hid_device *, struct hid_report *, unsigned char dir); void hid_init_reports(struct hid_device *hid); +int hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, struct hid_report **report, int type); -struct hid_report *hid_find_report_by_usage(struct hid_device *hid, __u32 wanted_usage, int type); int hid_wait_io(struct hid_device* hid); diff -u b/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c --- b/drivers/usb/input/hiddev.c 2005-02-22 18:43:15 -08:00 +++ b/drivers/usb/input/hiddev.c 2005-02-22 18:34:49 -08:00 @@ -124,6 +124,7 @@ int i, j; struct hid_report *report; struct hid_report_enum *report_enum; + struct list_head *list; struct hid_field *field; if (uref->report_type < HID_REPORT_TYPE_MIN || @@ -131,8 +132,9 @@ report_enum = hid->report_enum + (uref->report_type - HID_REPORT_TYPE_MIN); - - list_for_each_entry(report, &report_enum->report_list, list) + list = report_enum->report_list.next; + while (list != &report_enum->report_list) { + report = (struct hid_report *) list; for (i = 0; i < report->maxfield; i++) { field = report->field[i]; for (j = 0; j < field->maxusage; j++) { @@ -144,6 +146,8 @@ } } } + list = list->next; + } return NULL; } reverted: --- b/drivers/usb/input/pid.c 2005-02-22 18:43:15 -08:00 +++ a/drivers/usb/input/pid.c 2005-02-22 18:43:15 -08:00 @@ -114,28 +114,28 @@ struct hid_report* report; struct hid_ff_pid *pid = hid->ff_private; unsigned long flags; + unsigned wanted_report = HID_UP_PID | FF_PID_USAGE_BLOCK_FREE; /* PID Block Free Report */ int ret; if (!CHECK_OWNERSHIP(id, pid)) return -EACCES; /* Find report */ + ret = hid_find_report_by_usage(hid, wanted_report, &report, HID_OUTPUT_REPORT); + if(!ret) { - report = hid_find_report_by_usage(hid, - HID_UP_PID | FF_PID_USAGE_BLOCK_FREE, HID_OUTPUT_REPORT); - if (!report) { dev_err(&hid->dev->dev, "couldn't find report\n"); return ret; } /* Find field */ field = (struct hid_field *) kmalloc(sizeof(struct hid_field), GFP_KERNEL); + if(!field) { - if (!field) { dev_err(&hid->dev->dev, "couldn't allocate field\n"); return -ENOMEM; } ret = hid_set_field(field, ret, pid->effects[id].device_id); + if(!ret) { - if (ret) { dev_err(&hid->dev->dev, "couldn't set field\n"); return ret; } diff -u b/include/linux/gameport.h b/include/linux/gameport.h --- b/include/linux/gameport.h 2005-02-22 18:43:15 -08:00 +++ b/include/linux/gameport.h 2005-02-22 18:34:50 -08:00 @@ -30,12 +30,6 @@ int (*open)(struct gameport *, int); void (*close)(struct gameport *); - struct timer_list poll_timer; - unsigned int poll_interval; /* in msecs */ - spinlock_t timer_lock; - unsigned int poll_cnt; - void (*poll_handler)(struct gameport *); - struct gameport *parent, *child; struct gameport_driver *drv; @@ -184,15 +178,2 @@ -static inline void gameport_set_poll_handler(struct gameport *gameport, void (*handler)(struct gameport *)) -{ - gameport->poll_handler = handler; -} - -static inline void gameport_set_poll_interval(struct gameport *gameport, unsigned int msecs) -{ - gameport->poll_interval = msecs; -} - -void gameport_start_polling(struct gameport *gameport); -void gameport_stop_polling(struct gameport *gameport); - #endif reverted: --- b/include/linux/hiddev.h 2005-02-22 18:43:15 -08:00 +++ a/include/linux/hiddev.h 2005-02-22 18:43:15 -08:00 @@ -201,8 +201,8 @@ * ioctl(fd, HIDIOCGUSAGE, &uref); * } * } + * uref.report_id |= HID_REPORT_ID_NEXT; + * ret = ioctl(fd, HIDIOCGREPORTINFO, &uref); - * rinfo.report_id |= HID_REPORT_ID_NEXT; - * ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo); * } */