!Idrivers/parport/daisy.c
</chapter>
- <chapter id="viddev">
- <title>Video4Linux</title>
- !Edrivers/media/video/videodev.c
+ <chapter id="message_devices">
+ <title>Message-based devices</title>
+ <sect1><title>Fusion message devices</title>
+ !Edrivers/message/fusion/mptbase.c
+ !Idrivers/message/fusion/mptbase.c
+ !Edrivers/message/fusion/mptscsih.c
+ !Idrivers/message/fusion/mptscsih.c
+ !Idrivers/message/fusion/mptctl.c
+ !Idrivers/message/fusion/mptspi.c
+ !Idrivers/message/fusion/mptfc.c
+ !Idrivers/message/fusion/mptlan.c
+ </sect1>
+ <sect1><title>I2O message devices</title>
+ !Iinclude/linux/i2o.h
+ !Idrivers/message/i2o/core.h
+ !Edrivers/message/i2o/iop.c
+ !Idrivers/message/i2o/iop.c
+ !Idrivers/message/i2o/config-osm.c
+ !Edrivers/message/i2o/exec-osm.c
+ !Idrivers/message/i2o/exec-osm.c
+ !Idrivers/message/i2o/bus-osm.c
+ !Edrivers/message/i2o/device.c
+ !Idrivers/message/i2o/device.c
+ !Idrivers/message/i2o/driver.c
+ !Idrivers/message/i2o/pci.c
+ !Idrivers/message/i2o/i2o_block.c
+ !Idrivers/message/i2o/i2o_scsi.c
+ !Idrivers/message/i2o/i2o_proc.c
+ </sect1>
</chapter>
<chapter id="snddev">
-->
</sect1>
</chapter>
+
+ <chapter id="input_subsystem">
+ <title>Input Subsystem</title>
+!Iinclude/linux/input.h
+!Edrivers/input/input.c
+!Edrivers/input/ff-core.c
+!Edrivers/input/ff-memless.c
+ </chapter>
</book>
#include <linux/kthread.h>
#include <linux/sched.h> /* HZ */
#include <linux/mutex.h>
+ #include <linux/freezer.h>
/*#include <asm/io.h>*/
return 0;
}
-static struct bus_type gameport_bus = {
- .name = "gameport",
- .probe = gameport_driver_probe,
- .remove = gameport_driver_remove,
-};
-
static void gameport_add_driver(struct gameport_driver *drv)
{
int error;
return !gameport_drv->ignore;
}
+static struct bus_type gameport_bus = {
+ .name = "gameport",
+ .dev_attrs = gameport_device_attrs,
+ .drv_attrs = gameport_driver_attrs,
+ .match = gameport_bus_match,
+ .probe = gameport_driver_probe,
+ .remove = gameport_driver_remove,
+};
+
static void gameport_set_drv(struct gameport *gameport, struct gameport_driver *drv)
{
mutex_lock(&gameport->drv_mutex);
int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode)
{
-
if (gameport->open) {
if (gameport->open(gameport, mode)) {
return -1;
{
int error;
- gameport_bus.dev_attrs = gameport_device_attrs;
- gameport_bus.drv_attrs = gameport_driver_attrs;
- gameport_bus.match = gameport_bus_match;
error = bus_register(&gameport_bus);
if (error) {
printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error);
* interrupt context.
*/
- static void atkbd_event_work(void *data)
+ static void atkbd_event_work(struct work_struct *work)
{
- struct atkbd *atkbd = data;
+ struct atkbd *atkbd = container_of(work, struct atkbd, event_work);
mutex_lock(&atkbd->event_mutex);
atkbd = kzalloc(sizeof(struct atkbd), GFP_KERNEL);
dev = input_allocate_device();
if (!atkbd || !dev)
- goto fail;
+ goto fail1;
atkbd->dev = dev;
ps2_init(&atkbd->ps2dev, serio);
- INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd);
+ INIT_WORK(&atkbd->event_work, atkbd_event_work);
mutex_init(&atkbd->event_mutex);
switch (serio->id.type) {
err = serio_open(serio, drv);
if (err)
- goto fail;
+ goto fail2;
if (atkbd->write) {
if (atkbd_probe(atkbd)) {
- serio_close(serio);
err = -ENODEV;
- goto fail;
+ goto fail3;
}
atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
- sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group);
+ err = sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group);
+ if (err)
+ goto fail3;
atkbd_enable(atkbd);
- input_register_device(atkbd->dev);
+ err = input_register_device(atkbd->dev);
+ if (err)
+ goto fail4;
return 0;
- fail: serio_set_drvdata(serio, NULL);
- input_free_device(dev);
+ fail4: sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group);
+ fail3: serio_close(serio);
+ fail2: serio_set_drvdata(serio, NULL);
+ fail1: input_free_device(dev);
kfree(atkbd);
return err;
}
static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count)
{
- struct input_dev *new_dev;
+ struct input_dev *old_dev, *new_dev;
unsigned long value;
char *rest;
+ int err;
+ unsigned char old_extra, old_set;
if (!atkbd->write)
return -EIO;
if (atkbd->extra != value) {
/*
* Since device's properties will change we need to
- * unregister old device. But allocate new one first
- * to make sure we have it.
+ * unregister old device. But allocate and register
+ * new one first to make sure we have it.
*/
- if (!(new_dev = input_allocate_device()))
+ old_dev = atkbd->dev;
+ old_extra = atkbd->extra;
+ old_set = atkbd->set;
+
+ new_dev = input_allocate_device();
+ if (!new_dev)
return -ENOMEM;
- input_unregister_device(atkbd->dev);
+
atkbd->dev = new_dev;
atkbd->set = atkbd_select_set(atkbd, atkbd->set, value);
atkbd_activate(atkbd);
+ atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
- input_register_device(atkbd->dev);
+
+ err = input_register_device(atkbd->dev);
+ if (err) {
+ input_free_device(new_dev);
+
+ atkbd->dev = old_dev;
+ atkbd->set = atkbd_select_set(atkbd, old_set, old_extra);
+ atkbd_set_keycode_table(atkbd);
+ atkbd_set_device_attrs(atkbd);
+
+ return err;
+ }
+ input_unregister_device(old_dev);
+
}
return count;
}
static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count)
{
- struct input_dev *new_dev;
+ struct input_dev *old_dev, *new_dev;
unsigned long value;
char *rest;
+ int err;
+ unsigned char old_scroll;
value = simple_strtoul(buf, &rest, 10);
if (*rest || value > 1)
return -EINVAL;
if (atkbd->scroll != value) {
- if (!(new_dev = input_allocate_device()))
+ old_dev = atkbd->dev;
+ old_scroll = atkbd->scroll;
+
+ new_dev = input_allocate_device();
+ if (!new_dev)
return -ENOMEM;
- input_unregister_device(atkbd->dev);
+
atkbd->dev = new_dev;
atkbd->scroll = value;
atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
- input_register_device(atkbd->dev);
+
+ err = input_register_device(atkbd->dev);
+ if (err) {
+ input_free_device(new_dev);
+
+ atkbd->scroll = old_scroll;
+ atkbd->dev = old_dev;
+ atkbd_set_keycode_table(atkbd);
+ atkbd_set_device_attrs(atkbd);
+
+ return err;
+ }
+ input_unregister_device(old_dev);
}
return count;
}
static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
{
- struct input_dev *new_dev;
+ struct input_dev *old_dev, *new_dev;
unsigned long value;
char *rest;
+ int err;
+ unsigned char old_set, old_extra;
if (!atkbd->write)
return -EIO;
return -EINVAL;
if (atkbd->set != value) {
- if (!(new_dev = input_allocate_device()))
+ old_dev = atkbd->dev;
+ old_extra = atkbd->extra;
+ old_set = atkbd->set;
+
+ new_dev = input_allocate_device();
+ if (!new_dev)
return -ENOMEM;
- input_unregister_device(atkbd->dev);
+
atkbd->dev = new_dev;
atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra);
atkbd_activate(atkbd);
atkbd_set_keycode_table(atkbd);
atkbd_set_device_attrs(atkbd);
- input_register_device(atkbd->dev);
+
+ err = input_register_device(atkbd->dev);
+ if (err) {
+ input_free_device(new_dev);
+
+ atkbd->dev = old_dev;
+ atkbd->set = atkbd_select_set(atkbd, old_set, old_extra);
+ atkbd_set_keycode_table(atkbd);
+ atkbd_set_device_attrs(atkbd);
+
+ return err;
+ }
+ input_unregister_device(old_dev);
}
return count;
}
static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count)
{
- struct input_dev *new_dev;
+ struct input_dev *old_dev, *new_dev;
unsigned long value;
char *rest;
+ int err;
+ unsigned char old_softrepeat, old_softraw;
if (!atkbd->write)
return -EIO;
return -EINVAL;
if (atkbd->softrepeat != value) {
- if (!(new_dev = input_allocate_device()))
+ old_dev = atkbd->dev;
+ old_softrepeat = atkbd->softrepeat;
+ old_softraw = atkbd->softraw;
+
+ new_dev = input_allocate_device();
+ if (!new_dev)
return -ENOMEM;
- input_unregister_device(atkbd->dev);
+
atkbd->dev = new_dev;
atkbd->softrepeat = value;
if (atkbd->softrepeat)
atkbd->softraw = 1;
atkbd_set_device_attrs(atkbd);
- input_register_device(atkbd->dev);
+
+ err = input_register_device(atkbd->dev);
+ if (err) {
+ input_free_device(new_dev);
+
+ atkbd->dev = old_dev;
+ atkbd->softrepeat = old_softrepeat;
+ atkbd->softraw = old_softraw;
+ atkbd_set_device_attrs(atkbd);
+
+ return err;
+ }
+ input_unregister_device(old_dev);
}
return count;
}
static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count)
{
- struct input_dev *new_dev;
+ struct input_dev *old_dev, *new_dev;
unsigned long value;
char *rest;
+ int err;
+ unsigned char old_softraw;
value = simple_strtoul(buf, &rest, 10);
if (*rest || value > 1)
return -EINVAL;
if (atkbd->softraw != value) {
- if (!(new_dev = input_allocate_device()))
+ old_dev = atkbd->dev;
+ old_softraw = atkbd->softraw;
+
+ new_dev = input_allocate_device();
+ if (!new_dev)
return -ENOMEM;
- input_unregister_device(atkbd->dev);
+
atkbd->dev = new_dev;
atkbd->softraw = value;
atkbd_set_device_attrs(atkbd);
- input_register_device(atkbd->dev);
+
+ err = input_register_device(atkbd->dev);
+ if (err) {
+ input_free_device(new_dev);
+
+ atkbd->dev = old_dev;
+ atkbd->softraw = old_softraw;
+ atkbd_set_device_attrs(atkbd);
+
+ return err;
+ }
+ input_unregister_device(old_dev);
}
return count;
}
static int __init atkbd_init(void)
{
- serio_register_driver(&atkbd_drv);
- return 0;
+ return serio_register_driver(&atkbd_drv);
}
static void __exit atkbd_exit(void)
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Should you need to contact me, the author, you can do so either by
- * email or by paper mail:
- * Jan-Benedict Glaw, Lilienstraße 16, 33790 Hörste (near Halle/Westf.),
- * Germany.
*/
#include <linux/delay.h>
* were in.
*/
static void
- lkkbd_reinit (void *data)
+ lkkbd_reinit (struct work_struct *work)
{
- struct lkkbd *lk = data;
+ struct lkkbd *lk = container_of(work, struct lkkbd, tq);
int division;
unsigned char leds_on = 0;
unsigned char leds_off = 0;
input_dev = input_allocate_device ();
if (!lk || !input_dev) {
err = -ENOMEM;
- goto fail;
+ goto fail1;
}
lk->serio = serio;
lk->dev = input_dev;
- INIT_WORK (&lk->tq, lkkbd_reinit, lk);
+ INIT_WORK (&lk->tq, lkkbd_reinit);
lk->bell_volume = bell_volume;
lk->keyclick_volume = keyclick_volume;
lk->ctrlclick_volume = ctrlclick_volume;
err = serio_open (serio, drv);
if (err)
- goto fail;
+ goto fail2;
+
+ err = input_register_device (lk->dev);
+ if (err)
+ goto fail3;
- input_register_device (lk->dev);
lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET);
return 0;
- fail: serio_set_drvdata (serio, NULL);
- input_free_device (input_dev);
+ fail3: serio_close (serio);
+ fail2: serio_set_drvdata (serio, NULL);
+ fail1: input_free_device (input_dev);
kfree (lk);
return err;
}
static int __init
lkkbd_init (void)
{
- serio_register_driver(&lkkbd_drv);
- return 0;
+ return serio_register_driver(&lkkbd_drv);
}
static void __exit
* were in.
*/
- static void sunkbd_reinit(void *data)
+ static void sunkbd_reinit(struct work_struct *work)
{
- struct sunkbd *sunkbd = data;
+ struct sunkbd *sunkbd = container_of(work, struct sunkbd, tq);
wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
sunkbd = kzalloc(sizeof(struct sunkbd), GFP_KERNEL);
input_dev = input_allocate_device();
if (!sunkbd || !input_dev)
- goto fail;
+ goto fail1;
sunkbd->serio = serio;
sunkbd->dev = input_dev;
init_waitqueue_head(&sunkbd->wait);
- INIT_WORK(&sunkbd->tq, sunkbd_reinit, sunkbd);
+ INIT_WORK(&sunkbd->tq, sunkbd_reinit);
snprintf(sunkbd->phys, sizeof(sunkbd->phys), "%s/input0", serio->phys);
serio_set_drvdata(serio, sunkbd);
err = serio_open(serio, drv);
if (err)
- goto fail;
+ goto fail2;
if (sunkbd_initialize(sunkbd) < 0) {
- serio_close(serio);
- goto fail;
+ err = -ENODEV;
+ goto fail3;
}
snprintf(sunkbd->name, sizeof(sunkbd->name), "Sun Type %d keyboard", sunkbd->type);
clear_bit(0, input_dev->keybit);
sunkbd_enable(sunkbd, 1);
- input_register_device(sunkbd->dev);
+
+ err = input_register_device(sunkbd->dev);
+ if (err)
+ goto fail4;
+
return 0;
- fail: serio_set_drvdata(serio, NULL);
- input_free_device(input_dev);
+ fail4: sunkbd_enable(sunkbd, 0);
+ fail3: serio_close(serio);
+ fail2: serio_set_drvdata(serio, NULL);
+ fail1: input_free_device(input_dev);
kfree(sunkbd);
return err;
}
static int __init sunkbd_init(void)
{
- serio_register_driver(&sunkbd_drv);
- return 0;
+ return serio_register_driver(&sunkbd_drv);
}
static void __exit sunkbd_exit(void)
* psmouse_resync() attempts to re-validate current protocol.
*/
- static void psmouse_resync(void *p)
+ static void psmouse_resync(struct work_struct *work)
{
- struct psmouse *psmouse = p, *parent = NULL;
+ struct psmouse *parent = NULL, *psmouse =
+ container_of(work, struct psmouse, resync_work);
struct serio *serio = psmouse->ps2dev.serio;
psmouse_ret_t rc = PSMOUSE_GOOD_DATA;
int failed = 0, enabled = 0;
{
struct psmouse *psmouse, *parent = NULL;
struct input_dev *input_dev;
- int retval = -ENOMEM;
+ int retval = 0, error = -ENOMEM;
mutex_lock(&psmouse_mutex);
psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL);
input_dev = input_allocate_device();
if (!psmouse || !input_dev)
- goto out;
+ goto err_free;
ps2_init(&psmouse->ps2dev, serio);
- INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse);
+ INIT_WORK(&psmouse->resync_work, psmouse_resync);
psmouse->dev = input_dev;
snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys);
serio_set_drvdata(serio, psmouse);
- retval = serio_open(serio, drv);
- if (retval)
- goto out;
+ error = serio_open(serio, drv);
+ if (error)
+ goto err_clear_drvdata;
if (psmouse_probe(psmouse) < 0) {
- serio_close(serio);
- retval = -ENODEV;
- goto out;
+ error = -ENODEV;
+ goto err_close_serio;
}
psmouse->rate = psmouse_rate;
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
psmouse_initialize(psmouse);
- input_register_device(psmouse->dev);
+ error = input_register_device(psmouse->dev);
+ if (error)
+ goto err_protocol_disconnect;
if (parent && parent->pt_activate)
parent->pt_activate(parent);
- sysfs_create_group(&serio->dev.kobj, &psmouse_attribute_group);
+ error = sysfs_create_group(&serio->dev.kobj, &psmouse_attribute_group);
+ if (error)
+ goto err_pt_deactivate;
psmouse_activate(psmouse);
- retval = 0;
-
-out:
- if (retval) {
- serio_set_drvdata(serio, NULL);
- input_free_device(input_dev);
- kfree(psmouse);
- }
-
+ out:
/* If this is a pass-through port the parent needs to be re-activated */
if (parent)
psmouse_activate(parent);
mutex_unlock(&psmouse_mutex);
return retval;
+
+ err_pt_deactivate:
+ if (parent && parent->pt_deactivate)
+ parent->pt_deactivate(parent);
+ err_protocol_disconnect:
+ if (psmouse->disconnect)
+ psmouse->disconnect(psmouse);
+ psmouse_set_state(psmouse, PSMOUSE_IGNORE);
+ err_close_serio:
+ serio_close(serio);
+ err_clear_drvdata:
+ serio_set_drvdata(serio, NULL);
+ err_free:
+ input_free_device(input_dev);
+ kfree(psmouse);
+
+ retval = error;
+ goto out;
}
static ssize_t psmouse_show_int_attr(struct psmouse *psmouse, void *offset, char *buf)
{
- unsigned long *field = (unsigned long *)((char *)psmouse + (size_t)offset);
+ unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset);
- return sprintf(buf, "%lu\n", *field);
+ return sprintf(buf, "%u\n", *field);
}
static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const char *buf, size_t count)
{
- unsigned long *field = (unsigned long *)((char *)psmouse + (size_t)offset);
+ unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset);
unsigned long value;
char *rest;
if (*rest)
return -EINVAL;
+ if ((unsigned int)value != value)
+ return -EINVAL;
+
*field = value;
return count;
{
struct serio *serio = psmouse->ps2dev.serio;
struct psmouse *parent = NULL;
- struct input_dev *new_dev;
- const struct psmouse_protocol *proto;
+ struct input_dev *old_dev, *new_dev;
+ const struct psmouse_protocol *proto, *old_proto;
+ int error;
int retry = 0;
- if (!(proto = psmouse_protocol_by_name(buf, count)))
+ proto = psmouse_protocol_by_name(buf, count);
+ if (!proto)
return -EINVAL;
if (psmouse->type == proto->type)
return count;
- if (!(new_dev = input_allocate_device()))
+ new_dev = input_allocate_device();
+ if (!new_dev)
return -ENOMEM;
while (serio->child) {
parent->pt_deactivate(parent);
}
+ old_dev = psmouse->dev;
+ old_proto = psmouse_protocol_by_type(psmouse->type);
+
if (psmouse->disconnect)
psmouse->disconnect(psmouse);
psmouse_set_state(psmouse, PSMOUSE_IGNORE);
- input_unregister_device(psmouse->dev);
psmouse->dev = new_dev;
psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
psmouse_initialize(psmouse);
psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
- input_register_device(psmouse->dev);
+ error = input_register_device(psmouse->dev);
+ if (error) {
+ if (psmouse->disconnect)
+ psmouse->disconnect(psmouse);
+
+ psmouse_set_state(psmouse, PSMOUSE_IGNORE);
+ input_free_device(new_dev);
+ psmouse->dev = old_dev;
+ psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
+ psmouse_switch_protocol(psmouse, old_proto);
+ psmouse_initialize(psmouse);
+ psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
+
+ return error;
+ }
+
+ input_unregister_device(old_dev);
if (parent && parent->pt_activate)
parent->pt_activate(parent);
static int __init psmouse_init(void)
{
+ int err;
+
kpsmoused_wq = create_singlethread_workqueue("kpsmoused");
if (!kpsmoused_wq) {
printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n");
return -ENOMEM;
}
- serio_register_driver(&psmouse_drv);
+ err = serio_register_driver(&psmouse_drv);
+ if (err)
+ destroy_workqueue(kpsmoused_wq);
- return 0;
+ return err;
}
static void __exit psmouse_exit(void)
#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
+ #include <linux/freezer.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Serio abstraction core");
EXPORT_SYMBOL(__serio_register_port);
EXPORT_SYMBOL(serio_unregister_port);
EXPORT_SYMBOL(serio_unregister_child_port);
-EXPORT_SYMBOL(__serio_unregister_port_delayed);
-EXPORT_SYMBOL(__serio_register_driver);
+EXPORT_SYMBOL(serio_register_driver);
EXPORT_SYMBOL(serio_unregister_driver);
EXPORT_SYMBOL(serio_open);
EXPORT_SYMBOL(serio_close);
static struct bus_type serio_bus;
-static void serio_add_driver(struct serio_driver *drv);
static void serio_add_port(struct serio *serio);
-static void serio_destroy_port(struct serio *serio);
static void serio_reconnect_port(struct serio *serio);
static void serio_disconnect_port(struct serio *serio);
+static void serio_attach_driver(struct serio_driver *drv);
static int serio_connect_driver(struct serio *serio, struct serio_driver *drv)
{
*/
enum serio_event_type {
- SERIO_RESCAN,
- SERIO_RECONNECT,
+ SERIO_RESCAN_PORT,
+ SERIO_RECONNECT_PORT,
SERIO_REGISTER_PORT,
- SERIO_UNREGISTER_PORT,
- SERIO_REGISTER_DRIVER,
+ SERIO_ATTACH_DRIVER,
};
struct serio_event {
static DECLARE_WAIT_QUEUE_HEAD(serio_wait);
static struct task_struct *serio_task;
-static void serio_queue_event(void *object, struct module *owner,
- enum serio_event_type event_type)
+static int serio_queue_event(void *object, struct module *owner,
+ enum serio_event_type event_type)
{
unsigned long flags;
struct serio_event *event;
+ int retval = 0;
spin_lock_irqsave(&serio_event_lock, flags);
}
}
- if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
- if (!try_module_get(owner)) {
- printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type);
- kfree(event);
- goto out;
- }
-
- event->type = event_type;
- event->object = object;
- event->owner = owner;
+ event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC);
+ if (!event) {
+ printk(KERN_ERR
+ "serio: Not enough memory to queue event %d\n",
+ event_type);
+ retval = -ENOMEM;
+ goto out;
+ }
- list_add_tail(&event->node, &serio_event_list);
- wake_up(&serio_wait);
- } else {
- printk(KERN_ERR "serio: Not enough memory to queue event %d\n", event_type);
+ if (!try_module_get(owner)) {
+ printk(KERN_WARNING
+ "serio: Can't get module reference, dropping event %d\n",
+ event_type);
+ kfree(event);
+ retval = -EINVAL;
+ goto out;
}
+
+ event->type = event_type;
+ event->object = object;
+ event->owner = owner;
+
+ list_add_tail(&event->node, &serio_event_list);
+ wake_up(&serio_wait);
+
out:
spin_unlock_irqrestore(&serio_event_lock, flags);
+ return retval;
}
static void serio_free_event(struct serio_event *event)
serio_add_port(event->object);
break;
- case SERIO_UNREGISTER_PORT:
- serio_disconnect_port(event->object);
- serio_destroy_port(event->object);
- break;
-
- case SERIO_RECONNECT:
+ case SERIO_RECONNECT_PORT:
serio_reconnect_port(event->object);
break;
- case SERIO_RESCAN:
+ case SERIO_RESCAN_PORT:
serio_disconnect_port(event->object);
serio_find_driver(event->object);
break;
- case SERIO_REGISTER_DRIVER:
- serio_add_driver(event->object);
+ case SERIO_ATTACH_DRIVER:
+ serio_attach_driver(event->object);
break;
default:
void serio_rescan(struct serio *serio)
{
- serio_queue_event(serio, NULL, SERIO_RESCAN);
+ serio_queue_event(serio, NULL, SERIO_RESCAN_PORT);
}
void serio_reconnect(struct serio *serio)
{
- serio_queue_event(serio, NULL, SERIO_RECONNECT);
+ serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT);
}
/*
mutex_unlock(&serio_mutex);
}
-/*
- * Submits register request to kseriod for subsequent execution.
- * Can be used when it is not obvious whether the serio_mutex is
- * taken or not and when delayed execution is feasible.
- */
-void __serio_unregister_port_delayed(struct serio *serio, struct module *owner)
-{
- serio_queue_event(serio, owner, SERIO_UNREGISTER_PORT);
-}
-
/*
* Serio driver operations
return 0;
}
-static struct bus_type serio_bus = {
- .name = "serio",
- .probe = serio_driver_probe,
- .remove = serio_driver_remove,
-};
-
-static void serio_add_driver(struct serio_driver *drv)
+static void serio_attach_driver(struct serio_driver *drv)
{
int error;
- error = driver_register(&drv->driver);
+ error = driver_attach(&drv->driver);
if (error)
- printk(KERN_ERR
- "serio: driver_register() failed for %s, error: %d\n",
+ printk(KERN_WARNING
+ "serio: driver_attach() failed for %s with error %d\n",
drv->driver.name, error);
}
-void __serio_register_driver(struct serio_driver *drv, struct module *owner)
+int serio_register_driver(struct serio_driver *drv)
{
+ int manual_bind = drv->manual_bind;
+ int error;
+
drv->driver.bus = &serio_bus;
- serio_queue_event(drv, owner, SERIO_REGISTER_DRIVER);
+ /*
+ * Temporarily disable automatic binding because probing
+ * takes long time and we are better off doing it in kseriod
+ */
+ drv->manual_bind = 1;
+
+ error = driver_register(&drv->driver);
+ if (error) {
+ printk(KERN_ERR
+ "serio: driver_register() failed for %s, error: %d\n",
+ drv->driver.name, error);
+ return error;
+ }
+
+ /*
+ * Restore original bind mode and let kseriod bind the
+ * driver to free ports
+ */
+ if (!manual_bind) {
+ drv->manual_bind = 0;
+ error = serio_queue_event(drv, NULL, SERIO_ATTACH_DRIVER);
+ if (error) {
+ driver_unregister(&drv->driver);
+ return error;
+ }
+ }
+
+ return 0;
}
void serio_unregister_driver(struct serio_driver *drv)
return ret;
}
+static struct bus_type serio_bus = {
+ .name = "serio",
+ .dev_attrs = serio_device_attrs,
+ .drv_attrs = serio_driver_attrs,
+ .match = serio_bus_match,
+ .uevent = serio_uevent,
+ .probe = serio_driver_probe,
+ .remove = serio_driver_remove,
+ .resume = serio_resume,
+};
+
static int __init serio_init(void)
{
int error;
- serio_bus.dev_attrs = serio_device_attrs;
- serio_bus.drv_attrs = serio_driver_attrs;
- serio_bus.match = serio_bus_match;
- serio_bus.uevent = serio_uevent;
- serio_bus.resume = serio_resume;
error = bus_register(&serio_bus);
if (error) {
printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error);
serio_raw->dev.minor = PSMOUSE_MINOR;
serio_raw->dev.name = serio_raw->name;
- serio_raw->dev.dev = &serio->dev;
+ serio_raw->dev.parent = &serio->dev;
serio_raw->dev.fops = &serio_raw_fops;
err = misc_register(&serio_raw->dev);
static int __init serio_raw_init(void)
{
- serio_register_driver(&serio_raw_drv);
- return 0;
+ return serio_register_driver(&serio_raw_drv);
}
static void __exit serio_raw_exit(void)
char phys[32];
struct spi_device *spi;
+ struct attribute_group *attr_group;
u16 model;
u16 vref_delay_usecs;
u16 x_plate_ohms;
{
struct spi_device *spi = to_spi_device(dev);
struct ads7846 *ts = dev_get_drvdata(dev);
- struct ser_req *req = kzalloc(sizeof *req, SLAB_KERNEL);
+ struct ser_req *req = kzalloc(sizeof *req, GFP_KERNEL);
int status;
int sample;
int i;
static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store);
+static struct attribute *ads7846_attributes[] = {
+ &dev_attr_temp0.attr,
+ &dev_attr_temp1.attr,
+ &dev_attr_vbatt.attr,
+ &dev_attr_vaux.attr,
+ &dev_attr_pen_down.attr,
+ &dev_attr_disable.attr,
+ NULL,
+};
+
+static struct attribute_group ads7846_attr_group = {
+ .attrs = ads7846_attributes,
+};
+
+/*
+ * ads7843/7845 don't have temperature sensors, and
+ * use the other sensors a bit differently too
+ */
+
+static struct attribute *ads7843_attributes[] = {
+ &dev_attr_vbatt.attr,
+ &dev_attr_vaux.attr,
+ &dev_attr_pen_down.attr,
+ &dev_attr_disable.attr,
+ NULL,
+};
+
+static struct attribute_group ads7843_attr_group = {
+ .attrs = ads7843_attributes,
+};
+
+static struct attribute *ads7845_attributes[] = {
+ &dev_attr_vaux.attr,
+ &dev_attr_pen_down.attr,
+ &dev_attr_disable.attr,
+ NULL,
+};
+
+static struct attribute_group ads7845_attr_group = {
+ .attrs = ads7845_attributes,
+};
+
/*--------------------------------------------------------------------------*/
/*
(void) ads7846_read12_ser(&spi->dev,
READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
- /* ads7843/7845 don't have temperature sensors, and
- * use the other sensors a bit differently too
- */
- if (ts->model == 7846) {
- device_create_file(&spi->dev, &dev_attr_temp0);
- device_create_file(&spi->dev, &dev_attr_temp1);
+ switch (ts->model) {
+ case 7846:
+ ts->attr_group = &ads7846_attr_group;
+ break;
+ case 7845:
+ ts->attr_group = &ads7845_attr_group;
+ break;
+ default:
+ ts->attr_group = &ads7843_attr_group;
+ break;
}
- if (ts->model != 7845)
- device_create_file(&spi->dev, &dev_attr_vbatt);
- device_create_file(&spi->dev, &dev_attr_vaux);
-
- device_create_file(&spi->dev, &dev_attr_pen_down);
-
- device_create_file(&spi->dev, &dev_attr_disable);
+ err = sysfs_create_group(&spi->dev.kobj, ts->attr_group);
+ if (err)
+ goto err_free_irq;
err = input_register_device(input_dev);
if (err)
- goto err_remove_attr;
+ goto err_remove_attr_group;
return 0;
- err_remove_attr:
- device_remove_file(&spi->dev, &dev_attr_disable);
- device_remove_file(&spi->dev, &dev_attr_pen_down);
- if (ts->model == 7846) {
- device_remove_file(&spi->dev, &dev_attr_temp1);
- device_remove_file(&spi->dev, &dev_attr_temp0);
- }
- if (ts->model != 7845)
- device_remove_file(&spi->dev, &dev_attr_vbatt);
- device_remove_file(&spi->dev, &dev_attr_vaux);
-
+ err_remove_attr_group:
+ sysfs_remove_group(&spi->dev.kobj, ts->attr_group);
+ err_free_irq:
free_irq(spi->irq, ts);
err_free_mem:
input_free_device(input_dev);
ads7846_suspend(spi, PMSG_SUSPEND);
- device_remove_file(&spi->dev, &dev_attr_disable);
- device_remove_file(&spi->dev, &dev_attr_pen_down);
- if (ts->model == 7846) {
- device_remove_file(&spi->dev, &dev_attr_temp1);
- device_remove_file(&spi->dev, &dev_attr_temp0);
- }
- if (ts->model != 7845)
- device_remove_file(&spi->dev, &dev_attr_vbatt);
- device_remove_file(&spi->dev, &dev_attr_vaux);
+ sysfs_remove_group(&spi->dev.kobj, ts->attr_group);
free_irq(ts->spi->irq, ts);
/* suspend left the IRQ disabled */
config MAC_EMUMOUSEBTN
bool "Support for mouse button 2+3 emulation"
- depends on INPUT_ADBHID
help
This provides generic support for emulating the 2nd and 3rd mouse
button with keypresses. If you say Y here, the emulation is still
tristate "Support for ANS LCD display"
depends on ADB_CUDA && PPC_PMAC
+ config PMAC_RACKMETER
+ tristate "Support for Apple XServe front panel LEDs"
+ depends on PPC_PMAC
+ help
+ This driver procides some support to control the front panel
+ blue LEDs "vu-meter" of the XServer macs.
+
endmenu
hid_io_error(hid);
}
- /* Workqueue routine to reset the device */
- static void hid_reset(void *_hid)
+ /* Workqueue routine to reset the device or clear a halt */
+ static void hid_reset(struct work_struct *work)
{
- struct hid_device *hid = (struct hid_device *) _hid;
- int rc_lock, rc;
-
- dev_dbg(&hid->intf->dev, "resetting device\n");
- rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf);
- if (rc_lock >= 0) {
- rc = usb_reset_composite_device(hid->dev, hid->intf);
- if (rc_lock)
- usb_unlock_device(hid->dev);
+ struct hid_device *hid =
+ container_of(work, struct hid_device, reset_work);
+ int rc_lock, rc = 0;
+
+ if (test_bit(HID_CLEAR_HALT, &hid->iofl)) {
+ dev_dbg(&hid->intf->dev, "clear halt\n");
+ rc = usb_clear_halt(hid->dev, hid->urbin->pipe);
+ clear_bit(HID_CLEAR_HALT, &hid->iofl);
+ hid_start_in(hid);
+ }
+
+ else if (test_bit(HID_RESET_PENDING, &hid->iofl)) {
+ dev_dbg(&hid->intf->dev, "resetting device\n");
+ rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf);
+ if (rc_lock >= 0) {
+ rc = usb_reset_composite_device(hid->dev, hid->intf);
+ if (rc_lock)
+ usb_unlock_device(hid->dev);
+ }
+ clear_bit(HID_RESET_PENDING, &hid->iofl);
}
- clear_bit(HID_RESET_PENDING, &hid->iofl);
switch (rc) {
case 0:
/* Retries failed, so do a port reset */
if (!test_and_set_bit(HID_RESET_PENDING, &hid->iofl)) {
- if (schedule_work(&hid->reset_work))
- goto done;
- clear_bit(HID_RESET_PENDING, &hid->iofl);
+ schedule_work(&hid->reset_work);
+ goto done;
}
}
hid->retry_delay = 0;
hid_input_report(HID_INPUT_REPORT, urb, 1);
break;
+ case -EPIPE: /* stall */
+ clear_bit(HID_IN_RUNNING, &hid->iofl);
+ set_bit(HID_CLEAR_HALT, &hid->iofl);
+ schedule_work(&hid->reset_work);
+ return;
case -ECONNRESET: /* unlink */
case -ENOENT:
case -ESHUTDOWN: /* unplug */
warn("input irq status %d received", urb->status);
}
- status = usb_submit_urb(urb, SLAB_ATOMIC);
+ status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
clear_bit(HID_IN_RUNNING, &hid->iofl);
if (status != -EPERM) {
#define USB_VENDOR_ID_APPLE 0x05ac
#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
+ #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e
+ #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f
+ #define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214
+ #define USB_DEVICE_ID_APPLE_GEYSER_ISO 0x0215
+ #define USB_DEVICE_ID_APPLE_GEYSER_JIS 0x0216
+ #define USB_DEVICE_ID_APPLE_GEYSER3_ANSI 0x0217
+ #define USB_DEVICE_ID_APPLE_GEYSER3_ISO 0x0218
+ #define USB_DEVICE_ID_APPLE_GEYSER3_JIS 0x0219
+ #define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a
+ #define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b
+ #define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c
+ #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
+ #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
#define USB_VENDOR_ID_CHERRY 0x046a
#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
#define USB_VENDOR_ID_AIRCABLE 0x16CA
#define USB_DEVICE_ID_AIRCABLE1 0x1502
+#define USB_VENDOR_ID_LOGITECH 0x046d
+#define USB_DEVICE_ID_LOGITECH_USB_RECEIVER 0xc101
+
/*
* Alphabetically sorted blacklist by quirk type.
*/
{ USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION },
- { USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN },
- { USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN },
- { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN },
- { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN },
- { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN },
- { USB_VENDOR_ID_APPLE, 0x0217, HID_QUIRK_POWERBOOK_HAS_FN },
- { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN },
- { USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN },
- { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN },
- { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
-
+
+ { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_USB_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS },
+
{ 0, 0 }
};
static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
{
- if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->inbuf_dma)))
+ if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->inbuf_dma)))
return -1;
- if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->outbuf_dma)))
+ if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->outbuf_dma)))
return -1;
- if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma)))
+ if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), GFP_ATOMIC, &hid->cr_dma)))
return -1;
- if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->ctrlbuf_dma)))
+ if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->ctrlbuf_dma)))
return -1;
return 0;
if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0)
interval = hid_mousepoll_interval;
- if (endpoint->bEndpointAddress & USB_DIR_IN) {
+ if (usb_endpoint_dir_in(endpoint)) {
if (hid->urbin)
continue;
if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL)))
init_waitqueue_head(&hid->wait);
- INIT_WORK(&hid->reset_work, hid_reset, hid);
+ INIT_WORK(&hid->reset_work, hid_reset);
setup_timer(&hid->io_retry, hid_retry_timeout, (unsigned long) hid);
spin_lock_init(&hid->inlock);
return hid;
fail:
-
- if (hid->urbin)
- usb_free_urb(hid->urbin);
- if (hid->urbout)
- usb_free_urb(hid->urbout);
- if (hid->urbctrl)
- usb_free_urb(hid->urbctrl);
+ usb_free_urb(hid->urbin);
+ usb_free_urb(hid->urbout);
+ usb_free_urb(hid->urbctrl);
hid_free_buffers(dev, hid);
hid_free_device(hid);
usb_free_urb(hid->urbin);
usb_free_urb(hid->urbctrl);
- if (hid->urbout)
- usb_free_urb(hid->urbout);
+ usb_free_urb(hid->urbout);
hid_free_buffers(hid->dev, hid);
hid_free_device(hid);
{ }
};
+ static struct hidinput_key_translation powerbook_iso_keyboard[] = {
+ { KEY_GRAVE, KEY_102ND },
+ { KEY_102ND, KEY_GRAVE },
+ { }
+ };
+
static int usbhid_pb_fnmode = 1;
module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644);
MODULE_PARM_DESC(pb_fnmode,
}
}
+ if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) {
+ trans = find_translation(powerbook_iso_keyboard, usage->code);
+ if (trans) {
+ input_event(input, usage->type, trans->to, value);
+ return 1;
+ }
+ }
+
return 0;
}
for (trans = powerbook_numlock_keys; trans->from; trans++)
set_bit(trans->to, input->keybit);
+
+ for (trans = powerbook_iso_keyboard; trans->from; trans++)
+ set_bit(trans->to, input->keybit);
}
#else
static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
|| ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007)))
goto ignore;
+ if ((device->quirks & HID_QUIRK_BAD_RELATIVE_KEYS) &&
+ usage->type == EV_KEY && (field->flags & HID_MAIN_ITEM_RELATIVE))
+ field->flags &= ~HID_MAIN_ITEM_RELATIVE;
+
set_bit(usage->type, input->evbit);
while (usage->code <= max && test_and_set_bit(usage->code, bit))
#define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000
#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000
#define HID_QUIRK_INVERT_HWHEEL 0x00004000
- #define HID_QUIRK_BAD_RELATIVE_KEYS 0x00008000
+ #define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00008000
++#define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000
/*
* This is the global environment of the parser. This information is
#define HID_IN_RUNNING 3
#define HID_RESET_PENDING 4
#define HID_SUSPENDED 5
+ #define HID_CLEAR_HALT 6
struct hid_input {
struct list_head list;