博所搬至http://xiaogr.com
全部博文(79)
分类: LINUX
2008-07-16 14:22:51
static int __init serio_init(void)
printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error);
serio_task = kthread_run(serio_thread, NULL, "kseriod");
printk(KERN_ERR "serio: Failed to start kseriod, error: %d\n", error);
static inline void serio_register_port(struct serio *serio)
void __serio_register_port(struct serio *serio, struct module *owner)
serio_queue_event(serio, owner, SERIO_REGISTER_PORT);
static int serio_queue_event(void *object, struct module *owner,
spin_lock_irqsave(&serio_event_lock, flags);
* Scan event list for the other events for the same serio port,
* starting with the most recent one. If event is the same we
* do not need add new one. If event is of different type we
* need to add this event and should not look further because
* we need to preseve sequence of distinct events.
list_for_each_entry_reverse(event, &serio_event_list, node) {
event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC);
"serio: Not enough memory to queue event %d\n",
"serio: Can't get module reference, dropping event %d\n",
list_add_tail(&event->node, &serio_event_list);
spin_unlock_irqrestore(&serio_event_lock, flags);
static int serio_thread(void *nothing)
kthread_should_stop() || !list_empty(&serio_event_list));
printk(KERN_DEBUG "serio: kseriod exiting\n");
static void serio_handle_event(void)
* Note that we handle only one event here to give swsusp
* a chance to freeze kseriod thread. Serio events should
* be pretty rare so we are not concerned about taking
* performance hit.
static void serio_add_port(struct serio *serio)
list_add_tail(&serio->node, &serio_list);
"serio: device_add() failed for %s (%s), error: %d\n",
serio->phys, serio->name, error);
error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group);
"serio: sysfs_create_group() failed for %s (%s), error: %d\n",
serio->phys, serio->name, error);
static int serio_uevent(struct device *dev, struct kobj_uevent_env *env)
SERIO_ADD_UEVENT_VAR("SERIO_TYPE=%02x", serio->id.type);
SERIO_ADD_UEVENT_VAR("SERIO_PROTO=%02x", serio->id.proto);
SERIO_ADD_UEVENT_VAR("SERIO_ID=%02x", serio->id.id);
SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra);
serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
[root@localhost serio0]# cat /sys/bus/serio/devices/serio0/uevent
static inline int serio_register_driver(struct serio_driver *drv)
return __serio_register_driver(drv, THIS_MODULE, KBUILD_MODNAME);
int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name)
* Temporarily disable automatic binding because probing
* takes long time and we are better off doing it in kseriod
error = driver_register(&drv->driver);
"serio: driver_register() failed for %s, error: %d\n",
* Restore original bind mode and let kseriod bind the
* driver to free ports
error = serio_queue_event(drv, NULL, SERIO_ATTACH_DRIVER);
static int serio_bus_match(struct device *dev, struct device_driver *drv)
struct serio_driver *serio_drv = to_serio_driver(drv);
if (serio->manual_bind || serio_drv->manual_bind)
return serio_match_port(serio_drv->id_table, serio);
static int serio_match_port(const struct serio_device_id *ids, struct serio *serio)
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))
static int serio_driver_probe(struct device *dev)
struct serio_driver *drv = to_serio_driver(dev->driver);
static int serio_connect_driver(struct serio *serio, struct serio_driver *drv)
static void serio_attach_driver(struct serio_driver *drv)
"serio: driver_attach() failed for %s with error %d\n",
irqreturn_t serio_interrupt(struct serio *serio,
unsigned char data, unsigned int dfl)
spin_lock_irqsave(&serio->lock, flags);
ret = serio->drv->interrupt(serio, data, dfl);
} else if (!dfl && serio->registered) {
spin_unlock_irqrestore(&serio->lock, flags);
void serio_rescan(struct serio *serio)
serio_queue_event(serio, NULL, SERIO_RESCAN_PORT);
static void serio_add_port(struct serio *serio)
serio->parent->child = serio;
list_add_tail(&serio->node, &serio_list);
"serio: device_add() failed for %s (%s), error: %d\n",
serio->phys, serio->name, error);
error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group);
"serio: sysfs_create_group() failed for %s (%s), error: %d\n",
serio->phys, serio->name, error);
chinaunix网友2008-09-07 03:20:55
最后对SERIO_RESCAN_PORT的分析错误了哈,在serio_handle_event()对应的处理动作不是serio_add_port
chinaunix网友2008-09-07 03:20:55
最后对SERIO_RESCAN_PORT的分析错误了哈,在serio_handle_event()对应的处理动作不是serio_add_port
chinaunix网友2008-09-07 03:20:55
最后对SERIO_RESCAN_PORT的分析错误了哈,在serio_handle_event()对应的处理动作不是serio_add_port
chinaunix网友2008-09-07 02:54:22
Why! 为什么要这样做呢? 这次事件的动作实现上在driver_register()中已经做了。 ============================================= 代码里是二选一,有判断条件的。
chinaunix网友2008-09-07 02:54:22
Why! 为什么要这样做呢? 这次事件的动作实现上在driver_register()中已经做了。 ============================================= 代码里是二选一,有判断条件的。