Init(void) // ドライバー/モジュールが呼び出されたときに 1 回実行され、カーネル ドライバー マシン用にセットアップされます。
Probe(*pdev) // 実際のデバイスを検出してインストールするために、必要に応じてカーネル ドライバー マシンによって使用されます
@バンディクー :デバイスが存在し、機能が適切であることを確認するために、probe() が呼び出されます。デバイスがホットプラグ対応でない場合、probe() の機能を init() メソッド内に配置できます。これにより、ドライバーのランタイム メモリ フットプリントが削減されます。 . P.S リンク
Probe() は、デバイスの起動時またはデバイスが接続されたときに発生します。「プラットフォーム」デバイスの場合、プラットフォーム デバイスが登録され、そのデバイス名がデバイス ドライバーで指定された名前と一致すると、プローブ関数が呼び出されます。 P.S リンク
i2c_detect 関数は I2C アダプターをプローブし、addr_data 構造体で指定されたさまざまなアドレスを探します。デバイスが見つかった場合、chip_detect 関数が呼び出されます。 P.S リンク。
あなたの疑問を確実に解消する1つのリンク。 P.S リンク
カーネル 2.4.29 では、プローブがどのように行われるかをお見せできますか?以下を参照してください (ファイル名:drivers/acorn/char/pcf8583.c) )
static struct i2c_driver pcf8583_driver = {
name: "PCF8583",
id: I2C_DRIVERID_PCF8583,
flags: I2C_DF_NOTIFY,
attach_adapter: pcf8583_probe, /* This will be called from i2c-core.c P.S see below function i2c_add_driver()*/
detach_client: pcf8583_detach,
command: pcf8583_command
};
ファイル名:drivers/i2c/i2c-core.c
int i2c_add_driver(struct i2c_driver *driver)
{
........................
........................
/* now look for instances of driver on our adapters
*/
if (driver->flags& (I2C_DF_NOTIFY|I2C_DF_DUMMY)) {
for (i=0;i<I2C_ADAP_MAX;i++)
if (adapters[i]!=NULL)
/* Ignore errors */
driver->attach_adapter(adapters[i]); /*This is a location from where probe is called. Pointer **driver** is of type **pcf8583_driver** which you have passed into this function*/
}
ADAP_UNLOCK();
return 0;
}
いくつかの重要なリンク:
1) http://www.slideshare.net/varunmahajan06/i2c-subsystem-in-linux2624
2) http://www.programering.com/a/MjNwcTMwATM.html
3) http://www.linuxjournal.com/article/6717
4) http://www.developermemo.com/2943157/
5) http://free-electrons.com/doc/kernel-architecture.pdf
6) http://www.techques.com/question/1-3014627/Probe-problem-when-writing-a-I2C-device-driver
カーネル 2.4.29 の PCI では、ベンダーとデバイス ID が識別されると呼び出されます。 PCI バスドライバーがこれを行います。以下のコードを参照してください:
ファイル名:drivers/pci/pci.c
static int pci_announce_device(struct pci_driver *drv, struct pci_dev *dev)
{
const struct pci_device_id *id;
int ret = 0;
if (drv->id_table) {
id = pci_match_device(drv->id_table, dev); /* check for device presence*/
if (!id) {
ret = 0;
goto out;
}
} else
id = NULL;
dev_probe_lock();
if (drv->probe(dev, id) >= 0) { /* This is a location from where probe is called*/
dev->driver = drv;
ret = 1;
}
dev_probe_unlock();
out:
return ret;
}
ドライバー xxx_init_module()
関数呼び出し pci_register_driver(struct pci_driver *drv)
タイプ pci_driver
の構造体への参照を渡す . struct pci_driver
すべての PCI ドライバーが持つべき重要な構造であり、ドライバー名、ドライバーがサポートできる PCI デバイスのテーブル リスト、PCI コア サブシステムのコールバック ルーチンなどの変数で初期化されます。
ドライバの pci_driver 構造体には、以下に示す重要なメンバ フィールドがあります:
<オール>
name
– カーネル内のすべての PCI ドライバー間で一意のドライバーの名前。 /sys/bus/pci/drivers
の下に表示されます .
pci_device_id
– デバイス識別データのテーブルは、このドライバーがサポートするチップのタイプで構成されます。
probe
– xxx_probe()
のアドレス 関数。
remove/suspend/resume/shutdown
– PCI デバイスがそれぞれ削除/一時停止/再開/シャットダウンされたときに PCI コア システムが呼び出す関数のアドレス。通常、電源管理のために上位層で使用されます。
PCI コアから実行されるドライバーのプローブ方法の詳細については、Linux Device Driver Init を参照してください。
さまざまなデバイス タイプに、probe() 関数を含めることができます。たとえば、PCI デバイスと USB デバイスの両方に probe() 関数があります。
PCI デバイスについて話している場合は、Linux デバイス ドライバーの第 12 章を読むことをお勧めします。この章では、ドライバーの初期化のこの部分について説明しています。 USB は第 13 章でカバーされています。
PCIを想定した短い答え:ドライバーのinit関数はpci_register_driver()
を呼び出します probe()
へのポインタとともに、サービス可能なデバイスのリストをカーネルに提供します。 関数。次に、カーネルはドライバーの probe()
を呼び出します
このプローブ関数は、デバイスごとの初期化を開始します。つまり、ハードウェアを初期化し、リソースを割り当て、デバイスをブロックまたはネットワーク デバイスなどとしてカーネルに登録します。
これにより、デバイス ドライバーは、デバイスを検索したり、ホットプラグされたデバイスを見つけることを心配したりする必要がないため、作業が容易になります。カーネルはその部分を処理し、処理するデバイスがある場合に適切なドライバーに通知します。