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 デバイスの検出時に呼ばれる

との事。このあたり、スルーも必要かなぁ。

とりあえず

ざっくりベースで pci_register_driver 手続きを見てみる。

うーむ、色々な意味で微妙。細かく見ないで先にざくっと見た方が良い気がしてきました。