diff options
| author | Dmitry Torokhov <dtor@mail.ru> | 2005-02-04 15:39:25 +0100 |
|---|---|---|
| committer | Vojtech Pavlik <vojtech@suse.cz> | 2005-02-04 15:39:25 +0100 |
| commit | e122050fef4216632a43bf6ebcaa44c3ad6b07cf (patch) | |
| tree | e5525272fe8ba4577107d3572f72bbb06799ad33 /drivers/input/serio | |
| parent | 8f9ba920e5efff59cff044749a6cae9748f8b6f8 (diff) | |
Input: replace serio's type field with serio_id structure and
add id_table to serio drivers to split initial matching
and probing routines for better sysfs integration and
to assist hotplug scripts in loading proper drivers.
Add serio_hotplug to notify userspace about new ports.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Signed-off-by: Vojtech Pavlik <vojtech@suse.cz>
Diffstat (limited to 'drivers/input/serio')
| -rw-r--r-- | drivers/input/serio/ambakmi.c | 2 | ||||
| -rw-r--r-- | drivers/input/serio/ct82c710.c | 2 | ||||
| -rw-r--r-- | drivers/input/serio/gscps2.c | 6 | ||||
| -rw-r--r-- | drivers/input/serio/i8042.c | 6 | ||||
| -rw-r--r-- | drivers/input/serio/maceps2.c | 2 | ||||
| -rw-r--r-- | drivers/input/serio/parkbd.c | 2 | ||||
| -rw-r--r-- | drivers/input/serio/pcips2.c | 2 | ||||
| -rw-r--r-- | drivers/input/serio/q40kbd.c | 2 | ||||
| -rw-r--r-- | drivers/input/serio/rpckbd.c | 2 | ||||
| -rw-r--r-- | drivers/input/serio/sa1111ps2.c | 2 | ||||
| -rw-r--r-- | drivers/input/serio/serio.c | 73 | ||||
| -rw-r--r-- | drivers/input/serio/serio_raw.c | 16 | ||||
| -rw-r--r-- | drivers/input/serio/serport.c | 20 |
13 files changed, 106 insertions, 31 deletions
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index 4b3b5135f5c1..d9c144043d72 100644 --- a/drivers/input/serio/ambakmi.c +++ b/drivers/input/serio/ambakmi.c @@ -134,7 +134,7 @@ static int amba_kmi_probe(struct amba_device *dev, void *id) memset(kmi, 0, sizeof(struct amba_kmi_port)); memset(io, 0, sizeof(struct serio)); - io->type = SERIO_8042; + io->id.type = SERIO_8042; io->write = amba_kmi_write; io->open = amba_kmi_open; io->close = amba_kmi_close; diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index ee785460b78f..54b5edad0941 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c @@ -181,7 +181,7 @@ static struct serio * __init ct82c710_allocate_port(void) serio = kmalloc(sizeof(struct serio), GFP_KERNEL); if (serio) { memset(serio, 0, sizeof(struct serio)); - serio->type = SERIO_8042; + serio->id.type = SERIO_8042; serio->open = ct82c710_open; serio->close = ct82c710_close; serio->write = ct82c710_write; diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index 401d750116d5..d530e70a3b47 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c @@ -363,11 +363,7 @@ static int __init gscps2_probe(struct parisc_device *dev) snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s", (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse"); strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys)); - serio->idbus = BUS_GSC; - serio->idvendor = PCI_VENDOR_ID_HP; - serio->idproduct = 0x0001; - serio->idversion = 0x0010; - serio->type = SERIO_8042; + serio->id.type = SERIO_8042; serio->write = gscps2_write; serio->open = gscps2_open; serio->close = gscps2_close; diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index cc6a82e26bdb..496e42fbe855 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -971,7 +971,7 @@ static void __init i8042_create_kbd_port(void) serio = kmalloc(sizeof(struct serio), GFP_KERNEL); if (serio) { memset(serio, 0, sizeof(struct serio)); - serio->type = i8042_direct ? SERIO_8042 : SERIO_8042_XL; + serio->id.type = i8042_direct ? SERIO_8042 : SERIO_8042_XL; serio->write = i8042_dumbkbd ? NULL : i8042_kbd_write; serio->open = i8042_open; serio->close = i8042_close; @@ -995,7 +995,7 @@ static void __init i8042_create_aux_port(void) serio = kmalloc(sizeof(struct serio), GFP_KERNEL); if (serio) { memset(serio, 0, sizeof(struct serio)); - serio->type = SERIO_8042; + serio->id.type = SERIO_8042; serio->write = i8042_aux_write; serio->open = i8042_open; serio->close = i8042_close; @@ -1019,7 +1019,7 @@ static void __init i8042_create_mux_port(int index) serio = kmalloc(sizeof(struct serio), GFP_KERNEL); if (serio) { memset(serio, 0, sizeof(struct serio)); - serio->type = SERIO_8042; + serio->id.type = SERIO_8042; serio->write = i8042_aux_write; serio->open = i8042_open; serio->close = i8042_close; diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c index 72b15b20d2a5..9880fc145d90 100644 --- a/drivers/input/serio/maceps2.c +++ b/drivers/input/serio/maceps2.c @@ -125,7 +125,7 @@ static struct serio * __init maceps2_allocate_port(int idx) serio = kmalloc(sizeof(struct serio), GFP_KERNEL); if (serio) { memset(serio, 0, sizeof(struct serio)); - serio->type = SERIO_8042; + serio->id.type = SERIO_8042; serio->write = maceps2_write; serio->open = maceps2_open; serio->close = maceps2_close; diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c index d0510ecaf9ac..40b937e77334 100644 --- a/drivers/input/serio/parkbd.c +++ b/drivers/input/serio/parkbd.c @@ -158,7 +158,7 @@ static struct serio * __init parkbd_allocate_serio(void) serio = kmalloc(sizeof(struct serio), GFP_KERNEL); if (serio) { memset(serio, 0, sizeof(struct serio)); - serio->type = parkbd_mode; + serio->id.type = parkbd_mode; serio->write = parkbd_write, strlcpy(serio->name, "PARKBD AT/XT keyboard adapter", sizeof(serio->name)); snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", parkbd_dev->port->name); diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c index 489749e7c9d0..cb4cbe18c199 100644 --- a/drivers/input/serio/pcips2.c +++ b/drivers/input/serio/pcips2.c @@ -150,7 +150,7 @@ static int __devinit pcips2_probe(struct pci_dev *dev, const struct pci_device_i memset(ps2if, 0, sizeof(struct pcips2_data)); memset(serio, 0, sizeof(struct serio)); - serio->type = SERIO_8042; + serio->id.type = SERIO_8042; serio->write = pcips2_write; serio->open = pcips2_open; serio->close = pcips2_close; diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index ab4425db304c..46093c507988 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c @@ -122,7 +122,7 @@ static struct serio * __init q40kbd_allocate_port(void) serio = kmalloc(sizeof(struct serio), GFP_KERNEL); if (serio) { memset(serio, 0, sizeof(struct serio)); - serio->type = SERIO_8042; + serio->id.type = SERIO_8042; serio->open = q40kbd_open; serio->close = q40kbd_close; serio->dev.parent = &q40kbd_device->dev; diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index 49a58410295e..106f5eefd89a 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -115,7 +115,7 @@ static int __devinit rpckbd_probe(struct device *dev) return -ENOMEM; memset(serio, 0, sizeof(struct serio)); - serio->type = SERIO_8042; + serio->id.type = SERIO_8042; serio->write = rpckbd_write; serio->open = rpckbd_open; serio->close = rpckbd_close; diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c index 62937f5b3e57..d6433958a9d8 100644 --- a/drivers/input/serio/sa1111ps2.c +++ b/drivers/input/serio/sa1111ps2.c @@ -245,7 +245,7 @@ static int ps2_probe(struct sa1111_dev *dev) memset(ps2if, 0, sizeof(struct ps2if)); memset(serio, 0, sizeof(struct serio)); - serio->type = SERIO_8042; + serio->id.type = SERIO_8042; serio->write = ps2_write; serio->open = ps2_open; serio->close = ps2_close; diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 8eaa261e6545..2a9031a99744 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -68,17 +68,33 @@ static void serio_connect_port(struct serio *serio, struct serio_driver *drv); static void serio_reconnect_port(struct serio *serio); static void serio_disconnect_port(struct serio *serio); +static int serio_match_port(const struct serio_device_id *ids, struct serio *serio) +{ + while (ids->type || ids->proto) { + if ((ids->type == SERIO_ANY || ids->type == serio->id.type) && + (ids->proto == SERIO_ANY || ids->proto == serio->id.proto) && + (ids->extra == SERIO_ANY || ids->extra == serio->id.extra) && + (ids->id == SERIO_ANY || ids->id == serio->id.id)) + return 1; + ids++; + } + return 0; +} + static int serio_bind_driver(struct serio *serio, struct serio_driver *drv) { get_driver(&drv->driver); - drv->connect(serio, drv); - if (serio->drv) { - down_write(&serio_bus.subsys.rwsem); - serio->dev.driver = &drv->driver; - device_bind_driver(&serio->dev); - up_write(&serio_bus.subsys.rwsem); - return 1; + if (serio_match_port(drv->id_table, serio)) { + drv->connect(serio, drv); + + if (serio->drv) { + down_write(&serio_bus.subsys.rwsem); + serio->dev.driver = &drv->driver; + device_bind_driver(&serio->dev); + up_write(&serio_bus.subsys.rwsem); + return 1; + } } put_driver(&drv->driver); @@ -648,6 +664,48 @@ static void serio_set_drv(struct serio *serio, struct serio_driver *drv) up(&serio->drv_sem); } +#ifdef CONFIG_HOTPLUG + +#define PUT_ENVP(fmt, val) \ +do { \ + envp[i++] = buffer; \ + length += snprintf(buffer, buffer_size - length, fmt, val); \ + if (buffer_size - length <= 0 || i >= num_envp) \ + return -ENOMEM; \ + length++; \ + buffer += length; \ +} while (0) +static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) +{ + struct serio *serio; + int i = 0; + int length = 0; + + if (!dev) + return -ENODEV; + + serio = to_serio_port(dev); + + PUT_ENVP("SERIO_TYPE=%02x", serio->id.type); + PUT_ENVP("SERIO_PROTO=%02x", serio->id.proto); + PUT_ENVP("SERIO_ID=%02x", serio->id.id); + PUT_ENVP("SERIO_EXTRA=%02x", serio->id.extra); + + envp[i] = NULL; + + return 0; +} +#undef PUT_ENVP + +#else + +static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) +{ + return -ENODEV; +} + +#endif /* CONFIG_HOTPLUG */ + /* called from serio_driver->connect/disconnect methods under serio_sem */ int serio_open(struct serio *serio, struct serio_driver *drv) { @@ -698,6 +756,7 @@ static int __init serio_init(void) serio_bus.dev_attrs = serio_device_attrs; serio_bus.drv_attrs = serio_driver_attrs; + serio_bus.hotplug = serio_hotplug; bus_register(&serio_bus); return 0; diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 6e9144799034..6da5cea8129c 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -275,9 +275,6 @@ static void serio_raw_connect(struct serio *serio, struct serio_driver *drv) struct serio_raw *serio_raw; int err; - if ((serio->type & SERIO_TYPE) != SERIO_8042) - return; - if (!(serio_raw = kmalloc(sizeof(struct serio_raw), GFP_KERNEL))) { printk(KERN_ERR "serio_raw.c: can't allocate memory for a device\n"); return; @@ -363,11 +360,24 @@ static void serio_raw_disconnect(struct serio *serio) up(&serio_raw_sem); } +static struct serio_device_id serio_raw_serio_ids[] = { + { + .type = SERIO_8042, + .proto = SERIO_ANY, + .id = SERIO_ANY, + .extra = SERIO_ANY, + }, + { 0 } +}; + +MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids); + static struct serio_driver serio_raw_drv = { .driver = { .name = "serio_raw", }, .description = DRIVER_DESC, + .id_table = serio_raw_serio_ids, .interrupt = serio_raw_interrupt, .connect = serio_raw_connect, .reconnect = serio_raw_reconnect, diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 538ccf180797..22f73683952b 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -49,7 +49,7 @@ static void serport_serio_close(struct serio *serio) { struct serport *serport = serio->port_data; - serport->serio->type = 0; + serport->serio->id.type = 0; wake_up_interruptible(&serport->wait); } @@ -84,7 +84,7 @@ static int serport_ldisc_open(struct tty_struct *tty) memset(serio, 0, sizeof(struct serio)); strlcpy(serio->name, "Serial port", sizeof(serio->name)); snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty, name)); - serio->type = SERIO_RS232; + serio->id.type = SERIO_RS232; serio->write = serport_serio_write; serio->close = serport_serio_close; serio->port_data = serport; @@ -148,7 +148,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u serio_register_port(serport->serio); printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name)); - wait_event_interruptible(serport->wait, !serport->serio->type); + wait_event_interruptible(serport->wait, !serport->serio->id.type); serio_unregister_port(serport->serio); clear_bit(SERPORT_BUSY, &serport->flags); @@ -163,9 +163,19 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg) { struct serport *serport = (struct serport*) tty->disc_data; + struct serio *serio = serport->serio; + unsigned long type; - if (cmd == SPIOCSTYPE) - return get_user(serport->serio->type, (unsigned long __user *) arg); + if (cmd == SPIOCSTYPE) { + if (get_user(type, (unsigned long __user *) arg)) + return -EFAULT; + + serio->id.proto = type & 0x000000ff; + serio->id.id = (type & 0x0000ff00) >> 8; + serio->id.extra = (type & 0x00ff0000) >> 16; + + return 0; + } return -EINVAL; } |
