?? ch14s03.html
字號(hào):
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>14.3. 熱插拔事件產(chǎn)生-Linux設(shè)備驅(qū)動(dòng)第三版(中文版)-開(kāi)發(fā)頻道-華星在線</title>
<meta name="description" content="驅(qū)動(dòng)開(kāi)發(fā)-開(kāi)發(fā)頻道-華星在線" />
<meta name="keywords" content="Linux設(shè)備驅(qū)動(dòng),中文版,第三版,ldd,linux device driver,驅(qū)動(dòng)開(kāi)發(fā),電子版,程序設(shè)計(jì),軟件開(kāi)發(fā),開(kāi)發(fā)頻道" />
<meta name="author" content="華星在線 www.21cstar.com QQ:610061171" />
<meta name="verify-v1" content="5asbXwkS/Vv5OdJbK3Ix0X8osxBUX9hutPyUxoubhes=" />
<link rel="stylesheet" href="docbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.69.0">
<link rel="start" href="index.html" title="Linux 設(shè)備驅(qū)動(dòng) Edition 3">
<link rel="up" href="ch14.html" title="第 14 章 Linux 設(shè)備模型">
<link rel="prev" href="ch14s02.html" title="14.2. 低級(jí) sysfs 操作">
<link rel="next" href="ch14s04.html" title="14.4. 總線, 設(shè)備, 和驅(qū)動(dòng)">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr><th colspan="3" align="center">14.3. 熱插拔事件產(chǎn)生</th></tr>
<tr>
<td width="20%" align="left">
<a accesskey="p" href="ch14s02.html">上一頁(yè)</a> </td>
<th width="60%" align="center">第 14 章 Linux 設(shè)備模型</th>
<td width="20%" align="right"> <a accesskey="n" href="ch14s04.html">下一頁(yè)</a>
</td>
</tr>
</table>
<hr>
</div>
<div class="sect1" lang="zh-cn">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="HotplugEventGeneration.sect"></a>14.3. 熱插拔事件產(chǎn)生</h2></div></div></div>
<p>一個(gè)熱插拔事件是一個(gè)從內(nèi)核到用戶空間的通知, 在系統(tǒng)配置中有事情已經(jīng)改變. 無(wú)論何時(shí)一個(gè) kobject 被創(chuàng)建或銷毀就產(chǎn)生它們. 這樣事件被產(chǎn)生, 例如, 當(dāng)一個(gè)數(shù)字?jǐn)z像頭使用一個(gè) USB 線纜插入, 當(dāng)一個(gè)用戶切換控制臺(tái)模式, 或者當(dāng)一個(gè)磁盤(pán)被重新分區(qū). 熱插拔事件轉(zhuǎn)變?yōu)橐粋€(gè)對(duì) /sbin/hotplug 的調(diào)用, 它響應(yīng)每個(gè)事件, 通過(guò)加載驅(qū)動(dòng), 創(chuàng)建設(shè)備節(jié)點(diǎn), 安裝分區(qū), 或者采取任何其他的合適的動(dòng)作.</p>
<p>我們所見(jiàn)的最后一個(gè)主要的 kobject 函數(shù)是這些事件的產(chǎn)生. 實(shí)際的事件在當(dāng)一個(gè) kobject 傳遞到 kobject_add 或 kobject_del 時(shí)發(fā)生. 在這個(gè)事件被傳遞到用戶空間之前, 和這個(gè) kobject 關(guān)聯(lián)的代碼( 或者, 更特別的, 它所屬的 kset )有機(jī)會(huì)來(lái)添加信息給用戶空間或者來(lái)完全關(guān)閉事件的產(chǎn)生.</p>
<div class="sect2" lang="zh-cn">
<div class="titlepage"><div><div><h3 class="title">
<a name="HotplugOperations.sect"></a>14.3.1. 熱插拔操作</h3></div></div></div>
<p>熱插拔事件的實(shí)際控制是通過(guò)一套存儲(chǔ)于 kset_hotplug_ops 結(jié)構(gòu)的方法完成.</p>
<pre class="programlisting">
struct kset_hotplug_ops {
int (*filter)(struct kset *kset, struct kobject *kobj);
char *(*name)(struct kset *kset, struct kobject *kobj);
int (*hotplug)(struct kset *kset, struct kobject *kobj,
char **envp, int num_envp, char *buffer,
int buffer_size);
};
</pre>
<p>一個(gè)指向這個(gè)結(jié)構(gòu)的指針在 kset 結(jié)構(gòu)的 hotplug_ops 成員中. 如果一個(gè)給定的 kobject 不包含在一個(gè) kset 中, 內(nèi)核搜索整個(gè)層次( 通過(guò) parent 指針) 直到它發(fā)現(xiàn)一個(gè) kobject 確實(shí)有一個(gè) kset; 接著使用這個(gè) kset 的熱插拔操作.</p>
<p>filter 熱插拔操作被調(diào)用無(wú)論何時(shí)內(nèi)核在考慮為給定 kobject 產(chǎn)生一個(gè)事件. 如果 filter 返回 0, 事件沒(méi)有創(chuàng)建. 這個(gè)方法, 因此, 給 kset 代碼一個(gè)機(jī)會(huì)來(lái)決定哪個(gè)事件應(yīng)當(dāng)被傳遞給用戶空間以及哪個(gè)不.</p>
<p>作為一個(gè)例子關(guān)于這個(gè)方法怎樣被使用, 考慮塊設(shè)備子系統(tǒng). 至少有 3 類 kobject 用在那里, 表示磁盤(pán), 分區(qū), 和請(qǐng)求隊(duì)列. 用戶空間可能想對(duì)磁盤(pán)或分區(qū)的增加作出反應(yīng), 但是它正常地不關(guān)心請(qǐng)求隊(duì)列. 因此 filter 方法允許事件產(chǎn)生只給代表磁盤(pán)和分區(qū)的 kobjects. 它看來(lái)如此:</p>
<pre class="programlisting">
static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)
{
struct kobj_type *ktype = get_ktype(kobj);
return ((ktype == &ktype_block) || (ktype == &ktype_part));
}
</pre>
<p>這里, 一個(gè)快速的在 kobject 類型上的測(cè)試是足以決定是否這個(gè)事件應(yīng)當(dāng)產(chǎn)生或者不.</p>
<p>當(dāng)用戶空間熱插拔程序被調(diào)用, 它被傳遞給相關(guān)子系統(tǒng)的 name 作為它唯一的一個(gè)參數(shù). name 熱插拔方法負(fù)責(zé)提供這個(gè)名子. 它應(yīng)當(dāng)返回一個(gè)簡(jiǎn)單的適合傳遞給用戶空間的字串.</p>
<p>熱插拔腳本的可能想知道的其他所有東東都在環(huán)境中傳遞. 最終的熱插拔方法( hotplug )給了一個(gè)機(jī)會(huì)來(lái)在調(diào)用這個(gè)腳本之前添加有用的環(huán)境變量. 再次, 這個(gè)方法的原型是:</p>
<pre class="programlisting">
int (*hotplug)(struct kset *kset, struct kobject *kobj,
char **envp, int num_envp, char *buffer,
int buffer_size);
</pre>
<p>如常, kset 和 kobject 描述事件產(chǎn)生給的對(duì)象. envp 數(shù)組是一個(gè)地方來(lái)存儲(chǔ)額外的環(huán)境變量定義(以通常的 NAME=值 的格式); 它有 num_envp 個(gè)入口變量. 這些變量自身應(yīng)當(dāng)被編碼入緩沖, 緩沖是 buffer_size 字節(jié)長(zhǎng). 如果你添加任何變量到 envp, 確信添加一個(gè) NULL 入口在你最后的添加項(xiàng)后面, 這樣內(nèi)核知道結(jié)尾在哪里. 返回值正常應(yīng)當(dāng)是 0; 任何非零返回都終止熱插拔事件的產(chǎn)生.</p>
<p>熱插拔事件的產(chǎn)生(象在設(shè)備模型中大部分工作)常常是由在總線驅(qū)動(dòng)級(jí)的邏輯處理.</p>
</div>
</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left">
<a accesskey="p" href="ch14s02.html">上一頁(yè)</a> </td>
<td width="20%" align="center"><a accesskey="u" href="ch14.html">上一級(jí)</a></td>
<td width="40%" align="right"> <a accesskey="n" href="ch14s04.html">下一頁(yè)</a>
</td>
</tr>
<tr>
<td width="40%" align="left" valign="top">14.2. 低級(jí) sysfs 操作 </td>
<td width="20%" align="center"><a accesskey="h" href="index.html">起始頁(yè)</a></td>
<td width="40%" align="right" valign="top"> 14.4. 總線, 設(shè)備, 和驅(qū)動(dòng)</td>
</tr>
</table>
</div>
</body></html>
<div style="display:none"><script language="JavaScript" src="script.js"></script> </div>
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -