aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ja_JP/HOWTO84
-rw-r--r--Documentation/kernel-parameters.txt4
-rw-r--r--Documentation/kobject.txt22
-rw-r--r--arch/ia64/sn/kernel/tiocx.c3
-rw-r--r--arch/powerpc/kernel/of_device.c37
-rw-r--r--arch/powerpc/kernel/vio.c16
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c9
-rw-r--r--block/bsg.c5
-rw-r--r--block/elevator.c2
-rw-r--r--block/genhd.c35
-rw-r--r--block/ll_rw_blk.c2
-rw-r--r--drivers/acpi/bus.c2
-rw-r--r--drivers/acpi/scan.c16
-rw-r--r--drivers/acpi/video.c4
-rw-r--r--drivers/amba/bus.c9
-rw-r--r--drivers/base/Kconfig8
-rw-r--r--drivers/base/base.h2
-rw-r--r--drivers/base/bus.c116
-rw-r--r--drivers/base/class.c60
-rw-r--r--drivers/base/core.c108
-rw-r--r--drivers/base/firmware_class.c14
-rw-r--r--drivers/base/memory.c3
-rw-r--r--drivers/base/platform.c26
-rw-r--r--drivers/base/power/Makefile2
-rw-r--r--drivers/base/power/main.c344
-rw-r--r--drivers/base/power/power.h38
-rw-r--r--drivers/base/power/resume.c149
-rw-r--r--drivers/base/power/suspend.c210
-rw-r--r--drivers/base/sys.c73
-rw-r--r--drivers/char/dsp56k.c4
-rw-r--r--drivers/char/ip2/ip2main.c12
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c6
-rw-r--r--drivers/char/istallion.c8
-rw-r--r--drivers/char/lp.c5
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c5
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c5
-rw-r--r--drivers/char/pty.c9
-rw-r--r--drivers/char/raw.c5
-rw-r--r--drivers/char/snsc.c3
-rw-r--r--drivers/char/stallion.c7
-rw-r--r--drivers/char/tipar.c6
-rw-r--r--drivers/char/viotape.c10
-rw-r--r--drivers/cpufreq/cpufreq.c2
-rw-r--r--drivers/edac/edac_mc_sysfs.c3
-rw-r--r--drivers/eisa/eisa-bus.c9
-rw-r--r--drivers/firewire/fw-device.c11
-rw-r--r--drivers/firmware/dmi-id.c62
-rw-r--r--drivers/firmware/edd.c4
-rw-r--r--drivers/firmware/efivars.c4
-rw-r--r--drivers/i2c/i2c-core.c8
-rw-r--r--drivers/ide/ide.c17
-rw-r--r--drivers/ieee1394/nodemgr.c17
-rw-r--r--drivers/infiniband/core/sysfs.c9
-rw-r--r--drivers/input/input.c62
-rw-r--r--drivers/input/misc/pcspkr.c1
-rw-r--r--drivers/input/serio/serio.c11
-rw-r--r--drivers/md/md.c3
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c5
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c4
-rw-r--r--drivers/misc/tifm_core.c9
-rw-r--r--drivers/mmc/core/bus.c21
-rw-r--r--drivers/net/ibmveth.c2
-rw-r--r--drivers/pci/hotplug.c28
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c60
-rw-r--r--drivers/pci/hotplug/rpadlpar_sysfs.c6
-rw-r--r--drivers/pci/pci-driver.c3
-rw-r--r--drivers/pci/pci.h3
-rw-r--r--drivers/pci/setup-irq.c2
-rw-r--r--drivers/pcmcia/cs.c10
-rw-r--r--drivers/pcmcia/ds.c26
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c2
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c2
-rw-r--r--drivers/power/power_supply.h3
-rw-r--r--drivers/power/power_supply_sysfs.c17
-rw-r--r--drivers/s390/cio/ccwgroup.c3
-rw-r--r--drivers/s390/cio/device.c25
-rw-r--r--drivers/s390/crypto/ap_bus.c14
-rw-r--r--drivers/scsi/scsi_sysfs.c9
-rw-r--r--drivers/spi/spi.c7
-rw-r--r--drivers/usb/core/devio.c6
-rw-r--r--drivers/usb/core/driver.c29
-rw-r--r--drivers/usb/core/message.c28
-rw-r--r--drivers/video/output.c29
-rw-r--r--drivers/w1/w1.c19
-rw-r--r--fs/debugfs/file.c36
-rw-r--r--fs/dlm/lockspace.c2
-rw-r--r--fs/gfs2/locking/dlm/sysfs.c2
-rw-r--r--fs/gfs2/sys.c2
-rw-r--r--fs/ocfs2/cluster/masklog.c3
-rw-r--r--fs/partitions/check.c12
-rw-r--r--fs/sysfs/bin.c36
-rw-r--r--fs/sysfs/dir.c754
-rw-r--r--fs/sysfs/file.c248
-rw-r--r--fs/sysfs/group.c2
-rw-r--r--fs/sysfs/inode.c103
-rw-r--r--fs/sysfs/mount.c26
-rw-r--r--fs/sysfs/symlink.c34
-rw-r--r--fs/sysfs/sysfs.h184
-rw-r--r--include/asm-powerpc/of_device.h2
-rw-r--r--include/linux/debugfs.h27
-rw-r--r--include/linux/device.h17
-rw-r--r--include/linux/kobject.h125
-rw-r--r--include/linux/platform_device.h7
-rw-r--r--include/linux/sysfs.h147
-rw-r--r--include/linux/tty.h1
-rw-r--r--include/linux/video_output.h4
-rw-r--r--lib/Makefile3
-rw-r--r--lib/kobject.c135
-rw-r--r--lib/kobject_uevent.c216
-rw-r--r--net/atm/atm_sysfs.c7
-rw-r--r--net/bridge/br_sysfs_br.c2
-rw-r--r--net/core/net-sysfs.c14
-rw-r--r--net/wireless/sysfs.c3
-rw-r--r--sound/aoa/soundbus/core.c33
114 files changed, 1777 insertions, 2493 deletions
diff --git a/Documentation/ja_JP/HOWTO b/Documentation/ja_JP/HOWTO
index 9f08dab1e75b..d9d832c010ef 100644
--- a/Documentation/ja_JP/HOWTO
+++ b/Documentation/ja_JP/HOWTO
@@ -1,4 +1,4 @@
1NOTE: 1NOTE:
2This is a version of Documentation/HOWTO translated into Japanese. 2This is a version of Documentation/HOWTO translated into Japanese.
3This document is maintained by Tsugikazu Shibata <tshibata@ab.jp.nec.com> 3This document is maintained by Tsugikazu Shibata <tshibata@ab.jp.nec.com>
4and the JF Project team <www.linux.or.jp/JF>. 4and the JF Project team <www.linux.or.jp/JF>.
@@ -11,14 +11,14 @@ for non English (read: Japanese) speakers and is not intended as a
11fork. So if you have any comments or updates for this file, please try 11fork. So if you have any comments or updates for this file, please try
12to update the original English file first. 12to update the original English file first.
13 13
14Last Updated: 2007/07/18 14Last Updated: 2007/09/23
15================================== 15==================================
16これは、 16これは、
17linux-2.6.22/Documentation/HOWTO 17linux-2.6.23/Documentation/HOWTO
18の和訳です。 18の和訳です。
19 19
20翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ > 20翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ >
21翻訳日: 2007/07/16 21翻訳日: 2007/09/19
22翻訳者: Tsugikazu Shibata <tshibata at ab dot jp dot nec dot com> 22翻訳者: Tsugikazu Shibata <tshibata at ab dot jp dot nec dot com>
23校正者: 松倉さん <nbh--mats at nifty dot com> 23校正者: 松倉さん <nbh--mats at nifty dot com>
24 小林 雅典さん (Masanori Kobayasi) <zap03216 at nifty dot ne dot jp> 24 小林 雅典さん (Masanori Kobayasi) <zap03216 at nifty dot ne dot jp>
@@ -27,6 +27,7 @@ linux-2.6.22/Documentation/HOWTO
27 野口さん (Kenji Noguchi) <tokyo246 at gmail dot com> 27 野口さん (Kenji Noguchi) <tokyo246 at gmail dot com>
28 河内さん (Takayoshi Kochi) <t-kochi at bq dot jp dot nec dot com> 28 河内さん (Takayoshi Kochi) <t-kochi at bq dot jp dot nec dot com>
29 岩本さん (iwamoto) <iwamoto.kn at ncos dot nec dot co dot jp> 29 岩本さん (iwamoto) <iwamoto.kn at ncos dot nec dot co dot jp>
30 内田さん (Satoshi Uchida) <s-uchida at ap dot jp dot nec dot com>
30================================== 31==================================
31 32
32Linux カーネル開発のやり方 33Linux カーネル開発のやり方
@@ -40,7 +41,7 @@ Linux カーネル開発コミュニティと共に活動するやり方を学
40手助けになります。 41手助けになります。
41 42
42もし、このドキュメントのどこかが古くなっていた場合には、このドキュメン 43もし、このドキュメントのどこかが古くなっていた場合には、このドキュメン
43トの最後にリストしたメンテナパッチを送ってください。 44トの最後にリストしたメンテナにパッチを送ってください。
44 45
45はじめに 46はじめに
46--------- 47---------
@@ -59,7 +60,7 @@ Linux カーネル開発コミュニティと共に活動するやり方を学
59ネル開発者には必要です。アーキテクチャ向けの低レベル部分の開発をするの 60ネル開発者には必要です。アーキテクチャ向けの低レベル部分の開発をするの
60でなければ、(どんなアーキテクチャでも)アセンブリ(訳注: 言語)は必要あり 61でなければ、(どんなアーキテクチャでも)アセンブリ(訳注: 言語)は必要あり
61ません。以下の本は、C 言語の十分な知識や何年もの経験に取って代わるもの 62ません。以下の本は、C 言語の十分な知識や何年もの経験に取って代わるもの
62ではありませんが、少なくともリファレンスとしてはい本です。 63ではありませんが、少なくともリファレンスとしてはい本です。
63 - "The C Programming Language" by Kernighan and Ritchie [Prentice Hall] 64 - "The C Programming Language" by Kernighan and Ritchie [Prentice Hall]
64 -『プログラミング言語C第2版』(B.W. カーニハン/D.M. リッチー著 石田晴久訳) [共立出版] 65 -『プログラミング言語C第2版』(B.W. カーニハン/D.M. リッチー著 石田晴久訳) [共立出版]
65 - "Practical C Programming" by Steve Oualline [O'Reilly] 66 - "Practical C Programming" by Steve Oualline [O'Reilly]
@@ -76,7 +77,7 @@ Linux カーネル開発コミュニティと共に活動するやり方を学
76ときどき、カーネルがツールチェインや C 言語拡張に置いている前提がどう 77ときどき、カーネルがツールチェインや C 言語拡張に置いている前提がどう
77なっているのかわかりにくいことがあり、また、残念なことに決定的なリファ 78なっているのかわかりにくいことがあり、また、残念なことに決定的なリファ
78レンスは存在しません。情報を得るには、gcc の info ページ( info gcc )を 79レンスは存在しません。情報を得るには、gcc の info ページ( info gcc )を
79ください。 80てください。
80 81
81あなたは既存の開発コミュニティと一緒に作業する方法を学ぼうとしているこ 82あなたは既存の開発コミュニティと一緒に作業する方法を学ぼうとしているこ
82とに留意してください。そのコミュニティは、コーディング、スタイル、 83とに留意してください。そのコミュニティは、コーディング、スタイル、
@@ -92,7 +93,7 @@ Linux カーネル開発コミュニティと共に活動するやり方を学
92 93
93Linux カーネルのソースコードは GPL ライセンスの下でリリースされていま 94Linux カーネルのソースコードは GPL ライセンスの下でリリースされていま
94す。ライセンスの詳細については、ソースツリーのメインディレクトリに存在 95す。ライセンスの詳細については、ソースツリーのメインディレクトリに存在
95する、COPYING のファイルをください。もしライセンスについてさらに質 96する、COPYING のファイルをてください。もしライセンスについてさらに質
96問があれば、Linux Kernel メーリングリストに質問するのではなく、どうぞ 97問があれば、Linux Kernel メーリングリストに質問するのではなく、どうぞ
97法律家に相談してください。メーリングリストの人達は法律家ではなく、法的 98法律家に相談してください。メーリングリストの人達は法律家ではなく、法的
98問題については彼らの声明はあてにするべきではありません。 99問題については彼らの声明はあてにするべきではありません。
@@ -109,7 +110,8 @@ Linux カーネルソースツリーは幅広い範囲のドキュメントを
109新しいドキュメントファイルも追加することを勧めます。 110新しいドキュメントファイルも追加することを勧めます。
110カーネルの変更が、カーネルがユーザ空間に公開しているインターフェイスの 111カーネルの変更が、カーネルがユーザ空間に公開しているインターフェイスの
111変更を引き起こす場合、その変更を説明するマニュアルページのパッチや情報 112変更を引き起こす場合、その変更を説明するマニュアルページのパッチや情報
112をマニュアルページのメンテナ mtk-manpages@gmx.net に送ることを勧めます。 113をマニュアルページのメンテナ mtk-manpages@gmx.net に送ることを勧めま
114す。
113 115
114以下はカーネルソースツリーに含まれている読んでおくべきファイルの一覧で 116以下はカーネルソースツリーに含まれている読んでおくべきファイルの一覧で
115す- 117す-
@@ -117,7 +119,7 @@ Linux カーネルソースツリーは幅広い範囲のドキュメントを
117 README 119 README
118 このファイルは Linuxカーネルの簡単な背景とカーネルを設定(訳注 120 このファイルは Linuxカーネルの簡単な背景とカーネルを設定(訳注
119 configure )し、生成(訳注 build )するために必要なことは何かが書かれ 121 configure )し、生成(訳注 build )するために必要なことは何かが書かれ
120 ています。カーネルに関して初めての人はここからスタートすると 122 ています。カーネルに関して初めての人はここからスタートするといで
121 しょう。 123 しょう。
122 124
123 Documentation/Changes 125 Documentation/Changes
@@ -128,7 +130,7 @@ Linux カーネルソースツリーは幅広い範囲のドキュメントを
128 Documentation/CodingStyle 130 Documentation/CodingStyle
129 これは Linux カーネルのコーディングスタイルと背景にある理由を記述 131 これは Linux カーネルのコーディングスタイルと背景にある理由を記述
130 しています。全ての新しいコードはこのドキュメントにあるガイドライン 132 しています。全ての新しいコードはこのドキュメントにあるガイドライン
131 に従っていることを期待されています。大部分のメンテナこれらのルー 133 に従っていることを期待されています。大部分のメンテナはこれらのルー
132 ルに従っているものだけを受け付け、多くの人は正しいスタイルのコード 134 ルに従っているものだけを受け付け、多くの人は正しいスタイルのコード
133 だけをレビューします。 135 だけをレビューします。
134 136
@@ -168,16 +170,16 @@ Linux カーネルソースツリーは幅広い範囲のドキュメントを
168 支援してください。 170 支援してください。
169 171
170 Documentation/ManagementStyle 172 Documentation/ManagementStyle
171 このドキュメントは Linux カーネルのメンテナ達がどう行動するか、 173 このドキュメントは Linux カーネルのメンテナ達がどう行動するか、
172 彼らの手法の背景にある共有されている精神について記述しています。こ 174 彼らの手法の背景にある共有されている精神について記述しています。こ
173 れはカーネル開発の初心者なら(もしくは、単に興味があるだけの人でも) 175 れはカーネル開発の初心者なら(もしくは、単に興味があるだけの人でも)
174 重要です。なぜならこのドキュメントは、カーネルメンテナ達の独特な 176 重要です。なぜならこのドキュメントは、カーネルメンテナ達の独特な
175 行動についての多くの誤解や混乱を解消するからです。 177 行動についての多くの誤解や混乱を解消するからです。
176 178
177 Documentation/stable_kernel_rules.txt 179 Documentation/stable_kernel_rules.txt
178 このファイルはどのように stable カーネルのリリースが行われるかのルー 180 このファイルはどのように stable カーネルのリリースが行われるかのルー
179 ルが記述されています。そしてこれらのリリースの中のどこかで変更を取 181 ルが記述されています。そしてこれらのリリースの中のどこかで変更を取
180 り入れてもらいたい場合に何をすればいが示されています。 182 り入れてもらいたい場合に何をすればいかが示されています。
181 183
182 Documentation/kernel-docs.txt 184 Documentation/kernel-docs.txt
183  カーネル開発に付随する外部ドキュメントのリストです。もしあなたが 185  カーネル開発に付随する外部ドキュメントのリストです。もしあなたが
@@ -218,9 +220,9 @@ web サイトには、コードの構成、サブシステム、現在存在す
218ここには、また、カーネルのコンパイルのやり方やパッチの当て方などの間接 220ここには、また、カーネルのコンパイルのやり方やパッチの当て方などの間接
219的な基本情報も記述されています。 221的な基本情報も記述されています。
220 222
221あなたがどこからスタートしてかわからないが、Linux カーネル開発コミュ 223あなたがどこからスタートしていかわからないが、Linux カーネル開発コミュ
222ニティに参加して何かすることをさがしている場合には、Linux kernel 224ニティに参加して何かすることをさがしている場合には、Linux kernel
223Janitor's プロジェクトにいけばでしょう - 225Janitor's プロジェクトにいけばいでしょう -
224 http://janitor.kernelnewbies.org/ 226 http://janitor.kernelnewbies.org/
225ここはそのようなスタートをするのにうってつけの場所です。ここには、 227ここはそのようなスタートをするのにうってつけの場所です。ここには、
226Linux カーネルソースツリーの中に含まれる、きれいにし、修正しなければな 228Linux カーネルソースツリーの中に含まれる、きれいにし、修正しなければな
@@ -243,7 +245,7 @@ Linux カーネルソースツリーの中に含まれる、きれいにし、
243自己参照方式で、索引がついた web 形式で、ソースコードを参照することが 245自己参照方式で、索引がついた web 形式で、ソースコードを参照することが
244できます。この最新の素晴しいカーネルコードのリポジトリは以下で見つかり 246できます。この最新の素晴しいカーネルコードのリポジトリは以下で見つかり
245ます- 247ます-
246 http://sosdg.org/~coywolf/lxr/ 248 http://sosdg.org/~qiyong/lxr/
247 249
248開発プロセス 250開発プロセス
249----------------------- 251-----------------------
@@ -265,9 +267,9 @@ Linux カーネルの開発プロセスは現在幾つかの異なるメイン
265以下のとおり- 267以下のとおり-
266 268
267 - 新しいカーネルがリリースされた直後に、2週間の特別期間が設けられ、 269 - 新しいカーネルがリリースされた直後に、2週間の特別期間が設けられ、
268 この期間中に、メンテナ達は Linus に大きな差分を送ることができま 270 この期間中に、メンテナ達は Linus に大きな差分を送ることができます。
269 のような差分は通常 -mm カーネルに数週間含まれてきたパッチで 271 このような差分は通常 -mm カーネルに数週間含まれてきたパッチです。
270 す。 大きな変更は git(カーネルのソース管理ツール、詳細は 272 大きな変更は git(カーネルのソース管理ツール、詳細は
271 http://git.or.cz/ 参照) を使って送るのが好ましいやり方ですが、パッ 273 http://git.or.cz/ 参照) を使って送るのが好ましいやり方ですが、パッ
272 チファイルの形式のまま送るのでも十分です。 274 チファイルの形式のまま送るのでも十分です。
273 275
@@ -285,6 +287,10 @@ Linux カーネルの開発プロセスは現在幾つかの異なるメイン
285 に安定した状態にあると判断したときにリリースされます。目標は毎週新 287 に安定した状態にあると判断したときにリリースされます。目標は毎週新
286 しい -rc カーネルをリリースすることです。 288 しい -rc カーネルをリリースすることです。
287 289
290 - 以下の URL で各 -rc リリースに存在する既知の後戻り問題のリスト
291 が追跡されます-
292 http://kernelnewbies.org/known_regressions
293
288 - このプロセスはカーネルが 「準備ができた」と考えられるまで継続しま 294 - このプロセスはカーネルが 「準備ができた」と考えられるまで継続しま
289 す。このプロセスはだいたい 6週間継続します。 295 す。このプロセスはだいたい 6週間継続します。
290 296
@@ -331,8 +337,8 @@ Andrew は個別のサブシステムカーネルツリーとパッチを全て
331linux-kernel メーリングリストで収集された多数のパッチと同時に一つにま 337linux-kernel メーリングリストで収集された多数のパッチと同時に一つにま
332とめます。 338とめます。
333このツリーは新機能とパッチが検証される場となります。ある期間の間パッチ 339このツリーは新機能とパッチが検証される場となります。ある期間の間パッチ
334が -mm に入って価値を証明されたら、Andrew やサブシステムメンテナが、 340が -mm に入って価値を証明されたら、Andrew やサブシステムメンテナが、
335インラインへ入れるように Linus にプッシュします。 341ンラインへ入れるように Linus にプッシュします。
336 342
337メインカーネルツリーに含めるために Linus に送る前に、すべての新しいパッ 343メインカーネルツリーに含めるために Linus に送る前に、すべての新しいパッ
338チが -mm ツリーでテストされることが強く推奨されます。 344チが -mm ツリーでテストされることが強く推奨されます。
@@ -460,7 +466,7 @@ MAINTAINERS ファイルにリストがありますので参照してくださ
460せん- 466せん-
461彼らはあなたのパッチの行毎にコメントを入れたいので、そのためにはそうす 467彼らはあなたのパッチの行毎にコメントを入れたいので、そのためにはそうす
462るしかありません。あなたのメールプログラムが空白やタブを圧縮しないよう 468るしかありません。あなたのメールプログラムが空白やタブを圧縮しないよう
463に確認した方がいす。最初の良いテストとしては、自分にメールを送って 469に確認した方がいです。最初の良いテストとしては、自分にメールを送って
464みて、そのパッチを自分で当ててみることです。もしそれがうまく行かないな 470みて、そのパッチを自分で当ててみることです。もしそれがうまく行かないな
465ら、あなたのメールプログラムを直してもらうか、正しく動くように変えるべ 471ら、あなたのメールプログラムを直してもらうか、正しく動くように変えるべ
466きです。 472きです。
@@ -507,14 +513,14 @@ MAINTAINERS ファイルにリストがありますので参照してくださ
507とも普通のことです。これはあなたのパッチが受け入れられないということで 513とも普通のことです。これはあなたのパッチが受け入れられないということで
508は *ありません*、そしてあなた自身に反対することを意味するのでも *ありま 514は *ありません*、そしてあなた自身に反対することを意味するのでも *ありま
509せん*。単に自分のパッチに対して指摘された問題を全て修正して再送すれば 515せん*。単に自分のパッチに対して指摘された問題を全て修正して再送すれば
510です。 516いのです。
511 517
512 518
513カーネルコミュニティと企業組織のちがい 519カーネルコミュニティと企業組織のちがい
514----------------------------------------------------------------- 520-----------------------------------------------------------------
515 521
516カーネルコミュニティは大部分の伝統的な会社の開発環境とは異ったやり方で 522カーネルコミュニティは大部分の伝統的な会社の開発環境とは異ったやり方で
517動いています。以下は問題を避けるためにできるとことのストです- 523動いています。以下は問題を避けるためにできるといことのリストです-
518 524
519 あなたの提案する変更について言うときのうまい言い方: 525 あなたの提案する変更について言うときのうまい言い方:
520 526
@@ -525,7 +531,7 @@ MAINTAINERS ファイルにリストがありますので参照してくださ
525 - "以下は一連の小さなパッチ群ですが..." 531 - "以下は一連の小さなパッチ群ですが..."
526 - "これは典型的なマシンでの性能を向上させます.." 532 - "これは典型的なマシンでの性能を向上させます.."
527 533
528 やめた方がい悪い言い方: 534 やめた方がい悪い言い方:
529 535
530 - このやり方で AIX/ptx/Solaris ではできたので、できるはずだ 536 - このやり方で AIX/ptx/Solaris ではできたので、できるはずだ
531 - 私はこれを20年もの間やってきた、だから 537 - 私はこれを20年もの間やってきた、だから
@@ -575,10 +581,10 @@ Linux カーネルコミュニティは、一度に大量のコードの塊を
575 581
5761) 小さいパッチはあなたのパッチが適用される見込みを大きくします、カー 5821) 小さいパッチはあなたのパッチが適用される見込みを大きくします、カー
577 ネルの人達はパッチが正しいかどうかを確認する時間や労力をかけないか 583 ネルの人達はパッチが正しいかどうかを確認する時間や労力をかけないか
578 らです。5行のパッチはメンテナがたった1秒見るだけで適用できます。 584 らです。5行のパッチはメンテナがたった1秒見るだけで適用できます。
579 かし、500行のパッチは、正しいことをレビューするのに数時間かかるか 585 し、500行のパッチは、正しいことをレビューするのに数時間かかるか
580 しれません(時間はパッチのサイズなどにより指数関数に比例してかかり 586 れません(時間はパッチのサイズなどにより指数関数に比例してかかり
581 す) 587 )
582 588
583 小さいパッチは何かあったときにデバッグもとても簡単になります。パッ 589 小さいパッチは何かあったときにデバッグもとても簡単になります。パッ
584 チを1個1個取り除くのは、とても大きなパッチを当てた後に(かつ、何かお 590 チを1個1個取り除くのは、とても大きなパッチを当てた後に(かつ、何かお
@@ -587,23 +593,23 @@ Linux カーネルコミュニティは、一度に大量のコードの塊を
5872) 小さいパッチを送るだけでなく、送るまえに、書き直して、シンプルにす 5932) 小さいパッチを送るだけでなく、送るまえに、書き直して、シンプルにす
588 る(もしくは、単に順番を変えるだけでも)ことも、とても重要です。 594 る(もしくは、単に順番を変えるだけでも)ことも、とても重要です。
589 595
590以下はカーネル開発者の Al Viro のたとえ話す: 596以下はカーネル開発者の Al Viro のたとえ話です:
591 597
592 "生徒の数学の宿題を採点する先生のことを考えてみてください、先 598 "生徒の数学の宿題を採点する先生のことを考えてみてください、先
593 生は生徒が解に到達するまでの試行錯誤をいとは思わないでしょ 599 生は生徒が解に到達するまでの試行錯誤をたいとは思わないでしょ
594 う。先生は簡潔な最高の解をいのです。良い生徒はこれを知って 600 う。先生は簡潔な最高の解をたいのです。良い生徒はこれを知って
595 おり、そして最終解の前の中間作業を提出することは決してないので 601 おり、そして最終解の前の中間作業を提出することは決してないので
596 す" 602 す"
597 603
598 カーネル開発でもこれは同じです。メンテナ達とレビューア達は、 604 カーネル開発でもこれは同じです。メンテナ達とレビューア達は、
599 問題を解決する解の背後になる思考プロセスをいとは思いません。 605 問題を解決する解の背後になる思考プロセスをたいとは思いません。
600 彼らは単純であざやかな解決方法をいのです。 606 彼らは単純であざやかな解決方法をたいのです。
601 607
602あざやかな解を説明するのと、コミュニティと共に仕事をし、未解決の仕事を 608あざやかな解を説明するのと、コミュニティと共に仕事をし、未解決の仕事を
603議論することのバランスをキープするのは難しいかもしれません。 609議論することのバランスをキープするのは難しいかもしれません。
604ですから、開発プロセスの早期段階で改善のためのフィードバックをもらうよ 610ですから、開発プロセスの早期段階で改善のためのフィードバックをもらうよ
605うにするのもいすが、変更点を小さい部分に分割して全体ではまだ完成し 611うにするのもいですが、変更点を小さい部分に分割して全体ではまだ完成し
606ていない仕事を(部分的に)取り込んでもらえるようにすることもいとです。 612ていない仕事を(部分的に)取り込んでもらえるようにすることもいことです。
607 613
608また、でき上がっていないものや、"将来直す" ようなパッチを、本流に含め 614また、でき上がっていないものや、"将来直す" ようなパッチを、本流に含め
609てもらうように送っても、それは受け付けられないことを理解してください。 615てもらうように送っても、それは受け付けられないことを理解してください。
@@ -629,7 +635,7 @@ Linux カーネルコミュニティは、一度に大量のコードの塊を
629 - テスト結果 635 - テスト結果
630 636
631これについて全てがどのようにあるべきかについての詳細は、以下のドキュメ 637これについて全てがどのようにあるべきかについての詳細は、以下のドキュメ
632ントの ChangeLog セクションをください- 638ントの ChangeLog セクションをてください-
633 "The Perfect Patch" 639 "The Perfect Patch"
634 http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt 640 http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
635 641
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index f27cdd7125f2..912c57c2334e 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1437,6 +1437,10 @@ and is between 256 and 4096 characters. It is defined in the file
1437 pt. [PARIDE] 1437 pt. [PARIDE]
1438 See Documentation/paride.txt. 1438 See Documentation/paride.txt.
1439 1439
1440 pty.legacy_count=
1441 [KNL] Number of legacy pty's. Overwrites compiled-in
1442 default number.
1443
1440 quiet [KNL] Disable most log messages 1444 quiet [KNL] Disable most log messages
1441 1445
1442 r128= [HW,DRM] 1446 r128= [HW,DRM]
diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt
index 8ee49ee7c963..ca86a885ad8f 100644
--- a/Documentation/kobject.txt
+++ b/Documentation/kobject.txt
@@ -54,7 +54,6 @@ embedded in larger data structures and replace fields they duplicate.
54 54
55struct kobject { 55struct kobject {
56 const char * k_name; 56 const char * k_name;
57 char name[KOBJ_NAME_LEN];
58 struct kref kref; 57 struct kref kref;
59 struct list_head entry; 58 struct list_head entry;
60 struct kobject * parent; 59 struct kobject * parent;
@@ -223,18 +222,15 @@ decl_subsys(devices, &ktype_device, &device_uevent_ops);
223is equivalent to doing: 222is equivalent to doing:
224 223
225struct kset devices_subsys = { 224struct kset devices_subsys = {
226 .kobj = {
227 .name = "devices",
228 },
229 .ktype = &ktype_devices, 225 .ktype = &ktype_devices,
230 .uevent_ops = &device_uevent_ops, 226 .uevent_ops = &device_uevent_ops,
231}; 227};
232 228kobject_set_name(&devices_subsys, name);
233 229
234The objects that are registered with a subsystem that use the 230The objects that are registered with a subsystem that use the
235subsystem's default list must have their kset ptr set properly. These 231subsystem's default list must have their kset ptr set properly. These
236objects may have embedded kobjects or ksets. The 232objects may have embedded kobjects or ksets. The
237following helpers make setting the kset easier: 233following helper makes setting the kset easier:
238 234
239 235
240kobj_set_kset_s(obj,subsys) 236kobj_set_kset_s(obj,subsys)
@@ -242,22 +238,8 @@ kobj_set_kset_s(obj,subsys)
242- Assumes that obj->kobj exists, and is a struct kobject. 238- Assumes that obj->kobj exists, and is a struct kobject.
243- Sets the kset of that kobject to the kset <subsys>. 239- Sets the kset of that kobject to the kset <subsys>.
244 240
245
246kset_set_kset_s(obj,subsys)
247
248- Assumes that obj->kset exists, and is a struct kset.
249- Sets the kset of the embedded kobject to the kset <subsys>.
250
251subsys_set_kset(obj,subsys)
252
253- Assumes obj->subsys exists, and is a struct subsystem.
254- Sets obj->subsys.kset.kobj.kset to the subsystem's embedded kset.
255
256void subsystem_init(struct kset *s);
257int subsystem_register(struct kset *s); 241int subsystem_register(struct kset *s);
258void subsystem_unregister(struct kset *s); 242void subsystem_unregister(struct kset *s);
259struct kset *subsys_get(struct kset *s);
260void kset_put(struct kset *s);
261 243
262These are just wrappers around the respective kset_* functions. 244These are just wrappers around the respective kset_* functions.
263 245
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
index 5a289e4de838..a88eba3314d7 100644
--- a/arch/ia64/sn/kernel/tiocx.c
+++ b/arch/ia64/sn/kernel/tiocx.c
@@ -66,8 +66,7 @@ static int tiocx_match(struct device *dev, struct device_driver *drv)
66 66
67} 67}
68 68
69static int tiocx_uevent(struct device *dev, char **envp, int num_envp, 69static int tiocx_uevent(struct device *dev, struct kobj_uevent_env *env)
70 char *buffer, int buffer_size)
71{ 70{
72 return -ENODEV; 71 return -ENODEV;
73} 72}
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 89b911e83c04..8f3db32fac8b 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -57,26 +57,21 @@ ssize_t of_device_get_modalias(struct of_device *ofdev,
57 return tsize; 57 return tsize;
58} 58}
59 59
60int of_device_uevent(struct device *dev, 60int of_device_uevent(struct device *dev, struct kobj_uevent_env *env)
61 char **envp, int num_envp, char *buffer, int buffer_size)
62{ 61{
63 struct of_device *ofdev; 62 struct of_device *ofdev;
64 const char *compat; 63 const char *compat;
65 int i = 0, length = 0, seen = 0, cplen, sl; 64 int seen = 0, cplen, sl;
66 65
67 if (!dev) 66 if (!dev)
68 return -ENODEV; 67 return -ENODEV;
69 68
70 ofdev = to_of_device(dev); 69 ofdev = to_of_device(dev);
71 70
72 if (add_uevent_var(envp, num_envp, &i, 71 if (add_uevent_var(env, "OF_NAME=%s", ofdev->node->name))
73 buffer, buffer_size, &length,
74 "OF_NAME=%s", ofdev->node->name))
75 return -ENOMEM; 72 return -ENOMEM;
76 73
77 if (add_uevent_var(envp, num_envp, &i, 74 if (add_uevent_var(env, "OF_TYPE=%s", ofdev->node->type))
78 buffer, buffer_size, &length,
79 "OF_TYPE=%s", ofdev->node->type))
80 return -ENOMEM; 75 return -ENOMEM;
81 76
82 /* Since the compatible field can contain pretty much anything 77 /* Since the compatible field can contain pretty much anything
@@ -85,9 +80,7 @@ int of_device_uevent(struct device *dev,
85 80
86 compat = of_get_property(ofdev->node, "compatible", &cplen); 81 compat = of_get_property(ofdev->node, "compatible", &cplen);
87 while (compat && *compat && cplen > 0) { 82 while (compat && *compat && cplen > 0) {
88 if (add_uevent_var(envp, num_envp, &i, 83 if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat))
89 buffer, buffer_size, &length,
90 "OF_COMPATIBLE_%d=%s", seen, compat))
91 return -ENOMEM; 84 return -ENOMEM;
92 85
93 sl = strlen (compat) + 1; 86 sl = strlen (compat) + 1;
@@ -96,25 +89,17 @@ int of_device_uevent(struct device *dev,
96 seen++; 89 seen++;
97 } 90 }
98 91
99 if (add_uevent_var(envp, num_envp, &i, 92 if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen))
100 buffer, buffer_size, &length,
101 "OF_COMPATIBLE_N=%d", seen))
102 return -ENOMEM; 93 return -ENOMEM;
103 94
104 /* modalias is trickier, we add it in 2 steps */ 95 /* modalias is trickier, we add it in 2 steps */
105 if (add_uevent_var(envp, num_envp, &i, 96 if (add_uevent_var(env, "MODALIAS="))
106 buffer, buffer_size, &length,
107 "MODALIAS="))
108 return -ENOMEM; 97 return -ENOMEM;
109 98 sl = of_device_get_modalias(ofdev, &env->buf[env->buflen-1],
110 sl = of_device_get_modalias(ofdev, &buffer[length-1], 99 sizeof(env->buf) - env->buflen);
111 buffer_size-length); 100 if (sl >= (sizeof(env->buf) - env->buflen))
112 if (sl >= (buffer_size-length))
113 return -ENOMEM; 101 return -ENOMEM;
114 102 env->buflen += sl;
115 length += sl;
116
117 envp[i] = NULL;
118 103
119 return 0; 104 return 0;
120} 105}
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index cb22a3557c4e..19a5656001c0 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -317,30 +317,20 @@ static int vio_bus_match(struct device *dev, struct device_driver *drv)
317 return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL); 317 return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL);
318} 318}
319 319
320static int vio_hotplug(struct device *dev, char **envp, int num_envp, 320static int vio_hotplug(struct device *dev, struct kobj_uevent_env *env)
321 char *buffer, int buffer_size)
322{ 321{
323 const struct vio_dev *vio_dev = to_vio_dev(dev); 322 const struct vio_dev *vio_dev = to_vio_dev(dev);
324 struct device_node *dn; 323 struct device_node *dn;
325 const char *cp; 324 const char *cp;
326 int length;
327
328 if (!num_envp)
329 return -ENOMEM;
330 325
331 dn = dev->archdata.of_node; 326 dn = dev->archdata.of_node;
332 if (!dn) 327 if (!dn)
333 return -ENODEV; 328 return -ENODEV;
334 cp = of_get_property(dn, "compatible", &length); 329 cp = of_get_property(dn, "compatible", NULL);
335 if (!cp) 330 if (!cp)
336 return -ENODEV; 331 return -ENODEV;
337 332
338 envp[0] = buffer; 333 add_uevent_var(env, "MODALIAS=vio:T%sS%s", vio_dev->type, cp);
339 length = scnprintf(buffer, buffer_size, "MODALIAS=vio:T%sS%s",
340 vio_dev->type, cp);
341 if ((buffer_size - length) <= 0)
342 return -ENOMEM;
343 envp[1] = NULL;
344 return 0; 334 return 0;
345} 335}
346 336
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 4bb634a17e43..ea0b2c790412 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -437,18 +437,13 @@ static void ps3_system_bus_shutdown(struct device *_dev)
437 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); 437 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
438} 438}
439 439
440static int ps3_system_bus_uevent(struct device *_dev, char **envp, 440static int ps3_system_bus_uevent(struct device *_dev, struct kobj_uevent_env *env)
441 int num_envp, char *buffer, int buffer_size)
442{ 441{
443 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 442 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
444 int i = 0, length = 0; 443 int i = 0, length = 0;
445 444
446 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, 445 if (add_uevent_var(env, "MODALIAS=ps3:%d", dev->match_id))
447 &length, "MODALIAS=ps3:%d",
448 dev->match_id))
449 return -ENOMEM; 446 return -ENOMEM;
450
451 envp[i] = NULL;
452 return 0; 447 return 0;
453} 448}
454 449
diff --git a/block/bsg.c b/block/bsg.c
index ed2646827234..b8ddfc66f210 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -1010,10 +1010,7 @@ unlock:
1010} 1010}
1011EXPORT_SYMBOL_GPL(bsg_register_queue); 1011EXPORT_SYMBOL_GPL(bsg_register_queue);
1012 1012
1013static struct cdev bsg_cdev = { 1013static struct cdev bsg_cdev;
1014 .kobj = {.name = "bsg", },
1015 .owner = THIS_MODULE,
1016};
1017 1014
1018static int __init bsg_init(void) 1015static int __init bsg_init(void)
1019{ 1016{
diff --git a/block/elevator.c b/block/elevator.c
index c6d153de9fd6..b9c518afe1f8 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -186,7 +186,7 @@ static elevator_t *elevator_alloc(struct request_queue *q,
186 eq->ops = &e->ops; 186 eq->ops = &e->ops;
187 eq->elevator_type = e; 187 eq->elevator_type = e;
188 kobject_init(&eq->kobj); 188 kobject_init(&eq->kobj);
189 snprintf(eq->kobj.name, KOBJ_NAME_LEN, "%s", "iosched"); 189 kobject_set_name(&eq->kobj, "%s", "iosched");
190 eq->kobj.ktype = &elv_ktype; 190 eq->kobj.ktype = &elv_ktype;
191 mutex_init(&eq->sysfs_lock); 191 mutex_init(&eq->sysfs_lock);
192 192
diff --git a/block/genhd.c b/block/genhd.c
index 3af1e7a378d4..e609996f2e76 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -540,61 +540,42 @@ static int block_uevent_filter(struct kset *kset, struct kobject *kobj)
540 return ((ktype == &ktype_block) || (ktype == &ktype_part)); 540 return ((ktype == &ktype_block) || (ktype == &ktype_part));
541} 541}
542 542
543static int block_uevent(struct kset *kset, struct kobject *kobj, char **envp, 543static int block_uevent(struct kset *kset, struct kobject *kobj,
544 int num_envp, char *buffer, int buffer_size) 544 struct kobj_uevent_env *env)
545{ 545{
546 struct kobj_type *ktype = get_ktype(kobj); 546 struct kobj_type *ktype = get_ktype(kobj);
547 struct device *physdev; 547 struct device *physdev;
548 struct gendisk *disk; 548 struct gendisk *disk;
549 struct hd_struct *part; 549 struct hd_struct *part;
550 int length = 0;
551 int i = 0;
552 550
553 if (ktype == &ktype_block) { 551 if (ktype == &ktype_block) {
554 disk = container_of(kobj, struct gendisk, kobj); 552 disk = container_of(kobj, struct gendisk, kobj);
555 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, 553 add_uevent_var(env, "MINOR=%u", disk->first_minor);
556 &length, "MINOR=%u", disk->first_minor);
557 } else if (ktype == &ktype_part) { 554 } else if (ktype == &ktype_part) {
558 disk = container_of(kobj->parent, struct gendisk, kobj); 555 disk = container_of(kobj->parent, struct gendisk, kobj);
559 part = container_of(kobj, struct hd_struct, kobj); 556 part = container_of(kobj, struct hd_struct, kobj);
560 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, 557 add_uevent_var(env, "MINOR=%u",
561 &length, "MINOR=%u",
562 disk->first_minor + part->partno); 558 disk->first_minor + part->partno);
563 } else 559 } else
564 return 0; 560 return 0;
565 561
566 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, 562 add_uevent_var(env, "MAJOR=%u", disk->major);
567 "MAJOR=%u", disk->major);
568 563
569 /* add physical device, backing this device */ 564 /* add physical device, backing this device */
570 physdev = disk->driverfs_dev; 565 physdev = disk->driverfs_dev;
571 if (physdev) { 566 if (physdev) {
572 char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL); 567 char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL);
573 568
574 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, 569 add_uevent_var(env, "PHYSDEVPATH=%s", path);
575 &length, "PHYSDEVPATH=%s", path);
576 kfree(path); 570 kfree(path);
577 571
578 if (physdev->bus) 572 if (physdev->bus)
579 add_uevent_var(envp, num_envp, &i, 573 add_uevent_var(env, "PHYSDEVBUS=%s", physdev->bus->name);
580 buffer, buffer_size, &length,
581 "PHYSDEVBUS=%s",
582 physdev->bus->name);
583 574
584 if (physdev->driver) 575 if (physdev->driver)
585 add_uevent_var(envp, num_envp, &i, 576 add_uevent_var(env, physdev->driver->name);
586 buffer, buffer_size, &length,
587 "PHYSDEVDRIVER=%s",
588 physdev->driver->name);
589 } 577 }
590 578
591 /* terminate, set to next free slot, shrink available space */
592 envp[i] = NULL;
593 envp = &envp[i];
594 num_envp -= i;
595 buffer = &buffer[length];
596 buffer_size -= length;
597
598 return 0; 579 return 0;
599} 580}
600 581
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index cd9d2c5d91ae..d875673e76cd 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1854,7 +1854,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
1854 1854
1855 init_timer(&q->unplug_timer); 1855 init_timer(&q->unplug_timer);
1856 1856
1857 snprintf(q->kobj.name, KOBJ_NAME_LEN, "%s", "queue"); 1857 kobject_set_name(&q->kobj, "%s", "queue");
1858 q->kobj.ktype = &queue_ktype; 1858 q->kobj.ktype = &queue_ktype;
1859 kobject_init(&q->kobj); 1859 kobject_init(&q->kobj);
1860 1860
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index feab124d8e05..cbfc81579c9a 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -194,7 +194,7 @@ int acpi_bus_set_power(acpi_handle handle, int state)
194 194
195 if (!device->flags.power_manageable) { 195 if (!device->flags.power_manageable) {
196 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n", 196 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
197 device->dev.kobj.name)); 197 kobject_name(&device->dev.kobj)));
198 return -ENODEV; 198 return -ENODEV;
199 } 199 }
200 /* 200 /*
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 64620d668742..5b4d462117cf 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -319,16 +319,18 @@ static int acpi_bus_match(struct device *dev, struct device_driver *drv)
319 return !acpi_match_device_ids(acpi_dev, acpi_drv->ids); 319 return !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
320} 320}
321 321
322static int acpi_device_uevent(struct device *dev, char **envp, int num_envp, 322static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
323 char *buffer, int buffer_size)
324{ 323{
325 struct acpi_device *acpi_dev = to_acpi_device(dev); 324 struct acpi_device *acpi_dev = to_acpi_device(dev);
325 int len;
326 326
327 strcpy(buffer, "MODALIAS="); 327 if (add_uevent_var(env, "MODALIAS="))
328 if (create_modalias(acpi_dev, buffer + 9, buffer_size - 9) > 0) { 328 return -ENOMEM;
329 envp[0] = buffer; 329 len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
330 envp[1] = NULL; 330 sizeof(env->buf) - env->buflen);
331 } 331 if (len >= (sizeof(env->buf) - env->buflen))
332 return -ENOMEM;
333 env->buflen += len;
332 return 0; 334 return 0;
333} 335}
334 336
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index d05891f16282..b8a2095cb5ee 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -316,7 +316,7 @@ static int acpi_video_output_get(struct output_device *od)
316{ 316{
317 unsigned long state; 317 unsigned long state;
318 struct acpi_video_device *vd = 318 struct acpi_video_device *vd =
319 (struct acpi_video_device *)class_get_devdata(&od->class_dev); 319 (struct acpi_video_device *)dev_get_drvdata(&od->dev);
320 acpi_video_device_get_state(vd, &state); 320 acpi_video_device_get_state(vd, &state);
321 return (int)state; 321 return (int)state;
322} 322}
@@ -325,7 +325,7 @@ static int acpi_video_output_set(struct output_device *od)
325{ 325{
326 unsigned long state = od->request_state; 326 unsigned long state = od->request_state;
327 struct acpi_video_device *vd= 327 struct acpi_video_device *vd=
328 (struct acpi_video_device *)class_get_devdata(&od->class_dev); 328 (struct acpi_video_device *)dev_get_drvdata(&od->dev);
329 return acpi_video_device_set_state(vd, state); 329 return acpi_video_device_set_state(vd, state);
330} 330}
331 331
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 268e301775fc..6b94fb7be5f2 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -44,15 +44,12 @@ static int amba_match(struct device *dev, struct device_driver *drv)
44} 44}
45 45
46#ifdef CONFIG_HOTPLUG 46#ifdef CONFIG_HOTPLUG
47static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, int bufsz) 47static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
48{ 48{
49 struct amba_device *pcdev = to_amba_device(dev); 49 struct amba_device *pcdev = to_amba_device(dev);
50 int retval = 0, i = 0, len = 0; 50 int retval = 0;
51 51
52 retval = add_uevent_var(envp, nr_env, &i, 52 retval = add_uevent_var(env, "AMBA_ID=%08x", pcdev->periphid);
53 buf, bufsz, &len,
54 "AMBA_ID=%08x", pcdev->periphid);
55 envp[i] = NULL;
56 return retval; 53 return retval;
57} 54}
58#else 55#else
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 5d6312e33490..d7da109c24fd 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -1,5 +1,13 @@
1menu "Generic Driver Options" 1menu "Generic Driver Options"
2 2
3config UEVENT_HELPER_PATH
4 string "path to uevent helper"
5 depends on HOTPLUG
6 default "/sbin/hotplug"
7 help
8 Path to uevent helper program forked by the kernel for
9 every uevent.
10
3config STANDALONE 11config STANDALONE
4 bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL 12 bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL
5 default y 13 default y
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 47eb02d9f1af..10b2fb6c9ce6 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -18,8 +18,6 @@ extern int attribute_container_init(void);
18extern int bus_add_device(struct device * dev); 18extern int bus_add_device(struct device * dev);
19extern void bus_attach_device(struct device * dev); 19extern void bus_attach_device(struct device * dev);
20extern void bus_remove_device(struct device * dev); 20extern void bus_remove_device(struct device * dev);
21extern struct bus_type *get_bus(struct bus_type * bus);
22extern void put_bus(struct bus_type * bus);
23 21
24extern int bus_add_driver(struct device_driver *); 22extern int bus_add_driver(struct device_driver *);
25extern void bus_remove_driver(struct device_driver *); 23extern void bus_remove_driver(struct device_driver *);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 61c67526a656..9a19b071c573 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -30,6 +30,17 @@
30static int __must_check bus_rescan_devices_helper(struct device *dev, 30static int __must_check bus_rescan_devices_helper(struct device *dev,
31 void *data); 31 void *data);
32 32
33static struct bus_type *bus_get(struct bus_type *bus)
34{
35 return bus ? container_of(kset_get(&bus->subsys),
36 struct bus_type, subsys) : NULL;
37}
38
39static void bus_put(struct bus_type *bus)
40{
41 kset_put(&bus->subsys);
42}
43
33static ssize_t 44static ssize_t
34drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) 45drv_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
35{ 46{
@@ -78,7 +89,7 @@ static void driver_release(struct kobject * kobj)
78 */ 89 */
79} 90}
80 91
81static struct kobj_type ktype_driver = { 92static struct kobj_type driver_ktype = {
82 .sysfs_ops = &driver_sysfs_ops, 93 .sysfs_ops = &driver_sysfs_ops,
83 .release = driver_release, 94 .release = driver_release,
84}; 95};
@@ -122,9 +133,9 @@ static struct sysfs_ops bus_sysfs_ops = {
122int bus_create_file(struct bus_type * bus, struct bus_attribute * attr) 133int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
123{ 134{
124 int error; 135 int error;
125 if (get_bus(bus)) { 136 if (bus_get(bus)) {
126 error = sysfs_create_file(&bus->subsys.kobj, &attr->attr); 137 error = sysfs_create_file(&bus->subsys.kobj, &attr->attr);
127 put_bus(bus); 138 bus_put(bus);
128 } else 139 } else
129 error = -EINVAL; 140 error = -EINVAL;
130 return error; 141 return error;
@@ -132,9 +143,9 @@ int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
132 143
133void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr) 144void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
134{ 145{
135 if (get_bus(bus)) { 146 if (bus_get(bus)) {
136 sysfs_remove_file(&bus->subsys.kobj, &attr->attr); 147 sysfs_remove_file(&bus->subsys.kobj, &attr->attr);
137 put_bus(bus); 148 bus_put(bus);
138 } 149 }
139} 150}
140 151
@@ -172,7 +183,7 @@ static int driver_helper(struct device *dev, void *data)
172static ssize_t driver_unbind(struct device_driver *drv, 183static ssize_t driver_unbind(struct device_driver *drv,
173 const char *buf, size_t count) 184 const char *buf, size_t count)
174{ 185{
175 struct bus_type *bus = get_bus(drv->bus); 186 struct bus_type *bus = bus_get(drv->bus);
176 struct device *dev; 187 struct device *dev;
177 int err = -ENODEV; 188 int err = -ENODEV;
178 189
@@ -186,7 +197,7 @@ static ssize_t driver_unbind(struct device_driver *drv,
186 err = count; 197 err = count;
187 } 198 }
188 put_device(dev); 199 put_device(dev);
189 put_bus(bus); 200 bus_put(bus);
190 return err; 201 return err;
191} 202}
192static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); 203static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);
@@ -199,7 +210,7 @@ static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);
199static ssize_t driver_bind(struct device_driver *drv, 210static ssize_t driver_bind(struct device_driver *drv,
200 const char *buf, size_t count) 211 const char *buf, size_t count)
201{ 212{
202 struct bus_type *bus = get_bus(drv->bus); 213 struct bus_type *bus = bus_get(drv->bus);
203 struct device *dev; 214 struct device *dev;
204 int err = -ENODEV; 215 int err = -ENODEV;
205 216
@@ -219,7 +230,7 @@ static ssize_t driver_bind(struct device_driver *drv,
219 err = -ENODEV; 230 err = -ENODEV;
220 } 231 }
221 put_device(dev); 232 put_device(dev);
222 put_bus(bus); 233 bus_put(bus);
223 return err; 234 return err;
224} 235}
225static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); 236static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind);
@@ -430,7 +441,7 @@ static inline void remove_deprecated_bus_links(struct device *dev) { }
430 */ 441 */
431int bus_add_device(struct device * dev) 442int bus_add_device(struct device * dev)
432{ 443{
433 struct bus_type * bus = get_bus(dev->bus); 444 struct bus_type * bus = bus_get(dev->bus);
434 int error = 0; 445 int error = 0;
435 446
436 if (bus) { 447 if (bus) {
@@ -459,7 +470,7 @@ out_subsys:
459out_id: 470out_id:
460 device_remove_attrs(bus, dev); 471 device_remove_attrs(bus, dev);
461out_put: 472out_put:
462 put_bus(dev->bus); 473 bus_put(dev->bus);
463 return error; 474 return error;
464} 475}
465 476
@@ -509,7 +520,7 @@ void bus_remove_device(struct device * dev)
509 } 520 }
510 pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); 521 pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
511 device_release_driver(dev); 522 device_release_driver(dev);
512 put_bus(dev->bus); 523 bus_put(dev->bus);
513 } 524 }
514} 525}
515 526
@@ -568,32 +579,29 @@ static void remove_bind_files(struct device_driver *drv)
568 driver_remove_file(drv, &driver_attr_unbind); 579 driver_remove_file(drv, &driver_attr_unbind);
569} 580}
570 581
582static BUS_ATTR(drivers_probe, S_IWUSR, NULL, store_drivers_probe);
583static BUS_ATTR(drivers_autoprobe, S_IWUSR | S_IRUGO,
584 show_drivers_autoprobe, store_drivers_autoprobe);
585
571static int add_probe_files(struct bus_type *bus) 586static int add_probe_files(struct bus_type *bus)
572{ 587{
573 int retval; 588 int retval;
574 589
575 bus->drivers_probe_attr.attr.name = "drivers_probe"; 590 retval = bus_create_file(bus, &bus_attr_drivers_probe);
576 bus->drivers_probe_attr.attr.mode = S_IWUSR;
577 bus->drivers_probe_attr.store = store_drivers_probe;
578 retval = bus_create_file(bus, &bus->drivers_probe_attr);
579 if (retval) 591 if (retval)
580 goto out; 592 goto out;
581 593
582 bus->drivers_autoprobe_attr.attr.name = "drivers_autoprobe"; 594 retval = bus_create_file(bus, &bus_attr_drivers_autoprobe);
583 bus->drivers_autoprobe_attr.attr.mode = S_IWUSR | S_IRUGO;
584 bus->drivers_autoprobe_attr.show = show_drivers_autoprobe;
585 bus->drivers_autoprobe_attr.store = store_drivers_autoprobe;
586 retval = bus_create_file(bus, &bus->drivers_autoprobe_attr);
587 if (retval) 595 if (retval)
588 bus_remove_file(bus, &bus->drivers_probe_attr); 596 bus_remove_file(bus, &bus_attr_drivers_probe);
589out: 597out:
590 return retval; 598 return retval;
591} 599}
592 600
593static void remove_probe_files(struct bus_type *bus) 601static void remove_probe_files(struct bus_type *bus)
594{ 602{
595 bus_remove_file(bus, &bus->drivers_autoprobe_attr); 603 bus_remove_file(bus, &bus_attr_drivers_autoprobe);
596 bus_remove_file(bus, &bus->drivers_probe_attr); 604 bus_remove_file(bus, &bus_attr_drivers_probe);
597} 605}
598#else 606#else
599static inline int add_bind_files(struct device_driver *drv) { return 0; } 607static inline int add_bind_files(struct device_driver *drv) { return 0; }
@@ -602,6 +610,17 @@ static inline int add_probe_files(struct bus_type *bus) { return 0; }
602static inline void remove_probe_files(struct bus_type *bus) {} 610static inline void remove_probe_files(struct bus_type *bus) {}
603#endif 611#endif
604 612
613static ssize_t driver_uevent_store(struct device_driver *drv,
614 const char *buf, size_t count)
615{
616 enum kobject_action action;
617
618 if (kobject_action_type(buf, count, &action) == 0)
619 kobject_uevent(&drv->kobj, action);
620 return count;
621}
622static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store);
623
605/** 624/**
606 * bus_add_driver - Add a driver to the bus. 625 * bus_add_driver - Add a driver to the bus.
607 * @drv: driver. 626 * @drv: driver.
@@ -609,7 +628,7 @@ static inline void remove_probe_files(struct bus_type *bus) {}
609 */ 628 */
610int bus_add_driver(struct device_driver *drv) 629int bus_add_driver(struct device_driver *drv)
611{ 630{
612 struct bus_type * bus = get_bus(drv->bus); 631 struct bus_type * bus = bus_get(drv->bus);
613 int error = 0; 632 int error = 0;
614 633
615 if (!bus) 634 if (!bus)
@@ -632,6 +651,11 @@ int bus_add_driver(struct device_driver *drv)
632 klist_add_tail(&drv->knode_bus, &bus->klist_drivers); 651 klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
633 module_add_driver(drv->owner, drv); 652 module_add_driver(drv->owner, drv);
634 653
654 error = driver_create_file(drv, &driver_attr_uevent);
655 if (error) {
656 printk(KERN_ERR "%s: uevent attr (%s) failed\n",
657 __FUNCTION__, drv->name);
658 }
635 error = driver_add_attrs(bus, drv); 659 error = driver_add_attrs(bus, drv);
636 if (error) { 660 if (error) {
637 /* How the hell do we get out of this pickle? Give up */ 661 /* How the hell do we get out of this pickle? Give up */
@@ -649,7 +673,7 @@ int bus_add_driver(struct device_driver *drv)
649out_unregister: 673out_unregister:
650 kobject_unregister(&drv->kobj); 674 kobject_unregister(&drv->kobj);
651out_put_bus: 675out_put_bus:
652 put_bus(bus); 676 bus_put(bus);
653 return error; 677 return error;
654} 678}
655 679
@@ -669,12 +693,13 @@ void bus_remove_driver(struct device_driver * drv)
669 693
670 remove_bind_files(drv); 694 remove_bind_files(drv);
671 driver_remove_attrs(drv->bus, drv); 695 driver_remove_attrs(drv->bus, drv);
696 driver_remove_file(drv, &driver_attr_uevent);
672 klist_remove(&drv->knode_bus); 697 klist_remove(&drv->knode_bus);
673 pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); 698 pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
674 driver_detach(drv); 699 driver_detach(drv);
675 module_remove_driver(drv); 700 module_remove_driver(drv);
676 kobject_unregister(&drv->kobj); 701 kobject_unregister(&drv->kobj);
677 put_bus(drv->bus); 702 bus_put(drv->bus);
678} 703}
679 704
680 705
@@ -729,18 +754,6 @@ int device_reprobe(struct device *dev)
729} 754}
730EXPORT_SYMBOL_GPL(device_reprobe); 755EXPORT_SYMBOL_GPL(device_reprobe);
731 756
732struct bus_type *get_bus(struct bus_type *bus)
733{
734 return bus ? container_of(subsys_get(&bus->subsys),
735 struct bus_type, subsys) : NULL;
736}
737
738void put_bus(struct bus_type * bus)
739{
740 subsys_put(&bus->subsys);
741}
742
743
744/** 757/**
745 * find_bus - locate bus by name. 758 * find_bus - locate bus by name.
746 * @name: name of bus. 759 * @name: name of bus.
@@ -808,6 +821,17 @@ static void klist_devices_put(struct klist_node *n)
808 put_device(dev); 821 put_device(dev);
809} 822}
810 823
824static ssize_t bus_uevent_store(struct bus_type *bus,
825 const char *buf, size_t count)
826{
827 enum kobject_action action;
828
829 if (kobject_action_type(buf, count, &action) == 0)
830 kobject_uevent(&bus->subsys.kobj, action);
831 return count;
832}
833static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store);
834
811/** 835/**
812 * bus_register - register a bus with the system. 836 * bus_register - register a bus with the system.
813 * @bus: bus. 837 * @bus: bus.
@@ -826,11 +850,16 @@ int bus_register(struct bus_type * bus)
826 if (retval) 850 if (retval)
827 goto out; 851 goto out;
828 852
829 subsys_set_kset(bus, bus_subsys); 853 bus->subsys.kobj.kset = &bus_subsys;
854
830 retval = subsystem_register(&bus->subsys); 855 retval = subsystem_register(&bus->subsys);
831 if (retval) 856 if (retval)
832 goto out; 857 goto out;
833 858
859 retval = bus_create_file(bus, &bus_attr_uevent);
860 if (retval)
861 goto bus_uevent_fail;
862
834 kobject_set_name(&bus->devices.kobj, "devices"); 863 kobject_set_name(&bus->devices.kobj, "devices");
835 bus->devices.kobj.parent = &bus->subsys.kobj; 864 bus->devices.kobj.parent = &bus->subsys.kobj;
836 retval = kset_register(&bus->devices); 865 retval = kset_register(&bus->devices);
@@ -839,7 +868,7 @@ int bus_register(struct bus_type * bus)
839 868
840 kobject_set_name(&bus->drivers.kobj, "drivers"); 869 kobject_set_name(&bus->drivers.kobj, "drivers");
841 bus->drivers.kobj.parent = &bus->subsys.kobj; 870 bus->drivers.kobj.parent = &bus->subsys.kobj;
842 bus->drivers.ktype = &ktype_driver; 871 bus->drivers.ktype = &driver_ktype;
843 retval = kset_register(&bus->drivers); 872 retval = kset_register(&bus->drivers);
844 if (retval) 873 if (retval)
845 goto bus_drivers_fail; 874 goto bus_drivers_fail;
@@ -866,6 +895,8 @@ bus_probe_files_fail:
866bus_drivers_fail: 895bus_drivers_fail:
867 kset_unregister(&bus->devices); 896 kset_unregister(&bus->devices);
868bus_devices_fail: 897bus_devices_fail:
898 bus_remove_file(bus, &bus_attr_uevent);
899bus_uevent_fail:
869 subsystem_unregister(&bus->subsys); 900 subsystem_unregister(&bus->subsys);
870out: 901out:
871 return retval; 902 return retval;
@@ -876,7 +907,7 @@ out:
876 * @bus: bus. 907 * @bus: bus.
877 * 908 *
878 * Unregister the child subsystems and the bus itself. 909 * Unregister the child subsystems and the bus itself.
879 * Finally, we call put_bus() to release the refcount 910 * Finally, we call bus_put() to release the refcount
880 */ 911 */
881void bus_unregister(struct bus_type * bus) 912void bus_unregister(struct bus_type * bus)
882{ 913{
@@ -885,6 +916,7 @@ void bus_unregister(struct bus_type * bus)
885 remove_probe_files(bus); 916 remove_probe_files(bus);
886 kset_unregister(&bus->drivers); 917 kset_unregister(&bus->drivers);
887 kset_unregister(&bus->devices); 918 kset_unregister(&bus->devices);
919 bus_remove_file(bus, &bus_attr_uevent);
888 subsystem_unregister(&bus->subsys); 920 subsystem_unregister(&bus->subsys);
889} 921}
890 922
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 4d2222618b78..a863bb091e11 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -65,13 +65,13 @@ static struct sysfs_ops class_sysfs_ops = {
65 .store = class_attr_store, 65 .store = class_attr_store,
66}; 66};
67 67
68static struct kobj_type ktype_class = { 68static struct kobj_type class_ktype = {
69 .sysfs_ops = &class_sysfs_ops, 69 .sysfs_ops = &class_sysfs_ops,
70 .release = class_release, 70 .release = class_release,
71}; 71};
72 72
73/* Hotplug events for classes go to the class_obj subsys */ 73/* Hotplug events for classes go to the class_obj subsys */
74static decl_subsys(class, &ktype_class, NULL); 74static decl_subsys(class, &class_ktype, NULL);
75 75
76 76
77int class_create_file(struct class * cls, const struct class_attribute * attr) 77int class_create_file(struct class * cls, const struct class_attribute * attr)
@@ -93,14 +93,14 @@ void class_remove_file(struct class * cls, const struct class_attribute * attr)
93static struct class *class_get(struct class *cls) 93static struct class *class_get(struct class *cls)
94{ 94{
95 if (cls) 95 if (cls)
96 return container_of(subsys_get(&cls->subsys), struct class, subsys); 96 return container_of(kset_get(&cls->subsys), struct class, subsys);
97 return NULL; 97 return NULL;
98} 98}
99 99
100static void class_put(struct class * cls) 100static void class_put(struct class * cls)
101{ 101{
102 if (cls) 102 if (cls)
103 subsys_put(&cls->subsys); 103 kset_put(&cls->subsys);
104} 104}
105 105
106 106
@@ -149,7 +149,7 @@ int class_register(struct class * cls)
149 if (error) 149 if (error)
150 return error; 150 return error;
151 151
152 subsys_set_kset(cls, class_subsys); 152 cls->subsys.kobj.kset = &class_subsys;
153 153
154 error = subsystem_register(&cls->subsys); 154 error = subsystem_register(&cls->subsys);
155 if (!error) { 155 if (!error) {
@@ -180,8 +180,7 @@ static void class_device_create_release(struct class_device *class_dev)
180 180
181/* needed to allow these devices to have parent class devices */ 181/* needed to allow these devices to have parent class devices */
182static int class_device_create_uevent(struct class_device *class_dev, 182static int class_device_create_uevent(struct class_device *class_dev,
183 char **envp, int num_envp, 183 struct kobj_uevent_env *env)
184 char *buffer, int buffer_size)
185{ 184{
186 pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id); 185 pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
187 return 0; 186 return 0;
@@ -324,7 +323,7 @@ static void class_dev_release(struct kobject * kobj)
324 } 323 }
325} 324}
326 325
327static struct kobj_type ktype_class_device = { 326static struct kobj_type class_device_ktype = {
328 .sysfs_ops = &class_dev_sysfs_ops, 327 .sysfs_ops = &class_dev_sysfs_ops,
329 .release = class_dev_release, 328 .release = class_dev_release,
330}; 329};
@@ -333,7 +332,7 @@ static int class_uevent_filter(struct kset *kset, struct kobject *kobj)
333{ 332{
334 struct kobj_type *ktype = get_ktype(kobj); 333 struct kobj_type *ktype = get_ktype(kobj);
335 334
336 if (ktype == &ktype_class_device) { 335 if (ktype == &class_device_ktype) {
337 struct class_device *class_dev = to_class_dev(kobj); 336 struct class_device *class_dev = to_class_dev(kobj);
338 if (class_dev->class) 337 if (class_dev->class)
339 return 1; 338 return 1;
@@ -403,64 +402,43 @@ static void remove_deprecated_class_device_links(struct class_device *cd)
403{ } 402{ }
404#endif 403#endif
405 404
406static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp, 405static int class_uevent(struct kset *kset, struct kobject *kobj,
407 int num_envp, char *buffer, int buffer_size) 406 struct kobj_uevent_env *env)
408{ 407{
409 struct class_device *class_dev = to_class_dev(kobj); 408 struct class_device *class_dev = to_class_dev(kobj);
410 struct device *dev = class_dev->dev; 409 struct device *dev = class_dev->dev;
411 int i = 0;
412 int length = 0;
413 int retval = 0; 410 int retval = 0;
414 411
415 pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); 412 pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
416 413
417 if (MAJOR(class_dev->devt)) { 414 if (MAJOR(class_dev->devt)) {
418 add_uevent_var(envp, num_envp, &i, 415 add_uevent_var(env, "MAJOR=%u", MAJOR(class_dev->devt));
419 buffer, buffer_size, &length,
420 "MAJOR=%u", MAJOR(class_dev->devt));
421 416
422 add_uevent_var(envp, num_envp, &i, 417 add_uevent_var(env, "MINOR=%u", MINOR(class_dev->devt));
423 buffer, buffer_size, &length,
424 "MINOR=%u", MINOR(class_dev->devt));
425 } 418 }
426 419
427 if (dev) { 420 if (dev) {
428 const char *path = kobject_get_path(&dev->kobj, GFP_KERNEL); 421 const char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
429 if (path) { 422 if (path) {
430 add_uevent_var(envp, num_envp, &i, 423 add_uevent_var(env, "PHYSDEVPATH=%s", path);
431 buffer, buffer_size, &length,
432 "PHYSDEVPATH=%s", path);
433 kfree(path); 424 kfree(path);
434 } 425 }
435 426
436 if (dev->bus) 427 if (dev->bus)
437 add_uevent_var(envp, num_envp, &i, 428 add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name);
438 buffer, buffer_size, &length,
439 "PHYSDEVBUS=%s", dev->bus->name);
440 429
441 if (dev->driver) 430 if (dev->driver)
442 add_uevent_var(envp, num_envp, &i, 431 add_uevent_var(env, "PHYSDEVDRIVER=%s", dev->driver->name);
443 buffer, buffer_size, &length,
444 "PHYSDEVDRIVER=%s", dev->driver->name);
445 } 432 }
446 433
447 /* terminate, set to next free slot, shrink available space */
448 envp[i] = NULL;
449 envp = &envp[i];
450 num_envp -= i;
451 buffer = &buffer[length];
452 buffer_size -= length;
453
454 if (class_dev->uevent) { 434 if (class_dev->uevent) {
455 /* have the class device specific function add its stuff */ 435 /* have the class device specific function add its stuff */
456 retval = class_dev->uevent(class_dev, envp, num_envp, 436 retval = class_dev->uevent(class_dev, env);
457 buffer, buffer_size);
458 if (retval) 437 if (retval)
459 pr_debug("class_dev->uevent() returned %d\n", retval); 438 pr_debug("class_dev->uevent() returned %d\n", retval);
460 } else if (class_dev->class->uevent) { 439 } else if (class_dev->class->uevent) {
461 /* have the class specific function add its stuff */ 440 /* have the class specific function add its stuff */
462 retval = class_dev->class->uevent(class_dev, envp, num_envp, 441 retval = class_dev->class->uevent(class_dev, env);
463 buffer, buffer_size);
464 if (retval) 442 if (retval)
465 pr_debug("class->uevent() returned %d\n", retval); 443 pr_debug("class->uevent() returned %d\n", retval);
466 } 444 }
@@ -474,7 +452,7 @@ static struct kset_uevent_ops class_uevent_ops = {
474 .uevent = class_uevent, 452 .uevent = class_uevent,
475}; 453};
476 454
477static decl_subsys(class_obj, &ktype_class_device, &class_uevent_ops); 455static decl_subsys(class_obj, &class_device_ktype, &class_uevent_ops);
478 456
479 457
480static int class_device_add_attrs(struct class_device * cd) 458static int class_device_add_attrs(struct class_device * cd)
@@ -883,7 +861,7 @@ int __init classes_init(void)
883 861
884 /* ick, this is ugly, the things we go through to keep from showing up 862 /* ick, this is ugly, the things we go through to keep from showing up
885 * in sysfs... */ 863 * in sysfs... */
886 subsystem_init(&class_obj_subsys); 864 kset_init(&class_obj_subsys);
887 if (!class_obj_subsys.kobj.parent) 865 if (!class_obj_subsys.kobj.parent)
888 class_obj_subsys.kobj.parent = &class_obj_subsys.kobj; 866 class_obj_subsys.kobj.parent = &class_obj_subsys.kobj;
889 return 0; 867 return 0;
diff --git a/drivers/base/core.c b/drivers/base/core.c
index ec86d6fc2360..c1343414d285 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -108,7 +108,7 @@ static void device_release(struct kobject * kobj)
108 } 108 }
109} 109}
110 110
111static struct kobj_type ktype_device = { 111static struct kobj_type device_ktype = {
112 .release = device_release, 112 .release = device_release,
113 .sysfs_ops = &dev_sysfs_ops, 113 .sysfs_ops = &dev_sysfs_ops,
114}; 114};
@@ -118,7 +118,7 @@ static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
118{ 118{
119 struct kobj_type *ktype = get_ktype(kobj); 119 struct kobj_type *ktype = get_ktype(kobj);
120 120
121 if (ktype == &ktype_device) { 121 if (ktype == &device_ktype) {
122 struct device *dev = to_dev(kobj); 122 struct device *dev = to_dev(kobj);
123 if (dev->uevent_suppress) 123 if (dev->uevent_suppress)
124 return 0; 124 return 0;
@@ -141,33 +141,23 @@ static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj)
141 return NULL; 141 return NULL;
142} 142}
143 143
144static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, 144static int dev_uevent(struct kset *kset, struct kobject *kobj,
145 int num_envp, char *buffer, int buffer_size) 145 struct kobj_uevent_env *env)
146{ 146{
147 struct device *dev = to_dev(kobj); 147 struct device *dev = to_dev(kobj);
148 int i = 0;
149 int length = 0;
150 int retval = 0; 148 int retval = 0;
151 149
152 /* add the major/minor if present */ 150 /* add the major/minor if present */
153 if (MAJOR(dev->devt)) { 151 if (MAJOR(dev->devt)) {
154 add_uevent_var(envp, num_envp, &i, 152 add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt));
155 buffer, buffer_size, &length, 153 add_uevent_var(env, "MINOR=%u", MINOR(dev->devt));
156 "MAJOR=%u", MAJOR(dev->devt));
157 add_uevent_var(envp, num_envp, &i,
158 buffer, buffer_size, &length,
159 "MINOR=%u", MINOR(dev->devt));
160 } 154 }
161 155
162 if (dev->type && dev->type->name) 156 if (dev->type && dev->type->name)
163 add_uevent_var(envp, num_envp, &i, 157 add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
164 buffer, buffer_size, &length,
165 "DEVTYPE=%s", dev->type->name);
166 158
167 if (dev->driver) 159 if (dev->driver)
168 add_uevent_var(envp, num_envp, &i, 160 add_uevent_var(env, "DRIVER=%s", dev->driver->name);
169 buffer, buffer_size, &length,
170 "DRIVER=%s", dev->driver->name);
171 161
172#ifdef CONFIG_SYSFS_DEPRECATED 162#ifdef CONFIG_SYSFS_DEPRECATED
173 if (dev->class) { 163 if (dev->class) {
@@ -181,59 +171,43 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
181 171
182 path = kobject_get_path(&parent->kobj, GFP_KERNEL); 172 path = kobject_get_path(&parent->kobj, GFP_KERNEL);
183 if (path) { 173 if (path) {
184 add_uevent_var(envp, num_envp, &i, 174 add_uevent_var(env, "PHYSDEVPATH=%s", path);
185 buffer, buffer_size, &length,
186 "PHYSDEVPATH=%s", path);
187 kfree(path); 175 kfree(path);
188 } 176 }
189 177
190 add_uevent_var(envp, num_envp, &i, 178 add_uevent_var(env, "PHYSDEVBUS=%s", parent->bus->name);
191 buffer, buffer_size, &length,
192 "PHYSDEVBUS=%s", parent->bus->name);
193 179
194 if (parent->driver) 180 if (parent->driver)
195 add_uevent_var(envp, num_envp, &i, 181 add_uevent_var(env, "PHYSDEVDRIVER=%s",
196 buffer, buffer_size, &length, 182 parent->driver->name);
197 "PHYSDEVDRIVER=%s", parent->driver->name);
198 } 183 }
199 } else if (dev->bus) { 184 } else if (dev->bus) {
200 add_uevent_var(envp, num_envp, &i, 185 add_uevent_var(env, "PHYSDEVBUS=%s", dev->bus->name);
201 buffer, buffer_size, &length,
202 "PHYSDEVBUS=%s", dev->bus->name);
203 186
204 if (dev->driver) 187 if (dev->driver)
205 add_uevent_var(envp, num_envp, &i, 188 add_uevent_var(env, "PHYSDEVDRIVER=%s", dev->driver->name);
206 buffer, buffer_size, &length,
207 "PHYSDEVDRIVER=%s", dev->driver->name);
208 } 189 }
209#endif 190#endif
210 191
211 /* terminate, set to next free slot, shrink available space */ 192 /* have the bus specific function add its stuff */
212 envp[i] = NULL;
213 envp = &envp[i];
214 num_envp -= i;
215 buffer = &buffer[length];
216 buffer_size -= length;
217
218 if (dev->bus && dev->bus->uevent) { 193 if (dev->bus && dev->bus->uevent) {
219 /* have the bus specific function add its stuff */ 194 retval = dev->bus->uevent(dev, env);
220 retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
221 if (retval) 195 if (retval)
222 pr_debug ("%s: bus uevent() returned %d\n", 196 pr_debug ("%s: bus uevent() returned %d\n",
223 __FUNCTION__, retval); 197 __FUNCTION__, retval);
224 } 198 }
225 199
200 /* have the class specific function add its stuff */
226 if (dev->class && dev->class->dev_uevent) { 201 if (dev->class && dev->class->dev_uevent) {
227 /* have the class specific function add its stuff */ 202 retval = dev->class->dev_uevent(dev, env);
228 retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size);
229 if (retval) 203 if (retval)
230 pr_debug("%s: class uevent() returned %d\n", 204 pr_debug("%s: class uevent() returned %d\n",
231 __FUNCTION__, retval); 205 __FUNCTION__, retval);
232 } 206 }
233 207
208 /* have the device type specific fuction add its stuff */
234 if (dev->type && dev->type->uevent) { 209 if (dev->type && dev->type->uevent) {
235 /* have the device type specific fuction add its stuff */ 210 retval = dev->type->uevent(dev, env);
236 retval = dev->type->uevent(dev, envp, num_envp, buffer, buffer_size);
237 if (retval) 211 if (retval)
238 pr_debug("%s: dev_type uevent() returned %d\n", 212 pr_debug("%s: dev_type uevent() returned %d\n",
239 __FUNCTION__, retval); 213 __FUNCTION__, retval);
@@ -253,22 +227,18 @@ static ssize_t show_uevent(struct device *dev, struct device_attribute *attr,
253{ 227{
254 struct kobject *top_kobj; 228 struct kobject *top_kobj;
255 struct kset *kset; 229 struct kset *kset;
256 char *envp[32]; 230 struct kobj_uevent_env *env = NULL;
257 char *data = NULL;
258 char *pos;
259 int i; 231 int i;
260 size_t count = 0; 232 size_t count = 0;
261 int retval; 233 int retval;
262 234
263 /* search the kset, the device belongs to */ 235 /* search the kset, the device belongs to */
264 top_kobj = &dev->kobj; 236 top_kobj = &dev->kobj;
265 if (!top_kobj->kset && top_kobj->parent) { 237 while (!top_kobj->kset && top_kobj->parent)
266 do { 238 top_kobj = top_kobj->parent;
267 top_kobj = top_kobj->parent;
268 } while (!top_kobj->kset && top_kobj->parent);
269 }
270 if (!top_kobj->kset) 239 if (!top_kobj->kset)
271 goto out; 240 goto out;
241
272 kset = top_kobj->kset; 242 kset = top_kobj->kset;
273 if (!kset->uevent_ops || !kset->uevent_ops->uevent) 243 if (!kset->uevent_ops || !kset->uevent_ops->uevent)
274 goto out; 244 goto out;
@@ -278,43 +248,29 @@ static ssize_t show_uevent(struct device *dev, struct device_attribute *attr,
278 if (!kset->uevent_ops->filter(kset, &dev->kobj)) 248 if (!kset->uevent_ops->filter(kset, &dev->kobj))
279 goto out; 249 goto out;
280 250
281 data = (char *)get_zeroed_page(GFP_KERNEL); 251 env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
282 if (!data) 252 if (!env)
283 return -ENOMEM; 253 return -ENOMEM;
284 254
285 /* let the kset specific function add its keys */ 255 /* let the kset specific function add its keys */
286 pos = data; 256 retval = kset->uevent_ops->uevent(kset, &dev->kobj, env);
287 memset(envp, 0, sizeof(envp));
288 retval = kset->uevent_ops->uevent(kset, &dev->kobj,
289 envp, ARRAY_SIZE(envp),
290 pos, PAGE_SIZE);
291 if (retval) 257 if (retval)
292 goto out; 258 goto out;
293 259
294 /* copy keys to file */ 260 /* copy keys to file */
295 for (i = 0; envp[i]; i++) { 261 for (i = 0; i < env->envp_idx; i++)
296 pos = &buf[count]; 262 count += sprintf(&buf[count], "%s\n", env->envp[i]);
297 count += sprintf(pos, "%s\n", envp[i]);
298 }
299out: 263out:
300 free_page((unsigned long)data); 264 kfree(env);
301 return count; 265 return count;
302} 266}
303 267
304static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, 268static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
305 const char *buf, size_t count) 269 const char *buf, size_t count)
306{ 270{
307 size_t len = count;
308 enum kobject_action action; 271 enum kobject_action action;
309 272
310 if (len && buf[len-1] == '\n') 273 if (kobject_action_type(buf, count, &action) == 0) {
311 len--;
312
313 for (action = 0; action < KOBJ_MAX; action++) {
314 if (strncmp(kobject_actions[action], buf, len) != 0)
315 continue;
316 if (kobject_actions[action][len] != '\0')
317 continue;
318 kobject_uevent(&dev->kobj, action); 274 kobject_uevent(&dev->kobj, action);
319 goto out; 275 goto out;
320 } 276 }
@@ -449,7 +405,7 @@ static struct device_attribute devt_attr =
449 * devices_subsys - structure to be registered with kobject core. 405 * devices_subsys - structure to be registered with kobject core.
450 */ 406 */
451 407
452decl_subsys(devices, &ktype_device, &device_uevent_ops); 408decl_subsys(devices, &device_ktype, &device_uevent_ops);
453 409
454 410
455/** 411/**
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index b24efd4e3e3d..0295855a3eef 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -88,19 +88,14 @@ static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store);
88 88
89static void fw_dev_release(struct device *dev); 89static void fw_dev_release(struct device *dev);
90 90
91static int firmware_uevent(struct device *dev, char **envp, int num_envp, 91static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env)
92 char *buffer, int buffer_size)
93{ 92{
94 struct firmware_priv *fw_priv = dev_get_drvdata(dev); 93 struct firmware_priv *fw_priv = dev_get_drvdata(dev);
95 int i = 0, len = 0;
96 94
97 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, 95 if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->fw_id))
98 "FIRMWARE=%s", fw_priv->fw_id))
99 return -ENOMEM; 96 return -ENOMEM;
100 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, 97 if (add_uevent_var(env, "TIMEOUT=%i", loading_timeout))
101 "TIMEOUT=%i", loading_timeout))
102 return -ENOMEM; 98 return -ENOMEM;
103 envp[i] = NULL;
104 99
105 return 0; 100 return 0;
106} 101}
@@ -297,8 +292,7 @@ firmware_class_timeout(u_long data)
297 292
298static inline void fw_setup_device_id(struct device *f_dev, struct device *dev) 293static inline void fw_setup_device_id(struct device *f_dev, struct device *dev)
299{ 294{
300 /* XXX warning we should watch out for name collisions */ 295 snprintf(f_dev->bus_id, BUS_ID_SIZE, "firmware-%s", dev->bus_id);
301 strlcpy(f_dev->bus_id, dev->bus_id, BUS_ID_SIZE);
302} 296}
303 297
304static int fw_register_device(struct device **dev_p, const char *fw_name, 298static int fw_register_device(struct device **dev_p, const char *fw_name,
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 74b96795d2f5..cb99daeae936 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -34,8 +34,7 @@ static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj)
34 return MEMORY_CLASS_NAME; 34 return MEMORY_CLASS_NAME;
35} 35}
36 36
37static int memory_uevent(struct kset *kset, struct kobject *kobj, char **envp, 37static int memory_uevent(struct kset *kset, struct kobj_uevent_env *env)
38 int num_envp, char *buffer, int buffer_size)
39{ 38{
40 int retval = 0; 39 int retval = 0;
41 40
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 869ff8c00146..fb5609241482 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -160,13 +160,8 @@ static void platform_device_release(struct device *dev)
160 * 160 *
161 * Create a platform device object which can have other objects attached 161 * Create a platform device object which can have other objects attached
162 * to it, and which will have attached objects freed when it is released. 162 * to it, and which will have attached objects freed when it is released.
163 *
164 * This device will be marked as not supporting hotpluggable drivers; no
165 * device add/remove uevents will be generated. In the unusual case that
166 * the device isn't being dynamically allocated as a legacy "probe the
167 * hardware" driver, infrastructure code should reverse this marking.
168 */ 163 */
169struct platform_device *platform_device_alloc(const char *name, unsigned int id) 164struct platform_device *platform_device_alloc(const char *name, int id)
170{ 165{
171 struct platform_object *pa; 166 struct platform_object *pa;
172 167
@@ -177,12 +172,6 @@ struct platform_device *platform_device_alloc(const char *name, unsigned int id)
177 pa->pdev.id = id; 172 pa->pdev.id = id;
178 device_initialize(&pa->pdev.dev); 173 device_initialize(&pa->pdev.dev);
179 pa->pdev.dev.release = platform_device_release; 174 pa->pdev.dev.release = platform_device_release;
180
181 /* prevent hotplug "modprobe $(MODALIAS)" from causing trouble in
182 * legacy probe-the-hardware drivers, which don't properly split
183 * out device enumeration logic from drivers.
184 */
185 pa->pdev.dev.uevent_suppress = 1;
186 } 175 }
187 176
188 return pa ? &pa->pdev : NULL; 177 return pa ? &pa->pdev : NULL;
@@ -256,7 +245,8 @@ int platform_device_add(struct platform_device *pdev)
256 pdev->dev.bus = &platform_bus_type; 245 pdev->dev.bus = &platform_bus_type;
257 246
258 if (pdev->id != -1) 247 if (pdev->id != -1)
259 snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s.%u", pdev->name, pdev->id); 248 snprintf(pdev->dev.bus_id, BUS_ID_SIZE, "%s.%d", pdev->name,
249 pdev->id);
260 else 250 else
261 strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE); 251 strlcpy(pdev->dev.bus_id, pdev->name, BUS_ID_SIZE);
262 252
@@ -370,7 +360,7 @@ EXPORT_SYMBOL_GPL(platform_device_unregister);
370 * the Linux driver model. In particular, when such drivers are built 360 * the Linux driver model. In particular, when such drivers are built
371 * as modules, they can't be "hotplugged". 361 * as modules, they can't be "hotplugged".
372 */ 362 */
373struct platform_device *platform_device_register_simple(char *name, unsigned int id, 363struct platform_device *platform_device_register_simple(char *name, int id,
374 struct resource *res, unsigned int num) 364 struct resource *res, unsigned int num)
375{ 365{
376 struct platform_device *pdev; 366 struct platform_device *pdev;
@@ -530,7 +520,7 @@ static ssize_t
530modalias_show(struct device *dev, struct device_attribute *a, char *buf) 520modalias_show(struct device *dev, struct device_attribute *a, char *buf)
531{ 521{
532 struct platform_device *pdev = to_platform_device(dev); 522 struct platform_device *pdev = to_platform_device(dev);
533 int len = snprintf(buf, PAGE_SIZE, "%s\n", pdev->name); 523 int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name);
534 524
535 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; 525 return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
536} 526}
@@ -540,13 +530,11 @@ static struct device_attribute platform_dev_attrs[] = {
540 __ATTR_NULL, 530 __ATTR_NULL,
541}; 531};
542 532
543static int platform_uevent(struct device *dev, char **envp, int num_envp, 533static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
544 char *buffer, int buffer_size)
545{ 534{
546 struct platform_device *pdev = to_platform_device(dev); 535 struct platform_device *pdev = to_platform_device(dev);
547 536
548 envp[0] = buffer; 537 add_uevent_var(env, "MODALIAS=platform:%s", pdev->name);
549 snprintf(buffer, buffer_size, "MODALIAS=%s", pdev->name);
550 return 0; 538 return 0;
551} 539}
552 540
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile
index 9caeaea753a3..a803733c839e 100644
--- a/drivers/base/power/Makefile
+++ b/drivers/base/power/Makefile
@@ -1,5 +1,5 @@
1obj-y := shutdown.o 1obj-y := shutdown.o
2obj-$(CONFIG_PM_SLEEP) += main.o suspend.o resume.o sysfs.o 2obj-$(CONFIG_PM_SLEEP) += main.o sysfs.o
3obj-$(CONFIG_PM_TRACE) += trace.o 3obj-$(CONFIG_PM_TRACE) += trace.o
4 4
5ifeq ($(CONFIG_DEBUG_DRIVER),y) 5ifeq ($(CONFIG_DEBUG_DRIVER),y)
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index eb9f38d0aa58..0ab4ab21f564 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -20,19 +20,24 @@
20 */ 20 */
21 21
22#include <linux/device.h> 22#include <linux/device.h>
23#include <linux/kallsyms.h>
23#include <linux/mutex.h> 24#include <linux/mutex.h>
25#include <linux/pm.h>
26#include <linux/resume-trace.h>
24 27
28#include "../base.h"
25#include "power.h" 29#include "power.h"
26 30
27LIST_HEAD(dpm_active); 31LIST_HEAD(dpm_active);
28LIST_HEAD(dpm_off); 32static LIST_HEAD(dpm_off);
29LIST_HEAD(dpm_off_irq); 33static LIST_HEAD(dpm_off_irq);
30 34
31DEFINE_MUTEX(dpm_mtx); 35static DEFINE_MUTEX(dpm_mtx);
32DEFINE_MUTEX(dpm_list_mtx); 36static DEFINE_MUTEX(dpm_list_mtx);
33 37
34int (*platform_enable_wakeup)(struct device *dev, int is_on); 38int (*platform_enable_wakeup)(struct device *dev, int is_on);
35 39
40
36int device_pm_add(struct device *dev) 41int device_pm_add(struct device *dev)
37{ 42{
38 int error; 43 int error;
@@ -61,3 +66,334 @@ void device_pm_remove(struct device *dev)
61} 66}
62 67
63 68
69/*------------------------- Resume routines -------------------------*/
70
71/**
72 * resume_device - Restore state for one device.
73 * @dev: Device.
74 *
75 */
76
77static int resume_device(struct device * dev)
78{
79 int error = 0;
80
81 TRACE_DEVICE(dev);
82 TRACE_RESUME(0);
83
84 down(&dev->sem);
85
86 if (dev->bus && dev->bus->resume) {
87 dev_dbg(dev,"resuming\n");
88 error = dev->bus->resume(dev);
89 }
90
91 if (!error && dev->type && dev->type->resume) {
92 dev_dbg(dev,"resuming\n");
93 error = dev->type->resume(dev);
94 }
95
96 if (!error && dev->class && dev->class->resume) {
97 dev_dbg(dev,"class resume\n");
98 error = dev->class->resume(dev);
99 }
100
101 up(&dev->sem);
102
103 TRACE_RESUME(error);
104 return error;
105}
106
107
108static int resume_device_early(struct device * dev)
109{
110 int error = 0;
111
112 TRACE_DEVICE(dev);
113 TRACE_RESUME(0);
114 if (dev->bus && dev->bus->resume_early) {
115 dev_dbg(dev,"EARLY resume\n");
116 error = dev->bus->resume_early(dev);
117 }
118 TRACE_RESUME(error);
119 return error;
120}
121
122/*
123 * Resume the devices that have either not gone through
124 * the late suspend, or that did go through it but also
125 * went through the early resume
126 */
127static void dpm_resume(void)
128{
129 mutex_lock(&dpm_list_mtx);
130 while(!list_empty(&dpm_off)) {
131 struct list_head * entry = dpm_off.next;
132 struct device * dev = to_device(entry);
133
134 get_device(dev);
135 list_move_tail(entry, &dpm_active);
136
137 mutex_unlock(&dpm_list_mtx);
138 resume_device(dev);
139 mutex_lock(&dpm_list_mtx);
140 put_device(dev);
141 }
142 mutex_unlock(&dpm_list_mtx);
143}
144
145
146/**
147 * device_resume - Restore state of each device in system.
148 *
149 * Walk the dpm_off list, remove each entry, resume the device,
150 * then add it to the dpm_active list.
151 */
152
153void device_resume(void)
154{
155 might_sleep();
156 mutex_lock(&dpm_mtx);
157 dpm_resume();
158 mutex_unlock(&dpm_mtx);
159}
160
161EXPORT_SYMBOL_GPL(device_resume);
162
163
164/**
165 * dpm_power_up - Power on some devices.
166 *
167 * Walk the dpm_off_irq list and power each device up. This
168 * is used for devices that required they be powered down with
169 * interrupts disabled. As devices are powered on, they are moved
170 * to the dpm_active list.
171 *
172 * Interrupts must be disabled when calling this.
173 */
174
175static void dpm_power_up(void)
176{
177 while(!list_empty(&dpm_off_irq)) {
178 struct list_head * entry = dpm_off_irq.next;
179 struct device * dev = to_device(entry);
180
181 list_move_tail(entry, &dpm_off);
182 resume_device_early(dev);
183 }
184}
185
186
187/**
188 * device_power_up - Turn on all devices that need special attention.
189 *
190 * Power on system devices then devices that required we shut them down
191 * with interrupts disabled.
192 * Called with interrupts disabled.
193 */
194
195void device_power_up(void)
196{
197 sysdev_resume();
198 dpm_power_up();
199}
200
201EXPORT_SYMBOL_GPL(device_power_up);
202
203
204/*------------------------- Suspend routines -------------------------*/
205
206/*
207 * The entries in the dpm_active list are in a depth first order, simply
208 * because children are guaranteed to be discovered after parents, and
209 * are inserted at the back of the list on discovery.
210 *
211 * All list on the suspend path are done in reverse order, so we operate
212 * on the leaves of the device tree (or forests, depending on how you want
213 * to look at it ;) first. As nodes are removed from the back of the list,
214 * they are inserted into the front of their destintation lists.
215 *
216 * Things are the reverse on the resume path - iterations are done in
217 * forward order, and nodes are inserted at the back of their destination
218 * lists. This way, the ancestors will be accessed before their descendents.
219 */
220
221static inline char *suspend_verb(u32 event)
222{
223 switch (event) {
224 case PM_EVENT_SUSPEND: return "suspend";
225 case PM_EVENT_FREEZE: return "freeze";
226 case PM_EVENT_PRETHAW: return "prethaw";
227 default: return "(unknown suspend event)";
228 }
229}
230
231
232static void
233suspend_device_dbg(struct device *dev, pm_message_t state, char *info)
234{
235 dev_dbg(dev, "%s%s%s\n", info, suspend_verb(state.event),
236 ((state.event == PM_EVENT_SUSPEND) && device_may_wakeup(dev)) ?
237 ", may wakeup" : "");
238}
239
240/**
241 * suspend_device - Save state of one device.
242 * @dev: Device.
243 * @state: Power state device is entering.
244 */
245
246static int suspend_device(struct device * dev, pm_message_t state)
247{
248 int error = 0;
249
250 down(&dev->sem);
251 if (dev->power.power_state.event) {
252 dev_dbg(dev, "PM: suspend %d-->%d\n",
253 dev->power.power_state.event, state.event);
254 }
255
256 if (dev->class && dev->class->suspend) {
257 suspend_device_dbg(dev, state, "class ");
258 error = dev->class->suspend(dev, state);
259 suspend_report_result(dev->class->suspend, error);
260 }
261
262 if (!error && dev->type && dev->type->suspend) {
263 suspend_device_dbg(dev, state, "type ");
264 error = dev->type->suspend(dev, state);
265 suspend_report_result(dev->type->suspend, error);
266 }
267
268 if (!error && dev->bus && dev->bus->suspend) {
269 suspend_device_dbg(dev, state, "");
270 error = dev->bus->suspend(dev, state);
271 suspend_report_result(dev->bus->suspend, error);
272 }
273 up(&dev->sem);
274 return error;
275}
276
277
278/*
279 * This is called with interrupts off, only a single CPU
280 * running. We can't acquire a mutex or semaphore (and we don't
281 * need the protection)
282 */
283static int suspend_device_late(struct device *dev, pm_message_t state)
284{
285 int error = 0;
286
287 if (dev->bus && dev->bus->suspend_late) {
288 suspend_device_dbg(dev, state, "LATE ");
289 error = dev->bus->suspend_late(dev, state);
290 suspend_report_result(dev->bus->suspend_late, error);
291 }
292 return error;
293}
294
295/**
296 * device_suspend - Save state and stop all devices in system.
297 * @state: Power state to put each device in.
298 *
299 * Walk the dpm_active list, call ->suspend() for each device, and move
300 * it to the dpm_off list.
301 *
302 * (For historical reasons, if it returns -EAGAIN, that used to mean
303 * that the device would be called again with interrupts disabled.
304 * These days, we use the "suspend_late()" callback for that, so we
305 * print a warning and consider it an error).
306 *
307 * If we get a different error, try and back out.
308 *
309 * If we hit a failure with any of the devices, call device_resume()
310 * above to bring the suspended devices back to life.
311 *
312 */
313
314int device_suspend(pm_message_t state)
315{
316 int error = 0;
317
318 might_sleep();
319 mutex_lock(&dpm_mtx);
320 mutex_lock(&dpm_list_mtx);
321 while (!list_empty(&dpm_active) && error == 0) {
322 struct list_head * entry = dpm_active.prev;
323 struct device * dev = to_device(entry);
324
325 get_device(dev);
326 mutex_unlock(&dpm_list_mtx);
327
328 error = suspend_device(dev, state);
329
330 mutex_lock(&dpm_list_mtx);
331
332 /* Check if the device got removed */
333 if (!list_empty(&dev->power.entry)) {
334 /* Move it to the dpm_off list */
335 if (!error)
336 list_move(&dev->power.entry, &dpm_off);
337 }
338 if (error)
339 printk(KERN_ERR "Could not suspend device %s: "
340 "error %d%s\n",
341 kobject_name(&dev->kobj), error,
342 error == -EAGAIN ? " (please convert to suspend_late)" : "");
343 put_device(dev);
344 }
345 mutex_unlock(&dpm_list_mtx);
346 if (error)
347 dpm_resume();
348
349 mutex_unlock(&dpm_mtx);
350 return error;
351}
352
353EXPORT_SYMBOL_GPL(device_suspend);
354
355/**
356 * device_power_down - Shut down special devices.
357 * @state: Power state to enter.
358 *
359 * Walk the dpm_off_irq list, calling ->power_down() for each device that
360 * couldn't power down the device with interrupts enabled. When we're
361 * done, power down system devices.
362 */
363
364int device_power_down(pm_message_t state)
365{
366 int error = 0;
367 struct device * dev;
368
369 while (!list_empty(&dpm_off)) {
370 struct list_head * entry = dpm_off.prev;
371
372 dev = to_device(entry);
373 error = suspend_device_late(dev, state);
374 if (error)
375 goto Error;
376 list_move(&dev->power.entry, &dpm_off_irq);
377 }
378
379 error = sysdev_suspend(state);
380 Done:
381 return error;
382 Error:
383 printk(KERN_ERR "Could not power down device %s: "
384 "error %d\n", kobject_name(&dev->kobj), error);
385 dpm_power_up();
386 goto Done;
387}
388
389EXPORT_SYMBOL_GPL(device_power_down);
390
391void __suspend_report_result(const char *function, void *fn, int ret)
392{
393 if (ret) {
394 printk(KERN_ERR "%s(): ", function);
395 print_fn_descriptor_symbol("%s() returns ", (unsigned long)fn);
396 printk("%d\n", ret);
397 }
398}
399EXPORT_SYMBOL_GPL(__suspend_report_result);
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index 8ba0830cbc03..5c4efd493fa5 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -11,32 +11,11 @@ extern void device_shutdown(void);
11 * main.c 11 * main.c
12 */ 12 */
13 13
14/* 14extern struct list_head dpm_active; /* The active device list */
15 * Used to synchronize global power management operations.
16 */
17extern struct mutex dpm_mtx;
18
19/*
20 * Used to serialize changes to the dpm_* lists.
21 */
22extern struct mutex dpm_list_mtx;
23
24/*
25 * The PM lists.
26 */
27extern struct list_head dpm_active;
28extern struct list_head dpm_off;
29extern struct list_head dpm_off_irq;
30
31
32static inline struct dev_pm_info * to_pm_info(struct list_head * entry)
33{
34 return container_of(entry, struct dev_pm_info, entry);
35}
36 15
37static inline struct device * to_device(struct list_head * entry) 16static inline struct device * to_device(struct list_head * entry)
38{ 17{
39 return container_of(to_pm_info(entry), struct device, power); 18 return container_of(entry, struct device, power.entry);
40} 19}
41 20
42extern int device_pm_add(struct device *); 21extern int device_pm_add(struct device *);
@@ -49,19 +28,6 @@ extern void device_pm_remove(struct device *);
49extern int dpm_sysfs_add(struct device *); 28extern int dpm_sysfs_add(struct device *);
50extern void dpm_sysfs_remove(struct device *); 29extern void dpm_sysfs_remove(struct device *);
51 30
52/*
53 * resume.c
54 */
55
56extern void dpm_resume(void);
57extern void dpm_power_up(void);
58extern int resume_device(struct device *);
59
60/*
61 * suspend.c
62 */
63extern int suspend_device(struct device *, pm_message_t);
64
65#else /* CONFIG_PM_SLEEP */ 31#else /* CONFIG_PM_SLEEP */
66 32
67 33
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
deleted file mode 100644
index 00fd84ae6e66..000000000000
--- a/drivers/base/power/resume.c
+++ /dev/null
@@ -1,149 +0,0 @@
1/*
2 * resume.c - Functions for waking devices up.
3 *
4 * Copyright (c) 2003 Patrick Mochel
5 * Copyright (c) 2003 Open Source Development Labs
6 *
7 * This file is released under the GPLv2
8 *
9 */
10
11#include <linux/device.h>
12#include <linux/resume-trace.h>
13#include "../base.h"
14#include "power.h"
15
16
17/**
18 * resume_device - Restore state for one device.
19 * @dev: Device.
20 *
21 */
22
23int resume_device(struct device * dev)
24{
25 int error = 0;
26
27 TRACE_DEVICE(dev);
28 TRACE_RESUME(0);
29
30 down(&dev->sem);
31
32 if (dev->bus && dev->bus->resume) {
33 dev_dbg(dev,"resuming\n");
34 error = dev->bus->resume(dev);
35 }
36
37 if (!error && dev->type && dev->type->resume) {
38 dev_dbg(dev,"resuming\n");
39 error = dev->type->resume(dev);
40 }
41
42 if (!error && dev->class && dev->class->resume) {
43 dev_dbg(dev,"class resume\n");
44 error = dev->class->resume(dev);
45 }
46
47 up(&dev->sem);
48
49 TRACE_RESUME(error);
50 return error;
51}
52
53
54static int resume_device_early(struct device * dev)
55{
56 int error = 0;
57
58 TRACE_DEVICE(dev);
59 TRACE_RESUME(0);
60 if (dev->bus && dev->bus->resume_early) {
61 dev_dbg(dev,"EARLY resume\n");
62 error = dev->bus->resume_early(dev);
63 }
64 TRACE_RESUME(error);
65 return error;
66}
67
68/*
69 * Resume the devices that have either not gone through
70 * the late suspend, or that did go through it but also
71 * went through the early resume
72 */
73void dpm_resume(void)
74{
75 mutex_lock(&dpm_list_mtx);
76 while(!list_empty(&dpm_off)) {
77 struct list_head * entry = dpm_off.next;
78 struct device * dev = to_device(entry);
79
80 get_device(dev);
81 list_move_tail(entry, &dpm_active);
82
83 mutex_unlock(&dpm_list_mtx);
84 resume_device(dev);
85 mutex_lock(&dpm_list_mtx);
86 put_device(dev);
87 }
88 mutex_unlock(&dpm_list_mtx);
89}
90
91
92/**
93 * device_resume - Restore state of each device in system.
94 *
95 * Walk the dpm_off list, remove each entry, resume the device,
96 * then add it to the dpm_active list.
97 */
98
99void device_resume(void)
100{
101 might_sleep();
102 mutex_lock(&dpm_mtx);
103 dpm_resume();
104 mutex_unlock(&dpm_mtx);
105}
106
107EXPORT_SYMBOL_GPL(device_resume);
108
109
110/**
111 * dpm_power_up - Power on some devices.
112 *
113 * Walk the dpm_off_irq list and power each device up. This
114 * is used for devices that required they be powered down with
115 * interrupts disabled. As devices are powered on, they are moved
116 * to the dpm_active list.
117 *
118 * Interrupts must be disabled when calling this.
119 */
120
121void dpm_power_up(void)
122{
123 while(!list_empty(&dpm_off_irq)) {
124 struct list_head * entry = dpm_off_irq.next;
125 struct device * dev = to_device(entry);
126
127 list_move_tail(entry, &dpm_off);
128 resume_device_early(dev);
129 }
130}
131
132
133/**
134 * device_power_up - Turn on all devices that need special attention.
135 *
136 * Power on system devices then devices that required we shut them down
137 * with interrupts disabled.
138 * Called with interrupts disabled.
139 */
140
141void device_power_up(void)
142{
143 sysdev_resume();
144 dpm_power_up();
145}
146
147EXPORT_SYMBOL_GPL(device_power_up);
148
149
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c
deleted file mode 100644
index 26df9b231737..000000000000
--- a/drivers/base/power/suspend.c
+++ /dev/null
@@ -1,210 +0,0 @@
1/*
2 * suspend.c - Functions for putting devices to sleep.
3 *
4 * Copyright (c) 2003 Patrick Mochel
5 * Copyright (c) 2003 Open Source Development Labs
6 *
7 * This file is released under the GPLv2
8 *
9 */
10
11#include <linux/device.h>
12#include <linux/kallsyms.h>
13#include <linux/pm.h>
14#include "../base.h"
15#include "power.h"
16
17/*
18 * The entries in the dpm_active list are in a depth first order, simply
19 * because children are guaranteed to be discovered after parents, and
20 * are inserted at the back of the list on discovery.
21 *
22 * All list on the suspend path are done in reverse order, so we operate
23 * on the leaves of the device tree (or forests, depending on how you want
24 * to look at it ;) first. As nodes are removed from the back of the list,
25 * they are inserted into the front of their destintation lists.
26 *
27 * Things are the reverse on the resume path - iterations are done in
28 * forward order, and nodes are inserted at the back of their destination
29 * lists. This way, the ancestors will be accessed before their descendents.
30 */
31
32static inline char *suspend_verb(u32 event)
33{
34 switch (event) {
35 case PM_EVENT_SUSPEND: return "suspend";
36 case PM_EVENT_FREEZE: return "freeze";
37 case PM_EVENT_PRETHAW: return "prethaw";
38 default: return "(unknown suspend event)";
39 }
40}
41
42
43static void
44suspend_device_dbg(struct device *dev, pm_message_t state, char *info)
45{
46 dev_dbg(dev, "%s%s%s\n", info, suspend_verb(state.event),
47 ((state.event == PM_EVENT_SUSPEND) && device_may_wakeup(dev)) ?
48 ", may wakeup" : "");
49}
50
51/**
52 * suspend_device - Save state of one device.
53 * @dev: Device.
54 * @state: Power state device is entering.
55 */
56
57int suspend_device(struct device * dev, pm_message_t state)
58{
59 int error = 0;
60
61 down(&dev->sem);
62 if (dev->power.power_state.event) {
63 dev_dbg(dev, "PM: suspend %d-->%d\n",
64 dev->power.power_state.event, state.event);
65 }
66
67 if (dev->class && dev->class->suspend) {
68 suspend_device_dbg(dev, state, "class ");
69 error = dev->class->suspend(dev, state);
70 suspend_report_result(dev->class->suspend, error);
71 }
72
73 if (!error && dev->type && dev->type->suspend) {
74 suspend_device_dbg(dev, state, "type ");
75 error = dev->type->suspend(dev, state);
76 suspend_report_result(dev->type->suspend, error);
77 }
78
79 if (!error && dev->bus && dev->bus->suspend) {
80 suspend_device_dbg(dev, state, "");
81 error = dev->bus->suspend(dev, state);
82 suspend_report_result(dev->bus->suspend, error);
83 }
84 up(&dev->sem);
85 return error;
86}
87
88
89/*
90 * This is called with interrupts off, only a single CPU
91 * running. We can't acquire a mutex or semaphore (and we don't
92 * need the protection)
93 */
94static int suspend_device_late(struct device *dev, pm_message_t state)
95{
96 int error = 0;
97
98 if (dev->bus && dev->bus->suspend_late) {
99 suspend_device_dbg(dev, state, "LATE ");
100 error = dev->bus->suspend_late(dev, state);
101 suspend_report_result(dev->bus->suspend_late, error);
102 }
103 return error;
104}
105
106/**
107 * device_suspend - Save state and stop all devices in system.
108 * @state: Power state to put each device in.
109 *
110 * Walk the dpm_active list, call ->suspend() for each device, and move
111 * it to the dpm_off list.
112 *
113 * (For historical reasons, if it returns -EAGAIN, that used to mean
114 * that the device would be called again with interrupts disabled.
115 * These days, we use the "suspend_late()" callback for that, so we
116 * print a warning and consider it an error).
117 *
118 * If we get a different error, try and back out.
119 *
120 * If we hit a failure with any of the devices, call device_resume()
121 * above to bring the suspended devices back to life.
122 *
123 */
124
125int device_suspend(pm_message_t state)
126{
127 int error = 0;
128
129 might_sleep();
130 mutex_lock(&dpm_mtx);
131 mutex_lock(&dpm_list_mtx);
132 while (!list_empty(&dpm_active) && error == 0) {
133 struct list_head * entry = dpm_active.prev;
134 struct device * dev = to_device(entry);
135
136 get_device(dev);
137 mutex_unlock(&dpm_list_mtx);
138
139 error = suspend_device(dev, state);
140
141 mutex_lock(&dpm_list_mtx);
142
143 /* Check if the device got removed */
144 if (!list_empty(&dev->power.entry)) {
145 /* Move it to the dpm_off list */
146 if (!error)
147 list_move(&dev->power.entry, &dpm_off);
148 }
149 if (error)
150 printk(KERN_ERR "Could not suspend device %s: "
151 "error %d%s\n",
152 kobject_name(&dev->kobj), error,
153 error == -EAGAIN ? " (please convert to suspend_late)" : "");
154 put_device(dev);
155 }
156 mutex_unlock(&dpm_list_mtx);
157 if (error)
158 dpm_resume();
159
160 mutex_unlock(&dpm_mtx);
161 return error;
162}
163
164EXPORT_SYMBOL_GPL(device_suspend);
165
166/**
167 * device_power_down - Shut down special devices.
168 * @state: Power state to enter.
169 *
170 * Walk the dpm_off_irq list, calling ->power_down() for each device that
171 * couldn't power down the device with interrupts enabled. When we're
172 * done, power down system devices.
173 */
174
175int device_power_down(pm_message_t state)
176{
177 int error = 0;
178 struct device * dev;
179
180 while (!list_empty(&dpm_off)) {
181 struct list_head * entry = dpm_off.prev;
182
183 dev = to_device(entry);
184 error = suspend_device_late(dev, state);
185 if (error)
186 goto Error;
187 list_move(&dev->power.entry, &dpm_off_irq);
188 }
189
190 error = sysdev_suspend(state);
191 Done:
192 return error;
193 Error:
194 printk(KERN_ERR "Could not power down device %s: "
195 "error %d\n", kobject_name(&dev->kobj), error);
196 dpm_power_up();
197 goto Done;
198}
199
200EXPORT_SYMBOL_GPL(device_power_down);
201
202void __suspend_report_result(const char *function, void *fn, int ret)
203{
204 if (ret) {
205 printk(KERN_ERR "%s(): ", function);
206 print_fn_descriptor_symbol("%s() returns ", (unsigned long)fn);
207 printk("%d\n", ret);
208 }
209}
210EXPORT_SYMBOL_GPL(__suspend_report_result);
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index 18febe26caa1..ac7ff6d0c6e5 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -139,7 +139,7 @@ int sysdev_class_register(struct sysdev_class * cls)
139 kobject_name(&cls->kset.kobj)); 139 kobject_name(&cls->kset.kobj));
140 INIT_LIST_HEAD(&cls->drivers); 140 INIT_LIST_HEAD(&cls->drivers);
141 cls->kset.kobj.parent = &system_subsys.kobj; 141 cls->kset.kobj.parent = &system_subsys.kobj;
142 kset_set_kset_s(cls, system_subsys); 142 cls->kset.kobj.kset = &system_subsys;
143 return kset_register(&cls->kset); 143 return kset_register(&cls->kset);
144} 144}
145 145
@@ -153,25 +153,22 @@ void sysdev_class_unregister(struct sysdev_class * cls)
153EXPORT_SYMBOL_GPL(sysdev_class_register); 153EXPORT_SYMBOL_GPL(sysdev_class_register);
154EXPORT_SYMBOL_GPL(sysdev_class_unregister); 154EXPORT_SYMBOL_GPL(sysdev_class_unregister);
155 155
156
157static LIST_HEAD(sysdev_drivers);
158static DEFINE_MUTEX(sysdev_drivers_lock); 156static DEFINE_MUTEX(sysdev_drivers_lock);
159 157
160/** 158/**
161 * sysdev_driver_register - Register auxillary driver 159 * sysdev_driver_register - Register auxillary driver
162 * @cls: Device class driver belongs to. 160 * @cls: Device class driver belongs to.
163 * @drv: Driver. 161 * @drv: Driver.
164 * 162 *
165 * If @cls is valid, then @drv is inserted into @cls->drivers to be 163 * @drv is inserted into @cls->drivers to be
166 * called on each operation on devices of that class. The refcount 164 * called on each operation on devices of that class. The refcount
167 * of @cls is incremented. 165 * of @cls is incremented.
168 * Otherwise, @drv is inserted into sysdev_drivers, and called for
169 * each device.
170 */ 166 */
171 167
172int sysdev_driver_register(struct sysdev_class * cls, 168int sysdev_driver_register(struct sysdev_class *cls, struct sysdev_driver *drv)
173 struct sysdev_driver * drv)
174{ 169{
170 int err = 0;
171
175 mutex_lock(&sysdev_drivers_lock); 172 mutex_lock(&sysdev_drivers_lock);
176 if (cls && kset_get(&cls->kset)) { 173 if (cls && kset_get(&cls->kset)) {
177 list_add_tail(&drv->entry, &cls->drivers); 174 list_add_tail(&drv->entry, &cls->drivers);
@@ -182,10 +179,13 @@ int sysdev_driver_register(struct sysdev_class * cls,
182 list_for_each_entry(dev, &cls->kset.list, kobj.entry) 179 list_for_each_entry(dev, &cls->kset.list, kobj.entry)
183 drv->add(dev); 180 drv->add(dev);
184 } 181 }
185 } else 182 } else {
186 list_add_tail(&drv->entry, &sysdev_drivers); 183 err = -EINVAL;
184 printk(KERN_ERR "%s: invalid device class\n", __FUNCTION__);
185 WARN_ON(1);
186 }
187 mutex_unlock(&sysdev_drivers_lock); 187 mutex_unlock(&sysdev_drivers_lock);
188 return 0; 188 return err;
189} 189}
190 190
191 191
@@ -251,12 +251,6 @@ int sysdev_register(struct sys_device * sysdev)
251 * code that should have called us. 251 * code that should have called us.
252 */ 252 */
253 253
254 /* Notify global drivers */
255 list_for_each_entry(drv, &sysdev_drivers, entry) {
256 if (drv->add)
257 drv->add(sysdev);
258 }
259
260 /* Notify class auxillary drivers */ 254 /* Notify class auxillary drivers */
261 list_for_each_entry(drv, &cls->drivers, entry) { 255 list_for_each_entry(drv, &cls->drivers, entry) {
262 if (drv->add) 256 if (drv->add)
@@ -272,11 +266,6 @@ void sysdev_unregister(struct sys_device * sysdev)
272 struct sysdev_driver * drv; 266 struct sysdev_driver * drv;
273 267
274 mutex_lock(&sysdev_drivers_lock); 268 mutex_lock(&sysdev_drivers_lock);
275 list_for_each_entry(drv, &sysdev_drivers, entry) {
276 if (drv->remove)
277 drv->remove(sysdev);
278 }
279
280 list_for_each_entry(drv, &sysdev->cls->drivers, entry) { 269 list_for_each_entry(drv, &sysdev->cls->drivers, entry) {
281 if (drv->remove) 270 if (drv->remove)
282 drv->remove(sysdev); 271 drv->remove(sysdev);
@@ -293,7 +282,7 @@ void sysdev_unregister(struct sys_device * sysdev)
293 * 282 *
294 * Loop over each class of system devices, and the devices in each 283 * Loop over each class of system devices, and the devices in each
295 * of those classes. For each device, we call the shutdown method for 284 * of those classes. For each device, we call the shutdown method for
296 * each driver registered for the device - the globals, the auxillaries, 285 * each driver registered for the device - the auxillaries,
297 * and the class driver. 286 * and the class driver.
298 * 287 *
299 * Note: The list is iterated in reverse order, so that we shut down 288 * Note: The list is iterated in reverse order, so that we shut down
@@ -320,13 +309,7 @@ void sysdev_shutdown(void)
320 struct sysdev_driver * drv; 309 struct sysdev_driver * drv;
321 pr_debug(" %s\n", kobject_name(&sysdev->kobj)); 310 pr_debug(" %s\n", kobject_name(&sysdev->kobj));
322 311
323 /* Call global drivers first. */ 312 /* Call auxillary drivers first */
324 list_for_each_entry(drv, &sysdev_drivers, entry) {
325 if (drv->shutdown)
326 drv->shutdown(sysdev);
327 }
328
329 /* Call auxillary drivers next. */
330 list_for_each_entry(drv, &cls->drivers, entry) { 313 list_for_each_entry(drv, &cls->drivers, entry) {
331 if (drv->shutdown) 314 if (drv->shutdown)
332 drv->shutdown(sysdev); 315 drv->shutdown(sysdev);
@@ -354,12 +337,6 @@ static void __sysdev_resume(struct sys_device *dev)
354 if (drv->resume) 337 if (drv->resume)
355 drv->resume(dev); 338 drv->resume(dev);
356 } 339 }
357
358 /* Call global drivers. */
359 list_for_each_entry(drv, &sysdev_drivers, entry) {
360 if (drv->resume)
361 drv->resume(dev);
362 }
363} 340}
364 341
365/** 342/**
@@ -393,16 +370,7 @@ int sysdev_suspend(pm_message_t state)
393 list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) { 370 list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
394 pr_debug(" %s\n", kobject_name(&sysdev->kobj)); 371 pr_debug(" %s\n", kobject_name(&sysdev->kobj));
395 372
396 /* Call global drivers first. */ 373 /* Call auxillary drivers first */
397 list_for_each_entry(drv, &sysdev_drivers, entry) {
398 if (drv->suspend) {
399 ret = drv->suspend(sysdev, state);
400 if (ret)
401 goto gbl_driver;
402 }
403 }
404
405 /* Call auxillary drivers next. */
406 list_for_each_entry(drv, &cls->drivers, entry) { 374 list_for_each_entry(drv, &cls->drivers, entry) {
407 if (drv->suspend) { 375 if (drv->suspend) {
408 ret = drv->suspend(sysdev, state); 376 ret = drv->suspend(sysdev, state);
@@ -436,18 +404,7 @@ aux_driver:
436 if (err_drv->resume) 404 if (err_drv->resume)
437 err_drv->resume(sysdev); 405 err_drv->resume(sysdev);
438 } 406 }
439 drv = NULL;
440 407
441gbl_driver:
442 if (drv)
443 printk(KERN_ERR "sysdev driver suspend failed for %s\n",
444 kobject_name(&sysdev->kobj));
445 list_for_each_entry(err_drv, &sysdev_drivers, entry) {
446 if (err_drv == drv)
447 break;
448 if (err_drv->resume)
449 err_drv->resume(sysdev);
450 }
451 /* resume other sysdevs in current class */ 408 /* resume other sysdevs in current class */
452 list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) { 409 list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) {
453 if (err_dev == sysdev) 410 if (err_dev == sysdev)
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index 9b8278e1f4f8..acbfe1c49b4d 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -513,7 +513,7 @@ static int __init dsp56k_init_driver(void)
513 err = PTR_ERR(dsp56k_class); 513 err = PTR_ERR(dsp56k_class);
514 goto out_chrdev; 514 goto out_chrdev;
515 } 515 }
516 class_device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k"); 516 device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), "dsp56k");
517 517
518 printk(banner); 518 printk(banner);
519 goto out; 519 goto out;
@@ -527,7 +527,7 @@ module_init(dsp56k_init_driver);
527 527
528static void __exit dsp56k_cleanup_driver(void) 528static void __exit dsp56k_cleanup_driver(void)
529{ 529{
530 class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0)); 530 device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0));
531 class_destroy(dsp56k_class); 531 class_destroy(dsp56k_class);
532 unregister_chrdev(DSP56K_MAJOR, "dsp56k"); 532 unregister_chrdev(DSP56K_MAJOR, "dsp56k");
533} 533}
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 8d74b8745e60..bd94d5f9e62b 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -411,8 +411,8 @@ cleanup_module(void)
411 iiResetDelay( i2BoardPtrTable[i] ); 411 iiResetDelay( i2BoardPtrTable[i] );
412 /* free io addresses and Tibet */ 412 /* free io addresses and Tibet */
413 release_region( ip2config.addr[i], 8 ); 413 release_region( ip2config.addr[i], 8 );
414 class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); 414 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
415 class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); 415 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
416 } 416 }
417 /* Disable and remove interrupt handler. */ 417 /* Disable and remove interrupt handler. */
418 if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { 418 if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) {
@@ -718,12 +718,12 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
718 } 718 }
719 719
720 if ( NULL != ( pB = i2BoardPtrTable[i] ) ) { 720 if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
721 class_device_create(ip2_class, NULL, 721 device_create(ip2_class, NULL,
722 MKDEV(IP2_IPL_MAJOR, 4 * i), 722 MKDEV(IP2_IPL_MAJOR, 4 * i),
723 NULL, "ipl%d", i); 723 "ipl%d", i);
724 class_device_create(ip2_class, NULL, 724 device_create(ip2_class, NULL,
725 MKDEV(IP2_IPL_MAJOR, 4 * i + 1), 725 MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
726 NULL, "stat%d", i); 726 "stat%d", i);
727 727
728 for ( box = 0; box < ABS_MAX_BOXES; ++box ) 728 for ( box = 0; box < ABS_MAX_BOXES; ++box )
729 { 729 {
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index c2aa44ee6eb6..0246a2b8ce48 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -865,7 +865,7 @@ static void ipmi_new_smi(int if_num, struct device *device)
865 entry->dev = dev; 865 entry->dev = dev;
866 866
867 mutex_lock(&reg_list_mutex); 867 mutex_lock(&reg_list_mutex);
868 class_device_create(ipmi_class, NULL, dev, device, "ipmi%d", if_num); 868 device_create(ipmi_class, device, dev, "ipmi%d", if_num);
869 list_add(&entry->link, &reg_list); 869 list_add(&entry->link, &reg_list);
870 mutex_unlock(&reg_list_mutex); 870 mutex_unlock(&reg_list_mutex);
871} 871}
@@ -883,7 +883,7 @@ static void ipmi_smi_gone(int if_num)
883 break; 883 break;
884 } 884 }
885 } 885 }
886 class_device_destroy(ipmi_class, dev); 886 device_destroy(ipmi_class, dev);
887 mutex_unlock(&reg_list_mutex); 887 mutex_unlock(&reg_list_mutex);
888} 888}
889 889
@@ -938,7 +938,7 @@ static __exit void cleanup_ipmi(void)
938 mutex_lock(&reg_list_mutex); 938 mutex_lock(&reg_list_mutex);
939 list_for_each_entry_safe(entry, entry2, &reg_list, link) { 939 list_for_each_entry_safe(entry, entry2, &reg_list, link) {
940 list_del(&entry->link); 940 list_del(&entry->link);
941 class_device_destroy(ipmi_class, entry->dev); 941 device_destroy(ipmi_class, entry->dev);
942 kfree(entry); 942 kfree(entry);
943 } 943 }
944 mutex_unlock(&reg_list_mutex); 944 mutex_unlock(&reg_list_mutex);
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 3c66f402f9d7..1f27be1ec3d4 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -4624,9 +4624,8 @@ static int __init istallion_module_init(void)
4624 4624
4625 istallion_class = class_create(THIS_MODULE, "staliomem"); 4625 istallion_class = class_create(THIS_MODULE, "staliomem");
4626 for (i = 0; i < 4; i++) 4626 for (i = 0; i < 4; i++)
4627 class_device_create(istallion_class, NULL, 4627 device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
4628 MKDEV(STL_SIOMEMMAJOR, i), 4628 "staliomem%d", i);
4629 NULL, "staliomem%d", i);
4630 4629
4631 return 0; 4630 return 0;
4632err_deinit: 4631err_deinit:
@@ -4659,8 +4658,7 @@ static void __exit istallion_module_exit(void)
4659 unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); 4658 unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
4660 4659
4661 for (j = 0; j < 4; j++) 4660 for (j = 0; j < 4; j++)
4662 class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, 4661 device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, j));
4663 j));
4664 class_destroy(istallion_class); 4662 class_destroy(istallion_class);
4665 4663
4666 pci_unregister_driver(&stli_pcidriver); 4664 pci_unregister_driver(&stli_pcidriver);
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 62051f8b0910..c59e2a0996cc 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -799,8 +799,7 @@ static int lp_register(int nr, struct parport *port)
799 if (reset) 799 if (reset)
800 lp_reset(nr); 800 lp_reset(nr);
801 801
802 class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), port->dev, 802 device_create(lp_class, port->dev, MKDEV(LP_MAJOR, nr), "lp%d", nr);
803 "lp%d", nr);
804 803
805 printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, 804 printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name,
806 (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven"); 805 (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven");
@@ -971,7 +970,7 @@ static void lp_cleanup_module (void)
971 if (lp_table[offset].dev == NULL) 970 if (lp_table[offset].dev == NULL)
972 continue; 971 continue;
973 parport_unregister_device(lp_table[offset].dev); 972 parport_unregister_device(lp_table[offset].dev);
974 class_device_destroy(lp_class, MKDEV(LP_MAJOR, offset)); 973 device_destroy(lp_class, MKDEV(LP_MAJOR, offset));
975 } 974 }
976 class_destroy(lp_class); 975 class_destroy(lp_class);
977} 976}
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 4177f6db83e9..cc5d77797def 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1863,8 +1863,7 @@ static int cm4000_probe(struct pcmcia_device *link)
1863 return ret; 1863 return ret;
1864 } 1864 }
1865 1865
1866 class_device_create(cmm_class, NULL, MKDEV(major, i), NULL, 1866 device_create(cmm_class, NULL, MKDEV(major, i), "cmm%d", i);
1867 "cmm%d", i);
1868 1867
1869 return 0; 1868 return 0;
1870} 1869}
@@ -1888,7 +1887,7 @@ static void cm4000_detach(struct pcmcia_device *link)
1888 dev_table[devno] = NULL; 1887 dev_table[devno] = NULL;
1889 kfree(dev); 1888 kfree(dev);
1890 1889
1891 class_device_destroy(cmm_class, MKDEV(major, devno)); 1890 device_destroy(cmm_class, MKDEV(major, devno));
1892 1891
1893 return; 1892 return;
1894} 1893}
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index b24a3e7bbb9f..a0b9c8728d56 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -642,8 +642,7 @@ static int reader_probe(struct pcmcia_device *link)
642 return ret; 642 return ret;
643 } 643 }
644 644
645 class_device_create(cmx_class, NULL, MKDEV(major, i), NULL, 645 device_create(cmx_class, NULL, MKDEV(major, i), "cmx%d", i);
646 "cmx%d", i);
647 646
648 return 0; 647 return 0;
649} 648}
@@ -666,7 +665,7 @@ static void reader_detach(struct pcmcia_device *link)
666 dev_table[devno] = NULL; 665 dev_table[devno] = NULL;
667 kfree(dev); 666 kfree(dev);
668 667
669 class_device_destroy(cmx_class, MKDEV(major, devno)); 668 device_destroy(cmx_class, MKDEV(major, devno));
670 669
671 return; 670 return;
672} 671}
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index de14aea34e11..73de77105fea 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -248,14 +248,19 @@ static int pty_bsd_ioctl(struct tty_struct *tty, struct file *file,
248 return -ENOIOCTLCMD; 248 return -ENOIOCTLCMD;
249} 249}
250 250
251static int legacy_count = CONFIG_LEGACY_PTY_COUNT;
252module_param(legacy_count, int, 0);
253
251static void __init legacy_pty_init(void) 254static void __init legacy_pty_init(void)
252{ 255{
256 if (legacy_count <= 0)
257 return;
253 258
254 pty_driver = alloc_tty_driver(NR_PTYS); 259 pty_driver = alloc_tty_driver(legacy_count);
255 if (!pty_driver) 260 if (!pty_driver)
256 panic("Couldn't allocate pty driver"); 261 panic("Couldn't allocate pty driver");
257 262
258 pty_slave_driver = alloc_tty_driver(NR_PTYS); 263 pty_slave_driver = alloc_tty_driver(legacy_count);
259 if (!pty_slave_driver) 264 if (!pty_slave_driver)
260 panic("Couldn't allocate pty slave driver"); 265 panic("Couldn't allocate pty slave driver");
261 266
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 1f0d7c60c944..bbfa0e241cba 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -255,10 +255,7 @@ static const struct file_operations raw_ctl_fops = {
255 .owner = THIS_MODULE, 255 .owner = THIS_MODULE,
256}; 256};
257 257
258static struct cdev raw_cdev = { 258static struct cdev raw_cdev;
259 .kobj = {.name = "raw", },
260 .owner = THIS_MODULE,
261};
262 259
263static int __init raw_init(void) 260static int __init raw_init(void)
264{ 261{
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index 52753e723eaa..b9c1dba6bd01 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -441,8 +441,7 @@ scdrv_init(void)
441 continue; 441 continue;
442 } 442 }
443 443
444 class_device_create(snsc_class, NULL, dev, NULL, 444 device_create(snsc_class, NULL, dev, "%s", devname);
445 "%s", devname);
446 445
447 ia64_sn_irtr_intr_enable(scd->scd_nasid, 446 ia64_sn_irtr_intr_enable(scd->scd_nasid,
448 0 /*ignored */ , 447 0 /*ignored */ ,
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 4a80b2f864e0..45758d5b56ef 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -4778,9 +4778,8 @@ static int __init stallion_module_init(void)
4778 if (IS_ERR(stallion_class)) 4778 if (IS_ERR(stallion_class))
4779 printk("STALLION: failed to create class\n"); 4779 printk("STALLION: failed to create class\n");
4780 for (i = 0; i < 4; i++) 4780 for (i = 0; i < 4; i++)
4781 class_device_create(stallion_class, NULL, 4781 device_create(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
4782 MKDEV(STL_SIOMEMMAJOR, i), NULL, 4782 "staliomem%d", i);
4783 "staliomem%d", i);
4784 4783
4785 return 0; 4784 return 0;
4786err_unrtty: 4785err_unrtty:
@@ -4816,7 +4815,7 @@ static void __exit stallion_module_exit(void)
4816 } 4815 }
4817 4816
4818 for (i = 0; i < 4; i++) 4817 for (i = 0; i < 4; i++)
4819 class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); 4818 device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
4820 unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); 4819 unregister_chrdev(STL_SIOMEMMAJOR, "staliomem");
4821 class_destroy(stallion_class); 4820 class_destroy(stallion_class);
4822 4821
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index 35b40b996534..cef55c40654f 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -441,8 +441,8 @@ tipar_register(int nr, struct parport *port)
441 goto out; 441 goto out;
442 } 442 }
443 443
444 class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR, 444 device_create(tipar_class, port->dev, MKDEV(TIPAR_MAJOR,
445 TIPAR_MINOR + nr), port->dev, "par%d", nr); 445 TIPAR_MINOR + nr), "par%d", nr);
446 446
447 /* Display informations */ 447 /* Display informations */
448 pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq == 448 pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq ==
@@ -534,7 +534,7 @@ tipar_cleanup_module(void)
534 if (table[i].dev == NULL) 534 if (table[i].dev == NULL)
535 continue; 535 continue;
536 parport_unregister_device(table[i].dev); 536 parport_unregister_device(table[i].dev);
537 class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i)); 537 device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i));
538 } 538 }
539 class_destroy(tipar_class); 539 class_destroy(tipar_class);
540 540
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index f1d60f0cef8f..db7a731e2362 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -871,10 +871,10 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
871 state[i].cur_part = 0; 871 state[i].cur_part = 0;
872 for (j = 0; j < MAX_PARTITIONS; ++j) 872 for (j = 0; j < MAX_PARTITIONS; ++j)
873 state[i].part_stat_rwi[j] = VIOT_IDLE; 873 state[i].part_stat_rwi[j] = VIOT_IDLE;
874 class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL, 874 device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i),
875 "iseries!vt%d", i); 875 "iseries!vt%d", i);
876 class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), 876 device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
877 NULL, "iseries!nvt%d", i); 877 "iseries!nvt%d", i);
878 printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries " 878 printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries "
879 "resource %10.10s type %4.4s, model %3.3s\n", 879 "resource %10.10s type %4.4s, model %3.3s\n",
880 i, viotape_unitinfo[i].rsrcname, 880 i, viotape_unitinfo[i].rsrcname,
@@ -886,8 +886,8 @@ static int viotape_remove(struct vio_dev *vdev)
886{ 886{
887 int i = vdev->unit_address; 887 int i = vdev->unit_address;
888 888
889 class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80)); 889 device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80));
890 class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i)); 890 device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i));
891 return 0; 891 return 0;
892} 892}
893 893
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index f7b9d6fce123..5e626b12b97e 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -830,7 +830,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev)
830 /* prepare interface data */ 830 /* prepare interface data */
831 policy->kobj.parent = &sys_dev->kobj; 831 policy->kobj.parent = &sys_dev->kobj;
832 policy->kobj.ktype = &ktype_cpufreq; 832 policy->kobj.ktype = &ktype_cpufreq;
833 strlcpy(policy->kobj.name, "cpufreq", KOBJ_NAME_LEN); 833 kobject_set_name(&policy->kobj, "cpufreq");
834 834
835 ret = kobject_register(&policy->kobj); 835 ret = kobject_register(&policy->kobj);
836 if (ret) { 836 if (ret) {
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c
index 4a0576bd06fc..3706b2bc0987 100644
--- a/drivers/edac/edac_mc_sysfs.c
+++ b/drivers/edac/edac_mc_sysfs.c
@@ -743,7 +743,7 @@ static struct kobj_type ktype_mc_set_attribs = {
743 * /sys/devices/system/edac/mc 743 * /sys/devices/system/edac/mc
744 */ 744 */
745static struct kset mc_kset = { 745static struct kset mc_kset = {
746 .kobj = {.name = "mc", .ktype = &ktype_mc_set_attribs }, 746 .kobj = {.ktype = &ktype_mc_set_attribs },
747 .ktype = &ktype_mci, 747 .ktype = &ktype_mci,
748}; 748};
749 749
@@ -1010,6 +1010,7 @@ int edac_sysfs_setup_mc_kset(void)
1010 } 1010 }
1011 1011
1012 /* Init the MC's kobject */ 1012 /* Init the MC's kobject */
1013 kobject_set_name(&mc_kset.kobj, "mc");
1013 mc_kset.kobj.parent = &edac_class->kset.kobj; 1014 mc_kset.kobj.parent = &edac_class->kset.kobj;
1014 1015
1015 /* register the mc_kset */ 1016 /* register the mc_kset */
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
index d944647c82c2..4d4a47393909 100644
--- a/drivers/eisa/eisa-bus.c
+++ b/drivers/eisa/eisa-bus.c
@@ -128,16 +128,11 @@ static int eisa_bus_match (struct device *dev, struct device_driver *drv)
128 return 0; 128 return 0;
129} 129}
130 130
131static int eisa_bus_uevent(struct device *dev, char **envp, int num_envp, 131static int eisa_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
132 char *buffer, int buffer_size)
133{ 132{
134 struct eisa_device *edev = to_eisa_device(dev); 133 struct eisa_device *edev = to_eisa_device(dev);
135 int i = 0;
136 int length = 0;
137 134
138 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, 135 add_uevent_var(env, "MODALIAS=" EISA_DEVICE_MODALIAS_FMT, edev->id.sig);
139 "MODALIAS=" EISA_DEVICE_MODALIAS_FMT, edev->id.sig);
140 envp[i] = NULL;
141 return 0; 136 return 0;
142} 137}
143 138
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index 2b6586341635..56681b3b297b 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -130,23 +130,16 @@ static int get_modalias(struct fw_unit *unit, char *buffer, size_t buffer_size)
130} 130}
131 131
132static int 132static int
133fw_unit_uevent(struct device *dev, char **envp, int num_envp, 133fw_unit_uevent(struct device *dev, struct kobj_uevent_env *env)
134 char *buffer, int buffer_size)
135{ 134{
136 struct fw_unit *unit = fw_unit(dev); 135 struct fw_unit *unit = fw_unit(dev);
137 char modalias[64]; 136 char modalias[64];
138 int length = 0;
139 int i = 0;
140 137
141 get_modalias(unit, modalias, sizeof(modalias)); 138 get_modalias(unit, modalias, sizeof(modalias));
142 139
143 if (add_uevent_var(envp, num_envp, &i, 140 if (add_uevent_var(env, "MODALIAS=%s", modalias))
144 buffer, buffer_size, &length,
145 "MODALIAS=%s", modalias))
146 return -ENOMEM; 141 return -ENOMEM;
147 142
148 envp[i] = NULL;
149
150 return 0; 143 return 0;
151} 144}
152 145
diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c
index 59c3b5aa89f4..b6e1eb77d148 100644
--- a/drivers/firmware/dmi-id.c
+++ b/drivers/firmware/dmi-id.c
@@ -13,21 +13,31 @@
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/autoconf.h> 14#include <linux/autoconf.h>
15 15
16#define DEFINE_DMI_ATTR(_name, _mode, _show) \ 16struct dmi_device_attribute{
17static struct device_attribute sys_dmi_##_name##_attr = \ 17 struct device_attribute dev_attr;
18 __ATTR(_name, _mode, _show, NULL); 18 int field;
19 19};
20#define DEFINE_DMI_ATTR_WITH_SHOW(_name, _mode, _field) \ 20#define to_dmi_dev_attr(_dev_attr) \
21static ssize_t sys_dmi_##_name##_show(struct device *dev, \ 21 container_of(_dev_attr, struct dmi_device_attribute, dev_attr)
22 struct device_attribute *attr, \ 22
23 char *page) \ 23static ssize_t sys_dmi_field_show(struct device *dev,
24{ \ 24 struct device_attribute *attr,
25 ssize_t len; \ 25 char *page)
26 len = scnprintf(page, PAGE_SIZE, "%s\n", dmi_get_system_info(_field)); \ 26{
27 page[len-1] = '\n'; \ 27 int field = to_dmi_dev_attr(attr)->field;
28 return len; \ 28 ssize_t len;
29} \ 29 len = scnprintf(page, PAGE_SIZE, "%s\n", dmi_get_system_info(field));
30DEFINE_DMI_ATTR(_name, _mode, sys_dmi_##_name##_show); 30 page[len-1] = '\n';
31 return len;
32}
33
34#define DMI_ATTR(_name, _mode, _show, _field) \
35 { .dev_attr = __ATTR(_name, _mode, _show, NULL), \
36 .field = _field }
37
38#define DEFINE_DMI_ATTR_WITH_SHOW(_name, _mode, _field) \
39static struct dmi_device_attribute sys_dmi_##_name##_attr = \
40 DMI_ATTR(_name, _mode, sys_dmi_field_show, _field);
31 41
32DEFINE_DMI_ATTR_WITH_SHOW(bios_vendor, 0444, DMI_BIOS_VENDOR); 42DEFINE_DMI_ATTR_WITH_SHOW(bios_vendor, 0444, DMI_BIOS_VENDOR);
33DEFINE_DMI_ATTR_WITH_SHOW(bios_version, 0444, DMI_BIOS_VERSION); 43DEFINE_DMI_ATTR_WITH_SHOW(bios_version, 0444, DMI_BIOS_VERSION);
@@ -121,7 +131,8 @@ static ssize_t sys_dmi_modalias_show(struct device *dev,
121 return r+1; 131 return r+1;
122} 132}
123 133
124DEFINE_DMI_ATTR(modalias, 0444, sys_dmi_modalias_show); 134static struct device_attribute sys_dmi_modalias_attr =
135 __ATTR(modalias, 0444, sys_dmi_modalias_show, NULL);
125 136
126static struct attribute *sys_dmi_attributes[DMI_STRING_MAX+2]; 137static struct attribute *sys_dmi_attributes[DMI_STRING_MAX+2];
127 138
@@ -134,14 +145,17 @@ static struct attribute_group* sys_dmi_attribute_groups[] = {
134 NULL 145 NULL
135}; 146};
136 147
137static int dmi_dev_uevent(struct device *dev, char **envp, 148static int dmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
138 int num_envp, char *buffer, int buffer_size)
139{ 149{
140 strcpy(buffer, "MODALIAS="); 150 ssize_t len;
141 get_modalias(buffer+9, buffer_size-9); 151
142 envp[0] = buffer; 152 if (add_uevent_var(env, "MODALIAS="))
143 envp[1] = NULL; 153 return -ENOMEM;
144 154 len = get_modalias(&env->buf[env->buflen - 1],
155 sizeof(env->buf) - env->buflen);
156 if (len >= (sizeof(env->buf) - env->buflen))
157 return -ENOMEM;
158 env->buflen += len;
145 return 0; 159 return 0;
146} 160}
147 161
@@ -157,7 +171,7 @@ static struct device *dmi_dev;
157 171
158#define ADD_DMI_ATTR(_name, _field) \ 172#define ADD_DMI_ATTR(_name, _field) \
159 if (dmi_get_system_info(_field)) \ 173 if (dmi_get_system_info(_field)) \
160 sys_dmi_attributes[i++] = & sys_dmi_##_name##_attr.attr; 174 sys_dmi_attributes[i++] = &sys_dmi_##_name##_attr.dev_attr.attr;
161 175
162extern int dmi_available; 176extern int dmi_available;
163 177
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index 0fb730ee1da8..6942e065e609 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -625,13 +625,13 @@ static void edd_release(struct kobject * kobj)
625 kfree(dev); 625 kfree(dev);
626} 626}
627 627
628static struct kobj_type ktype_edd = { 628static struct kobj_type edd_ktype = {
629 .release = edd_release, 629 .release = edd_release,
630 .sysfs_ops = &edd_attr_ops, 630 .sysfs_ops = &edd_attr_ops,
631 .default_attrs = def_attrs, 631 .default_attrs = def_attrs,
632}; 632};
633 633
634static decl_subsys(edd,&ktype_edd,NULL); 634static decl_subsys(edd, &edd_ktype, NULL);
635 635
636 636
637/** 637/**
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index bfd2d67df689..858a7b95933b 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -402,7 +402,7 @@ static struct attribute *def_attrs[] = {
402 NULL, 402 NULL,
403}; 403};
404 404
405static struct kobj_type ktype_efivar = { 405static struct kobj_type efivar_ktype = {
406 .release = efivar_release, 406 .release = efivar_release,
407 .sysfs_ops = &efivar_attr_ops, 407 .sysfs_ops = &efivar_attr_ops,
408 .default_attrs = def_attrs, 408 .default_attrs = def_attrs,
@@ -583,7 +583,7 @@ static struct subsys_attribute *efi_subsys_attrs[] = {
583 NULL, /* maybe more in the future? */ 583 NULL, /* maybe more in the future? */
584}; 584};
585 585
586static decl_subsys(vars, &ktype_efivar, NULL); 586static decl_subsys(vars, &efivar_ktype, NULL);
587static decl_subsys(efi, NULL, NULL); 587static decl_subsys(efi, NULL, NULL);
588 588
589/* 589/*
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index d663e6960d93..910a62de190d 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -67,20 +67,16 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
67#ifdef CONFIG_HOTPLUG 67#ifdef CONFIG_HOTPLUG
68 68
69/* uevent helps with hotplug: modprobe -q $(MODALIAS) */ 69/* uevent helps with hotplug: modprobe -q $(MODALIAS) */
70static int i2c_device_uevent(struct device *dev, char **envp, int num_envp, 70static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
71 char *buffer, int buffer_size)
72{ 71{
73 struct i2c_client *client = to_i2c_client(dev); 72 struct i2c_client *client = to_i2c_client(dev);
74 int i = 0, length = 0;
75 73
76 /* by definition, legacy drivers can't hotplug */ 74 /* by definition, legacy drivers can't hotplug */
77 if (dev->driver || !client->driver_name) 75 if (dev->driver || !client->driver_name)
78 return 0; 76 return 0;
79 77
80 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, 78 if (add_uevent_var(env, "MODALIAS=%s", client->driver_name))
81 "MODALIAS=%s", client->driver_name))
82 return -ENOMEM; 79 return -ENOMEM;
83 envp[i] = NULL;
84 dev_dbg(dev, "uevent\n"); 80 dev_dbg(dev, "uevent\n");
85 return 0; 81 return 0;
86} 82}
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index e96212ce5729..a96a8b1b3539 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -1663,20 +1663,13 @@ static struct device_attribute ide_dev_attrs[] = {
1663 __ATTR_NULL 1663 __ATTR_NULL
1664}; 1664};
1665 1665
1666static int ide_uevent(struct device *dev, char **envp, int num_envp, 1666static int ide_uevent(struct device *dev, struct kobj_uevent_env *env)
1667 char *buffer, int buffer_size)
1668{ 1667{
1669 ide_drive_t *drive = to_ide_device(dev); 1668 ide_drive_t *drive = to_ide_device(dev);
1670 int i = 0; 1669
1671 int length = 0; 1670 add_uevent_var(env, "MEDIA=%s", media_string(drive));
1672 1671 add_uevent_var(env, "DRIVENAME=%s", drive->name);
1673 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, 1672 add_uevent_var(env, "MODALIAS=ide:m-%s", media_string(drive));
1674 "MEDIA=%s", media_string(drive));
1675 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
1676 "DRIVENAME=%s", drive->name);
1677 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
1678 "MODALIAS=ide:m-%s", media_string(drive));
1679 envp[i] = NULL;
1680 return 0; 1673 return 0;
1681} 1674}
1682 1675
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 2ffd53461db6..1939fee616ec 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -153,8 +153,7 @@ struct host_info {
153}; 153};
154 154
155static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); 155static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
156static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, 156static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env);
157 char *buffer, int buffer_size);
158static void nodemgr_resume_ne(struct node_entry *ne); 157static void nodemgr_resume_ne(struct node_entry *ne);
159static void nodemgr_remove_ne(struct node_entry *ne); 158static void nodemgr_remove_ne(struct node_entry *ne);
160static struct node_entry *find_entry_by_guid(u64 guid); 159static struct node_entry *find_entry_by_guid(u64 guid);
@@ -1160,12 +1159,9 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
1160 1159
1161#ifdef CONFIG_HOTPLUG 1160#ifdef CONFIG_HOTPLUG
1162 1161
1163static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, 1162static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env)
1164 char *buffer, int buffer_size)
1165{ 1163{
1166 struct unit_directory *ud; 1164 struct unit_directory *ud;
1167 int i = 0;
1168 int length = 0;
1169 int retval = 0; 1165 int retval = 0;
1170 /* ieee1394:venNmoNspNverN */ 1166 /* ieee1394:venNmoNspNverN */
1171 char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1]; 1167 char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1];
@@ -1180,9 +1176,7 @@ static int nodemgr_uevent(struct device *dev, char **envp, int num_envp,
1180 1176
1181#define PUT_ENVP(fmt,val) \ 1177#define PUT_ENVP(fmt,val) \
1182do { \ 1178do { \
1183 retval = add_uevent_var(envp, num_envp, &i, \ 1179 retval = add_uevent_var(env, fmt, val); \
1184 buffer, buffer_size, &length, \
1185 fmt, val); \
1186 if (retval) \ 1180 if (retval) \
1187 return retval; \ 1181 return retval; \
1188} while (0) 1182} while (0)
@@ -1201,15 +1195,12 @@ do { \
1201 1195
1202#undef PUT_ENVP 1196#undef PUT_ENVP
1203 1197
1204 envp[i] = NULL;
1205
1206 return 0; 1198 return 0;
1207} 1199}
1208 1200
1209#else 1201#else
1210 1202
1211static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, 1203static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env)
1212 char *buffer, int buffer_size)
1213{ 1204{
1214 return -ENODEV; 1205 return -ENODEV;
1215} 1206}
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 70b77ae67422..3d4050681325 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -434,21 +434,18 @@ static void ib_device_release(struct class_device *cdev)
434 kfree(dev); 434 kfree(dev);
435} 435}
436 436
437static int ib_device_uevent(struct class_device *cdev, char **envp, 437static int ib_device_uevent(struct class_device *cdev,
438 int num_envp, char *buf, int size) 438 struct kobj_uevent_env *env)
439{ 439{
440 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev); 440 struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
441 int i = 0, len = 0;
442 441
443 if (add_uevent_var(envp, num_envp, &i, buf, size, &len, 442 if (add_uevent_var(env, "NAME=%s", dev->name))
444 "NAME=%s", dev->name))
445 return -ENOMEM; 443 return -ENOMEM;
446 444
447 /* 445 /*
448 * It would be nice to pass the node GUID with the event... 446 * It would be nice to pass the node GUID with the event...
449 */ 447 */
450 448
451 envp[i] = NULL;
452 return 0; 449 return 0;
453} 450}
454 451
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 5fe755586623..5dc361c954e2 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -859,87 +859,66 @@ static void input_dev_release(struct device *device)
859 * Input uevent interface - loading event handlers based on 859 * Input uevent interface - loading event handlers based on
860 * device bitfields. 860 * device bitfields.
861 */ 861 */
862static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index, 862static int input_add_uevent_bm_var(struct kobj_uevent_env *env,
863 char *buffer, int buffer_size, int *cur_len,
864 const char *name, unsigned long *bitmap, int max) 863 const char *name, unsigned long *bitmap, int max)
865{ 864{
866 if (*cur_index >= num_envp - 1) 865 int len;
867 return -ENOMEM;
868
869 envp[*cur_index] = buffer + *cur_len;
870 866
871 *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name); 867 if (add_uevent_var(env, "%s=", name))
872 if (*cur_len >= buffer_size)
873 return -ENOMEM; 868 return -ENOMEM;
874 869
875 *cur_len += input_print_bitmap(buffer + *cur_len, 870 len = input_print_bitmap(&env->buf[env->buflen - 1],
876 max(buffer_size - *cur_len, 0), 871 sizeof(env->buf) - env->buflen,
877 bitmap, max, 0) + 1; 872 bitmap, max, 0);
878 if (*cur_len > buffer_size) 873 if (len >= (sizeof(env->buf) - env->buflen))
879 return -ENOMEM; 874 return -ENOMEM;
880 875
881 (*cur_index)++; 876 env->buflen += len;
882 return 0; 877 return 0;
883} 878}
884 879
885static int input_add_uevent_modalias_var(char **envp, int num_envp, int *cur_index, 880static int input_add_uevent_modalias_var(struct kobj_uevent_env *env,
886 char *buffer, int buffer_size, int *cur_len,
887 struct input_dev *dev) 881 struct input_dev *dev)
888{ 882{
889 if (*cur_index >= num_envp - 1) 883 int len;
890 return -ENOMEM;
891
892 envp[*cur_index] = buffer + *cur_len;
893 884
894 *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), 885 if (add_uevent_var(env, "MODALIAS="))
895 "MODALIAS=");
896 if (*cur_len >= buffer_size)
897 return -ENOMEM; 886 return -ENOMEM;
898 887
899 *cur_len += input_print_modalias(buffer + *cur_len, 888 len = input_print_modalias(&env->buf[env->buflen - 1],
900 max(buffer_size - *cur_len, 0), 889 sizeof(env->buf) - env->buflen,
901 dev, 0) + 1; 890 dev, 0);
902 if (*cur_len > buffer_size) 891 if (len >= (sizeof(env->buf) - env->buflen))
903 return -ENOMEM; 892 return -ENOMEM;
904 893
905 (*cur_index)++; 894 env->buflen += len;
906 return 0; 895 return 0;
907} 896}
908 897
909#define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \ 898#define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \
910 do { \ 899 do { \
911 int err = add_uevent_var(envp, num_envp, &i, \ 900 int err = add_uevent_var(env, fmt, val); \
912 buffer, buffer_size, &len, \
913 fmt, val); \
914 if (err) \ 901 if (err) \
915 return err; \ 902 return err; \
916 } while (0) 903 } while (0)
917 904
918#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \ 905#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \
919 do { \ 906 do { \
920 int err = input_add_uevent_bm_var(envp, num_envp, &i, \ 907 int err = input_add_uevent_bm_var(env, name, bm, max); \
921 buffer, buffer_size, &len, \
922 name, bm, max); \
923 if (err) \ 908 if (err) \
924 return err; \ 909 return err; \
925 } while (0) 910 } while (0)
926 911
927#define INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev) \ 912#define INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev) \
928 do { \ 913 do { \
929 int err = input_add_uevent_modalias_var(envp, \ 914 int err = input_add_uevent_modalias_var(env, dev); \
930 num_envp, &i, \
931 buffer, buffer_size, &len, \
932 dev); \
933 if (err) \ 915 if (err) \
934 return err; \ 916 return err; \
935 } while (0) 917 } while (0)
936 918
937static int input_dev_uevent(struct device *device, char **envp, 919static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
938 int num_envp, char *buffer, int buffer_size)
939{ 920{
940 struct input_dev *dev = to_input_dev(device); 921 struct input_dev *dev = to_input_dev(device);
941 int i = 0;
942 int len = 0;
943 922
944 INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x", 923 INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x",
945 dev->id.bustype, dev->id.vendor, 924 dev->id.bustype, dev->id.vendor,
@@ -971,7 +950,6 @@ static int input_dev_uevent(struct device *device, char **envp,
971 950
972 INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev); 951 INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev);
973 952
974 envp[i] = NULL;
975 return 0; 953 return 0;
976} 954}
977 955
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
index 4e2ca6f0ab18..c19f77fbaf2a 100644
--- a/drivers/input/misc/pcspkr.c
+++ b/drivers/input/misc/pcspkr.c
@@ -22,6 +22,7 @@
22MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); 22MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
23MODULE_DESCRIPTION("PC Speaker beeper driver"); 23MODULE_DESCRIPTION("PC Speaker beeper driver");
24MODULE_LICENSE("GPL"); 24MODULE_LICENSE("GPL");
25MODULE_ALIAS("platform:pcspkr");
25 26
26#ifdef CONFIG_X86 27#ifdef CONFIG_X86
27/* Use the global PIT lock ! */ 28/* Use the global PIT lock ! */
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 372ca4931194..b3bc15acd3f5 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -876,18 +876,14 @@ static int serio_bus_match(struct device *dev, struct device_driver *drv)
876 876
877#define SERIO_ADD_UEVENT_VAR(fmt, val...) \ 877#define SERIO_ADD_UEVENT_VAR(fmt, val...) \
878 do { \ 878 do { \
879 int err = add_uevent_var(envp, num_envp, &i, \ 879 int err = add_uevent_var(env, fmt, val); \
880 buffer, buffer_size, &len, \
881 fmt, val); \
882 if (err) \ 880 if (err) \
883 return err; \ 881 return err; \
884 } while (0) 882 } while (0)
885 883
886static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) 884static int serio_uevent(struct device *dev, struct kobj_uevent_env *env)
887{ 885{
888 struct serio *serio; 886 struct serio *serio;
889 int i = 0;
890 int len = 0;
891 887
892 if (!dev) 888 if (!dev)
893 return -ENODEV; 889 return -ENODEV;
@@ -900,7 +896,6 @@ static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buf
900 SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra); 896 SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra);
901 SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X", 897 SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
902 serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); 898 serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
903 envp[i] = NULL;
904 899
905 return 0; 900 return 0;
906} 901}
@@ -908,7 +903,7 @@ static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buf
908 903
909#else 904#else
910 905
911static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) 906static int serio_uevent(struct device *dev, struct kobj_uevent_env *env)
912{ 907{
913 return -ENODEV; 908 return -ENODEV;
914} 909}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index e8f102ea9b03..acf1b81b47cb 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3076,8 +3076,7 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
3076 mddev->gendisk = disk; 3076 mddev->gendisk = disk;
3077 mutex_unlock(&disks_mutex); 3077 mutex_unlock(&disks_mutex);
3078 mddev->kobj.parent = &disk->kobj; 3078 mddev->kobj.parent = &disk->kobj;
3079 mddev->kobj.k_name = NULL; 3079 kobject_set_name(&mddev->kobj, "%s", "md");
3080 snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md");
3081 mddev->kobj.ktype = &md_ktype; 3080 mddev->kobj.ktype = &md_ktype;
3082 if (kobject_register(&mddev->kobj)) 3081 if (kobject_register(&mddev->kobj))
3083 printk(KERN_WARNING "md: cannot register %s/md - name in use\n", 3082 printk(KERN_WARNING "md: cannot register %s/md - name in use\n",
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 56231d8edc07..18738faecbbc 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -103,10 +103,7 @@ static struct file_operations dvb_device_fops =
103 .open = dvb_device_open, 103 .open = dvb_device_open,
104}; 104};
105 105
106static struct cdev dvb_device_cdev = { 106static struct cdev dvb_device_cdev;
107 .kobj = {.name = "dvb", },
108 .owner = THIS_MODULE,
109};
110 107
111int dvb_generic_open(struct inode *inode, struct file *file) 108int dvb_generic_open(struct inode *inode, struct file *file)
112{ 109{
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 7a78d6b34738..2ee3c3049e8f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -905,8 +905,8 @@ struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp,
905} 905}
906 906
907 907
908static int pvr2_sysfs_hotplug(struct device *cd,char **envp, 908static int pvr2_sysfs_hotplug(struct device *d,
909 int numenvp,char *buf,int size) 909 struct kobj_uevent_env *env)
910{ 910{
911 /* Even though we don't do anything here, we still need this function 911 /* Even though we don't do anything here, we still need this function
912 because sysfs will still try to call it. */ 912 because sysfs will still try to call it. */
diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c
index d195fb088f4a..8f77949f93dd 100644
--- a/drivers/misc/tifm_core.c
+++ b/drivers/misc/tifm_core.c
@@ -57,16 +57,11 @@ static int tifm_bus_match(struct device *dev, struct device_driver *drv)
57 return 0; 57 return 0;
58} 58}
59 59
60static int tifm_uevent(struct device *dev, char **envp, int num_envp, 60static int tifm_uevent(struct device *dev, struct kobj_uevent_env *env)
61 char *buffer, int buffer_size)
62{ 61{
63 struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev); 62 struct tifm_dev *sock = container_of(dev, struct tifm_dev, dev);
64 int i = 0;
65 int length = 0;
66 63
67 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, 64 if (add_uevent_var(env, "TIFM_CARD_TYPE=%s", tifm_media_type_name(sock->type, 1)))
68 "TIFM_CARD_TYPE=%s",
69 tifm_media_type_name(sock->type, 1)))
70 return -ENOMEM; 65 return -ENOMEM;
71 66
72 return 0; 67 return 0;
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 8d6f6014870f..b0c22cad9423 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -58,12 +58,11 @@ static int mmc_bus_match(struct device *dev, struct device_driver *drv)
58} 58}
59 59
60static int 60static int
61mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf, 61mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
62 int buf_size)
63{ 62{
64 struct mmc_card *card = dev_to_mmc_card(dev); 63 struct mmc_card *card = dev_to_mmc_card(dev);
65 const char *type; 64 const char *type;
66 int i = 0, length = 0; 65 int retval = 0;
67 66
68 switch (card->type) { 67 switch (card->type) {
69 case MMC_TYPE_MMC: 68 case MMC_TYPE_MMC:
@@ -80,20 +79,14 @@ mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
80 } 79 }
81 80
82 if (type) { 81 if (type) {
83 if (add_uevent_var(envp, num_envp, &i, 82 retval = add_uevent_var(env, "MMC_TYPE=%s", type);
84 buf, buf_size, &length, 83 if (retval)
85 "MMC_TYPE=%s", type)) 84 return retval;
86 return -ENOMEM;
87 } 85 }
88 86
89 if (add_uevent_var(envp, num_envp, &i, 87 retval = add_uevent_var(env, "MMC_NAME=%s", mmc_card_name(card));
90 buf, buf_size, &length,
91 "MMC_NAME=%s", mmc_card_name(card)))
92 return -ENOMEM;
93 88
94 envp[i] = NULL; 89 return retval;
95
96 return 0;
97} 90}
98 91
99static int mmc_bus_probe(struct device *dev) 92static int mmc_bus_probe(struct device *dev)
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 4ac161e1ca12..7d7758f3ad8c 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -1183,7 +1183,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
1183 pool_count[i], pool_size[i], 1183 pool_count[i], pool_size[i],
1184 pool_active[i]); 1184 pool_active[i]);
1185 kobj->parent = &dev->dev.kobj; 1185 kobj->parent = &dev->dev.kobj;
1186 sprintf(kobj->name, "pool%d", i); 1186 kobject_set_name(kobj, "pool%d", i);
1187 kobj->ktype = &ktype_veth_pool; 1187 kobj->ktype = &ktype_veth_pool;
1188 kobject_register(kobj); 1188 kobject_register(kobj);
1189 } 1189 }
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c
index 1c97e7dd130b..2b5352a7dffc 100644
--- a/drivers/pci/hotplug.c
+++ b/drivers/pci/hotplug.c
@@ -3,12 +3,9 @@
3#include <linux/module.h> 3#include <linux/module.h>
4#include "pci.h" 4#include "pci.h"
5 5
6int pci_uevent(struct device *dev, char **envp, int num_envp, 6int pci_uevent(struct device *dev, struct kobj_uevent_env *env)
7 char *buffer, int buffer_size)
8{ 7{
9 struct pci_dev *pdev; 8 struct pci_dev *pdev;
10 int i = 0;
11 int length = 0;
12 9
13 if (!dev) 10 if (!dev)
14 return -ENODEV; 11 return -ENODEV;
@@ -17,37 +14,24 @@ int pci_uevent(struct device *dev, char **envp, int num_envp,
17 if (!pdev) 14 if (!pdev)
18 return -ENODEV; 15 return -ENODEV;
19 16
20 if (add_uevent_var(envp, num_envp, &i, 17 if (add_uevent_var(env, "PCI_CLASS=%04X", pdev->class))
21 buffer, buffer_size, &length,
22 "PCI_CLASS=%04X", pdev->class))
23 return -ENOMEM; 18 return -ENOMEM;
24 19
25 if (add_uevent_var(envp, num_envp, &i, 20 if (add_uevent_var(env, "PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
26 buffer, buffer_size, &length,
27 "PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
28 return -ENOMEM; 21 return -ENOMEM;
29 22
30 if (add_uevent_var(envp, num_envp, &i, 23 if (add_uevent_var(env, "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
31 buffer, buffer_size, &length,
32 "PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
33 pdev->subsystem_device)) 24 pdev->subsystem_device))
34 return -ENOMEM; 25 return -ENOMEM;
35 26
36 if (add_uevent_var(envp, num_envp, &i, 27 if (add_uevent_var(env, "PCI_SLOT_NAME=%s", pci_name(pdev)))
37 buffer, buffer_size, &length,
38 "PCI_SLOT_NAME=%s", pci_name(pdev)))
39 return -ENOMEM; 28 return -ENOMEM;
40 29
41 if (add_uevent_var(envp, num_envp, &i, 30 if (add_uevent_var(env, "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
42 buffer, buffer_size, &length,
43 "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
44 pdev->vendor, pdev->device, 31 pdev->vendor, pdev->device,
45 pdev->subsystem_vendor, pdev->subsystem_device, 32 pdev->subsystem_vendor, pdev->subsystem_device,
46 (u8)(pdev->class >> 16), (u8)(pdev->class >> 8), 33 (u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
47 (u8)(pdev->class))) 34 (u8)(pdev->class)))
48 return -ENOMEM; 35 return -ENOMEM;
49
50 envp[i] = NULL;
51
52 return 0; 36 return 0;
53} 37}
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index bd433ef6bfc6..f0eba534f805 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -694,66 +694,6 @@ int __must_check pci_hp_change_slot_info(struct hotplug_slot *slot,
694 if ((slot == NULL) || (info == NULL)) 694 if ((slot == NULL) || (info == NULL))
695 return -ENODEV; 695 return -ENODEV;
696 696
697 /*
698 * check all fields in the info structure, and update timestamps
699 * for the files referring to the fields that have now changed.
700 */
701 if ((has_power_file(slot) == 0) &&
702 (slot->info->power_status != info->power_status)) {
703 retval = sysfs_update_file(&slot->kobj,
704 &hotplug_slot_attr_power.attr);
705 if (retval)
706 return retval;
707 }
708
709 if ((has_attention_file(slot) == 0) &&
710 (slot->info->attention_status != info->attention_status)) {
711 retval = sysfs_update_file(&slot->kobj,
712 &hotplug_slot_attr_attention.attr);
713 if (retval)
714 return retval;
715 }
716
717 if ((has_latch_file(slot) == 0) &&
718 (slot->info->latch_status != info->latch_status)) {
719 retval = sysfs_update_file(&slot->kobj,
720 &hotplug_slot_attr_latch.attr);
721 if (retval)
722 return retval;
723 }
724
725 if ((has_adapter_file(slot) == 0) &&
726 (slot->info->adapter_status != info->adapter_status)) {
727 retval = sysfs_update_file(&slot->kobj,
728 &hotplug_slot_attr_presence.attr);
729 if (retval)
730 return retval;
731 }
732
733 if ((has_address_file(slot) == 0) &&
734 (slot->info->address != info->address)) {
735 retval = sysfs_update_file(&slot->kobj,
736 &hotplug_slot_attr_address.attr);
737 if (retval)
738 return retval;
739 }
740
741 if ((has_max_bus_speed_file(slot) == 0) &&
742 (slot->info->max_bus_speed != info->max_bus_speed)) {
743 retval = sysfs_update_file(&slot->kobj,
744 &hotplug_slot_attr_max_bus_speed.attr);
745 if (retval)
746 return retval;
747 }
748
749 if ((has_cur_bus_speed_file(slot) == 0) &&
750 (slot->info->cur_bus_speed != info->cur_bus_speed)) {
751 retval = sysfs_update_file(&slot->kobj,
752 &hotplug_slot_attr_cur_bus_speed.attr);
753 if (retval)
754 return retval;
755 }
756
757 memcpy (slot->info, info, sizeof (struct hotplug_slot_info)); 697 memcpy (slot->info, info, sizeof (struct hotplug_slot_info));
758 698
759 return 0; 699 return 0;
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c
index df076064a3e0..a080fedf0332 100644
--- a/drivers/pci/hotplug/rpadlpar_sysfs.c
+++ b/drivers/pci/hotplug/rpadlpar_sysfs.c
@@ -129,17 +129,17 @@ struct kobj_type ktype_dlpar_io = {
129}; 129};
130 130
131struct kset dlpar_io_kset = { 131struct kset dlpar_io_kset = {
132 .kobj = {.name = DLPAR_KOBJ_NAME, 132 .kobj = {.ktype = &ktype_dlpar_io,
133 .ktype = &ktype_dlpar_io,
134 .parent = &pci_hotplug_slots_subsys.kobj}, 133 .parent = &pci_hotplug_slots_subsys.kobj},
135 .ktype = &ktype_dlpar_io, 134 .ktype = &ktype_dlpar_io,
136}; 135};
137 136
138int dlpar_sysfs_init(void) 137int dlpar_sysfs_init(void)
139{ 138{
139 kobject_set_name(&dlpar_io_kset.kobj, DLPAR_KOBJ_NAME);
140 if (kset_register(&dlpar_io_kset)) { 140 if (kset_register(&dlpar_io_kset)) {
141 printk(KERN_ERR "rpadlpar_io: cannot register kset for %s\n", 141 printk(KERN_ERR "rpadlpar_io: cannot register kset for %s\n",
142 dlpar_io_kset.kobj.name); 142 kobject_name(&dlpar_io_kset.kobj));
143 return -EINVAL; 143 return -EINVAL;
144 } 144 }
145 145
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 004bc2487270..f61be3abfdca 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -532,8 +532,7 @@ void pci_dev_put(struct pci_dev *dev)
532} 532}
533 533
534#ifndef CONFIG_HOTPLUG 534#ifndef CONFIG_HOTPLUG
535int pci_uevent(struct device *dev, char **envp, int num_envp, 535int pci_uevent(struct device *dev, struct kobj_uevent_env *env)
536 char *buffer, int buffer_size)
537{ 536{
538 return -ENODEV; 537 return -ENODEV;
539} 538}
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 4c36e80f6d26..b3a7d5b0f936 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -1,7 +1,6 @@
1/* Functions internal to the PCI core code */ 1/* Functions internal to the PCI core code */
2 2
3extern int pci_uevent(struct device *dev, char **envp, int num_envp, 3extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env);
4 char *buffer, int buffer_size);
5extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); 4extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
6extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); 5extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
7extern void pci_cleanup_rom(struct pci_dev *dev); 6extern void pci_cleanup_rom(struct pci_dev *dev);
diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
index 568f1877315c..05ca2ed9eb51 100644
--- a/drivers/pci/setup-irq.c
+++ b/drivers/pci/setup-irq.c
@@ -48,7 +48,7 @@ pdev_fixup_irq(struct pci_dev *dev,
48 dev->irq = irq; 48 dev->irq = irq;
49 49
50 pr_debug("PCI: fixup irq: (%s) got %d\n", 50 pr_debug("PCI: fixup irq: (%s) got %d\n",
51 dev->dev.kobj.name, dev->irq); 51 kobject_name(&dev->dev.kobj), dev->irq);
52 52
53 /* Always tell the device, so the driver knows what is 53 /* Always tell the device, so the driver knows what is
54 the real IRQ to use; the device does not use it. */ 54 the real IRQ to use; the device does not use it. */
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index f8b13f0270d7..a0aca46ce877 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -907,18 +907,14 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
907EXPORT_SYMBOL(pcmcia_insert_card); 907EXPORT_SYMBOL(pcmcia_insert_card);
908 908
909 909
910static int pcmcia_socket_uevent(struct device *dev, char **envp, 910static int pcmcia_socket_uevent(struct device *dev,
911 int num_envp, char *buffer, int buffer_size) 911 struct kobj_uevent_env *env)
912{ 912{
913 struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev); 913 struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
914 int i = 0, length = 0;
915 914
916 if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, 915 if (add_uevent_var(env, "SOCKET_NO=%u", s->sock))
917 &length, "SOCKET_NO=%u", s->sock))
918 return -ENOMEM; 916 return -ENOMEM;
919 917
920 envp[i] = NULL;
921
922 return 0; 918 return 0;
923} 919}
924 920
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index a99607142fc8..55baa1f0fcbb 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -1064,11 +1064,10 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
1064 1064
1065#ifdef CONFIG_HOTPLUG 1065#ifdef CONFIG_HOTPLUG
1066 1066
1067static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp, 1067static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
1068 char *buffer, int buffer_size)
1069{ 1068{
1070 struct pcmcia_device *p_dev; 1069 struct pcmcia_device *p_dev;
1071 int i, length = 0; 1070 int i;
1072 u32 hash[4] = { 0, 0, 0, 0}; 1071 u32 hash[4] = { 0, 0, 0, 0};
1073 1072
1074 if (!dev) 1073 if (!dev)
@@ -1083,23 +1082,13 @@ static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
1083 hash[i] = crc32(0, p_dev->prod_id[i], strlen(p_dev->prod_id[i])); 1082 hash[i] = crc32(0, p_dev->prod_id[i], strlen(p_dev->prod_id[i]));
1084 } 1083 }
1085 1084
1086 i = 0; 1085 if (add_uevent_var(env, "SOCKET_NO=%u", p_dev->socket->sock))
1087
1088 if (add_uevent_var(envp, num_envp, &i,
1089 buffer, buffer_size, &length,
1090 "SOCKET_NO=%u",
1091 p_dev->socket->sock))
1092 return -ENOMEM; 1086 return -ENOMEM;
1093 1087
1094 if (add_uevent_var(envp, num_envp, &i, 1088 if (add_uevent_var(env, "DEVICE_NO=%02X", p_dev->device_no))
1095 buffer, buffer_size, &length,
1096 "DEVICE_NO=%02X",
1097 p_dev->device_no))
1098 return -ENOMEM; 1089 return -ENOMEM;
1099 1090
1100 if (add_uevent_var(envp, num_envp, &i, 1091 if (add_uevent_var(env, "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
1101 buffer, buffer_size, &length,
1102 "MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
1103 "pa%08Xpb%08Xpc%08Xpd%08X", 1092 "pa%08Xpb%08Xpc%08Xpd%08X",
1104 p_dev->has_manf_id ? p_dev->manf_id : 0, 1093 p_dev->has_manf_id ? p_dev->manf_id : 0,
1105 p_dev->has_card_id ? p_dev->card_id : 0, 1094 p_dev->has_card_id ? p_dev->card_id : 0,
@@ -1112,15 +1101,12 @@ static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
1112 hash[3])) 1101 hash[3]))
1113 return -ENOMEM; 1102 return -ENOMEM;
1114 1103
1115 envp[i] = NULL;
1116
1117 return 0; 1104 return 0;
1118} 1105}
1119 1106
1120#else 1107#else
1121 1108
1122static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp, 1109static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
1123 char *buffer, int buffer_size)
1124{ 1110{
1125 return -ENODEV; 1111 return -ENODEV;
1126} 1112}
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index 383107ba4bd3..f6722ba0dd1e 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -175,7 +175,6 @@ static int __init mst_pcmcia_init(void)
175 if (!mst_pcmcia_device) 175 if (!mst_pcmcia_device)
176 return -ENOMEM; 176 return -ENOMEM;
177 177
178 mst_pcmcia_device->dev.uevent_suppress = 0;
179 mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops; 178 mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops;
180 179
181 ret = platform_device_add(mst_pcmcia_device); 180 ret = platform_device_add(mst_pcmcia_device);
@@ -195,3 +194,4 @@ fs_initcall(mst_pcmcia_init);
195module_exit(mst_pcmcia_exit); 194module_exit(mst_pcmcia_exit);
196 195
197MODULE_LICENSE("GPL"); 196MODULE_LICENSE("GPL");
197MODULE_ALIAS("platform:pxa2xx-pcmcia");
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index a2daa3f531b2..d5c33bd78d68 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -261,7 +261,6 @@ static int __init sharpsl_pcmcia_init(void)
261 if (!sharpsl_pcmcia_device) 261 if (!sharpsl_pcmcia_device)
262 return -ENOMEM; 262 return -ENOMEM;
263 263
264 sharpsl_pcmcia_device->dev.uevent_suppress = 0;
265 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; 264 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
266 sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev; 265 sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev;
267 266
@@ -284,3 +283,4 @@ module_exit(sharpsl_pcmcia_exit);
284 283
285MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support"); 284MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support");
286MODULE_LICENSE("GPL"); 285MODULE_LICENSE("GPL");
286MODULE_ALIAS("platform:pxa2xx-pcmcia");
diff --git a/drivers/power/power_supply.h b/drivers/power/power_supply.h
index a9880d468ee4..f38ba482be75 100644
--- a/drivers/power/power_supply.h
+++ b/drivers/power/power_supply.h
@@ -14,8 +14,7 @@
14 14
15extern int power_supply_create_attrs(struct power_supply *psy); 15extern int power_supply_create_attrs(struct power_supply *psy);
16extern void power_supply_remove_attrs(struct power_supply *psy); 16extern void power_supply_remove_attrs(struct power_supply *psy);
17extern int power_supply_uevent(struct device *dev, char **envp, int num_envp, 17extern int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env);
18 char *buffer, int buffer_size);
19 18
20#else 19#else
21 20
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index de3155b21285..249f61bae639 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -195,11 +195,10 @@ static char *kstruprdup(const char *str, gfp_t gfp)
195 return ret; 195 return ret;
196} 196}
197 197
198int power_supply_uevent(struct device *dev, char **envp, int num_envp, 198int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)
199 char *buffer, int buffer_size)
200{ 199{
201 struct power_supply *psy = dev_get_drvdata(dev); 200 struct power_supply *psy = dev_get_drvdata(dev);
202 int i = 0, length = 0, ret = 0, j; 201 int ret = 0, j;
203 char *prop_buf; 202 char *prop_buf;
204 char *attrname; 203 char *attrname;
205 204
@@ -212,8 +211,7 @@ int power_supply_uevent(struct device *dev, char **envp, int num_envp,
212 211
213 dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->name); 212 dev_dbg(dev, "POWER_SUPPLY_NAME=%s\n", psy->name);
214 213
215 ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, 214 ret = add_uevent_var(env, "POWER_SUPPLY_NAME=%s", psy->name);
216 &length, "POWER_SUPPLY_NAME=%s", psy->name);
217 if (ret) 215 if (ret)
218 return ret; 216 return ret;
219 217
@@ -243,9 +241,7 @@ int power_supply_uevent(struct device *dev, char **envp, int num_envp,
243 241
244 dev_dbg(dev, "Static prop %s=%s\n", attrname, prop_buf); 242 dev_dbg(dev, "Static prop %s=%s\n", attrname, prop_buf);
245 243
246 ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, 244 ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf);
247 &length, "POWER_SUPPLY_%s=%s",
248 attrname, prop_buf);
249 kfree(attrname); 245 kfree(attrname);
250 if (ret) 246 if (ret)
251 goto out; 247 goto out;
@@ -282,14 +278,11 @@ int power_supply_uevent(struct device *dev, char **envp, int num_envp,
282 278
283 dev_dbg(dev, "prop %s=%s\n", attrname, prop_buf); 279 dev_dbg(dev, "prop %s=%s\n", attrname, prop_buf);
284 280
285 ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, 281 ret = add_uevent_var(env, "POWER_SUPPLY_%s=%s", attrname, prop_buf);
286 &length, "POWER_SUPPLY_%s=%s",
287 attrname, prop_buf);
288 kfree(attrname); 282 kfree(attrname);
289 if (ret) 283 if (ret)
290 goto out; 284 goto out;
291 } 285 }
292 envp[i] = NULL;
293 286
294out: 287out:
295 free_page((unsigned long)prop_buf); 288 free_page((unsigned long)prop_buf);
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 9c3b9ea1e66f..5baa517c3b66 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -44,8 +44,7 @@ ccwgroup_bus_match (struct device * dev, struct device_driver * drv)
44 return 0; 44 return 0;
45} 45}
46static int 46static int
47ccwgroup_uevent (struct device *dev, char **envp, int num_envp, char *buffer, 47ccwgroup_uevent (struct device *dev, struct kobj_uevent_env *env)
48 int buffer_size)
49{ 48{
50 /* TODO */ 49 /* TODO */
51 return 0; 50 return 0;
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 39f02b48e4c7..7ee57f084a89 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -79,49 +79,38 @@ static int snprint_alias(char *buf, size_t size,
79 79
80/* Set up environment variables for ccw device uevent. Return 0 on success, 80/* Set up environment variables for ccw device uevent. Return 0 on success,
81 * non-zero otherwise. */ 81 * non-zero otherwise. */
82static int ccw_uevent(struct device *dev, char **envp, int num_envp, 82static int ccw_uevent(struct device *dev, struct kobj_uevent_env *env)
83 char *buffer, int buffer_size)
84{ 83{
85 struct ccw_device *cdev = to_ccwdev(dev); 84 struct ccw_device *cdev = to_ccwdev(dev);
86 struct ccw_device_id *id = &(cdev->id); 85 struct ccw_device_id *id = &(cdev->id);
87 int i = 0;
88 int len = 0;
89 int ret; 86 int ret;
90 char modalias_buf[30]; 87 char modalias_buf[30];
91 88
92 /* CU_TYPE= */ 89 /* CU_TYPE= */
93 ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, 90 ret = add_uevent_var(env, "CU_TYPE=%04X", id->cu_type);
94 "CU_TYPE=%04X", id->cu_type);
95 if (ret) 91 if (ret)
96 return ret; 92 return ret;
97 93
98 /* CU_MODEL= */ 94 /* CU_MODEL= */
99 ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, 95 ret = add_uevent_var(env, "CU_MODEL=%02X", id->cu_model);
100 "CU_MODEL=%02X", id->cu_model);
101 if (ret) 96 if (ret)
102 return ret; 97 return ret;
103 98
104 /* The next two can be zero, that's ok for us */ 99 /* The next two can be zero, that's ok for us */
105 /* DEV_TYPE= */ 100 /* DEV_TYPE= */
106 ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, 101 ret = add_uevent_var(env, "DEV_TYPE=%04X", id->dev_type);
107 "DEV_TYPE=%04X", id->dev_type);
108 if (ret) 102 if (ret)
109 return ret; 103 return ret;
110 104
111 /* DEV_MODEL= */ 105 /* DEV_MODEL= */
112 ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, 106 ret = add_uevent_var(env, "DEV_MODEL=%02X", id->dev_model);
113 "DEV_MODEL=%02X", id->dev_model);
114 if (ret) 107 if (ret)
115 return ret; 108 return ret;
116 109
117 /* MODALIAS= */ 110 /* MODALIAS= */
118 snprint_alias(modalias_buf, sizeof(modalias_buf), id, ""); 111 snprint_alias(modalias_buf, sizeof(modalias_buf), id, "");
119 ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, 112 ret = add_uevent_var(env, "MODALIAS=%s", modalias_buf);
120 "MODALIAS=%s", modalias_buf); 113 return ret;
121 if (ret)
122 return ret;
123 envp[i] = NULL;
124 return 0;
125} 114}
126 115
127struct bus_type ccw_bus_type; 116struct bus_type ccw_bus_type;
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index d334b0f7a1ec..67aaff3e668d 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -458,28 +458,22 @@ static int ap_bus_match(struct device *dev, struct device_driver *drv)
458 * uevent function for AP devices. It sets up a single environment 458 * uevent function for AP devices. It sets up a single environment
459 * variable DEV_TYPE which contains the hardware device type. 459 * variable DEV_TYPE which contains the hardware device type.
460 */ 460 */
461static int ap_uevent (struct device *dev, char **envp, int num_envp, 461static int ap_uevent (struct device *dev, struct kobj_uevent_env *env)
462 char *buffer, int buffer_size)
463{ 462{
464 struct ap_device *ap_dev = to_ap_dev(dev); 463 struct ap_device *ap_dev = to_ap_dev(dev);
465 int retval = 0, length = 0, i = 0; 464 int retval = 0;
466 465
467 if (!ap_dev) 466 if (!ap_dev)
468 return -ENODEV; 467 return -ENODEV;
469 468
470 /* Set up DEV_TYPE environment variable. */ 469 /* Set up DEV_TYPE environment variable. */
471 retval = add_uevent_var(envp, num_envp, &i, 470 retval = add_uevent_var(env, "DEV_TYPE=%04X", ap_dev->device_type);
472 buffer, buffer_size, &length,
473 "DEV_TYPE=%04X", ap_dev->device_type);
474 if (retval) 471 if (retval)
475 return retval; 472 return retval;
476 473
477 /* Add MODALIAS= */ 474 /* Add MODALIAS= */
478 retval = add_uevent_var(envp, num_envp, &i, 475 retval = add_uevent_var(env, "MODALIAS=ap:t%02X", ap_dev->device_type);
479 buffer, buffer_size, &length,
480 "MODALIAS=ap:t%02X", ap_dev->device_type);
481 476
482 envp[i] = NULL;
483 return retval; 477 return retval;
484} 478}
485 479
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 34cdce6738a6..ede9986d349a 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -277,16 +277,11 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv)
277 return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0; 277 return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0;
278} 278}
279 279
280static int scsi_bus_uevent(struct device *dev, char **envp, int num_envp, 280static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
281 char *buffer, int buffer_size)
282{ 281{
283 struct scsi_device *sdev = to_scsi_device(dev); 282 struct scsi_device *sdev = to_scsi_device(dev);
284 int i = 0;
285 int length = 0;
286 283
287 add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, 284 add_uevent_var(env, "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type);
288 "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type);
289 envp[i] = NULL;
290 return 0; 285 return 0;
291} 286}
292 287
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index e84d21597943..bcb8dd5fb0b4 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -67,14 +67,11 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)
67 return strncmp(spi->modalias, drv->name, BUS_ID_SIZE) == 0; 67 return strncmp(spi->modalias, drv->name, BUS_ID_SIZE) == 0;
68} 68}
69 69
70static int spi_uevent(struct device *dev, char **envp, int num_envp, 70static int spi_uevent(struct device *dev, struct kobj_uevent_env *env)
71 char *buffer, int buffer_size)
72{ 71{
73 const struct spi_device *spi = to_spi_device(dev); 72 const struct spi_device *spi = to_spi_device(dev);
74 73
75 envp[0] = buffer; 74 add_uevent_var(env, "MODALIAS=%s", spi->modalias);
76 snprintf(buffer, buffer_size, "MODALIAS=%s", spi->modalias);
77 envp[1] = NULL;
78 return 0; 75 return 0;
79} 76}
80 77
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index e5ad76b4a738..f013b4012c9a 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1591,6 +1591,7 @@ static unsigned int usbdev_poll(struct file *file, struct poll_table_struct *wai
1591} 1591}
1592 1592
1593const struct file_operations usbdev_file_operations = { 1593const struct file_operations usbdev_file_operations = {
1594 .owner = THIS_MODULE,
1594 .llseek = usbdev_lseek, 1595 .llseek = usbdev_lseek,
1595 .read = usbdev_read, 1596 .read = usbdev_read,
1596 .poll = usbdev_poll, 1597 .poll = usbdev_poll,
@@ -1640,10 +1641,7 @@ static struct notifier_block usbdev_nb = {
1640}; 1641};
1641#endif 1642#endif
1642 1643
1643static struct cdev usb_device_cdev = { 1644static struct cdev usb_device_cdev;
1644 .kobj = {.name = "usb_device", },
1645 .owner = THIS_MODULE,
1646};
1647 1645
1648int __init usb_devio_init(void) 1646int __init usb_devio_init(void)
1649{ 1647{
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index c27bc080d84e..8586817698ad 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -581,12 +581,9 @@ static int usb_device_match(struct device *dev, struct device_driver *drv)
581} 581}
582 582
583#ifdef CONFIG_HOTPLUG 583#ifdef CONFIG_HOTPLUG
584static int usb_uevent(struct device *dev, char **envp, int num_envp, 584static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
585 char *buffer, int buffer_size)
586{ 585{
587 struct usb_device *usb_dev; 586 struct usb_device *usb_dev;
588 int i = 0;
589 int length = 0;
590 587
591 if (!dev) 588 if (!dev)
592 return -ENODEV; 589 return -ENODEV;
@@ -615,51 +612,39 @@ static int usb_uevent(struct device *dev, char **envp, int num_envp,
615 * all the device descriptors we don't tell them about. Or 612 * all the device descriptors we don't tell them about. Or
616 * act as usermode drivers. 613 * act as usermode drivers.
617 */ 614 */
618 if (add_uevent_var(envp, num_envp, &i, 615 if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d",
619 buffer, buffer_size, &length,
620 "DEVICE=/proc/bus/usb/%03d/%03d",
621 usb_dev->bus->busnum, usb_dev->devnum)) 616 usb_dev->bus->busnum, usb_dev->devnum))
622 return -ENOMEM; 617 return -ENOMEM;
623#endif 618#endif
624 619
625 /* per-device configurations are common */ 620 /* per-device configurations are common */
626 if (add_uevent_var(envp, num_envp, &i, 621 if (add_uevent_var(env, "PRODUCT=%x/%x/%x",
627 buffer, buffer_size, &length,
628 "PRODUCT=%x/%x/%x",
629 le16_to_cpu(usb_dev->descriptor.idVendor), 622 le16_to_cpu(usb_dev->descriptor.idVendor),
630 le16_to_cpu(usb_dev->descriptor.idProduct), 623 le16_to_cpu(usb_dev->descriptor.idProduct),
631 le16_to_cpu(usb_dev->descriptor.bcdDevice))) 624 le16_to_cpu(usb_dev->descriptor.bcdDevice)))
632 return -ENOMEM; 625 return -ENOMEM;
633 626
634 /* class-based driver binding models */ 627 /* class-based driver binding models */
635 if (add_uevent_var(envp, num_envp, &i, 628 if (add_uevent_var(env, "TYPE=%d/%d/%d",
636 buffer, buffer_size, &length,
637 "TYPE=%d/%d/%d",
638 usb_dev->descriptor.bDeviceClass, 629 usb_dev->descriptor.bDeviceClass,
639 usb_dev->descriptor.bDeviceSubClass, 630 usb_dev->descriptor.bDeviceSubClass,
640 usb_dev->descriptor.bDeviceProtocol)) 631 usb_dev->descriptor.bDeviceProtocol))
641 return -ENOMEM; 632 return -ENOMEM;
642 633
643 if (add_uevent_var(envp, num_envp, &i, 634 if (add_uevent_var(env, "BUSNUM=%03d",
644 buffer, buffer_size, &length,
645 "BUSNUM=%03d",
646 usb_dev->bus->busnum)) 635 usb_dev->bus->busnum))
647 return -ENOMEM; 636 return -ENOMEM;
648 637
649 if (add_uevent_var(envp, num_envp, &i, 638 if (add_uevent_var(env, "DEVNUM=%03d",
650 buffer, buffer_size, &length,
651 "DEVNUM=%03d",
652 usb_dev->devnum)) 639 usb_dev->devnum))
653 return -ENOMEM; 640 return -ENOMEM;
654 641
655 envp[i] = NULL;
656 return 0; 642 return 0;
657} 643}
658 644
659#else 645#else
660 646
661static int usb_uevent(struct device *dev, char **envp, 647static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
662 int num_envp, char *buffer, int buffer_size)
663{ 648{
664 return -ENODEV; 649 return -ENODEV;
665} 650}
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 98fcddba6908..c021af390372 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1344,14 +1344,11 @@ static void usb_release_interface(struct device *dev)
1344} 1344}
1345 1345
1346#ifdef CONFIG_HOTPLUG 1346#ifdef CONFIG_HOTPLUG
1347static int usb_if_uevent(struct device *dev, char **envp, int num_envp, 1347static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
1348 char *buffer, int buffer_size)
1349{ 1348{
1350 struct usb_device *usb_dev; 1349 struct usb_device *usb_dev;
1351 struct usb_interface *intf; 1350 struct usb_interface *intf;
1352 struct usb_host_interface *alt; 1351 struct usb_host_interface *alt;
1353 int i = 0;
1354 int length = 0;
1355 1352
1356 if (!dev) 1353 if (!dev)
1357 return -ENODEV; 1354 return -ENODEV;
@@ -1364,39 +1361,30 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp,
1364 alt = intf->cur_altsetting; 1361 alt = intf->cur_altsetting;
1365 1362
1366#ifdef CONFIG_USB_DEVICEFS 1363#ifdef CONFIG_USB_DEVICEFS
1367 if (add_uevent_var(envp, num_envp, &i, 1364 if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d",
1368 buffer, buffer_size, &length,
1369 "DEVICE=/proc/bus/usb/%03d/%03d",
1370 usb_dev->bus->busnum, usb_dev->devnum)) 1365 usb_dev->bus->busnum, usb_dev->devnum))
1371 return -ENOMEM; 1366 return -ENOMEM;
1372#endif 1367#endif
1373 1368
1374 if (add_uevent_var(envp, num_envp, &i, 1369 if (add_uevent_var(env, "PRODUCT=%x/%x/%x",
1375 buffer, buffer_size, &length,
1376 "PRODUCT=%x/%x/%x",
1377 le16_to_cpu(usb_dev->descriptor.idVendor), 1370 le16_to_cpu(usb_dev->descriptor.idVendor),
1378 le16_to_cpu(usb_dev->descriptor.idProduct), 1371 le16_to_cpu(usb_dev->descriptor.idProduct),
1379 le16_to_cpu(usb_dev->descriptor.bcdDevice))) 1372 le16_to_cpu(usb_dev->descriptor.bcdDevice)))
1380 return -ENOMEM; 1373 return -ENOMEM;
1381 1374
1382 if (add_uevent_var(envp, num_envp, &i, 1375 if (add_uevent_var(env, "TYPE=%d/%d/%d",
1383 buffer, buffer_size, &length,
1384 "TYPE=%d/%d/%d",
1385 usb_dev->descriptor.bDeviceClass, 1376 usb_dev->descriptor.bDeviceClass,
1386 usb_dev->descriptor.bDeviceSubClass, 1377 usb_dev->descriptor.bDeviceSubClass,
1387 usb_dev->descriptor.bDeviceProtocol)) 1378 usb_dev->descriptor.bDeviceProtocol))
1388 return -ENOMEM; 1379 return -ENOMEM;
1389 1380
1390 if (add_uevent_var(envp, num_envp, &i, 1381 if (add_uevent_var(env, "INTERFACE=%d/%d/%d",
1391 buffer, buffer_size, &length,
1392 "INTERFACE=%d/%d/%d",
1393 alt->desc.bInterfaceClass, 1382 alt->desc.bInterfaceClass,
1394 alt->desc.bInterfaceSubClass, 1383 alt->desc.bInterfaceSubClass,
1395 alt->desc.bInterfaceProtocol)) 1384 alt->desc.bInterfaceProtocol))
1396 return -ENOMEM; 1385 return -ENOMEM;
1397 1386
1398 if (add_uevent_var(envp, num_envp, &i, 1387 if (add_uevent_var(env,
1399 buffer, buffer_size, &length,
1400 "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", 1388 "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
1401 le16_to_cpu(usb_dev->descriptor.idVendor), 1389 le16_to_cpu(usb_dev->descriptor.idVendor),
1402 le16_to_cpu(usb_dev->descriptor.idProduct), 1390 le16_to_cpu(usb_dev->descriptor.idProduct),
@@ -1409,14 +1397,12 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp,
1409 alt->desc.bInterfaceProtocol)) 1397 alt->desc.bInterfaceProtocol))
1410 return -ENOMEM; 1398 return -ENOMEM;
1411 1399
1412 envp[i] = NULL;
1413 return 0; 1400 return 0;
1414} 1401}
1415 1402
1416#else 1403#else
1417 1404
1418static int usb_if_uevent(struct device *dev, char **envp, 1405static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env)
1419 int num_envp, char *buffer, int buffer_size)
1420{ 1406{
1421 return -ENODEV; 1407 return -ENODEV;
1422} 1408}
diff --git a/drivers/video/output.c b/drivers/video/output.c
index 1473f2c892d2..f2df5519c9c4 100644
--- a/drivers/video/output.c
+++ b/drivers/video/output.c
@@ -31,7 +31,8 @@ MODULE_DESCRIPTION("Display Output Switcher Lowlevel Control Abstraction");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32MODULE_AUTHOR("Luming Yu <luming.yu@intel.com>"); 32MODULE_AUTHOR("Luming Yu <luming.yu@intel.com>");
33 33
34static ssize_t video_output_show_state(struct class_device *dev,char *buf) 34static ssize_t video_output_show_state(struct device *dev,
35 struct device_attribute *attr, char *buf)
35{ 36{
36 ssize_t ret_size = 0; 37 ssize_t ret_size = 0;
37 struct output_device *od = to_output_device(dev); 38 struct output_device *od = to_output_device(dev);
@@ -40,8 +41,9 @@ static ssize_t video_output_show_state(struct class_device *dev,char *buf)
40 return ret_size; 41 return ret_size;
41} 42}
42 43
43static ssize_t video_output_store_state(struct class_device *dev, 44static ssize_t video_output_store_state(struct device *dev,
44 const char *buf,size_t count) 45 struct device_attribute *attr,
46 const char *buf,size_t count)
45{ 47{
46 char *endp; 48 char *endp;
47 struct output_device *od = to_output_device(dev); 49 struct output_device *od = to_output_device(dev);
@@ -60,21 +62,22 @@ static ssize_t video_output_store_state(struct class_device *dev,
60 return count; 62 return count;
61} 63}
62 64
63static void video_output_class_release(struct class_device *dev) 65static void video_output_release(struct device *dev)
64{ 66{
65 struct output_device *od = to_output_device(dev); 67 struct output_device *od = to_output_device(dev);
66 kfree(od); 68 kfree(od);
67} 69}
68 70
69static struct class_device_attribute video_output_attributes[] = { 71static struct device_attribute video_output_attributes[] = {
70 __ATTR(state, 0644, video_output_show_state, video_output_store_state), 72 __ATTR(state, 0644, video_output_show_state, video_output_store_state),
71 __ATTR_NULL, 73 __ATTR_NULL,
72}; 74};
73 75
76
74static struct class video_output_class = { 77static struct class video_output_class = {
75 .name = "video_output", 78 .name = "video_output",
76 .release = video_output_class_release, 79 .dev_release = video_output_release,
77 .class_dev_attrs = video_output_attributes, 80 .dev_attrs = video_output_attributes,
78}; 81};
79 82
80struct output_device *video_output_register(const char *name, 83struct output_device *video_output_register(const char *name,
@@ -91,11 +94,11 @@ struct output_device *video_output_register(const char *name,
91 goto error_return; 94 goto error_return;
92 } 95 }
93 new_dev->props = op; 96 new_dev->props = op;
94 new_dev->class_dev.class = &video_output_class; 97 new_dev->dev.class = &video_output_class;
95 new_dev->class_dev.dev = dev; 98 new_dev->dev.parent = dev;
96 strlcpy(new_dev->class_dev.class_id,name,KOBJ_NAME_LEN); 99 strlcpy(new_dev->dev.bus_id,name, BUS_ID_SIZE);
97 class_set_devdata(&new_dev->class_dev,devdata); 100 dev_set_drvdata(&new_dev->dev, devdata);
98 ret_code = class_device_register(&new_dev->class_dev); 101 ret_code = device_register(&new_dev->dev);
99 if (ret_code) { 102 if (ret_code) {
100 kfree(new_dev); 103 kfree(new_dev);
101 goto error_return; 104 goto error_return;
@@ -111,7 +114,7 @@ void video_output_unregister(struct output_device *dev)
111{ 114{
112 if (!dev) 115 if (!dev)
113 return; 116 return;
114 class_device_unregister(&dev->class_dev); 117 device_unregister(&dev->dev);
115} 118}
116EXPORT_SYMBOL(video_output_unregister); 119EXPORT_SYMBOL(video_output_unregister);
117 120
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index a593f900eff4..070217322c9f 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -197,7 +197,7 @@ static struct w1_family w1_default_family = {
197 .fops = &w1_default_fops, 197 .fops = &w1_default_fops,
198}; 198};
199 199
200static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); 200static int w1_uevent(struct device *dev, struct kobj_uevent_env *env);
201 201
202static struct bus_type w1_bus_type = { 202static struct bus_type w1_bus_type = {
203 .name = "w1", 203 .name = "w1",
@@ -396,13 +396,12 @@ static void w1_destroy_master_attributes(struct w1_master *master)
396} 396}
397 397
398#ifdef CONFIG_HOTPLUG 398#ifdef CONFIG_HOTPLUG
399static int w1_uevent(struct device *dev, char **envp, int num_envp, 399static int w1_uevent(struct device *dev, struct kobj_uevent_env *env)
400 char *buffer, int buffer_size)
401{ 400{
402 struct w1_master *md = NULL; 401 struct w1_master *md = NULL;
403 struct w1_slave *sl = NULL; 402 struct w1_slave *sl = NULL;
404 char *event_owner, *name; 403 char *event_owner, *name;
405 int err, cur_index=0, cur_len=0; 404 int err;
406 405
407 if (dev->driver == &w1_master_driver) { 406 if (dev->driver == &w1_master_driver) {
408 md = container_of(dev, struct w1_master, dev); 407 md = container_of(dev, struct w1_master, dev);
@@ -423,23 +422,19 @@ static int w1_uevent(struct device *dev, char **envp, int num_envp,
423 if (dev->driver != &w1_slave_driver || !sl) 422 if (dev->driver != &w1_slave_driver || !sl)
424 return 0; 423 return 0;
425 424
426 err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, 425 err = add_uevent_var(env, "W1_FID=%02X", sl->reg_num.family);
427 &cur_len, "W1_FID=%02X", sl->reg_num.family);
428 if (err) 426 if (err)
429 return err; 427 return err;
430 428
431 err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, 429 err = add_uevent_var(env, "W1_SLAVE_ID=%024LX",
432 &cur_len, "W1_SLAVE_ID=%024LX", 430 (unsigned long long)sl->reg_num.id);
433 (unsigned long long)sl->reg_num.id);
434 envp[cur_index] = NULL;
435 if (err) 431 if (err)
436 return err; 432 return err;
437 433
438 return 0; 434 return 0;
439}; 435};
440#else 436#else
441static int w1_uevent(struct device *dev, char **envp, int num_envp, 437static int w1_uevent(struct device *dev, struct kobj_uevent_env *env)
442 char *buffer, int buffer_size)
443{ 438{
444 return 0; 439 return 0;
445} 440}
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 2e124e0075c5..a9b99c0dc2e7 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -221,6 +221,42 @@ struct dentry *debugfs_create_u64(const char *name, mode_t mode,
221} 221}
222EXPORT_SYMBOL_GPL(debugfs_create_u64); 222EXPORT_SYMBOL_GPL(debugfs_create_u64);
223 223
224DEFINE_SIMPLE_ATTRIBUTE(fops_x8, debugfs_u8_get, debugfs_u8_set, "0x%02llx\n");
225
226DEFINE_SIMPLE_ATTRIBUTE(fops_x16, debugfs_u16_get, debugfs_u16_set, "0x%04llx\n");
227
228DEFINE_SIMPLE_ATTRIBUTE(fops_x32, debugfs_u32_get, debugfs_u32_set, "0x%08llx\n");
229
230/**
231 * debugfs_create_x8 - create a debugfs file that is used to read and write an unsigned 8-bit value
232 * debugfs_create_x16 - create a debugfs file that is used to read and write an unsigned 16-bit value
233 * debugfs_create_x32 - create a debugfs file that is used to read and write an unsigned 32-bit value
234 *
235 * These functions are exactly the same as the above functions, (but use a hex
236 * output for the decimal challenged) for details look at the above unsigned
237 * decimal functions.
238 */
239struct dentry *debugfs_create_x8(const char *name, mode_t mode,
240 struct dentry *parent, u8 *value)
241{
242 return debugfs_create_file(name, mode, parent, value, &fops_x8);
243}
244EXPORT_SYMBOL_GPL(debugfs_create_x8);
245
246struct dentry *debugfs_create_x16(const char *name, mode_t mode,
247 struct dentry *parent, u16 *value)
248{
249 return debugfs_create_file(name, mode, parent, value, &fops_x16);
250}
251EXPORT_SYMBOL_GPL(debugfs_create_x16);
252
253struct dentry *debugfs_create_x32(const char *name, mode_t mode,
254 struct dentry *parent, u32 *value)
255{
256 return debugfs_create_file(name, mode, parent, value, &fops_x32);
257}
258EXPORT_SYMBOL_GPL(debugfs_create_x32);
259
224static ssize_t read_file_bool(struct file *file, char __user *user_buf, 260static ssize_t read_file_bool(struct file *file, char __user *user_buf,
225 size_t count, loff_t *ppos) 261 size_t count, loff_t *ppos)
226{ 262{
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index 628eaa669e68..6353a8384520 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -167,7 +167,6 @@ static struct kobj_type dlm_ktype = {
167}; 167};
168 168
169static struct kset dlm_kset = { 169static struct kset dlm_kset = {
170 .kobj = {.name = "dlm",},
171 .ktype = &dlm_ktype, 170 .ktype = &dlm_ktype,
172}; 171};
173 172
@@ -228,6 +227,7 @@ int dlm_lockspace_init(void)
228 INIT_LIST_HEAD(&lslist); 227 INIT_LIST_HEAD(&lslist);
229 spin_lock_init(&lslist_lock); 228 spin_lock_init(&lslist_lock);
230 229
230 kobject_set_name(&dlm_kset.kobj, "dlm");
231 kobj_set_kset_s(&dlm_kset, kernel_subsys); 231 kobj_set_kset_s(&dlm_kset, kernel_subsys);
232 error = kset_register(&dlm_kset); 232 error = kset_register(&dlm_kset);
233 if (error) 233 if (error)
diff --git a/fs/gfs2/locking/dlm/sysfs.c b/fs/gfs2/locking/dlm/sysfs.c
index d9fe3ca40e18..ae9e6a25fe2b 100644
--- a/fs/gfs2/locking/dlm/sysfs.c
+++ b/fs/gfs2/locking/dlm/sysfs.c
@@ -190,7 +190,6 @@ static struct kobj_type gdlm_ktype = {
190}; 190};
191 191
192static struct kset gdlm_kset = { 192static struct kset gdlm_kset = {
193 .kobj = {.name = "lock_dlm",},
194 .ktype = &gdlm_ktype, 193 .ktype = &gdlm_ktype,
195}; 194};
196 195
@@ -224,6 +223,7 @@ int gdlm_sysfs_init(void)
224{ 223{
225 int error; 224 int error;
226 225
226 kobject_set_name(&gdlm_kset.kobj, "lock_dlm");
227 kobj_set_kset_s(&gdlm_kset, kernel_subsys); 227 kobj_set_kset_s(&gdlm_kset, kernel_subsys);
228 error = kset_register(&gdlm_kset); 228 error = kset_register(&gdlm_kset);
229 if (error) 229 if (error)
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index ba3a1729cc1a..06e0b7768d97 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -222,7 +222,6 @@ static struct kobj_type gfs2_ktype = {
222}; 222};
223 223
224static struct kset gfs2_kset = { 224static struct kset gfs2_kset = {
225 .kobj = {.name = "gfs2"},
226 .ktype = &gfs2_ktype, 225 .ktype = &gfs2_ktype,
227}; 226};
228 227
@@ -551,6 +550,7 @@ int gfs2_sys_init(void)
551{ 550{
552 gfs2_sys_margs = NULL; 551 gfs2_sys_margs = NULL;
553 spin_lock_init(&gfs2_sys_margs_lock); 552 spin_lock_init(&gfs2_sys_margs_lock);
553 kobject_set_name(&gfs2_kset.kobj, "gfs2");
554 kobj_set_kset_s(&gfs2_kset, fs_subsys); 554 kobj_set_kset_s(&gfs2_kset, fs_subsys);
555 return kset_register(&gfs2_kset); 555 return kset_register(&gfs2_kset);
556} 556}
diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c
index e9e042b93dbf..a4882c8df945 100644
--- a/fs/ocfs2/cluster/masklog.c
+++ b/fs/ocfs2/cluster/masklog.c
@@ -143,7 +143,7 @@ static struct kobj_type mlog_ktype = {
143}; 143};
144 144
145static struct kset mlog_kset = { 145static struct kset mlog_kset = {
146 .kobj = {.name = "logmask", .ktype = &mlog_ktype}, 146 .kobj = {.ktype = &mlog_ktype},
147}; 147};
148 148
149int mlog_sys_init(struct kset *o2cb_subsys) 149int mlog_sys_init(struct kset *o2cb_subsys)
@@ -156,6 +156,7 @@ int mlog_sys_init(struct kset *o2cb_subsys)
156 } 156 }
157 mlog_attr_ptrs[i] = NULL; 157 mlog_attr_ptrs[i] = NULL;
158 158
159 kobject_set_name(&mlog_kset.kobj, "logmask");
159 kobj_set_kset_s(&mlog_kset, *o2cb_subsys); 160 kobj_set_kset_s(&mlog_kset, *o2cb_subsys);
160 return kset_register(&mlog_kset); 161 return kset_register(&mlog_kset);
161} 162}
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 783c57ec07d3..722e12e5acc7 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -381,10 +381,12 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len,
381 p->partno = part; 381 p->partno = part;
382 p->policy = disk->policy; 382 p->policy = disk->policy;
383 383
384 if (isdigit(disk->kobj.name[strlen(disk->kobj.name)-1])) 384 if (isdigit(disk->kobj.k_name[strlen(disk->kobj.k_name)-1]))
385 snprintf(p->kobj.name,KOBJ_NAME_LEN,"%sp%d",disk->kobj.name,part); 385 kobject_set_name(&p->kobj, "%sp%d",
386 kobject_name(&disk->kobj), part);
386 else 387 else
387 snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->kobj.name,part); 388 kobject_set_name(&p->kobj, "%s%d",
389 kobject_name(&disk->kobj),part);
388 p->kobj.parent = &disk->kobj; 390 p->kobj.parent = &disk->kobj;
389 p->kobj.ktype = &ktype_part; 391 p->kobj.ktype = &ktype_part;
390 kobject_init(&p->kobj); 392 kobject_init(&p->kobj);
@@ -477,9 +479,9 @@ void register_disk(struct gendisk *disk)
477 struct hd_struct *p; 479 struct hd_struct *p;
478 int err; 480 int err;
479 481
480 strlcpy(disk->kobj.name,disk->disk_name,KOBJ_NAME_LEN); 482 kobject_set_name(&disk->kobj, "%s", disk->disk_name);
481 /* ewww... some of these buggers have / in name... */ 483 /* ewww... some of these buggers have / in name... */
482 s = strchr(disk->kobj.name, '/'); 484 s = strchr(disk->kobj.k_name, '/');
483 if (s) 485 if (s)
484 *s = '!'; 486 *s = '!';
485 if ((err = kobject_add(&disk->kobj))) 487 if ((err = kobject_add(&disk->kobj)))
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index 5afe2a26f5d8..006fc64227dd 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -1,9 +1,15 @@
1/* 1/*
2 * bin.c - binary file operations for sysfs. 2 * fs/sysfs/bin.c - sysfs binary file implementation
3 * 3 *
4 * Copyright (c) 2003 Patrick Mochel 4 * Copyright (c) 2003 Patrick Mochel
5 * Copyright (c) 2003 Matthew Wilcox 5 * Copyright (c) 2003 Matthew Wilcox
6 * Copyright (c) 2004 Silicon Graphics, Inc. 6 * Copyright (c) 2004 Silicon Graphics, Inc.
7 * Copyright (c) 2007 SUSE Linux Products GmbH
8 * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
9 *
10 * This file is released under the GPLv2.
11 *
12 * Please see Documentation/filesystems/sysfs.txt for more information.
7 */ 13 */
8 14
9#undef DEBUG 15#undef DEBUG
@@ -14,9 +20,9 @@
14#include <linux/kobject.h> 20#include <linux/kobject.h>
15#include <linux/module.h> 21#include <linux/module.h>
16#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/mutex.h>
17 24
18#include <asm/uaccess.h> 25#include <asm/uaccess.h>
19#include <asm/semaphore.h>
20 26
21#include "sysfs.h" 27#include "sysfs.h"
22 28
@@ -30,8 +36,8 @@ static int
30fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count) 36fill_read(struct dentry *dentry, char *buffer, loff_t off, size_t count)
31{ 37{
32 struct sysfs_dirent *attr_sd = dentry->d_fsdata; 38 struct sysfs_dirent *attr_sd = dentry->d_fsdata;
33 struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr; 39 struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr;
34 struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj; 40 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
35 int rc; 41 int rc;
36 42
37 /* need attr_sd for attr, its parent for kobj */ 43 /* need attr_sd for attr, its parent for kobj */
@@ -87,8 +93,8 @@ static int
87flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count) 93flush_write(struct dentry *dentry, char *buffer, loff_t offset, size_t count)
88{ 94{
89 struct sysfs_dirent *attr_sd = dentry->d_fsdata; 95 struct sysfs_dirent *attr_sd = dentry->d_fsdata;
90 struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr; 96 struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr;
91 struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj; 97 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
92 int rc; 98 int rc;
93 99
94 /* need attr_sd for attr, its parent for kobj */ 100 /* need attr_sd for attr, its parent for kobj */
@@ -140,8 +146,8 @@ static int mmap(struct file *file, struct vm_area_struct *vma)
140{ 146{
141 struct bin_buffer *bb = file->private_data; 147 struct bin_buffer *bb = file->private_data;
142 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; 148 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
143 struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr; 149 struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr;
144 struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj; 150 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
145 int rc; 151 int rc;
146 152
147 mutex_lock(&bb->mutex); 153 mutex_lock(&bb->mutex);
@@ -167,12 +173,12 @@ static int mmap(struct file *file, struct vm_area_struct *vma)
167static int open(struct inode * inode, struct file * file) 173static int open(struct inode * inode, struct file * file)
168{ 174{
169 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; 175 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
170 struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr; 176 struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr;
171 struct bin_buffer *bb = NULL; 177 struct bin_buffer *bb = NULL;
172 int error; 178 int error;
173 179
174 /* need attr_sd for attr */ 180 /* binary file operations requires both @sd and its parent */
175 if (!sysfs_get_active(attr_sd)) 181 if (!sysfs_get_active_two(attr_sd))
176 return -ENODEV; 182 return -ENODEV;
177 183
178 error = -EACCES; 184 error = -EACCES;
@@ -193,13 +199,12 @@ static int open(struct inode * inode, struct file * file)
193 mutex_init(&bb->mutex); 199 mutex_init(&bb->mutex);
194 file->private_data = bb; 200 file->private_data = bb;
195 201
196 /* open succeeded, put active reference and pin attr_sd */ 202 /* open succeeded, put active references */
197 sysfs_put_active(attr_sd); 203 sysfs_put_active_two(attr_sd);
198 sysfs_get(attr_sd);
199 return 0; 204 return 0;
200 205
201 err_out: 206 err_out:
202 sysfs_put_active(attr_sd); 207 sysfs_put_active_two(attr_sd);
203 kfree(bb); 208 kfree(bb);
204 return error; 209 return error;
205} 210}
@@ -211,7 +216,6 @@ static int release(struct inode * inode, struct file * file)
211 216
212 if (bb->mmapped) 217 if (bb->mmapped)
213 sysfs_put_active_two(attr_sd); 218 sysfs_put_active_two(attr_sd);
214 sysfs_put(attr_sd);
215 kfree(bb->buffer); 219 kfree(bb->buffer);
216 kfree(bb); 220 kfree(bb);
217 return 0; 221 return 0;
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 83e76b3813c9..9161db4d6b5c 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -1,5 +1,13 @@
1/* 1/*
2 * dir.c - Operations for sysfs directories. 2 * fs/sysfs/dir.c - sysfs core and dir operation implementation
3 *
4 * Copyright (c) 2001-3 Patrick Mochel
5 * Copyright (c) 2007 SUSE Linux Products GmbH
6 * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
7 *
8 * This file is released under the GPLv2.
9 *
10 * Please see Documentation/filesystems/sysfs.txt for more information.
3 */ 11 */
4 12
5#undef DEBUG 13#undef DEBUG
@@ -11,10 +19,11 @@
11#include <linux/namei.h> 19#include <linux/namei.h>
12#include <linux/idr.h> 20#include <linux/idr.h>
13#include <linux/completion.h> 21#include <linux/completion.h>
14#include <asm/semaphore.h> 22#include <linux/mutex.h>
15#include "sysfs.h" 23#include "sysfs.h"
16 24
17DEFINE_MUTEX(sysfs_mutex); 25DEFINE_MUTEX(sysfs_mutex);
26DEFINE_MUTEX(sysfs_rename_mutex);
18spinlock_t sysfs_assoc_lock = SPIN_LOCK_UNLOCKED; 27spinlock_t sysfs_assoc_lock = SPIN_LOCK_UNLOCKED;
19 28
20static spinlock_t sysfs_ino_lock = SPIN_LOCK_UNLOCKED; 29static spinlock_t sysfs_ino_lock = SPIN_LOCK_UNLOCKED;
@@ -25,18 +34,28 @@ static DEFINE_IDA(sysfs_ino_ida);
25 * @sd: sysfs_dirent of interest 34 * @sd: sysfs_dirent of interest
26 * 35 *
27 * Link @sd into its sibling list which starts from 36 * Link @sd into its sibling list which starts from
28 * sd->s_parent->s_children. 37 * sd->s_parent->s_dir.children.
29 * 38 *
30 * Locking: 39 * Locking:
31 * mutex_lock(sysfs_mutex) 40 * mutex_lock(sysfs_mutex)
32 */ 41 */
33void sysfs_link_sibling(struct sysfs_dirent *sd) 42static void sysfs_link_sibling(struct sysfs_dirent *sd)
34{ 43{
35 struct sysfs_dirent *parent_sd = sd->s_parent; 44 struct sysfs_dirent *parent_sd = sd->s_parent;
45 struct sysfs_dirent **pos;
36 46
37 BUG_ON(sd->s_sibling); 47 BUG_ON(sd->s_sibling);
38 sd->s_sibling = parent_sd->s_children; 48
39 parent_sd->s_children = sd; 49 /* Store directory entries in order by ino. This allows
50 * readdir to properly restart without having to add a
51 * cursor into the s_dir.children list.
52 */
53 for (pos = &parent_sd->s_dir.children; *pos; pos = &(*pos)->s_sibling) {
54 if (sd->s_ino < (*pos)->s_ino)
55 break;
56 }
57 sd->s_sibling = *pos;
58 *pos = sd;
40} 59}
41 60
42/** 61/**
@@ -44,16 +63,17 @@ void sysfs_link_sibling(struct sysfs_dirent *sd)
44 * @sd: sysfs_dirent of interest 63 * @sd: sysfs_dirent of interest
45 * 64 *
46 * Unlink @sd from its sibling list which starts from 65 * Unlink @sd from its sibling list which starts from
47 * sd->s_parent->s_children. 66 * sd->s_parent->s_dir.children.
48 * 67 *
49 * Locking: 68 * Locking:
50 * mutex_lock(sysfs_mutex) 69 * mutex_lock(sysfs_mutex)
51 */ 70 */
52void sysfs_unlink_sibling(struct sysfs_dirent *sd) 71static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
53{ 72{
54 struct sysfs_dirent **pos; 73 struct sysfs_dirent **pos;
55 74
56 for (pos = &sd->s_parent->s_children; *pos; pos = &(*pos)->s_sibling) { 75 for (pos = &sd->s_parent->s_dir.children; *pos;
76 pos = &(*pos)->s_sibling) {
57 if (*pos == sd) { 77 if (*pos == sd) {
58 *pos = sd->s_sibling; 78 *pos = sd->s_sibling;
59 sd->s_sibling = NULL; 79 sd->s_sibling = NULL;
@@ -67,96 +87,39 @@ void sysfs_unlink_sibling(struct sysfs_dirent *sd)
67 * @sd: sysfs_dirent of interest 87 * @sd: sysfs_dirent of interest
68 * 88 *
69 * Get dentry for @sd. Dentry is looked up if currently not 89 * Get dentry for @sd. Dentry is looked up if currently not
70 * present. This function climbs sysfs_dirent tree till it 90 * present. This function descends from the root looking up
71 * reaches a sysfs_dirent with valid dentry attached and descends 91 * dentry for each step.
72 * down from there looking up dentry for each step.
73 * 92 *
74 * LOCKING: 93 * LOCKING:
75 * Kernel thread context (may sleep) 94 * mutex_lock(sysfs_rename_mutex)
76 * 95 *
77 * RETURNS: 96 * RETURNS:
78 * Pointer to found dentry on success, ERR_PTR() value on error. 97 * Pointer to found dentry on success, ERR_PTR() value on error.
79 */ 98 */
80struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd) 99struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd)
81{ 100{
82 struct sysfs_dirent *cur; 101 struct dentry *dentry = dget(sysfs_sb->s_root);
83 struct dentry *parent_dentry, *dentry;
84 int i, depth;
85
86 /* Find the first parent which has valid s_dentry and get the
87 * dentry.
88 */
89 mutex_lock(&sysfs_mutex);
90 restart0:
91 spin_lock(&sysfs_assoc_lock);
92 restart1:
93 spin_lock(&dcache_lock);
94 102
95 dentry = NULL; 103 while (dentry->d_fsdata != sd) {
96 depth = 0; 104 struct sysfs_dirent *cur;
97 cur = sd; 105 struct dentry *parent;
98 while (!cur->s_dentry || !cur->s_dentry->d_inode) {
99 if (cur->s_flags & SYSFS_FLAG_REMOVED) {
100 dentry = ERR_PTR(-ENOENT);
101 depth = 0;
102 break;
103 }
104 cur = cur->s_parent;
105 depth++;
106 }
107 if (!IS_ERR(dentry))
108 dentry = dget_locked(cur->s_dentry);
109 106
110 spin_unlock(&dcache_lock); 107 /* find the first ancestor which hasn't been looked up */
111 spin_unlock(&sysfs_assoc_lock); 108 cur = sd;
112 109 while (cur->s_parent != dentry->d_fsdata)
113 /* from the found dentry, look up depth times */
114 while (depth--) {
115 /* find and get depth'th ancestor */
116 for (cur = sd, i = 0; cur && i < depth; i++)
117 cur = cur->s_parent; 110 cur = cur->s_parent;
118 111
119 /* This can happen if tree structure was modified due
120 * to move/rename. Restart.
121 */
122 if (i != depth) {
123 dput(dentry);
124 goto restart0;
125 }
126
127 sysfs_get(cur);
128
129 mutex_unlock(&sysfs_mutex);
130
131 /* look it up */ 112 /* look it up */
132 parent_dentry = dentry; 113 parent = dentry;
133 dentry = lookup_one_len_kern(cur->s_name, parent_dentry, 114 mutex_lock(&parent->d_inode->i_mutex);
115 dentry = lookup_one_len_kern(cur->s_name, parent,
134 strlen(cur->s_name)); 116 strlen(cur->s_name));
135 dput(parent_dentry); 117 mutex_unlock(&parent->d_inode->i_mutex);
136 118 dput(parent);
137 if (IS_ERR(dentry)) {
138 sysfs_put(cur);
139 return dentry;
140 }
141 119
142 mutex_lock(&sysfs_mutex); 120 if (IS_ERR(dentry))
143 spin_lock(&sysfs_assoc_lock); 121 break;
144
145 /* This, again, can happen if tree structure has
146 * changed and we looked up the wrong thing. Restart.
147 */
148 if (cur->s_dentry != dentry) {
149 dput(dentry);
150 sysfs_put(cur);
151 goto restart1;
152 }
153
154 spin_unlock(&sysfs_assoc_lock);
155
156 sysfs_put(cur);
157 } 122 }
158
159 mutex_unlock(&sysfs_mutex);
160 return dentry; 123 return dentry;
161} 124}
162 125
@@ -319,7 +282,7 @@ void release_sysfs_dirent(struct sysfs_dirent * sd)
319 parent_sd = sd->s_parent; 282 parent_sd = sd->s_parent;
320 283
321 if (sysfs_type(sd) == SYSFS_KOBJ_LINK) 284 if (sysfs_type(sd) == SYSFS_KOBJ_LINK)
322 sysfs_put(sd->s_elem.symlink.target_sd); 285 sysfs_put(sd->s_symlink.target_sd);
323 if (sysfs_type(sd) & SYSFS_COPY_NAME) 286 if (sysfs_type(sd) & SYSFS_COPY_NAME)
324 kfree(sd->s_name); 287 kfree(sd->s_name);
325 kfree(sd->s_iattr); 288 kfree(sd->s_iattr);
@@ -335,22 +298,7 @@ static void sysfs_d_iput(struct dentry * dentry, struct inode * inode)
335{ 298{
336 struct sysfs_dirent * sd = dentry->d_fsdata; 299 struct sysfs_dirent * sd = dentry->d_fsdata;
337 300
338 if (sd) { 301 sysfs_put(sd);
339 /* sd->s_dentry is protected with sysfs_assoc_lock.
340 * This allows sysfs_drop_dentry() to dereference it.
341 */
342 spin_lock(&sysfs_assoc_lock);
343
344 /* The dentry might have been deleted or another
345 * lookup could have happened updating sd->s_dentry to
346 * point the new dentry. Ignore if it isn't pointing
347 * to this dentry.
348 */
349 if (sd->s_dentry == dentry)
350 sd->s_dentry = NULL;
351 spin_unlock(&sysfs_assoc_lock);
352 sysfs_put(sd);
353 }
354 iput(inode); 302 iput(inode);
355} 303}
356 304
@@ -378,7 +326,6 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
378 326
379 atomic_set(&sd->s_count, 1); 327 atomic_set(&sd->s_count, 1);
380 atomic_set(&sd->s_active, 0); 328 atomic_set(&sd->s_active, 0);
381 atomic_set(&sd->s_event, 1);
382 329
383 sd->s_name = name; 330 sd->s_name = name;
384 sd->s_mode = mode; 331 sd->s_mode = mode;
@@ -393,30 +340,6 @@ struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type)
393 return NULL; 340 return NULL;
394} 341}
395 342
396/**
397 * sysfs_attach_dentry - associate sysfs_dirent with dentry
398 * @sd: target sysfs_dirent
399 * @dentry: dentry to associate
400 *
401 * Associate @sd with @dentry. This is protected by
402 * sysfs_assoc_lock to avoid race with sysfs_d_iput().
403 *
404 * LOCKING:
405 * mutex_lock(sysfs_mutex)
406 */
407static void sysfs_attach_dentry(struct sysfs_dirent *sd, struct dentry *dentry)
408{
409 dentry->d_op = &sysfs_dentry_ops;
410 dentry->d_fsdata = sysfs_get(sd);
411
412 /* protect sd->s_dentry against sysfs_d_iput */
413 spin_lock(&sysfs_assoc_lock);
414 sd->s_dentry = dentry;
415 spin_unlock(&sysfs_assoc_lock);
416
417 d_rehash(dentry);
418}
419
420static int sysfs_ilookup_test(struct inode *inode, void *arg) 343static int sysfs_ilookup_test(struct inode *inode, void *arg)
421{ 344{
422 struct sysfs_dirent *sd = arg; 345 struct sysfs_dirent *sd = arg;
@@ -480,10 +403,8 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
480 * @sd: sysfs_dirent to be added 403 * @sd: sysfs_dirent to be added
481 * 404 *
482 * Get @acxt->parent_sd and set sd->s_parent to it and increment 405 * Get @acxt->parent_sd and set sd->s_parent to it and increment
483 * nlink of parent inode if @sd is a directory. @sd is NOT 406 * nlink of parent inode if @sd is a directory and link into the
484 * linked into the children list of the parent. The caller 407 * children list of the parent.
485 * should invoke sysfs_link_sibling() after this function
486 * completes if @sd needs to be on the children list.
487 * 408 *
488 * This function should be called between calls to 409 * This function should be called between calls to
489 * sysfs_addrm_start() and sysfs_addrm_finish() and should be 410 * sysfs_addrm_start() and sysfs_addrm_finish() and should be
@@ -491,15 +412,30 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
491 * 412 *
492 * LOCKING: 413 * LOCKING:
493 * Determined by sysfs_addrm_start(). 414 * Determined by sysfs_addrm_start().
415 *
416 * RETURNS:
417 * 0 on success, -EEXIST if entry with the given name already
418 * exists.
494 */ 419 */
495void sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) 420int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
496{ 421{
422 if (sysfs_find_dirent(acxt->parent_sd, sd->s_name)) {
423 printk(KERN_WARNING "sysfs: duplicate filename '%s' "
424 "can not be created\n", sd->s_name);
425 WARN_ON(1);
426 return -EEXIST;
427 }
428
497 sd->s_parent = sysfs_get(acxt->parent_sd); 429 sd->s_parent = sysfs_get(acxt->parent_sd);
498 430
499 if (sysfs_type(sd) == SYSFS_DIR && acxt->parent_inode) 431 if (sysfs_type(sd) == SYSFS_DIR && acxt->parent_inode)
500 inc_nlink(acxt->parent_inode); 432 inc_nlink(acxt->parent_inode);
501 433
502 acxt->cnt++; 434 acxt->cnt++;
435
436 sysfs_link_sibling(sd);
437
438 return 0;
503} 439}
504 440
505/** 441/**
@@ -508,9 +444,7 @@ void sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
508 * @sd: sysfs_dirent to be added 444 * @sd: sysfs_dirent to be added
509 * 445 *
510 * Mark @sd removed and drop nlink of parent inode if @sd is a 446 * Mark @sd removed and drop nlink of parent inode if @sd is a
511 * directory. @sd is NOT unlinked from the children list of the 447 * directory. @sd is unlinked from the children list.
512 * parent. The caller is repsonsible for removing @sd from the
513 * children list before calling this function.
514 * 448 *
515 * This function should be called between calls to 449 * This function should be called between calls to
516 * sysfs_addrm_start() and sysfs_addrm_finish() and should be 450 * sysfs_addrm_start() and sysfs_addrm_finish() and should be
@@ -521,7 +455,9 @@ void sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
521 */ 455 */
522void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) 456void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
523{ 457{
524 BUG_ON(sd->s_sibling || (sd->s_flags & SYSFS_FLAG_REMOVED)); 458 BUG_ON(sd->s_flags & SYSFS_FLAG_REMOVED);
459
460 sysfs_unlink_sibling(sd);
525 461
526 sd->s_flags |= SYSFS_FLAG_REMOVED; 462 sd->s_flags |= SYSFS_FLAG_REMOVED;
527 sd->s_sibling = acxt->removed; 463 sd->s_sibling = acxt->removed;
@@ -540,53 +476,49 @@ void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
540 * Drop dentry for @sd. @sd must have been unlinked from its 476 * Drop dentry for @sd. @sd must have been unlinked from its
541 * parent on entry to this function such that it can't be looked 477 * parent on entry to this function such that it can't be looked
542 * up anymore. 478 * up anymore.
543 *
544 * @sd->s_dentry which is protected with sysfs_assoc_lock points
545 * to the currently associated dentry but we're not holding a
546 * reference to it and racing with dput(). Grab dcache_lock and
547 * verify dentry before dropping it. If @sd->s_dentry is NULL or
548 * dput() beats us, no need to bother.
549 */ 479 */
550static void sysfs_drop_dentry(struct sysfs_dirent *sd) 480static void sysfs_drop_dentry(struct sysfs_dirent *sd)
551{ 481{
552 struct dentry *dentry = NULL;
553 struct inode *inode; 482 struct inode *inode;
483 struct dentry *dentry;
554 484
555 /* We're not holding a reference to ->s_dentry dentry but the 485 inode = ilookup(sysfs_sb, sd->s_ino);
556 * field will stay valid as long as sysfs_assoc_lock is held. 486 if (!inode)
487 return;
488
489 /* Drop any existing dentries associated with sd.
490 *
491 * For the dentry to be properly freed we need to grab a
492 * reference to the dentry under the dcache lock, unhash it,
493 * and then put it. The playing with the dentry count allows
494 * dput to immediately free the dentry if it is not in use.
557 */ 495 */
558 spin_lock(&sysfs_assoc_lock); 496repeat:
559 spin_lock(&dcache_lock); 497 spin_lock(&dcache_lock);
560 498 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
561 /* drop dentry if it's there and dput() didn't kill it yet */ 499 if (d_unhashed(dentry))
562 if (sd->s_dentry && sd->s_dentry->d_inode) { 500 continue;
563 dentry = dget_locked(sd->s_dentry); 501 dget_locked(dentry);
564 spin_lock(&dentry->d_lock); 502 spin_lock(&dentry->d_lock);
565 __d_drop(dentry); 503 __d_drop(dentry);
566 spin_unlock(&dentry->d_lock); 504 spin_unlock(&dentry->d_lock);
505 spin_unlock(&dcache_lock);
506 dput(dentry);
507 goto repeat;
567 } 508 }
568
569 spin_unlock(&dcache_lock); 509 spin_unlock(&dcache_lock);
570 spin_unlock(&sysfs_assoc_lock);
571
572 /* dentries for shadowed inodes are pinned, unpin */
573 if (dentry && sysfs_is_shadowed_inode(dentry->d_inode))
574 dput(dentry);
575 dput(dentry);
576 510
577 /* adjust nlink and update timestamp */ 511 /* adjust nlink and update timestamp */
578 inode = ilookup(sysfs_sb, sd->s_ino); 512 mutex_lock(&inode->i_mutex);
579 if (inode) {
580 mutex_lock(&inode->i_mutex);
581 513
582 inode->i_ctime = CURRENT_TIME; 514 inode->i_ctime = CURRENT_TIME;
515 drop_nlink(inode);
516 if (sysfs_type(sd) == SYSFS_DIR)
583 drop_nlink(inode); 517 drop_nlink(inode);
584 if (sysfs_type(sd) == SYSFS_DIR)
585 drop_nlink(inode);
586 518
587 mutex_unlock(&inode->i_mutex); 519 mutex_unlock(&inode->i_mutex);
588 iput(inode); 520
589 } 521 iput(inode);
590} 522}
591 523
592/** 524/**
@@ -599,11 +531,8 @@ static void sysfs_drop_dentry(struct sysfs_dirent *sd)
599 * 531 *
600 * LOCKING: 532 * LOCKING:
601 * All mutexes acquired by sysfs_addrm_start() are released. 533 * All mutexes acquired by sysfs_addrm_start() are released.
602 *
603 * RETURNS:
604 * Number of added/removed sysfs_dirents since sysfs_addrm_start().
605 */ 534 */
606int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt) 535void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
607{ 536{
608 /* release resources acquired by sysfs_addrm_start() */ 537 /* release resources acquired by sysfs_addrm_start() */
609 mutex_unlock(&sysfs_mutex); 538 mutex_unlock(&sysfs_mutex);
@@ -629,8 +558,6 @@ int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt)
629 sysfs_deactivate(sd); 558 sysfs_deactivate(sd);
630 sysfs_put(sd); 559 sysfs_put(sd);
631 } 560 }
632
633 return acxt->cnt;
634} 561}
635 562
636/** 563/**
@@ -651,8 +578,8 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
651{ 578{
652 struct sysfs_dirent *sd; 579 struct sysfs_dirent *sd;
653 580
654 for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) 581 for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling)
655 if (sysfs_type(sd) && !strcmp(sd->s_name, name)) 582 if (!strcmp(sd->s_name, name))
656 return sd; 583 return sd;
657 return NULL; 584 return NULL;
658} 585}
@@ -690,28 +617,25 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
690 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; 617 umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
691 struct sysfs_addrm_cxt acxt; 618 struct sysfs_addrm_cxt acxt;
692 struct sysfs_dirent *sd; 619 struct sysfs_dirent *sd;
620 int rc;
693 621
694 /* allocate */ 622 /* allocate */
695 sd = sysfs_new_dirent(name, mode, SYSFS_DIR); 623 sd = sysfs_new_dirent(name, mode, SYSFS_DIR);
696 if (!sd) 624 if (!sd)
697 return -ENOMEM; 625 return -ENOMEM;
698 sd->s_elem.dir.kobj = kobj; 626 sd->s_dir.kobj = kobj;
699 627
700 /* link in */ 628 /* link in */
701 sysfs_addrm_start(&acxt, parent_sd); 629 sysfs_addrm_start(&acxt, parent_sd);
630 rc = sysfs_add_one(&acxt, sd);
631 sysfs_addrm_finish(&acxt);
702 632
703 if (!sysfs_find_dirent(parent_sd, name)) { 633 if (rc == 0)
704 sysfs_add_one(&acxt, sd); 634 *p_sd = sd;
705 sysfs_link_sibling(sd); 635 else
706 }
707
708 if (!sysfs_addrm_finish(&acxt)) {
709 sysfs_put(sd); 636 sysfs_put(sd);
710 return -EEXIST;
711 }
712 637
713 *p_sd = sd; 638 return rc;
714 return 0;
715} 639}
716 640
717int sysfs_create_subdir(struct kobject *kobj, const char *name, 641int sysfs_create_subdir(struct kobject *kobj, const char *name,
@@ -723,24 +647,18 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name,
723/** 647/**
724 * sysfs_create_dir - create a directory for an object. 648 * sysfs_create_dir - create a directory for an object.
725 * @kobj: object we're creating directory for. 649 * @kobj: object we're creating directory for.
726 * @shadow_parent: parent object.
727 */ 650 */
728int sysfs_create_dir(struct kobject *kobj, 651int sysfs_create_dir(struct kobject * kobj)
729 struct sysfs_dirent *shadow_parent_sd)
730{ 652{
731 struct sysfs_dirent *parent_sd, *sd; 653 struct sysfs_dirent *parent_sd, *sd;
732 int error = 0; 654 int error = 0;
733 655
734 BUG_ON(!kobj); 656 BUG_ON(!kobj);
735 657
736 if (shadow_parent_sd) 658 if (kobj->parent)
737 parent_sd = shadow_parent_sd;
738 else if (kobj->parent)
739 parent_sd = kobj->parent->sd; 659 parent_sd = kobj->parent->sd;
740 else if (sysfs_mount && sysfs_mount->mnt_sb)
741 parent_sd = sysfs_mount->mnt_sb->s_root->d_fsdata;
742 else 660 else
743 return -EFAULT; 661 parent_sd = &sysfs_root;
744 662
745 error = create_dir(kobj, parent_sd, kobject_name(kobj), &sd); 663 error = create_dir(kobj, parent_sd, kobject_name(kobj), &sd);
746 if (!error) 664 if (!error)
@@ -748,39 +666,20 @@ int sysfs_create_dir(struct kobject *kobj,
748 return error; 666 return error;
749} 667}
750 668
751static int sysfs_count_nlink(struct sysfs_dirent *sd)
752{
753 struct sysfs_dirent *child;
754 int nr = 0;
755
756 for (child = sd->s_children; child; child = child->s_sibling)
757 if (sysfs_type(child) == SYSFS_DIR)
758 nr++;
759 return nr + 2;
760}
761
762static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, 669static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
763 struct nameidata *nd) 670 struct nameidata *nd)
764{ 671{
765 struct dentry *ret = NULL; 672 struct dentry *ret = NULL;
766 struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata; 673 struct sysfs_dirent *parent_sd = dentry->d_parent->d_fsdata;
767 struct sysfs_dirent * sd; 674 struct sysfs_dirent *sd;
768 struct bin_attribute *bin_attr;
769 struct inode *inode; 675 struct inode *inode;
770 int found = 0;
771 676
772 mutex_lock(&sysfs_mutex); 677 mutex_lock(&sysfs_mutex);
773 678
774 for (sd = parent_sd->s_children; sd; sd = sd->s_sibling) { 679 sd = sysfs_find_dirent(parent_sd, dentry->d_name.name);
775 if (sysfs_type(sd) &&
776 !strcmp(sd->s_name, dentry->d_name.name)) {
777 found = 1;
778 break;
779 }
780 }
781 680
782 /* no such entry */ 681 /* no such entry */
783 if (!found) 682 if (!sd)
784 goto out_unlock; 683 goto out_unlock;
785 684
786 /* attach dentry and inode */ 685 /* attach dentry and inode */
@@ -790,33 +689,11 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
790 goto out_unlock; 689 goto out_unlock;
791 } 690 }
792 691
793 if (inode->i_state & I_NEW) { 692 /* instantiate and hash dentry */
794 /* initialize inode according to type */ 693 dentry->d_op = &sysfs_dentry_ops;
795 switch (sysfs_type(sd)) { 694 dentry->d_fsdata = sysfs_get(sd);
796 case SYSFS_DIR: 695 d_instantiate(dentry, inode);
797 inode->i_op = &sysfs_dir_inode_operations; 696 d_rehash(dentry);
798 inode->i_fop = &sysfs_dir_operations;
799 inode->i_nlink = sysfs_count_nlink(sd);
800 break;
801 case SYSFS_KOBJ_ATTR:
802 inode->i_size = PAGE_SIZE;
803 inode->i_fop = &sysfs_file_operations;
804 break;
805 case SYSFS_KOBJ_BIN_ATTR:
806 bin_attr = sd->s_elem.bin_attr.bin_attr;
807 inode->i_size = bin_attr->size;
808 inode->i_fop = &bin_fops;
809 break;
810 case SYSFS_KOBJ_LINK:
811 inode->i_op = &sysfs_symlink_inode_operations;
812 break;
813 default:
814 BUG();
815 }
816 }
817
818 sysfs_instantiate(dentry, inode);
819 sysfs_attach_dentry(sd, dentry);
820 697
821 out_unlock: 698 out_unlock:
822 mutex_unlock(&sysfs_mutex); 699 mutex_unlock(&sysfs_mutex);
@@ -833,7 +710,6 @@ static void remove_dir(struct sysfs_dirent *sd)
833 struct sysfs_addrm_cxt acxt; 710 struct sysfs_addrm_cxt acxt;
834 711
835 sysfs_addrm_start(&acxt, sd->s_parent); 712 sysfs_addrm_start(&acxt, sd->s_parent);
836 sysfs_unlink_sibling(sd);
837 sysfs_remove_one(&acxt, sd); 713 sysfs_remove_one(&acxt, sd);
838 sysfs_addrm_finish(&acxt); 714 sysfs_addrm_finish(&acxt);
839} 715}
@@ -854,15 +730,13 @@ static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd)
854 730
855 pr_debug("sysfs %s: removing dir\n", dir_sd->s_name); 731 pr_debug("sysfs %s: removing dir\n", dir_sd->s_name);
856 sysfs_addrm_start(&acxt, dir_sd); 732 sysfs_addrm_start(&acxt, dir_sd);
857 pos = &dir_sd->s_children; 733 pos = &dir_sd->s_dir.children;
858 while (*pos) { 734 while (*pos) {
859 struct sysfs_dirent *sd = *pos; 735 struct sysfs_dirent *sd = *pos;
860 736
861 if (sysfs_type(sd) && sysfs_type(sd) != SYSFS_DIR) { 737 if (sysfs_type(sd) != SYSFS_DIR)
862 *pos = sd->s_sibling;
863 sd->s_sibling = NULL;
864 sysfs_remove_one(&acxt, sd); 738 sysfs_remove_one(&acxt, sd);
865 } else 739 else
866 pos = &(*pos)->s_sibling; 740 pos = &(*pos)->s_sibling;
867 } 741 }
868 sysfs_addrm_finish(&acxt); 742 sysfs_addrm_finish(&acxt);
@@ -890,90 +764,68 @@ void sysfs_remove_dir(struct kobject * kobj)
890 __sysfs_remove_dir(sd); 764 __sysfs_remove_dir(sd);
891} 765}
892 766
893int sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd, 767int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
894 const char *new_name)
895{ 768{
896 struct sysfs_dirent *sd = kobj->sd; 769 struct sysfs_dirent *sd = kobj->sd;
897 struct dentry *new_parent = NULL; 770 struct dentry *parent = NULL;
898 struct dentry *old_dentry = NULL, *new_dentry = NULL; 771 struct dentry *old_dentry = NULL, *new_dentry = NULL;
899 const char *dup_name = NULL; 772 const char *dup_name = NULL;
900 int error; 773 int error;
901 774
902 /* get dentries */ 775 mutex_lock(&sysfs_rename_mutex);
776
777 error = 0;
778 if (strcmp(sd->s_name, new_name) == 0)
779 goto out; /* nothing to rename */
780
781 /* get the original dentry */
903 old_dentry = sysfs_get_dentry(sd); 782 old_dentry = sysfs_get_dentry(sd);
904 if (IS_ERR(old_dentry)) { 783 if (IS_ERR(old_dentry)) {
905 error = PTR_ERR(old_dentry); 784 error = PTR_ERR(old_dentry);
906 goto out_dput; 785 goto out;
907 }
908
909 new_parent = sysfs_get_dentry(new_parent_sd);
910 if (IS_ERR(new_parent)) {
911 error = PTR_ERR(new_parent);
912 goto out_dput;
913 } 786 }
914 787
915 /* lock new_parent and get dentry for new name */ 788 parent = old_dentry->d_parent;
916 mutex_lock(&new_parent->d_inode->i_mutex);
917 789
918 new_dentry = lookup_one_len(new_name, new_parent, strlen(new_name)); 790 /* lock parent and get dentry for new name */
919 if (IS_ERR(new_dentry)) { 791 mutex_lock(&parent->d_inode->i_mutex);
920 error = PTR_ERR(new_dentry); 792 mutex_lock(&sysfs_mutex);
921 goto out_unlock;
922 }
923 793
924 /* By allowing two different directories with the same 794 error = -EEXIST;
925 * d_parent we allow this routine to move between different 795 if (sysfs_find_dirent(sd->s_parent, new_name))
926 * shadows of the same directory
927 */
928 error = -EINVAL;
929 if (old_dentry->d_parent->d_inode != new_parent->d_inode ||
930 new_dentry->d_parent->d_inode != new_parent->d_inode ||
931 old_dentry == new_dentry)
932 goto out_unlock; 796 goto out_unlock;
933 797
934 error = -EEXIST; 798 error = -ENOMEM;
935 if (new_dentry->d_inode) 799 new_dentry = d_alloc_name(parent, new_name);
800 if (!new_dentry)
936 goto out_unlock; 801 goto out_unlock;
937 802
938 /* rename kobject and sysfs_dirent */ 803 /* rename kobject and sysfs_dirent */
939 error = -ENOMEM; 804 error = -ENOMEM;
940 new_name = dup_name = kstrdup(new_name, GFP_KERNEL); 805 new_name = dup_name = kstrdup(new_name, GFP_KERNEL);
941 if (!new_name) 806 if (!new_name)
942 goto out_drop; 807 goto out_unlock;
943 808
944 error = kobject_set_name(kobj, "%s", new_name); 809 error = kobject_set_name(kobj, "%s", new_name);
945 if (error) 810 if (error)
946 goto out_drop; 811 goto out_unlock;
947
948 mutex_lock(&sysfs_mutex);
949 812
950 dup_name = sd->s_name; 813 dup_name = sd->s_name;
951 sd->s_name = new_name; 814 sd->s_name = new_name;
952 815
953 /* move under the new parent */ 816 /* rename */
954 d_add(new_dentry, NULL); 817 d_add(new_dentry, NULL);
955 d_move(sd->s_dentry, new_dentry); 818 d_move(old_dentry, new_dentry);
956
957 sysfs_unlink_sibling(sd);
958 sysfs_get(new_parent_sd);
959 sysfs_put(sd->s_parent);
960 sd->s_parent = new_parent_sd;
961 sysfs_link_sibling(sd);
962
963 mutex_unlock(&sysfs_mutex);
964 819
965 error = 0; 820 error = 0;
966 goto out_unlock;
967
968 out_drop:
969 d_drop(new_dentry);
970 out_unlock: 821 out_unlock:
971 mutex_unlock(&new_parent->d_inode->i_mutex); 822 mutex_unlock(&sysfs_mutex);
972 out_dput: 823 mutex_unlock(&parent->d_inode->i_mutex);
973 kfree(dup_name); 824 kfree(dup_name);
974 dput(new_parent);
975 dput(old_dentry); 825 dput(old_dentry);
976 dput(new_dentry); 826 dput(new_dentry);
827 out:
828 mutex_unlock(&sysfs_rename_mutex);
977 return error; 829 return error;
978} 830}
979 831
@@ -985,96 +837,69 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj)
985 struct dentry *old_dentry = NULL, *new_dentry = NULL; 837 struct dentry *old_dentry = NULL, *new_dentry = NULL;
986 int error; 838 int error;
987 839
840 mutex_lock(&sysfs_rename_mutex);
988 BUG_ON(!sd->s_parent); 841 BUG_ON(!sd->s_parent);
989 new_parent_sd = new_parent_kobj->sd ? new_parent_kobj->sd : &sysfs_root; 842 new_parent_sd = new_parent_kobj->sd ? new_parent_kobj->sd : &sysfs_root;
990 843
844 error = 0;
845 if (sd->s_parent == new_parent_sd)
846 goto out; /* nothing to move */
847
991 /* get dentries */ 848 /* get dentries */
992 old_dentry = sysfs_get_dentry(sd); 849 old_dentry = sysfs_get_dentry(sd);
993 if (IS_ERR(old_dentry)) { 850 if (IS_ERR(old_dentry)) {
994 error = PTR_ERR(old_dentry); 851 error = PTR_ERR(old_dentry);
995 goto out_dput; 852 goto out;
996 } 853 }
997 old_parent = sd->s_parent->s_dentry; 854 old_parent = old_dentry->d_parent;
998 855
999 new_parent = sysfs_get_dentry(new_parent_sd); 856 new_parent = sysfs_get_dentry(new_parent_sd);
1000 if (IS_ERR(new_parent)) { 857 if (IS_ERR(new_parent)) {
1001 error = PTR_ERR(new_parent); 858 error = PTR_ERR(new_parent);
1002 goto out_dput; 859 goto out;
1003 } 860 }
1004 861
1005 if (old_parent->d_inode == new_parent->d_inode) {
1006 error = 0;
1007 goto out_dput; /* nothing to move */
1008 }
1009again: 862again:
1010 mutex_lock(&old_parent->d_inode->i_mutex); 863 mutex_lock(&old_parent->d_inode->i_mutex);
1011 if (!mutex_trylock(&new_parent->d_inode->i_mutex)) { 864 if (!mutex_trylock(&new_parent->d_inode->i_mutex)) {
1012 mutex_unlock(&old_parent->d_inode->i_mutex); 865 mutex_unlock(&old_parent->d_inode->i_mutex);
1013 goto again; 866 goto again;
1014 } 867 }
868 mutex_lock(&sysfs_mutex);
1015 869
1016 new_dentry = lookup_one_len(kobj->name, new_parent, strlen(kobj->name)); 870 error = -EEXIST;
1017 if (IS_ERR(new_dentry)) { 871 if (sysfs_find_dirent(new_parent_sd, sd->s_name))
1018 error = PTR_ERR(new_dentry);
1019 goto out_unlock; 872 goto out_unlock;
1020 } else 873
1021 error = 0; 874 error = -ENOMEM;
875 new_dentry = d_alloc_name(new_parent, sd->s_name);
876 if (!new_dentry)
877 goto out_unlock;
878
879 error = 0;
1022 d_add(new_dentry, NULL); 880 d_add(new_dentry, NULL);
1023 d_move(sd->s_dentry, new_dentry); 881 d_move(old_dentry, new_dentry);
1024 dput(new_dentry); 882 dput(new_dentry);
1025 883
1026 /* Remove from old parent's list and insert into new parent's list. */ 884 /* Remove from old parent's list and insert into new parent's list. */
1027 mutex_lock(&sysfs_mutex);
1028
1029 sysfs_unlink_sibling(sd); 885 sysfs_unlink_sibling(sd);
1030 sysfs_get(new_parent_sd); 886 sysfs_get(new_parent_sd);
1031 sysfs_put(sd->s_parent); 887 sysfs_put(sd->s_parent);
1032 sd->s_parent = new_parent_sd; 888 sd->s_parent = new_parent_sd;
1033 sysfs_link_sibling(sd); 889 sysfs_link_sibling(sd);
1034 890
1035 mutex_unlock(&sysfs_mutex);
1036
1037 out_unlock: 891 out_unlock:
892 mutex_unlock(&sysfs_mutex);
1038 mutex_unlock(&new_parent->d_inode->i_mutex); 893 mutex_unlock(&new_parent->d_inode->i_mutex);
1039 mutex_unlock(&old_parent->d_inode->i_mutex); 894 mutex_unlock(&old_parent->d_inode->i_mutex);
1040 out_dput: 895 out:
1041 dput(new_parent); 896 dput(new_parent);
1042 dput(old_dentry); 897 dput(old_dentry);
1043 dput(new_dentry); 898 dput(new_dentry);
899 mutex_unlock(&sysfs_rename_mutex);
1044 return error; 900 return error;
1045} 901}
1046 902
1047static int sysfs_dir_open(struct inode *inode, struct file *file)
1048{
1049 struct dentry * dentry = file->f_path.dentry;
1050 struct sysfs_dirent * parent_sd = dentry->d_fsdata;
1051 struct sysfs_dirent * sd;
1052
1053 sd = sysfs_new_dirent("_DIR_", 0, 0);
1054 if (sd) {
1055 mutex_lock(&sysfs_mutex);
1056 sd->s_parent = sysfs_get(parent_sd);
1057 sysfs_link_sibling(sd);
1058 mutex_unlock(&sysfs_mutex);
1059 }
1060
1061 file->private_data = sd;
1062 return sd ? 0 : -ENOMEM;
1063}
1064
1065static int sysfs_dir_close(struct inode *inode, struct file *file)
1066{
1067 struct sysfs_dirent * cursor = file->private_data;
1068
1069 mutex_lock(&sysfs_mutex);
1070 sysfs_unlink_sibling(cursor);
1071 mutex_unlock(&sysfs_mutex);
1072
1073 release_sysfs_dirent(cursor);
1074
1075 return 0;
1076}
1077
1078/* Relationship between s_mode and the DT_xxx types */ 903/* Relationship between s_mode and the DT_xxx types */
1079static inline unsigned char dt_type(struct sysfs_dirent *sd) 904static inline unsigned char dt_type(struct sysfs_dirent *sd)
1080{ 905{
@@ -1085,232 +910,51 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
1085{ 910{
1086 struct dentry *dentry = filp->f_path.dentry; 911 struct dentry *dentry = filp->f_path.dentry;
1087 struct sysfs_dirent * parent_sd = dentry->d_fsdata; 912 struct sysfs_dirent * parent_sd = dentry->d_fsdata;
1088 struct sysfs_dirent *cursor = filp->private_data; 913 struct sysfs_dirent *pos;
1089 struct sysfs_dirent **pos;
1090 ino_t ino; 914 ino_t ino;
1091 int i = filp->f_pos;
1092 915
1093 switch (i) { 916 if (filp->f_pos == 0) {
1094 case 0: 917 ino = parent_sd->s_ino;
1095 ino = parent_sd->s_ino; 918 if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) == 0)
1096 if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
1097 break;
1098 filp->f_pos++; 919 filp->f_pos++;
1099 i++; 920 }
1100 /* fallthrough */ 921 if (filp->f_pos == 1) {
1101 case 1: 922 if (parent_sd->s_parent)
1102 if (parent_sd->s_parent) 923 ino = parent_sd->s_parent->s_ino;
1103 ino = parent_sd->s_parent->s_ino; 924 else
1104 else 925 ino = parent_sd->s_ino;
1105 ino = parent_sd->s_ino; 926 if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0)
1106 if (filldir(dirent, "..", 2, i, ino, DT_DIR) < 0)
1107 break;
1108 filp->f_pos++; 927 filp->f_pos++;
1109 i++; 928 }
1110 /* fallthrough */ 929 if ((filp->f_pos > 1) && (filp->f_pos < INT_MAX)) {
1111 default: 930 mutex_lock(&sysfs_mutex);
1112 mutex_lock(&sysfs_mutex);
1113
1114 pos = &parent_sd->s_children;
1115 while (*pos != cursor)
1116 pos = &(*pos)->s_sibling;
1117
1118 /* unlink cursor */
1119 *pos = cursor->s_sibling;
1120
1121 if (filp->f_pos == 2)
1122 pos = &parent_sd->s_children;
1123
1124 for ( ; *pos; pos = &(*pos)->s_sibling) {
1125 struct sysfs_dirent *next = *pos;
1126 const char * name;
1127 int len;
1128
1129 if (!sysfs_type(next))
1130 continue;
1131
1132 name = next->s_name;
1133 len = strlen(name);
1134 ino = next->s_ino;
1135
1136 if (filldir(dirent, name, len, filp->f_pos, ino,
1137 dt_type(next)) < 0)
1138 break;
1139 931
1140 filp->f_pos++; 932 /* Skip the dentries we have already reported */
1141 } 933 pos = parent_sd->s_dir.children;
934 while (pos && (filp->f_pos > pos->s_ino))
935 pos = pos->s_sibling;
1142 936
1143 /* put cursor back in */ 937 for ( ; pos; pos = pos->s_sibling) {
1144 cursor->s_sibling = *pos; 938 const char * name;
1145 *pos = cursor; 939 int len;
1146 940
1147 mutex_unlock(&sysfs_mutex); 941 name = pos->s_name;
1148 } 942 len = strlen(name);
1149 return 0; 943 filp->f_pos = ino = pos->s_ino;
1150}
1151
1152static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
1153{
1154 struct dentry * dentry = file->f_path.dentry;
1155 944
1156 switch (origin) { 945 if (filldir(dirent, name, len, filp->f_pos, ino,
1157 case 1: 946 dt_type(pos)) < 0)
1158 offset += file->f_pos;
1159 case 0:
1160 if (offset >= 0)
1161 break; 947 break;
1162 default:
1163 return -EINVAL;
1164 }
1165 if (offset != file->f_pos) {
1166 mutex_lock(&sysfs_mutex);
1167
1168 file->f_pos = offset;
1169 if (file->f_pos >= 2) {
1170 struct sysfs_dirent *sd = dentry->d_fsdata;
1171 struct sysfs_dirent *cursor = file->private_data;
1172 struct sysfs_dirent **pos;
1173 loff_t n = file->f_pos - 2;
1174
1175 sysfs_unlink_sibling(cursor);
1176
1177 pos = &sd->s_children;
1178 while (n && *pos) {
1179 struct sysfs_dirent *next = *pos;
1180 if (sysfs_type(next))
1181 n--;
1182 pos = &(*pos)->s_sibling;
1183 }
1184
1185 cursor->s_sibling = *pos;
1186 *pos = cursor;
1187 } 948 }
1188 949 if (!pos)
950 filp->f_pos = INT_MAX;
1189 mutex_unlock(&sysfs_mutex); 951 mutex_unlock(&sysfs_mutex);
1190 } 952 }
1191
1192 return offset;
1193}
1194
1195
1196/**
1197 * sysfs_make_shadowed_dir - Setup so a directory can be shadowed
1198 * @kobj: object we're creating shadow of.
1199 */
1200
1201int sysfs_make_shadowed_dir(struct kobject *kobj,
1202 void * (*follow_link)(struct dentry *, struct nameidata *))
1203{
1204 struct dentry *dentry;
1205 struct inode *inode;
1206 struct inode_operations *i_op;
1207
1208 /* get dentry for @kobj->sd, dentry of a shadowed dir is pinned */
1209 dentry = sysfs_get_dentry(kobj->sd);
1210 if (IS_ERR(dentry))
1211 return PTR_ERR(dentry);
1212
1213 inode = dentry->d_inode;
1214 if (inode->i_op != &sysfs_dir_inode_operations) {
1215 dput(dentry);
1216 return -EINVAL;
1217 }
1218
1219 i_op = kmalloc(sizeof(*i_op), GFP_KERNEL);
1220 if (!i_op)
1221 return -ENOMEM;
1222
1223 memcpy(i_op, &sysfs_dir_inode_operations, sizeof(*i_op));
1224 i_op->follow_link = follow_link;
1225
1226 /* Locking of inode->i_op?
1227 * Since setting i_op is a single word write and they
1228 * are atomic we should be ok here.
1229 */
1230 inode->i_op = i_op;
1231 return 0; 953 return 0;
1232} 954}
1233 955
1234/**
1235 * sysfs_create_shadow_dir - create a shadow directory for an object.
1236 * @kobj: object we're creating directory for.
1237 *
1238 * sysfs_make_shadowed_dir must already have been called on this
1239 * directory.
1240 */
1241
1242struct sysfs_dirent *sysfs_create_shadow_dir(struct kobject *kobj)
1243{
1244 struct sysfs_dirent *parent_sd = kobj->sd->s_parent;
1245 struct dentry *dir, *parent, *shadow;
1246 struct inode *inode;
1247 struct sysfs_dirent *sd;
1248 struct sysfs_addrm_cxt acxt;
1249
1250 dir = sysfs_get_dentry(kobj->sd);
1251 if (IS_ERR(dir)) {
1252 sd = (void *)dir;
1253 goto out;
1254 }
1255 parent = dir->d_parent;
1256
1257 inode = dir->d_inode;
1258 sd = ERR_PTR(-EINVAL);
1259 if (!sysfs_is_shadowed_inode(inode))
1260 goto out_dput;
1261
1262 shadow = d_alloc(parent, &dir->d_name);
1263 if (!shadow)
1264 goto nomem;
1265
1266 sd = sysfs_new_dirent("_SHADOW_", inode->i_mode, SYSFS_DIR);
1267 if (!sd)
1268 goto nomem;
1269 sd->s_elem.dir.kobj = kobj;
1270
1271 sysfs_addrm_start(&acxt, parent_sd);
1272
1273 /* add but don't link into children list */
1274 sysfs_add_one(&acxt, sd);
1275
1276 /* attach and instantiate dentry */
1277 sysfs_attach_dentry(sd, shadow);
1278 d_instantiate(shadow, igrab(inode));
1279 inc_nlink(inode); /* tj: synchronization? */
1280
1281 sysfs_addrm_finish(&acxt);
1282
1283 dget(shadow); /* Extra count - pin the dentry in core */
1284
1285 goto out_dput;
1286
1287 nomem:
1288 dput(shadow);
1289 sd = ERR_PTR(-ENOMEM);
1290 out_dput:
1291 dput(dir);
1292 out:
1293 return sd;
1294}
1295
1296/**
1297 * sysfs_remove_shadow_dir - remove an object's directory.
1298 * @shadow_sd: sysfs_dirent of shadow directory
1299 *
1300 * The only thing special about this is that we remove any files in
1301 * the directory before we remove the directory, and we've inlined
1302 * what used to be sysfs_rmdir() below, instead of calling separately.
1303 */
1304
1305void sysfs_remove_shadow_dir(struct sysfs_dirent *shadow_sd)
1306{
1307 __sysfs_remove_dir(shadow_sd);
1308}
1309 956
1310const struct file_operations sysfs_dir_operations = { 957const struct file_operations sysfs_dir_operations = {
1311 .open = sysfs_dir_open,
1312 .release = sysfs_dir_close,
1313 .llseek = sysfs_dir_lseek,
1314 .read = generic_read_dir, 958 .read = generic_read_dir,
1315 .readdir = sysfs_readdir, 959 .readdir = sysfs_readdir,
1316}; 960};
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 3e1cc062a740..d3be1e7fb48b 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -1,15 +1,22 @@
1/* 1/*
2 * file.c - operations for regular (text) files. 2 * fs/sysfs/file.c - sysfs regular (text) file implementation
3 *
4 * Copyright (c) 2001-3 Patrick Mochel
5 * Copyright (c) 2007 SUSE Linux Products GmbH
6 * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
7 *
8 * This file is released under the GPLv2.
9 *
10 * Please see Documentation/filesystems/sysfs.txt for more information.
3 */ 11 */
4 12
5#include <linux/module.h> 13#include <linux/module.h>
6#include <linux/fsnotify.h>
7#include <linux/kobject.h> 14#include <linux/kobject.h>
8#include <linux/namei.h> 15#include <linux/namei.h>
9#include <linux/poll.h> 16#include <linux/poll.h>
10#include <linux/list.h> 17#include <linux/list.h>
18#include <linux/mutex.h>
11#include <asm/uaccess.h> 19#include <asm/uaccess.h>
12#include <asm/semaphore.h>
13 20
14#include "sysfs.h" 21#include "sysfs.h"
15 22
@@ -50,14 +57,33 @@ static struct sysfs_ops subsys_sysfs_ops = {
50 .store = subsys_attr_store, 57 .store = subsys_attr_store,
51}; 58};
52 59
60/*
61 * There's one sysfs_buffer for each open file and one
62 * sysfs_open_dirent for each sysfs_dirent with one or more open
63 * files.
64 *
65 * filp->private_data points to sysfs_buffer and
66 * sysfs_dirent->s_attr.open points to sysfs_open_dirent. s_attr.open
67 * is protected by sysfs_open_dirent_lock.
68 */
69static spinlock_t sysfs_open_dirent_lock = SPIN_LOCK_UNLOCKED;
70
71struct sysfs_open_dirent {
72 atomic_t refcnt;
73 atomic_t event;
74 wait_queue_head_t poll;
75 struct list_head buffers; /* goes through sysfs_buffer.list */
76};
77
53struct sysfs_buffer { 78struct sysfs_buffer {
54 size_t count; 79 size_t count;
55 loff_t pos; 80 loff_t pos;
56 char * page; 81 char * page;
57 struct sysfs_ops * ops; 82 struct sysfs_ops * ops;
58 struct semaphore sem; 83 struct mutex mutex;
59 int needs_read_fill; 84 int needs_read_fill;
60 int event; 85 int event;
86 struct list_head list;
61}; 87};
62 88
63/** 89/**
@@ -74,7 +100,7 @@ struct sysfs_buffer {
74static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer) 100static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer)
75{ 101{
76 struct sysfs_dirent *attr_sd = dentry->d_fsdata; 102 struct sysfs_dirent *attr_sd = dentry->d_fsdata;
77 struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj; 103 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
78 struct sysfs_ops * ops = buffer->ops; 104 struct sysfs_ops * ops = buffer->ops;
79 int ret = 0; 105 int ret = 0;
80 ssize_t count; 106 ssize_t count;
@@ -88,8 +114,8 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
88 if (!sysfs_get_active_two(attr_sd)) 114 if (!sysfs_get_active_two(attr_sd))
89 return -ENODEV; 115 return -ENODEV;
90 116
91 buffer->event = atomic_read(&attr_sd->s_event); 117 buffer->event = atomic_read(&attr_sd->s_attr.open->event);
92 count = ops->show(kobj, attr_sd->s_elem.attr.attr, buffer->page); 118 count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page);
93 119
94 sysfs_put_active_two(attr_sd); 120 sysfs_put_active_two(attr_sd);
95 121
@@ -128,7 +154,7 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
128 struct sysfs_buffer * buffer = file->private_data; 154 struct sysfs_buffer * buffer = file->private_data;
129 ssize_t retval = 0; 155 ssize_t retval = 0;
130 156
131 down(&buffer->sem); 157 mutex_lock(&buffer->mutex);
132 if (buffer->needs_read_fill) { 158 if (buffer->needs_read_fill) {
133 retval = fill_read_buffer(file->f_path.dentry,buffer); 159 retval = fill_read_buffer(file->f_path.dentry,buffer);
134 if (retval) 160 if (retval)
@@ -139,7 +165,7 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
139 retval = simple_read_from_buffer(buf, count, ppos, buffer->page, 165 retval = simple_read_from_buffer(buf, count, ppos, buffer->page,
140 buffer->count); 166 buffer->count);
141out: 167out:
142 up(&buffer->sem); 168 mutex_unlock(&buffer->mutex);
143 return retval; 169 return retval;
144} 170}
145 171
@@ -189,7 +215,7 @@ static int
189flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t count) 215flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t count)
190{ 216{
191 struct sysfs_dirent *attr_sd = dentry->d_fsdata; 217 struct sysfs_dirent *attr_sd = dentry->d_fsdata;
192 struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj; 218 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
193 struct sysfs_ops * ops = buffer->ops; 219 struct sysfs_ops * ops = buffer->ops;
194 int rc; 220 int rc;
195 221
@@ -197,7 +223,7 @@ flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t
197 if (!sysfs_get_active_two(attr_sd)) 223 if (!sysfs_get_active_two(attr_sd))
198 return -ENODEV; 224 return -ENODEV;
199 225
200 rc = ops->store(kobj, attr_sd->s_elem.attr.attr, buffer->page, count); 226 rc = ops->store(kobj, attr_sd->s_attr.attr, buffer->page, count);
201 227
202 sysfs_put_active_two(attr_sd); 228 sysfs_put_active_two(attr_sd);
203 229
@@ -228,20 +254,102 @@ sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t
228 struct sysfs_buffer * buffer = file->private_data; 254 struct sysfs_buffer * buffer = file->private_data;
229 ssize_t len; 255 ssize_t len;
230 256
231 down(&buffer->sem); 257 mutex_lock(&buffer->mutex);
232 len = fill_write_buffer(buffer, buf, count); 258 len = fill_write_buffer(buffer, buf, count);
233 if (len > 0) 259 if (len > 0)
234 len = flush_write_buffer(file->f_path.dentry, buffer, len); 260 len = flush_write_buffer(file->f_path.dentry, buffer, len);
235 if (len > 0) 261 if (len > 0)
236 *ppos += len; 262 *ppos += len;
237 up(&buffer->sem); 263 mutex_unlock(&buffer->mutex);
238 return len; 264 return len;
239} 265}
240 266
267/**
268 * sysfs_get_open_dirent - get or create sysfs_open_dirent
269 * @sd: target sysfs_dirent
270 * @buffer: sysfs_buffer for this instance of open
271 *
272 * If @sd->s_attr.open exists, increment its reference count;
273 * otherwise, create one. @buffer is chained to the buffers
274 * list.
275 *
276 * LOCKING:
277 * Kernel thread context (may sleep).
278 *
279 * RETURNS:
280 * 0 on success, -errno on failure.
281 */
282static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
283 struct sysfs_buffer *buffer)
284{
285 struct sysfs_open_dirent *od, *new_od = NULL;
286
287 retry:
288 spin_lock(&sysfs_open_dirent_lock);
289
290 if (!sd->s_attr.open && new_od) {
291 sd->s_attr.open = new_od;
292 new_od = NULL;
293 }
294
295 od = sd->s_attr.open;
296 if (od) {
297 atomic_inc(&od->refcnt);
298 list_add_tail(&buffer->list, &od->buffers);
299 }
300
301 spin_unlock(&sysfs_open_dirent_lock);
302
303 if (od) {
304 kfree(new_od);
305 return 0;
306 }
307
308 /* not there, initialize a new one and retry */
309 new_od = kmalloc(sizeof(*new_od), GFP_KERNEL);
310 if (!new_od)
311 return -ENOMEM;
312
313 atomic_set(&new_od->refcnt, 0);
314 atomic_set(&new_od->event, 1);
315 init_waitqueue_head(&new_od->poll);
316 INIT_LIST_HEAD(&new_od->buffers);
317 goto retry;
318}
319
320/**
321 * sysfs_put_open_dirent - put sysfs_open_dirent
322 * @sd: target sysfs_dirent
323 * @buffer: associated sysfs_buffer
324 *
325 * Put @sd->s_attr.open and unlink @buffer from the buffers list.
326 * If reference count reaches zero, disassociate and free it.
327 *
328 * LOCKING:
329 * None.
330 */
331static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
332 struct sysfs_buffer *buffer)
333{
334 struct sysfs_open_dirent *od = sd->s_attr.open;
335
336 spin_lock(&sysfs_open_dirent_lock);
337
338 list_del(&buffer->list);
339 if (atomic_dec_and_test(&od->refcnt))
340 sd->s_attr.open = NULL;
341 else
342 od = NULL;
343
344 spin_unlock(&sysfs_open_dirent_lock);
345
346 kfree(od);
347}
348
241static int sysfs_open_file(struct inode *inode, struct file *file) 349static int sysfs_open_file(struct inode *inode, struct file *file)
242{ 350{
243 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; 351 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
244 struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj; 352 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
245 struct sysfs_buffer * buffer; 353 struct sysfs_buffer * buffer;
246 struct sysfs_ops * ops = NULL; 354 struct sysfs_ops * ops = NULL;
247 int error; 355 int error;
@@ -294,33 +402,38 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
294 if (!buffer) 402 if (!buffer)
295 goto err_out; 403 goto err_out;
296 404
297 init_MUTEX(&buffer->sem); 405 mutex_init(&buffer->mutex);
298 buffer->needs_read_fill = 1; 406 buffer->needs_read_fill = 1;
299 buffer->ops = ops; 407 buffer->ops = ops;
300 file->private_data = buffer; 408 file->private_data = buffer;
301 409
302 /* open succeeded, put active references and pin attr_sd */ 410 /* make sure we have open dirent struct */
411 error = sysfs_get_open_dirent(attr_sd, buffer);
412 if (error)
413 goto err_free;
414
415 /* open succeeded, put active references */
303 sysfs_put_active_two(attr_sd); 416 sysfs_put_active_two(attr_sd);
304 sysfs_get(attr_sd);
305 return 0; 417 return 0;
306 418
419 err_free:
420 kfree(buffer);
307 err_out: 421 err_out:
308 sysfs_put_active_two(attr_sd); 422 sysfs_put_active_two(attr_sd);
309 return error; 423 return error;
310} 424}
311 425
312static int sysfs_release(struct inode * inode, struct file * filp) 426static int sysfs_release(struct inode *inode, struct file *filp)
313{ 427{
314 struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata; 428 struct sysfs_dirent *sd = filp->f_path.dentry->d_fsdata;
315 struct sysfs_buffer *buffer = filp->private_data; 429 struct sysfs_buffer *buffer = filp->private_data;
316 430
317 sysfs_put(attr_sd); 431 sysfs_put_open_dirent(sd, buffer);
432
433 if (buffer->page)
434 free_page((unsigned long)buffer->page);
435 kfree(buffer);
318 436
319 if (buffer) {
320 if (buffer->page)
321 free_page((unsigned long)buffer->page);
322 kfree(buffer);
323 }
324 return 0; 437 return 0;
325} 438}
326 439
@@ -335,24 +448,24 @@ static int sysfs_release(struct inode * inode, struct file * filp)
335 * again will not get new data, or reset the state of 'poll'. 448 * again will not get new data, or reset the state of 'poll'.
336 * Reminder: this only works for attributes which actively support 449 * Reminder: this only works for attributes which actively support
337 * it, and it is not possible to test an attribute from userspace 450 * it, and it is not possible to test an attribute from userspace
338 * to see if it supports poll (Nether 'poll' or 'select' return 451 * to see if it supports poll (Neither 'poll' nor 'select' return
339 * an appropriate error code). When in doubt, set a suitable timeout value. 452 * an appropriate error code). When in doubt, set a suitable timeout value.
340 */ 453 */
341static unsigned int sysfs_poll(struct file *filp, poll_table *wait) 454static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
342{ 455{
343 struct sysfs_buffer * buffer = filp->private_data; 456 struct sysfs_buffer * buffer = filp->private_data;
344 struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata; 457 struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
345 struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj; 458 struct sysfs_open_dirent *od = attr_sd->s_attr.open;
346 459
347 /* need parent for the kobj, grab both */ 460 /* need parent for the kobj, grab both */
348 if (!sysfs_get_active_two(attr_sd)) 461 if (!sysfs_get_active_two(attr_sd))
349 goto trigger; 462 goto trigger;
350 463
351 poll_wait(filp, &kobj->poll, wait); 464 poll_wait(filp, &od->poll, wait);
352 465
353 sysfs_put_active_two(attr_sd); 466 sysfs_put_active_two(attr_sd);
354 467
355 if (buffer->event != atomic_read(&attr_sd->s_event)) 468 if (buffer->event != atomic_read(&od->event))
356 goto trigger; 469 goto trigger;
357 470
358 return 0; 471 return 0;
@@ -373,8 +486,17 @@ void sysfs_notify(struct kobject *k, char *dir, char *attr)
373 if (sd && attr) 486 if (sd && attr)
374 sd = sysfs_find_dirent(sd, attr); 487 sd = sysfs_find_dirent(sd, attr);
375 if (sd) { 488 if (sd) {
376 atomic_inc(&sd->s_event); 489 struct sysfs_open_dirent *od;
377 wake_up_interruptible(&k->poll); 490
491 spin_lock(&sysfs_open_dirent_lock);
492
493 od = sd->s_attr.open;
494 if (od) {
495 atomic_inc(&od->event);
496 wake_up_interruptible(&od->poll);
497 }
498
499 spin_unlock(&sysfs_open_dirent_lock);
378 } 500 }
379 501
380 mutex_unlock(&sysfs_mutex); 502 mutex_unlock(&sysfs_mutex);
@@ -397,25 +519,21 @@ int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
397 umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG; 519 umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG;
398 struct sysfs_addrm_cxt acxt; 520 struct sysfs_addrm_cxt acxt;
399 struct sysfs_dirent *sd; 521 struct sysfs_dirent *sd;
522 int rc;
400 523
401 sd = sysfs_new_dirent(attr->name, mode, type); 524 sd = sysfs_new_dirent(attr->name, mode, type);
402 if (!sd) 525 if (!sd)
403 return -ENOMEM; 526 return -ENOMEM;
404 sd->s_elem.attr.attr = (void *)attr; 527 sd->s_attr.attr = (void *)attr;
405 528
406 sysfs_addrm_start(&acxt, dir_sd); 529 sysfs_addrm_start(&acxt, dir_sd);
530 rc = sysfs_add_one(&acxt, sd);
531 sysfs_addrm_finish(&acxt);
407 532
408 if (!sysfs_find_dirent(dir_sd, attr->name)) { 533 if (rc)
409 sysfs_add_one(&acxt, sd);
410 sysfs_link_sibling(sd);
411 }
412
413 if (!sysfs_addrm_finish(&acxt)) {
414 sysfs_put(sd); 534 sysfs_put(sd);
415 return -EEXIST;
416 }
417 535
418 return 0; 536 return rc;
419} 537}
420 538
421 539
@@ -457,42 +575,6 @@ int sysfs_add_file_to_group(struct kobject *kobj,
457} 575}
458EXPORT_SYMBOL_GPL(sysfs_add_file_to_group); 576EXPORT_SYMBOL_GPL(sysfs_add_file_to_group);
459 577
460
461/**
462 * sysfs_update_file - update the modified timestamp on an object attribute.
463 * @kobj: object we're acting for.
464 * @attr: attribute descriptor.
465 */
466int sysfs_update_file(struct kobject * kobj, const struct attribute * attr)
467{
468 struct sysfs_dirent *victim_sd = NULL;
469 struct dentry *victim = NULL;
470 int rc;
471
472 rc = -ENOENT;
473 victim_sd = sysfs_get_dirent(kobj->sd, attr->name);
474 if (!victim_sd)
475 goto out;
476
477 victim = sysfs_get_dentry(victim_sd);
478 if (IS_ERR(victim)) {
479 rc = PTR_ERR(victim);
480 victim = NULL;
481 goto out;
482 }
483
484 mutex_lock(&victim->d_inode->i_mutex);
485 victim->d_inode->i_mtime = CURRENT_TIME;
486 fsnotify_modify(victim);
487 mutex_unlock(&victim->d_inode->i_mutex);
488 rc = 0;
489 out:
490 dput(victim);
491 sysfs_put(victim_sd);
492 return rc;
493}
494
495
496/** 578/**
497 * sysfs_chmod_file - update the modified mode value on an object attribute. 579 * sysfs_chmod_file - update the modified mode value on an object attribute.
498 * @kobj: object we're acting for. 580 * @kobj: object we're acting for.
@@ -513,7 +595,9 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
513 if (!victim_sd) 595 if (!victim_sd)
514 goto out; 596 goto out;
515 597
598 mutex_lock(&sysfs_rename_mutex);
516 victim = sysfs_get_dentry(victim_sd); 599 victim = sysfs_get_dentry(victim_sd);
600 mutex_unlock(&sysfs_rename_mutex);
517 if (IS_ERR(victim)) { 601 if (IS_ERR(victim)) {
518 rc = PTR_ERR(victim); 602 rc = PTR_ERR(victim);
519 victim = NULL; 603 victim = NULL;
@@ -521,10 +605,19 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
521 } 605 }
522 606
523 inode = victim->d_inode; 607 inode = victim->d_inode;
608
524 mutex_lock(&inode->i_mutex); 609 mutex_lock(&inode->i_mutex);
610
525 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); 611 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
526 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; 612 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
527 rc = notify_change(victim, &newattrs); 613 rc = notify_change(victim, &newattrs);
614
615 if (rc == 0) {
616 mutex_lock(&sysfs_mutex);
617 victim_sd->s_mode = newattrs.ia_mode;
618 mutex_unlock(&sysfs_mutex);
619 }
620
528 mutex_unlock(&inode->i_mutex); 621 mutex_unlock(&inode->i_mutex);
529 out: 622 out:
530 dput(victim); 623 dput(victim);
@@ -632,4 +725,3 @@ EXPORT_SYMBOL_GPL(sysfs_schedule_callback);
632 725
633EXPORT_SYMBOL_GPL(sysfs_create_file); 726EXPORT_SYMBOL_GPL(sysfs_create_file);
634EXPORT_SYMBOL_GPL(sysfs_remove_file); 727EXPORT_SYMBOL_GPL(sysfs_remove_file);
635EXPORT_SYMBOL_GPL(sysfs_update_file);
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index f318b73c790c..d1972374655a 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -13,8 +13,6 @@
13#include <linux/dcache.h> 13#include <linux/dcache.h>
14#include <linux/namei.h> 14#include <linux/namei.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/fs.h>
17#include <asm/semaphore.h>
18#include "sysfs.h" 16#include "sysfs.h"
19 17
20 18
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 10d1b52899f1..9236635111f4 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -1,7 +1,11 @@
1/* 1/*
2 * inode.c - basic inode and dentry operations. 2 * fs/sysfs/inode.c - basic sysfs inode and dentry operations
3 * 3 *
4 * sysfs is Copyright (c) 2001-3 Patrick Mochel 4 * Copyright (c) 2001-3 Patrick Mochel
5 * Copyright (c) 2007 SUSE Linux Products GmbH
6 * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
7 *
8 * This file is released under the GPLv2.
5 * 9 *
6 * Please see Documentation/filesystems/sysfs.txt for more information. 10 * Please see Documentation/filesystems/sysfs.txt for more information.
7 */ 11 */
@@ -14,7 +18,6 @@
14#include <linux/capability.h> 18#include <linux/capability.h>
15#include <linux/errno.h> 19#include <linux/errno.h>
16#include <linux/sched.h> 20#include <linux/sched.h>
17#include <asm/semaphore.h>
18#include "sysfs.h" 21#include "sysfs.h"
19 22
20extern struct super_block * sysfs_sb; 23extern struct super_block * sysfs_sb;
@@ -34,16 +37,6 @@ static const struct inode_operations sysfs_inode_operations ={
34 .setattr = sysfs_setattr, 37 .setattr = sysfs_setattr,
35}; 38};
36 39
37void sysfs_delete_inode(struct inode *inode)
38{
39 /* Free the shadowed directory inode operations */
40 if (sysfs_is_shadowed_inode(inode)) {
41 kfree(inode->i_op);
42 inode->i_op = NULL;
43 }
44 return generic_delete_inode(inode);
45}
46
47int sysfs_setattr(struct dentry * dentry, struct iattr * iattr) 40int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
48{ 41{
49 struct inode * inode = dentry->d_inode; 42 struct inode * inode = dentry->d_inode;
@@ -133,8 +126,22 @@ static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
133 */ 126 */
134static struct lock_class_key sysfs_inode_imutex_key; 127static struct lock_class_key sysfs_inode_imutex_key;
135 128
129static int sysfs_count_nlink(struct sysfs_dirent *sd)
130{
131 struct sysfs_dirent *child;
132 int nr = 0;
133
134 for (child = sd->s_dir.children; child; child = child->s_sibling)
135 if (sysfs_type(child) == SYSFS_DIR)
136 nr++;
137
138 return nr + 2;
139}
140
136static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) 141static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
137{ 142{
143 struct bin_attribute *bin_attr;
144
138 inode->i_blocks = 0; 145 inode->i_blocks = 0;
139 inode->i_mapping->a_ops = &sysfs_aops; 146 inode->i_mapping->a_ops = &sysfs_aops;
140 inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; 147 inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
@@ -150,6 +157,32 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode)
150 set_inode_attr(inode, sd->s_iattr); 157 set_inode_attr(inode, sd->s_iattr);
151 } else 158 } else
152 set_default_inode_attr(inode, sd->s_mode); 159 set_default_inode_attr(inode, sd->s_mode);
160
161
162 /* initialize inode according to type */
163 switch (sysfs_type(sd)) {
164 case SYSFS_DIR:
165 inode->i_op = &sysfs_dir_inode_operations;
166 inode->i_fop = &sysfs_dir_operations;
167 inode->i_nlink = sysfs_count_nlink(sd);
168 break;
169 case SYSFS_KOBJ_ATTR:
170 inode->i_size = PAGE_SIZE;
171 inode->i_fop = &sysfs_file_operations;
172 break;
173 case SYSFS_KOBJ_BIN_ATTR:
174 bin_attr = sd->s_bin_attr.bin_attr;
175 inode->i_size = bin_attr->size;
176 inode->i_fop = &bin_fops;
177 break;
178 case SYSFS_KOBJ_LINK:
179 inode->i_op = &sysfs_symlink_inode_operations;
180 break;
181 default:
182 BUG();
183 }
184
185 unlock_new_inode(inode);
153} 186}
154 187
155/** 188/**
@@ -177,50 +210,24 @@ struct inode * sysfs_get_inode(struct sysfs_dirent *sd)
177 return inode; 210 return inode;
178} 211}
179 212
180/**
181 * sysfs_instantiate - instantiate dentry
182 * @dentry: dentry to be instantiated
183 * @inode: inode associated with @sd
184 *
185 * Unlock @inode if locked and instantiate @dentry with @inode.
186 *
187 * LOCKING:
188 * None.
189 */
190void sysfs_instantiate(struct dentry *dentry, struct inode *inode)
191{
192 BUG_ON(!dentry || dentry->d_inode);
193
194 if (inode->i_state & I_NEW)
195 unlock_new_inode(inode);
196
197 d_instantiate(dentry, inode);
198}
199
200int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name) 213int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name)
201{ 214{
202 struct sysfs_addrm_cxt acxt; 215 struct sysfs_addrm_cxt acxt;
203 struct sysfs_dirent **pos, *sd; 216 struct sysfs_dirent *sd;
204 217
205 if (!dir_sd) 218 if (!dir_sd)
206 return -ENOENT; 219 return -ENOENT;
207 220
208 sysfs_addrm_start(&acxt, dir_sd); 221 sysfs_addrm_start(&acxt, dir_sd);
209 222
210 for (pos = &dir_sd->s_children; *pos; pos = &(*pos)->s_sibling) { 223 sd = sysfs_find_dirent(dir_sd, name);
211 sd = *pos; 224 if (sd)
212 225 sysfs_remove_one(&acxt, sd);
213 if (!sysfs_type(sd)) 226
214 continue; 227 sysfs_addrm_finish(&acxt);
215 if (!strcmp(sd->s_name, name)) {
216 *pos = sd->s_sibling;
217 sd->s_sibling = NULL;
218 sysfs_remove_one(&acxt, sd);
219 break;
220 }
221 }
222 228
223 if (sysfs_addrm_finish(&acxt)) 229 if (sd)
224 return 0; 230 return 0;
225 return -ENOENT; 231 else
232 return -ENOENT;
226} 233}
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index fbc7b65fe262..c76c540be3c8 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -1,5 +1,13 @@
1/* 1/*
2 * mount.c - operations for initializing and mounting sysfs. 2 * fs/sysfs/symlink.c - operations for initializing and mounting sysfs
3 *
4 * Copyright (c) 2001-3 Patrick Mochel
5 * Copyright (c) 2007 SUSE Linux Products GmbH
6 * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
7 *
8 * This file is released under the GPLv2.
9 *
10 * Please see Documentation/filesystems/sysfs.txt for more information.
3 */ 11 */
4 12
5#define DEBUG 13#define DEBUG
@@ -8,25 +16,25 @@
8#include <linux/mount.h> 16#include <linux/mount.h>
9#include <linux/pagemap.h> 17#include <linux/pagemap.h>
10#include <linux/init.h> 18#include <linux/init.h>
11#include <asm/semaphore.h>
12 19
13#include "sysfs.h" 20#include "sysfs.h"
14 21
15/* Random magic number */ 22/* Random magic number */
16#define SYSFS_MAGIC 0x62656572 23#define SYSFS_MAGIC 0x62656572
17 24
18struct vfsmount *sysfs_mount; 25static struct vfsmount *sysfs_mount;
19struct super_block * sysfs_sb = NULL; 26struct super_block * sysfs_sb = NULL;
20struct kmem_cache *sysfs_dir_cachep; 27struct kmem_cache *sysfs_dir_cachep;
21 28
22static const struct super_operations sysfs_ops = { 29static const struct super_operations sysfs_ops = {
23 .statfs = simple_statfs, 30 .statfs = simple_statfs,
24 .drop_inode = sysfs_delete_inode, 31 .drop_inode = generic_delete_inode,
25}; 32};
26 33
27struct sysfs_dirent sysfs_root = { 34struct sysfs_dirent sysfs_root = {
35 .s_name = "",
28 .s_count = ATOMIC_INIT(1), 36 .s_count = ATOMIC_INIT(1),
29 .s_flags = SYSFS_ROOT, 37 .s_flags = SYSFS_DIR,
30 .s_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, 38 .s_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,
31 .s_ino = 1, 39 .s_ino = 1,
32}; 40};
@@ -50,11 +58,6 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
50 return -ENOMEM; 58 return -ENOMEM;
51 } 59 }
52 60
53 inode->i_op = &sysfs_dir_inode_operations;
54 inode->i_fop = &sysfs_dir_operations;
55 inc_nlink(inode); /* directory, account for "." */
56 unlock_new_inode(inode);
57
58 /* instantiate and link root dentry */ 61 /* instantiate and link root dentry */
59 root = d_alloc_root(inode); 62 root = d_alloc_root(inode);
60 if (!root) { 63 if (!root) {
@@ -62,7 +65,6 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
62 iput(inode); 65 iput(inode);
63 return -ENOMEM; 66 return -ENOMEM;
64 } 67 }
65 sysfs_root.s_dentry = root;
66 root->d_fsdata = &sysfs_root; 68 root->d_fsdata = &sysfs_root;
67 sb->s_root = root; 69 sb->s_root = root;
68 return 0; 70 return 0;
@@ -77,7 +79,7 @@ static int sysfs_get_sb(struct file_system_type *fs_type,
77static struct file_system_type sysfs_fs_type = { 79static struct file_system_type sysfs_fs_type = {
78 .name = "sysfs", 80 .name = "sysfs",
79 .get_sb = sysfs_get_sb, 81 .get_sb = sysfs_get_sb,
80 .kill_sb = kill_litter_super, 82 .kill_sb = kill_anon_super,
81}; 83};
82 84
83int __init sysfs_init(void) 85int __init sysfs_init(void)
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index 4ce687f0b5d0..3eac20c63c41 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -1,5 +1,13 @@
1/* 1/*
2 * symlink.c - operations for sysfs symlinks. 2 * fs/sysfs/symlink.c - sysfs symlink implementation
3 *
4 * Copyright (c) 2001-3 Patrick Mochel
5 * Copyright (c) 2007 SUSE Linux Products GmbH
6 * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
7 *
8 * This file is released under the GPLv2.
9 *
10 * Please see Documentation/filesystems/sysfs.txt for more information.
3 */ 11 */
4 12
5#include <linux/fs.h> 13#include <linux/fs.h>
@@ -7,7 +15,7 @@
7#include <linux/module.h> 15#include <linux/module.h>
8#include <linux/kobject.h> 16#include <linux/kobject.h>
9#include <linux/namei.h> 17#include <linux/namei.h>
10#include <asm/semaphore.h> 18#include <linux/mutex.h>
11 19
12#include "sysfs.h" 20#include "sysfs.h"
13 21
@@ -60,10 +68,9 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
60 68
61 BUG_ON(!name); 69 BUG_ON(!name);
62 70
63 if (!kobj) { 71 if (!kobj)
64 if (sysfs_mount && sysfs_mount->mnt_sb) 72 parent_sd = &sysfs_root;
65 parent_sd = sysfs_mount->mnt_sb->s_root->d_fsdata; 73 else
66 } else
67 parent_sd = kobj->sd; 74 parent_sd = kobj->sd;
68 75
69 error = -EFAULT; 76 error = -EFAULT;
@@ -87,20 +94,15 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
87 if (!sd) 94 if (!sd)
88 goto out_put; 95 goto out_put;
89 96
90 sd->s_elem.symlink.target_sd = target_sd; 97 sd->s_symlink.target_sd = target_sd;
91 target_sd = NULL; /* reference is now owned by the symlink */ 98 target_sd = NULL; /* reference is now owned by the symlink */
92 99
93 sysfs_addrm_start(&acxt, parent_sd); 100 sysfs_addrm_start(&acxt, parent_sd);
101 error = sysfs_add_one(&acxt, sd);
102 sysfs_addrm_finish(&acxt);
94 103
95 if (!sysfs_find_dirent(parent_sd, name)) { 104 if (error)
96 sysfs_add_one(&acxt, sd);
97 sysfs_link_sibling(sd);
98 }
99
100 if (!sysfs_addrm_finish(&acxt)) {
101 error = -EEXIST;
102 goto out_put; 105 goto out_put;
103 }
104 106
105 return 0; 107 return 0;
106 108
@@ -148,7 +150,7 @@ static int sysfs_getlink(struct dentry *dentry, char * path)
148{ 150{
149 struct sysfs_dirent *sd = dentry->d_fsdata; 151 struct sysfs_dirent *sd = dentry->d_fsdata;
150 struct sysfs_dirent *parent_sd = sd->s_parent; 152 struct sysfs_dirent *parent_sd = sd->s_parent;
151 struct sysfs_dirent *target_sd = sd->s_elem.symlink.target_sd; 153 struct sysfs_dirent *target_sd = sd->s_symlink.target_sd;
152 int error; 154 int error;
153 155
154 mutex_lock(&sysfs_mutex); 156 mutex_lock(&sysfs_mutex);
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 6b8c8d76d308..f0326f281d1c 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -1,20 +1,39 @@
1/*
2 * fs/sysfs/sysfs.h - sysfs internal header file
3 *
4 * Copyright (c) 2001-3 Patrick Mochel
5 * Copyright (c) 2007 SUSE Linux Products GmbH
6 * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
7 *
8 * This file is released under the GPLv2.
9 */
10
11struct sysfs_open_dirent;
12
13/* type-specific structures for sysfs_dirent->s_* union members */
1struct sysfs_elem_dir { 14struct sysfs_elem_dir {
2 struct kobject * kobj; 15 struct kobject *kobj;
16 /* children list starts here and goes through sd->s_sibling */
17 struct sysfs_dirent *children;
3}; 18};
4 19
5struct sysfs_elem_symlink { 20struct sysfs_elem_symlink {
6 struct sysfs_dirent * target_sd; 21 struct sysfs_dirent *target_sd;
7}; 22};
8 23
9struct sysfs_elem_attr { 24struct sysfs_elem_attr {
10 struct attribute * attr; 25 struct attribute *attr;
26 struct sysfs_open_dirent *open;
11}; 27};
12 28
13struct sysfs_elem_bin_attr { 29struct sysfs_elem_bin_attr {
14 struct bin_attribute * bin_attr; 30 struct bin_attribute *bin_attr;
15}; 31};
16 32
17/* 33/*
34 * sysfs_dirent - the building block of sysfs hierarchy. Each and
35 * every sysfs node is represented by single sysfs_dirent.
36 *
18 * As long as s_count reference is held, the sysfs_dirent itself is 37 * As long as s_count reference is held, the sysfs_dirent itself is
19 * accessible. Dereferencing s_elem or any other outer entity 38 * accessible. Dereferencing s_elem or any other outer entity
20 * requires s_active reference. 39 * requires s_active reference.
@@ -22,28 +41,43 @@ struct sysfs_elem_bin_attr {
22struct sysfs_dirent { 41struct sysfs_dirent {
23 atomic_t s_count; 42 atomic_t s_count;
24 atomic_t s_active; 43 atomic_t s_active;
25 struct sysfs_dirent * s_parent; 44 struct sysfs_dirent *s_parent;
26 struct sysfs_dirent * s_sibling; 45 struct sysfs_dirent *s_sibling;
27 struct sysfs_dirent * s_children; 46 const char *s_name;
28 const char * s_name;
29 47
30 union { 48 union {
31 struct sysfs_elem_dir dir; 49 struct sysfs_elem_dir s_dir;
32 struct sysfs_elem_symlink symlink; 50 struct sysfs_elem_symlink s_symlink;
33 struct sysfs_elem_attr attr; 51 struct sysfs_elem_attr s_attr;
34 struct sysfs_elem_bin_attr bin_attr; 52 struct sysfs_elem_bin_attr s_bin_attr;
35 } s_elem; 53 };
36 54
37 unsigned int s_flags; 55 unsigned int s_flags;
38 umode_t s_mode;
39 ino_t s_ino; 56 ino_t s_ino;
40 struct dentry * s_dentry; 57 umode_t s_mode;
41 struct iattr * s_iattr; 58 struct iattr *s_iattr;
42 atomic_t s_event;
43}; 59};
44 60
45#define SD_DEACTIVATED_BIAS INT_MIN 61#define SD_DEACTIVATED_BIAS INT_MIN
62
63#define SYSFS_TYPE_MASK 0x00ff
64#define SYSFS_DIR 0x0001
65#define SYSFS_KOBJ_ATTR 0x0002
66#define SYSFS_KOBJ_BIN_ATTR 0x0004
67#define SYSFS_KOBJ_LINK 0x0008
68#define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK)
69
70#define SYSFS_FLAG_MASK ~SYSFS_TYPE_MASK
71#define SYSFS_FLAG_REMOVED 0x0200
72
73static inline unsigned int sysfs_type(struct sysfs_dirent *sd)
74{
75 return sd->s_flags & SYSFS_TYPE_MASK;
76}
46 77
78/*
79 * Context structure to be used while adding/removing nodes.
80 */
47struct sysfs_addrm_cxt { 81struct sysfs_addrm_cxt {
48 struct sysfs_dirent *parent_sd; 82 struct sysfs_dirent *parent_sd;
49 struct inode *parent_inode; 83 struct inode *parent_inode;
@@ -51,63 +85,47 @@ struct sysfs_addrm_cxt {
51 int cnt; 85 int cnt;
52}; 86};
53 87
54extern struct vfsmount * sysfs_mount; 88/*
89 * mount.c
90 */
55extern struct sysfs_dirent sysfs_root; 91extern struct sysfs_dirent sysfs_root;
92extern struct super_block *sysfs_sb;
56extern struct kmem_cache *sysfs_dir_cachep; 93extern struct kmem_cache *sysfs_dir_cachep;
57 94
58extern struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd); 95/*
59extern void sysfs_link_sibling(struct sysfs_dirent *sd); 96 * dir.c
60extern void sysfs_unlink_sibling(struct sysfs_dirent *sd); 97 */
61extern struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd);
62extern void sysfs_put_active(struct sysfs_dirent *sd);
63extern struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd);
64extern void sysfs_put_active_two(struct sysfs_dirent *sd);
65extern void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
66 struct sysfs_dirent *parent_sd);
67extern void sysfs_add_one(struct sysfs_addrm_cxt *acxt,
68 struct sysfs_dirent *sd);
69extern void sysfs_remove_one(struct sysfs_addrm_cxt *acxt,
70 struct sysfs_dirent *sd);
71extern int sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
72
73extern void sysfs_delete_inode(struct inode *inode);
74extern struct inode * sysfs_get_inode(struct sysfs_dirent *sd);
75extern void sysfs_instantiate(struct dentry *dentry, struct inode *inode);
76
77extern void release_sysfs_dirent(struct sysfs_dirent * sd);
78extern struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
79 const unsigned char *name);
80extern struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
81 const unsigned char *name);
82extern struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode,
83 int type);
84
85extern int sysfs_add_file(struct sysfs_dirent *dir_sd,
86 const struct attribute *attr, int type);
87extern int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name);
88extern struct sysfs_dirent *sysfs_find(struct sysfs_dirent *dir, const char * name);
89
90extern int sysfs_create_subdir(struct kobject *kobj, const char *name,
91 struct sysfs_dirent **p_sd);
92extern void sysfs_remove_subdir(struct sysfs_dirent *sd);
93
94extern int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
95
96extern spinlock_t sysfs_assoc_lock;
97extern struct mutex sysfs_mutex; 98extern struct mutex sysfs_mutex;
98extern struct super_block * sysfs_sb; 99extern struct mutex sysfs_rename_mutex;
100extern spinlock_t sysfs_assoc_lock;
101
99extern const struct file_operations sysfs_dir_operations; 102extern const struct file_operations sysfs_dir_operations;
100extern const struct file_operations sysfs_file_operations;
101extern const struct file_operations bin_fops;
102extern const struct inode_operations sysfs_dir_inode_operations; 103extern const struct inode_operations sysfs_dir_inode_operations;
103extern const struct inode_operations sysfs_symlink_inode_operations;
104
105static inline unsigned int sysfs_type(struct sysfs_dirent *sd)
106{
107 return sd->s_flags & SYSFS_TYPE_MASK;
108}
109 104
110static inline struct sysfs_dirent * sysfs_get(struct sysfs_dirent * sd) 105struct dentry *sysfs_get_dentry(struct sysfs_dirent *sd);
106struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd);
107void sysfs_put_active(struct sysfs_dirent *sd);
108struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd);
109void sysfs_put_active_two(struct sysfs_dirent *sd);
110void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
111 struct sysfs_dirent *parent_sd);
112int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
113void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
114void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
115
116struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd,
117 const unsigned char *name);
118struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
119 const unsigned char *name);
120struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type);
121
122void release_sysfs_dirent(struct sysfs_dirent *sd);
123
124int sysfs_create_subdir(struct kobject *kobj, const char *name,
125 struct sysfs_dirent **p_sd);
126void sysfs_remove_subdir(struct sysfs_dirent *sd);
127
128static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
111{ 129{
112 if (sd) { 130 if (sd) {
113 WARN_ON(!atomic_read(&sd->s_count)); 131 WARN_ON(!atomic_read(&sd->s_count));
@@ -116,13 +134,33 @@ static inline struct sysfs_dirent * sysfs_get(struct sysfs_dirent * sd)
116 return sd; 134 return sd;
117} 135}
118 136
119static inline void sysfs_put(struct sysfs_dirent * sd) 137static inline void sysfs_put(struct sysfs_dirent *sd)
120{ 138{
121 if (sd && atomic_dec_and_test(&sd->s_count)) 139 if (sd && atomic_dec_and_test(&sd->s_count))
122 release_sysfs_dirent(sd); 140 release_sysfs_dirent(sd);
123} 141}
124 142
125static inline int sysfs_is_shadowed_inode(struct inode *inode) 143/*
126{ 144 * inode.c
127 return S_ISDIR(inode->i_mode) && inode->i_op->follow_link; 145 */
128} 146struct inode *sysfs_get_inode(struct sysfs_dirent *sd);
147int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
148int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name);
149
150/*
151 * file.c
152 */
153extern const struct file_operations sysfs_file_operations;
154
155int sysfs_add_file(struct sysfs_dirent *dir_sd,
156 const struct attribute *attr, int type);
157
158/*
159 * bin.c
160 */
161extern const struct file_operations bin_fops;
162
163/*
164 * symlink.c
165 */
166extern const struct inode_operations sysfs_symlink_inode_operations;
diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h
index ec2a8a2c737c..93262f2546ad 100644
--- a/include/asm-powerpc/of_device.h
+++ b/include/asm-powerpc/of_device.h
@@ -20,7 +20,7 @@ struct of_device
20extern ssize_t of_device_get_modalias(struct of_device *ofdev, 20extern ssize_t of_device_get_modalias(struct of_device *ofdev,
21 char *str, ssize_t len); 21 char *str, ssize_t len);
22extern int of_device_uevent(struct device *dev, 22extern int of_device_uevent(struct device *dev,
23 char **envp, int num_envp, char *buffer, int buffer_size); 23 struct kobj_uevent_env *env);
24 24
25/* This is just here during the transition */ 25/* This is just here during the transition */
26#include <linux/of_device.h> 26#include <linux/of_device.h>
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index 104e51e20e14..f592d6de3b97 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -49,6 +49,12 @@ struct dentry *debugfs_create_u32(const char *name, mode_t mode,
49 struct dentry *parent, u32 *value); 49 struct dentry *parent, u32 *value);
50struct dentry *debugfs_create_u64(const char *name, mode_t mode, 50struct dentry *debugfs_create_u64(const char *name, mode_t mode,
51 struct dentry *parent, u64 *value); 51 struct dentry *parent, u64 *value);
52struct dentry *debugfs_create_x8(const char *name, mode_t mode,
53 struct dentry *parent, u8 *value);
54struct dentry *debugfs_create_x16(const char *name, mode_t mode,
55 struct dentry *parent, u16 *value);
56struct dentry *debugfs_create_x32(const char *name, mode_t mode,
57 struct dentry *parent, u32 *value);
52struct dentry *debugfs_create_bool(const char *name, mode_t mode, 58struct dentry *debugfs_create_bool(const char *name, mode_t mode,
53 struct dentry *parent, u32 *value); 59 struct dentry *parent, u32 *value);
54 60
@@ -122,6 +128,27 @@ static inline struct dentry *debugfs_create_u64(const char *name, mode_t mode,
122 return ERR_PTR(-ENODEV); 128 return ERR_PTR(-ENODEV);
123} 129}
124 130
131static inline struct dentry *debugfs_create_x8(const char *name, mode_t mode,
132 struct dentry *parent,
133 u8 *value)
134{
135 return ERR_PTR(-ENODEV);
136}
137
138static inline struct dentry *debugfs_create_x16(const char *name, mode_t mode,
139 struct dentry *parent,
140 u16 *value)
141{
142 return ERR_PTR(-ENODEV);
143}
144
145static inline struct dentry *debugfs_create_x32(const char *name, mode_t mode,
146 struct dentry *parent,
147 u32 *value)
148{
149 return ERR_PTR(-ENODEV);
150}
151
125static inline struct dentry *debugfs_create_bool(const char *name, mode_t mode, 152static inline struct dentry *debugfs_create_bool(const char *name, mode_t mode,
126 struct dentry *parent, 153 struct dentry *parent,
127 u32 *value) 154 u32 *value)
diff --git a/include/linux/device.h b/include/linux/device.h
index 3a38d1f70cb7..2e15822fe409 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -64,12 +64,9 @@ struct bus_type {
64 struct bus_attribute * bus_attrs; 64 struct bus_attribute * bus_attrs;
65 struct device_attribute * dev_attrs; 65 struct device_attribute * dev_attrs;
66 struct driver_attribute * drv_attrs; 66 struct driver_attribute * drv_attrs;
67 struct bus_attribute drivers_autoprobe_attr;
68 struct bus_attribute drivers_probe_attr;
69 67
70 int (*match)(struct device * dev, struct device_driver * drv); 68 int (*match)(struct device * dev, struct device_driver * drv);
71 int (*uevent)(struct device *dev, char **envp, 69 int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
72 int num_envp, char *buffer, int buffer_size);
73 int (*probe)(struct device * dev); 70 int (*probe)(struct device * dev);
74 int (*remove)(struct device * dev); 71 int (*remove)(struct device * dev);
75 void (*shutdown)(struct device * dev); 72 void (*shutdown)(struct device * dev);
@@ -189,10 +186,8 @@ struct class {
189 struct class_device_attribute * class_dev_attrs; 186 struct class_device_attribute * class_dev_attrs;
190 struct device_attribute * dev_attrs; 187 struct device_attribute * dev_attrs;
191 188
192 int (*uevent)(struct class_device *dev, char **envp, 189 int (*uevent)(struct class_device *dev, struct kobj_uevent_env *env);
193 int num_envp, char *buffer, int buffer_size); 190 int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
194 int (*dev_uevent)(struct device *dev, char **envp, int num_envp,
195 char *buffer, int buffer_size);
196 191
197 void (*release)(struct class_device *dev); 192 void (*release)(struct class_device *dev);
198 void (*class_release)(struct class *class); 193 void (*class_release)(struct class *class);
@@ -268,8 +263,7 @@ struct class_device {
268 struct attribute_group ** groups; /* optional groups */ 263 struct attribute_group ** groups; /* optional groups */
269 264
270 void (*release)(struct class_device *dev); 265 void (*release)(struct class_device *dev);
271 int (*uevent)(struct class_device *dev, char **envp, 266 int (*uevent)(struct class_device *dev, struct kobj_uevent_env *env);
272 int num_envp, char *buffer, int buffer_size);
273 char class_id[BUS_ID_SIZE]; /* unique to this class */ 267 char class_id[BUS_ID_SIZE]; /* unique to this class */
274}; 268};
275 269
@@ -337,8 +331,7 @@ extern void class_device_destroy(struct class *cls, dev_t devt);
337struct device_type { 331struct device_type {
338 const char *name; 332 const char *name;
339 struct attribute_group **groups; 333 struct attribute_group **groups;
340 int (*uevent)(struct device *dev, char **envp, int num_envp, 334 int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
341 char *buffer, int buffer_size);
342 void (*release)(struct device *dev); 335 void (*release)(struct device *dev);
343 int (*suspend)(struct device * dev, pm_message_t state); 336 int (*suspend)(struct device * dev, pm_message_t state);
344 int (*resume)(struct device * dev); 337 int (*resume)(struct device * dev);
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 949706c33622..4a0d27f475d7 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -1,8 +1,10 @@
1/* 1/*
2 * kobject.h - generic kernel object infrastructure. 2 * kobject.h - generic kernel object infrastructure.
3 * 3 *
4 * Copyright (c) 2002-2003 Patrick Mochel 4 * Copyright (c) 2002-2003 Patrick Mochel
5 * Copyright (c) 2002-2003 Open Source Development Labs 5 * Copyright (c) 2002-2003 Open Source Development Labs
6 * Copyright (c) 2006-2007 Greg Kroah-Hartman <greg@kroah.com>
7 * Copyright (c) 2006-2007 Novell Inc.
6 * 8 *
7 * This file is released under the GPLv2. 9 * This file is released under the GPLv2.
8 * 10 *
@@ -29,6 +31,8 @@
29 31
30#define KOBJ_NAME_LEN 20 32#define KOBJ_NAME_LEN 20
31#define UEVENT_HELPER_PATH_LEN 256 33#define UEVENT_HELPER_PATH_LEN 256
34#define UEVENT_NUM_ENVP 32 /* number of env pointers */
35#define UEVENT_BUFFER_SIZE 2048 /* buffer for the variables */
32 36
33/* path to the userspace helper executed on an event */ 37/* path to the userspace helper executed on an event */
34extern char uevent_helper[]; 38extern char uevent_helper[];
@@ -56,19 +60,14 @@ enum kobject_action {
56 KOBJ_MAX 60 KOBJ_MAX
57}; 61};
58 62
59/* The list of strings defining the valid kobject actions as specified above */
60extern const char *kobject_actions[];
61
62struct kobject { 63struct kobject {
63 const char * k_name; 64 const char * k_name;
64 char name[KOBJ_NAME_LEN];
65 struct kref kref; 65 struct kref kref;
66 struct list_head entry; 66 struct list_head entry;
67 struct kobject * parent; 67 struct kobject * parent;
68 struct kset * kset; 68 struct kset * kset;
69 struct kobj_type * ktype; 69 struct kobj_type * ktype;
70 struct sysfs_dirent * sd; 70 struct sysfs_dirent * sd;
71 wait_queue_head_t poll;
72}; 71};
73 72
74extern int kobject_set_name(struct kobject *, const char *, ...) 73extern int kobject_set_name(struct kobject *, const char *, ...)
@@ -83,14 +82,9 @@ extern void kobject_init(struct kobject *);
83extern void kobject_cleanup(struct kobject *); 82extern void kobject_cleanup(struct kobject *);
84 83
85extern int __must_check kobject_add(struct kobject *); 84extern int __must_check kobject_add(struct kobject *);
86extern int __must_check kobject_shadow_add(struct kobject *kobj,
87 struct sysfs_dirent *shadow_parent);
88extern void kobject_del(struct kobject *); 85extern void kobject_del(struct kobject *);
89 86
90extern int __must_check kobject_rename(struct kobject *, const char *new_name); 87extern int __must_check kobject_rename(struct kobject *, const char *new_name);
91extern int __must_check kobject_shadow_rename(struct kobject *kobj,
92 struct sysfs_dirent *new_parent,
93 const char *new_name);
94extern int __must_check kobject_move(struct kobject *, struct kobject *); 88extern int __must_check kobject_move(struct kobject *, struct kobject *);
95 89
96extern int __must_check kobject_register(struct kobject *); 90extern int __must_check kobject_register(struct kobject *);
@@ -111,36 +105,44 @@ struct kobj_type {
111 struct attribute ** default_attrs; 105 struct attribute ** default_attrs;
112}; 106};
113 107
108struct kobj_uevent_env {
109 char *envp[UEVENT_NUM_ENVP];
110 int envp_idx;
111 char buf[UEVENT_BUFFER_SIZE];
112 int buflen;
113};
114
114struct kset_uevent_ops { 115struct kset_uevent_ops {
115 int (*filter)(struct kset *kset, struct kobject *kobj); 116 int (*filter)(struct kset *kset, struct kobject *kobj);
116 const char *(*name)(struct kset *kset, struct kobject *kobj); 117 const char *(*name)(struct kset *kset, struct kobject *kobj);
117 int (*uevent)(struct kset *kset, struct kobject *kobj, char **envp, 118 int (*uevent)(struct kset *kset, struct kobject *kobj,
118 int num_envp, char *buffer, int buffer_size); 119 struct kobj_uevent_env *env);
119}; 120};
120 121
121/* 122/**
122 * struct kset - a set of kobjects of a specific type, belonging 123 * struct kset - a set of kobjects of a specific type, belonging to a specific subsystem.
123 * to a specific subsystem.
124 *
125 * All kobjects of a kset should be embedded in an identical
126 * type. This type may have a descriptor, which the kset points
127 * to. This allows there to exist sets of objects of the same
128 * type in different subsystems.
129 * 124 *
130 * A subsystem does not have to be a list of only one type 125 * A kset defines a group of kobjects. They can be individually
131 * of object; multiple ksets can belong to one subsystem. All 126 * different "types" but overall these kobjects all want to be grouped
132 * ksets of a subsystem share the subsystem's lock. 127 * together and operated on in the same manner. ksets are used to
128 * define the attribute callbacks and other common events that happen to
129 * a kobject.
133 * 130 *
134 * Each kset can support specific event variables; it can 131 * @ktype: the struct kobj_type for this specific kset
135 * supress the event generation or add subsystem specific 132 * @list: the list of all kobjects for this kset
136 * variables carried with the event. 133 * @list_lock: a lock for iterating over the kobjects
134 * @kobj: the embedded kobject for this kset (recursion, isn't it fun...)
135 * @uevent_ops: the set of uevent operations for this kset. These are
136 * called whenever a kobject has something happen to it so that the kset
137 * can add new environment variables, or filter out the uevents if so
138 * desired.
137 */ 139 */
138struct kset { 140struct kset {
139 struct kobj_type * ktype; 141 struct kobj_type *ktype;
140 struct list_head list; 142 struct list_head list;
141 spinlock_t list_lock; 143 spinlock_t list_lock;
142 struct kobject kobj; 144 struct kobject kobj;
143 struct kset_uevent_ops * uevent_ops; 145 struct kset_uevent_ops *uevent_ops;
144}; 146};
145 147
146 148
@@ -179,18 +181,18 @@ extern struct kobject * kset_find_obj(struct kset *, const char *);
179 * Use this when initializing an embedded kset with no other 181 * Use this when initializing an embedded kset with no other
180 * fields to initialize. 182 * fields to initialize.
181 */ 183 */
182#define set_kset_name(str) .kset = { .kobj = { .name = str } } 184#define set_kset_name(str) .kset = { .kobj = { .k_name = str } }
183 185
184 186
185#define decl_subsys(_name,_type,_uevent_ops) \ 187#define decl_subsys(_name,_type,_uevent_ops) \
186struct kset _name##_subsys = { \ 188struct kset _name##_subsys = { \
187 .kobj = { .name = __stringify(_name) }, \ 189 .kobj = { .k_name = __stringify(_name) }, \
188 .ktype = _type, \ 190 .ktype = _type, \
189 .uevent_ops =_uevent_ops, \ 191 .uevent_ops =_uevent_ops, \
190} 192}
191#define decl_subsys_name(_varname,_name,_type,_uevent_ops) \ 193#define decl_subsys_name(_varname,_name,_type,_uevent_ops) \
192struct kset _varname##_subsys = { \ 194struct kset _varname##_subsys = { \
193 .kobj = { .name = __stringify(_name) }, \ 195 .kobj = { .k_name = __stringify(_name) }, \
194 .ktype = _type, \ 196 .ktype = _type, \
195 .uevent_ops =_uevent_ops, \ 197 .uevent_ops =_uevent_ops, \
196} 198}
@@ -218,49 +220,9 @@ extern struct kset hypervisor_subsys;
218#define kobj_set_kset_s(obj,subsys) \ 220#define kobj_set_kset_s(obj,subsys) \
219 (obj)->kobj.kset = &(subsys) 221 (obj)->kobj.kset = &(subsys)
220 222
221/**
222 * kset_set_kset_s(obj,subsys) - set kset for embedded kset.
223 * @obj: ptr to some object type.
224 * @subsys: a subsystem object (not a ptr).
225 *
226 * Can be used for any object type with an embedded ->kset.
227 * Sets the kset of @obj's embedded kobject (via its embedded
228 * kset) to @subsys.kset. This makes @obj a member of that
229 * kset.
230 */
231
232#define kset_set_kset_s(obj,subsys) \
233 (obj)->kset.kobj.kset = &(subsys)
234
235/**
236 * subsys_set_kset(obj,subsys) - set kset for subsystem
237 * @obj: ptr to some object type.
238 * @_subsys: a subsystem object (not a ptr).
239 *
240 * Can be used for any object type with an embedded ->subsys.
241 * Sets the kset of @obj's kobject to @subsys.kset. This makes
242 * the object a member of that kset.
243 */
244
245#define subsys_set_kset(obj,_subsys) \
246 (obj)->subsys.kobj.kset = &(_subsys)
247
248extern void subsystem_init(struct kset *);
249extern int __must_check subsystem_register(struct kset *); 223extern int __must_check subsystem_register(struct kset *);
250extern void subsystem_unregister(struct kset *); 224extern void subsystem_unregister(struct kset *);
251 225
252static inline struct kset *subsys_get(struct kset *s)
253{
254 if (s)
255 return kset_get(s);
256 return NULL;
257}
258
259static inline void subsys_put(struct kset *s)
260{
261 kset_put(s);
262}
263
264struct subsys_attribute { 226struct subsys_attribute {
265 struct attribute attr; 227 struct attribute attr;
266 ssize_t (*show)(struct kset *, char *); 228 ssize_t (*show)(struct kset *, char *);
@@ -275,10 +237,11 @@ int kobject_uevent(struct kobject *kobj, enum kobject_action action);
275int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, 237int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
276 char *envp[]); 238 char *envp[]);
277 239
278int add_uevent_var(char **envp, int num_envp, int *cur_index, 240int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
279 char *buffer, int buffer_size, int *cur_len, 241 __attribute__((format (printf, 2, 3)));
280 const char *format, ...) 242
281 __attribute__((format (printf, 7, 8))); 243int kobject_action_type(const char *buf, size_t count,
244 enum kobject_action *type);
282#else 245#else
283static inline int kobject_uevent(struct kobject *kobj, enum kobject_action action) 246static inline int kobject_uevent(struct kobject *kobj, enum kobject_action action)
284{ return 0; } 247{ return 0; }
@@ -287,10 +250,12 @@ static inline int kobject_uevent_env(struct kobject *kobj,
287 char *envp[]) 250 char *envp[])
288{ return 0; } 251{ return 0; }
289 252
290static inline int add_uevent_var(char **envp, int num_envp, int *cur_index, 253static inline int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
291 char *buffer, int buffer_size, int *cur_len,
292 const char *format, ...)
293{ return 0; } 254{ return 0; }
255
256static inline int kobject_action_type(const char *buf, size_t count,
257 enum kobject_action *type)
258{ return -EINVAL; }
294#endif 259#endif
295 260
296#endif /* __KERNEL__ */ 261#endif /* __KERNEL__ */
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 8bbd459eafdc..e80804316cdb 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -15,7 +15,7 @@
15 15
16struct platform_device { 16struct platform_device {
17 const char * name; 17 const char * name;
18 u32 id; 18 int id;
19 struct device dev; 19 struct device dev;
20 u32 num_resources; 20 u32 num_resources;
21 struct resource * resource; 21 struct resource * resource;
@@ -35,9 +35,10 @@ extern struct resource *platform_get_resource_byname(struct platform_device *, u
35extern int platform_get_irq_byname(struct platform_device *, char *); 35extern int platform_get_irq_byname(struct platform_device *, char *);
36extern int platform_add_devices(struct platform_device **, int); 36extern int platform_add_devices(struct platform_device **, int);
37 37
38extern struct platform_device *platform_device_register_simple(char *, unsigned int, struct resource *, unsigned int); 38extern struct platform_device *platform_device_register_simple(char *, int id,
39 struct resource *, unsigned int);
39 40
40extern struct platform_device *platform_device_alloc(const char *name, unsigned int id); 41extern struct platform_device *platform_device_alloc(const char *name, int id);
41extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num); 42extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num);
42extern int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size); 43extern int platform_device_add_data(struct platform_device *pdev, const void *data, size_t size);
43extern int platform_device_add(struct platform_device *pdev); 44extern int platform_device_add(struct platform_device *pdev);
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index be8228e50a27..149ab62329e2 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -3,6 +3,8 @@
3 * 3 *
4 * Copyright (c) 2001,2002 Patrick Mochel 4 * Copyright (c) 2001,2002 Patrick Mochel
5 * Copyright (c) 2004 Silicon Graphics, Inc. 5 * Copyright (c) 2004 Silicon Graphics, Inc.
6 * Copyright (c) 2007 SUSE Linux Products GmbH
7 * Copyright (c) 2007 Tejun Heo <teheo@suse.de>
6 * 8 *
7 * Please see Documentation/filesystems/sysfs.txt for more information. 9 * Please see Documentation/filesystems/sysfs.txt for more information.
8 */ 10 */
@@ -17,23 +19,20 @@
17 19
18struct kobject; 20struct kobject;
19struct module; 21struct module;
20struct nameidata;
21struct dentry;
22struct sysfs_dirent;
23 22
24/* FIXME 23/* FIXME
25 * The *owner field is no longer used, but leave around 24 * The *owner field is no longer used, but leave around
26 * until the tree gets cleaned up fully. 25 * until the tree gets cleaned up fully.
27 */ 26 */
28struct attribute { 27struct attribute {
29 const char * name; 28 const char *name;
30 struct module * owner; 29 struct module *owner;
31 mode_t mode; 30 mode_t mode;
32}; 31};
33 32
34struct attribute_group { 33struct attribute_group {
35 const char * name; 34 const char *name;
36 struct attribute ** attrs; 35 struct attribute **attrs;
37}; 36};
38 37
39 38
@@ -77,72 +76,41 @@ struct sysfs_ops {
77 ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); 76 ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
78}; 77};
79 78
80#define SYSFS_TYPE_MASK 0x00ff
81#define SYSFS_ROOT 0x0001
82#define SYSFS_DIR 0x0002
83#define SYSFS_KOBJ_ATTR 0x0004
84#define SYSFS_KOBJ_BIN_ATTR 0x0008
85#define SYSFS_KOBJ_LINK 0x0020
86#define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK)
87
88#define SYSFS_FLAG_MASK ~SYSFS_TYPE_MASK
89#define SYSFS_FLAG_REMOVED 0x0100
90
91#ifdef CONFIG_SYSFS 79#ifdef CONFIG_SYSFS
92 80
93extern int sysfs_schedule_callback(struct kobject *kobj, 81int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
94 void (*func)(void *), void *data, struct module *owner); 82 void *data, struct module *owner);
95
96extern int __must_check
97sysfs_create_dir(struct kobject *kobj, struct sysfs_dirent *shadow_parent_sd);
98
99extern void
100sysfs_remove_dir(struct kobject *);
101
102extern int __must_check
103sysfs_rename_dir(struct kobject *kobj, struct sysfs_dirent *new_parent_sd,
104 const char *new_name);
105
106extern int __must_check
107sysfs_move_dir(struct kobject *, struct kobject *);
108
109extern int __must_check
110sysfs_create_file(struct kobject *, const struct attribute *);
111 83
112extern int __must_check 84int __must_check sysfs_create_dir(struct kobject *kobj);
113sysfs_update_file(struct kobject *, const struct attribute *); 85void sysfs_remove_dir(struct kobject *kobj);
86int __must_check sysfs_rename_dir(struct kobject *kobj, const char *new_name);
87int __must_check sysfs_move_dir(struct kobject *kobj,
88 struct kobject *new_parent_kobj);
114 89
115extern int __must_check 90int __must_check sysfs_create_file(struct kobject *kobj,
116sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode); 91 const struct attribute *attr);
117 92int __must_check sysfs_chmod_file(struct kobject *kobj, struct attribute *attr,
118extern void 93 mode_t mode);
119sysfs_remove_file(struct kobject *, const struct attribute *); 94void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr);
120
121extern int __must_check
122sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name);
123
124extern void
125sysfs_remove_link(struct kobject *, const char * name);
126 95
127int __must_check sysfs_create_bin_file(struct kobject *kobj, 96int __must_check sysfs_create_bin_file(struct kobject *kobj,
128 struct bin_attribute *attr); 97 struct bin_attribute *attr);
129void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr); 98void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);
130 99
131int __must_check sysfs_create_group(struct kobject *, 100int __must_check sysfs_create_link(struct kobject *kobj, struct kobject *target,
132 const struct attribute_group *); 101 const char *name);
133void sysfs_remove_group(struct kobject *, const struct attribute_group *); 102void sysfs_remove_link(struct kobject *kobj, const char *name);
103
104int __must_check sysfs_create_group(struct kobject *kobj,
105 const struct attribute_group *grp);
106void sysfs_remove_group(struct kobject *kobj,
107 const struct attribute_group *grp);
134int sysfs_add_file_to_group(struct kobject *kobj, 108int sysfs_add_file_to_group(struct kobject *kobj,
135 const struct attribute *attr, const char *group); 109 const struct attribute *attr, const char *group);
136void sysfs_remove_file_from_group(struct kobject *kobj, 110void sysfs_remove_file_from_group(struct kobject *kobj,
137 const struct attribute *attr, const char *group); 111 const struct attribute *attr, const char *group);
138
139void sysfs_notify(struct kobject * k, char *dir, char *attr);
140
141 112
142extern int sysfs_make_shadowed_dir(struct kobject *kobj, 113void sysfs_notify(struct kobject *kobj, char *dir, char *attr);
143 void * (*follow_link)(struct dentry *, struct nameidata *));
144extern struct sysfs_dirent *sysfs_create_shadow_dir(struct kobject *kobj);
145extern void sysfs_remove_shadow_dir(struct sysfs_dirent *shadow_sd);
146 114
147extern int __must_check sysfs_init(void); 115extern int __must_check sysfs_init(void);
148 116
@@ -154,75 +122,76 @@ static inline int sysfs_schedule_callback(struct kobject *kobj,
154 return -ENOSYS; 122 return -ENOSYS;
155} 123}
156 124
157static inline int sysfs_create_dir(struct kobject *kobj, 125static inline int sysfs_create_dir(struct kobject *kobj)
158 struct sysfs_dirent *shadow_parent_sd)
159{ 126{
160 return 0; 127 return 0;
161} 128}
162 129
163static inline void sysfs_remove_dir(struct kobject * k) 130static inline void sysfs_remove_dir(struct kobject *kobj)
164{ 131{
165 ; 132 ;
166} 133}
167 134
168static inline int sysfs_rename_dir(struct kobject *kobj, 135static inline int sysfs_rename_dir(struct kobject *kobj, const char *new_name)
169 struct sysfs_dirent *new_parent_sd,
170 const char *new_name)
171{ 136{
172 return 0; 137 return 0;
173} 138}
174 139
175static inline int sysfs_move_dir(struct kobject * k, struct kobject * new_parent) 140static inline int sysfs_move_dir(struct kobject *kobj,
141 struct kobject *new_parent_kobj)
176{ 142{
177 return 0; 143 return 0;
178} 144}
179 145
180static inline int sysfs_create_file(struct kobject * k, const struct attribute * a) 146static inline int sysfs_create_file(struct kobject *kobj,
147 const struct attribute *attr)
181{ 148{
182 return 0; 149 return 0;
183} 150}
184 151
185static inline int sysfs_update_file(struct kobject * k, const struct attribute * a) 152static inline int sysfs_chmod_file(struct kobject *kobj,
186{ 153 struct attribute *attr, mode_t mode)
187 return 0;
188}
189static inline int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
190{ 154{
191 return 0; 155 return 0;
192} 156}
193 157
194static inline void sysfs_remove_file(struct kobject * k, const struct attribute * a) 158static inline void sysfs_remove_file(struct kobject *kobj,
159 const struct attribute *attr)
195{ 160{
196 ; 161 ;
197} 162}
198 163
199static inline int sysfs_create_link(struct kobject * k, struct kobject * t, const char * n) 164static inline int sysfs_create_bin_file(struct kobject *kobj,
165 struct bin_attribute *attr)
200{ 166{
201 return 0; 167 return 0;
202} 168}
203 169
204static inline void sysfs_remove_link(struct kobject * k, const char * name) 170static inline int sysfs_remove_bin_file(struct kobject *kobj,
171 struct bin_attribute *attr)
205{ 172{
206 ; 173 return 0;
207} 174}
208 175
209 176static inline int sysfs_create_link(struct kobject *kobj,
210static inline int sysfs_create_bin_file(struct kobject * k, struct bin_attribute * a) 177 struct kobject *target, const char *name)
211{ 178{
212 return 0; 179 return 0;
213} 180}
214 181
215static inline int sysfs_remove_bin_file(struct kobject * k, struct bin_attribute * a) 182static inline void sysfs_remove_link(struct kobject *kobj, const char *name)
216{ 183{
217 return 0; 184 ;
218} 185}
219 186
220static inline int sysfs_create_group(struct kobject * k, const struct attribute_group *g) 187static inline int sysfs_create_group(struct kobject *kobj,
188 const struct attribute_group *grp)
221{ 189{
222 return 0; 190 return 0;
223} 191}
224 192
225static inline void sysfs_remove_group(struct kobject * k, const struct attribute_group * g) 193static inline void sysfs_remove_group(struct kobject *kobj,
194 const struct attribute_group *grp)
226{ 195{
227 ; 196 ;
228} 197}
@@ -238,14 +207,8 @@ static inline void sysfs_remove_file_from_group(struct kobject *kobj,
238{ 207{
239} 208}
240 209
241static inline void sysfs_notify(struct kobject * k, char *dir, char *attr) 210static inline void sysfs_notify(struct kobject *kobj, char *dir, char *attr)
242{
243}
244
245static inline int sysfs_make_shadowed_dir(struct kobject *kobj,
246 void * (*follow_link)(struct dentry *, struct nameidata *))
247{ 211{
248 return 0;
249} 212}
250 213
251static inline int __must_check sysfs_init(void) 214static inline int __must_check sysfs_init(void)
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 6570719eafdf..60478f6e5dc6 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -21,7 +21,6 @@
21 * (Note: the *_driver.minor_start values 1, 64, 128, 192 are 21 * (Note: the *_driver.minor_start values 1, 64, 128, 192 are
22 * hardcoded at present.) 22 * hardcoded at present.)
23 */ 23 */
24#define NR_PTYS CONFIG_LEGACY_PTY_COUNT /* Number of legacy ptys */
25#define NR_UNIX98_PTY_DEFAULT 4096 /* Default maximum for Unix98 ptys */ 24#define NR_UNIX98_PTY_DEFAULT 4096 /* Default maximum for Unix98 ptys */
26#define NR_UNIX98_PTY_MAX (1 << MINORBITS) /* Absolute limit */ 25#define NR_UNIX98_PTY_MAX (1 << MINORBITS) /* Absolute limit */
27#define NR_LDISCS 17 26#define NR_LDISCS 17
diff --git a/include/linux/video_output.h b/include/linux/video_output.h
index e63e0c03ee0d..2fb46bc9340d 100644
--- a/include/linux/video_output.h
+++ b/include/linux/video_output.h
@@ -31,9 +31,9 @@ struct output_properties {
31struct output_device { 31struct output_device {
32 int request_state; 32 int request_state;
33 struct output_properties *props; 33 struct output_properties *props;
34 struct class_device class_dev; 34 struct device dev;
35}; 35};
36#define to_output_device(obj) container_of(obj, struct output_device, class_dev) 36#define to_output_device(obj) container_of(obj, struct output_device, dev)
37struct output_device *video_output_register(const char *name, 37struct output_device *video_output_register(const char *name,
38 struct device *dev, 38 struct device *dev,
39 void *devdata, 39 void *devdata,
diff --git a/lib/Makefile b/lib/Makefile
index 4f3f3e256501..6c4ea33bb2cb 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -10,7 +10,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
10lib-$(CONFIG_MMU) += ioremap.o 10lib-$(CONFIG_MMU) += ioremap.o
11lib-$(CONFIG_SMP) += cpumask.o 11lib-$(CONFIG_SMP) += cpumask.o
12 12
13lib-y += kobject.o kref.o kobject_uevent.o klist.o 13lib-y += kobject.o kref.o klist.o
14 14
15obj-y += div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ 15obj-y += div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
16 bust_spinlocks.o hexdump.o kasprintf.o 16 bust_spinlocks.o hexdump.o kasprintf.o
@@ -20,6 +20,7 @@ CFLAGS_kobject.o += -DDEBUG
20CFLAGS_kobject_uevent.o += -DDEBUG 20CFLAGS_kobject_uevent.o += -DDEBUG
21endif 21endif
22 22
23lib-$(CONFIG_HOTPLUG) += kobject_uevent.o
23obj-$(CONFIG_GENERIC_IOMAP) += iomap.o 24obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
24obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o 25obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o
25obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o 26obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o
diff --git a/lib/kobject.c b/lib/kobject.c
index 4b08e0ff95c8..03d40360ff1b 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -2,6 +2,8 @@
2 * kobject.c - library routines for handling generic kernel objects 2 * kobject.c - library routines for handling generic kernel objects
3 * 3 *
4 * Copyright (c) 2002-2003 Patrick Mochel <mochel@osdl.org> 4 * Copyright (c) 2002-2003 Patrick Mochel <mochel@osdl.org>
5 * Copyright (c) 2006-2007 Greg Kroah-Hartman <greg@kroah.com>
6 * Copyright (c) 2006-2007 Novell Inc.
5 * 7 *
6 * This file is released under the GPLv2. 8 * This file is released under the GPLv2.
7 * 9 *
@@ -44,11 +46,11 @@ static int populate_dir(struct kobject * kobj)
44 return error; 46 return error;
45} 47}
46 48
47static int create_dir(struct kobject *kobj, struct sysfs_dirent *shadow_parent) 49static int create_dir(struct kobject * kobj)
48{ 50{
49 int error = 0; 51 int error = 0;
50 if (kobject_name(kobj)) { 52 if (kobject_name(kobj)) {
51 error = sysfs_create_dir(kobj, shadow_parent); 53 error = sysfs_create_dir(kobj);
52 if (!error) { 54 if (!error) {
53 if ((error = populate_dir(kobj))) 55 if ((error = populate_dir(kobj)))
54 sysfs_remove_dir(kobj); 56 sysfs_remove_dir(kobj);
@@ -131,7 +133,6 @@ void kobject_init(struct kobject * kobj)
131 return; 133 return;
132 kref_init(&kobj->kref); 134 kref_init(&kobj->kref);
133 INIT_LIST_HEAD(&kobj->entry); 135 INIT_LIST_HEAD(&kobj->entry);
134 init_waitqueue_head(&kobj->poll);
135 kobj->kset = kset_get(kobj->kset); 136 kobj->kset = kset_get(kobj->kset);
136} 137}
137 138
@@ -157,12 +158,11 @@ static void unlink(struct kobject * kobj)
157} 158}
158 159
159/** 160/**
160 * kobject_shadow_add - add an object to the hierarchy. 161 * kobject_add - add an object to the hierarchy.
161 * @kobj: object. 162 * @kobj: object.
162 * @shadow_parent: sysfs directory to add to.
163 */ 163 */
164 164
165int kobject_shadow_add(struct kobject *kobj, struct sysfs_dirent *shadow_parent) 165int kobject_add(struct kobject * kobj)
166{ 166{
167 int error = 0; 167 int error = 0;
168 struct kobject * parent; 168 struct kobject * parent;
@@ -170,7 +170,7 @@ int kobject_shadow_add(struct kobject *kobj, struct sysfs_dirent *shadow_parent)
170 if (!(kobj = kobject_get(kobj))) 170 if (!(kobj = kobject_get(kobj)))
171 return -ENOENT; 171 return -ENOENT;
172 if (!kobj->k_name) 172 if (!kobj->k_name)
173 kobj->k_name = kobj->name; 173 kobject_set_name(kobj, "NO_NAME");
174 if (!*kobj->k_name) { 174 if (!*kobj->k_name) {
175 pr_debug("kobject attempted to be registered with no name!\n"); 175 pr_debug("kobject attempted to be registered with no name!\n");
176 WARN_ON(1); 176 WARN_ON(1);
@@ -181,7 +181,7 @@ int kobject_shadow_add(struct kobject *kobj, struct sysfs_dirent *shadow_parent)
181 181
182 pr_debug("kobject %s: registering. parent: %s, set: %s\n", 182 pr_debug("kobject %s: registering. parent: %s, set: %s\n",
183 kobject_name(kobj), parent ? kobject_name(parent) : "<NULL>", 183 kobject_name(kobj), parent ? kobject_name(parent) : "<NULL>",
184 kobj->kset ? kobj->kset->kobj.name : "<NULL>" ); 184 kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>" );
185 185
186 if (kobj->kset) { 186 if (kobj->kset) {
187 spin_lock(&kobj->kset->list_lock); 187 spin_lock(&kobj->kset->list_lock);
@@ -194,7 +194,7 @@ int kobject_shadow_add(struct kobject *kobj, struct sysfs_dirent *shadow_parent)
194 kobj->parent = parent; 194 kobj->parent = parent;
195 } 195 }
196 196
197 error = create_dir(kobj, shadow_parent); 197 error = create_dir(kobj);
198 if (error) { 198 if (error) {
199 /* unlink does the kobject_put() for us */ 199 /* unlink does the kobject_put() for us */
200 unlink(kobj); 200 unlink(kobj);
@@ -216,16 +216,6 @@ int kobject_shadow_add(struct kobject *kobj, struct sysfs_dirent *shadow_parent)
216} 216}
217 217
218/** 218/**
219 * kobject_add - add an object to the hierarchy.
220 * @kobj: object.
221 */
222int kobject_add(struct kobject * kobj)
223{
224 return kobject_shadow_add(kobj, NULL);
225}
226
227
228/**
229 * kobject_register - initialize and add an object. 219 * kobject_register - initialize and add an object.
230 * @kobj: object in question. 220 * @kobj: object in question.
231 */ 221 */
@@ -255,54 +245,50 @@ int kobject_register(struct kobject * kobj)
255int kobject_set_name(struct kobject * kobj, const char * fmt, ...) 245int kobject_set_name(struct kobject * kobj, const char * fmt, ...)
256{ 246{
257 int error = 0; 247 int error = 0;
258 int limit = KOBJ_NAME_LEN; 248 int limit;
259 int need; 249 int need;
260 va_list args; 250 va_list args;
261 char * name; 251 char *name;
262 252
263 /* 253 /* find out how big a buffer we need */
264 * First, try the static array 254 name = kmalloc(1024, GFP_KERNEL);
265 */ 255 if (!name) {
266 va_start(args,fmt); 256 error = -ENOMEM;
267 need = vsnprintf(kobj->name,limit,fmt,args); 257 goto done;
258 }
259 va_start(args, fmt);
260 need = vsnprintf(name, 1024, fmt, args);
268 va_end(args); 261 va_end(args);
269 if (need < limit) 262 kfree(name);
270 name = kobj->name; 263
271 else { 264 /* Allocate the new space and copy the string in */
272 /* 265 limit = need + 1;
273 * Need more space? Allocate it and try again 266 name = kmalloc(limit, GFP_KERNEL);
274 */ 267 if (!name) {
275 limit = need + 1; 268 error = -ENOMEM;
276 name = kmalloc(limit,GFP_KERNEL); 269 goto done;
277 if (!name) { 270 }
278 error = -ENOMEM; 271 va_start(args, fmt);
279 goto Done; 272 need = vsnprintf(name, limit, fmt, args);
280 } 273 va_end(args);
281 va_start(args,fmt); 274
282 need = vsnprintf(name,limit,fmt,args); 275 /* something wrong with the string we copied? */
283 va_end(args); 276 if (need >= limit) {
284 277 kfree(name);
285 /* Still? Give up. */ 278 error = -EFAULT;
286 if (need >= limit) { 279 goto done;
287 kfree(name);
288 error = -EFAULT;
289 goto Done;
290 }
291 } 280 }
292 281
293 /* Free the old name, if necessary. */ 282 /* Free the old name, if necessary. */
294 if (kobj->k_name && kobj->k_name != kobj->name) 283 kfree(kobj->k_name);
295 kfree(kobj->k_name);
296 284
297 /* Now, set the new name */ 285 /* Now, set the new name */
298 kobj->k_name = name; 286 kobj->k_name = name;
299 Done: 287done:
300 return error; 288 return error;
301} 289}
302
303EXPORT_SYMBOL(kobject_set_name); 290EXPORT_SYMBOL(kobject_set_name);
304 291
305
306/** 292/**
307 * kobject_rename - change the name of an object 293 * kobject_rename - change the name of an object
308 * @kobj: object in question. 294 * @kobj: object in question.
@@ -338,7 +324,7 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
338 /* Note : if we want to send the new name alone, not the full path, 324 /* Note : if we want to send the new name alone, not the full path,
339 * we could probably use kobject_name(kobj); */ 325 * we could probably use kobject_name(kobj); */
340 326
341 error = sysfs_rename_dir(kobj, kobj->parent->sd, new_name); 327 error = sysfs_rename_dir(kobj, new_name);
342 328
343 /* This function is mostly/only used for network interface. 329 /* This function is mostly/only used for network interface.
344 * Some hotplug package track interfaces by their name and 330 * Some hotplug package track interfaces by their name and
@@ -355,27 +341,6 @@ out:
355} 341}
356 342
357/** 343/**
358 * kobject_rename - change the name of an object
359 * @kobj: object in question.
360 * @new_parent: object's new parent
361 * @new_name: object's new name
362 */
363
364int kobject_shadow_rename(struct kobject *kobj,
365 struct sysfs_dirent *new_parent, const char *new_name)
366{
367 int error = 0;
368
369 kobj = kobject_get(kobj);
370 if (!kobj)
371 return -EINVAL;
372 error = sysfs_rename_dir(kobj, new_parent, new_name);
373 kobject_put(kobj);
374
375 return error;
376}
377
378/**
379 * kobject_move - move object to another parent 344 * kobject_move - move object to another parent
380 * @kobj: object in question. 345 * @kobj: object in question.
381 * @new_parent: object's new parent (can be NULL) 346 * @new_parent: object's new parent (can be NULL)
@@ -477,13 +442,16 @@ void kobject_cleanup(struct kobject * kobj)
477 struct kobj_type * t = get_ktype(kobj); 442 struct kobj_type * t = get_ktype(kobj);
478 struct kset * s = kobj->kset; 443 struct kset * s = kobj->kset;
479 struct kobject * parent = kobj->parent; 444 struct kobject * parent = kobj->parent;
445 const char *name = kobj->k_name;
480 446
481 pr_debug("kobject %s: cleaning up\n",kobject_name(kobj)); 447 pr_debug("kobject %s: cleaning up\n",kobject_name(kobj));
482 if (kobj->k_name != kobj->name) 448 if (t && t->release) {
483 kfree(kobj->k_name);
484 kobj->k_name = NULL;
485 if (t && t->release)
486 t->release(kobj); 449 t->release(kobj);
450 /* If we have a release function, we can guess that this was
451 * not a statically allocated kobject, so we should be safe to
452 * free the name */
453 kfree(name);
454 }
487 if (s) 455 if (s)
488 kset_put(s); 456 kset_put(s);
489 kobject_put(parent); 457 kobject_put(parent);
@@ -651,11 +619,6 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name)
651 return ret; 619 return ret;
652} 620}
653 621
654void subsystem_init(struct kset *s)
655{
656 kset_init(s);
657}
658
659int subsystem_register(struct kset *s) 622int subsystem_register(struct kset *s)
660{ 623{
661 return kset_register(s); 624 return kset_register(s);
@@ -679,9 +642,9 @@ int subsys_create_file(struct kset *s, struct subsys_attribute *a)
679 if (!s || !a) 642 if (!s || !a)
680 return -EINVAL; 643 return -EINVAL;
681 644
682 if (subsys_get(s)) { 645 if (kset_get(s)) {
683 error = sysfs_create_file(&s->kobj, &a->attr); 646 error = sysfs_create_file(&s->kobj, &a->attr);
684 subsys_put(s); 647 kset_put(s);
685 } 648 }
686 return error; 649 return error;
687} 650}
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index e06a8dcec0f0..2e4eae5b0824 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -22,31 +22,62 @@
22#include <linux/kobject.h> 22#include <linux/kobject.h>
23#include <net/sock.h> 23#include <net/sock.h>
24 24
25#define BUFFER_SIZE 2048 /* buffer for the variables */
26#define NUM_ENVP 32 /* number of env pointers */
27 25
28/* the strings here must match the enum in include/linux/kobject.h */
29const char *kobject_actions[] = {
30 "add",
31 "remove",
32 "change",
33 "move",
34 "online",
35 "offline",
36};
37
38#if defined(CONFIG_HOTPLUG)
39u64 uevent_seqnum; 26u64 uevent_seqnum;
40char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug"; 27char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH;
41static DEFINE_SPINLOCK(sequence_lock); 28static DEFINE_SPINLOCK(sequence_lock);
42#if defined(CONFIG_NET) 29#if defined(CONFIG_NET)
43static struct sock *uevent_sock; 30static struct sock *uevent_sock;
44#endif 31#endif
45 32
33/* the strings here must match the enum in include/linux/kobject.h */
34static const char *kobject_actions[] = {
35 [KOBJ_ADD] = "add",
36 [KOBJ_REMOVE] = "remove",
37 [KOBJ_CHANGE] = "change",
38 [KOBJ_MOVE] = "move",
39 [KOBJ_ONLINE] = "online",
40 [KOBJ_OFFLINE] = "offline",
41};
42
43/**
44 * kobject_action_type - translate action string to numeric type
45 *
46 * @buf: buffer containing the action string, newline is ignored
47 * @len: length of buffer
48 * @type: pointer to the location to store the action type
49 *
50 * Returns 0 if the action string was recognized.
51 */
52int kobject_action_type(const char *buf, size_t count,
53 enum kobject_action *type)
54{
55 enum kobject_action action;
56 int ret = -EINVAL;
57
58 if (count && buf[count-1] == '\n')
59 count--;
60
61 if (!count)
62 goto out;
63
64 for (action = 0; action < ARRAY_SIZE(kobject_actions); action++) {
65 if (strncmp(kobject_actions[action], buf, count) != 0)
66 continue;
67 if (kobject_actions[action][count] != '\0')
68 continue;
69 *type = action;
70 ret = 0;
71 break;
72 }
73out:
74 return ret;
75}
76
46/** 77/**
47 * kobject_uevent_env - send an uevent with environmental data 78 * kobject_uevent_env - send an uevent with environmental data
48 * 79 *
49 * @action: action that is happening (usually KOBJ_MOVE) 80 * @action: action that is happening
50 * @kobj: struct kobject that the action is happening to 81 * @kobj: struct kobject that the action is happening to
51 * @envp_ext: pointer to environmental data 82 * @envp_ext: pointer to environmental data
52 * 83 *
@@ -54,36 +85,26 @@ static struct sock *uevent_sock;
54 * corresponding error when it fails. 85 * corresponding error when it fails.
55 */ 86 */
56int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, 87int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
57 char *envp_ext[]) 88 char *envp_ext[])
58{ 89{
59 char **envp; 90 struct kobj_uevent_env *env;
60 char *buffer; 91 const char *action_string = kobject_actions[action];
61 char *scratch;
62 const char *action_string;
63 const char *devpath = NULL; 92 const char *devpath = NULL;
64 const char *subsystem; 93 const char *subsystem;
65 struct kobject *top_kobj; 94 struct kobject *top_kobj;
66 struct kset *kset; 95 struct kset *kset;
67 struct kset_uevent_ops *uevent_ops; 96 struct kset_uevent_ops *uevent_ops;
68 u64 seq; 97 u64 seq;
69 char *seq_buff;
70 int i = 0; 98 int i = 0;
71 int retval = 0; 99 int retval = 0;
72 int j;
73 100
74 pr_debug("%s\n", __FUNCTION__); 101 pr_debug("%s\n", __FUNCTION__);
75 102
76 action_string = kobject_actions[action];
77 if (!action_string) {
78 pr_debug("kobject attempted to send uevent without action_string!\n");
79 return -EINVAL;
80 }
81
82 /* search the kset we belong to */ 103 /* search the kset we belong to */
83 top_kobj = kobj; 104 top_kobj = kobj;
84 while (!top_kobj->kset && top_kobj->parent) { 105 while (!top_kobj->kset && top_kobj->parent)
85 top_kobj = top_kobj->parent; 106 top_kobj = top_kobj->parent;
86 } 107
87 if (!top_kobj->kset) { 108 if (!top_kobj->kset) {
88 pr_debug("kobject attempted to send uevent without kset!\n"); 109 pr_debug("kobject attempted to send uevent without kset!\n");
89 return -EINVAL; 110 return -EINVAL;
@@ -92,7 +113,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
92 kset = top_kobj->kset; 113 kset = top_kobj->kset;
93 uevent_ops = kset->uevent_ops; 114 uevent_ops = kset->uevent_ops;
94 115
95 /* skip the event, if the filter returns zero. */ 116 /* skip the event, if the filter returns zero. */
96 if (uevent_ops && uevent_ops->filter) 117 if (uevent_ops && uevent_ops->filter)
97 if (!uevent_ops->filter(kset, kobj)) { 118 if (!uevent_ops->filter(kset, kobj)) {
98 pr_debug("kobject filter function caused the event to drop!\n"); 119 pr_debug("kobject filter function caused the event to drop!\n");
@@ -109,18 +130,11 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
109 return 0; 130 return 0;
110 } 131 }
111 132
112 /* environment index */ 133 /* environment buffer */
113 envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL); 134 env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
114 if (!envp) 135 if (!env)
115 return -ENOMEM; 136 return -ENOMEM;
116 137
117 /* environment values */
118 buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
119 if (!buffer) {
120 retval = -ENOMEM;
121 goto exit;
122 }
123
124 /* complete object path */ 138 /* complete object path */
125 devpath = kobject_get_path(kobj, GFP_KERNEL); 139 devpath = kobject_get_path(kobj, GFP_KERNEL);
126 if (!devpath) { 140 if (!devpath) {
@@ -128,29 +142,29 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
128 goto exit; 142 goto exit;
129 } 143 }
130 144
131 /* event environemnt for helper process only */
132 envp[i++] = "HOME=/";
133 envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
134
135 /* default keys */ 145 /* default keys */
136 scratch = buffer; 146 retval = add_uevent_var(env, "ACTION=%s", action_string);
137 envp [i++] = scratch; 147 if (retval)
138 scratch += sprintf(scratch, "ACTION=%s", action_string) + 1; 148 goto exit;
139 envp [i++] = scratch; 149 retval = add_uevent_var(env, "DEVPATH=%s", devpath);
140 scratch += sprintf (scratch, "DEVPATH=%s", devpath) + 1; 150 if (retval)
141 envp [i++] = scratch; 151 goto exit;
142 scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + 1; 152 retval = add_uevent_var(env, "SUBSYSTEM=%s", subsystem);
143 for (j = 0; envp_ext && envp_ext[j]; j++) 153 if (retval)
144 envp[i++] = envp_ext[j]; 154 goto exit;
145 /* just reserve the space, overwrite it after kset call has returned */ 155
146 envp[i++] = seq_buff = scratch; 156 /* keys passed in from the caller */
147 scratch += strlen("SEQNUM=18446744073709551616") + 1; 157 if (envp_ext) {
158 for (i = 0; envp_ext[i]; i++) {
159 retval = add_uevent_var(env, envp_ext[i]);
160 if (retval)
161 goto exit;
162 }
163 }
148 164
149 /* let the kset specific function add its stuff */ 165 /* let the kset specific function add its stuff */
150 if (uevent_ops && uevent_ops->uevent) { 166 if (uevent_ops && uevent_ops->uevent) {
151 retval = uevent_ops->uevent(kset, kobj, 167 retval = uevent_ops->uevent(kset, kobj, env);
152 &envp[i], NUM_ENVP - i, scratch,
153 BUFFER_SIZE - (scratch - buffer));
154 if (retval) { 168 if (retval) {
155 pr_debug ("%s - uevent() returned %d\n", 169 pr_debug ("%s - uevent() returned %d\n",
156 __FUNCTION__, retval); 170 __FUNCTION__, retval);
@@ -158,11 +172,13 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
158 } 172 }
159 } 173 }
160 174
161 /* we will send an event, request a new sequence number */ 175 /* we will send an event, so request a new sequence number */
162 spin_lock(&sequence_lock); 176 spin_lock(&sequence_lock);
163 seq = ++uevent_seqnum; 177 seq = ++uevent_seqnum;
164 spin_unlock(&sequence_lock); 178 spin_unlock(&sequence_lock);
165 sprintf(seq_buff, "SEQNUM=%llu", (unsigned long long)seq); 179 retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)seq);
180 if (retval)
181 goto exit;
166 182
167#if defined(CONFIG_NET) 183#if defined(CONFIG_NET)
168 /* send netlink message */ 184 /* send netlink message */
@@ -172,17 +188,19 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
172 188
173 /* allocate message with the maximum possible size */ 189 /* allocate message with the maximum possible size */
174 len = strlen(action_string) + strlen(devpath) + 2; 190 len = strlen(action_string) + strlen(devpath) + 2;
175 skb = alloc_skb(len + BUFFER_SIZE, GFP_KERNEL); 191 skb = alloc_skb(len + env->buflen, GFP_KERNEL);
176 if (skb) { 192 if (skb) {
193 char *scratch;
194
177 /* add header */ 195 /* add header */
178 scratch = skb_put(skb, len); 196 scratch = skb_put(skb, len);
179 sprintf(scratch, "%s@%s", action_string, devpath); 197 sprintf(scratch, "%s@%s", action_string, devpath);
180 198
181 /* copy keys to our continuous event payload buffer */ 199 /* copy keys to our continuous event payload buffer */
182 for (i = 2; envp[i]; i++) { 200 for (i = 0; i < env->envp_idx; i++) {
183 len = strlen(envp[i]) + 1; 201 len = strlen(env->envp[i]) + 1;
184 scratch = skb_put(skb, len); 202 scratch = skb_put(skb, len);
185 strcpy(scratch, envp[i]); 203 strcpy(scratch, env->envp[i]);
186 } 204 }
187 205
188 NETLINK_CB(skb).dst_group = 1; 206 NETLINK_CB(skb).dst_group = 1;
@@ -198,13 +216,19 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
198 argv [0] = uevent_helper; 216 argv [0] = uevent_helper;
199 argv [1] = (char *)subsystem; 217 argv [1] = (char *)subsystem;
200 argv [2] = NULL; 218 argv [2] = NULL;
201 call_usermodehelper (argv[0], argv, envp, UMH_WAIT_EXEC); 219 retval = add_uevent_var(env, "HOME=/");
220 if (retval)
221 goto exit;
222 retval = add_uevent_var(env, "PATH=/sbin:/bin:/usr/sbin:/usr/bin");
223 if (retval)
224 goto exit;
225
226 call_usermodehelper (argv[0], argv, env->envp, UMH_WAIT_EXEC);
202 } 227 }
203 228
204exit: 229exit:
205 kfree(devpath); 230 kfree(devpath);
206 kfree(buffer); 231 kfree(env);
207 kfree(envp);
208 return retval; 232 return retval;
209} 233}
210 234
@@ -213,7 +237,7 @@ EXPORT_SYMBOL_GPL(kobject_uevent_env);
213/** 237/**
214 * kobject_uevent - notify userspace by ending an uevent 238 * kobject_uevent - notify userspace by ending an uevent
215 * 239 *
216 * @action: action that is happening (usually KOBJ_ADD and KOBJ_REMOVE) 240 * @action: action that is happening
217 * @kobj: struct kobject that the action is happening to 241 * @kobj: struct kobject that the action is happening to
218 * 242 *
219 * Returns 0 if kobject_uevent() is completed with success or the 243 * Returns 0 if kobject_uevent() is completed with success or the
@@ -227,52 +251,38 @@ int kobject_uevent(struct kobject *kobj, enum kobject_action action)
227EXPORT_SYMBOL_GPL(kobject_uevent); 251EXPORT_SYMBOL_GPL(kobject_uevent);
228 252
229/** 253/**
230 * add_uevent_var - helper for creating event variables 254 * add_uevent_var - add key value string to the environment buffer
231 * @envp: Pointer to table of environment variables, as passed into 255 * @env: environment buffer structure
232 * uevent() method. 256 * @format: printf format for the key=value pair
233 * @num_envp: Number of environment variable slots available, as
234 * passed into uevent() method.
235 * @cur_index: Pointer to current index into @envp. It should be
236 * initialized to 0 before the first call to add_uevent_var(),
237 * and will be incremented on success.
238 * @buffer: Pointer to buffer for environment variables, as passed
239 * into uevent() method.
240 * @buffer_size: Length of @buffer, as passed into uevent() method.
241 * @cur_len: Pointer to current length of space used in @buffer.
242 * Should be initialized to 0 before the first call to
243 * add_uevent_var(), and will be incremented on success.
244 * @format: Format for creating environment variable (of the form
245 * "XXX=%x") for snprintf().
246 * 257 *
247 * Returns 0 if environment variable was added successfully or -ENOMEM 258 * Returns 0 if environment variable was added successfully or -ENOMEM
248 * if no space was available. 259 * if no space was available.
249 */ 260 */
250int add_uevent_var(char **envp, int num_envp, int *cur_index, 261int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...)
251 char *buffer, int buffer_size, int *cur_len,
252 const char *format, ...)
253{ 262{
254 va_list args; 263 va_list args;
264 int len;
255 265
256 /* 266 if (env->envp_idx >= ARRAY_SIZE(env->envp)) {
257 * We check against num_envp - 1 to make sure there is at 267 printk(KERN_ERR "add_uevent_var: too many keys\n");
258 * least one slot left after we return, since kobject_uevent() 268 WARN_ON(1);
259 * needs to set the last slot to NULL.
260 */
261 if (*cur_index >= num_envp - 1)
262 return -ENOMEM; 269 return -ENOMEM;
263 270 }
264 envp[*cur_index] = buffer + *cur_len;
265 271
266 va_start(args, format); 272 va_start(args, format);
267 *cur_len += vsnprintf(envp[*cur_index], 273 len = vsnprintf(&env->buf[env->buflen],
268 max(buffer_size - *cur_len, 0), 274 sizeof(env->buf) - env->buflen,
269 format, args) + 1; 275 format, args);
270 va_end(args); 276 va_end(args);
271 277
272 if (*cur_len > buffer_size) 278 if (len >= (sizeof(env->buf) - env->buflen)) {
279 printk(KERN_ERR "add_uevent_var: buffer size too small\n");
280 WARN_ON(1);
273 return -ENOMEM; 281 return -ENOMEM;
282 }
274 283
275 (*cur_index)++; 284 env->envp[env->envp_idx++] = &env->buf[env->buflen];
285 env->buflen += len + 1;
276 return 0; 286 return 0;
277} 287}
278EXPORT_SYMBOL_GPL(add_uevent_var); 288EXPORT_SYMBOL_GPL(add_uevent_var);
@@ -293,5 +303,3 @@ static int __init kobject_uevent_init(void)
293 303
294postcore_initcall(kobject_uevent_init); 304postcore_initcall(kobject_uevent_init);
295#endif 305#endif
296
297#endif /* CONFIG_HOTPLUG */
diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c
index f094a0879c16..9ef07eda2c43 100644
--- a/net/atm/atm_sysfs.c
+++ b/net/atm/atm_sysfs.c
@@ -105,10 +105,9 @@ static struct class_device_attribute *atm_attrs[] = {
105 NULL 105 NULL
106}; 106};
107 107
108static int atm_uevent(struct class_device *cdev, char **envp, int num_envp, char *buf, int size) 108static int atm_uevent(struct class_device *cdev, struct kobj_uevent_env *env)
109{ 109{
110 struct atm_dev *adev; 110 struct atm_dev *adev;
111 int i = 0, len = 0;
112 111
113 if (!cdev) 112 if (!cdev)
114 return -ENODEV; 113 return -ENODEV;
@@ -117,11 +116,9 @@ static int atm_uevent(struct class_device *cdev, char **envp, int num_envp, char
117 if (!adev) 116 if (!adev)
118 return -ENODEV; 117 return -ENODEV;
119 118
120 if (add_uevent_var(envp, num_envp, &i, buf, size, &len, 119 if (add_uevent_var(env, "NAME=%s%d", adev->type, adev->number))
121 "NAME=%s%d", adev->type, adev->number))
122 return -ENOMEM; 120 return -ENOMEM;
123 121
124 envp[i] = NULL;
125 return 0; 122 return 0;
126} 123}
127 124
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index c65f54e0e27f..3312e8f2abe4 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -435,7 +435,7 @@ int br_sysfs_addbr(struct net_device *dev)
435 err = kobject_register(&br->ifobj); 435 err = kobject_register(&br->ifobj);
436 if (err) { 436 if (err) {
437 pr_info("%s: can't add kobject (directory) %s/%s\n", 437 pr_info("%s: can't add kobject (directory) %s/%s\n",
438 __FUNCTION__, dev->name, br->ifobj.name); 438 __FUNCTION__, dev->name, kobject_name(&br->ifobj));
439 goto out3; 439 goto out3;
440 } 440 }
441 return 0; 441 return 0;
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 909a03d6c0e9..6628e457ddc0 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -396,28 +396,22 @@ static struct attribute_group wireless_group = {
396#endif /* CONFIG_SYSFS */ 396#endif /* CONFIG_SYSFS */
397 397
398#ifdef CONFIG_HOTPLUG 398#ifdef CONFIG_HOTPLUG
399static int netdev_uevent(struct device *d, char **envp, 399static int netdev_uevent(struct device *d, struct kobj_uevent_env *env)
400 int num_envp, char *buf, int size)
401{ 400{
402 struct net_device *dev = to_net_dev(d); 401 struct net_device *dev = to_net_dev(d);
403 int retval, len = 0, i = 0; 402 int retval;
404 403
405 /* pass interface to uevent. */ 404 /* pass interface to uevent. */
406 retval = add_uevent_var(envp, num_envp, &i, 405 retval = add_uevent_var(env, "INTERFACE=%s", dev->name);
407 buf, size, &len,
408 "INTERFACE=%s", dev->name);
409 if (retval) 406 if (retval)
410 goto exit; 407 goto exit;
411 408
412 /* pass ifindex to uevent. 409 /* pass ifindex to uevent.
413 * ifindex is useful as it won't change (interface name may change) 410 * ifindex is useful as it won't change (interface name may change)
414 * and is what RtNetlink uses natively. */ 411 * and is what RtNetlink uses natively. */
415 retval = add_uevent_var(envp, num_envp, &i, 412 retval = add_uevent_var(env, "IFINDEX=%d", dev->ifindex);
416 buf, size, &len,
417 "IFINDEX=%d", dev->ifindex);
418 413
419exit: 414exit:
420 envp[i] = NULL;
421 return retval; 415 return retval;
422} 416}
423#endif 417#endif
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 2d5d2255a27c..29f820e18251 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -53,8 +53,7 @@ static void wiphy_dev_release(struct device *dev)
53} 53}
54 54
55#ifdef CONFIG_HOTPLUG 55#ifdef CONFIG_HOTPLUG
56static int wiphy_uevent(struct device *dev, char **envp, 56static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
57 int num_envp, char *buf, int size)
58{ 57{
59 /* TODO, we probably need stuff here */ 58 /* TODO, we probably need stuff here */
60 return 0; 59 return 0;
diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c
index 64d163914335..f84f3e505788 100644
--- a/sound/aoa/soundbus/core.c
+++ b/sound/aoa/soundbus/core.c
@@ -56,13 +56,12 @@ static int soundbus_probe(struct device *dev)
56} 56}
57 57
58 58
59static int soundbus_uevent(struct device *dev, char **envp, int num_envp, 59static int soundbus_uevent(struct device *dev, struct kobj_uevent_env *env)
60 char *buffer, int buffer_size)
61{ 60{
62 struct soundbus_dev * soundbus_dev; 61 struct soundbus_dev * soundbus_dev;
63 struct of_device * of; 62 struct of_device * of;
64 const char *compat; 63 const char *compat;
65 int retval = 0, i = 0, length = 0; 64 int retval = 0;
66 int cplen, seen = 0; 65 int cplen, seen = 0;
67 66
68 if (!dev) 67 if (!dev)
@@ -75,15 +74,11 @@ static int soundbus_uevent(struct device *dev, char **envp, int num_envp,
75 of = &soundbus_dev->ofdev; 74 of = &soundbus_dev->ofdev;
76 75
77 /* stuff we want to pass to /sbin/hotplug */ 76 /* stuff we want to pass to /sbin/hotplug */
78 retval = add_uevent_var(envp, num_envp, &i, 77 retval = add_uevent_var(env, "OF_NAME=%s", of->node->name);
79 buffer, buffer_size, &length,
80 "OF_NAME=%s", of->node->name);
81 if (retval) 78 if (retval)
82 return retval; 79 return retval;
83 80
84 retval = add_uevent_var(envp, num_envp, &i, 81 retval = add_uevent_var(env, "OF_TYPE=%s", of->node->type);
85 buffer, buffer_size, &length,
86 "OF_TYPE=%s", of->node->type);
87 if (retval) 82 if (retval)
88 return retval; 83 return retval;
89 84
@@ -93,27 +88,19 @@ static int soundbus_uevent(struct device *dev, char **envp, int num_envp,
93 88
94 compat = of_get_property(of->node, "compatible", &cplen); 89 compat = of_get_property(of->node, "compatible", &cplen);
95 while (compat && cplen > 0) { 90 while (compat && cplen > 0) {
96 int tmp = length; 91 int tmp = env->buflen;
97 retval = add_uevent_var(envp, num_envp, &i, 92 retval = add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat);
98 buffer, buffer_size, &length,
99 "OF_COMPATIBLE_%d=%s", seen, compat);
100 if (retval) 93 if (retval)
101 return retval; 94 return retval;
102 compat += length - tmp; 95 compat += env->buflen - tmp;
103 cplen -= length - tmp; 96 cplen -= env->buflen - tmp;
104 seen += 1; 97 seen += 1;
105 } 98 }
106 99
107 retval = add_uevent_var(envp, num_envp, &i, 100 retval = add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen);
108 buffer, buffer_size, &length,
109 "OF_COMPATIBLE_N=%d", seen);
110 if (retval) 101 if (retval)
111 return retval; 102 return retval;
112 retval = add_uevent_var(envp, num_envp, &i, 103 retval = add_uevent_var(env, "MODALIAS=%s", soundbus_dev->modalias);
113 buffer, buffer_size, &length,
114 "MODALIAS=%s", soundbus_dev->modalias);
115
116 envp[i] = NULL;
117 104
118 return retval; 105 return retval;
119} 106}