掘削ログ
昨晩、class_create な手続き呼び出し箇所を特定するために rt2870sta の中身を掘ってて力尽きた模様です。何故か日報に残されたソレをこちらに纏めてみます。
とりあえず rt2870 の中身からスタートという事で初期化な手続きが rtusb_init な模様。os/linux/us_main_dev.c にて定義。
INT __init rtusb_init(void) { printk("rtusb init --->\n"); return usb_register(&rtusb_driver); }
usb_register 手続きの定義は rt2870 なツリーの中には無い。カーネルツリーの include/linux/usb.h にて以下。
static inline int usb_register(struct usb_driver *driver) { return usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME); }
日報なログにはパスが書いてない。相当へろへろだった事が伺えます。で、usb_register_driver 手続きですが、drivers/usb/core/driver.c な模様。
int usb_register_driver(struct usb_driver *new_driver, struct module *owner, const char *mod_name) { int retval = 0; if (usb_disabled()) return -ENODEV; new_driver->drvwrap.for_devices = 0; new_driver->drvwrap.driver.name = (char *) new_driver->name; new_driver->drvwrap.driver.bus = &usb_bus_type; new_driver->drvwrap.driver.probe = usb_probe_interface; new_driver->drvwrap.driver.remove = usb_unbind_interface; new_driver->drvwrap.driver.owner = owner; new_driver->drvwrap.driver.mod_name = mod_name; spin_lock_init(&new_driver->dynids.lock); INIT_LIST_HEAD(&new_driver->dynids.list); retval = driver_register(&new_driver->drvwrap.driver); if (!retval) { pr_info("%s: registered new interface driver %s\n", usbcore_name, new_driver->name); usbfs_update_special(); usb_create_newid_file(new_driver); } else { printk(KERN_ERR "%s: error %d registering interface " " driver %s\n", usbcore_name, retval, new_driver->name); } return retval; }
で、driver_register は何処、というあたりで倒れた模様です。ちなみに driver_register 手続きですが、driver/base/driver.c にて定義されておりますな。そこから呼び出されている手続きの内、クサそうなのは
- driver_find 手続き (ではないかも
- bus_add_driver 手続き
- driver_add_groups 手続き
なんですが、端末で探すの疲れる。gtags するのは微妙だしなぁ。bus_add_driver にアタリを付けて掘削。定義が以下です。ちょっと長いので小刻みに引用します。
/** * bus_add_driver - Add a driver to the bus. * @drv: driver. */ int bus_add_driver(struct device_driver *drv) { struct bus_type *bus; struct driver_private *priv; int error = 0; bus = bus_get(drv->bus); if (!bus) return -EINVAL; pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name); priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { error = -ENOMEM; goto out_put_bus; } klist_init(&priv->klist_devices, NULL, NULL); priv->driver = drv; drv->p = priv; priv->kobj.kset = bus->p->drivers_kset; error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL, "%s", drv->name); if (error) goto out_unregister;
kobject_init_and_add とか怪しげ。driver 配下で find|grep したら定義が無い。定義自体は lib/kobject.c で以下。
/** * kobject_init_and_add - initialize a kobject structure and add it to the kobject hierarchy * @kobj: pointer to the kobject to initialize * @ktype: pointer to the ktype for this kobject. * @parent: pointer to the parent of this kobject. * @fmt: the name of the kobject. * * This function combines the call to kobject_init() and * kobject_add(). The same type of error handling after a call to * kobject_add() and kobject lifetime rules are the same here. */ int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, struct kobject *parent, const char *fmt, ...) { va_list args; int retval; kobject_init(kobj, ktype); va_start(args, fmt); retval = kobject_add_varg(kobj, parent, fmt, args); va_end(args); return retval; } EXPORT_SYMBOL_GPL(kobject_init_and_add);
そっから先を見てみたんですが、class 云々は無いのかどうなのか。gdgd のまま勉強会が始まってしまうので、ここでエントリ投入。