8139too.c (2)
まずはデータ構造を、という事で以下のエントリポイントにて
static int __init rtl8139_init_module (void) { /* when we're a module, we always print a version message, * even if no 8139 board is found. */ #ifdef MODULE printk (KERN_INFO RTL8139_DRIVER_NAME "\n"); #endif return pci_module_init (&rtl8139_pci_driver); }
pci_module_init (実体は pci_register_driver) に渡している rtl8139_pci_driver という変数の定義を見てみる。
定義は上記の手続きの直上で以下。
static struct pci_driver rtl8139_pci_driver = { .name = DRV_NAME, .id_table = rtl8139_pci_tbl, .probe = rtl8139_init_one, .remove = __devexit_p(rtl8139_remove_one), #ifdef CONFIG_PM .suspend = rtl8139_suspend, .resume = rtl8139_resume, #endif /* CONFIG_PM */ };
ええと、pci_driver 構造体の定義を掘ってみるに、include/linux/pci.h で以下。
struct pci_driver { struct list_head node; char *name; struct module *owner; const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */ int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */ void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ int (*suspend) (struct pci_dev *dev, u32 state); /* Device suspended */ int (*resume) (struct pci_dev *dev); /* Device woken up */ int (*enable_wake) (struct pci_dev *dev, u32 state, int enable); /* Enable wake event */ struct device_driver driver; struct pci_dynids dynids; };
詳解 Linux カーネルによれば
通常、デバイスドライバオブジェクトは、大きなディスクリプタに静的に組込まれています。PCI デバイスドライバの場合は、pci_driver 構造体で表します。
とありますな。ちなみに device_driver 構造体の定義が以下。
struct device_driver { char * name; struct bus_type * bus; struct semaphore unload_sem; struct kobject kobj; struct list_head devices; struct module * owner; int (*probe) (struct device * dev); int (*remove) (struct device * dev); void (*shutdown) (struct device * dev); int (*suspend) (struct device * dev, u32 state, u32 level); int (*resume) (struct device * dev, u32 level); };
似た名前の関数ポインタな属性があるんですが同一な型は無い。あと上記構造体の属性に pci_register_driver 関数で値をセットしてますが
drv->driver.name = drv->name; drv->driver.bus = &pci_bus_type; drv->driver.probe = pci_device_probe; drv->driver.remove = pci_device_remove; drv->driver.owner = drv->owner; drv->driver.kobj.ktype = &pci_driver_kobj_type;
という事で drv な属性がそのまま代入されてるのはてっぺんだけ。ちなみに probe と remove な属性に代入されてる手続きポインタの実体ですが、pri-driver.c にて定義されてます。中身を掘るのは別途で。
むむ
device_driver 構造体と pci_driver 構造体の関係が直感的に理解できんな。参考書の記述によれば
- device_driver 構造体の probe はバスのデバイスドライバが処理可能なデバイスを見つけたときに呼ばれる
- pci_driver 構造体の probe は PCI デバイスの検出時に呼ばれる
との事。このあたり、スルーも必要かなぁ。