5429a0e4b0a8d3866902d31ef0cd29a7efd8d986
[openwrt.git] / target / linux / generic-2.6 / patches / 000-reinstate-devfs.patch
1 diff -urN linux-2.6.19.old/arch/cris/arch-v10/kernel/debugport.c linux-2.6.19.dev/arch/cris/arch-v10/kernel/debugport.c
2 --- linux-2.6.19.old/arch/cris/arch-v10/kernel/debugport.c      2006-11-29 22:57:37.000000000 +0100
3 +++ linux-2.6.19.dev/arch/cris/arch-v10/kernel/debugport.c      2006-12-14 03:12:59.000000000 +0100
4 @@ -540,7 +540,7 @@
5         dummy_driver.init_termios = tty_std_termios;
6         dummy_driver.init_termios.c_cflag =
7                 B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
8 -       dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
9 +       dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
10  
11         dummy_driver.open = dummy_open;
12         dummy_driver.close = dummy_close;
13 diff -urN linux-2.6.19.old/arch/cris/arch-v32/kernel/debugport.c linux-2.6.19.dev/arch/cris/arch-v32/kernel/debugport.c
14 --- linux-2.6.19.old/arch/cris/arch-v32/kernel/debugport.c      2006-11-29 22:57:37.000000000 +0100
15 +++ linux-2.6.19.dev/arch/cris/arch-v32/kernel/debugport.c      2006-12-14 03:12:59.000000000 +0100
16 @@ -352,7 +352,7 @@
17         dummy_driver.init_termios = tty_std_termios;
18         dummy_driver.init_termios.c_cflag =
19                 B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
20 -       dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
21 +       dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
22  
23         dummy_driver.open = dummy_open;
24         dummy_driver.close = dummy_close;
25 diff -urN linux-2.6.19.old/arch/i386/kernel/microcode.c linux-2.6.19.dev/arch/i386/kernel/microcode.c
26 --- linux-2.6.19.old/arch/i386/kernel/microcode.c       2006-11-29 22:57:37.000000000 +0100
27 +++ linux-2.6.19.dev/arch/i386/kernel/microcode.c       2006-12-14 03:12:59.000000000 +0100
28 @@ -460,6 +460,7 @@
29  static struct miscdevice microcode_dev = {
30         .minor          = MICROCODE_MINOR,
31         .name           = "microcode",
32 +       .devfs_name     = "cpu/microcode",
33         .fops           = &microcode_fops,
34  };
35  
36 diff -urN linux-2.6.19.old/arch/ppc/4xx_io/serial_sicc.c linux-2.6.19.dev/arch/ppc/4xx_io/serial_sicc.c
37 --- linux-2.6.19.old/arch/ppc/4xx_io/serial_sicc.c      2006-11-29 22:57:37.000000000 +0100
38 +++ linux-2.6.19.dev/arch/ppc/4xx_io/serial_sicc.c      2006-12-14 03:12:59.000000000 +0100
39 @@ -1757,7 +1757,7 @@
40      siccnormal_driver->subtype = SERIAL_TYPE_NORMAL;
41      siccnormal_driver->init_termios = tty_std_termios;
42      siccnormal_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
43 -    siccnormal_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
44 +    siccnormal_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
45      tty_set_operations(siccnormal_driver, &sicc_ops);
46  
47      if (tty_register_driver(siccnormal_driver))
48 diff -urN linux-2.6.19.old/arch/sparc64/solaris/socksys.c linux-2.6.19.dev/arch/sparc64/solaris/socksys.c
49 --- linux-2.6.19.old/arch/sparc64/solaris/socksys.c     2006-11-29 22:57:37.000000000 +0100
50 +++ linux-2.6.19.dev/arch/sparc64/solaris/socksys.c     2006-12-14 03:12:59.000000000 +0100
51 @@ -26,6 +26,7 @@
52  #include <linux/slab.h>
53  #include <linux/syscalls.h>
54  #include <linux/in.h>
55 +#include <linux/devfs_fs_kernel.h>
56  
57  #include <net/sock.h>
58  
59 @@ -188,6 +189,8 @@
60                 return ret;
61         }
62  
63 +       devfs_mk_cdev(MKDEV(30, 0), S_IFCHR|S_IRUSR|S_IWUSR, "socksys");
64 +
65         file = fcheck(ret);
66         /* N.B. Is this valid? Suppose the f_ops are in a module ... */
67         socksys_file_ops = *file->f_op;
68 @@ -202,4 +205,5 @@
69  {
70         if (unregister_chrdev(30, "socksys"))
71                 printk ("Couldn't unregister socksys character device\n");
72 +       devfs_remove ("socksys");
73  }
74 diff -urN linux-2.6.19.old/arch/um/drivers/line.c linux-2.6.19.dev/arch/um/drivers/line.c
75 --- linux-2.6.19.old/arch/um/drivers/line.c     2006-11-29 22:57:37.000000000 +0100
76 +++ linux-2.6.19.dev/arch/um/drivers/line.c     2006-12-14 03:12:59.000000000 +0100
77 @@ -8,6 +8,7 @@
78  #include "linux/list.h"
79  #include "linux/kd.h"
80  #include "linux/interrupt.h"
81 +#include "linux/devfs_fs_kernel.h"
82  #include "asm/uaccess.h"
83  #include "chan_kern.h"
84  #include "irq_user.h"
85 @@ -653,6 +654,7 @@
86  
87         driver->driver_name = line_driver->name;
88         driver->name = line_driver->device_name;
89 +       driver->devfs_name = line_driver->devfs_name;
90         driver->major = line_driver->major;
91         driver->minor_start = line_driver->minor_start;
92         driver->type = line_driver->type;
93 diff -urN linux-2.6.19.old/arch/um/drivers/ssl.c linux-2.6.19.dev/arch/um/drivers/ssl.c
94 --- linux-2.6.19.old/arch/um/drivers/ssl.c      2006-11-29 22:57:37.000000000 +0100
95 +++ linux-2.6.19.dev/arch/um/drivers/ssl.c      2006-12-14 03:12:59.000000000 +0100
96 @@ -53,6 +53,7 @@
97  static struct line_driver driver = {
98         .name                   = "UML serial line",
99         .device_name            = "ttyS",
100 +       .devfs_name             = "tts/",
101         .major                  = TTY_MAJOR,
102         .minor_start            = 64,
103         .type                   = TTY_DRIVER_TYPE_SERIAL,
104 diff -urN linux-2.6.19.old/arch/um/drivers/stdio_console.c linux-2.6.19.dev/arch/um/drivers/stdio_console.c
105 --- linux-2.6.19.old/arch/um/drivers/stdio_console.c    2006-11-29 22:57:37.000000000 +0100
106 +++ linux-2.6.19.dev/arch/um/drivers/stdio_console.c    2006-12-14 03:12:59.000000000 +0100
107 @@ -59,6 +59,7 @@
108  static struct line_driver driver = {
109         .name                   = "UML console",
110         .device_name            = "tty",
111 +       .devfs_name             = "vc/",
112         .major                  = TTY_MAJOR,
113         .minor_start            = 0,
114         .type                   = TTY_DRIVER_TYPE_CONSOLE,
115 diff -urN linux-2.6.19.old/arch/um/drivers/ubd_kern.c linux-2.6.19.dev/arch/um/drivers/ubd_kern.c
116 --- linux-2.6.19.old/arch/um/drivers/ubd_kern.c 2006-11-29 22:57:37.000000000 +0100
117 +++ linux-2.6.19.dev/arch/um/drivers/ubd_kern.c 2006-12-14 03:12:59.000000000 +0100
118 @@ -24,6 +24,7 @@
119  #include "linux/blkdev.h"
120  #include "linux/hdreg.h"
121  #include "linux/init.h"
122 +#include "linux/devfs_fs_kernel.h"
123  #include "linux/cdrom.h"
124  #include "linux/proc_fs.h"
125  #include "linux/ctype.h"
126 @@ -645,10 +646,14 @@
127         disk->first_minor = unit << UBD_SHIFT;
128         disk->fops = &ubd_blops;
129         set_capacity(disk, size / 512);
130 -       if(major == MAJOR_NR)
131 +       if(major == MAJOR_NR){
132                 sprintf(disk->disk_name, "ubd%c", 'a' + unit);
133 -       else
134 +               sprintf(disk->devfs_name, "ubd/disc%d", unit);
135 +       }
136 +       else {
137                 sprintf(disk->disk_name, "ubd_fake%d", unit);
138 +               sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
139 +       }
140  
141         /* sysfs register (not for ide fake devices) */
142         if (major == MAJOR_NR) {
143 @@ -853,6 +864,7 @@
144  {
145          int i;
146  
147 +       devfs_mk_dir("ubd");
148         if (register_blkdev(MAJOR_NR, "ubd"))
149                 return -1;
150  
151 @@ -866,6 +878,7 @@
152                 char name[sizeof("ubd_nnn\0")];
153  
154                 snprintf(name, sizeof(name), "ubd_%d", fake_major);
155 +               devfs_mk_dir(name);
156                 if (register_blkdev(fake_major, "ubd"))
157                         return -1;
158         }
159 diff -urN linux-2.6.19.old/arch/um/include/line.h linux-2.6.19.dev/arch/um/include/line.h
160 --- linux-2.6.19.old/arch/um/include/line.h     2006-11-29 22:57:37.000000000 +0100
161 +++ linux-2.6.19.dev/arch/um/include/line.h     2006-12-14 03:12:59.000000000 +0100
162 @@ -17,6 +17,7 @@
163  struct line_driver {
164         char *name;
165         char *device_name;
166 +       char *devfs_name;
167         short major;
168         short minor_start;
169         short type;
170 diff -urN linux-2.6.19.old/Documentation/Changes linux-2.6.19.dev/Documentation/Changes
171 --- linux-2.6.19.old/Documentation/Changes      2006-11-29 22:57:37.000000000 +0100
172 +++ linux-2.6.19.dev/Documentation/Changes      2006-12-14 03:12:59.000000000 +0100
173 @@ -180,8 +180,8 @@
174  --------------------
175  
176  A driver has been added to allow updating of Intel IA32 microcode,
177 -accessible as a normal (misc) character device.  If you are not using
178 -udev you may need to:
179 +accessible as both a devfs regular file and as a normal (misc)
180 +character device.  If you are not using devfs you may need to:
181  
182  mkdir /dev/cpu
183  mknod /dev/cpu/microcode c 10 184
184 @@ -200,9 +200,7 @@
185  udev
186  ----
187  udev is a userspace application for populating /dev dynamically with
188 -only entries for devices actually present.  udev replaces the basic
189 -functionality of devfs, while allowing persistant device naming for
190 -devices.
191 +only entries for devices actually present. udev replaces devfs.
192  
193  FUSE
194  ----
195 @@ -232,13 +230,18 @@
196  enable it to operate over diverse media layers.  If you use PPP,
197  upgrade pppd to at least 2.4.0.
198  
199 -If you are not using udev, you must have the device file /dev/ppp
200 +If you are not using devfs, you must have the device file /dev/ppp
201  which can be made by:
202  
203  mknod /dev/ppp c 108 0
204  
205  as root.
206  
207 +If you use devfsd and build ppp support as modules, you will need
208 +the following in your /etc/devfsd.conf file:
209 +
210 +LOOKUP PPP     MODLOAD
211 +
212  Isdn4k-utils
213  ------------
214  
215 diff -urN linux-2.6.19.old/Documentation/DocBook/kernel-api.tmpl linux-2.6.19.dev/Documentation/DocBook/kernel-api.tmpl
216 --- linux-2.6.19.old/Documentation/DocBook/kernel-api.tmpl      2006-11-29 22:57:37.000000000 +0100
217 +++ linux-2.6.19.dev/Documentation/DocBook/kernel-api.tmpl      2006-12-14 03:12:59.000000000 +0100
218 @@ -84,6 +84,9 @@
219  !Ekernel/rcupdate.c
220       </sect1>
221  
222 +  <chapter id="devfs">
223 +     <title>The Device File System</title>
224 +!Efs/devfs/base.c
225    </chapter>
226  
227    <chapter id="adt">
228 diff -urN linux-2.6.19.old/Documentation/filesystems/devfs/boot-options linux-2.6.19.dev/Documentation/filesystems/devfs/boot-options
229 --- linux-2.6.19.old/Documentation/filesystems/devfs/boot-options       1970-01-01 01:00:00.000000000 +0100
230 +++ linux-2.6.19.dev/Documentation/filesystems/devfs/boot-options       2006-12-14 03:12:59.000000000 +0100
231 @@ -0,0 +1,65 @@
232 +/* -*- auto-fill -*-                                                         */
233 +
234 +               Device File System (devfs) Boot Options
235 +
236 +               Richard Gooch <rgooch@atnf.csiro.au>
237 +
238 +                             18-AUG-2001
239 +
240 +
241 +When CONFIG_DEVFS_DEBUG is enabled, you can pass several boot options
242 +to the kernel to debug devfs. The boot options are prefixed by
243 +"devfs=", and are separated by commas. Spaces are not allowed. The
244 +syntax looks like this:
245 +
246 +devfs=<option1>,<option2>,<option3>
247 +
248 +and so on. For example, if you wanted to turn on debugging for module
249 +load requests and device registration, you would do:
250 +
251 +devfs=dmod,dreg
252 +
253 +You may prefix "no" to any option. This will invert the option.
254 +
255 +
256 +Debugging Options
257 +=================
258 +
259 +These requires CONFIG_DEVFS_DEBUG to be enabled.
260 +Note that all debugging options have 'd' as the first character. By
261 +default all options are off. All debugging output is sent to the
262 +kernel logs. The debugging options do not take effect until the devfs
263 +version message appears (just prior to the root filesystem being
264 +mounted).
265 +
266 +These are the options:
267 +
268 +dmod           print module load requests to <request_module>
269 +
270 +dreg           print device register requests to <devfs_register>
271 +
272 +dunreg         print device unregister requests to <devfs_unregister>
273 +
274 +dchange                print device change requests to <devfs_set_flags>
275 +
276 +dilookup       print inode lookup requests
277 +
278 +diget          print VFS inode allocations
279 +
280 +diunlink       print inode unlinks
281 +
282 +dichange       print inode changes
283 +
284 +dimknod                print calls to mknod(2)
285 +
286 +dall           some debugging turned on
287 +
288 +
289 +Other Options
290 +=============
291 +
292 +These control the default behaviour of devfs. The options are:
293 +
294 +mount          mount devfs onto /dev at boot time
295 +
296 +only           disable non-devfs device nodes for devfs-capable drivers
297 diff -urN linux-2.6.19.old/Documentation/filesystems/devfs/ChangeLog linux-2.6.19.dev/Documentation/filesystems/devfs/ChangeLog
298 --- linux-2.6.19.old/Documentation/filesystems/devfs/ChangeLog  1970-01-01 01:00:00.000000000 +0100
299 +++ linux-2.6.19.dev/Documentation/filesystems/devfs/ChangeLog  2006-12-14 03:12:59.000000000 +0100
300 @@ -0,0 +1,1977 @@
301 +/* -*- auto-fill -*-                                                         */
302 +===============================================================================
303 +Changes for patch v1
304 +
305 +- creation of devfs
306 +
307 +- modified miscellaneous character devices to support devfs
308 +===============================================================================
309 +Changes for patch v2
310 +
311 +- bug fix with manual inode creation
312 +===============================================================================
313 +Changes for patch v3
314 +
315 +- bugfixes
316 +
317 +- documentation improvements
318 +
319 +- created a couple of scripts (one to save&restore a devfs and the
320 +  other to set up compatibility symlinks)
321 +
322 +- devfs support for SCSI discs. New name format is: sd_hHcCiIlL
323 +===============================================================================
324 +Changes for patch v4
325 +
326 +- bugfix for the directory reading code
327 +
328 +- bugfix for compilation with kerneld
329 +
330 +- devfs support for generic hard discs
331 +
332 +- rationalisation of the various watchdog drivers
333 +===============================================================================
334 +Changes for patch v5
335 +
336 +- support for mounting directly from entries in the devfs (it doesn't
337 +  need to be mounted to do this), including the root filesystem.
338 +  Mounting of swap partitions also works. Hence, now if you set
339 +  CONFIG_DEVFS_ONLY to 'Y' then you won't be able to access your discs
340 +  via ordinary device nodes. Naturally, the default is 'N' so that you
341 +  can still use your old device nodes.  If you want to mount from devfs
342 +  entries, make sure you use: append = "root=/dev/sd_..." in your
343 +  lilo.conf. It seems LILO looks for the device number (major&minor)
344 +  and writes that into the kernel image :-( 
345 +
346 +- support for character memory devices (/dev/null, /dev/zero, /dev/full
347 +  and so on). Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
348 +===============================================================================
349 +Changes for patch v6
350 +
351 +- support for subdirectories
352 +
353 +- support for symbolic links (created by devfs_mk_symlink(), no
354 +  support yet for creation via symlink(2))
355 +
356 +- SCSI disc naming now cast in stone, with the format:
357 +  /dev/sd/c0b1t2u3     controller=0, bus=1, ID=2, LUN=3, whole disc
358 +  /dev/sd/c0b1t2u3p4   controller=0, bus=1, ID=2, LUN=3, 4th partition
359 +
360 +- loop devices now appear in devfs
361 +
362 +- tty devices, console, serial ports, etc. now appear in devfs
363 +  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
364 +
365 +- bugs with mounting devfs-only devices now fixed
366 +===============================================================================
367 +Changes for patch v7
368 +
369 +- SCSI CD-ROMS, tapes and generic devices now appear in devfs
370 +===============================================================================
371 +Changes for patch v8
372 +
373 +- bugfix with no-rewind SCSI tapes
374 +
375 +- RAMDISCs now appear in devfs
376 +
377 +- better cleaning up of devfs entries created by various modules
378 +
379 +- interface change to <devfs_register>
380 +===============================================================================
381 +Changes for patch v9
382 +
383 +- the v8 patch was corrupted somehow, which would affect the patch for
384 +  linux/fs/filesystems.c
385 +  I've also fixed the v8 patch file on the WWW
386 +
387 +- MetaDevices (/dev/md*) should now appear in devfs
388 +===============================================================================
389 +Changes for patch v10
390 +
391 +- bugfix in meta device support for devfs
392 +
393 +- created this ChangeLog file
394 +
395 +- added devfs support to the floppy driver
396 +
397 +- added support for creating sockets in a devfs
398 +===============================================================================
399 +Changes for patch v11
400 +
401 +- added DEVFS_FL_HIDE_UNREG flag
402 +
403 +- incorporated better patch for ttyname() in libc 5.4.43 from H.J. Lu.
404 +
405 +- interface change to <devfs_mk_symlink>
406 +
407 +- support for creating symlinks with symlink(2)
408 +
409 +- parallel port printer (/dev/lp*) now appears in devfs
410 +===============================================================================
411 +Changes for patch v12
412 +
413 +- added inode check to <devfs_fill_file> function
414 +
415 +- improved devfs support when mounting from devfs
416 +
417 +- added call to <<release>> operation when removing swap areas on
418 +  devfs devices
419 +
420 +- increased NR_SUPER to 128 to support large numbers of devfs mounts
421 +  (for chroot(2) gaols)
422 +
423 +- fixed bug in SCSI disc support: was generating incorrect minors if
424 +  SCSI ID's did not start at 0 and increase by 1
425 +
426 +- support symlink traversal when mounting root
427 +===============================================================================
428 +Changes for patch v13
429 +
430 +- added devfs support to soundcard driver
431 +  Thanks to Eric Dumas <dumas@linux.eu.org> and
432 +  C. Scott Ananian <cananian@alumni.princeton.edu>
433 +
434 +- added devfs support to the joystick driver
435 +
436 +- loop driver now has it's own subdirectory "/dev/loop/"
437 +
438 +- created <devfs_get_flags> and <devfs_set_flags> functions
439 +
440 +- fix problem with SCSI disc compatibility names (sd{a,b,c,d,e,f})
441 +  which assumes ID's start at 0 and increase by 1. Also only create
442 +  devfs entries for SCSI disc partitions which actually exist
443 +  Show new names in partition check
444 +  Thanks to Jakub Jelinek <jj@sunsite.ms.mff.cuni.cz>
445 +===============================================================================
446 +Changes for patch v14
447 +
448 +- bug fix in floppy driver: would not compile without
449 +  CONFIG_DEVFS_FS='Y'
450 +  Thanks to Jurgen Botz <jbotz@nova.botz.org>
451 +
452 +- bug fix in loop driver
453 +  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
454 +
455 +- do not create devfs entries for printers not configured
456 +  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
457 +
458 +- do not create devfs entries for serial ports not present
459 +  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
460 +
461 +- ensure <tty_register_devfs> is exported from tty_io.c
462 +  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
463 +
464 +- allow unregistering of devfs symlink entries
465 +
466 +- fixed bug in SCSI disc naming introduced in last patch version
467 +===============================================================================
468 +Changes for patch v15
469 +
470 +- ported to kernel 2.1.81
471 +===============================================================================
472 +Changes for patch v16
473 +
474 +- created <devfs_set_symlink_destination> function
475 +
476 +- moved DEVFS_SUPER_MAGIC into header file
477 +
478 +- added DEVFS_FL_HIDE flag
479 +
480 +- created <devfs_get_maj_min>
481 +
482 +- created <devfs_get_handle_from_inode>
483 +
484 +- fixed bugs in searching by major&minor
485 +
486 +- changed interface to <devfs_unregister>, <devfs_fill_file> and
487 +  <devfs_find_handle>
488 +
489 +- fixed inode times when symlink created with symlink(2)
490 +
491 +- change tty driver to do auto-creation of devfs entries
492 +  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
493 +
494 +- fixed bug in genhd.c: whole disc (non-SCSI) was not registered to
495 +  devfs
496 +
497 +- updated libc 5.4.43 patch for ttyname()
498 +===============================================================================
499 +Changes for patch v17
500 +
501 +- added CONFIG_DEVFS_TTY_COMPAT
502 +  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
503 +
504 +- bugfix in devfs support for drivers/char/lp.c
505 +  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
506 +
507 +- clean up serial driver so that PCMCIA devices unregister correctly
508 +  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
509 +
510 +- fixed bug in genhd.c: whole disc (non-SCSI) was not registered to
511 +  devfs [was missing in patch v16]
512 +
513 +- updated libc 5.4.43 patch for ttyname() [was missing in patch v16]
514 +
515 +- all SCSI devices now registered in /dev/sg
516 +
517 +- support removal of devfs entries via unlink(2)
518 +===============================================================================
519 +Changes for patch v18
520 +
521 +- added floppy/?u720 floppy entry
522 +
523 +- fixed kerneld support for entries in devfs subdirectories
524 +
525 +- incorporated latest patch for ttyname() in libc 5.4.43 from H.J. Lu.
526 +===============================================================================
527 +Changes for patch v19
528 +
529 +- bug fix when looking up unregistered entries: kerneld was not called
530 +
531 +- fixes for kernel 2.1.86 (now requires 2.1.86)
532 +===============================================================================
533 +Changes for patch v20
534 +
535 +- only create available floppy entries
536 +  Thanks to Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
537 +
538 +- new IDE naming scheme following SCSI format (i.e. /dev/id/c0b0t0u0p1
539 +  instead of /dev/hda1)
540 +  Thanks to Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
541 +
542 +- new XT disc naming scheme following SCSI format (i.e. /dev/xd/c0t0p1
543 +  instead of /dev/xda1)
544 +  Thanks to Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
545 +
546 +- new non-standard CD-ROM names (i.e. /dev/sbp/c#t#)
547 +  Thanks to Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
548 +
549 +- allow symlink traversal when mounting the root filesystem
550 +
551 +- Create entries for MD devices at MD init
552 +  Thanks to Christophe Leroy <christophe.leroy5@capway.com>
553 +===============================================================================
554 +Changes for patch v21
555 +
556 +- ported to kernel 2.1.91
557 +===============================================================================
558 +Changes for patch v22
559 +
560 +- SCSI host number patch ("scsihosts=" kernel option)
561 +  Thanks to Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
562 +===============================================================================
563 +Changes for patch v23
564 +
565 +- Fixed persistence bug with device numbers for manually created
566 +  device files
567 +
568 +- Fixed problem with recreating symlinks with different content
569 +
570 +- Added CONFIG_DEVFS_MOUNT (mount devfs on /dev at boot time)
571 +===============================================================================
572 +Changes for patch v24
573 +
574 +- Switched from CONFIG_KERNELD to CONFIG_KMOD: module autoloading
575 +  should now work again
576 +
577 +- Hide entries which are manually unlinked
578 +
579 +- Always invalidate devfs dentry cache when registering entries
580 +
581 +- Support removal of devfs directories via rmdir(2)
582 +
583 +- Ensure directories created by <devfs_mk_dir> are visible
584 +
585 +- Default no access for "other" for floppy device
586 +===============================================================================
587 +Changes for patch v25
588 +
589 +- Updates to CREDITS file and minor IDE numbering change
590 +  Thanks to Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
591 +
592 +- Invalidate devfs dentry cache when making directories
593 +
594 +- Invalidate devfs dentry cache when removing entries
595 +
596 +- More informative message if root FS mount fails when devfs
597 +  configured
598 +
599 +- Fixed persistence bug with fifos
600 +===============================================================================
601 +Changes for patch v26
602 +
603 +- ported to kernel 2.1.97
604 +
605 +- Changed serial directory from "/dev/serial" to "/dev/tts" and
606 +  "/dev/consoles" to "/dev/vc" to be more friendly to new procps
607 +===============================================================================
608 +Changes for patch v27
609 +
610 +- Added support for IDE4 and IDE5
611 +  Thanks to Andrzej Krzysztofowicz <ankry@green.mif.pg.gda.pl>
612 +
613 +- Documented "scsihosts=" boot parameter
614 +
615 +- Print process command when debugging kerneld/kmod
616 +
617 +- Added debugging for register/unregister/change operations
618 +
619 +- Added "devfs=" boot options
620 +
621 +- Hide unregistered entries by default
622 +===============================================================================
623 +Changes for patch v28
624 +
625 +- No longer lock/unlock superblock in <devfs_put_super> (cope with
626 +  recent VFS interface change)
627 +
628 +- Do not automatically change ownership/protection of /dev/tty
629 +
630 +- Drop negative dentries when they are released
631 +
632 +- Manage dcache more efficiently
633 +===============================================================================
634 +Changes for patch v29
635 +
636 +- Added DEVFS_FL_AUTO_DEVNUM flag
637 +===============================================================================
638 +Changes for patch v30
639 +
640 +- No longer set unnecessary methods
641 +
642 +- Ported to kernel 2.1.99-pre3
643 +===============================================================================
644 +Changes for patch v31
645 +
646 +- Added PID display to <call_kerneld> debugging message
647 +
648 +- Added "diread" and "diwrite" options
649 +
650 +- Ported to kernel 2.1.102
651 +
652 +- Fixed persistence problem with permissions
653 +===============================================================================
654 +Changes for patch v32
655 +
656 +- Fixed devfs support in drivers/block/md.c
657 +===============================================================================
658 +Changes for patch v33
659 +
660 +- Support legacy device nodes
661 +
662 +- Fixed bug where recreated inodes were hidden
663 +
664 +- New IDE naming scheme: everything is under /dev/ide
665 +===============================================================================
666 +Changes for patch v34
667 +
668 +- Improved debugging in <get_vfs_inode>
669 +
670 +- Prevent duplicate calls to <devfs_mk_dir> in SCSI layer
671 +
672 +- No longer free old dentries in <devfs_mk_dir>
673 +
674 +- Free all dentries for a given entry when deleting inodes
675 +===============================================================================
676 +Changes for patch v35
677 +
678 +- Ported to kernel 2.1.105 (sound driver changes)
679 +===============================================================================
680 +Changes for patch v36
681 +
682 +- Fixed sound driver port
683 +===============================================================================
684 +Changes for patch v37
685 +
686 +- Minor documentation tweaks
687 +===============================================================================
688 +Changes for patch v38
689 +
690 +- More documentation tweaks
691 +
692 +- Fix for sound driver port
693 +
694 +- Removed ttyname-patch (grab libc 5.4.44 instead)
695 +
696 +- Ported to kernel 2.1.107-pre2 (loop driver fix)
697 +===============================================================================
698 +Changes for patch v39
699 +
700 +- Ported to kernel 2.1.107 (hd.c hunk broke due to spelling "fixes"). Sigh
701 +
702 +- Removed many #ifdef's, replaced with trickery in include/devfs_fs.h
703 +===============================================================================
704 +Changes for patch v40
705 +
706 +- Fix for sound driver port
707 +
708 +- Limit auto-device numbering to majors 128 to 239
709 +===============================================================================
710 +Changes for patch v41
711 +
712 +- Fixed inode times persistence problem
713 +===============================================================================
714 +Changes for patch v42
715 +
716 +- Ported to kernel 2.1.108 (drivers/scsi/hosts.c hunk broke)
717 +===============================================================================
718 +Changes for patch v43
719 +
720 +- Fixed spelling in <devfs_readlink> debug
721 +
722 +- Fixed bug in <devfs_setup> parsing "dilookup"
723 +
724 +- More #ifdef's removed
725 +
726 +- Supported Sparc keyboard (/dev/kbd)
727 +
728 +- Supported DSP56001 digital signal processor (/dev/dsp56k)
729 +
730 +- Supported Apple Desktop Bus (/dev/adb)
731 +
732 +- Supported Coda network file system (/dev/cfs*)
733 +===============================================================================
734 +Changes for patch v44
735 +
736 +- Fixed devfs inode leak when manually recreating inodes
737 +
738 +- Fixed permission persistence problem when recreating inodes
739 +===============================================================================
740 +Changes for patch v45
741 +
742 +- Ported to kernel 2.1.110
743 +===============================================================================
744 +Changes for patch v46
745 +
746 +- Ported to kernel 2.1.112-pre1
747 +
748 +- Removed harmless "unused variable" compiler warning
749 +
750 +- Fixed modes for manually recreated device nodes
751 +===============================================================================
752 +Changes for patch v47
753 +
754 +- Added NULL devfs inode warning in <devfs_read_inode>
755 +
756 +- Force all inode nlink values to 1
757 +===============================================================================
758 +Changes for patch v48
759 +
760 +- Added "dimknod" option
761 +
762 +- Set inode nlink to 0 when freeing dentries
763 +
764 +- Added support for virtual console capture devices (/dev/vcs*)
765 +  Thanks to Dennis Hou <smilax@mindmeld.yi.org>
766 +
767 +- Fixed modes for manually recreated symlinks
768 +===============================================================================
769 +Changes for patch v49
770 +
771 +- Ported to kernel 2.1.113
772 +===============================================================================
773 +Changes for patch v50
774 +
775 +- Fixed bugs in recreated directories and symlinks
776 +===============================================================================
777 +Changes for patch v51
778 +
779 +- Improved robustness of rc.devfs script
780 +  Thanks to Roderich Schupp <rsch@experteam.de>
781 +
782 +- Fixed bugs in recreated device nodes
783 +
784 +- Fixed bug in currently unused <devfs_get_handle_from_inode>
785 +
786 +- Defined new <devfs_handle_t> type
787 +
788 +- Improved debugging when getting entries
789 +
790 +- Fixed bug where directories could be emptied
791 +
792 +- Ported to kernel 2.1.115
793 +===============================================================================
794 +Changes for patch v52
795 +
796 +- Replaced dummy .epoch inode with .devfsd character device
797 +
798 +- Modified rc.devfs to take account of above change
799 +
800 +- Removed spurious driver warning messages when CONFIG_DEVFS_FS=n
801 +
802 +- Implemented devfsd protocol revision 0
803 +===============================================================================
804 +Changes for patch v53
805 +
806 +- Ported to kernel 2.1.116 (kmod change broke hunk)
807 +
808 +- Updated Documentation/Configure.help
809 +
810 +- Test and tty pattern patch for rc.devfs script
811 +  Thanks to Roderich Schupp <rsch@experteam.de>
812 +
813 +- Added soothing message to warning in <devfs_d_iput>
814 +===============================================================================
815 +Changes for patch v54
816 +
817 +- Ported to kernel 2.1.117
818 +
819 +- Fixed default permissions in sound driver
820 +
821 +- Added support for frame buffer devices (/dev/fb*)
822 +===============================================================================
823 +Changes for patch v55
824 +
825 +- Ported to kernel 2.1.119
826 +
827 +- Use GCC extensions for structure initialisations
828 +
829 +- Implemented async open notification
830 +
831 +- Incremented devfsd protocol revision to 1
832 +===============================================================================
833 +Changes for patch v56
834 +
835 +- Ported to kernel 2.1.120-pre3
836 +
837 +- Moved async open notification to end of <devfs_open>
838 +===============================================================================
839 +Changes for patch v57
840 +
841 +- Ported to kernel 2.1.121
842 +
843 +- Prepended "/dev/" to module load request
844 +
845 +- Renamed <call_kerneld> to <call_kmod>
846 +
847 +- Created sample modules.conf file
848 +===============================================================================
849 +Changes for patch v58
850 +
851 +- Fixed typo "AYSNC" -> "ASYNC"
852 +===============================================================================
853 +Changes for patch v59
854 +
855 +- Added open flag for files
856 +===============================================================================
857 +Changes for patch v60
858 +
859 +- Ported to kernel 2.1.123-pre2
860 +===============================================================================
861 +Changes for patch v61
862 +
863 +- Set i_blocks=0 and i_blksize=1024 in <devfs_read_inode>
864 +===============================================================================
865 +Changes for patch v62
866 +
867 +- Ported to kernel 2.1.123
868 +===============================================================================
869 +Changes for patch v63
870 +
871 +- Ported to kernel 2.1.124-pre2
872 +===============================================================================
873 +Changes for patch v64
874 +
875 +- Fixed Unix98 pty support
876 +
877 +- Increased buffer size in <get_partition_list> to avoid crash and
878 +  burn
879 +===============================================================================
880 +Changes for patch v65
881 +
882 +- More Unix98 pty support fixes
883 +
884 +- Added test for empty <<name>> in <devfs_find_handle>
885 +
886 +- Renamed <generate_path> to <devfs_generate_path> and published
887 +
888 +- Created /dev/root symlink
889 +  Thanks to Roderich Schupp <rsch@ExperTeam.de>
890 +  with further modifications by me
891 +===============================================================================
892 +Changes for patch v66
893 +
894 +- Yet more Unix98 pty support fixes (now tested)
895 +
896 +- Created <devfs_get_fops>
897 +
898 +- Support media change checks when CONFIG_DEVFS_ONLY=y
899 +
900 +- Abolished Unix98-style PTY names for old PTY devices
901 +===============================================================================
902 +Changes for patch v67
903 +
904 +- Added inline declaration for dummy <devfs_generate_path>
905 +
906 +- Removed spurious "unable to register... in devfs" messages when
907 +  CONFIG_DEVFS_FS=n
908 +
909 +- Fixed misc. devices when CONFIG_DEVFS_FS=n
910 +
911 +- Limit auto-device numbering to majors 144 to 239
912 +===============================================================================
913 +Changes for patch v68
914 +
915 +- Hide unopened virtual consoles from directory listings
916 +
917 +- Added support for video capture devices
918 +
919 +- Ported to kernel 2.1.125
920 +===============================================================================
921 +Changes for patch v69
922 +
923 +- Fix for CONFIG_VT=n
924 +===============================================================================
925 +Changes for patch v70
926 +
927 +- Added support for non-OSS/Free sound cards
928 +===============================================================================
929 +Changes for patch v71
930 +
931 +- Ported to kernel 2.1.126-pre2
932 +===============================================================================
933 +Changes for patch v72
934 +
935 +- #ifdef's for CONFIG_DEVFS_DISABLE_OLD_NAMES removed
936 +===============================================================================
937 +Changes for patch v73
938 +
939 +- CONFIG_DEVFS_DISABLE_OLD_NAMES replaced with "nocompat" boot option
940 +
941 +- CONFIG_DEVFS_BOOT_OPTIONS removed: boot options always available
942 +===============================================================================
943 +Changes for patch v74
944 +
945 +- Removed CONFIG_DEVFS_MOUNT and "mount" boot option and replaced with
946 +  "nomount" boot option
947 +
948 +- Documentation updates
949 +
950 +- Updated sample modules.conf
951 +===============================================================================
952 +Changes for patch v75
953 +
954 +- Updated sample modules.conf
955 +
956 +- Remount devfs after initrd finishes
957 +
958 +- Ported to kernel 2.1.127
959 +
960 +- Added support for ISDN
961 +  Thanks to Christophe Leroy <christophe.leroy5@capway.com>
962 +===============================================================================
963 +Changes for patch v76
964 +
965 +- Updated an email address in ChangeLog
966 +
967 +- CONFIG_DEVFS_ONLY replaced with "only" boot option
968 +===============================================================================
969 +Changes for patch v77
970 +
971 +- Added DEVFS_FL_REMOVABLE flag
972 +
973 +- Check for disc change when listing directories with removable media
974 +  devices
975 +
976 +- Use DEVFS_FL_REMOVABLE in sd.c
977 +
978 +- Ported to kernel 2.1.128
979 +===============================================================================
980 +Changes for patch v78
981 +
982 +- Only call <scan_dir_for_removable> on first call to <devfs_readdir>
983 +
984 +- Ported to kernel 2.1.129-pre5
985 +
986 +- ISDN support improvements
987 +  Thanks to Christophe Leroy <christophe.leroy5@capway.com>
988 +===============================================================================
989 +Changes for patch v79
990 +
991 +- Ported to kernel 2.1.130
992 +
993 +- Renamed miscdevice "apm" to "apm_bios" to be consistent with
994 +  devices.txt
995 +===============================================================================
996 +Changes for patch v80
997 +
998 +- Ported to kernel 2.1.131
999 +
1000 +- Updated <devfs_rmdir> for VFS change in 2.1.131
1001 +===============================================================================
1002 +Changes for patch v81
1003 +
1004 +- Fixed permissions on /dev/ptmx
1005 +===============================================================================
1006 +Changes for patch v82
1007 +
1008 +- Ported to kernel 2.1.132-pre4
1009 +
1010 +- Changed initial permissions on /dev/pts/*
1011 +
1012 +- Created <devfs_mk_compat>
1013 +
1014 +- Added "symlinks" boot option
1015 +
1016 +- Changed devfs_register_blkdev() back to register_blkdev() for IDE
1017 +
1018 +- Check for partitions on removable media in <devfs_lookup>
1019 +===============================================================================
1020 +Changes for patch v83
1021 +
1022 +- Fixed support for ramdisc when using string-based root FS name
1023 +
1024 +- Ported to kernel 2.2.0-pre1
1025 +===============================================================================
1026 +Changes for patch v84
1027 +
1028 +- Ported to kernel 2.2.0-pre7
1029 +===============================================================================
1030 +Changes for patch v85
1031 +
1032 +- Compile fixes for driver/sound/sound_common.c (non-module) and
1033 +  drivers/isdn/isdn_common.c
1034 +  Thanks to Christophe Leroy <christophe.leroy5@capway.com>
1035 +
1036 +- Added support for registering regular files
1037 +
1038 +- Created <devfs_set_file_size>
1039 +
1040 +- Added /dev/cpu/mtrr as an alternative interface to /proc/mtrr
1041 +
1042 +- Update devfs inodes from entries if not changed through FS
1043 +===============================================================================
1044 +Changes for patch v86
1045 +
1046 +- Ported to kernel 2.2.0-pre9
1047 +===============================================================================
1048 +Changes for patch v87
1049 +
1050 +- Fixed bug when mounting non-devfs devices in a devfs
1051 +===============================================================================
1052 +Changes for patch v88
1053 +
1054 +- Fixed <devfs_fill_file> to only initialise temporary inodes
1055 +
1056 +- Trap for NULL fops in <devfs_register>
1057 +
1058 +- Return -ENODEV in <devfs_fill_file> for non-driver inodes
1059 +
1060 +- Fixed bug when unswapping non-devfs devices in a devfs
1061 +===============================================================================
1062 +Changes for patch v89
1063 +
1064 +- Switched to C data types in include/linux/devfs_fs.h
1065 +
1066 +- Switched from PATH_MAX to DEVFS_PATHLEN
1067 +
1068 +- Updated Documentation/filesystems/devfs/modules.conf to take account
1069 +  of reverse scanning (!) by modprobe
1070 +
1071 +- Ported to kernel 2.2.0
1072 +===============================================================================
1073 +Changes for patch v90
1074 +
1075 +- CONFIG_DEVFS_DISABLE_OLD_TTY_NAMES replaced with "nottycompat" boot
1076 +  option
1077 +
1078 +- CONFIG_DEVFS_TTY_COMPAT removed: existing "symlinks" boot option now
1079 +  controls this. This means you must have libc 5.4.44 or later, or a
1080 +  recent version of libc 6 if you use the "symlinks" option
1081 +===============================================================================
1082 +Changes for patch v91
1083 +
1084 +- Switch from <devfs_mk_symlink> to <devfs_mk_compat> in
1085 +  drivers/char/vc_screen.c to fix problems with Midnight Commander
1086 +===============================================================================
1087 +Changes for patch v92
1088 +
1089 +- Ported to kernel 2.2.2-pre5
1090 +===============================================================================
1091 +Changes for patch v93
1092 +
1093 +- Modified <sd_name> in drivers/scsi/sd.c to cope with devices that
1094 +  don't exist (which happens with new RAID autostart code printk()s)
1095 +===============================================================================
1096 +Changes for patch v94
1097 +
1098 +- Fixed bug in joystick driver: only first joystick was registered
1099 +===============================================================================
1100 +Changes for patch v95
1101 +
1102 +- Fixed another bug in joystick driver
1103 +
1104 +- Fixed <devfsd_read> to not overrun event buffer
1105 +===============================================================================
1106 +Changes for patch v96
1107 +
1108 +- Ported to kernel 2.2.5-2
1109 +
1110 +- Created <devfs_auto_unregister>
1111 +
1112 +- Fixed bugs: compatibility entries were not unregistered for:
1113 +    loop driver
1114 +    floppy driver
1115 +    RAMDISC driver
1116 +    IDE tape driver
1117 +    SCSI CD-ROM driver
1118 +    SCSI HDD driver
1119 +===============================================================================
1120 +Changes for patch v97
1121 +
1122 +- Fixed bugs: compatibility entries were not unregistered for:
1123 +    ALSA sound driver
1124 +    partitions in generic disc driver
1125 +
1126 +- Don't return unregistred entries in <devfs_find_handle>
1127 +
1128 +- Panic in <devfs_unregister> if entry unregistered
1129 +
1130 +- Don't panic in <devfs_auto_unregister> for duplicates
1131 +===============================================================================
1132 +Changes for patch v98
1133 +
1134 +- Don't unregister already unregistered entries in <unregister>
1135 +
1136 +- Register entry in <sd_detect>
1137 +
1138 +- Unregister entry in <sd_detach>
1139 +
1140 +- Changed to <devfs_*register_chrdev> in drivers/char/tty_io.c
1141 +
1142 +- Ported to kernel 2.2.7
1143 +===============================================================================
1144 +Changes for patch v99
1145 +
1146 +- Ported to kernel 2.2.8
1147 +
1148 +- Fixed bug in drivers/scsi/sd.c when >16 SCSI discs
1149 +
1150 +- Disable warning messages when unable to read partition table for
1151 +  removable media
1152 +===============================================================================
1153 +Changes for patch v100
1154 +
1155 +- Ported to kernel 2.3.1-pre5
1156 +
1157 +- Added "oops-on-panic" boot option
1158 +
1159 +- Improved debugging in <devfs_register> and <devfs_unregister>
1160 +
1161 +- Register entry in <sr_detect>
1162 +
1163 +- Unregister entry in <sr_detach>
1164 +
1165 +- Register entry in <sg_detect>
1166 +
1167 +- Unregister entry in <sg_detach>
1168 +
1169 +- Added support for ALSA drivers
1170 +===============================================================================
1171 +Changes for patch v101
1172 +
1173 +- Ported to kernel 2.3.2
1174 +===============================================================================
1175 +Changes for patch v102
1176 +
1177 +- Update serial driver to register PCMCIA entries
1178 +  Thanks to Roch-Alexandre Nomine-Beguin <roch@samarkand.infini.fr>
1179 +
1180 +- Updated an email address in ChangeLog
1181 +
1182 +- Hide virtual console capture entries from directory listings when
1183 +  corresponding console device is not open
1184 +===============================================================================
1185 +Changes for patch v103
1186 +
1187 +- Ported to kernel 2.3.3
1188 +===============================================================================
1189 +Changes for patch v104
1190 +
1191 +- Added documentation for some functions
1192 +
1193 +- Added "doc" target to fs/devfs/Makefile
1194 +
1195 +- Added "v4l" directory for video4linux devices
1196 +
1197 +- Replaced call to <devfs_unregister> in <sd_detach> with call to
1198 +  <devfs_register_partitions>
1199 +
1200 +- Moved registration for sr and sg drivers from detect() to attach()
1201 +  methods
1202 +
1203 +- Register entries in <st_attach> and unregister in <st_detach>
1204 +
1205 +- Work around IDE driver treating CD-ROM as gendisk
1206 +
1207 +- Use <sed> instead of <tr> in rc.devfs
1208 +
1209 +- Updated ToDo list
1210 +
1211 +- Removed "oops-on-panic" boot option: now always Oops
1212 +===============================================================================
1213 +Changes for patch v105
1214 +
1215 +- Unregister SCSI host from <scsi_host_no_list> in <scsi_unregister>
1216 +  Thanks to Zoltán Böszörményi <zboszor@mail.externet.hu>
1217 +
1218 +- Don't save /dev/log in rc.devfs
1219 +
1220 +- Ported to kernel 2.3.4-pre1
1221 +===============================================================================
1222 +Changes for patch v106
1223 +
1224 +- Fixed silly typo in drivers/scsi/st.c
1225 +
1226 +- Improved debugging in <devfs_register>
1227 +===============================================================================
1228 +Changes for patch v107
1229 +
1230 +- Added "diunlink" and "nokmod" boot options
1231 +
1232 +- Removed superfluous warning message in <devfs_d_iput>
1233 +===============================================================================
1234 +Changes for patch v108
1235 +
1236 +- Remove entries when unloading sound module
1237 +===============================================================================
1238 +Changes for patch v109
1239 +
1240 +- Ported to kernel 2.3.6-pre2
1241 +===============================================================================
1242 +Changes for patch v110
1243 +
1244 +- Took account of change to <d_alloc_root>
1245 +===============================================================================
1246 +Changes for patch v111
1247 +
1248 +- Created separate event queue for each mounted devfs
1249 +
1250 +- Removed <devfs_invalidate_dcache>
1251 +
1252 +- Created new ioctl()s for devfsd
1253 +
1254 +- Incremented devfsd protocol revision to 3
1255 +
1256 +- Fixed bug when re-creating directories: contents were lost
1257 +
1258 +- Block access to inodes until devfsd updates permissions
1259 +===============================================================================
1260 +Changes for patch v112
1261 +
1262 +- Modified patch so it applies against 2.3.5 and 2.3.6
1263 +
1264 +- Updated an email address in ChangeLog
1265 +
1266 +- Do not automatically change ownership/protection of /dev/tty<n>
1267 +
1268 +- Updated sample modules.conf
1269 +
1270 +- Switched to sending process uid/gid to devfsd
1271 +
1272 +- Renamed <call_kmod> to <try_modload>
1273 +
1274 +- Added DEVFSD_NOTIFY_LOOKUP event
1275 +
1276 +- Added DEVFSD_NOTIFY_CHANGE event
1277 +
1278 +- Added DEVFSD_NOTIFY_CREATE event
1279 +
1280 +- Incremented devfsd protocol revision to 4
1281 +
1282 +- Moved kernel-specific stuff to include/linux/devfs_fs_kernel.h
1283 +===============================================================================
1284 +Changes for patch v113
1285 +
1286 +- Ported to kernel 2.3.9
1287 +
1288 +- Restricted permissions on some block devices
1289 +===============================================================================
1290 +Changes for patch v114
1291 +
1292 +- Added support for /dev/netlink
1293 +  Thanks to Dennis Hou <smilax@mindmeld.yi.org>
1294 +
1295 +- Return EISDIR rather than EINVAL for read(2) on directories
1296 +
1297 +- Ported to kernel 2.3.10
1298 +===============================================================================
1299 +Changes for patch v115
1300 +
1301 +- Added support for all remaining character devices
1302 +  Thanks to Dennis Hou <smilax@mindmeld.yi.org>
1303 +
1304 +- Cleaned up netlink support
1305 +===============================================================================
1306 +Changes for patch v116
1307 +
1308 +- Added support for /dev/parport%d
1309 +  Thanks to Tim Waugh <tim@cyberelk.demon.co.uk>
1310 +
1311 +- Fixed parallel port ATAPI tape driver
1312 +
1313 +- Fixed Atari SLM laser printer driver
1314 +===============================================================================
1315 +Changes for patch v117
1316 +
1317 +- Added support for COSA card
1318 +  Thanks to Dennis Hou <smilax@mindmeld.yi.org>
1319 +
1320 +- Fixed drivers/char/ppdev.c: missing #include <linux/init.h>
1321 +
1322 +- Fixed drivers/char/ftape/zftape/zftape-init.c
1323 +  Thanks to Vladimir Popov <mashgrad@usa.net>
1324 +===============================================================================
1325 +Changes for patch v118
1326 +
1327 +- Ported to kernel 2.3.15-pre3
1328 +
1329 +- Fixed bug in loop driver
1330 +
1331 +- Unregister /dev/lp%d entries in drivers/char/lp.c
1332 +  Thanks to Maciej W. Rozycki <macro@ds2.pg.gda.pl>
1333 +===============================================================================
1334 +Changes for patch v119
1335 +
1336 +- Ported to kernel 2.3.16
1337 +===============================================================================
1338 +Changes for patch v120
1339 +
1340 +- Fixed bug in drivers/scsi/scsi.c
1341 +
1342 +- Added /dev/ppp
1343 +  Thanks to Dennis Hou <smilax@mindmeld.yi.org>
1344 +
1345 +- Ported to kernel 2.3.17
1346 +===============================================================================
1347 +Changes for patch v121
1348 +
1349 +- Fixed bug in drivers/block/loop.c
1350 +
1351 +- Ported to kernel 2.3.18
1352 +===============================================================================
1353 +Changes for patch v122
1354 +
1355 +- Ported to kernel 2.3.19
1356 +===============================================================================
1357 +Changes for patch v123
1358 +
1359 +- Ported to kernel 2.3.20
1360 +===============================================================================
1361 +Changes for patch v124
1362 +
1363 +- Ported to kernel 2.3.21
1364 +===============================================================================
1365 +Changes for patch v125
1366 +
1367 +- Created <devfs_get_info>, <devfs_set_info>,
1368 +  <devfs_get_first_child> and <devfs_get_next_sibling>
1369 +  Added <<dir>> parameter to <devfs_register>, <devfs_mk_compat>,
1370 +  <devfs_mk_dir> and <devfs_find_handle>
1371 +  Work sponsored by SGI
1372 +
1373 +- Fixed apparent bug in COSA driver
1374 +
1375 +- Re-instated "scsihosts=" boot option
1376 +===============================================================================
1377 +Changes for patch v126
1378 +
1379 +- Always create /dev/pts if CONFIG_UNIX98_PTYS=y
1380 +
1381 +- Fixed call to <devfs_mk_dir> in drivers/block/ide-disk.c
1382 +  Thanks to Dennis Hou <smilax@mindmeld.yi.org>
1383 +
1384 +- Allow multiple unregistrations
1385 +
1386 +- Created /dev/scsi hierarchy
1387 +  Work sponsored by SGI
1388 +===============================================================================
1389 +Changes for patch v127
1390 +
1391 +Work sponsored by SGI
1392 +
1393 +- No longer disable devpts if devfs enabled (caveat emptor)
1394 +
1395 +- Added flags array to struct gendisk and removed code from
1396 +  drivers/scsi/sd.c
1397 +
1398 +- Created /dev/discs hierarchy
1399 +===============================================================================
1400 +Changes for patch v128
1401 +
1402 +Work sponsored by SGI
1403 +
1404 +- Created /dev/cdroms hierarchy
1405 +===============================================================================
1406 +Changes for patch v129
1407 +
1408 +Work sponsored by SGI
1409 +
1410 +- Removed compatibility entries for sound devices
1411 +
1412 +- Removed compatibility entries for printer devices
1413 +
1414 +- Removed compatibility entries for video4linux devices
1415 +
1416 +- Removed compatibility entries for parallel port devices
1417 +
1418 +- Removed compatibility entries for frame buffer devices
1419 +===============================================================================
1420 +Changes for patch v130
1421 +
1422 +Work sponsored by SGI
1423 +
1424 +- Added major and minor number to devfsd protocol
1425 +
1426 +- Incremented devfsd protocol revision to 5
1427 +
1428 +- Removed compatibility entries for SoundBlaster CD-ROMs
1429 +
1430 +- Removed compatibility entries for netlink devices
1431 +
1432 +- Removed compatibility entries for SCSI generic devices
1433 +
1434 +- Removed compatibility entries for SCSI tape devices
1435 +===============================================================================
1436 +Changes for patch v131
1437 +
1438 +Work sponsored by SGI
1439 +
1440 +- Support info pointer for all devfs entry types
1441 +
1442 +- Added <<info>> parameter to <devfs_mk_dir> and <devfs_mk_symlink>
1443 +
1444 +- Removed /dev/st hierarchy
1445 +
1446 +- Removed /dev/sg hierarchy
1447 +
1448 +- Removed compatibility entries for loop devices
1449 +
1450 +- Removed compatibility entries for IDE tape devices
1451 +
1452 +- Removed compatibility entries for SCSI CD-ROMs
1453 +
1454 +- Removed /dev/sr hierarchy
1455 +===============================================================================
1456 +Changes for patch v132
1457 +
1458 +Work sponsored by SGI
1459 +
1460 +- Removed compatibility entries for floppy devices
1461 +
1462 +- Removed compatibility entries for RAMDISCs
1463 +
1464 +- Removed compatibility entries for meta-devices
1465 +
1466 +- Removed compatibility entries for SCSI discs
1467 +
1468 +- Created <devfs_make_root>
1469 +
1470 +- Removed /dev/sd hierarchy
1471 +
1472 +- Support "../" when searching devfs namespace
1473 +
1474 +- Created /dev/ide/host* hierarchy
1475 +
1476 +- Supported IDE hard discs in /dev/ide/host* hierarchy
1477 +
1478 +- Removed compatibility entries for IDE discs
1479 +
1480 +- Removed /dev/ide/hd hierarchy
1481 +
1482 +- Supported IDE CD-ROMs in /dev/ide/host* hierarchy
1483 +
1484 +- Removed compatibility entries for IDE CD-ROMs
1485 +
1486 +- Removed /dev/ide/cd hierarchy
1487 +===============================================================================
1488 +Changes for patch v133
1489 +
1490 +Work sponsored by SGI
1491 +
1492 +- Created <devfs_get_unregister_slave>
1493 +
1494 +- Fixed bug in fs/partitions/check.c when rescanning
1495 +===============================================================================
1496 +Changes for patch v134
1497 +
1498 +Work sponsored by SGI
1499 +
1500 +- Removed /dev/sd, /dev/sr, /dev/st and /dev/sg directories
1501 +
1502 +- Removed /dev/ide/hd directory
1503 +
1504 +- Exported <devfs_get_parent>
1505 +
1506 +- Created <devfs_register_tape> and /dev/tapes hierarchy
1507 +
1508 +- Removed /dev/ide/mt hierarchy
1509 +
1510 +- Removed /dev/ide/fd hierarchy
1511 +
1512 +- Ported to kernel 2.3.25
1513 +===============================================================================
1514 +Changes for patch v135
1515 +
1516 +Work sponsored by SGI
1517 +
1518 +- Removed compatibility entries for virtual console capture devices
1519 +
1520 +- Removed unused <devfs_set_symlink_destination>
1521 +
1522 +- Removed compatibility entries for serial devices
1523 +
1524 +- Removed compatibility entries for console devices
1525 +
1526 +- Do not hide entries from devfsd or children
1527 +
1528 +- Removed DEVFS_FL_TTY_COMPAT flag
1529 +
1530 +- Removed "nottycompat" boot option
1531 +
1532 +- Removed <devfs_mk_compat>
1533 +===============================================================================
1534 +Changes for patch v136
1535 +
1536 +Work sponsored by SGI
1537 +
1538 +- Moved BSD pty devices to /dev/pty
1539 +
1540 +- Added DEVFS_FL_WAIT flag
1541 +===============================================================================
1542 +Changes for patch v137
1543 +
1544 +Work sponsored by SGI
1545 +
1546 +- Really fixed bug in fs/partitions/check.c when rescanning
1547 +
1548 +- Support new "disc" naming scheme in <get_removable_partition>
1549 +
1550 +- Allow NULL fops in <devfs_register>
1551 +
1552 +- Removed redundant name functions in SCSI disc and IDE drivers
1553 +===============================================================================
1554 +Changes for patch v138
1555 +
1556 +Work sponsored by SGI
1557 +
1558 +- Fixed old bugs in drivers/block/paride/pt.c, drivers/char/tpqic02.c,
1559 +  drivers/net/wan/cosa.c and drivers/scsi/scsi.c
1560 +  Thanks to Sergey Kubushin <ksi@ksi-linux.com>
1561 +
1562 +- Fall back to major table if NULL fops given to <devfs_register>
1563 +===============================================================================
1564 +Changes for patch v139
1565 +
1566 +Work sponsored by SGI
1567 +
1568 +- Corrected and moved <get_blkfops> and <get_chrfops> declarations
1569 +  from arch/alpha/kernel/osf_sys.c to include/linux/fs.h
1570 +
1571 +- Removed name function from struct gendisk
1572 +
1573 +- Updated devfs FAQ
1574 +===============================================================================
1575 +Changes for patch v140
1576 +
1577 +Work sponsored by SGI
1578 +
1579 +- Ported to kernel 2.3.27
1580 +===============================================================================
1581 +Changes for patch v141
1582 +
1583 +Work sponsored by SGI
1584 +
1585 +- Bug fix in arch/m68k/atari/joystick.c
1586 +
1587 +- Moved ISDN and capi devices to /dev/isdn
1588 +===============================================================================
1589 +Changes for patch v142
1590 +
1591 +Work sponsored by SGI
1592 +
1593 +- Bug fix in drivers/block/ide-probe.c (patch confusion)
1594 +===============================================================================
1595 +Changes for patch v143
1596 +
1597 +Work sponsored by SGI
1598 +
1599 +- Bug fix in drivers/block/blkpg.c:partition_name()
1600 +===============================================================================
1601 +Changes for patch v144
1602 +
1603 +Work sponsored by SGI
1604 +
1605 +- Ported to kernel 2.3.29
1606 +
1607 +- Removed calls to <devfs_register> from cdu31a, cm206, mcd and mcdx
1608 +  CD-ROM drivers: generic driver handles this now
1609 +
1610 +- Moved joystick devices to /dev/joysticks
1611 +===============================================================================
1612 +Changes for patch v145
1613 +
1614 +Work sponsored by SGI
1615 +
1616 +- Ported to kernel 2.3.30-pre3
1617 +
1618 +- Register whole-disc entry even for invalid partition tables
1619 +
1620 +- Fixed bug in mounting root FS when initrd enabled
1621 +
1622 +- Fixed device entry leak with IDE CD-ROMs
1623 +
1624 +- Fixed compile problem with drivers/isdn/isdn_common.c
1625 +
1626 +- Moved COSA devices to /dev/cosa
1627 +
1628 +- Support fifos when unregistering
1629 +
1630 +- Created <devfs_register_series> and used in many drivers
1631 +
1632 +- Moved Coda devices to /dev/coda
1633 +
1634 +- Moved parallel port IDE tapes to /dev/pt
1635 +
1636 +- Moved parallel port IDE generic devices to /dev/pg
1637 +===============================================================================
1638 +Changes for patch v146
1639 +
1640 +Work sponsored by SGI
1641 +
1642 +- Removed obsolete DEVFS_FL_COMPAT and DEVFS_FL_TOLERANT flags
1643 +
1644 +- Fixed compile problem with fs/coda/psdev.c
1645 +
1646 +- Reinstate change to <devfs_register_blkdev> in
1647 +  drivers/block/ide-probe.c now that fs/isofs/inode.c is fixed
1648 +
1649 +- Switched to <devfs_register_blkdev> in drivers/block/floppy.c,
1650 +  drivers/scsi/sr.c and drivers/block/md.c
1651 +
1652 +- Moved DAC960 devices to /dev/dac960
1653 +===============================================================================
1654 +Changes for patch v147
1655 +
1656 +Work sponsored by SGI
1657 +
1658 +- Ported to kernel 2.3.32-pre4
1659 +===============================================================================
1660 +Changes for patch v148
1661 +
1662 +Work sponsored by SGI
1663 +
1664 +- Removed kmod support: use devfsd instead
1665 +
1666 +- Moved miscellaneous character devices to /dev/misc
1667 +===============================================================================
1668 +Changes for patch v149
1669 +
1670 +Work sponsored by SGI
1671 +
1672 +- Ensure include/linux/joystick.h is OK for user-space
1673 +
1674 +- Improved debugging in <get_vfs_inode>
1675 +
1676 +- Ensure dentries created by devfsd will be cleaned up
1677 +===============================================================================
1678 +Changes for patch v150
1679 +
1680 +Work sponsored by SGI
1681 +
1682 +- Ported to kernel 2.3.34
1683 +===============================================================================
1684 +Changes for patch v151
1685 +
1686 +Work sponsored by SGI
1687 +
1688 +- Ported to kernel 2.3.35-pre1
1689 +
1690 +- Created <devfs_get_name>
1691 +===============================================================================
1692 +Changes for patch v152
1693 +
1694 +Work sponsored by SGI
1695 +
1696 +- Updated sample modules.conf
1697 +
1698 +- Ported to kernel 2.3.36-pre1
1699 +===============================================================================
1700 +Changes for patch v153
1701 +
1702 +Work sponsored by SGI
1703 +
1704 +- Ported to kernel 2.3.42
1705 +
1706 +- Removed <devfs_fill_file>
1707 +===============================================================================
1708 +Changes for patch v154
1709 +
1710 +Work sponsored by SGI
1711 +
1712 +- Took account of device number changes for /dev/fb*
1713 +===============================================================================
1714 +Changes for patch v155
1715 +
1716 +Work sponsored by SGI
1717 +
1718 +- Ported to kernel 2.3.43-pre8
1719 +
1720 +- Moved /dev/tty0 to /dev/vc/0
1721 +
1722 +- Moved sequence number formatting from <_tty_make_name> to drivers
1723 +===============================================================================
1724 +Changes for patch v156
1725 +
1726 +Work sponsored by SGI
1727 +
1728 +- Fixed breakage in drivers/scsi/sd.c due to recent SCSI changes
1729 +===============================================================================
1730 +Changes for patch v157
1731 +
1732 +Work sponsored by SGI
1733 +
1734 +- Ported to kernel 2.3.45
1735 +===============================================================================
1736 +Changes for patch v158
1737 +
1738 +Work sponsored by SGI
1739 +
1740 +- Ported to kernel 2.3.46-pre2
1741 +===============================================================================
1742 +Changes for patch v159
1743 +
1744 +Work sponsored by SGI
1745 +
1746 +- Fixed drivers/block/md.c
1747 +  Thanks to Mike Galbraith <mikeg@weiden.de>
1748 +
1749 +- Documentation fixes
1750 +
1751 +- Moved device registration from <lp_init> to <lp_register>
1752 +  Thanks to Tim Waugh <twaugh@redhat.com>
1753 +===============================================================================
1754 +Changes for patch v160
1755 +
1756 +Work sponsored by SGI
1757 +
1758 +- Fixed drivers/char/joystick/joystick.c
1759 +  Thanks to Vojtech Pavlik <vojtech@suse.cz>
1760 +
1761 +- Documentation updates
1762 +
1763 +- Fixed arch/i386/kernel/mtrr.c if procfs and devfs not enabled
1764 +
1765 +- Fixed drivers/char/stallion.c
1766 +===============================================================================
1767 +Changes for patch v161
1768 +
1769 +Work sponsored by SGI
1770 +
1771 +- Remove /dev/ide when ide-mod is unloaded
1772 +
1773 +- Fixed bug in drivers/block/ide-probe.c when secondary but no primary
1774 +
1775 +- Added DEVFS_FL_NO_PERSISTENCE flag
1776 +
1777 +- Used new DEVFS_FL_NO_PERSISTENCE flag for Unix98 pty slaves
1778 +
1779 +- Removed unnecessary call to <update_devfs_inode_from_entry> in
1780 +  <devfs_readdir>
1781 +
1782 +- Only set auto-ownership for /dev/pty/s*
1783 +===============================================================================
1784 +Changes for patch v162
1785 +
1786 +Work sponsored by SGI
1787 +
1788 +- Set inode->i_size to correct size for symlinks
1789 +  Thanks to Jeremy Fitzhardinge <jeremy@goop.org>
1790 +
1791 +- Only give lookup() method to directories to comply with new VFS
1792 +  assumptions
1793 +
1794 +- Remove unnecessary tests in symlink methods
1795 +
1796 +- Don't kill existing block ops in <devfs_read_inode>
1797 +
1798 +- Restore auto-ownership for /dev/pty/m*
1799 +===============================================================================
1800 +Changes for patch v163
1801 +
1802 +Work sponsored by SGI
1803 +
1804 +- Don't create missing directories in <devfs_find_handle>
1805 +
1806 +- Removed Documentation/filesystems/devfs/mk-devlinks
1807 +
1808 +- Updated Documentation/filesystems/devfs/README
1809 +===============================================================================
1810 +Changes for patch v164
1811 +
1812 +Work sponsored by SGI
1813 +
1814 +- Fixed CONFIG_DEVFS breakage in drivers/char/serial.c introduced in
1815 +  linux-2.3.99-pre6-7
1816 +===============================================================================
1817 +Changes for patch v165
1818 +
1819 +Work sponsored by SGI
1820 +
1821 +- Ported to kernel 2.3.99-pre6
1822 +===============================================================================
1823 +Changes for patch v166
1824 +
1825 +Work sponsored by SGI
1826 +
1827 +- Added CONFIG_DEVFS_MOUNT
1828 +===============================================================================
1829 +Changes for patch v167
1830 +
1831 +Work sponsored by SGI
1832 +
1833 +- Updated Documentation/filesystems/devfs/README
1834 +
1835 +- Updated sample modules.conf
1836 +===============================================================================
1837 +Changes for patch v168
1838 +
1839 +Work sponsored by SGI
1840 +
1841 +- Disabled multi-mount capability (use VFS bindings instead)
1842 +
1843 +- Updated README from master HTML file
1844 +===============================================================================
1845 +Changes for patch v169
1846 +
1847 +Work sponsored by SGI
1848 +
1849 +- Removed multi-mount code
1850 +
1851 +- Removed compatibility macros: VFS has changed too much
1852 +===============================================================================
1853 +Changes for patch v170
1854 +
1855 +Work sponsored by SGI
1856 +
1857 +- Updated README from master HTML file
1858 +
1859 +- Merged devfs inode into devfs entry
1860 +===============================================================================
1861 +Changes for patch v171
1862 +
1863 +Work sponsored by SGI
1864 +
1865 +- Updated sample modules.conf
1866 +
1867 +- Removed dead code in <devfs_register> which used to call
1868 +  <free_dentries>
1869 +
1870 +- Ported to kernel 2.4.0-test2-pre3
1871 +===============================================================================
1872 +Changes for patch v172
1873 +
1874 +Work sponsored by SGI
1875 +
1876 +- Changed interface to <devfs_register>
1877 +
1878 +- Changed interface to <devfs_register_series>
1879 +===============================================================================
1880 +Changes for patch v173
1881 +
1882 +Work sponsored by SGI
1883 +
1884 +- Simplified interface to <devfs_mk_symlink>
1885 +
1886 +- Simplified interface to <devfs_mk_dir>
1887 +
1888 +- Simplified interface to <devfs_find_handle>
1889 +===============================================================================
1890 +Changes for patch v174
1891 +
1892 +Work sponsored by SGI
1893 +
1894 +- Updated README from master HTML file
1895 +===============================================================================
1896 +Changes for patch v175
1897 +
1898 +Work sponsored by SGI
1899 +
1900 +- DocBook update for fs/devfs/base.c
1901 +  Thanks to Tim Waugh <twaugh@redhat.com>
1902 +
1903 +- Removed stale fs/tunnel.c (was never used or completed)
1904 +===============================================================================
1905 +Changes for patch v176
1906 +
1907 +Work sponsored by SGI
1908 +
1909 +- Updated ToDo list
1910 +
1911 +- Removed sample modules.conf: now distributed with devfsd
1912 +
1913 +- Updated README from master HTML file
1914 +
1915 +- Ported to kernel 2.4.0-test3-pre4 (which had devfs-patch-v174)
1916 +===============================================================================
1917 +Changes for patch v177
1918 +
1919 +- Updated README from master HTML file
1920 +
1921 +- Documentation cleanups
1922 +
1923 +- Ensure <devfs_generate_path> terminates string for root entry
1924 +  Thanks to Tim Jansen <tim@tjansen.de>
1925 +
1926 +- Exported <devfs_get_name> to modules
1927 +
1928 +- Make <devfs_mk_symlink> send events to devfsd
1929 +
1930 +- Cleaned up option processing in <devfs_setup>
1931 +
1932 +- Fixed bugs in handling symlinks: could leak or cause Oops
1933 +
1934 +- Cleaned up directory handling by separating fops
1935 +  Thanks to Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk>
1936 +===============================================================================
1937 +Changes for patch v178
1938 +
1939 +- Fixed handling of inverted options in <devfs_setup>
1940 +===============================================================================
1941 +Changes for patch v179
1942 +
1943 +- Adjusted <try_modload> to account for <devfs_generate_path> fix
1944 +===============================================================================
1945 +Changes for patch v180
1946 +
1947 +- Fixed !CONFIG_DEVFS_FS stub declaration of <devfs_get_info>
1948 +===============================================================================
1949 +Changes for patch v181
1950 +
1951 +- Answered question posed by Al Viro and removed his comments from <devfs_open>
1952 +
1953 +- Moved setting of registered flag after other fields are changed
1954 +
1955 +- Fixed race between <devfsd_close> and <devfsd_notify_one>
1956 +
1957 +- Global VFS changes added bogus BKL to devfsd_close(): removed
1958 +
1959 +- Widened locking in <devfs_readlink> and <devfs_follow_link>
1960 +
1961 +- Replaced <devfsd_read> stack usage with <devfsd_ioctl> kmalloc
1962 +
1963 +- Simplified locking in <devfsd_ioctl> and fixed memory leak
1964 +===============================================================================
1965 +Changes for patch v182
1966 +
1967 +- Created <devfs_*alloc_major> and <devfs_*alloc_devnum>
1968 +
1969 +- Removed broken devnum allocation and use <devfs_alloc_devnum>
1970 +
1971 +- Fixed old devnum leak by calling new <devfs_dealloc_devnum>
1972 +
1973 +- Created <devfs_*alloc_unique_number>
1974 +
1975 +- Fixed number leak for /dev/cdroms/cdrom%d
1976 +
1977 +- Fixed number leak for /dev/discs/disc%d
1978 +===============================================================================
1979 +Changes for patch v183
1980 +
1981 +- Fixed bug in <devfs_setup> which could hang boot process
1982 +===============================================================================
1983 +Changes for patch v184
1984 +
1985 +- Documentation typo fix for fs/devfs/util.c
1986 +
1987 +- Fixed drivers/char/stallion.c for devfs
1988 +
1989 +- Added DEVFSD_NOTIFY_DELETE event
1990 +
1991 +- Updated README from master HTML file
1992 +
1993 +- Removed #include <asm/segment.h> from fs/devfs/base.c
1994 +===============================================================================
1995 +Changes for patch v185
1996 +
1997 +- Made <block_semaphore> and <char_semaphore> in fs/devfs/util.c
1998 +  private
1999 +
2000 +- Fixed inode table races by removing it and using inode->u.generic_ip
2001 +  instead
2002 +
2003 +- Moved <devfs_read_inode> into <get_vfs_inode>
2004 +
2005 +- Moved <devfs_write_inode> into <devfs_notify_change>
2006 +===============================================================================
2007 +Changes for patch v186
2008 +
2009 +- Fixed race in <devfs_do_symlink> for uni-processor
2010 +
2011 +- Updated README from master HTML file
2012 +===============================================================================
2013 +Changes for patch v187
2014 +
2015 +- Fixed drivers/char/stallion.c for devfs
2016 +
2017 +- Fixed drivers/char/rocket.c for devfs
2018 +
2019 +- Fixed bug in <devfs_alloc_unique_number>: limited to 128 numbers
2020 +===============================================================================
2021 +Changes for patch v188
2022 +
2023 +- Updated major masks in fs/devfs/util.c up to Linus' "no new majors"
2024 +  proclamation. Block: were 126 now 122 free, char: were 26 now 19 free
2025 +
2026 +- Updated README from master HTML file
2027 +
2028 +- Removed remnant of multi-mount support in <devfs_mknod>
2029 +
2030 +- Removed unused DEVFS_FL_SHOW_UNREG flag
2031 +===============================================================================
2032 +Changes for patch v189
2033 +
2034 +- Removed nlink field from struct devfs_inode
2035 +
2036 +- Removed auto-ownership for /dev/pty/* (BSD ptys) and used
2037 +  DEVFS_FL_CURRENT_OWNER|DEVFS_FL_NO_PERSISTENCE for /dev/pty/s* (just
2038 +  like Unix98 pty slaves) and made /dev/pty/m* rw-rw-rw- access
2039 +===============================================================================
2040 +Changes for patch v190
2041 +
2042 +- Updated README from master HTML file
2043 +
2044 +- Replaced BKL with global rwsem to protect symlink data (quick and
2045 +  dirty hack)
2046 +===============================================================================
2047 +Changes for patch v191
2048 +
2049 +- Replaced global rwsem for symlink with per-link refcount
2050 +===============================================================================
2051 +Changes for patch v192
2052 +
2053 +- Removed unnecessary #ifdef CONFIG_DEVFS_FS from arch/i386/kernel/mtrr.c
2054 +
2055 +- Ported to kernel 2.4.10-pre11
2056 +
2057 +- Set inode->i_mapping->a_ops for block nodes in <get_vfs_inode>
2058 +===============================================================================
2059 +Changes for patch v193
2060 +
2061 +- Went back to global rwsem for symlinks (refcount scheme no good)
2062 +===============================================================================
2063 +Changes for patch v194
2064 +
2065 +- Fixed overrun in <devfs_link> by removing function (not needed)
2066 +
2067 +- Updated README from master HTML file
2068 +===============================================================================
2069 +Changes for patch v195
2070 +
2071 +- Fixed buffer underrun in <try_modload>
2072 +
2073 +- Moved down_read() from <search_for_entry_in_dir> to <find_entry>
2074 +===============================================================================
2075 +Changes for patch v196
2076 +
2077 +- Fixed race in <devfsd_ioctl> when setting event mask
2078 +  Thanks to Kari Hurtta <hurtta@leija.mh.fmi.fi>
2079 +
2080 +- Avoid deadlock in <devfs_follow_link> by using temporary buffer
2081 +===============================================================================
2082 +Changes for patch v197
2083 +
2084 +- First release of new locking code for devfs core (v1.0)
2085 +
2086 +- Fixed bug in drivers/cdrom/cdrom.c
2087 +===============================================================================
2088 +Changes for patch v198
2089 +
2090 +- Discard temporary buffer, now use "%s" for dentry names
2091 +
2092 +- Don't generate path in <try_modload>: use fake entry instead
2093 +
2094 +- Use "existing" directory in <_devfs_make_parent_for_leaf>
2095 +
2096 +- Use slab cache rather than fixed buffer for devfsd events
2097 +===============================================================================
2098 +Changes for patch v199
2099 +
2100 +- Removed obsolete usage of DEVFS_FL_NO_PERSISTENCE
2101 +
2102 +- Send DEVFSD_NOTIFY_REGISTERED events in <devfs_mk_dir>
2103 +
2104 +- Fixed locking bug in <devfs_d_revalidate_wait> due to typo
2105 +
2106 +- Do not send CREATE, CHANGE, ASYNC_OPEN or DELETE events from devfsd
2107 +  or children
2108 +===============================================================================
2109 +Changes for patch v200
2110 +
2111 +- Ported to kernel 2.5.1-pre2
2112 +===============================================================================
2113 +Changes for patch v201
2114 +
2115 +- Fixed bug in <devfsd_read>: was dereferencing freed pointer
2116 +===============================================================================
2117 +Changes for patch v202
2118 +
2119 +- Fixed bug in <devfsd_close>: was dereferencing freed pointer
2120 +
2121 +- Added process group check for devfsd privileges
2122 +===============================================================================
2123 +Changes for patch v203
2124 +
2125 +- Use SLAB_ATOMIC in <devfsd_notify_de> from <devfs_d_delete>
2126 +===============================================================================
2127 +Changes for patch v204
2128 +
2129 +- Removed long obsolete rc.devfs
2130 +
2131 +- Return old entry in <devfs_mk_dir> for 2.4.x kernels
2132 +
2133 +- Updated README from master HTML file
2134 +
2135 +- Increment refcount on module in <check_disc_changed>
2136 +
2137 +- Created <devfs_get_handle> and exported <devfs_put>
2138 +
2139 +- Increment refcount on module in <devfs_get_ops>
2140 +
2141 +- Created <devfs_put_ops> and used where needed to fix races
2142 +
2143 +- Added clarifying comments in response to preliminary EMC code review
2144 +
2145 +- Added poisoning to <devfs_put>
2146 +
2147 +- Improved debugging messages
2148 +
2149 +- Fixed unregister bugs in drivers/md/lvm-fs.c
2150 +===============================================================================
2151 +Changes for patch v205
2152 +
2153 +- Corrected (made useful) debugging message in <unregister>
2154 +
2155 +- Moved <kmem_cache_create> in <mount_devfs_fs> to <init_devfs_fs>
2156 +
2157 +- Fixed drivers/md/lvm-fs.c to create "lvm" entry
2158 +
2159 +- Added magic number to guard against scribbling drivers
2160 +
2161 +- Only return old entry in <devfs_mk_dir> if a directory
2162 +
2163 +- Defined macros for error and debug messages
2164 +
2165 +- Updated README from master HTML file
2166 +===============================================================================
2167 +Changes for patch v206
2168 +
2169 +- Added support for multiple Compaq cpqarray controllers
2170 +
2171 +- Fixed (rare, old) race in <devfs_lookup>
2172 +===============================================================================
2173 +Changes for patch v207
2174 +
2175 +- Fixed deadlock bug in <devfs_d_revalidate_wait>
2176 +
2177 +- Tag VFS deletable in <devfs_mk_symlink> if handle ignored
2178 +
2179 +- Updated README from master HTML file
2180 +===============================================================================
2181 +Changes for patch v208
2182 +
2183 +- Added KERN_* to remaining messages
2184 +
2185 +- Cleaned up declaration of <stat_read>
2186 +
2187 +- Updated README from master HTML file
2188 +===============================================================================
2189 +Changes for patch v209
2190 +
2191 +- Updated README from master HTML file
2192 +
2193 +- Removed silently introduced calls to lock_kernel() and
2194 +  unlock_kernel() due to recent VFS locking changes. BKL isn't
2195 +  required in devfs 
2196 +
2197 +- Changed <devfs_rmdir> to allow later additions if not yet empty
2198 +
2199 +- Added calls to <devfs_register_partitions> in drivers/block/blkpc.c
2200 +  <add_partition> and <del_partition>
2201 +
2202 +- Fixed bug in <devfs_alloc_unique_number>: was clearing beyond
2203 +  bitfield
2204 +
2205 +- Fixed bitfield data type for <devfs_*alloc_devnum>
2206 +
2207 +- Made major bitfield type and initialiser 64 bit safe
2208 +===============================================================================
2209 +Changes for patch v210
2210 +
2211 +- Updated fs/devfs/util.c to fix shift warning on 64 bit machines
2212 +  Thanks to Anton Blanchard <anton@samba.org>
2213 +
2214 +- Updated README from master HTML file
2215 +===============================================================================
2216 +Changes for patch v211
2217 +
2218 +- Do not put miscellaneous character devices in /dev/misc if they
2219 +  specify their own directory (i.e. contain a '/' character)
2220 +
2221 +- Copied macro for error messages from fs/devfs/base.c to
2222 +  fs/devfs/util.c and made use of this macro
2223 +
2224 +- Removed 2.4.x compatibility code from fs/devfs/base.c
2225 +===============================================================================
2226 +Changes for patch v212
2227 +
2228 +- Added BKL to <devfs_open> because drivers still need it
2229 +===============================================================================
2230 +Changes for patch v213
2231 +
2232 +- Protected <scan_dir_for_removable> and <get_removable_partition>
2233 +  from changing directory contents
2234 +===============================================================================
2235 +Changes for patch v214
2236 +
2237 +- Switched to ISO C structure field initialisers
2238 +
2239 +- Switch to set_current_state() and move before add_wait_queue()
2240 +
2241 +- Updated README from master HTML file
2242 +
2243 +- Fixed devfs entry leak in <devfs_readdir> when *readdir fails
2244 +===============================================================================
2245 +Changes for patch v215
2246 +
2247 +- Created <devfs_find_and_unregister>
2248 +
2249 +- Switched many functions from <devfs_find_handle> to
2250 +  <devfs_find_and_unregister>
2251 +
2252 +- Switched many functions from <devfs_find_handle> to <devfs_get_handle>
2253 +===============================================================================
2254 +Changes for patch v216
2255 +
2256 +- Switched arch/ia64/sn/io/hcl.c from <devfs_find_handle> to
2257 +  <devfs_get_handle>
2258 +
2259 +- Removed deprecated <devfs_find_handle>
2260 +===============================================================================
2261 +Changes for patch v217
2262 +
2263 +- Exported <devfs_find_and_unregister> and <devfs_only> to modules
2264 +
2265 +- Updated README from master HTML file
2266 +
2267 +- Fixed module unload race in <devfs_open>
2268 +===============================================================================
2269 +Changes for patch v218
2270 +
2271 +- Removed DEVFS_FL_AUTO_OWNER flag
2272 +
2273 +- Switched lingering structure field initialiser to ISO C
2274 +
2275 +- Added locking when setting/clearing flags
2276 +
2277 +- Documentation fix in fs/devfs/util.c
2278 diff -urN linux-2.6.19.old/Documentation/filesystems/devfs/README linux-2.6.19.dev/Documentation/filesystems/devfs/README
2279 --- linux-2.6.19.old/Documentation/filesystems/devfs/README     1970-01-01 01:00:00.000000000 +0100
2280 +++ linux-2.6.19.dev/Documentation/filesystems/devfs/README     2006-12-14 03:12:59.000000000 +0100
2281 @@ -0,0 +1,1959 @@
2282 +Devfs (Device File System) FAQ
2283 +
2284 +
2285 +Linux Devfs (Device File System) FAQ
2286 +Richard Gooch
2287 +20-AUG-2002
2288 +
2289 +
2290 +Document languages:
2291 +
2292 +
2293 +
2294 +
2295 +
2296 +
2297 +
2298 +-----------------------------------------------------------------------------
2299 +
2300 +NOTE: the master copy of this document is available online at:
2301 +
2302 +http://www.atnf.csiro.au/~rgooch/linux/docs/devfs.html
2303 +and looks much better than the text version distributed with the
2304 +kernel sources. A mirror site is available at:
2305 +
2306 +http://www.ras.ucalgary.ca/~rgooch/linux/docs/devfs.html
2307 +
2308 +There is also an optional daemon that may be used with devfs. You can
2309 +find out more about it at:
2310 +
2311 +http://www.atnf.csiro.au/~rgooch/linux/
2312 +
2313 +A mailing list is available which you may subscribe to. Send
2314 +email
2315 +to majordomo@oss.sgi.com with the following line in the
2316 +body of the message:
2317 +subscribe devfs
2318 +To unsubscribe, send the message body:
2319 +unsubscribe devfs
2320 +instead. The list is archived at
2321 +
2322 +http://oss.sgi.com/projects/devfs/archive/.
2323 +
2324 +-----------------------------------------------------------------------------
2325 +
2326 +Contents
2327 +
2328 +
2329 +What is it?
2330 +
2331 +Why do it?
2332 +
2333 +Who else does it?
2334 +
2335 +How it works
2336 +
2337 +Operational issues (essential reading)
2338 +
2339 +Instructions for the impatient
2340 +Permissions persistence across reboots
2341 +Dealing with drivers without devfs support
2342 +All the way with Devfs
2343 +Other Issues
2344 +Kernel Naming Scheme
2345 +Devfsd Naming Scheme
2346 +Old Compatibility Names
2347 +SCSI Host Probing Issues
2348 +
2349 +
2350 +
2351 +Device drivers currently ported
2352 +
2353 +Allocation of Device Numbers
2354 +
2355 +Questions and Answers
2356 +
2357 +Making things work
2358 +Alternatives to devfs
2359 +What I don't like about devfs
2360 +How to report bugs
2361 +Strange kernel messages
2362 +Compilation problems with devfsd
2363 +
2364 +
2365 +Other resources
2366 +
2367 +Translations of this document
2368 +
2369 +
2370 +-----------------------------------------------------------------------------
2371 +
2372 +
2373 +What is it?
2374 +
2375 +Devfs is an alternative to "real" character and block special devices
2376 +on your root filesystem. Kernel device drivers can register devices by
2377 +name rather than major and minor numbers. These devices will appear in
2378 +devfs automatically, with whatever default ownership and
2379 +protection the driver specified. A daemon (devfsd) can be used to
2380 +override these defaults. Devfs has been in the kernel since 2.3.46.
2381 +
2382 +NOTE that devfs is entirely optional. If you prefer the old
2383 +disc-based device nodes, then simply leave CONFIG_DEVFS_FS=n (the
2384 +default). In this case, nothing will change.  ALSO NOTE that if you do
2385 +enable devfs, the defaults are such that full compatibility is
2386 +maintained with the old devices names.
2387 +
2388 +There are two aspects to devfs: one is the underlying device
2389 +namespace, which is a namespace just like any mounted filesystem. The
2390 +other aspect is the filesystem code which provides a view of the
2391 +device namespace. The reason I make a distinction is because devfs
2392 +can be mounted many times, with each mount showing the same device
2393 +namespace. Changes made are global to all mounted devfs filesystems.
2394 +Also, because the devfs namespace exists without any devfs mounts, you
2395 +can easily mount the root filesystem by referring to an entry in the
2396 +devfs namespace.
2397 +
2398 +
2399 +The cost of devfs is a small increase in kernel code size and memory
2400 +usage. About 7 pages of code (some of that in __init sections) and 72
2401 +bytes for each entry in the namespace. A modest system has only a
2402 +couple of hundred device entries, so this costs a few more
2403 +pages. Compare this with the suggestion to put /dev on a <a
2404 +href="#why-faq-ramdisc">ramdisc.
2405 +
2406 +On a typical machine, the cost is under 0.2 percent. On a modest
2407 +system with 64 MBytes of RAM, the cost is under 0.1 percent.  The
2408 +accusations of "bloatware" levelled at devfs are not justified.
2409 +
2410 +-----------------------------------------------------------------------------
2411 +
2412 +
2413 +Why do it?
2414 +
2415 +There are several problems that devfs addresses. Some of these
2416 +problems are more serious than others (depending on your point of
2417 +view), and some can be solved without devfs. However, the totality of
2418 +these problems really calls out for devfs.
2419 +
2420 +The choice is a patchwork of inefficient user space solutions, which
2421 +are complex and likely to be fragile, or to use a simple and efficient
2422 +devfs which is robust.
2423 +
2424 +There have been many counter-proposals to devfs, all seeking to
2425 +provide some of the benefits without actually implementing devfs. So
2426 +far there has been an absence of code and no proposed alternative has
2427 +been able to provide all the features that devfs does. Further,
2428 +alternative proposals require far more complexity in user-space (and
2429 +still deliver less functionality than devfs). Some people have the
2430 +mantra of reducing "kernel bloat", but don't consider the effects on
2431 +user-space.
2432 +
2433 +A good solution limits the total complexity of kernel-space and
2434 +user-space.
2435 +
2436 +
2437 +Major&minor allocation
2438 +
2439 +The existing scheme requires the allocation of major and minor device
2440 +numbers for each and every device. This means that a central
2441 +co-ordinating authority is required to issue these device numbers
2442 +(unless you're developing a "private" device driver), in order to
2443 +preserve uniqueness. Devfs shifts the burden to a namespace. This may
2444 +not seem like a huge benefit, but actually it is. Since driver authors
2445 +will naturally choose a device name which reflects the functionality
2446 +of the device, there is far less potential for namespace conflict.
2447 +Solving this requires a kernel change.
2448 +
2449 +/dev management
2450 +
2451 +Because you currently access devices through device nodes, these must
2452 +be created by the system administrator. For standard devices you can
2453 +usually find a MAKEDEV programme which creates all these (hundreds!)
2454 +of nodes. This means that changes in the kernel must be reflected by
2455 +changes in the MAKEDEV programme, or else the system administrator
2456 +creates device nodes by hand.
2457 +
2458 +The basic problem is that there are two separate databases of
2459 +major and minor numbers. One is in the kernel and one is in /dev (or
2460 +in a MAKEDEV programme, if you want to look at it that way). This is
2461 +duplication of information, which is not good practice.
2462 +Solving this requires a kernel change.
2463 +
2464 +/dev growth
2465 +
2466 +A typical /dev has over 1200 nodes! Most of these devices simply don't
2467 +exist because the hardware is not available. A huge /dev increases the
2468 +time to access devices (I'm just referring to the dentry lookup times
2469 +and the time taken to read inodes off disc: the next subsection shows
2470 +some more horrors).
2471 +
2472 +An example of how big /dev can grow is if we consider SCSI devices:
2473 +
2474 +host           6  bits  (say up to 64 hosts on a really big machine)
2475 +channel        4  bits  (say up to 16 SCSI buses per host)
2476 +id             4  bits
2477 +lun            3  bits
2478 +partition      6  bits
2479 +TOTAL          23 bits
2480 +
2481 +
2482 +This requires 8 Mega (1024*1024) inodes if we want to store all
2483 +possible device nodes. Even if we scrap everything but id,partition
2484 +and assume a single host adapter with a single SCSI bus and only one
2485 +logical unit per SCSI target (id), that's still 10 bits or 1024
2486 +inodes. Each VFS inode takes around 256 bytes (kernel 2.1.78), so
2487 +that's 256 kBytes of inode storage on disc (assuming real inodes take
2488 +a similar amount of space as VFS inodes). This is actually not so bad,
2489 +because disc is cheap these days. Embedded systems would care about
2490 +256 kBytes of /dev inodes, but you could argue that embedded systems
2491 +would have hand-tuned /dev directories. I've had to do just that on my
2492 +embedded systems, but I would rather just leave it to devfs.
2493 +
2494 +Another issue is the time taken to lookup an inode when first
2495 +referenced. Not only does this take time in scanning through a list in
2496 +memory, but also the seek times to read the inodes off disc.
2497 +This could be solved in user-space using a clever programme which
2498 +scanned the kernel logs and deleted /dev entries which are not
2499 +available and created them when they were available. This programme
2500 +would need to be run every time a new module was loaded, which would
2501 +slow things down a lot.
2502 +
2503 +There is an existing programme called scsidev which will automatically
2504 +create device nodes for SCSI devices. It can do this by scanning files
2505 +in /proc/scsi. Unfortunately, to extend this idea to other device
2506 +nodes would require significant modifications to existing drivers (so
2507 +they too would provide information in /proc). This is a non-trivial
2508 +change (I should know: devfs has had to do something similar). Once
2509 +you go to this much effort, you may as well use devfs itself (which
2510 +also provides this information).  Furthermore, such a system would
2511 +likely be implemented in an ad-hoc fashion, as different drivers will
2512 +provide their information in different ways.
2513 +
2514 +Devfs is much cleaner, because it (naturally) has a uniform mechanism
2515 +to provide this information: the device nodes themselves!
2516 +
2517 +
2518 +Node to driver file_operations translation
2519 +
2520 +There is an important difference between the way disc-based character
2521 +and block nodes and devfs entries make the connection between an entry
2522 +in /dev and the actual device driver.
2523 +
2524 +With the current 8 bit major and minor numbers the connection between
2525 +disc-based c&b nodes and per-major drivers is done through a
2526 +fixed-length table of 128 entries. The various filesystem types set
2527 +the inode operations for c&b nodes to {chr,blk}dev_inode_operations,
2528 +so when a device is opened a few quick levels of indirection bring us
2529 +to the driver file_operations.
2530 +
2531 +For miscellaneous character devices a second step is required: there
2532 +is a scan for the driver entry with the same minor number as the file
2533 +that was opened, and the appropriate minor open method is called. This
2534 +scanning is done *every time* you open a device node. Potentially, you
2535 +may be searching through dozens of misc. entries before you find your
2536 +open method. While not an enormous performance overhead, this does
2537 +seem pointless.
2538 +
2539 +Linux *must* move beyond the 8 bit major and minor barrier,
2540 +somehow. If we simply increase each to 16 bits, then the indexing
2541 +scheme used for major driver lookup becomes untenable, because the
2542 +major tables (one each for character and block devices) would need to
2543 +be 64 k entries long (512 kBytes on x86, 1 MByte for 64 bit
2544 +systems). So we would have to use a scheme like that used for
2545 +miscellaneous character devices, which means the search time goes up
2546 +linearly with the average number of major device drivers on your
2547 +system. Not all "devices" are hardware, some are higher-level drivers
2548 +like KGI, so you can get more "devices" without adding hardware
2549 +You can improve this by creating an ordered (balanced:-)
2550 +binary tree, in which case your search time becomes log(N).
2551 +Alternatively, you can use hashing to speed up the search.
2552 +But why do that search at all if you don't have to? Once again, it
2553 +seems pointless.
2554 +
2555 +Note that devfs doesn't use the major&minor system. For devfs
2556 +entries, the connection is done when you lookup the /dev entry. When
2557 +devfs_register() is called, an internal table is appended which has
2558 +the entry name and the file_operations. If the dentry cache doesn't
2559 +have the /dev entry already, this internal table is scanned to get the
2560 +file_operations, and an inode is created. If the dentry cache already
2561 +has the entry, there is *no lookup time* (other than the dentry scan
2562 +itself, but we can't avoid that anyway, and besides Linux dentries
2563 +cream other OS's which don't have them:-). Furthermore, the number of
2564 +node entries in a devfs is only the number of available device
2565 +entries, not the number of *conceivable* entries. Even if you remove
2566 +unnecessary entries in a disc-based /dev, the number of conceivable
2567 +entries remains the same: you just limit yourself in order to save
2568 +space.
2569 +
2570 +Devfs provides a fast connection between a VFS node and the device
2571 +driver, in a scalable way.
2572 +
2573 +/dev as a system administration tool
2574 +
2575 +Right now /dev contains a list of conceivable devices, most of which I
2576 +don't have. Devfs only shows those devices available on my
2577 +system. This means that listing /dev is a handy way of checking what
2578 +devices are available.
2579 +
2580 +Major&minor size
2581 +
2582 +Existing major and minor numbers are limited to 8 bits each. This is
2583 +now a limiting factor for some drivers, particularly the SCSI disc
2584 +driver, which consumes a single major number. Only 16 discs are
2585 +supported, and each disc may have only 15 partitions. Maybe this isn't
2586 +a problem for you, but some of us are building huge Linux systems with
2587 +disc arrays. With devfs an arbitrary pointer can be associated with
2588 +each device entry, which can be used to give an effective 32 bit
2589 +device identifier (i.e. that's like having a 32 bit minor
2590 +number). Since this is private to the kernel, there are no C library
2591 +compatibility issues which you would have with increasing major and
2592 +minor number sizes. See the section on "Allocation of Device Numbers"
2593 +for details on maintaining compatibility with userspace.
2594 +
2595 +Solving this requires a kernel change.
2596 +
2597 +Since writing this, the kernel has been modified so that the SCSI disc
2598 +driver has more major numbers allocated to it and now supports up to
2599 +128 discs. Since these major numbers are non-contiguous (a result of
2600 +unplanned expansion), the implementation is a little more cumbersome
2601 +than originally.
2602 +
2603 +Just like the changes to IPv4 to fix impending limitations in the
2604 +address space, people find ways around the limitations. In the long
2605 +run, however, solutions like IPv6 or devfs can't be put off forever.
2606 +
2607 +Read-only root filesystem
2608 +
2609 +Having your device nodes on the root filesystem means that you can't
2610 +operate properly with a read-only root filesystem. This is because you
2611 +want to change ownerships and protections of tty devices. Existing
2612 +practice prevents you using a CD-ROM as your root filesystem for a
2613 +*real* system. Sure, you can boot off a CD-ROM, but you can't change
2614 +tty ownerships, so it's only good for installing.
2615 +
2616 +Also, you can't use a shared NFS root filesystem for a cluster of
2617 +discless Linux machines (having tty ownerships changed on a common
2618 +/dev is not good). Nor can you embed your root filesystem in a
2619 +ROM-FS.
2620 +
2621 +You can get around this by creating a RAMDISC at boot time, making
2622 +an ext2 filesystem in it, mounting it somewhere and copying the
2623 +contents of /dev into it, then unmounting it and mounting it over
2624 +/dev.
2625 +
2626 +A devfs is a cleaner way of solving this.
2627 +
2628 +Non-Unix root filesystem
2629 +
2630 +Non-Unix filesystems (such as NTFS) can't be used for a root
2631 +filesystem because they variously don't support character and block
2632 +special files or symbolic links. You can't have a separate disc-based
2633 +or RAMDISC-based filesystem mounted on /dev because you need device
2634 +nodes before you can mount these. Devfs can be mounted without any
2635 +device nodes. Devlinks won't work because symlinks aren't supported.
2636 +An alternative solution is to use initrd to mount a RAMDISC initial
2637 +root filesystem (which is populated with a minimal set of device
2638 +nodes), and then construct a new /dev in another RAMDISC, and finally
2639 +switch to your non-Unix root filesystem. This requires clever boot
2640 +scripts and a fragile and conceptually complex boot procedure.
2641 +
2642 +Devfs solves this in a robust and conceptually simple way.
2643 +
2644 +PTY security
2645 +
2646 +Current pseudo-tty (pty) devices are owned by root and read-writable
2647 +by everyone. The user of a pty-pair cannot change
2648 +ownership/protections without being suid-root.
2649 +
2650 +This could be solved with a secure user-space daemon which runs as
2651 +root and does the actual creation of pty-pairs. Such a daemon would
2652 +require modification to *every* programme that wants to use this new
2653 +mechanism. It also slows down creation of pty-pairs.
2654 +
2655 +An alternative is to create a new open_pty() syscall which does much
2656 +the same thing as the user-space daemon. Once again, this requires
2657 +modifications to pty-handling programmes.
2658 +
2659 +The devfs solution allows a device driver to "tag" certain device
2660 +files so that when an unopened device is opened, the ownerships are
2661 +changed to the current euid and egid of the opening process, and the
2662 +protections are changed to the default registered by the driver. When
2663 +the device is closed ownership is set back to root and protections are
2664 +set back to read-write for everybody. No programme need be changed.
2665 +The devpts filesystem provides this auto-ownership feature for Unix98
2666 +ptys. It doesn't support old-style pty devices, nor does it have all
2667 +the other features of devfs.
2668 +
2669 +Intelligent device management
2670 +
2671 +Devfs implements a simple yet powerful protocol for communication with
2672 +a device management daemon (devfsd) which runs in user space. It is
2673 +possible to send a message (either synchronously or asynchronously) to
2674 +devfsd on any event, such as registration/unregistration of device
2675 +entries, opening and closing devices, looking up inodes, scanning
2676 +directories and more. This has many possibilities. Some of these are
2677 +already implemented. See:
2678 +
2679 +
2680 +http://www.atnf.csiro.au/~rgooch/linux/
2681 +
2682 +Device entry registration events can be used by devfsd to change
2683 +permissions of newly-created device nodes. This is one mechanism to
2684 +control device permissions.
2685 +
2686 +Device entry registration/unregistration events can be used to run
2687 +programmes or scripts. This can be used to provide automatic mounting
2688 +of filesystems when a new block device media is inserted into the
2689 +drive.
2690 +
2691 +Asynchronous device open and close events can be used to implement
2692 +clever permissions management. For example, the default permissions on
2693 +/dev/dsp do not allow everybody to read from the device. This is
2694 +sensible, as you don't want some remote user recording what you say at
2695 +your console. However, the console user is also prevented from
2696 +recording. This behaviour is not desirable. With asynchronous device
2697 +open and close events, you can have devfsd run a programme or script
2698 +when console devices are opened to change the ownerships for *other*
2699 +device nodes (such as /dev/dsp). On closure, you can run a different
2700 +script to restore permissions. An advantage of this scheme over
2701 +modifying the C library tty handling is that this works even if your
2702 +programme crashes (how many times have you seen the utmp database with
2703 +lingering entries for non-existent logins?).
2704 +
2705 +Synchronous device open events can be used to perform intelligent
2706 +device access protections. Before the device driver open() method is
2707 +called, the daemon must first validate the open attempt, by running an
2708 +external programme or script. This is far more flexible than access
2709 +control lists, as access can be determined on the basis of other
2710 +system conditions instead of just the UID and GID.
2711 +
2712 +Inode lookup events can be used to authenticate module autoload
2713 +requests. Instead of using kmod directly, the event is sent to
2714 +devfsd which can implement an arbitrary authentication before loading
2715 +the module itself.
2716 +
2717 +Inode lookup events can also be used to construct arbitrary
2718 +namespaces, without having to resort to populating devfs with symlinks
2719 +to devices that don't exist.
2720 +
2721 +Speculative Device Scanning
2722 +
2723 +Consider an application (like cdparanoia) that wants to find all
2724 +CD-ROM devices on the system (SCSI, IDE and other types), whether or
2725 +not their respective modules are loaded. The application must
2726 +speculatively open certain device nodes (such as /dev/sr0 for the SCSI
2727 +CD-ROMs) in order to make sure the module is loaded. This requires
2728 +that all Linux distributions follow the standard device naming scheme
2729 +(last time I looked RedHat did things differently). Devfs solves the
2730 +naming problem.
2731 +
2732 +The same application also wants to see which devices are actually
2733 +available on the system. With the existing system it needs to read the
2734 +/dev directory and speculatively open each /dev/sr* device to
2735 +determine if the device exists or not. With a large /dev this is an
2736 +inefficient operation, especially if there are many /dev/sr* nodes. A
2737 +solution like scsidev could reduce the number of /dev/sr* entries (but
2738 +of course that also requires all that inefficient directory scanning).
2739 +
2740 +With devfs, the application can open the /dev/sr directory
2741 +(which triggers the module autoloading if required), and proceed to
2742 +read /dev/sr. Since only the available devices will have
2743 +entries, there are no inefficencies in directory scanning or device
2744 +openings.
2745 +
2746 +-----------------------------------------------------------------------------
2747 +
2748 +Who else does it?
2749 +
2750 +FreeBSD has a devfs implementation. Solaris and AIX each have a
2751 +pseudo-devfs (something akin to scsidev but for all devices, with some
2752 +unspecified kernel support). BeOS, Plan9 and QNX also have it. SGI's
2753 +IRIX 6.4 and above also have a device filesystem.
2754 +
2755 +While we shouldn't just automatically do something because others do
2756 +it, we should not ignore the work of others either. FreeBSD has a lot
2757 +of competent people working on it, so their opinion should not be
2758 +blithely ignored.
2759 +
2760 +-----------------------------------------------------------------------------
2761 +
2762 +
2763 +How it works
2764 +
2765 +Registering device entries
2766 +
2767 +For every entry (device node) in a devfs-based /dev a driver must call
2768 +devfs_register(). This adds the name of the device entry, the
2769 +file_operations structure pointer and a few other things to an
2770 +internal table. Device entries may be added and removed at any
2771 +time. When a device entry is registered, it automagically appears in
2772 +any mounted devfs'.
2773 +
2774 +Inode lookup
2775 +
2776 +When a lookup operation on an entry is performed and if there is no
2777 +driver information for that entry devfs will attempt to call
2778 +devfsd. If still no driver information can be found then a negative
2779 +dentry is yielded and the next stage operation will be called by the
2780 +VFS (such as create() or mknod() inode methods). If driver information
2781 +can be found, an inode is created (if one does not exist already) and
2782 +all is well.
2783 +
2784 +Manually creating device nodes
2785 +
2786 +The mknod() method allows you to create an ordinary named pipe in the
2787 +devfs, or you can create a character or block special inode if one
2788 +does not already exist. You may wish to create a character or block
2789 +special inode so that you can set permissions and ownership. Later, if
2790 +a device driver registers an entry with the same name, the
2791 +permissions, ownership and times are retained. This is how you can set
2792 +the protections on a device even before the driver is loaded. Once you
2793 +create an inode it appears in the directory listing.
2794 +
2795 +Unregistering device entries
2796 +
2797 +A device driver calls devfs_unregister() to unregister an entry.
2798 +
2799 +Chroot() gaols
2800 +
2801 +2.2.x kernels
2802 +
2803 +The semantics of inode creation are different when devfs is mounted
2804 +with the "explicit" option. Now, when a device entry is registered, it
2805 +will not appear until you use mknod() to create the device. It doesn't
2806 +matter if you mknod() before or after the device is registered with
2807 +devfs_register(). The purpose of this behaviour is to support
2808 +chroot(2) gaols, where you want to mount a minimal devfs inside the
2809 +gaol. Only the devices you specifically want to be available (through
2810 +your mknod() setup) will be accessible.
2811 +
2812 +2.4.x kernels
2813 +
2814 +As of kernel 2.3.99, the VFS has had the ability to rebind parts of
2815 +the global filesystem namespace into another part of the namespace.
2816 +This now works even at the leaf-node level, which means that
2817 +individual files and device nodes may be bound into other parts of the
2818 +namespace. This is like making links, but better, because it works
2819 +across filesystems (unlike hard links) and works through chroot()
2820 +gaols (unlike symbolic links).
2821 +
2822 +Because of these improvements to the VFS, the multi-mount capability
2823 +in devfs is no longer needed. The administrator may create a minimal
2824 +device tree inside a chroot(2) gaol by using VFS bindings. As this
2825 +provides most of the features of the devfs multi-mount capability, I
2826 +removed the multi-mount support code (after issuing an RFC). This
2827 +yielded code size reductions and simplifications.
2828 +
2829 +If you want to construct a minimal chroot() gaol, the following
2830 +command should suffice:
2831 +
2832 +mount --bind /dev/null /gaol/dev/null
2833 +
2834 +
2835 +Repeat for other device nodes you want to expose. Simple!
2836 +
2837 +-----------------------------------------------------------------------------
2838 +
2839 +
2840 +Operational issues
2841 +
2842 +
2843 +Instructions for the impatient
2844 +
2845 +Nobody likes reading documentation. People just want to get in there
2846 +and play. So this section tells you quickly the steps you need to take
2847 +to run with devfs mounted over /dev. Skip these steps and you will end
2848 +up with a nearly unbootable system. Subsequent sections describe the
2849 +issues in more detail, and discuss non-essential configuration
2850 +options.
2851 +
2852 +Devfsd
2853 +OK, if you're reading this, I assume you want to play with
2854 +devfs. First you should ensure that /usr/src/linux contains a
2855 +recent kernel source tree. Then you need to compile devfsd, the device
2856 +management daemon, available at
2857 +
2858 +http://www.atnf.csiro.au/~rgooch/linux/.
2859 +Because the kernel has a naming scheme
2860 +which is quite different from the old naming scheme, you need to
2861 +install devfsd so that software and configuration files that use the
2862 +old naming scheme will not break.
2863 +
2864 +Compile and install devfsd. You will be provided with a default
2865 +configuration file /etc/devfsd.conf which will provide
2866 +compatibility symlinks for the old naming scheme. Don't change this
2867 +config file unless you know what you're doing. Even if you think you
2868 +do know what you're doing, don't change it until you've followed all
2869 +the steps below and booted a devfs-enabled system and verified that it
2870 +works.
2871 +
2872 +Now edit your main system boot script so that devfsd is started at the
2873 +very beginning (before any filesystem
2874 +checks). /etc/rc.d/rc.sysinit is often the main boot script
2875 +on systems with SysV-style boot scripts. On systems with BSD-style
2876 +boot scripts it is often /etc/rc. Also check
2877 +/sbin/rc.
2878 +
2879 +NOTE that the line you put into the boot
2880 +script should be exactly:
2881 +
2882 +/sbin/devfsd /dev
2883 +
2884 +DO NOT use some special daemon-launching
2885 +programme, otherwise the boot script may not wait for devfsd to finish
2886 +initialising.
2887 +
2888 +System Libraries
2889 +There may still be some problems because of broken software making
2890 +assumptions about device names. In particular, some software does not
2891 +handle devices which are symbolic links. If you are running a libc 5
2892 +based system, install libc 5.4.44 (if you have libc 5.4.46, go back to
2893 +libc 5.4.44, which is actually correct). If you are running a glibc
2894 +based system, make sure you have glibc 2.1.3 or later.
2895 +
2896 +/etc/securetty
2897 +PAM (Pluggable Authentication Modules) is supposed to be a flexible
2898 +mechanism for providing better user authentication and access to
2899 +services. Unfortunately, it's also fragile, complex and undocumented
2900 +(check out RedHat 6.1, and probably other distributions as well). PAM
2901 +has problems with symbolic links. Append the following lines to your
2902 +/etc/securetty file:
2903 +
2904 +vc/1
2905 +vc/2
2906 +vc/3
2907 +vc/4
2908 +vc/5
2909 +vc/6
2910 +vc/7
2911 +vc/8
2912 +
2913 +This will not weaken security. If you have a version of util-linux
2914 +earlier than 2.10.h, please upgrade to 2.10.h or later. If you
2915 +absolutely cannot upgrade, then also append the following lines to
2916 +your /etc/securetty file:
2917 +
2918 +1
2919 +2
2920 +3
2921 +4
2922 +5
2923 +6
2924 +7
2925 +8
2926 +
2927 +This may potentially weaken security by allowing root logins over the
2928 +network (a password is still required, though). However, since there
2929 +are problems with dealing with symlinks, I'm suspicious of the level
2930 +of security offered in any case.
2931 +
2932 +XFree86
2933 +While not essential, it's probably a good idea to upgrade to XFree86
2934 +4.0, as patches went in to make it more devfs-friendly. If you don't,
2935 +you'll probably need to apply the following patch to
2936 +/etc/security/console.perms so that ordinary users can run
2937 +startx. Note that not all distributions have this file (e.g. Debian),
2938 +so if it's not present, don't worry about it.
2939 +
2940 +--- /etc/security/console.perms.orig    Sat Apr 17 16:26:47 1999 
2941 ++++ /etc/security/console.perms Fri Feb 25 23:53:55 2000 
2942 +@@ -14,7 +14,7 @@ 
2943 + # man 5 console.perms 
2944 +
2945 + # file classes -- these are regular expressions 
2946 +-<console>=tty[0-9][0-9]* :[0-9]\.[0-9] :[0-9] 
2947 ++<console>=tty[0-9][0-9]* vc/[0-9][0-9]* :[0-9]\.[0-9] :[0-9] 
2948 +
2949 + # device classes -- these are shell-style globs 
2950 + <floppy>=/dev/fd[0-1]* 
2951 +
2952 +If the patch does not apply, then change the line:
2953 +
2954 +<console>=tty[0-9][0-9]* :[0-9]\.[0-9] :[0-9]
2955 +
2956 +with:
2957 +
2958 +<console>=tty[0-9][0-9]* vc/[0-9][0-9]* :[0-9]\.[0-9] :[0-9]
2959 +
2960 +
2961 +Disable devpts
2962 +I've had a report of devpts mounted on /dev/pts not working
2963 +correctly. Since devfs will also manage /dev/pts, there is no
2964 +need to mount devpts as well. You should either edit your
2965 +/etc/fstab so devpts is not mounted, or disable devpts from
2966 +your kernel configuration.
2967 +
2968 +Unsupported drivers
2969 +Not all drivers have devfs support. If you depend on one of these
2970 +drivers, you will need to create a script or tarfile that you can use
2971 +at boot time to create device nodes as appropriate. There is a
2972 +section which describes this. Another
2973 +section lists the drivers which have
2974 +devfs support.
2975 +
2976 +/dev/mouse
2977 +
2978 +Many disributions configure /dev/mouse to be the mouse device
2979 +for XFree86 and GPM. I actually think this is a bad idea, because it
2980 +adds another level of indirection. When looking at a config file, if
2981 +you see /dev/mouse you're left wondering which mouse
2982 +is being referred to. Hence I recommend putting the actual mouse
2983 +device (for example /dev/psaux) into your
2984 +/etc/X11/XF86Config file (and similarly for the GPM
2985 +configuration file).
2986 +
2987 +Alternatively, use the same technique used for unsupported drivers
2988 +described above.
2989 +
2990 +The Kernel
2991 +Finally, you need to make sure devfs is compiled into your kernel. Set
2992 +CONFIG_EXPERIMENTAL=y, CONFIG_DEVFS_FS=y and CONFIG_DEVFS_MOUNT=y by
2993 +using favourite configuration tool (i.e. make config or
2994 +make xconfig) and then make clean and then recompile your kernel and 
2995 +modules. At boot, devfs will be mounted onto /dev.
2996 +
2997 +If you encounter problems booting (for example if you forgot a
2998 +configuration step), you can pass devfs=nomount at the kernel
2999 +boot command line. This will prevent the kernel from mounting devfs at
3000 +boot time onto /dev.
3001 +
3002 +In general, a kernel built with CONFIG_DEVFS_FS=y but without mounting
3003 +devfs onto /dev is completely safe, and requires no
3004 +configuration changes. One exception to take note of is when
3005 +LABEL= directives are used in /etc/fstab. In this
3006 +case you will be unable to boot properly. This is because the
3007 +mount(8) programme uses /proc/partitions as part of
3008 +the volume label search process, and the device names it finds are not
3009 +available, because setting CONFIG_DEVFS_FS=y changes the names in
3010 +/proc/partitions, irrespective of whether devfs is mounted.
3011 +
3012 +Now you've finished all the steps required. You're now ready to boot
3013 +your shiny new kernel. Enjoy.
3014 +
3015 +Changing the configuration
3016 +
3017 +OK, you've now booted a devfs-enabled system, and everything works.
3018 +Now you may feel like changing the configuration (common targets are
3019 +/etc/fstab and /etc/devfsd.conf). Since you have a
3020 +system that works, if you make any changes and it doesn't work, you
3021 +now know that you only have to restore your configuration files to the
3022 +default and it will work again.
3023 +
3024 +
3025 +Permissions persistence across reboots
3026 +
3027 +If you don't use mknod(2) to create a device file, nor use chmod(2) or
3028 +chown(2) to change the ownerships/permissions, the inode ctime will
3029 +remain at 0 (the epoch, 12 am, 1-JAN-1970, GMT). Anything with a ctime
3030 +later than this has had it's ownership/permissions changed. Hence, a
3031 +simple script or programme may be used to tar up all changed inodes,
3032 +prior to shutdown. Although effective, many consider this approach a
3033 +kludge.
3034 +
3035 +A much better approach is to use devfsd to save and restore
3036 +permissions. It may be configured to record changes in permissions and
3037 +will save them in a database (in fact a directory tree), and restore
3038 +these upon boot. This is an efficient method and results in immediate
3039 +saving of current permissions (unlike the tar approach, which saves
3040 +permissions at some unspecified future time).
3041 +
3042 +The default configuration file supplied with devfsd has config entries
3043 +which you may uncomment to enable persistence management.
3044 +
3045 +If you decide to use the tar approach anyway, be aware that tar will
3046 +first unlink(2) an inode before creating a new device node. The
3047 +unlink(2) has the effect of breaking the connection between a devfs
3048 +entry and the device driver. If you use the "devfs=only" boot option,
3049 +you lose access to the device driver, requiring you to reload the
3050 +module. I consider this a bug in tar (there is no real need to
3051 +unlink(2) the inode first).
3052 +
3053 +Alternatively, you can use devfsd to provide more sophisticated
3054 +management of device permissions. You can use devfsd to store
3055 +permissions for whole groups of devices with a single configuration
3056 +entry, rather than the conventional single entry per device entry.
3057 +
3058 +Permissions database stored in mounted-over /dev
3059 +
3060 +If you wish to save and restore your device permissions into the
3061 +disc-based /dev while still mounting devfs onto /dev
3062 +you may do so. This requires a 2.4.x kernel (in fact, 2.3.99 or
3063 +later), which has the VFS binding facility. You need to do the
3064 +following to set this up:
3065 +
3066 +
3067 +
3068 +make sure the kernel does not mount devfs at boot time
3069 +
3070 +
3071 +make sure you have a correct /dev/console entry in your
3072 +root file-system (where your disc-based /dev lives)
3073 +
3074 +create the /dev-state directory
3075 +
3076 +
3077 +add the following lines near the very beginning of your boot
3078 +scripts:
3079 +
3080 +mount --bind /dev /dev-state
3081 +mount -t devfs none /dev
3082 +devfsd /dev
3083 +
3084 +
3085 +
3086 +
3087 +add the following lines to your /etc/devfsd.conf file:
3088 +
3089 +REGISTER       ^pt[sy]         IGNORE
3090 +CREATE         ^pt[sy]         IGNORE
3091 +CHANGE         ^pt[sy]         IGNORE
3092 +DELETE         ^pt[sy]         IGNORE
3093 +REGISTER       .*              COPY    /dev-state/$devname $devpath
3094 +CREATE         .*              COPY    $devpath /dev-state/$devname
3095 +CHANGE         .*              COPY    $devpath /dev-state/$devname
3096 +DELETE         .*              CFUNCTION GLOBAL unlink /dev-state/$devname
3097 +RESTORE                /dev-state
3098 +
3099 +Note that the sample devfsd.conf file contains these lines,
3100 +as well as other sample configurations you may find useful. See the
3101 +devfsd distribution
3102 +
3103 +
3104 +reboot.
3105 +
3106 +
3107 +
3108 +
3109 +Permissions database stored in normal directory
3110 +
3111 +If you are using an older kernel which doesn't support VFS binding,
3112 +then you won't be able to have the permissions database in a
3113 +mounted-over /dev. However, you can still use a regular
3114 +directory to store the database. The sample /etc/devfsd.conf
3115 +file above may still be used. You will need to create the
3116 +/dev-state directory prior to installing devfsd. If you have
3117 +old permissions in /dev, then just copy (or move) the device
3118 +nodes over to the new directory.
3119 +
3120 +Which method is better?
3121 +
3122 +The best method is to have the permissions database stored in the
3123 +mounted-over /dev. This is because you will not need to copy
3124 +device nodes over to /dev-state, and because it allows you to
3125 +switch between devfs and non-devfs kernels, without requiring you to
3126 +copy permissions between /dev-state (for devfs) and
3127 +/dev (for non-devfs).
3128 +
3129 +
3130 +Dealing with drivers without devfs support
3131 +
3132 +Currently, not all device drivers in the kernel have been modified to
3133 +use devfs. Device drivers which do not yet have devfs support will not
3134 +automagically appear in devfs. The simplest way to create device nodes
3135 +for these drivers is to unpack a tarfile containing the required
3136 +device nodes. You can do this in your boot scripts. All your drivers
3137 +will now work as before.
3138 +
3139 +Hopefully for most people devfs will have enough support so that they
3140 +can mount devfs directly over /dev without losing most functionality
3141 +(i.e. losing access to various devices). As of 22-JAN-1998 (devfs
3142 +patch version 10) I am now running this way. All the devices I have
3143 +are available in devfs, so I don't lose anything.
3144 +
3145 +WARNING: if your configuration requires the old-style device names
3146 +(i.e. /dev/hda1 or /dev/sda1), you must install devfsd and configure
3147 +it to maintain compatibility entries. It is almost certain that you
3148 +will require this. Note that the kernel creates a compatibility entry
3149 +for the root device, so you don't need initrd.
3150 +
3151 +Note that you no longer need to mount devpts if you use Unix98 PTYs,
3152 +as devfs can manage /dev/pts itself. This saves you some RAM, as you
3153 +don't need to compile and install devpts. Note that some versions of
3154 +glibc have a bug with Unix98 pty handling on devfs systems. Contact
3155 +the glibc maintainers for a fix. Glibc 2.1.3 has the fix.
3156 +
3157 +Note also that apart from editing /etc/fstab, other things will need
3158 +to be changed if you *don't* install devfsd. Some software (like the X
3159 +server) hard-wire device names in their source. It really is much
3160 +easier to install devfsd so that compatibility entries are created.
3161 +You can then slowly migrate your system to using the new device names
3162 +(for example, by starting with /etc/fstab), and then limiting the
3163 +compatibility entries that devfsd creates.
3164 +
3165 +IF YOU CONFIGURE TO MOUNT DEVFS AT BOOT, MAKE SURE YOU INSTALL DEVFSD
3166 +BEFORE YOU BOOT A DEVFS-ENABLED KERNEL!
3167 +
3168 +Now that devfs has gone into the 2.3.46 kernel, I'm getting a lot of
3169 +reports back. Many of these are because people are trying to run
3170 +without devfsd, and hence some things break. Please just run devfsd if
3171 +things break. I want to concentrate on real bugs rather than
3172 +misconfiguration problems at the moment. If people are willing to fix
3173 +bugs/false assumptions in other code (i.e. glibc, X server) and submit
3174 +that to the respective maintainers, that would be great.
3175 +
3176 +
3177 +All the way with Devfs
3178 +
3179 +The devfs kernel patch creates a rationalised device tree. As stated
3180 +above, if you want to keep using the old /dev naming scheme,
3181 +you just need to configure devfsd appopriately (see the man
3182 +page). People who prefer the old names can ignore this section. For
3183 +those of us who like the rationalised names and an uncluttered
3184 +/dev, read on.
3185 +
3186 +If you don't run devfsd, or don't enable compatibility entry
3187 +management, then you will have to configure your system to use the new
3188 +names. For example, you will then need to edit your
3189 +/etc/fstab to use the new disc naming scheme. If you want to
3190 +be able to boot non-devfs kernels, you will need compatibility
3191 +symlinks in the underlying disc-based /dev pointing back to
3192 +the old-style names for when you boot a kernel without devfs.
3193 +
3194 +You can selectively decide which devices you want compatibility
3195 +entries for. For example, you may only want compatibility entries for
3196 +BSD pseudo-terminal devices (otherwise you'll have to patch you C
3197 +library or use Unix98 ptys instead). It's just a matter of putting in
3198 +the correct regular expression into /dev/devfsd.conf.
3199 +
3200 +There are other choices of naming schemes that you may prefer. For
3201 +example, I don't use the kernel-supplied
3202 +names, because they are too verbose. A common misconception is
3203 +that the kernel-supplied names are meant to be used directly in
3204 +configuration files. This is not the case. They are designed to
3205 +reflect the layout of the devices attached and to provide easy
3206 +classification.
3207 +
3208 +If you like the kernel-supplied names, that's fine. If you don't then
3209 +you should be using devfsd to construct a namespace more to your
3210 +liking. Devfsd has built-in code to construct a
3211 +namespace that is both logical and easy to
3212 +manage. In essence, it creates a convenient abbreviation of the
3213 +kernel-supplied namespace.
3214 +
3215 +You are of course free to build your own namespace. Devfsd has all the
3216 +infrastructure required to make this easy for you. All you need do is
3217 +write a script. You can even write some C code and devfsd can load the
3218 +shared object as a callable extension.
3219 +
3220 +
3221 +Other Issues
3222 +
3223 +The init programme
3224 +Another thing to take note of is whether your init programme
3225 +creates a Unix socket /dev/telinit. Some versions of init
3226 +create /dev/telinit so that the telinit programme can
3227 +communicate with the init process. If you have such a system you need
3228 +to make sure that devfs is mounted over /dev *before* init
3229 +starts. In other words, you can't leave the mounting of devfs to
3230 +/etc/rc, since this is executed after init. Other
3231 +versions of init require a named pipe /dev/initctl
3232 +which must exist *before* init starts. Once again, you need to
3233 +mount devfs and then create the named pipe *before* init
3234 +starts.
3235 +
3236 +The default behaviour now is not to mount devfs onto /dev at
3237 +boot time for 2.3.x and later kernels. You can correct this with the
3238 +"devfs=mount" boot option. This solves any problems with init,
3239 +and also prevents the dreaded:
3240 +
3241 +Cannot open initial console
3242 +
3243 +message. For 2.2.x kernels where you need to apply the devfs patch,
3244 +the default is to mount.
3245 +
3246 +If you have automatic mounting of devfs onto /dev then you
3247 +may need to create /dev/initctl in your boot scripts. The
3248 +following lines should suffice:
3249 +
3250 +mknod /dev/initctl p
3251 +kill -SIGUSR1 1       # tell init that /dev/initctl now exists
3252 +
3253 +Alternatively, if you don't want the kernel to mount devfs onto
3254 +/dev then you could use the following procedure is a
3255 +guideline for how to get around /dev/initctl problems:
3256 +
3257 +# cd /sbin
3258 +# mv init init.real
3259 +# cat > init
3260 +#! /bin/sh
3261 +mount -n -t devfs none /dev
3262 +mknod /dev/initctl p
3263 +exec /sbin/init.real $*
3264 +[control-D]
3265 +# chmod a+x init
3266 +
3267 +Note that newer versions of init create /dev/initctl
3268 +automatically, so you don't have to worry about this.
3269 +
3270 +Module autoloading
3271 +You will need to configure devfsd to enable module
3272 +autoloading. The following lines should be placed in your
3273 +/etc/devfsd.conf file:
3274 +
3275 +LOOKUP .*              MODLOAD
3276 +
3277 +
3278 +As of devfsd-v1.3.10, a generic /etc/modules.devfs
3279 +configuration file is installed, which is used by the MODLOAD
3280 +action. This should be sufficient for most configurations. If you
3281 +require further configuration, edit your /etc/modules.conf
3282 +file. The way module autoloading work with devfs is:
3283 +
3284 +
3285 +a process attempts to lookup a device node (e.g. /dev/fred)
3286 +
3287 +
3288 +if that device node does not exist, the full pathname is passed to
3289 +devfsd as a string
3290 +
3291 +
3292 +devfsd will pass the string to the modprobe programme (provided the
3293 +configuration line shown above is present), and specifies that
3294 +/etc/modules.devfs is the configuration file
3295 +
3296 +
3297 +/etc/modules.devfs includes /etc/modules.conf to
3298 +access local configurations
3299 +
3300 +modprobe will search it's configuration files, looking for an alias
3301 +that translates the pathname into a module name
3302 +
3303 +
3304 +the translated pathname is then used to load the module.
3305 +
3306 +
3307 +If you wanted a lookup of /dev/fred to load the
3308 +mymod module, you would require the following configuration
3309 +line in /etc/modules.conf:
3310 +
3311 +alias    /dev/fred    mymod
3312 +
3313 +The /etc/modules.devfs configuration file provides many such
3314 +aliases for standard device names. If you look closely at this file,
3315 +you will note that some modules require multiple alias configuration
3316 +lines. This is required to support module autoloading for old and new
3317 +device names.
3318 +
3319 +Mounting root off a devfs device
3320 +If you wish to mount root off a devfs device when you pass the
3321 +"devfs=only" boot option, then you need to pass in the
3322 +"root=<device>" option to the kernel when booting. If you use
3323 +LILO, then you must have this in lilo.conf:
3324 +
3325 +append = "root=<device>"
3326 +
3327 +Surprised? Yep, so was I. It turns out if you have (as most people
3328 +do):
3329 +
3330 +root = <device>
3331 +
3332 +
3333 +then LILO will determine the device number of <device> and will
3334 +write that device number into a special place in the kernel image
3335 +before starting the kernel, and the kernel will use that device number
3336 +to mount the root filesystem. So, using the "append" variety ensures
3337 +that LILO passes the root filesystem device as a string, which devfs
3338 +can then use.
3339 +
3340 +Note that this isn't an issue if you don't pass "devfs=only".
3341 +
3342 +TTY issues
3343 +The ttyname(3) function in some versions of the C library makes
3344 +false assumptions about device entries which are symbolic links.  The
3345 +tty(1) programme is one that depends on this function.  I've
3346 +written a patch to libc 5.4.43 which fixes this. This has been
3347 +included in libc 5.4.44 and a similar fix is in glibc 2.1.3.
3348 +
3349 +
3350 +Kernel Naming Scheme
3351 +
3352 +The kernel provides a default naming scheme. This scheme is designed
3353 +to make it easy to search for specific devices or device types, and to
3354 +view the available devices. Some device types (such as hard discs),
3355 +have a directory of entries, making it easy to see what devices of
3356 +that class are available. Often, the entries are symbolic links into a
3357 +directory tree that reflects the topology of available devices. The
3358 +topological tree is useful for finding how your devices are arranged.
3359 +
3360 +Below is a list of the naming schemes for the most common drivers. A
3361 +list of reserved device names is
3362 +available for reference. Please send email to
3363 +rgooch@atnf.csiro.au to obtain an allocation. Please be
3364 +patient (the maintainer is busy). An alternative name may be allocated
3365 +instead of the requested name, at the discretion of the maintainer.
3366 +
3367 +Disc Devices
3368 +
3369 +All discs, whether SCSI, IDE or whatever, are placed under the
3370 +/dev/discs hierarchy:
3371 +
3372 +       /dev/discs/disc0        first disc
3373 +       /dev/discs/disc1        second disc
3374 +
3375 +
3376 +Each of these entries is a symbolic link to the directory for that
3377 +device. The device directory contains:
3378 +
3379 +       disc    for the whole disc
3380 +       part*   for individual partitions
3381 +
3382 +
3383 +CD-ROM Devices
3384 +
3385 +All CD-ROMs, whether SCSI, IDE or whatever, are placed under the
3386 +/dev/cdroms hierarchy:
3387 +
3388 +       /dev/cdroms/cdrom0      first CD-ROM
3389 +       /dev/cdroms/cdrom1      second CD-ROM
3390 +
3391 +
3392 +Each of these entries is a symbolic link to the real device entry for
3393 +that device.
3394 +
3395 +Tape Devices
3396 +
3397 +All tapes, whether SCSI, IDE or whatever, are placed under the
3398 +/dev/tapes hierarchy:
3399 +
3400 +       /dev/tapes/tape0        first tape
3401 +       /dev/tapes/tape1        second tape
3402 +
3403 +
3404 +Each of these entries is a symbolic link to the directory for that
3405 +device. The device directory contains:
3406 +
3407 +       mt                      for mode 0
3408 +       mtl                     for mode 1
3409 +       mtm                     for mode 2
3410 +       mta                     for mode 3
3411 +       mtn                     for mode 0, no rewind
3412 +       mtln                    for mode 1, no rewind
3413 +       mtmn                    for mode 2, no rewind
3414 +       mtan                    for mode 3, no rewind
3415 +
3416 +
3417 +SCSI Devices
3418 +
3419 +To uniquely identify any SCSI device requires the following
3420 +information:
3421 +
3422 +  controller   (host adapter)
3423 +  bus          (SCSI channel)
3424 +  target       (SCSI ID)
3425 +  unit         (Logical Unit Number)
3426 +
3427 +
3428 +All SCSI devices are placed under /dev/scsi (assuming devfs
3429 +is mounted on /dev). Hence, a SCSI device with the following
3430 +parameters: c=1,b=2,t=3,u=4 would appear as:
3431 +
3432 +       /dev/scsi/host1/bus2/target3/lun4       device directory
3433 +
3434 +
3435 +Inside this directory, a number of device entries may be created,
3436 +depending on which SCSI device-type drivers were installed.
3437 +
3438 +See the section on the disc naming scheme to see what entries the SCSI
3439 +disc driver creates.
3440 +
3441 +See the section on the tape naming scheme to see what entries the SCSI
3442 +tape driver creates.
3443 +
3444 +The SCSI CD-ROM driver creates:
3445 +
3446 +       cd
3447 +
3448 +
3449 +The SCSI generic driver creates:
3450 +
3451 +       generic
3452 +
3453 +
3454 +IDE Devices
3455 +
3456 +To uniquely identify any IDE device requires the following
3457 +information:
3458 +
3459 +  controller
3460 +  bus          (aka. primary/secondary)
3461 +  target       (aka. master/slave)
3462 +  unit
3463 +
3464 +
3465 +All IDE devices are placed under /dev/ide, and uses a similar
3466 +naming scheme to the SCSI subsystem.
3467 +
3468 +XT Hard Discs
3469 +
3470 +All XT discs are placed under /dev/xd. The first XT disc has
3471 +the directory /dev/xd/disc0.
3472 +
3473 +TTY devices
3474 +
3475 +The tty devices now appear as:
3476 +
3477 +  New name                   Old-name                   Device Type
3478 +  --------                   --------                   -----------
3479 +  /dev/tts/{0,1,...}         /dev/ttyS{0,1,...}         Serial ports
3480 +  /dev/cua/{0,1,...}         /dev/cua{0,1,...}          Call out devices
3481 +  /dev/vc/0                  /dev/tty                   Current virtual console
3482 +  /dev/vc/{1,2,...}          /dev/tty{1...63}           Virtual consoles
3483 +  /dev/vcc/{0,1,...}         /dev/vcs{1...63}           Virtual consoles
3484 +  /dev/pty/m{0,1,...}        /dev/ptyp??                PTY masters
3485 +  /dev/pty/s{0,1,...}        /dev/ttyp??                PTY slaves
3486 +
3487 +
3488 +RAMDISCS
3489 +
3490 +The RAMDISCS are placed in their own directory, and are named thus:
3491 +
3492 +  /dev/rd/{0,1,2,...}
3493 +
3494 +
3495 +Meta Devices
3496 +
3497 +The meta devices are placed in their own directory, and are named
3498 +thus:
3499 +
3500 +  /dev/md/{0,1,2,...}
3501 +
3502 +
3503 +Floppy discs
3504 +
3505 +Floppy discs are placed in the /dev/floppy directory.
3506 +
3507 +Loop devices
3508 +
3509 +Loop devices are placed in the /dev/loop directory.
3510 +
3511 +Sound devices
3512 +
3513 +Sound devices are placed in the /dev/sound directory
3514 +(audio, sequencer, ...).
3515 +
3516 +
3517 +Devfsd Naming Scheme
3518 +
3519 +Devfsd provides a naming scheme which is a convenient abbreviation of
3520 +the kernel-supplied namespace. In some
3521 +cases, the kernel-supplied naming scheme is quite convenient, so
3522 +devfsd does not provide another naming scheme. The convenience names
3523 +that devfsd creates are in fact the same names as the original devfs
3524 +kernel patch created (before Linus mandated the Big Name
3525 +Change). These are referred to as "new compatibility entries".
3526 +
3527 +In order to configure devfsd to create these convenience names, the
3528 +following lines should be placed in your /etc/devfsd.conf:
3529 +
3530 +REGISTER       .*              MKNEWCOMPAT
3531 +UNREGISTER     .*              RMNEWCOMPAT
3532 +
3533 +This will cause devfsd to create (and destroy) symbolic links which
3534 +point to the kernel-supplied names.
3535 +
3536 +SCSI Hard Discs
3537 +
3538 +All SCSI discs are placed under /dev/sd (assuming devfs is
3539 +mounted on /dev). Hence, a SCSI disc with the following
3540 +parameters: c=1,b=2,t=3,u=4 would appear as:
3541 +
3542 +       /dev/sd/c1b2t3u4        for the whole disc
3543 +       /dev/sd/c1b2t3u4p5      for the 5th partition
3544 +       /dev/sd/c1b2t3u4p5s6    for the 6th slice in the 5th partition
3545 +
3546 +
3547 +SCSI Tapes
3548 +
3549 +All SCSI tapes are placed under /dev/st. A similar naming
3550 +scheme is used as for SCSI discs. A SCSI tape with the
3551 +parameters:c=1,b=2,t=3,u=4 would appear as:
3552 +
3553 +       /dev/st/c1b2t3u4m0      for mode 0
3554 +       /dev/st/c1b2t3u4m1      for mode 1
3555 +       /dev/st/c1b2t3u4m2      for mode 2
3556 +       /dev/st/c1b2t3u4m3      for mode 3
3557 +       /dev/st/c1b2t3u4m0n     for mode 0, no rewind
3558 +       /dev/st/c1b2t3u4m1n     for mode 1, no rewind
3559 +       /dev/st/c1b2t3u4m2n     for mode 2, no rewind
3560 +       /dev/st/c1b2t3u4m3n     for mode 3, no rewind
3561 +
3562 +
3563 +SCSI CD-ROMs
3564 +
3565 +All SCSI CD-ROMs are placed under /dev/sr. A similar naming
3566 +scheme is used as for SCSI discs. A SCSI CD-ROM with the
3567 +parameters:c=1,b=2,t=3,u=4 would appear as:
3568 +
3569 +       /dev/sr/c1b2t3u4
3570 +
3571 +
3572 +SCSI Generic Devices
3573 +
3574 +The generic (aka. raw) interface for all SCSI devices are placed under
3575 +/dev/sg. A similar naming scheme is used as for SCSI discs. A
3576 +SCSI generic device with the parameters:c=1,b=2,t=3,u=4 would appear
3577 +as:
3578 +
3579 +       /dev/sg/c1b2t3u4
3580 +
3581 +
3582 +IDE Hard Discs
3583 +
3584 +All IDE discs are placed under /dev/ide/hd, using a similar
3585 +convention to SCSI discs. The following mappings exist between the new
3586 +and the old names:
3587 +
3588 +       /dev/hda        /dev/ide/hd/c0b0t0u0
3589 +       /dev/hdb        /dev/ide/hd/c0b0t1u0
3590 +       /dev/hdc        /dev/ide/hd/c0b1t0u0
3591 +       /dev/hdd        /dev/ide/hd/c0b1t1u0
3592 +
3593 +
3594 +IDE Tapes
3595 +
3596 +A similar naming scheme is used as for IDE discs. The entries will
3597 +appear in the /dev/ide/mt directory.
3598 +
3599 +IDE CD-ROM
3600 +
3601 +A similar naming scheme is used as for IDE discs. The entries will
3602 +appear in the /dev/ide/cd directory.
3603 +
3604 +IDE Floppies
3605 +
3606 +A similar naming scheme is used as for IDE discs. The entries will
3607 +appear in the /dev/ide/fd directory.
3608 +
3609 +XT Hard Discs
3610 +
3611 +All XT discs are placed under /dev/xd. The first XT disc
3612 +would appear as /dev/xd/c0t0.
3613 +
3614 +
3615 +Old Compatibility Names
3616 +
3617 +The old compatibility names are the legacy device names, such as
3618 +/dev/hda, /dev/sda, /dev/rtc and so on.
3619 +Devfsd can be configured to create compatibility symlinks so that you
3620 +may continue to use the old names in your configuration files and so
3621 +that old applications will continue to function correctly.
3622 +
3623 +In order to configure devfsd to create these legacy names, the
3624 +following lines should be placed in your /etc/devfsd.conf:
3625 +
3626 +REGISTER       .*              MKOLDCOMPAT
3627 +UNREGISTER     .*              RMOLDCOMPAT
3628 +
3629 +This will cause devfsd to create (and destroy) symbolic links which
3630 +point to the kernel-supplied names.
3631 +
3632 +
3633 +-----------------------------------------------------------------------------
3634 +
3635 +
3636 +Device drivers currently ported
3637 +
3638 +- All miscellaneous character devices support devfs (this is done
3639 +  transparently through misc_register())
3640 +
3641 +- SCSI discs and generic hard discs
3642 +
3643 +- Character memory devices (null, zero, full and so on)
3644 +  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
3645 +
3646 +- Loop devices (/dev/loop?)
3647
3648 +- TTY devices (console, serial ports, terminals and pseudo-terminals)
3649 +  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
3650 +
3651 +- SCSI tapes (/dev/scsi and /dev/tapes)
3652 +
3653 +- SCSI CD-ROMs (/dev/scsi and /dev/cdroms)
3654 +
3655 +- SCSI generic devices (/dev/scsi)
3656 +
3657 +- RAMDISCS (/dev/ram?)
3658 +
3659 +- Meta Devices (/dev/md*)
3660 +
3661 +- Floppy discs (/dev/floppy)
3662 +
3663 +- Parallel port printers (/dev/printers)
3664 +
3665 +- Sound devices (/dev/sound)
3666 +  Thanks to Eric Dumas <dumas@linux.eu.org> and
3667 +  C. Scott Ananian <cananian@alumni.princeton.edu>
3668 +
3669 +- Joysticks (/dev/joysticks)
3670 +
3671 +- Sparc keyboard (/dev/kbd)
3672 +
3673 +- DSP56001 digital signal processor (/dev/dsp56k)
3674 +
3675 +- Apple Desktop Bus (/dev/adb)
3676 +
3677 +- Coda network file system (/dev/cfs*)
3678 +
3679 +- Virtual console capture devices (/dev/vcc)
3680 +  Thanks to Dennis Hou <smilax@mindmeld.yi.org>
3681 +
3682 +- Frame buffer devices (/dev/fb)
3683 +
3684 +- Video capture devices (/dev/v4l)
3685 +
3686 +
3687 +-----------------------------------------------------------------------------
3688 +
3689 +
3690 +Allocation of Device Numbers
3691 +
3692 +Devfs allows you to write a driver which doesn't need to allocate a
3693 +device number (major&minor numbers) for the internal operation of the
3694 +kernel. However, there are a number of userspace programmes that use
3695 +the device number as a unique handle for a device. An example is the
3696 +find programme, which uses device numbers to determine whether
3697 +an inode is on a different filesystem than another inode. The device
3698 +number used is the one for the block device which a filesystem is
3699 +using. To preserve compatibility with userspace programmes, block
3700 +devices using devfs need to have unique device numbers allocated to
3701 +them. Furthermore, POSIX specifies device numbers, so some kind of
3702 +device number needs to be presented to userspace.
3703 +
3704 +The simplest option (especially when porting drivers to devfs) is to
3705 +keep using the old major and minor numbers. Devfs will take whatever
3706 +values are given for major&minor and pass them onto userspace.
3707 +
3708 +This device number is a 16 bit number, so this leaves plenty of space
3709 +for large numbers of discs and partitions. This scheme can also be
3710 +used for character devices, in particular the tty devices, which are
3711 +currently limited to 256 pseudo-ttys (this limits the total number of
3712 +simultaneous xterms and remote logins).  Note that the device number
3713 +is limited to the range 36864-61439 (majors 144-239), in order to
3714 +avoid any possible conflicts with existing official allocations.
3715 +
3716 +Please note that using dynamically allocated block device numbers may
3717 +break the NFS daemons (both user and kernel mode), which expect dev_t
3718 +for a given device to be constant over the lifetime of remote mounts.
3719 +
3720 +A final note on this scheme: since it doesn't increase the size of
3721 +device numbers, there are no compatibility issues with userspace.
3722 +
3723 +-----------------------------------------------------------------------------
3724 +
3725 +
3726 +Questions and Answers
3727 +
3728 +
3729 +Making things work
3730 +Alternatives to devfs
3731 +What I don't like about devfs
3732 +How to report bugs
3733 +Strange kernel messages
3734 +Compilation problems with devfsd
3735 +
3736 +
3737 +
3738 +Making things work
3739 +
3740 +Here are some common questions and answers.
3741 +
3742 +
3743 +
3744 +Devfsd doesn't start
3745 +
3746 +Make sure you have compiled and installed devfsd
3747 +Make sure devfsd is being started from your boot
3748 +scripts
3749 +Make sure you have configured your kernel to enable devfs (see
3750 +below)
3751 +Make sure devfs is mounted (see below)
3752 +
3753 +
3754 +Devfsd is not managing all my permissions
3755 +
3756 +Make sure you are capturing the appropriate events. For example,
3757 +device entries created by the kernel generate REGISTER events,
3758 +but those created by devfsd generate CREATE events.
3759 +
3760 +
3761 +Devfsd is not capturing all REGISTER events
3762 +
3763 +See the previous entry: you may need to capture CREATE events.
3764 +
3765 +
3766 +X will not start
3767 +
3768 +Make sure you followed the steps 
3769 +outlined above.
3770 +
3771 +
3772 +Why don't my network devices appear in devfs?
3773 +
3774 +This is not a bug. Network devices have their own, completely separate
3775 +namespace. They are accessed via socket(2) and
3776 +setsockopt(2) calls, and thus require no device nodes. I have
3777 +raised the possibilty of moving network devices into the device
3778 +namespace, but have had no response.
3779 +
3780 +
3781 +How can I test if I have devfs compiled into my kernel?
3782 +
3783 +All filesystems built-in or currently loaded are listed in
3784 +/proc/filesystems. If you see a devfs entry, then
3785 +you know that devfs was compiled into your kernel. If you have
3786 +correctly configured and rebuilt your kernel, then devfs will be
3787 +built-in. If you think you've configured it in, but
3788 +/proc/filesystems doesn't show it, you've made a mistake.
3789 +Common mistakes include:
3790 +
3791 +Using a 2.2.x kernel without applying the devfs patch (if you
3792 +don't know how to patch your kernel, use 2.4.x instead, don't bother
3793 +asking me how to patch)
3794 +Forgetting to set CONFIG_EXPERIMENTAL=y
3795 +Forgetting to set CONFIG_DEVFS_FS=y
3796 +Forgetting to set CONFIG_DEVFS_MOUNT=y (if you want devfs
3797 +to be automatically mounted at boot)
3798 +Editing your .config manually, instead of using make
3799 +config or make xconfig
3800 +Forgetting to run make dep; make clean after changing the
3801 +configuration and before compiling
3802 +Forgetting to compile your kernel and modules
3803 +Forgetting to install your kernel
3804 +Forgetting to install your modules
3805 +
3806 +Please check twice that you've done all these steps before sending in
3807 +a bug report.
3808 +
3809 +
3810 +
3811 +How can I test if devfs is mounted on /dev?
3812 +
3813 +The device filesystem will always create an entry called
3814 +".devfsd", which is used to communicate with the daemon. Even
3815 +if the daemon is not running, this entry will exist. Testing for the
3816 +existence of this entry is the approved method of determining if devfs
3817 +is mounted or not. Note that the type of entry (i.e. regular file,
3818 +character device, named pipe, etc.) may change without notice. Only
3819 +the existence of the entry should be relied upon.
3820 +
3821 +
3822 +When I start devfsd, I see the error:
3823 +Error opening file: ".devfsd"   No such file or directory?
3824 +
3825 +This means that devfs is not mounted. Make sure you have devfs mounted.
3826 +
3827 +
3828 +How do I mount devfs?
3829 +
3830 +First make sure you have devfs compiled into your kernel (see
3831 +above). Then you will either need to:
3832 +
3833 +set CONFIG_DEVFS_MOUNT=y in your kernel config
3834 +pass devfs=mount to your boot loader
3835 +mount devfs manually in your boot scripts with:
3836 +mount -t none devfs /dev
3837 +
3838 +
3839 +
3840 +Mount by volume LABEL=<label> doesn't work with
3841 +devfs
3842 +
3843 +Most probably you are not mounting devfs onto /dev. What
3844 +happens is that if your kernel config has CONFIG_DEVFS_FS=y
3845 +then the contents of /proc/partitions will have the devfs
3846 +names (such as scsi/host0/bus0/target0/lun0/part1). The
3847 +contents of /proc/partitions are used by mount(8) when
3848 +mounting by volume label. If devfs is not mounted on /dev,
3849 +then mount(8) will fail to find devices. The solution is to
3850 +make sure that devfs is mounted on /dev. See above for how to
3851 +do that.
3852 +
3853 +
3854 +I have extra or incorrect entries in /dev
3855 +
3856 +You may have stale entries in your dev-state area. Check for a
3857 +RESTORE configuration line in your devfsd configuration
3858 +(typically /etc/devfsd.conf). If you have this line, check
3859 +the contents of the specified directory for stale entries. Remove
3860 +any entries which are incorrect, then reboot.
3861 +
3862 +
3863 +I get "Unable to open initial console" messages at boot
3864 +
3865 +This usually happens when you don't have devfs automounted onto
3866 +/dev at boot time, and there is no valid
3867 +/dev/console entry on your root file-system. Create a valid
3868 +/dev/console device node.
3869 +
3870 +
3871 +
3872 +
3873 +
3874 +Alternatives to devfs
3875 +
3876 +I've attempted to collate all the anti-devfs proposals and explain
3877 +their limitations. Under construction.
3878 +
3879 +
3880 +Why not just pass device create/remove events to a daemon?
3881 +
3882 +Here the suggestion is to develop an API in the kernel so that devices
3883 +can register create and remove events, and a daemon listens for those
3884 +events. The daemon would then populate/depopulate /dev (which
3885 +resides on disc).
3886 +
3887 +This has several limitations:
3888 +
3889 +
3890 +it only works for modules loaded and unloaded (or devices inserted
3891 +and removed) after the kernel has finished booting. Without a database
3892 +of events, there is no way the daemon could fully populate
3893 +/dev
3894 +
3895 +
3896 +if you add a database to this scheme, the question is then how to
3897 +present that database to user-space. If you make it a list of strings
3898 +with embedded event codes which are passed through a pipe to the
3899 +daemon, then this is only of use to the daemon. I would argue that the
3900 +natural way to present this data is via a filesystem (since many of
3901 +the events will be of a hierarchical nature), such as devfs.
3902 +Presenting the data as a filesystem makes it easy for the user to see
3903 +what is available and also makes it easy to write scripts to scan the
3904 +"database"
3905 +
3906 +
3907 +the tight binding between device nodes and drivers is no longer
3908 +possible (requiring the otherwise perfectly avoidable
3909 +table lookups)
3910 +
3911 +
3912 +you cannot catch inode lookup events on /dev which means
3913 +that module autoloading requires device nodes to be created. This is a
3914 +problem, particularly for drivers where only a few inodes are created
3915 +from a potentially large set
3916 +
3917 +
3918 +this technique can't be used when the root FS is mounted
3919 +read-only
3920 +
3921 +
3922 +
3923 +
3924 +Just implement a better scsidev
3925 +
3926 +This suggestion involves taking the scsidev programme and
3927 +extending it to scan for all devices, not just SCSI devices. The
3928 +scsidev programme works by scanning /proc/scsi
3929 +
3930 +Problems:
3931 +
3932 +
3933 +the kernel does not currently provide a list of all devices
3934 +available. Not all drivers register entries in /proc or
3935 +generate kernel messages
3936 +
3937 +
3938 +there is no uniform mechanism to register devices other than the
3939 +devfs API
3940 +
3941 +
3942 +implementing such an API is then the same as the
3943 +proposal above
3944 +
3945 +
3946 +
3947 +
3948 +Put /dev on a ramdisc
3949 +
3950 +This suggestion involves creating a ramdisc and populating it with
3951 +device nodes and then mounting it over /dev.
3952 +
3953 +Problems:
3954 +
3955 +
3956 +
3957 +this doesn't help when mounting the root filesystem, since you
3958 +still need a device node to do that
3959 +
3960 +
3961 +if you want to use this technique for the root device node as
3962 +well, you need to use initrd. This complicates the booting sequence
3963 +and makes it significantly harder to administer and configure. The
3964 +initrd is essentially opaque, robbing the system administrator of easy
3965 +configuration
3966 +
3967 +
3968 +insufficient information is available to correctly populate the
3969 +ramdisc. So we come back to the
3970 +proposal above to "solve" this
3971 +
3972 +
3973 +a ramdisc-based solution would take more kernel memory, since the
3974 +backing store would be (at best) normal VFS inodes and dentries, which
3975 +take 284 bytes and 112 bytes, respectively, for each entry. Compare
3976 +that to 72 bytes for devfs
3977 +
3978 +
3979 +
3980 +
3981 +Do nothing: there's no problem
3982 +
3983 +Sometimes people can be heard to claim that the existing scheme is
3984 +fine. This is what they're ignoring:
3985 +
3986 +
3987 +device number size (8 bits each for major and minor) is a real
3988 +limitation, and must be fixed somehow. Systems with large numbers of
3989 +SCSI devices, for example, will continue to consume the remaining
3990 +unallocated major numbers. USB will also need to push beyond the 8 bit
3991 +minor limitation
3992 +
3993 +
3994 +simply increasing the device number size is insufficient. Apart
3995 +from causing a lot of pain, it doesn't solve the management issues
3996 +of a /dev with thousands or more device nodes
3997 +
3998 +
3999 +ignoring the problem of a huge /dev will not make it go
4000 +away, and dismisses the legitimacy of a large number of people who
4001 +want a dynamic /dev
4002 +
4003 +
4004 +the standard response then becomes: "write a device management
4005 +daemon", which brings us back to the
4006 +proposal above
4007 +
4008 +
4009 +
4010 +
4011 +What I don't like about devfs
4012 +
4013 +Here are some common complaints about devfs, and some suggestions and
4014 +solutions that may make it more palatable for you. I can't please
4015 +everybody, but I do try :-)
4016 +
4017 +I hate the naming scheme
4018 +
4019 +First, remember that no naming scheme will please everybody. You hate
4020 +the scheme, others love it. Who's to say who's right and who's wrong?
4021 +Ultimately, the person who writes the code gets to choose, and what
4022 +exists now is a combination of the choices made by the
4023 +devfs author and the
4024 +kernel maintainer (Linus).
4025 +
4026 +However, not all is lost. If you want to create your own naming
4027 +scheme, it is a simple matter to write a standalone script, hack
4028 +devfsd, or write a script called by devfsd. You can create whatever
4029 +naming scheme you like.
4030 +
4031 +Further, if you want to remove all traces of the devfs naming scheme
4032 +from /dev, you can mount devfs elsewhere (say
4033 +/devfs) and populate /dev with links into
4034 +/devfs. This population can be automated using devfsd if you
4035 +wish.
4036 +
4037 +You can even use the VFS binding facility to make the links, rather
4038 +than using symbolic links. This way, you don't even have to see the
4039 +"destination" of these symbolic links.
4040 +
4041 +Devfs puts policy into the kernel
4042 +
4043 +There's already policy in the kernel. Device numbers are in fact
4044 +policy (why should the kernel dictate what device numbers I use?).
4045 +Face it, some policy has to be in the kernel. The real difference
4046 +between device names as policy and device numbers as policy is that
4047 +no one will use device numbers directly, because device
4048 +numbers are devoid of meaning to humans and are ugly. At least with
4049 +the devfs device names, (even though you can add your own naming
4050 +scheme) some people will use the devfs-supplied names directly. This
4051 +offends some people :-)
4052 +
4053 +Devfs is bloatware
4054 +
4055 +This is not even remotely true. As shown above,
4056 +both code and data size are quite modest.
4057 +
4058 +
4059 +How to report bugs
4060 +
4061 +If you have (or think you have) a bug with devfs, please follow the
4062 +steps below:
4063 +
4064 +
4065 +
4066 +make sure you have enabled debugging output when configuring your
4067 +kernel. You will need to set (at least) the following config options:
4068 +
4069 +CONFIG_DEVFS_DEBUG=y
4070 +CONFIG_DEBUG_KERNEL=y
4071 +CONFIG_DEBUG_SLAB=y
4072 +
4073 +
4074 +
4075 +please make sure you have the latest devfs patches applied. The
4076 +latest kernel version might not have the latest devfs patches applied
4077 +yet (Linus is very busy)
4078 +
4079 +
4080 +save a copy of your complete kernel logs (preferably by
4081 +using the dmesg programme) for later inclusion in your bug
4082 +report. You may need to use the -s switch to increase the
4083 +internal buffer size so you can capture all the boot messages.
4084 +Don't edit or trim the dmesg output
4085 +
4086 +
4087 +
4088 +
4089 +try booting with devfs=dall passed to the kernel boot
4090 +command line (read the documentation on your bootloader on how to do
4091 +this), and save the result to a file. This may be quite verbose, and
4092 +it may overflow the messages buffer, but try to get as much of it as
4093 +you can
4094 +
4095 +
4096 +send a copy of your devfsd configuration file(s)
4097 +
4098 +send the bug report to me first.
4099 +Don't expect that I will see it if you post it to the linux-kernel
4100 +mailing list. Include all the information listed above, plus
4101 +anything else that you think might be relevant. Put the string
4102 +devfs somewhere in the subject line, so my mail filters mark
4103 +it as urgent
4104 +
4105 +
4106 +
4107 +
4108 +Here is a general guide on how to ask questions in a way that greatly
4109 +improves your chances of getting a reply:
4110 +
4111 +http://www.tuxedo.org/~esr/faqs/smart-questions.html. If you have
4112 +a bug to report, you should also read
4113 +
4114 +http://www.chiark.greenend.org.uk/~sgtatham/bugs.html.
4115 +
4116 +
4117 +Strange kernel messages
4118 +
4119 +You may see devfs-related messages in your kernel logs. Below are some
4120 +messages and what they mean (and what you should do about them, if
4121 +anything).
4122 +
4123 +
4124 +
4125 +devfs_register(fred): could not append to parent, err: -17
4126 +
4127 +You need to check what the error code means, but usually 17 means
4128 +EEXIST. This means that a driver attempted to create an entry
4129 +fred in a directory, but there already was an entry with that
4130 +name. This is often caused by flawed boot scripts which untar a bunch
4131 +of inodes into /dev, as a way to restore permissions. This
4132 +message is harmless, as the device nodes will still
4133 +provide access to the driver (unless you use the devfs=only
4134 +boot option, which is only for dedicated souls:-). If you want to get
4135 +rid of these annoying messages, upgrade to devfsd-v1.3.20 and use the
4136 +recommended RESTORE directive to restore permissions.
4137 +
4138 +
4139 +devfs_mk_dir(bill): using old entry in dir: c1808724 ""
4140 +
4141 +This is similar to the message above, except that a driver attempted
4142 +to create a directory named bill, and the parent directory
4143 +has an entry with the same name. In this case, to ensure that drivers
4144 +continue to work properly, the old entry is re-used and given to the
4145 +driver. In 2.5 kernels, the driver is given a NULL entry, and thus,
4146 +under rare circumstances, may not create the require device nodes.
4147 +The solution is the same as above.
4148 +
4149 +
4150 +
4151 +
4152 +
4153 +Compilation problems with devfsd
4154 +
4155 +Usually, you can compile devfsd just by typing in
4156 +make in the source directory, followed by a make
4157 +install (as root). Sometimes, you may have problems, particularly
4158 +on broken configurations.
4159 +
4160 +
4161 +
4162 +error messages relating to DEVFSD_NOTIFY_DELETE
4163 +
4164 +This happened because you have an ancient set of kernel headers
4165 +installed in /usr/include/linux or /usr/src/linux.
4166 +Install kernel 2.4.10 or later. You may need to pass the
4167 +KERNEL_DIR variable to make (if you did not install
4168 +the new kernel sources as /usr/src/linux), or you may copy
4169 +the devfs_fs.h file in the kernel source tree into
4170 +/usr/include/linux.
4171 +
4172 +
4173 +
4174 +
4175 +-----------------------------------------------------------------------------
4176 +
4177 +
4178 +Other resources
4179 +
4180 +
4181 +
4182 +Douglas Gilbert has written a useful document at
4183 +
4184 +http://www.torque.net/sg/devfs_scsi.html which
4185 +explores the SCSI subsystem and how it interacts with devfs
4186 +
4187 +
4188 +Douglas Gilbert has written another useful document at
4189 +
4190 +http://www.torque.net/scsi/SCSI-2.4-HOWTO/ which
4191 +discusses the Linux SCSI subsystem in 2.4.
4192 +
4193 +
4194 +Johannes Erdfelt has started a discussion paper on Linux and
4195 +hot-swap devices, describing what the requirements are for a scalable
4196 +solution and how and why he's used devfs+devfsd. Note that this is an
4197 +early draft only, available in plain text form at:
4198 +
4199 +http://johannes.erdfelt.com/hotswap.txt.
4200 +Johannes has promised a HTML version will follow.
4201 +
4202 +
4203 +I presented an invited 
4204 +paper
4205 +at the
4206 +
4207 +2nd Annual Storage Management Workshop held in Miamia, Florida,
4208 +U.S.A. in October 2000.
4209 +
4210 +
4211 +
4212 +
4213 +-----------------------------------------------------------------------------
4214 +
4215 +
4216 +Translations of this document
4217 +
4218 +This document has been translated into other languages.
4219 +
4220 +
4221 +
4222 +
4223 +The document master (in English) by rgooch@atnf.csiro.au is
4224 +available at
4225 +
4226 +http://www.atnf.csiro.au/~rgooch/linux/docs/devfs.html
4227 +
4228 +
4229 +
4230 +A Korean translation by viatoris@nownuri.net is available at
4231 +
4232 +http://your.destiny.pe.kr/devfs/devfs.html
4233 +
4234 +
4235 +
4236 +
4237 +-----------------------------------------------------------------------------
4238 +Most flags courtesy of ITA's 
4239 +Flags of All Countries
4240 +used with permission. 
4241 diff -urN linux-2.6.19.old/Documentation/filesystems/devfs/ToDo linux-2.6.19.dev/Documentation/filesystems/devfs/ToDo
4242 --- linux-2.6.19.old/Documentation/filesystems/devfs/ToDo       1970-01-01 01:00:00.000000000 +0100
4243 +++ linux-2.6.19.dev/Documentation/filesystems/devfs/ToDo       2006-12-14 03:12:59.000000000 +0100
4244 @@ -0,0 +1,40 @@
4245 +               Device File System (devfs) ToDo List
4246 +
4247 +               Richard Gooch <rgooch@atnf.csiro.au>
4248 +
4249 +                             3-JUL-2000
4250 +
4251 +This is a list of things to be done for better devfs support in the
4252 +Linux kernel. If you'd like to contribute to the devfs, please have a
4253 +look at this list for anything that is unallocated. Also, if there are
4254 +items missing (surely), please contact me so I can add them to the
4255 +list (preferably with your name attached to them:-).
4256 +
4257 +
4258 +- >256 ptys
4259 +  Thanks to C. Scott Ananian <cananian@alumni.princeton.edu>
4260 +
4261 +- Amiga floppy driver (drivers/block/amiflop.c)
4262 +
4263 +- Atari floppy driver (drivers/block/ataflop.c)
4264 +
4265 +- SWIM3 (Super Woz Integrated Machine 3) floppy driver (drivers/block/swim3.c)
4266 +
4267 +- Amiga ZorroII ramdisc driver (drivers/block/z2ram.c)
4268 +
4269 +- Parallel port ATAPI CD-ROM (drivers/block/paride/pcd.c)
4270 +
4271 +- Parallel port ATAPI floppy (drivers/block/paride/pf.c)
4272 +
4273 +- AP1000 block driver (drivers/ap1000/ap.c, drivers/ap1000/ddv.c)
4274 +
4275 +- Archimedes floppy (drivers/acorn/block/fd1772.c)
4276 +
4277 +- MFM hard drive (drivers/acorn/block/mfmhd.c)
4278 +
4279 +- I2O block device (drivers/message/i2o/i2o_block.c)
4280 +
4281 +- ST-RAM device (arch/m68k/atari/stram.c)
4282 +
4283 +- Raw devices
4284 +
4285 diff -urN linux-2.6.19.old/Documentation/ioctl-number.txt linux-2.6.19.dev/Documentation/ioctl-number.txt
4286 --- linux-2.6.19.old/Documentation/ioctl-number.txt     2006-11-29 22:57:37.000000000 +0100
4287 +++ linux-2.6.19.dev/Documentation/ioctl-number.txt     2006-12-14 03:12:59.000000000 +0100
4288 @@ -119,6 +119,7 @@
4289  'c'    00-7F   linux/comstats.h        conflict!
4290  'c'    00-7F   linux/coda.h            conflict!
4291  'd'    00-FF   linux/char/drm/drm/h    conflict!
4292 +'d'    00-1F   linux/devfs_fs.h        conflict!
4293  'd'    00-DF   linux/video_decoder.h   conflict!
4294  'd'    F0-FF   linux/digi1.h
4295  'e'    all     linux/digi1.h           conflict!
4296 diff -urN linux-2.6.19.old/Documentation/kernel-parameters.txt linux-2.6.19.dev/Documentation/kernel-parameters.txt
4297 --- linux-2.6.19.old/Documentation/kernel-parameters.txt        2006-11-29 22:57:37.000000000 +0100
4298 +++ linux-2.6.19.dev/Documentation/kernel-parameters.txt        2006-12-14 03:12:59.000000000 +0100
4299 @@ -35,6 +35,7 @@
4300         APM     Advanced Power Management support is enabled.
4301         AX25    Appropriate AX.25 support is enabled.
4302         CD      Appropriate CD support is enabled.
4303 +       DEVFS   devfs support is enabled.
4304         DRM     Direct Rendering Management support is enabled.
4305         EDD     BIOS Enhanced Disk Drive Services (EDD) is enabled
4306         EFI     EFI Partitioning (GPT) is enabled
4307 @@ -456,6 +457,9 @@
4308                         Format: <area>[,<node>]
4309                         See also Documentation/networking/decnet.txt.
4310  
4311 +       devfs=          [DEVFS]
4312 +                       See Documentation/filesystems/devfs/boot-options.
4313 +
4314         dhash_entries=  [KNL]
4315                         Set number of hash buckets for dentry cache.
4316  
4317 diff -urN linux-2.6.19.old/drivers/block/acsi.c linux-2.6.19.dev/drivers/block/acsi.c
4318 --- linux-2.6.19.old/drivers/block/acsi.c       2006-11-29 22:57:37.000000000 +0100
4319 +++ linux-2.6.19.dev/drivers/block/acsi.c       2006-12-14 03:12:59.000000000 +0100
4320 @@ -1731,10 +1731,13 @@
4321                 struct gendisk *disk = acsi_gendisk[i];
4322                 sprintf(disk->disk_name, "ad%c", 'a'+i);
4323                 aip = &acsi_info[NDevices];
4324 +               sprintf(disk->devfs_name, "ad/target%d/lun%d", aip->target, aip->lun);
4325                 disk->major = ACSI_MAJOR;
4326                 disk->first_minor = i << 4;
4327 -               if (acsi_info[i].type != HARDDISK)
4328 +               if (acsi_info[i].type != HARDDISK) {
4329                         disk->minors = 1;
4330 +                       strcat(disk->devfs_name, "/disc");
4331 +               }
4332                 disk->fops = &acsi_fops;
4333                 disk->private_data = &acsi_info[i];
4334                 set_capacity(disk, acsi_info[i].size);
4335 diff -urN linux-2.6.19.old/drivers/block/acsi_slm.c linux-2.6.19.dev/drivers/block/acsi_slm.c
4336 --- linux-2.6.19.old/drivers/block/acsi_slm.c   2006-11-29 22:57:37.000000000 +0100
4337 +++ linux-2.6.19.dev/drivers/block/acsi_slm.c   2006-12-14 03:12:59.000000000 +0100
4338 @@ -65,6 +65,7 @@
4339  #include <linux/time.h>
4340  #include <linux/mm.h>
4341  #include <linux/slab.h>
4342 +#include <linux/devfs_fs_kernel.h>
4343  #include <linux/smp_lock.h>
4344  
4345  #include <asm/pgtable.h>
4346 @@ -1004,6 +1005,11 @@
4347         BufferP = SLMBuffer;
4348         SLMState = IDLE;
4349         
4350 +       devfs_mk_dir("slm");
4351 +       for (i = 0; i < MAX_SLM; i++) {
4352 +               devfs_mk_cdev(MKDEV(ACSI_MAJOR, i),
4353 +                               S_IFCHR|S_IRUSR|S_IWUSR, "slm/%d", i);
4354 +       }
4355         return 0;
4356  }
4357  
4358 @@ -1026,6 +1032,10 @@
4359  
4360  void cleanup_module(void)
4361  {
4362 +       int i;
4363 +       for (i = 0; i < MAX_SLM; i++)
4364 +               devfs_remove("slm/%d", i);
4365 +       devfs_remove("slm");
4366         if (unregister_chrdev( ACSI_MAJOR, "slm" ) != 0)
4367                 printk( KERN_ERR "acsi_slm: cleanup_module failed\n");
4368         atari_stram_free( SLMBuffer );
4369 diff -urN linux-2.6.19.old/drivers/block/cpqarray.c linux-2.6.19.dev/drivers/block/cpqarray.c
4370 --- linux-2.6.19.old/drivers/block/cpqarray.c   2006-11-29 22:57:37.000000000 +0100
4371 +++ linux-2.6.19.dev/drivers/block/cpqarray.c   2006-12-14 03:12:59.000000000 +0100
4372 @@ -32,6 +32,7 @@
4373  #include <linux/blkpg.h>
4374  #include <linux/timer.h>
4375  #include <linux/proc_fs.h>
4376 +#include <linux/devfs_fs_kernel.h>
4377  #include <linux/init.h>
4378  #include <linux/hdreg.h>
4379  #include <linux/spinlock.h>
4380 @@ -346,6 +347,7 @@
4381         for(j = 0; j < NWD; j++) {
4382                 if (ida_gendisk[i][j]->flags & GENHD_FL_UP)
4383                         del_gendisk(ida_gendisk[i][j]);
4384 +               devfs_remove("ida/c%dd%d",i,j);
4385                 put_disk(ida_gendisk[i][j]);
4386         }
4387         blk_cleanup_queue(hba[i]->queue);
4388 @@ -1808,6 +1810,8 @@
4389  
4390                                 }
4391  
4392 +                               sprintf(disk->devfs_name, "ida/c%dd%d", ctlr, log_unit);
4393 +
4394                                 info_p->phys_drives =
4395                                     sense_config_buf->ctlr_phys_drv;
4396                                 info_p->drv_assign_map
4397 @@ -1843,6 +1847,7 @@
4398                 }
4399         }
4400  
4401 +       devfs_remove("ida");
4402         remove_proc_entry("cpqarray", proc_root_driver);
4403  }
4404  
4405 diff -urN linux-2.6.19.old/drivers/block/DAC960.c linux-2.6.19.dev/drivers/block/DAC960.c
4406 --- linux-2.6.19.old/drivers/block/DAC960.c     2006-11-29 22:57:37.000000000 +0100
4407 +++ linux-2.6.19.dev/drivers/block/DAC960.c     2006-12-14 03:12:59.000000000 +0100
4408 @@ -2530,6 +2530,7 @@
4409         blk_queue_max_sectors(RequestQueue, Controller->MaxBlocksPerCommand);
4410         disk->queue = RequestQueue;
4411         sprintf(disk->disk_name, "rd/c%dd%d", Controller->ControllerNumber, n);
4412 +       sprintf(disk->devfs_name, "rd/host%d/target%d", Controller->ControllerNumber, n);
4413         disk->major = MajorNumber;
4414         disk->first_minor = n << DAC960_MaxPartitionsBits;
4415         disk->fops = &DAC960_BlockDeviceOperations;
4416 diff -urN linux-2.6.19.old/drivers/block/floppy.c linux-2.6.19.dev/drivers/block/floppy.c
4417 --- linux-2.6.19.old/drivers/block/floppy.c     2006-11-29 22:57:37.000000000 +0100
4418 +++ linux-2.6.19.dev/drivers/block/floppy.c     2006-12-14 03:12:59.000000000 +0100
4419 @@ -177,6 +177,7 @@
4420  #include <linux/ioport.h>
4421  #include <linux/interrupt.h>
4422  #include <linux/init.h>
4423 +#include <linux/devfs_fs_kernel.h>
4424  #include <linux/platform_device.h>
4425  #include <linux/buffer_head.h> /* for invalidate_buffers() */
4426  #include <linux/mutex.h>
4427 @@ -223,6 +224,7 @@
4428  static unsigned short virtual_dma_port = 0x3f0;
4429  irqreturn_t floppy_interrupt(int irq, void *dev_id);
4430  static int set_dor(int fdc, char mask, char data);
4431 +static void register_devfs_entries(int drive) __init;
4432  
4433  #define K_64   0x10000         /* 64KB */
4434  
4435 @@ -3652,6 +3654,7 @@
4436                                 first = 0;
4437                         }
4438                         printk("%s fd%d is %s", prepend, drive, name);
4439 +                       register_devfs_entries(drive);
4440                 }
4441                 *UDP = *params;
4442         }
4443 @@ -3921,6 +3924,23 @@
4444         .revalidate_disk = floppy_revalidate,
4445  };
4446  
4447 +static void __init register_devfs_entries(int drive)
4448 +{
4449 +       int base_minor = (drive < 4) ? drive : (124 + drive);
4450 +
4451 +       if (UDP->cmos < ARRAY_SIZE(default_drive_params)) {
4452 +               int i = 0;
4453 +               do {
4454 +                       int minor = base_minor + (table_sup[UDP->cmos][i] << 2);
4455 +
4456 +                       devfs_mk_bdev(MKDEV(FLOPPY_MAJOR, minor),
4457 +                                     S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP |
4458 +                                     S_IWGRP, "floppy/%d%s", drive,
4459 +                                     table[table_sup[UDP->cmos][i]]);
4460 +               } while (table_sup[UDP->cmos][i++]);
4461 +       }
4462 +}
4463 +
4464  /*
4465   * Floppy Driver initialization
4466   * =============================
4467 @@ -4201,9 +4221,11 @@
4468                 motor_off_timer[dr].function = motor_off_callback;
4469         }
4470  
4471 +       devfs_mk_dir("floppy");
4472 +
4473         err = register_blkdev(FLOPPY_MAJOR, "fd");
4474         if (err)
4475 -               goto out_put_disk;
4476 +               goto out_devfs_remove;
4477  
4478         floppy_queue = blk_init_queue(do_fd_request, &floppy_lock);
4479         if (!floppy_queue) {
4480 @@ -4354,6 +4376,8 @@
4481         blk_cleanup_queue(floppy_queue);
4482  out_unreg_blkdev:
4483         unregister_blkdev(FLOPPY_MAJOR, "fd");
4484 +out_devfs_remove:
4485 +       devfs_remove("floppy");
4486  out_put_disk:
4487         while (dr--) {
4488                 del_timer(&motor_off_timer[dr]);
4489 @@ -4514,6 +4538,19 @@
4490  
4491  static char *floppy;
4492  
4493 +static void unregister_devfs_entries(int drive)
4494 +{
4495 +       int i;
4496 +
4497 +       if (UDP->cmos < ARRAY_SIZE(default_drive_params)) {
4498 +               i = 0;
4499 +               do {
4500 +                       devfs_remove("floppy/%d%s", drive,
4501 +                                    table[table_sup[UDP->cmos][i]]);
4502 +               } while (table_sup[UDP->cmos][i++]);
4503 +       }
4504 +}
4505 +
4506  static void __init parse_floppy_cfg_string(char *cfg)
4507  {
4508         char *ptr;
4509 @@ -4550,11 +4587,13 @@
4510                 if ((allowed_drive_mask & (1 << drive)) &&
4511                     fdc_state[FDC(drive)].version != FDC_NONE) {
4512                         del_gendisk(disks[drive]);
4513 +                       unregister_devfs_entries(drive);
4514                         device_remove_file(&floppy_device[drive].dev, &dev_attr_cmos);
4515                         platform_device_unregister(&floppy_device[drive]);
4516                 }
4517                 put_disk(disks[drive]);
4518         }
4519 +       devfs_remove("floppy");
4520  
4521         del_timer_sync(&fd_timeout);
4522         del_timer_sync(&fd_timer);
4523 diff -urN linux-2.6.19.old/drivers/block/loop.c linux-2.6.19.dev/drivers/block/loop.c
4524 --- linux-2.6.19.old/drivers/block/loop.c       2006-11-29 22:57:37.000000000 +0100
4525 +++ linux-2.6.19.dev/drivers/block/loop.c       2006-12-14 03:12:59.000000000 +0100
4526 @@ -62,6 +62,7 @@
4527  #include <linux/blkdev.h>
4528  #include <linux/blkpg.h>
4529  #include <linux/init.h>
4530 +#include <linux/devfs_fs_kernel.h>
4531  #include <linux/smp_lock.h>
4532  #include <linux/swap.h>
4533  #include <linux/slab.h>
4534 @@ -1426,6 +1427,8 @@
4535                         goto out_mem3;
4536         }
4537  
4538 +       devfs_mk_dir("loop");
4539 +
4540         for (i = 0; i < max_loop; i++) {
4541                 struct loop_device *lo = &loop_dev[i];
4542                 struct gendisk *disk = disks[i];
4543 @@ -1443,6 +1446,7 @@
4544                 disk->first_minor = i;
4545                 disk->fops = &lo_fops;
4546                 sprintf(disk->disk_name, "loop%d", i);
4547 +               sprintf(disk->devfs_name, "loop/%d", i);
4548                 disk->private_data = lo;
4549                 disk->queue = lo->lo_queue;
4550         }
4551 @@ -1456,6 +1460,7 @@
4552  out_mem4:
4553         while (i--)
4554                 blk_cleanup_queue(loop_dev[i].lo_queue);
4555 +       devfs_remove("loop");
4556         i = max_loop;
4557  out_mem3:
4558         while (i--)
4559 @@ -1478,6 +1483,7 @@
4560                 blk_cleanup_queue(loop_dev[i].lo_queue);
4561                 put_disk(disks[i]);
4562         }
4563 +       devfs_remove("loop");
4564         if (unregister_blkdev(LOOP_MAJOR, "loop"))
4565                 printk(KERN_WARNING "loop: cannot unregister blkdev\n");
4566  
4567 diff -urN linux-2.6.19.old/drivers/block/nbd.c linux-2.6.19.dev/drivers/block/nbd.c
4568 --- linux-2.6.19.old/drivers/block/nbd.c        2006-11-29 22:57:37.000000000 +0100
4569 +++ linux-2.6.19.dev/drivers/block/nbd.c        2006-12-14 03:12:59.000000000 +0100
4570 @@ -29,6 +29,8 @@
4571  #include <linux/kernel.h>
4572  #include <net/sock.h>
4573  
4574 +#include <linux/devfs_fs_kernel.h>
4575 +
4576  #include <asm/uaccess.h>
4577  #include <asm/system.h>
4578  #include <asm/types.h>
4579 @@ -643,6 +645,7 @@
4580         printk(KERN_INFO "nbd: registered device at major %d\n", NBD_MAJOR);
4581         dprintk(DBG_INIT, "nbd: debugflags=0x%x\n", debugflags);
4582  
4583 +       devfs_mk_dir("nbd");
4584         for (i = 0; i < nbds_max; i++) {
4585                 struct gendisk *disk = nbd_dev[i].disk;
4586                 nbd_dev[i].file = NULL;
4587 @@ -660,6 +663,7 @@
4588                 disk->private_data = &nbd_dev[i];
4589                 disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
4590                 sprintf(disk->disk_name, "nbd%d", i);
4591 +               sprintf(disk->devfs_name, "nbd/%d", i);
4592                 set_capacity(disk, 0x7ffffc00ULL << 1); /* 2 TB */
4593                 add_disk(disk);
4594         }
4595 @@ -685,6 +689,7 @@
4596                         put_disk(disk);
4597                 }
4598         }
4599 +       devfs_remove("nbd");
4600         unregister_blkdev(NBD_MAJOR, "nbd");
4601         printk(KERN_INFO "nbd: unregistered device at major %d\n", NBD_MAJOR);
4602  }
4603 diff -urN linux-2.6.19.old/drivers/block/paride/pg.c linux-2.6.19.dev/drivers/block/paride/pg.c
4604 --- linux-2.6.19.old/drivers/block/paride/pg.c  2006-11-29 22:57:37.000000000 +0100
4605 +++ linux-2.6.19.dev/drivers/block/paride/pg.c  2006-12-14 03:12:59.000000000 +0100
4606 @@ -156,6 +156,7 @@
4607  #include <linux/module.h>
4608  #include <linux/init.h>
4609  #include <linux/fs.h>
4610 +#include <linux/devfs_fs_kernel.h>
4611  #include <linux/delay.h>
4612  #include <linux/slab.h>
4613  #include <linux/mtio.h>
4614 @@ -673,15 +674,25 @@
4615                 err = PTR_ERR(pg_class);
4616                 goto out_chrdev;
4617         }
4618 +       devfs_mk_dir("pg");
4619         for (unit = 0; unit < PG_UNITS; unit++) {
4620                 struct pg *dev = &devices[unit];
4621 -               if (dev->present)
4622 +               if (dev->present) {
4623                         class_device_create(pg_class, NULL, MKDEV(major, unit),
4624                                         NULL, "pg%u", unit);
4625 +                       err = devfs_mk_cdev(MKDEV(major, unit),
4626 +                                     S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u",
4627 +                                     unit);
4628 +                       if (err) 
4629 +                               goto out_class;
4630 +               }
4631         }
4632         err = 0;
4633         goto out;
4634  
4635 +out_class:
4636 +       class_device_destroy(pg_class, MKDEV(major, unit));
4637 +       class_destroy(pg_class);
4638  out_chrdev:
4639         unregister_chrdev(major, "pg");
4640  out:
4641 @@ -694,10 +705,13 @@
4642  
4643         for (unit = 0; unit < PG_UNITS; unit++) {
4644                 struct pg *dev = &devices[unit];
4645 -               if (dev->present)
4646 +               if (dev->present) {
4647                         class_device_destroy(pg_class, MKDEV(major, unit));
4648 +                       devfs_remove("pg/%u", unit);
4649 +               }
4650         }
4651         class_destroy(pg_class);
4652 +       devfs_remove("pg");
4653         unregister_chrdev(major, name);
4654  
4655         for (unit = 0; unit < PG_UNITS; unit++) {
4656 diff -urN linux-2.6.19.old/drivers/block/paride/pt.c linux-2.6.19.dev/drivers/block/paride/pt.c
4657 --- linux-2.6.19.old/drivers/block/paride/pt.c  2006-11-29 22:57:37.000000000 +0100
4658 +++ linux-2.6.19.dev/drivers/block/paride/pt.c  2006-12-14 03:12:59.000000000 +0100
4659 @@ -141,6 +141,7 @@
4660  #include <linux/module.h>
4661  #include <linux/init.h>
4662  #include <linux/fs.h>
4663 +#include <linux/devfs_fs_kernel.h>
4664  #include <linux/delay.h>
4665  #include <linux/slab.h>
4666  #include <linux/mtio.h>
4667 @@ -970,15 +971,32 @@
4668                 goto out_chrdev;
4669         }
4670  
4671 +       devfs_mk_dir("pt");
4672         for (unit = 0; unit < PT_UNITS; unit++)
4673                 if (pt[unit].present) {
4674                         class_device_create(pt_class, NULL, MKDEV(major, unit),
4675                                         NULL, "pt%d", unit);
4676 +                       err = devfs_mk_cdev(MKDEV(major, unit),
4677 +                                     S_IFCHR | S_IRUSR | S_IWUSR,
4678 +                                     "pt/%d", unit);
4679 +                       if (err) {
4680 +                               class_device_destroy(pt_class, MKDEV(major, unit));
4681 +                               goto out_class;
4682 +                       }
4683                         class_device_create(pt_class, NULL, MKDEV(major, unit + 128),
4684                                         NULL, "pt%dn", unit);
4685 +                       err = devfs_mk_cdev(MKDEV(major, unit + 128),
4686 +                                     S_IFCHR | S_IRUSR | S_IWUSR,
4687 +                                     "pt/%dn", unit);
4688 +                       if (err) {
4689 +                               class_device_destroy(pt_class, MKDEV(major, unit + 128));
4690 +                               goto out_class;
4691 +                       }
4692                 }
4693         goto out;
4694  
4695 +out_class:
4696 +       class_destroy(pt_class);
4697  out_chrdev:
4698         unregister_chrdev(major, "pt");
4699  out:
4700 @@ -991,9 +1009,12 @@
4701         for (unit = 0; unit < PT_UNITS; unit++)
4702                 if (pt[unit].present) {
4703                         class_device_destroy(pt_class, MKDEV(major, unit));
4704 +                       devfs_remove("pt/%d", unit);
4705                         class_device_destroy(pt_class, MKDEV(major, unit + 128));
4706 +                       devfs_remove("pt/%dn", unit);
4707                 }
4708         class_destroy(pt_class);
4709 +       devfs_remove("pt");
4710         unregister_chrdev(major, name);
4711         for (unit = 0; unit < PT_UNITS; unit++)
4712                 if (pt[unit].present)
4713 diff -urN linux-2.6.19.old/drivers/block/pktcdvd.c linux-2.6.19.dev/drivers/block/pktcdvd.c
4714 --- linux-2.6.19.old/drivers/block/pktcdvd.c    2006-11-29 22:57:37.000000000 +0100
4715 +++ linux-2.6.19.dev/drivers/block/pktcdvd.c    2006-12-14 03:12:59.000000000 +0100
4716 @@ -2613,6 +2613,7 @@
4717  static struct miscdevice pkt_misc = {
4718         .minor          = MISC_DYNAMIC_MINOR,
4719         .name           = DRIVER_NAME,
4720 +       .devfs_name     = "pktcdvd/control",
4721         .fops           = &pkt_ctl_fops
4722  };
4723  
4724 diff -urN linux-2.6.19.old/drivers/block/ps2esdi.c linux-2.6.19.dev/drivers/block/ps2esdi.c
4725 --- linux-2.6.19.old/drivers/block/ps2esdi.c    2006-11-29 22:57:37.000000000 +0100
4726 +++ linux-2.6.19.dev/drivers/block/ps2esdi.c    2006-12-14 03:12:59.000000000 +0100
4727 @@ -419,6 +419,7 @@
4728                 disk->major = PS2ESDI_MAJOR;
4729                 disk->first_minor = i<<6;
4730                 sprintf(disk->disk_name, "ed%c", 'a'+i);
4731 +               sprintf(disk->devfs_name, "ed/target%d", i);
4732                 disk->fops = &ps2esdi_fops;
4733                 ps2esdi_gendisk[i] = disk;
4734         }
4735 diff -urN linux-2.6.19.old/drivers/block/rd.c linux-2.6.19.dev/drivers/block/rd.c
4736 --- linux-2.6.19.old/drivers/block/rd.c 2006-11-29 22:57:37.000000000 +0100
4737 +++ linux-2.6.19.dev/drivers/block/rd.c 2006-12-14 03:12:59.000000000 +0100
4738 @@ -49,6 +49,7 @@
4739  #include <linux/module.h>
4740  #include <linux/moduleparam.h>
4741  #include <linux/init.h>
4742 +#include <linux/devfs_fs_kernel.h>
4743  #include <linux/pagemap.h>
4744  #include <linux/blkdev.h>
4745  #include <linux/genhd.h>
4746 @@ -410,6 +411,7 @@
4747                 put_disk(rd_disks[i]);
4748                 blk_cleanup_queue(rd_queue[i]);
4749         }
4750 +       devfs_remove("rd");
4751         unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
4752  }
4753  
4754 @@ -445,6 +447,8 @@
4755                 goto out;
4756         }
4757  
4758 +       devfs_mk_dir("rd");
4759 +
4760         for (i = 0; i < CONFIG_BLK_DEV_RAM_COUNT; i++) {
4761                 struct gendisk *disk = rd_disks[i];
4762  
4763 @@ -458,6 +462,7 @@
4764                 disk->queue = rd_queue[i];
4765                 disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
4766                 sprintf(disk->disk_name, "ram%d", i);
4767 +               sprintf(disk->devfs_name, "rd/%d", i);
4768                 set_capacity(disk, rd_size * 2);
4769                 add_disk(rd_disks[i]);
4770         }
4771 diff -urN linux-2.6.19.old/drivers/block/sx8.c linux-2.6.19.dev/drivers/block/sx8.c
4772 --- linux-2.6.19.old/drivers/block/sx8.c        2006-11-29 22:57:37.000000000 +0100
4773 +++ linux-2.6.19.dev/drivers/block/sx8.c        2006-12-14 03:12:59.000000000 +0100
4774 @@ -18,6 +18,7 @@
4775  #include <linux/spinlock.h>
4776  #include <linux/blkdev.h>
4777  #include <linux/sched.h>
4778 +#include <linux/devfs_fs_kernel.h>
4779  #include <linux/interrupt.h>
4780  #include <linux/compiler.h>
4781  #include <linux/workqueue.h>
4782 @@ -1509,6 +1510,7 @@
4783                 port->disk = disk;
4784                 sprintf(disk->disk_name, DRV_NAME "/%u",
4785                         (unsigned int) (host->id * CARM_MAX_PORTS) + i);
4786 +               sprintf(disk->devfs_name, DRV_NAME "/%u_%u", host->id, i);
4787                 disk->major = host->major;
4788                 disk->first_minor = i * CARM_MINORS_PER_MAJOR;
4789                 disk->fops = &carm_bd_ops;
4790 @@ -1670,6 +1672,8 @@
4791         if (host->flags & FL_DYN_MAJOR)
4792                 host->major = rc;
4793  
4794 +       devfs_mk_dir(DRV_NAME);
4795 +
4796         rc = carm_init_disks(host);
4797         if (rc)
4798                 goto err_out_blkdev_disks;
4799 @@ -1735,6 +1739,7 @@
4800  
4801         free_irq(pdev->irq, host);
4802         carm_free_disks(host);
4803 +       devfs_remove(DRV_NAME);
4804         unregister_blkdev(host->major, host->name);
4805         if (host->major == 160)
4806                 clear_bit(0, &carm_major_alloc);
4807 diff -urN linux-2.6.19.old/drivers/block/ub.c linux-2.6.19.dev/drivers/block/ub.c
4808 --- linux-2.6.19.old/drivers/block/ub.c 2006-11-29 22:57:37.000000000 +0100
4809 +++ linux-2.6.19.dev/drivers/block/ub.c 2006-12-14 03:12:59.000000000 +0100
4810 @@ -24,10 +24,12 @@
4811  #include <linux/usb.h>
4812  #include <linux/usb_usual.h>
4813  #include <linux/blkdev.h>
4814 +#include <linux/devfs_fs_kernel.h>
4815  #include <linux/timer.h>
4816  #include <scsi/scsi.h>
4817  
4818  #define DRV_NAME "ub"
4819 +#define DEVFS_NAME DRV_NAME
4820  
4821  #define UB_MAJOR 180
4822  
4823 @@ -2301,6 +2303,7 @@
4824                 goto err_diskalloc;
4825  
4826         sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a');
4827 +       sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a');
4828         disk->major = UB_MAJOR;
4829         disk->first_minor = lun->id * UB_PARTS_PER_LUN;
4830         disk->fops = &ub_bd_fops;
4831 @@ -2454,6 +2457,7 @@
4832  
4833         if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0)
4834                 goto err_regblkdev;
4835 +       devfs_mk_dir(DEVFS_NAME);
4836  
4837         if ((rc = usb_register(&ub_driver)) != 0)
4838                 goto err_register;
4839 @@ -2462,6 +2466,7 @@
4840         return 0;
4841  
4842  err_register:
4843 +       devfs_remove(DEVFS_NAME);
4844         unregister_blkdev(UB_MAJOR, DRV_NAME);
4845  err_regblkdev:
4846         return rc;
4847 @@ -2471,6 +2476,7 @@
4848  {
4849         usb_deregister(&ub_driver);
4850  
4851 +       devfs_remove(DEVFS_NAME);
4852         unregister_blkdev(UB_MAJOR, DRV_NAME);
4853         usb_usual_clear_present(USB_US_TYPE_UB);
4854  }
4855 diff -urN linux-2.6.19.old/drivers/block/umem.c linux-2.6.19.dev/drivers/block/umem.c
4856 --- linux-2.6.19.old/drivers/block/umem.c       2006-11-29 22:57:37.000000000 +0100
4857 +++ linux-2.6.19.dev/drivers/block/umem.c       2006-12-14 03:12:59.000000000 +0100
4858 @@ -1192,6 +1192,7 @@
4859         for (i = 0; i < num_cards; i++) {
4860                 struct gendisk *disk = mm_gendisk[i];
4861                 sprintf(disk->disk_name, "umem%c", 'a'+i);
4862 +               sprintf(disk->devfs_name, "umem/card%d", i);
4863                 spin_lock_init(&cards[i].lock);
4864                 disk->major = major_nr;
4865                 disk->first_minor  = i << MM_SHIFT;
4866 diff -urN linux-2.6.19.old/drivers/block/viodasd.c linux-2.6.19.dev/drivers/block/viodasd.c
4867 --- linux-2.6.19.old/drivers/block/viodasd.c    2006-11-29 22:57:37.000000000 +0100
4868 +++ linux-2.6.19.dev/drivers/block/viodasd.c    2006-12-14 03:12:59.000000000 +0100
4869 @@ -59,6 +59,7 @@
4870   * numbers 0-255 we get a maximum of 32 disks.
4871   */
4872  #define VIOD_GENHD_NAME                "iseries/vd"
4873 +#define VIOD_GENHD_DEVFS_NAME  "iseries/disc"
4874  
4875  #define VIOD_VERS              "1.64"
4876  
4877 @@ -522,6 +523,8 @@
4878         else
4879                 snprintf(g->disk_name, sizeof(g->disk_name),
4880                                 VIOD_GENHD_NAME "%c", 'a' + (dev_no % 26));
4881 +       snprintf(g->devfs_name, sizeof(g->devfs_name),
4882 +                       "%s%d", VIOD_GENHD_DEVFS_NAME, dev_no);
4883         g->fops = &viodasd_fops;
4884         g->queue = q;
4885         g->private_data = d;
4886 diff -urN linux-2.6.19.old/drivers/block/xd.c linux-2.6.19.dev/drivers/block/xd.c
4887 --- linux-2.6.19.old/drivers/block/xd.c 2006-11-29 22:57:37.000000000 +0100
4888 +++ linux-2.6.19.dev/drivers/block/xd.c 2006-12-14 03:12:59.000000000 +0100
4889 @@ -215,6 +215,7 @@
4890                 disk->major = XT_DISK_MAJOR;
4891                 disk->first_minor = i<<6;
4892                 sprintf(disk->disk_name, "xd%c", i+'a');
4893 +               sprintf(disk->devfs_name, "xd/target%d", i);
4894                 disk->fops = &xd_fops;
4895                 disk->private_data = p;
4896                 disk->queue = xd_queue;
4897 diff -urN linux-2.6.19.old/drivers/block/z2ram.c linux-2.6.19.dev/drivers/block/z2ram.c
4898 --- linux-2.6.19.old/drivers/block/z2ram.c      2006-11-29 22:57:37.000000000 +0100
4899 +++ linux-2.6.19.dev/drivers/block/z2ram.c      2006-12-14 03:12:59.000000000 +0100
4900 @@ -354,6 +354,7 @@
4901      z2ram_gendisk->first_minor = 0;
4902      z2ram_gendisk->fops = &z2_fops;
4903      sprintf(z2ram_gendisk->disk_name, "z2ram");
4904 +    strcpy(z2ram_gendisk->devfs_name, z2ram_gendisk->disk_name);
4905  
4906      z2ram_gendisk->queue = z2_queue;
4907      add_disk(z2ram_gendisk);
4908 diff -urN linux-2.6.19.old/drivers/cdrom/aztcd.c linux-2.6.19.dev/drivers/cdrom/aztcd.c
4909 --- linux-2.6.19.old/drivers/cdrom/aztcd.c      2006-11-29 22:57:37.000000000 +0100
4910 +++ linux-2.6.19.dev/drivers/cdrom/aztcd.c      2006-12-14 03:12:59.000000000 +0100
4911 @@ -1918,6 +1918,7 @@
4912         azt_disk->first_minor = 0;
4913         azt_disk->fops = &azt_fops;
4914         sprintf(azt_disk->disk_name, "aztcd");
4915 +       sprintf(azt_disk->devfs_name, "aztcd");
4916         azt_disk->queue = azt_queue;
4917         add_disk(azt_disk);
4918         azt_invalidate_buffers();
4919 diff -urN linux-2.6.19.old/drivers/cdrom/cdu31a.c linux-2.6.19.dev/drivers/cdrom/cdu31a.c
4920 --- linux-2.6.19.old/drivers/cdrom/cdu31a.c     2006-11-29 22:57:37.000000000 +0100
4921 +++ linux-2.6.19.dev/drivers/cdrom/cdu31a.c     2006-12-14 03:12:59.000000000 +0100
4922 @@ -161,6 +161,7 @@
4923  #include <linux/hdreg.h>
4924  #include <linux/genhd.h>
4925  #include <linux/ioport.h>
4926 +#include <linux/devfs_fs_kernel.h>
4927  #include <linux/string.h>
4928  #include <linux/slab.h>
4929  #include <linux/init.h>
4930 diff -urN linux-2.6.19.old/drivers/cdrom/cm206.c linux-2.6.19.dev/drivers/cdrom/cm206.c
4931 --- linux-2.6.19.old/drivers/cdrom/cm206.c      2006-11-29 22:57:37.000000000 +0100
4932 +++ linux-2.6.19.dev/drivers/cdrom/cm206.c      2006-12-14 03:12:59.000000000 +0100
4933 @@ -187,6 +187,7 @@
4934  #include <linux/interrupt.h>
4935  #include <linux/timer.h>
4936  #include <linux/cdrom.h>
4937 +#include <linux/devfs_fs_kernel.h>
4938  #include <linux/ioport.h>
4939  #include <linux/mm.h>
4940  #include <linux/slab.h>
4941 diff -urN linux-2.6.19.old/drivers/cdrom/gscd.c linux-2.6.19.dev/drivers/cdrom/gscd.c
4942 --- linux-2.6.19.old/drivers/cdrom/gscd.c       2006-11-29 22:57:37.000000000 +0100
4943 +++ linux-2.6.19.dev/drivers/cdrom/gscd.c       2006-12-14 03:12:59.000000000 +0100
4944 @@ -955,6 +955,7 @@
4945         gscd_disk->first_minor = 0;
4946         gscd_disk->fops = &gscd_fops;
4947         sprintf(gscd_disk->disk_name, "gscd");
4948 +       sprintf(gscd_disk->devfs_name, "gscd");
4949  
4950         if (register_blkdev(MAJOR_NR, "gscd")) {
4951                 ret = -EIO;
4952 diff -urN linux-2.6.19.old/drivers/cdrom/mcdx.c linux-2.6.19.dev/drivers/cdrom/mcdx.c
4953 --- linux-2.6.19.old/drivers/cdrom/mcdx.c       2006-11-29 22:57:37.000000000 +0100
4954 +++ linux-2.6.19.dev/drivers/cdrom/mcdx.c       2006-12-14 03:12:59.000000000 +0100
4955 @@ -74,6 +74,7 @@
4956  #include <linux/major.h>
4957  #define MAJOR_NR MITSUMI_X_CDROM_MAJOR
4958  #include <linux/blkdev.h>
4959 +#include <linux/devfs_fs_kernel.h>
4960  
4961  #include "mcdx.h"
4962  
4963 diff -urN linux-2.6.19.old/drivers/cdrom/optcd.c linux-2.6.19.dev/drivers/cdrom/optcd.c
4964 --- linux-2.6.19.old/drivers/cdrom/optcd.c      2006-11-29 22:57:37.000000000 +0100
4965 +++ linux-2.6.19.dev/drivers/cdrom/optcd.c      2006-12-14 03:12:59.000000000 +0100
4966 @@ -2033,6 +2033,7 @@
4967         optcd_disk->first_minor = 0;
4968         optcd_disk->fops = &opt_fops;
4969         sprintf(optcd_disk->disk_name, "optcd");
4970 +       sprintf(optcd_disk->devfs_name, "optcd");
4971  
4972         if (!request_region(optcd_port, 4, "optcd")) {
4973                 printk(KERN_ERR "optcd: conflict, I/O port 0x%x already used\n",
4974 diff -urN linux-2.6.19.old/drivers/cdrom/sbpcd.c linux-2.6.19.dev/drivers/cdrom/sbpcd.c
4975 --- linux-2.6.19.old/drivers/cdrom/sbpcd.c      2006-11-29 22:57:37.000000000 +0100
4976 +++ linux-2.6.19.dev/drivers/cdrom/sbpcd.c      2006-12-14 03:12:59.000000000 +0100
4977 @@ -371,6 +371,7 @@
4978  #include <linux/kernel.h>
4979  #include <linux/cdrom.h>
4980  #include <linux/ioport.h>
4981 +#include <linux/devfs_fs_kernel.h>
4982  #include <linux/major.h>
4983  #include <linux/string.h>
4984  #include <linux/vmalloc.h>
4985 @@ -5806,6 +5807,8 @@
4986                 return -ENOMEM;
4987         }
4988  
4989 +       devfs_mk_dir("sbp");
4990 +
4991         for (j=0;j<NR_SBPCD;j++)
4992         {
4993                 struct cdrom_device_info * sbpcd_infop;
4994 @@ -5867,6 +5870,7 @@
4995                 disk->fops = &sbpcd_bdops;
4996                 strcpy(disk->disk_name, sbpcd_infop->name);
4997                 disk->flags = GENHD_FL_CD;
4998 +               sprintf(disk->devfs_name, "sbp/c0t%d", p->drv_id);
4999                 p->disk = disk;
5000                 if (register_cdrom(sbpcd_infop))
5001                 {
5002 @@ -5901,6 +5905,7 @@
5003                 if (D_S[j].drv_id==-1) continue;
5004                 del_gendisk(D_S[j].disk);
5005                 put_disk(D_S[j].disk);
5006 +               devfs_remove("sbp/c0t%d", j);
5007                 vfree(D_S[j].sbp_buf);
5008                 if (D_S[j].sbp_audsiz>0)
5009                         vfree(D_S[j].aud_buf);
5010 @@ -5911,6 +5916,7 @@
5011                 }
5012                 vfree(D_S[j].sbpcd_infop);
5013         }
5014 +       devfs_remove("sbp");
5015         msg(DBG_INF, "%s module released.\n", major_name);
5016  }
5017  
5018 diff -urN linux-2.6.19.old/drivers/cdrom/sjcd.c linux-2.6.19.dev/drivers/cdrom/sjcd.c
5019 --- linux-2.6.19.old/drivers/cdrom/sjcd.c       2006-11-29 22:57:37.000000000 +0100
5020 +++ linux-2.6.19.dev/drivers/cdrom/sjcd.c       2006-12-14 03:12:59.000000000 +0100
5021 @@ -1695,6 +1695,7 @@
5022         sjcd_disk->first_minor = 0,
5023         sjcd_disk->fops = &sjcd_fops,
5024         sprintf(sjcd_disk->disk_name, "sjcd");
5025 +       sprintf(sjcd_disk->devfs_name, "sjcd");
5026  
5027         if (!request_region(sjcd_base, 4,"sjcd")) {
5028                 printk
5029 diff -urN linux-2.6.19.old/drivers/cdrom/sonycd535.c linux-2.6.19.dev/drivers/cdrom/sonycd535.c
5030 --- linux-2.6.19.old/drivers/cdrom/sonycd535.c  2006-11-29 22:57:37.000000000 +0100
5031 +++ linux-2.6.19.dev/drivers/cdrom/sonycd535.c  2006-12-14 03:12:59.000000000 +0100
5032 @@ -1589,6 +1589,7 @@
5033         cdu_disk->first_minor = 0;
5034         cdu_disk->fops = &cdu_fops;
5035         sprintf(cdu_disk->disk_name, "cdu");
5036 +       sprintf(cdu_disk->devfs_name, "cdu535");
5037  
5038         if (!request_region(sony535_cd_base_io, 4, CDU535_HANDLE)) {
5039                 printk(KERN_WARNING"sonycd535: Unable to request region 0x%x\n",
5040 diff -urN linux-2.6.19.old/drivers/cdrom/viocd.c linux-2.6.19.dev/drivers/cdrom/viocd.c
5041 --- linux-2.6.19.old/drivers/cdrom/viocd.c      2006-11-29 22:57:37.000000000 +0100
5042 +++ linux-2.6.19.dev/drivers/cdrom/viocd.c      2006-12-14 03:12:59.000000000 +0100
5043 @@ -49,6 +49,7 @@
5044  #include <asm/iseries/vio.h>
5045  
5046  #define VIOCD_DEVICE                   "iseries/vcd"
5047 +#define VIOCD_DEVICE_DEVFS             "iseries/vcd"
5048  
5049  #define VIOCD_VERS "1.06"
5050  
5051 @@ -687,6 +688,8 @@
5052         gendisk->first_minor = deviceno;
5053         strncpy(gendisk->disk_name, c->name,
5054                         sizeof(gendisk->disk_name));
5055 +       snprintf(gendisk->devfs_name, sizeof(gendisk->devfs_name),
5056 +                       VIOCD_DEVICE_DEVFS "%d", deviceno);
5057         blk_queue_max_hw_segments(q, 1);
5058         blk_queue_max_phys_segments(q, 1);
5059         blk_queue_max_sectors(q, 4096 / 512);
5060 diff -urN linux-2.6.19.old/drivers/char/cyclades.c linux-2.6.19.dev/drivers/char/cyclades.c
5061 --- linux-2.6.19.old/drivers/char/cyclades.c    2006-11-29 22:57:37.000000000 +0100
5062 +++ linux-2.6.19.dev/drivers/char/cyclades.c    2006-12-14 03:12:59.000000000 +0100
5063 @@ -5227,6 +5227,7 @@
5064      cy_serial_driver->owner = THIS_MODULE;
5065      cy_serial_driver->driver_name = "cyclades";
5066      cy_serial_driver->name = "ttyC";
5067 +    cy_serial_driver->devfs_name = "tts/C";
5068      cy_serial_driver->major = CYCLADES_MAJOR;
5069      cy_serial_driver->minor_start = 0;
5070      cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL;
5071 diff -urN linux-2.6.19.old/drivers/char/dsp56k.c linux-2.6.19.dev/drivers/char/dsp56k.c
5072 --- linux-2.6.19.old/drivers/char/dsp56k.c      2006-11-29 22:57:37.000000000 +0100
5073 +++ linux-2.6.19.dev/drivers/char/dsp56k.c      2006-12-14 03:12:59.000000000 +0100
5074 @@ -33,6 +33,7 @@
5075  #include <linux/fs.h>
5076  #include <linux/mm.h>
5077  #include <linux/init.h>
5078 +#include <linux/devfs_fs_kernel.h>
5079  #include <linux/smp_lock.h>
5080  #include <linux/device.h>
5081  
5082 @@ -517,9 +518,17 @@
5083         }
5084         class_device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
5085  
5086 +       err = devfs_mk_cdev(MKDEV(DSP56K_MAJOR, 0),
5087 +                     S_IFCHR | S_IRUSR | S_IWUSR, "dsp56k");
5088 +       if(err)
5089 +               goto out_class;
5090 +
5091         printk(banner);
5092         goto out;
5093  
5094 +out_class:
5095 +       class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0));
5096 +       class_destroy(dsp56k_class);
5097  out_chrdev:
5098         unregister_chrdev(DSP56K_MAJOR, "dsp56k");
5099  out:
5100 @@ -532,6 +541,7 @@
5101         class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0));
5102         class_destroy(dsp56k_class);
5103         unregister_chrdev(DSP56K_MAJOR, "dsp56k");
5104 +       devfs_remove("dsp56k");
5105  }
5106  module_exit(dsp56k_cleanup_driver);
5107  
5108 diff -urN linux-2.6.19.old/drivers/char/dtlk.c linux-2.6.19.dev/drivers/char/dtlk.c
5109 --- linux-2.6.19.old/drivers/char/dtlk.c        2006-11-29 22:57:37.000000000 +0100
5110 +++ linux-2.6.19.dev/drivers/char/dtlk.c        2006-12-14 03:12:59.000000000 +0100
5111 @@ -62,6 +62,7 @@
5112  #include <linux/init.h>                /* for __init, module_{init,exit} */
5113  #include <linux/poll.h>                /* for POLLIN, etc. */
5114  #include <linux/dtlk.h>                /* local header file for DoubleTalk values */
5115 +#include <linux/devfs_fs_kernel.h>
5116  #include <linux/smp_lock.h>
5117  
5118  #ifdef TRACING
5119 @@ -336,6 +337,9 @@
5120         if (dtlk_dev_probe() == 0)
5121                 printk(", MAJOR %d\n", dtlk_major);
5122  
5123 +       devfs_mk_cdev(MKDEV(dtlk_major, DTLK_MINOR),
5124 +                      S_IFCHR | S_IRUSR | S_IWUSR, "dtlk");
5125 +
5126         init_timer(&dtlk_timer);
5127         dtlk_timer.function = dtlk_timer_tick;
5128         init_waitqueue_head(&dtlk_process_list);
5129 @@ -353,6 +357,7 @@
5130  
5131         dtlk_write_tts(DTLK_CLEAR);
5132         unregister_chrdev(dtlk_major, "dtlk");
5133 +       devfs_remove("dtlk");
5134         release_region(dtlk_port_lpc, DTLK_IO_EXTENT);
5135  }
5136  
5137 diff -urN linux-2.6.19.old/drivers/char/epca.c linux-2.6.19.dev/drivers/char/epca.c
5138 --- linux-2.6.19.old/drivers/char/epca.c        2006-11-29 22:57:37.000000000 +0100
5139 +++ linux-2.6.19.dev/drivers/char/epca.c        2006-12-14 03:12:59.000000000 +0100
5140 @@ -1227,6 +1227,7 @@
5141  
5142         pc_driver->owner = THIS_MODULE;
5143         pc_driver->name = "ttyD"; 
5144 +       pc_driver->devfs_name = "tts/D";
5145         pc_driver->major = DIGI_MAJOR; 
5146         pc_driver->minor_start = 0;
5147         pc_driver->type = TTY_DRIVER_TYPE_SERIAL;
5148 diff -urN linux-2.6.19.old/drivers/char/esp.c linux-2.6.19.dev/drivers/char/esp.c
5149 --- linux-2.6.19.old/drivers/char/esp.c 2006-11-29 22:57:37.000000000 +0100
5150 +++ linux-2.6.19.dev/drivers/char/esp.c 2006-12-14 03:12:59.000000000 +0100
5151 @@ -2448,6 +2448,7 @@
5152         
5153         esp_driver->owner = THIS_MODULE;
5154         esp_driver->name = "ttyP";
5155 +       esp_driver->devfs_name = "tts/P";
5156         esp_driver->major = ESP_IN_MAJOR;
5157         esp_driver->minor_start = 0;
5158         esp_driver->type = TTY_DRIVER_TYPE_SERIAL;
5159 diff -urN linux-2.6.19.old/drivers/char/ftape/zftape/zftape-init.c linux-2.6.19.dev/drivers/char/ftape/zftape/zftape-init.c
5160 --- linux-2.6.19.old/drivers/char/ftape/zftape/zftape-init.c    2006-11-29 22:57:37.000000000 +0100
5161 +++ linux-2.6.19.dev/drivers/char/ftape/zftape/zftape-init.c    2006-12-14 03:12:59.000000000 +0100
5162 @@ -32,6 +32,7 @@
5163  #endif
5164  #include <linux/fcntl.h>
5165  #include <linux/smp_lock.h>
5166 +#include <linux/devfs_fs_kernel.h>
5167  
5168  #include <linux/zftape.h>
5169  #include <linux/init.h>
5170 @@ -330,11 +331,29 @@
5171         zft_class = class_create(THIS_MODULE, "zft");
5172         for (i = 0; i < 4; i++) {
5173                 class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
5174 +               devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i),
5175 +                               S_IFCHR | S_IRUSR | S_IWUSR,
5176 +                               "qft%i", i);
5177                 class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
5178 +               devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 4),
5179 +                               S_IFCHR | S_IRUSR | S_IWUSR,
5180 +                               "nqft%i", i);
5181                 class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
5182 +               devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 16),
5183 +                               S_IFCHR | S_IRUSR | S_IWUSR,
5184 +                               "zqft%i", i);
5185                 class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
5186 +               devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 20),
5187 +                               S_IFCHR | S_IRUSR | S_IWUSR,
5188 +                               "nzqft%i", i);
5189                 class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
5190 +               devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 32),
5191 +                               S_IFCHR | S_IRUSR | S_IWUSR,
5192 +                               "rawqft%i", i);
5193                 class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
5194 +               devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 36),
5195 +                               S_IFCHR | S_IRUSR | S_IWUSR,
5196 +                               "nrawqft%i", i);
5197         }
5198  
5199  #ifdef CONFIG_ZFT_COMPRESSOR
5200 @@ -360,11 +379,17 @@
5201                 TRACE(ft_t_info, "successful");
5202         }
5203          for (i = 0; i < 4; i++) {
5204 +               devfs_remove("qft%i", i);
5205                 class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i));
5206 +               devfs_remove("nqft%i", i);
5207                 class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4));
5208 +               devfs_remove("zqft%i", i);
5209                 class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16));
5210 +               devfs_remove("nzqft%i", i);
5211                 class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20));
5212 +               devfs_remove("rawqft%i", i);
5213                 class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32));
5214 +               devfs_remove("nrawqft%i", i);
5215                 class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36));
5216         }
5217         class_destroy(zft_class);
5218 diff -urN linux-2.6.19.old/drivers/char/hvc_console.c linux-2.6.19.dev/drivers/char/hvc_console.c
5219 --- linux-2.6.19.old/drivers/char/hvc_console.c 2006-11-29 22:57:37.000000000 +0100
5220 +++ linux-2.6.19.dev/drivers/char/hvc_console.c 2006-12-14 03:12:59.000000000 +0100
5221 @@ -822,6 +822,7 @@
5222                 return -ENOMEM;
5223  
5224         drv->owner = THIS_MODULE;
5225 +       drv->devfs_name = "hvc/";
5226         drv->driver_name = "hvc";
5227         drv->name = "hvc";
5228         drv->major = HVC_MAJOR;
5229 diff -urN linux-2.6.19.old/drivers/char/hvcs.c linux-2.6.19.dev/drivers/char/hvcs.c
5230 --- linux-2.6.19.old/drivers/char/hvcs.c        2006-11-29 22:57:37.000000000 +0100
5231 +++ linux-2.6.19.dev/drivers/char/hvcs.c        2006-12-14 03:12:59.000000000 +0100
5232 @@ -1361,6 +1361,7 @@
5233  
5234         hvcs_tty_driver->driver_name = hvcs_driver_name;
5235         hvcs_tty_driver->name = hvcs_device_node;
5236 +       hvcs_tty_driver->devfs_name = hvcs_device_node;
5237  
5238         /*
5239          * We'll let the system assign us a major number, indicated by leaving
5240 diff -urN linux-2.6.19.old/drivers/char/hvsi.c linux-2.6.19.dev/drivers/char/hvsi.c
5241 --- linux-2.6.19.old/drivers/char/hvsi.c        2006-11-29 22:57:37.000000000 +0100
5242 +++ linux-2.6.19.dev/drivers/char/hvsi.c        2006-12-14 03:12:59.000000000 +0100
5243 @@ -1152,6 +1152,7 @@
5244                 return -ENOMEM;
5245  
5246         hvsi_driver->owner = THIS_MODULE;
5247 +       hvsi_driver->devfs_name = "hvsi/";
5248         hvsi_driver->driver_name = "hvsi";
5249         hvsi_driver->name = "hvsi";
5250         hvsi_driver->major = HVSI_MAJOR;
5251 diff -urN linux-2.6.19.old/drivers/char/ip2/ip2main.c linux-2.6.19.dev/drivers/char/ip2/ip2main.c
5252 --- linux-2.6.19.old/drivers/char/ip2/ip2main.c 2006-11-29 22:57:37.000000000 +0100
5253 +++ linux-2.6.19.dev/drivers/char/ip2/ip2main.c 2006-12-14 03:12:59.000000000 +0100
5254 @@ -90,6 +90,7 @@
5255  #include <linux/module.h>
5256  #include <linux/signal.h>
5257  #include <linux/sched.h>
5258 +#include <linux/devfs_fs_kernel.h>
5259  #include <linux/timer.h>
5260  #include <linux/interrupt.h>
5261  #include <linux/pci.h>
5262 @@ -412,7 +413,9 @@
5263                         /* free io addresses and Tibet */
5264                         release_region( ip2config.addr[i], 8 );
5265                         class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
5266 +                       devfs_remove("ip2/ipl%d", i);
5267                         class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
5268 +                       devfs_remove("ip2/stat%d", i);
5269                 }
5270                 /* Disable and remove interrupt handler. */
5271                 if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { 
5272 @@ -421,6 +424,7 @@
5273                 }
5274         }
5275         class_destroy(ip2_class);
5276 +       devfs_remove("ip2");
5277         if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) {
5278                 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err);
5279         }
5280 @@ -674,6 +678,7 @@
5281  
5282         ip2_tty_driver->owner               = THIS_MODULE;
5283         ip2_tty_driver->name                 = "ttyF";
5284 +       ip2_tty_driver->devfs_name          = "tts/F";
5285         ip2_tty_driver->driver_name          = pcDriver_name;
5286         ip2_tty_driver->major                = IP2_TTY_MAJOR;
5287         ip2_tty_driver->minor_start          = 0;
5288 @@ -722,9 +727,26 @@
5289                                 class_device_create(ip2_class, NULL,
5290                                                 MKDEV(IP2_IPL_MAJOR, 4 * i),
5291                                                 NULL, "ipl%d", i);
5292 +                               err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
5293 +                                               S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
5294 +                                               "ip2/ipl%d", i);
5295 +                               if (err) {
5296 +                                       class_device_destroy(ip2_class,
5297 +                                               MKDEV(IP2_IPL_MAJOR, 4 * i));
5298 +                                       goto out_class;
5299 +                               }
5300 +
5301                                 class_device_create(ip2_class, NULL,
5302                                                 MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
5303                                                 NULL, "stat%d", i);
5304 +                               err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
5305 +                                               S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
5306 +                                               "ip2/stat%d", i);
5307 +                               if (err) {
5308 +                                       class_device_destroy(ip2_class,
5309 +                                               MKDEV(IP2_IPL_MAJOR, 4 * i + 1));
5310 +                                       goto out_class;
5311 +                               }
5312  
5313                             for ( box = 0; box < ABS_MAX_BOXES; ++box )
5314                             {
5315 diff -urN linux-2.6.19.old/drivers/char/ipmi/ipmi_devintf.c linux-2.6.19.dev/drivers/char/ipmi/ipmi_devintf.c
5316 --- linux-2.6.19.old/drivers/char/ipmi/ipmi_devintf.c   2006-11-29 22:57:37.000000000 +0100
5317 +++ linux-2.6.19.dev/drivers/char/ipmi/ipmi_devintf.c   2006-12-14 03:12:59.000000000 +0100
5318 @@ -39,6 +39,7 @@
5319  #include <linux/poll.h>
5320  #include <linux/spinlock.h>
5321  #include <linux/slab.h>
5322 +#include <linux/devfs_fs_kernel.h>
5323  #include <linux/ipmi.h>
5324  #include <linux/mutex.h>
5325  #include <linux/init.h>
5326 @@ -832,6 +833,9 @@
5327         dev_t dev = MKDEV(ipmi_major, if_num);
5328         struct ipmi_reg_list *entry;
5329  
5330 +       devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
5331 +                     "ipmidev/%d", if_num);
5332 +
5333         entry = kmalloc(sizeof(*entry), GFP_KERNEL);
5334         if (!entry) {
5335                 printk(KERN_ERR "ipmi_devintf: Unable to create the"
5336 @@ -861,6 +865,7 @@
5337         }
5338         class_device_destroy(ipmi_class, dev);
5339         mutex_unlock(&reg_list_mutex);
5340 +       devfs_remove("ipmidev/%d", if_num);
5341  }
5342  
5343  static struct ipmi_smi_watcher smi_watcher =
5344 @@ -896,6 +901,8 @@
5345                 ipmi_major = rv;
5346         }
5347  
5348 +       devfs_mk_dir(DEVICE_NAME);
5349 +
5350         rv = ipmi_smi_watcher_register(&smi_watcher);
5351         if (rv) {
5352                 unregister_chrdev(ipmi_major, DEVICE_NAME);
5353 @@ -920,6 +927,7 @@
5354         mutex_unlock(&reg_list_mutex);
5355         class_destroy(ipmi_class);
5356         ipmi_smi_watcher_unregister(&smi_watcher);
5357 +       devfs_remove(DEVICE_NAME);
5358         unregister_chrdev(ipmi_major, DEVICE_NAME);
5359  }
5360  module_exit(cleanup_ipmi);
5361 diff -urN linux-2.6.19.old/drivers/char/isicom.c linux-2.6.19.dev/drivers/char/isicom.c
5362 --- linux-2.6.19.old/drivers/char/isicom.c      2006-11-29 22:57:37.000000000 +0100
5363 +++ linux-2.6.19.dev/drivers/char/isicom.c      2006-12-14 03:12:59.000000000 +0100
5364 @@ -1582,6 +1582,7 @@
5365  
5366         isicom_normal->owner                    = THIS_MODULE;
5367         isicom_normal->name                     = "ttyM";
5368 +       isicom_normal->devfs_name               = "isicom/";
5369         isicom_normal->major                    = ISICOM_NMAJOR;
5370         isicom_normal->minor_start              = 0;
5371         isicom_normal->type                     = TTY_DRIVER_TYPE_SERIAL;
5372 diff -urN linux-2.6.19.old/drivers/char/lp.c linux-2.6.19.dev/drivers/char/lp.c
5373 --- linux-2.6.19.old/drivers/char/lp.c  2006-11-29 22:57:37.000000000 +0100
5374 +++ linux-2.6.19.dev/drivers/char/lp.c  2006-12-14 03:12:59.000000000 +0100
5375 @@ -119,6 +119,7 @@
5376  #include <linux/major.h>
5377  #include <linux/sched.h>
5378  #include <linux/smp_lock.h>
5379 +#include <linux/devfs_fs_kernel.h>
5380  #include <linux/slab.h>
5381  #include <linux/fcntl.h>
5382  #include <linux/delay.h>
5383 @@ -805,6 +806,8 @@
5384  
5385         class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL,
5386                                 "lp%d", nr);
5387 +       devfs_mk_cdev(MKDEV(LP_MAJOR, nr), S_IFCHR | S_IRUGO | S_IWUGO,
5388 +                       "printers/%d", nr);
5389  
5390         printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, 
5391                (port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven");
5392 @@ -903,6 +906,7 @@
5393                 return -EIO;
5394         }
5395  
5396 +       devfs_mk_dir("printers");
5397         lp_class = class_create(THIS_MODULE, "printer");
5398         if (IS_ERR(lp_class)) {
5399                 err = PTR_ERR(lp_class);
5400 @@ -928,6 +932,7 @@
5401  out_class:
5402         class_destroy(lp_class);
5403  out_reg:
5404 +       devfs_remove("printers");
5405         unregister_chrdev(LP_MAJOR, "lp");
5406         return err;
5407  }
5408 @@ -975,8 +980,10 @@
5409                 if (lp_table[offset].dev == NULL)
5410                         continue;
5411                 parport_unregister_device(lp_table[offset].dev);
5412 +               devfs_remove("printers/%d", offset);
5413                 class_device_destroy(lp_class, MKDEV(LP_MAJOR, offset));
5414         }
5415 +       devfs_remove("printers");
5416         class_destroy(lp_class);
5417  }
5418  
5419 diff -urN linux-2.6.19.old/drivers/char/mem.c linux-2.6.19.dev/drivers/char/mem.c
5420 --- linux-2.6.19.old/drivers/char/mem.c 2006-11-29 22:57:37.000000000 +0100
5421 +++ linux-2.6.19.dev/drivers/char/mem.c 2006-12-14 03:12:59.000000000 +0100
5422 @@ -19,6 +19,7 @@
5423  #include <linux/tty.h>
5424  #include <linux/capability.h>
5425  #include <linux/smp_lock.h>
5426 +#include <linux/devfs_fs_kernel.h>
5427  #include <linux/ptrace.h>
5428  #include <linux/device.h>
5429  #include <linux/highmem.h>
5430 @@ -979,10 +980,13 @@
5431                 printk("unable to get major %d for memory devs\n", MEM_MAJOR);
5432  
5433         mem_class = class_create(THIS_MODULE, "mem");
5434 -       for (i = 0; i < ARRAY_SIZE(devlist); i++)
5435 +       for (i = 0; i < ARRAY_SIZE(devlist); i++) {
5436                 class_device_create(mem_class, NULL,
5437                                         MKDEV(MEM_MAJOR, devlist[i].minor),
5438                                         NULL, devlist[i].name);
5439 +               devfs_mk_cdev(MKDEV(MEM_MAJOR, devlist[i].minor),
5440 +                               S_IFCHR | devlist[i].mode, devlist[i].name);
5441 +       }
5442         
5443         return 0;
5444  }
5445 diff -urN linux-2.6.19.old/drivers/char/misc.c linux-2.6.19.dev/drivers/char/misc.c
5446 --- linux-2.6.19.old/drivers/char/misc.c        2006-11-29 22:57:37.000000000 +0100
5447 +++ linux-2.6.19.dev/drivers/char/misc.c        2006-12-14 03:12:59.000000000 +0100
5448 @@ -43,6 +43,7 @@
5449  #include <linux/slab.h>
5450  #include <linux/proc_fs.h>
5451  #include <linux/seq_file.h>
5452 +#include <linux/devfs_fs_kernel.h>
5453  #include <linux/stat.h>
5454  #include <linux/init.h>
5455  #include <linux/device.h>
5456 @@ -226,6 +227,10 @@
5457  
5458         if (misc->minor < DYNAMIC_MINORS)
5459                 misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
5460 +       if (misc->devfs_name[0] == '\0') {
5461 +               snprintf(misc->devfs_name, sizeof(misc->devfs_name),
5462 +                               "misc/%s", misc->name);
5463 +       }
5464         dev = MKDEV(MISC_MAJOR, misc->minor);
5465  
5466         misc->class = class_device_create(misc_class, NULL, dev, misc->dev,
5467 @@ -235,6 +240,13 @@
5468                 goto out;
5469         }
5470  
5471 +       err = devfs_mk_cdev(dev, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP, 
5472 +                           misc->devfs_name);
5473 +       if (err) {
5474 +               class_device_destroy(misc_class, dev);
5475 +               goto out;
5476 +       }
5477 +
5478         /*
5479          * Add it to the front, so that later devices can "override"
5480          * earlier defaults
5481 @@ -265,6 +277,7 @@
5482         down(&misc_sem);
5483         list_del(&misc->list);
5484         class_device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
5485 +       devfs_remove(misc->devfs_name);
5486         if (i < DYNAMIC_MINORS && i>0) {
5487                 misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
5488         }
5489 diff -urN linux-2.6.19.old/drivers/char/mmtimer.c linux-2.6.19.dev/drivers/char/mmtimer.c
5490 --- linux-2.6.19.old/drivers/char/mmtimer.c     2006-11-29 22:57:37.000000000 +0100
5491 +++ linux-2.6.19.dev/drivers/char/mmtimer.c     2006-12-14 03:12:59.000000000 +0100
5492 @@ -25,6 +25,7 @@
5493  #include <linux/init.h>
5494  #include <linux/errno.h>
5495  #include <linux/mm.h>
5496 +#include <linux/devfs_fs_kernel.h>
5497  #include <linux/mmtimer.h>
5498  #include <linux/miscdevice.h>
5499  #include <linux/posix-timers.h>
5500 @@ -692,6 +693,7 @@
5501                 return -1;
5502         }
5503  
5504 +       strcpy(mmtimer_miscdev.devfs_name, MMTIMER_NAME);
5505         if (misc_register(&mmtimer_miscdev)) {
5506                 printk(KERN_ERR "%s: failed to register device\n",
5507                        MMTIMER_NAME);
5508 diff -urN linux-2.6.19.old/drivers/char/moxa.c linux-2.6.19.dev/drivers/char/moxa.c
5509 --- linux-2.6.19.old/drivers/char/moxa.c        2006-11-29 22:57:37.000000000 +0100
5510 +++ linux-2.6.19.dev/drivers/char/moxa.c        2006-12-14 03:12:59.000000000 +0100
5511 @@ -346,6 +346,7 @@
5512         init_MUTEX(&moxaBuffSem);
5513         moxaDriver->owner = THIS_MODULE;
5514         moxaDriver->name = "ttyMX";
5515 +       moxaDriver->devfs_name = "tts/a";
5516         moxaDriver->major = ttymajor;
5517         moxaDriver->minor_start = 0;
5518         moxaDriver->type = TTY_DRIVER_TYPE_SERIAL;
5519 diff -urN linux-2.6.19.old/drivers/char/ppdev.c linux-2.6.19.dev/drivers/char/ppdev.c
5520 --- linux-2.6.19.old/drivers/char/ppdev.c       2006-11-29 22:57:37.000000000 +0100
5521 +++ linux-2.6.19.dev/drivers/char/ppdev.c       2006-12-14 03:12:59.000000000 +0100
5522 @@ -60,6 +60,7 @@
5523  #include <linux/init.h>
5524  #include <linux/sched.h>
5525  #include <linux/device.h>
5526 +#include <linux/devfs_fs_kernel.h>
5527  #include <linux/ioctl.h>
5528  #include <linux/parport.h>
5529  #include <linux/ctype.h>
5530 @@ -781,6 +782,11 @@
5531                 err = PTR_ERR(ppdev_class);
5532                 goto out_chrdev;
5533         }
5534 +       devfs_mk_dir("parports");
5535 +       for (i = 0; i < PARPORT_MAX; i++) {
5536 +               devfs_mk_cdev(MKDEV(PP_MAJOR, i),
5537 +                               S_IFCHR | S_IRUGO | S_IWUGO, "parports/%d", i);
5538 +       }
5539         if (parport_register_driver(&pp_driver)) {
5540                 printk (KERN_WARNING CHRDEV ": unable to register with parport\n");
5541                 goto out_class;
5542 @@ -790,6 +796,9 @@
5543         goto out;
5544  
5545  out_class:
5546 +       for (i = 0; i < PARPORT_MAX; i++)
5547 +               devfs_remove("parports/%d", i);
5548 +       devfs_remove("parports");
5549         class_destroy(ppdev_class);
5550  out_chrdev:
5551         unregister_chrdev(PP_MAJOR, CHRDEV);
5552 @@ -799,8 +808,12 @@
5553  
5554  static void __exit ppdev_cleanup (void)
5555  {
5556 +       int i;
5557         /* Clean up all parport stuff */
5558 +       for (i = 0; i < PARPORT_MAX; i++)
5559 +               devfs_remove("parports/%d", i);
5560         parport_unregister_driver(&pp_driver);
5561 +       devfs_remove("parports");
5562         class_destroy(ppdev_class);
5563         unregister_chrdev (PP_MAJOR, CHRDEV);
5564  }
5565 diff -urN linux-2.6.19.old/drivers/char/pty.c linux-2.6.19.dev/drivers/char/pty.c
5566 --- linux-2.6.19.old/drivers/char/pty.c 2006-11-29 22:57:37.000000000 +0100
5567 +++ linux-2.6.19.dev/drivers/char/pty.c 2006-12-14 03:12:59.000000000 +0100
5568 @@ -23,6 +23,7 @@
5569  #include <linux/major.h>
5570  #include <linux/mm.h>
5571  #include <linux/init.h>
5572 +#include <linux/devfs_fs_kernel.h>
5573  #include <linux/sysctl.h>
5574  
5575  #include <asm/uaccess.h>
5576 @@ -263,6 +264,7 @@
5577         pty_driver->owner = THIS_MODULE;
5578         pty_driver->driver_name = "pty_master";
5579         pty_driver->name = "pty";
5580 +       pty_driver->devfs_name = "pty/m";
5581         pty_driver->major = PTY_MASTER_MAJOR;
5582         pty_driver->minor_start = 0;
5583         pty_driver->type = TTY_DRIVER_TYPE_PTY;
5584 @@ -280,6 +282,7 @@
5585         pty_slave_driver->owner = THIS_MODULE;
5586         pty_slave_driver->driver_name = "pty_slave";
5587         pty_slave_driver->name = "ttyp";
5588 +       pty_slave_driver->devfs_name = "pty/s";
5589         pty_slave_driver->major = PTY_SLAVE_MAJOR;
5590         pty_slave_driver->minor_start = 0;
5591         pty_slave_driver->type = TTY_DRIVER_TYPE_PTY;
5592 @@ -347,6 +350,7 @@
5593  
5594  static void __init unix98_pty_init(void)
5595  {
5596 +       devfs_mk_dir("pts");
5597         ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX);
5598         if (!ptm_driver)
5599                 panic("Couldn't allocate Unix98 ptm driver");
5600 diff -urN linux-2.6.19.old/drivers/char/raw.c linux-2.6.19.dev/drivers/char/raw.c
5601 --- linux-2.6.19.old/drivers/char/raw.c 2006-11-29 22:57:37.000000000 +0100
5602 +++ linux-2.6.19.dev/drivers/char/raw.c 2006-12-14 03:12:59.000000000 +0100
5603 @@ -10,6 +10,7 @@
5604  
5605  #include <linux/init.h>
5606  #include <linux/fs.h>
5607 +#include <linux/devfs_fs_kernel.h>
5608  #include <linux/major.h>
5609  #include <linux/blkdev.h>
5610  #include <linux/module.h>
5611 @@ -285,6 +286,13 @@
5612         }
5613         class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
5614  
5615 +       devfs_mk_cdev(MKDEV(RAW_MAJOR, 0),
5616 +                     S_IFCHR | S_IRUGO | S_IWUGO,
5617 +                     "raw/rawctl");
5618 +       for (i = 1; i < MAX_RAW_MINORS; i++)
5619 +               devfs_mk_cdev(MKDEV(RAW_MAJOR, i),
5620 +                             S_IFCHR | S_IRUGO | S_IWUGO,
5621 +                             "raw/raw%d", i);
5622         return 0;
5623  
5624  error_region:
5625 @@ -295,6 +303,12 @@
5626  
5627  static void __exit raw_exit(void)
5628  {
5629 +       int i;
5630 +
5631 +       for (i = 1; i < MAX_RAW_MINORS; i++)
5632 +               devfs_remove("raw/raw%d", i);
5633 +       devfs_remove("raw/rawctl");
5634 +       devfs_remove("raw");
5635         class_device_destroy(raw_class, MKDEV(RAW_MAJOR, 0));
5636         class_destroy(raw_class);
5637         cdev_del(&raw_cdev);
5638 diff -urN linux-2.6.19.old/drivers/char/riscom8.c linux-2.6.19.dev/drivers/char/riscom8.c
5639 --- linux-2.6.19.old/drivers/char/riscom8.c     2006-11-29 22:57:37.000000000 +0100
5640 +++ linux-2.6.19.dev/drivers/char/riscom8.c     2006-12-14 03:12:59.000000000 +0100
5641 @@ -1613,6 +1613,7 @@
5642         memset(IRQ_to_board, 0, sizeof(IRQ_to_board));
5643         riscom_driver->owner = THIS_MODULE;
5644         riscom_driver->name = "ttyL";
5645 +       riscom_driver->devfs_name = "tts/L";
5646         riscom_driver->major = RISCOM8_NORMAL_MAJOR;
5647         riscom_driver->type = TTY_DRIVER_TYPE_SERIAL;
5648         riscom_driver->subtype = SERIAL_TYPE_NORMAL;
5649 diff -urN linux-2.6.19.old/drivers/char/rocket.c linux-2.6.19.dev/drivers/char/rocket.c
5650 --- linux-2.6.19.old/drivers/char/rocket.c      2006-11-29 22:57:37.000000000 +0100
5651 +++ linux-2.6.19.dev/drivers/char/rocket.c      2006-12-14 03:12:59.000000000 +0100
5652 @@ -2426,7 +2426,8 @@
5653          */
5654  
5655         rocket_driver->owner = THIS_MODULE;
5656 -       rocket_driver->flags = TTY_DRIVER_DYNAMIC_DEV;
5657 +       rocket_driver->flags = TTY_DRIVER_NO_DEVFS;
5658 +       rocket_driver->devfs_name = "tts/R";
5659         rocket_driver->name = "ttyR";
5660         rocket_driver->driver_name = "Comtrol RocketPort";
5661         rocket_driver->major = TTY_ROCKET_MAJOR;
5662 @@ -2437,7 +2438,7 @@
5663         rocket_driver->init_termios.c_cflag =
5664             B9600 | CS8 | CREAD | HUPCL | CLOCAL;
5665  #ifdef ROCKET_SOFT_FLOW
5666 -       rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
5667 +       rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
5668  #endif
5669         tty_set_operations(rocket_driver, &rocket_ops);
5670  
5671 diff -urN linux-2.6.19.old/drivers/char/serial167.c linux-2.6.19.dev/drivers/char/serial167.c
5672 --- linux-2.6.19.old/drivers/char/serial167.c   2006-11-29 22:57:37.000000000 +0100
5673 +++ linux-2.6.19.dev/drivers/char/serial167.c   2006-12-14 03:12:59.000000000 +0100
5674 @@ -2218,6 +2218,7 @@
5675      /* Initialize the tty_driver structure */
5676      
5677      cy_serial_driver->owner = THIS_MODULE;
5678 +    cy_serial_driver->devfs_name = "tts/";
5679      cy_serial_driver->name = "ttyS";
5680      cy_serial_driver->major = TTY_MAJOR;
5681      cy_serial_driver->minor_start = 64;
5682 diff -urN linux-2.6.19.old/drivers/char/stallion.c linux-2.6.19.dev/drivers/char/stallion.c
5683 --- linux-2.6.19.old/drivers/char/stallion.c    2006-11-29 22:57:37.000000000 +0100
5684 +++ linux-2.6.19.dev/drivers/char/stallion.c    2006-12-14 03:12:59.000000000 +0100
5685 @@ -39,6 +39,7 @@
5686  #include <linux/ioport.h>
5687  #include <linux/init.h>
5688  #include <linux/smp_lock.h>
5689 +#include <linux/devfs_fs_kernel.h>
5690  #include <linux/device.h>
5691  #include <linux/delay.h>
5692  
5693 @@ -753,15 +754,21 @@
5694         if (i) {
5695                 printk("STALLION: failed to un-register tty driver, "
5696                         "errno=%d\n", -i);
5697 +               restore_flags(flags);
5698                 return;
5699         }
5700 -       for (i = 0; i < 4; i++)
5701 +       for (i = 0; i < 4; i++) {
5702 +               devfs_remove("staliomem/%d", i);
5703                 class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i));
5704 +       }
5705 +       devfs_remove("staliomem");
5706         if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
5707                 printk("STALLION: failed to un-register serial memory device, "
5708                         "errno=%d\n", -i);
5709         class_destroy(stallion_class);
5710  
5711 +       kfree(stl_tmpwritebuf);
5712 +
5713         for (i = 0; (i < stl_nrbrds); i++) {
5714                 if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
5715                         continue;
5716 @@ -3033,21 +3040,35 @@
5717                 return -1;
5718  
5719  /*
5720 + *     Allocate a temporary write buffer.
5721 + */
5722 +       stl_tmpwritebuf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
5723 +       if (!stl_tmpwritebuf)
5724 +               printk("STALLION: failed to allocate memory (size=%d)\n",
5725 +                       STL_TXBUFSIZE);
5726 +
5727 +/*
5728   *     Set up a character driver for per board stuff. This is mainly used
5729   *     to do stats ioctls on the ports.
5730   */
5731         if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem))
5732                 printk("STALLION: failed to register serial board device\n");
5733 +       devfs_mk_dir("staliomem");
5734  
5735         stallion_class = class_create(THIS_MODULE, "staliomem");
5736 -       for (i = 0; i < 4; i++)
5737 +       for (i = 0; i < 4; i++) {
5738 +               devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
5739 +                               S_IFCHR|S_IRUSR|S_IWUSR,
5740 +                               "staliomem/%d", i);
5741                 class_device_create(stallion_class, NULL,
5742                                     MKDEV(STL_SIOMEMMAJOR, i), NULL,
5743                                     "staliomem%d", i);
5744 +       }
5745  
5746         stl_serial->owner = THIS_MODULE;
5747         stl_serial->driver_name = stl_drvname;
5748         stl_serial->name = "ttyE";
5749 +       stl_serial->devfs_name = "tts/E";
5750         stl_serial->major = STL_SERIALMAJOR;
5751         stl_serial->minor_start = 0;
5752         stl_serial->type = TTY_DRIVER_TYPE_SERIAL;
5753 diff -urN linux-2.6.19.old/drivers/char/tipar.c linux-2.6.19.dev/drivers/char/tipar.c
5754 --- linux-2.6.19.old/drivers/char/tipar.c       2006-11-29 22:57:37.000000000 +0100
5755 +++ linux-2.6.19.dev/drivers/char/tipar.c       2006-12-14 03:12:59.000000000 +0100
5756 @@ -55,6 +55,7 @@
5757  #include <linux/ioport.h>
5758  #include <asm/io.h>
5759  #include <linux/bitops.h>
5760 +#include <linux/devfs_fs_kernel.h>     /* DevFs support */
5761  #include <linux/parport.h>             /* Our code depend on parport */
5762  #include <linux/device.h>
5763  
5764 @@ -443,6 +444,12 @@
5765  
5766         class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR,
5767                         TIPAR_MINOR + nr), NULL, "par%d", nr);
5768 +       /* Use devfs, tree: /dev/ticables/par/[0..2] */
5769 +       err = devfs_mk_cdev(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr),
5770 +                       S_IFCHR | S_IRUGO | S_IWUGO,
5771 +                       "ticables/par/%d", nr);
5772 +       if (err)
5773 +               goto out_class;
5774  
5775         /* Display informations */
5776         pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq ==
5777 @@ -497,6 +504,9 @@
5778                 goto out;
5779         }
5780  
5781 +       /* Use devfs with tree: /dev/ticables/par/[0..2] */
5782 +       devfs_mk_dir("ticables/par");
5783 +
5784         tipar_class = class_create(THIS_MODULE, "ticables");
5785         if (IS_ERR(tipar_class)) {
5786                 err = PTR_ERR(tipar_class);
5787 @@ -515,6 +525,7 @@
5788         class_destroy(tipar_class);
5789  
5790  out_chrdev:
5791 +       devfs_remove("ticables/par");
5792         unregister_chrdev(TIPAR_MAJOR, "tipar");
5793  out:
5794         return err;     
5795 @@ -535,8 +546,10 @@
5796                         continue;
5797                 parport_unregister_device(table[i].dev);
5798                 class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i));
5799 +               devfs_remove("ticables/par/%d", i);
5800         }
5801         class_destroy(tipar_class);
5802 +       devfs_remove("ticables/par");
5803  
5804         pr_info("tipar: module unloaded\n");
5805  }
5806 diff -urN linux-2.6.19.old/drivers/char/tty_io.c linux-2.6.19.dev/drivers/char/tty_io.c
5807 --- linux-2.6.19.old/drivers/char/tty_io.c      2006-11-29 22:57:37.000000000 +0100
5808 +++ linux-2.6.19.dev/drivers/char/tty_io.c      2006-12-14 03:12:59.000000000 +0100
5809 @@ -101,6 +101,7 @@
5810  #include <linux/kbd_kern.h>
5811  #include <linux/vt_kern.h>
5812  #include <linux/selection.h>
5813 +#include <linux/devfs_fs_kernel.h>
5814  
5815  #include <linux/kmod.h>
5816  
5817 @@ -3634,6 +3635,9 @@
5818                 return ERR_PTR(-EINVAL);
5819         }
5820  
5821 +       devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
5822 +                       "%s%d", driver->devfs_name, index + driver->name_base);
5823 +
5824         if (driver->type == TTY_DRIVER_TYPE_PTY)
5825                 pty_line_name(driver, index, name);
5826         else
5827 @@ -3655,6 +3659,7 @@
5828  
5829  void tty_unregister_device(struct tty_driver *driver, unsigned index)
5830  {
5831 +       devfs_remove("%s%d", driver->devfs_name, index + driver->name_base);
5832         class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index);
5833  }
5834  
5835 @@ -3776,7 +3781,7 @@
5836         
5837         list_add(&driver->tty_drivers, &tty_drivers);
5838         
5839 -       if ( !(driver->flags & TTY_DRIVER_DYNAMIC_DEV) ) {
5840 +       if ( !(driver->flags & TTY_DRIVER_NO_DEVFS) ) {
5841                 for(i = 0; i < driver->num; i++)
5842                     tty_register_device(driver, i, NULL);
5843         }
5844 @@ -3819,7 +3824,7 @@
5845                         driver->termios_locked[i] = NULL;
5846                         kfree(tp);
5847                 }
5848 -               if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
5849 +               if (!(driver->flags & TTY_DRIVER_NO_DEVFS))
5850                         tty_unregister_device(driver, i);
5851         }
5852         p = driver->ttys;
5853 @@ -3895,12 +3900,14 @@
5854         if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
5855             register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
5856                 panic("Couldn't register /dev/tty driver\n");
5857 +       devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty");
5858         class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
5859  
5860         cdev_init(&console_cdev, &console_fops);
5861         if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
5862             register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
5863                 panic("Couldn't register /dev/console driver\n");
5864 +       devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console");
5865         class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
5866  
5867  #ifdef CONFIG_UNIX98_PTYS
5868 @@ -3908,6 +3915,7 @@
5869         if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
5870             register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
5871                 panic("Couldn't register /dev/ptmx driver\n");
5872 +       devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx");
5873         class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
5874  #endif
5875  
5876 @@ -3916,6 +3924,7 @@
5877         if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
5878             register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
5879                 panic("Couldn't register /dev/tty0 driver\n");
5880 +       devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0");
5881         class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
5882  
5883         vty_init();
5884 diff -urN linux-2.6.19.old/drivers/char/vc_screen.c linux-2.6.19.dev/drivers/char/vc_screen.c
5885 --- linux-2.6.19.old/drivers/char/vc_screen.c   2006-11-29 22:57:37.000000000 +0100
5886 +++ linux-2.6.19.dev/drivers/char/vc_screen.c   2006-12-14 03:12:59.000000000 +0100
5887 @@ -25,6 +25,7 @@
5888  #include <linux/major.h>
5889  #include <linux/errno.h>
5890  #include <linux/tty.h>
5891 +#include <linux/devfs_fs_kernel.h>
5892  #include <linux/sched.h>
5893  #include <linux/interrupt.h>
5894  #include <linux/mm.h>
5895 @@ -476,6 +477,12 @@
5896  
5897  void vcs_make_sysfs(struct tty_struct *tty)
5898  {
5899 +       devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 1),
5900 +                       S_IFCHR|S_IRUSR|S_IWUSR,
5901 +                       "vcc/%u", tty->index + 1);
5902 +       devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 129),
5903 +                       S_IFCHR|S_IRUSR|S_IWUSR,
5904 +                       "vcc/a%u", tty->index + 1);
5905         class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
5906                         NULL, "vcs%u", tty->index + 1);
5907         class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
5908 @@ -484,6 +491,8 @@
5909  
5910  void vcs_remove_sysfs(struct tty_struct *tty)
5911  {
5912 +       devfs_remove("vcc/%u", tty->index + 1);
5913 +       devfs_remove("vcc/a%u", tty->index + 1);
5914         class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1));
5915         class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129));
5916  }
5917 @@ -494,6 +503,8 @@
5918                 panic("unable to get major %d for vcs device", VCS_MAJOR);
5919         vc_class = class_create(THIS_MODULE, "vc");
5920  
5921 +       devfs_mk_cdev(MKDEV(VCS_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/0");
5922 +       devfs_mk_cdev(MKDEV(VCS_MAJOR, 128), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a0");
5923         class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
5924         class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
5925         return 0;
5926 diff -urN linux-2.6.19.old/drivers/char/viocons.c linux-2.6.19.dev/drivers/char/viocons.c
5927 --- linux-2.6.19.old/drivers/char/viocons.c     2006-11-29 22:57:37.000000000 +0100
5928 +++ linux-2.6.19.dev/drivers/char/viocons.c     2006-12-14 03:12:59.000000000 +0100
5929 @@ -1121,6 +1121,7 @@
5930         viotty_driver = alloc_tty_driver(VTTY_PORTS);
5931         viotty_driver->owner = THIS_MODULE;
5932         viotty_driver->driver_name = "vioconsole";
5933 +       viotty_driver->devfs_name = "vcs/";
5934         viotty_driver->name = "tty";
5935         viotty_driver->name_base = 1;
5936         viotty_driver->major = TTY_MAJOR;
5937 diff -urN linux-2.6.19.old/drivers/char/viotape.c linux-2.6.19.dev/drivers/char/viotape.c
5938 --- linux-2.6.19.old/drivers/char/viotape.c     2006-11-29 22:57:37.000000000 +0100
5939 +++ linux-2.6.19.dev/drivers/char/viotape.c     2006-12-14 03:12:59.000000000 +0100
5940 @@ -42,6 +42,7 @@
5941  #include <linux/dma-mapping.h>
5942  #include <linux/fs.h>
5943  #include <linux/cdev.h>
5944 +#include <linux/devfs_fs_kernel.h>
5945  #include <linux/major.h>
5946  #include <linux/completion.h>
5947  #include <linux/proc_fs.h>
5948 @@ -942,6 +943,7 @@
5949  {
5950         int i = vdev->unit_address;
5951         int j;
5952 +       char tapename[16];
5953  
5954         if (i >= viotape_numdev)
5955                 return -ENODEV;
5956 @@ -955,6 +957,12 @@
5957                         "iseries!vt%d", i);
5958         class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
5959                         NULL, "iseries!nvt%d", i);
5960 +       devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR,
5961 +                       "iseries/vt%d", i);
5962 +       devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i | 0x80),
5963 +                       S_IFCHR | S_IRUSR | S_IWUSR, "iseries/nvt%d", i);
5964 +       sprintf(tapename, "iseries/vt%d", i);
5965 +       state[i].dev_handle = devfs_register_tape(tapename);
5966         printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries "
5967                         "resource %10.10s type %4.4s, model %3.3s\n",
5968                         i, viotape_unitinfo[i].rsrcname,
5969 @@ -966,6 +974,9 @@
5970  {
5971         int i = vdev->unit_address;
5972  
5973 +       devfs_remove("iseries/nvt%d", i);
5974 +       devfs_remove("iseries/vt%d", i);
5975 +       devfs_unregister_tape(state[i].dev_handle);
5976         class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80));
5977         class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i));
5978         return 0;
5979 diff -urN linux-2.6.19.old/drivers/char/vme_scc.c linux-2.6.19.dev/drivers/char/vme_scc.c
5980 --- linux-2.6.19.old/drivers/char/vme_scc.c     2006-11-29 22:57:37.000000000 +0100
5981 +++ linux-2.6.19.dev/drivers/char/vme_scc.c     2006-12-14 03:12:59.000000000 +0100
5982 @@ -146,6 +146,7 @@
5983         scc_driver->owner = THIS_MODULE;
5984         scc_driver->driver_name = "scc";
5985         scc_driver->name = "ttyS";
5986 +       scc_driver->devfs_name = "tts/";
5987         scc_driver->major = TTY_MAJOR;
5988         scc_driver->minor_start = SCC_MINOR_BASE;
5989         scc_driver->type = TTY_DRIVER_TYPE_SERIAL;
5990 diff -urN linux-2.6.19.old/drivers/char/vt.c linux-2.6.19.dev/drivers/char/vt.c
5991 --- linux-2.6.19.old/drivers/char/vt.c  2006-11-29 22:57:37.000000000 +0100
5992 +++ linux-2.6.19.dev/drivers/char/vt.c  2006-12-14 03:12:59.000000000 +0100
5993 @@ -86,6 +86,7 @@
5994  #include <linux/mm.h>
5995  #include <linux/console.h>
5996  #include <linux/init.h>
5997 +#include <linux/devfs_fs_kernel.h>
5998  #include <linux/vt_kern.h>
5999  #include <linux/selection.h>
6000  #include <linux/tiocl.h>
6001 @@ -2691,6 +2692,7 @@
6002         if (!console_driver)
6003                 panic("Couldn't allocate console driver\n");
6004         console_driver->owner = THIS_MODULE;
6005 +       console_driver->devfs_name = "vc/";
6006         console_driver->name = "tty";
6007         console_driver->name_base = 1;
6008         console_driver->major = TTY_MAJOR;
6009 diff -urN linux-2.6.19.old/drivers/ide/ide.c linux-2.6.19.dev/drivers/ide/ide.c
6010 --- linux-2.6.19.old/drivers/ide/ide.c  2006-11-29 22:57:37.000000000 +0100
6011 +++ linux-2.6.19.dev/drivers/ide/ide.c  2006-12-14 03:12:59.000000000 +0100
6012 @@ -146,6 +146,7 @@
6013  #include <linux/pci.h>
6014  #include <linux/delay.h>
6015  #include <linux/ide.h>
6016 +#include <linux/devfs_fs_kernel.h>
6017  #include <linux/completion.h>
6018  #include <linux/reboot.h>
6019  #include <linux/cdrom.h>
6020 @@ -591,8 +592,13 @@
6021                 goto abort;
6022         for (unit = 0; unit < MAX_DRIVES; ++unit) {
6023                 drive = &hwif->drives[unit];
6024 -               if (!drive->present)
6025 +               if (!drive->present) {
6026 +                       if (drive->devfs_name[0] != '\0') {
6027 +                               devfs_remove(drive->devfs_name);
6028 +                               drive->devfs_name[0] = '\0';
6029 +                       }
6030                         continue;
6031 +               }
6032                 spin_unlock_irq(&ide_lock);
6033                 device_unregister(&drive->gendev);
6034                 wait_for_completion(&drive->gendev_rel_comp);
6035 @@ -2005,6 +2011,7 @@
6036         int ret;
6037  
6038         printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
6039 +       devfs_mk_dir("ide");
6040         system_bus_speed = ide_system_bus_speed();
6041  
6042         ret = bus_register(&ide_bus_type);
6043 @@ -2086,6 +2093,7 @@
6044  #ifdef CONFIG_PROC_FS
6045         proc_ide_destroy();
6046  #endif
6047 +       devfs_remove("ide");
6048  
6049         bus_unregister(&ide_bus_type);
6050  }
6051 diff -urN linux-2.6.19.old/drivers/ide/ide-cd.c linux-2.6.19.dev/drivers/ide/ide-cd.c
6052 --- linux-2.6.19.old/drivers/ide/ide-cd.c       2006-11-29 22:57:37.000000000 +0100
6053 +++ linux-2.6.19.dev/drivers/ide/ide-cd.c       2006-12-14 03:12:59.000000000 +0100
6054 @@ -3528,6 +3528,8 @@
6055         drive->driver_data = info;
6056  
6057         g->minors = 1;
6058 +       snprintf(g->devfs_name, sizeof(g->devfs_name),
6059 +                       "%s/cd", drive->devfs_name);
6060         g->driverfs_dev = &drive->gendev;
6061         g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
6062         if (ide_cdrom_setup(drive)) {
6063 diff -urN linux-2.6.19.old/drivers/ide/ide-disk.c linux-2.6.19.dev/drivers/ide/ide-disk.c
6064 --- linux-2.6.19.old/drivers/ide/ide-disk.c     2006-11-29 22:57:37.000000000 +0100
6065 +++ linux-2.6.19.dev/drivers/ide/ide-disk.c     2006-12-14 03:12:59.000000000 +0100
6066 @@ -1018,6 +1018,7 @@
6067         struct gendisk *g = idkp->disk;
6068  
6069         drive->driver_data = NULL;
6070 +       drive->devfs_name[0] = '\0';
6071         g->private_data = NULL;
6072         put_disk(g);
6073         kfree(idkp);
6074 @@ -1221,6 +1222,7 @@
6075                 drive->attach = 1;
6076  
6077         g->minors = 1 << PARTN_BITS;
6078 +       strcpy(g->devfs_name, drive->devfs_name);
6079         g->driverfs_dev = &drive->gendev;
6080         g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0;
6081         set_capacity(g, idedisk_capacity(drive));
6082 diff -urN linux-2.6.19.old/drivers/ide/ide-floppy.c linux-2.6.19.dev/drivers/ide/ide-floppy.c
6083 --- linux-2.6.19.old/drivers/ide/ide-floppy.c   2006-11-29 22:57:37.000000000 +0100
6084 +++ linux-2.6.19.dev/drivers/ide/ide-floppy.c   2006-12-14 03:12:59.000000000 +0100
6085 @@ -2174,6 +2174,7 @@
6086  
6087         g->minors = 1 << PARTN_BITS;
6088         g->driverfs_dev = &drive->gendev;
6089 +       strcpy(g->devfs_name, drive->devfs_name);
6090         g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0;
6091         g->fops = &idefloppy_ops;
6092         drive->attach = 1;
6093 diff -urN linux-2.6.19.old/drivers/ide/ide-probe.c linux-2.6.19.dev/drivers/ide/ide-probe.c
6094 --- linux-2.6.19.old/drivers/ide/ide-probe.c    2006-11-29 22:57:37.000000000 +0100
6095 +++ linux-2.6.19.dev/drivers/ide/ide-probe.c    2006-12-14 03:12:59.000000000 +0100
6096 @@ -46,6 +46,7 @@
6097  #include <linux/slab.h>
6098  #include <linux/delay.h>
6099  #include <linux/ide.h>
6100 +#include <linux/devfs_fs_kernel.h>
6101  #include <linux/spinlock.h>
6102  #include <linux/kmod.h>
6103  #include <linux/pci.h>
6104 @@ -1288,6 +1289,10 @@
6105         ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
6106  
6107         spin_lock_irq(&ide_lock);
6108 +       if (drive->devfs_name[0] != '\0') {
6109 +               devfs_remove(drive->devfs_name);
6110 +               drive->devfs_name[0] = '\0';
6111 +       }
6112         ide_remove_drive_from_hwgroup(drive);
6113         kfree(drive->id);
6114         drive->id = NULL;
6115 @@ -1321,6 +1326,12 @@
6116                 drive->gendev.bus = &ide_bus_type;
6117                 drive->gendev.driver_data = drive;
6118                 drive->gendev.release = drive_release_dev;
6119 +               if (drive->present) {
6120 +                       sprintf(drive->devfs_name, "ide/host%d/bus%d/target%d/lun%d",
6121 +                               (hwif->channel && hwif->mate) ?
6122 +                               hwif->mate->index : hwif->index,
6123 +                               hwif->channel, unit, drive->lun);
6124 +               }
6125         }
6126         blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS,
6127                         THIS_MODULE, ata_probe, ata_lock, hwif);
6128 diff -urN linux-2.6.19.old/drivers/ide/ide-tape.c linux-2.6.19.dev/drivers/ide/ide-tape.c
6129 --- linux-2.6.19.old/drivers/ide/ide-tape.c     2006-11-29 22:57:37.000000000 +0100
6130 +++ linux-2.6.19.dev/drivers/ide/ide-tape.c     2006-12-14 03:12:59.000000000 +0100
6131 @@ -434,6 +434,7 @@
6132  #include <linux/interrupt.h>
6133  #include <linux/jiffies.h>
6134  #include <linux/major.h>
6135 +#include <linux/devfs_fs_kernel.h>
6136  #include <linux/errno.h>
6137  #include <linux/genhd.h>
6138  #include <linux/slab.h>
6139 @@ -4724,6 +4725,9 @@
6140                         MKDEV(IDETAPE_MAJOR, tape->minor));
6141         class_device_destroy(idetape_sysfs_class,
6142                         MKDEV(IDETAPE_MAJOR, tape->minor + 128));
6143 +       devfs_remove("%s/mt", drive->devfs_name);
6144 +       devfs_remove("%s/mtn", drive->devfs_name);
6145 +       devfs_unregister_tape(g->number);
6146         idetape_devs[tape->minor] = NULL;
6147         g->private_data = NULL;
6148         put_disk(g);
6149 @@ -4897,6 +4901,14 @@
6150         class_device_create(idetape_sysfs_class, NULL,
6151                         MKDEV(IDETAPE_MAJOR, minor + 128), &drive->gendev, "n%s", tape->name);
6152  
6153 +       devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor),
6154 +                       S_IFCHR | S_IRUGO | S_IWUGO,
6155 +                       "%s/mt", drive->devfs_name);
6156 +       devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor + 128),
6157 +                       S_IFCHR | S_IRUGO | S_IWUGO,
6158 +                       "%s/mtn", drive->devfs_name);
6159 +
6160 +       g->number = devfs_register_tape(drive->devfs_name);
6161         g->fops = &idetape_block_ops;
6162         ide_register_region(g);
6163  
6164 diff -urN linux-2.6.19.old/drivers/ieee1394/dv1394.c linux-2.6.19.dev/drivers/ieee1394/dv1394.c
6165 --- linux-2.6.19.old/drivers/ieee1394/dv1394.c  2006-11-29 22:57:37.000000000 +0100
6166 +++ linux-2.6.19.dev/drivers/ieee1394/dv1394.c  2006-12-14 03:12:59.000000000 +0100
6167 @@ -2263,14 +2263,37 @@
6168         list_add_tail(&video->list, &dv1394_cards);
6169         spin_unlock_irqrestore(&dv1394_cards_lock, flags);
6170  
6171 +       if (devfs_mk_cdev(MKDEV(IEEE1394_MAJOR,
6172 +                               IEEE1394_MINOR_BLOCK_DV1394*16 + video->id),
6173 +                       S_IFCHR|S_IRUGO|S_IWUGO,
6174 +                        "ieee1394/dv/host%d/%s/%s",
6175 +                        (video->id>>2),
6176 +                        (video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"),
6177 +                        (video->mode == MODE_RECEIVE ? "in" : "out")) < 0)
6178 +                       goto err_free;
6179 +
6180         debug_printk("dv1394: dv1394_init() OK on ID %d\n", video->id);
6181 +
6182         return 0;
6183 +
6184 + err_free:
6185 +       kfree(video);
6186 + err:
6187 +       return -1;
6188  }
6189  
6190  static void dv1394_un_init(struct video_card *video)
6191  {
6192 +       char buf[32];
6193 +
6194         /* obviously nobody has the driver open at this point */
6195         do_dv1394_shutdown(video, 1);
6196 +       snprintf(buf, sizeof(buf), "dv/host%d/%s/%s", (video->id >> 2),
6197 +               (video->pal_or_ntsc == DV1394_NTSC ? "NTSC" : "PAL"),
6198 +               (video->mode == MODE_RECEIVE ? "in" : "out")
6199 +               );
6200 +
6201 +       devfs_remove("ieee1394/%s", buf);
6202         kfree(video);
6203  }
6204  
6205 @@ -2307,6 +2330,9 @@
6206  
6207         class_device_destroy(hpsb_protocol_class,
6208                 MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)));
6209 +       devfs_remove("ieee1394/dv/host%d/NTSC", id);
6210 +       devfs_remove("ieee1394/dv/host%d/PAL", id);
6211 +       devfs_remove("ieee1394/dv/host%d", id);
6212  }
6213  
6214  static void dv1394_add_host (struct hpsb_host *host)
6215 @@ -2323,6 +2349,9 @@
6216         class_device_create(hpsb_protocol_class, NULL, MKDEV(
6217                 IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), 
6218                 NULL, "dv1394-%d", id);
6219 +       devfs_mk_dir("ieee1394/dv/host%d", id);
6220 +       devfs_mk_dir("ieee1394/dv/host%d/NTSC", id);
6221 +       devfs_mk_dir("ieee1394/dv/host%d/PAL", id);
6222  
6223         dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
6224         dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT);
6225 @@ -2579,8 +2608,10 @@
6226  static void __exit dv1394_exit_module(void)
6227  {
6228         hpsb_unregister_protocol(&dv1394_driver);
6229 +
6230         hpsb_unregister_highlevel(&dv1394_highlevel);
6231         cdev_del(&dv1394_cdev);
6232 +       devfs_remove("ieee1394/dv");
6233  }
6234  
6235  static int __init dv1394_init_module(void)
6236 @@ -2596,12 +2627,15 @@
6237                 return ret;
6238         }
6239  
6240 +       devfs_mk_dir("ieee1394/dv");
6241 +
6242         hpsb_register_highlevel(&dv1394_highlevel);
6243  
6244         ret = hpsb_register_protocol(&dv1394_driver);
6245         if (ret) {
6246                 printk(KERN_ERR "dv1394: failed to register protocol\n");
6247                 hpsb_unregister_highlevel(&dv1394_highlevel);
6248 +               devfs_remove("ieee1394/dv");
6249                 cdev_del(&dv1394_cdev);
6250                 return ret;
6251         }
6252 diff -urN linux-2.6.19.old/drivers/ieee1394/ieee1394_core.c linux-2.6.19.dev/drivers/ieee1394/ieee1394_core.c
6253 --- linux-2.6.19.old/drivers/ieee1394/ieee1394_core.c   2006-11-29 22:57:37.000000000 +0100
6254 +++ linux-2.6.19.dev/drivers/ieee1394/ieee1394_core.c   2006-12-14 03:12:59.000000000 +0100
6255 @@ -1072,10 +1072,17 @@
6256                 goto exit_release_kernel_thread;
6257         }
6258  
6259 +       /* actually this is a non-fatal error */
6260 +       ret = devfs_mk_dir("ieee1394");
6261 +       if (ret < 0) {
6262 +               HPSB_ERR("unable to make devfs dir for device major %d!\n", IEEE1394_MAJOR);
6263 +               goto release_chrdev;
6264 +       }
6265 +
6266         ret = bus_register(&ieee1394_bus_type);
6267         if (ret < 0) {
6268                 HPSB_INFO("bus register failed");
6269 -               goto release_chrdev;
6270 +               goto release_devfs;
6271         }
6272  
6273         for (i = 0; fw_bus_attrs[i]; i++) {
6274 @@ -1086,7 +1093,7 @@
6275                                                 fw_bus_attrs[i--]);
6276                         }
6277                         bus_unregister(&ieee1394_bus_type);
6278 -                       goto release_chrdev;
6279 +                       goto release_devfs;
6280                 }
6281         }
6282  
6283 @@ -1139,6 +1146,8 @@
6284         for (i = 0; fw_bus_attrs[i]; i++)
6285                 bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]);
6286         bus_unregister(&ieee1394_bus_type);
6287 +release_devfs:
6288 +       devfs_remove("ieee1394");
6289  release_chrdev:
6290         unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
6291  exit_release_kernel_thread:
6292 @@ -1168,6 +1177,7 @@
6293         hpsb_cleanup_config_roms();
6294  
6295         unregister_chrdev_region(IEEE1394_CORE_DEV, 256);
6296 +       devfs_remove("ieee1394");
6297  }
6298  
6299  fs_initcall(ieee1394_init); /* same as ohci1394 */
6300 diff -urN linux-2.6.19.old/drivers/ieee1394/ieee1394_core.h linux-2.6.19.dev/drivers/ieee1394/ieee1394_core.h
6301 --- linux-2.6.19.old/drivers/ieee1394/ieee1394_core.h   2006-11-29 22:57:37.000000000 +0100
6302 +++ linux-2.6.19.dev/drivers/ieee1394/ieee1394_core.h   2006-12-14 03:12:59.000000000 +0100
6303 @@ -6,6 +6,7 @@
6304  #include <linux/list.h>
6305  #include <linux/skbuff.h>
6306  #include <linux/types.h>
6307 +#include <linux/devfs_fs_kernel.h>
6308  #include <asm/atomic.h>
6309  
6310  #include "hosts.h"
6311 diff -urN linux-2.6.19.old/drivers/ieee1394/raw1394.c linux-2.6.19.dev/drivers/ieee1394/raw1394.c
6312 --- linux-2.6.19.old/drivers/ieee1394/raw1394.c 2006-11-29 22:57:37.000000000 +0100
6313 +++ linux-2.6.19.dev/drivers/ieee1394/raw1394.c 2006-12-14 03:12:59.000000000 +0100
6314 @@ -41,6 +41,7 @@
6315  #include <linux/cdev.h>
6316  #include <asm/uaccess.h>
6317  #include <asm/atomic.h>
6318 +#include <linux/devfs_fs_kernel.h>
6319  #include <linux/compat.h>
6320  
6321  #include "csr1212.h"
6322 @@ -3017,6 +3018,9 @@
6323                 goto out_unreg;
6324         }
6325  
6326 +       devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
6327 +                     S_IFCHR | S_IRUSR | S_IWUSR, RAW1394_DEVICE_NAME);
6328 +
6329         cdev_init(&raw1394_cdev, &raw1394_fops);
6330         raw1394_cdev.owner = THIS_MODULE;
6331         kobject_set_name(&raw1394_cdev.kobj, RAW1394_DEVICE_NAME);
6332 @@ -3038,6 +3042,7 @@
6333         goto out;
6334  
6335        out_dev:
6336 +       devfs_remove(RAW1394_DEVICE_NAME);
6337         class_device_destroy(hpsb_protocol_class,
6338                              MKDEV(IEEE1394_MAJOR,
6339                                    IEEE1394_MINOR_BLOCK_RAW1394 * 16));
6340 @@ -3053,6 +3058,7 @@
6341                              MKDEV(IEEE1394_MAJOR,
6342                                    IEEE1394_MINOR_BLOCK_RAW1394 * 16));
6343         cdev_del(&raw1394_cdev);
6344 +       devfs_remove(RAW1394_DEVICE_NAME);
6345         hpsb_unregister_highlevel(&raw1394_highlevel);
6346         hpsb_unregister_protocol(&raw1394_driver);
6347  }
6348 diff -urN linux-2.6.19.old/drivers/ieee1394/video1394.c linux-2.6.19.dev/drivers/ieee1394/video1394.c
6349 --- linux-2.6.19.old/drivers/ieee1394/video1394.c       2006-11-29 22:57:37.000000000 +0100
6350 +++ linux-2.6.19.dev/drivers/ieee1394/video1394.c       2006-12-14 03:12:59.000000000 +0100
6351 @@ -41,6 +41,7 @@
6352  #include <linux/poll.h>
6353  #include <linux/smp_lock.h>
6354  #include <linux/delay.h>
6355 +#include <linux/devfs_fs_kernel.h>
6356  #include <linux/bitops.h>
6357  #include <linux/types.h>
6358  #include <linux/vmalloc.h>
6359 @@ -1356,6 +1357,9 @@
6360         class_device_create(hpsb_protocol_class, NULL, MKDEV(
6361                 IEEE1394_MAJOR, minor), 
6362                 NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
6363 +       devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor),
6364 +                      S_IFCHR | S_IRUSR | S_IWUSR,
6365 +                      "%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
6366  }
6367  
6368  
6369 @@ -1363,9 +1367,12 @@
6370  {
6371         struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host);
6372  
6373 -       if (ohci)
6374 +       if (ohci) {
6375                 class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR,
6376                         IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id));
6377 +               devfs_remove("%s/%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
6378 +       }
6379 +       
6380         return;
6381  }
6382  
6383 @@ -1506,8 +1513,12 @@
6384  static void __exit video1394_exit_module (void)
6385  {
6386         hpsb_unregister_protocol(&video1394_driver);
6387 +
6388         hpsb_unregister_highlevel(&video1394_highlevel);
6389 +
6390 +       devfs_remove(VIDEO1394_DRIVER_NAME);
6391         cdev_del(&video1394_cdev);
6392 +
6393         PRINT_G(KERN_INFO, "Removed " VIDEO1394_DRIVER_NAME " module");
6394  }
6395  
6396 @@ -1524,12 +1535,15 @@
6397                 return ret;
6398          }
6399  
6400 +       devfs_mk_dir(VIDEO1394_DRIVER_NAME);
6401 +
6402         hpsb_register_highlevel(&video1394_highlevel);
6403  
6404         ret = hpsb_register_protocol(&video1394_driver);
6405         if (ret) {
6406                 PRINT_G(KERN_ERR, "video1394: failed to register protocol");
6407                 hpsb_unregister_highlevel(&video1394_highlevel);
6408 +               devfs_remove(VIDEO1394_DRIVER_NAME);
6409                 cdev_del(&video1394_cdev);
6410                 return ret;
6411         }
6412 diff -urN linux-2.6.19.old/drivers/input/serio/serio_raw.c linux-2.6.19.dev/drivers/input/serio/serio_raw.c
6413 --- linux-2.6.19.old/drivers/input/serio/serio_raw.c    2006-11-29 22:57:37.000000000 +0100
6414 +++ linux-2.6.19.dev/drivers/input/serio/serio_raw.c    2006-12-14 03:12:59.000000000 +0100
6415 @@ -16,6 +16,7 @@
6416  #include <linux/init.h>
6417  #include <linux/major.h>
6418  #include <linux/device.h>
6419 +#include <linux/devfs_fs_kernel.h>
6420  #include <linux/miscdevice.h>
6421  #include <linux/wait.h>
6422  #include <linux/mutex.h>
6423 diff -urN linux-2.6.19.old/drivers/isdn/capi/capi.c linux-2.6.19.dev/drivers/isdn/capi/capi.c
6424 --- linux-2.6.19.old/drivers/isdn/capi/capi.c   2006-11-29 22:57:37.000000000 +0100
6425 +++ linux-2.6.19.dev/drivers/isdn/capi/capi.c   2006-12-14 03:12:59.000000000 +0100
6426 @@ -38,6 +38,7 @@
6427  #include <linux/init.h>
6428  #include <linux/device.h>
6429  #include <linux/moduleparam.h>
6430 +#include <linux/devfs_fs_kernel.h>
6431  #include <linux/isdn/capiutil.h>
6432  #include <linux/isdn/capicmd.h>
6433  #if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
6434 @@ -1335,6 +1336,7 @@
6435  
6436         drv->owner = THIS_MODULE;
6437         drv->driver_name = "capi_nc";
6438 +       drv->devfs_name = "capi/";
6439         drv->name = "capi";
6440         drv->major = capi_ttymajor;
6441         drv->minor_start = 0;
6442 @@ -1513,6 +1515,8 @@
6443         }
6444  
6445         class_device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");
6446 +       devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR,
6447 +                       "isdn/capi20");
6448  
6449  #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
6450         if (capinc_tty_init() < 0) {
6451 @@ -1547,6 +1551,7 @@
6452         class_device_destroy(capi_class, MKDEV(capi_major, 0));
6453         class_destroy(capi_class);
6454         unregister_chrdev(capi_major, "capi20");
6455 +       devfs_remove("isdn/capi20");
6456  
6457  #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
6458         capinc_tty_exit();
6459 diff -urN linux-2.6.19.old/drivers/isdn/gigaset/bas-gigaset.c linux-2.6.19.dev/drivers/isdn/gigaset/bas-gigaset.c
6460 --- linux-2.6.19.old/drivers/isdn/gigaset/bas-gigaset.c 2006-11-29 22:57:37.000000000 +0100
6461 +++ linux-2.6.19.dev/drivers/isdn/gigaset/bas-gigaset.c 2006-12-14 03:12:59.000000000 +0100
6462 @@ -41,6 +41,7 @@
6463  #define GIGASET_MINORS     1
6464  #define GIGASET_MINOR      16
6465  #define GIGASET_MODULENAME "bas_gigaset"
6466 +#define GIGASET_DEVFSNAME  "gig/bas/"
6467  #define GIGASET_DEVNAME    "ttyGB"
6468  
6469  /* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */
6470 @@ -2348,7 +2349,8 @@
6471         /* allocate memory for our driver state and intialize it */
6472         if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
6473                                        GIGASET_MODULENAME, GIGASET_DEVNAME,
6474 -                                      &gigops, THIS_MODULE)) == NULL)
6475 +                                      GIGASET_DEVFSNAME, &gigops,
6476 +                                      THIS_MODULE)) == NULL)
6477                 goto error;
6478  
6479         /* allocate memory for our device state and intialize it */
6480 diff -urN linux-2.6.19.old/drivers/isdn/gigaset/common.c linux-2.6.19.dev/drivers/isdn/gigaset/common.c
6481 --- linux-2.6.19.old/drivers/isdn/gigaset/common.c      2006-11-29 22:57:37.000000000 +0100
6482 +++ linux-2.6.19.dev/drivers/isdn/gigaset/common.c      2006-12-14 03:12:59.000000000 +0100
6483 @@ -1092,12 +1092,14 @@
6484   *     minors          Number of minors this driver can handle
6485   *     procname        Name of the driver
6486   *     devname         Name of the device files (prefix without minor number)
6487 + *     devfsname       Devfs name of the device files without %d
6488   * return value:
6489   *     Pointer to the gigaset_driver structure on success, NULL on failure.
6490   */
6491  struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
6492                                           const char *procname,
6493                                           const char *devname,
6494 +                                         const char *devfsname,
6495                                           const struct gigaset_ops *ops,
6496                                           struct module *owner)
6497  {
6498 @@ -1137,7 +1139,7 @@
6499                 drv->cs[i].minor_index = i;
6500         }
6501  
6502 -       gigaset_if_initdriver(drv, procname, devname);
6503 +       gigaset_if_initdriver(drv, procname, devname, devfsname);
6504  
6505         spin_lock_irqsave(&driver_lock, flags);
6506         list_add(&drv->list, &drivers);
6507 diff -urN linux-2.6.19.old/drivers/isdn/gigaset/gigaset.h linux-2.6.19.dev/drivers/isdn/gigaset/gigaset.h
6508 --- linux-2.6.19.old/drivers/isdn/gigaset/gigaset.h     2006-11-29 22:57:37.000000000 +0100
6509 +++ linux-2.6.19.dev/drivers/isdn/gigaset/gigaset.h     2006-12-14 03:12:59.000000000 +0100
6510 @@ -768,6 +768,7 @@
6511  struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
6512                                           const char *procname,
6513                                           const char *devname,
6514 +                                         const char *devfsname,
6515                                           const struct gigaset_ops *ops,
6516                                           struct module *owner);
6517  
6518 @@ -890,7 +891,7 @@
6519  
6520  /* initialize interface */
6521  void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname,
6522 -                          const char *devname);
6523 +                          const char *devname, const char *devfsname);
6524  /* release interface */
6525  void gigaset_if_freedriver(struct gigaset_driver *drv);
6526  /* add minor */
6527 diff -urN linux-2.6.19.old/drivers/isdn/gigaset/interface.c linux-2.6.19.dev/drivers/isdn/gigaset/interface.c
6528 --- linux-2.6.19.old/drivers/isdn/gigaset/interface.c   2006-11-29 22:57:37.000000000 +0100
6529 +++ linux-2.6.19.dev/drivers/isdn/gigaset/interface.c   2006-12-14 03:12:59.000000000 +0100
6530 @@ -673,9 +673,10 @@
6531   *     drv             Driver
6532   *     procname        Name of the driver (e.g. for /proc/tty/drivers)
6533   *     devname         Name of the device files (prefix without minor number)
6534 + *     devfsname       Devfs name of the device files without %d
6535   */
6536  void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname,
6537 -                          const char *devname)
6538 +                          const char *devname, const char *devfsname)
6539  {
6540         unsigned minors = drv->minors;
6541         int ret;
6542 @@ -691,7 +692,7 @@
6543         tty->major =            GIG_MAJOR,
6544         tty->type =             TTY_DRIVER_TYPE_SERIAL,
6545         tty->subtype =          SERIAL_TYPE_NORMAL,
6546 -       tty->flags =            TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
6547 +       tty->flags =            TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
6548  
6549         tty->driver_name =      procname;
6550         tty->name =             devname;
6551 @@ -699,6 +700,7 @@
6552         tty->num =              drv->minors;
6553  
6554         tty->owner =            THIS_MODULE;
6555 +       tty->devfs_name =       devfsname;
6556  
6557         tty->init_termios          = tty_std_termios; //FIXME
6558         tty->init_termios.c_cflag  = B9600 | CS8 | CREAD | HUPCL | CLOCAL; //FIXME
6559 diff -urN linux-2.6.19.old/drivers/isdn/gigaset/usb-gigaset.c linux-2.6.19.dev/drivers/isdn/gigaset/usb-gigaset.c
6560 --- linux-2.6.19.old/drivers/isdn/gigaset/usb-gigaset.c 2006-11-29 22:57:37.000000000 +0100
6561 +++ linux-2.6.19.dev/drivers/isdn/gigaset/usb-gigaset.c 2006-12-14 03:12:59.000000000 +0100
6562 @@ -41,6 +41,7 @@
6563  #define GIGASET_MINORS     1
6564  #define GIGASET_MINOR      8
6565  #define GIGASET_MODULENAME "usb_gigaset"
6566 +#define GIGASET_DEVFSNAME  "gig/usb/"
6567  #define GIGASET_DEVNAME    "ttyGU"
6568  
6569  #define IF_WRITEBUF 2000 //FIXME  // WAKEUP_CHARS: 256
6570 @@ -895,7 +896,8 @@
6571         /* allocate memory for our driver state and intialize it */
6572         if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
6573                                        GIGASET_MODULENAME, GIGASET_DEVNAME,
6574 -                                      &ops, THIS_MODULE)) == NULL)
6575 +                                      GIGASET_DEVFSNAME, &ops,
6576 +                                      THIS_MODULE)) == NULL)
6577                 goto error;
6578  
6579         /* allocate memory for our device state and intialize it */
6580 diff -urN linux-2.6.19.old/drivers/isdn/hardware/eicon/divamnt.c linux-2.6.19.dev/drivers/isdn/hardware/eicon/divamnt.c
6581 --- linux-2.6.19.old/drivers/isdn/hardware/eicon/divamnt.c      2006-11-29 22:57:37.000000000 +0100
6582 +++ linux-2.6.19.dev/drivers/isdn/hardware/eicon/divamnt.c      2006-12-14 03:12:59.000000000 +0100
6583 @@ -10,12 +10,14 @@
6584   * of the GNU General Public License, incorporated herein by reference.
6585   */
6586  
6587 +#include <linux/config.h>
6588  #include <linux/module.h>
6589  #include <linux/init.h>
6590  #include <linux/kernel.h>
6591  #include <linux/sched.h>
6592  #include <linux/smp_lock.h>
6593  #include <linux/poll.h>
6594 +#include <linux/devfs_fs_kernel.h>
6595  #include <asm/uaccess.h>
6596  
6597  #include "platform.h"
6598 @@ -176,6 +178,7 @@
6599  
6600  static void divas_maint_unregister_chrdev(void)
6601  {
6602 +       devfs_remove(DEVNAME);
6603         unregister_chrdev(major, DEVNAME);
6604  }
6605  
6606 @@ -187,6 +190,7 @@
6607                        DRIVERLNAME);
6608                 return (0);
6609         }
6610 +       devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
6611  
6612         return (1);
6613  }
6614 diff -urN linux-2.6.19.old/drivers/isdn/hardware/eicon/divasi.c linux-2.6.19.dev/drivers/isdn/hardware/eicon/divasi.c
6615 --- linux-2.6.19.old/drivers/isdn/hardware/eicon/divasi.c       2006-11-29 22:57:37.000000000 +0100
6616 +++ linux-2.6.19.dev/drivers/isdn/hardware/eicon/divasi.c       2006-12-14 03:12:59.000000000 +0100
6617 @@ -18,6 +18,7 @@
6618  #include <linux/poll.h>
6619  #include <linux/proc_fs.h>
6620  #include <linux/skbuff.h>
6621 +#include <linux/devfs_fs_kernel.h>
6622  #include <asm/uaccess.h>
6623  
6624  #include "platform.h"
6625 @@ -143,6 +144,7 @@
6626  
6627  static void divas_idi_unregister_chrdev(void)
6628  {
6629 +       devfs_remove(DEVNAME);
6630         unregister_chrdev(major, DEVNAME);
6631  }
6632  
6633 @@ -154,6 +156,7 @@
6634                        DRIVERLNAME);
6635                 return (0);
6636         }
6637 +       devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
6638  
6639         return (1);
6640  }
6641 diff -urN linux-2.6.19.old/drivers/isdn/hardware/eicon/divasmain.c linux-2.6.19.dev/drivers/isdn/hardware/eicon/divasmain.c
6642 --- linux-2.6.19.old/drivers/isdn/hardware/eicon/divasmain.c    2006-11-29 22:57:37.000000000 +0100
6643 +++ linux-2.6.19.dev/drivers/isdn/hardware/eicon/divasmain.c    2006-12-14 03:12:59.000000000 +0100
6644 @@ -9,10 +9,12 @@
6645   * of the GNU General Public License, incorporated herein by reference.
6646   */
6647  
6648 +#include <linux/config.h>
6649  #include <linux/module.h>
6650  #include <linux/init.h>
6651  #include <linux/kernel.h>
6652  #include <linux/sched.h>
6653 +#include <linux/devfs_fs_kernel.h>
6654  #include <asm/uaccess.h>
6655  #include <asm/io.h>
6656  #include <linux/ioport.h>
6657 @@ -675,6 +677,7 @@
6658  
6659  static void divas_unregister_chrdev(void)
6660  {
6661 +       devfs_remove(DEVNAME);
6662         unregister_chrdev(major, DEVNAME);
6663  }
6664  
6665 @@ -686,6 +689,7 @@
6666                        DRIVERLNAME);
6667                 return (0);
6668         }
6669 +       devfs_mk_cdev(MKDEV(major, 0), S_IFCHR|S_IRUSR|S_IWUSR, DEVNAME);
6670  
6671         return (1);
6672  }
6673 diff -urN linux-2.6.19.old/drivers/isdn/i4l/isdn_tty.c linux-2.6.19.dev/drivers/isdn/i4l/isdn_tty.c
6674 --- linux-2.6.19.old/drivers/isdn/i4l/isdn_tty.c        2006-11-29 22:57:37.000000000 +0100
6675 +++ linux-2.6.19.dev/drivers/isdn/i4l/isdn_tty.c        2006-12-14 03:12:59.000000000 +0100
6676 @@ -1889,13 +1889,14 @@
6677         if (!m->tty_modem)
6678                 return -ENOMEM;
6679         m->tty_modem->name = "ttyI";
6680 +       m->tty_modem->devfs_name = "isdn/ttyI";
6681         m->tty_modem->major = ISDN_TTY_MAJOR;
6682         m->tty_modem->minor_start = 0;
6683         m->tty_modem->type = TTY_DRIVER_TYPE_SERIAL;
6684         m->tty_modem->subtype = SERIAL_TYPE_NORMAL;
6685         m->tty_modem->init_termios = tty_std_termios;
6686         m->tty_modem->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
6687 -       m->tty_modem->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
6688 +       m->tty_modem->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
6689         m->tty_modem->driver_name = "isdn_tty";
6690         tty_set_operations(m->tty_modem, &modem_ops);
6691         retval = tty_register_driver(m->tty_modem);
6692 diff -urN linux-2.6.19.old/drivers/macintosh/adb.c linux-2.6.19.dev/drivers/macintosh/adb.c
6693 --- linux-2.6.19.old/drivers/macintosh/adb.c    2006-11-29 22:57:37.000000000 +0100
6694 +++ linux-2.6.19.dev/drivers/macintosh/adb.c    2006-12-14 03:12:59.000000000 +0100
6695 @@ -35,6 +35,7 @@
6696  #include <linux/spinlock.h>
6697  #include <linux/completion.h>
6698  #include <linux/device.h>
6699 +#include <linux/devfs_fs_kernel.h>
6700  
6701  #include <asm/uaccess.h>
6702  #include <asm/semaphore.h>
6703 @@ -902,6 +903,8 @@
6704                 return;
6705         }
6706  
6707 +       devfs_mk_cdev(MKDEV(ADB_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR, "adb");
6708 +
6709         adb_dev_class = class_create(THIS_MODULE, "adb");
6710         if (IS_ERR(adb_dev_class))
6711                 return;
6712 diff -urN linux-2.6.19.old/drivers/md/dm-ioctl.c linux-2.6.19.dev/drivers/md/dm-ioctl.c
6713 --- linux-2.6.19.old/drivers/md/dm-ioctl.c      2006-11-29 22:57:37.000000000 +0100
6714 +++ linux-2.6.19.dev/drivers/md/dm-ioctl.c      2006-12-14 03:12:59.000000000 +0100
6715 @@ -13,6 +13,7 @@
6716  #include <linux/init.h>
6717  #include <linux/wait.h>
6718  #include <linux/slab.h>
6719 +#include <linux/devfs_fs_kernel.h>
6720  #include <linux/dm-ioctl.h>
6721  #include <linux/hdreg.h>
6722  
6723 @@ -67,12 +68,14 @@
6724  {
6725         init_buckets(_name_buckets);
6726         init_buckets(_uuid_buckets);
6727 +       devfs_mk_dir(DM_DIR);
6728         return 0;
6729  }
6730  
6731  static void dm_hash_exit(void)
6732  {
6733         dm_hash_remove_all(0);
6734 +       devfs_remove(DM_DIR);
6735  }
6736  
6737  /*-----------------------------------------------------------------
6738 @@ -169,6 +172,25 @@
6739  }
6740  
6741  /*
6742 + * devfs stuff.
6743 + */
6744 +static int register_with_devfs(struct hash_cell *hc)
6745 +{
6746 +       struct gendisk *disk = dm_disk(hc->md);
6747 +
6748 +       devfs_mk_bdev(MKDEV(disk->major, disk->first_minor),
6749 +                     S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP,
6750 +                     DM_DIR "/%s", hc->name);
6751 +       return 0;
6752 +}
6753 +
6754 +static int unregister_with_devfs(struct hash_cell *hc)
6755 +{
6756 +       devfs_remove(DM_DIR"/%s", hc->name);
6757 +       return 0;
6758 +}
6759 +
6760 +/*
6761   * The kdev_t and uuid of a device can never change once it is
6762   * initially inserted.
6763   */
6764 @@ -204,6 +226,7 @@
6765                 }
6766                 list_add(&cell->uuid_list, _uuid_buckets + hash_str(uuid));
6767         }
6768 +       register_with_devfs(cell);
6769         dm_get(md);
6770         dm_set_mdptr(md, cell);
6771         up_write(&_hash_lock);
6772 @@ -223,6 +246,7 @@
6773         /* remove from the dev hash */
6774         list_del(&hc->uuid_list);
6775         list_del(&hc->name_list);
6776 +       unregister_with_devfs(hc);
6777         dm_set_mdptr(hc->md, NULL);
6778  
6779         table = dm_get_table(hc->md);
6780 @@ -318,11 +342,16 @@
6781         /*
6782          * rename and move the name cell.
6783          */
6784 +       unregister_with_devfs(hc);
6785 +
6786         list_del(&hc->name_list);
6787         old_name = hc->name;
6788         hc->name = new_name;
6789         list_add(&hc->name_list, _name_buckets + hash_str(new_name));
6790  
6791 +       /* rename the device node in devfs */
6792 +       register_with_devfs(hc);
6793 +
6794         /*
6795          * Wake up any dm event waiters.
6796          */
6797 @@ -1477,6 +1506,7 @@
6798  static struct miscdevice _dm_misc = {
6799         .minor          = MISC_DYNAMIC_MINOR,
6800         .name           = DM_NAME,
6801 +       .devfs_name     = "mapper/control",
6802         .fops           = &_ctl_fops
6803  };
6804  
6805 diff -urN linux-2.6.19.old/drivers/md/md.c linux-2.6.19.dev/drivers/md/md.c
6806 --- linux-2.6.19.old/drivers/md/md.c    2006-11-29 22:57:37.000000000 +0100
6807 +++ linux-2.6.19.dev/drivers/md/md.c    2006-12-14 03:12:59.000000000 +0100
6808 @@ -38,6 +38,7 @@
6809  #include <linux/raid/md.h>
6810  #include <linux/raid/bitmap.h>
6811  #include <linux/sysctl.h>
6812 +#include <linux/devfs_fs_kernel.h>
6813  #include <linux/buffer_head.h> /* for invalidate_bdev */
6814  #include <linux/suspend.h>
6815  #include <linux/poll.h>
6816 @@ -2969,10 +2970,13 @@
6817         }
6818         disk->major = MAJOR(dev);
6819         disk->first_minor = unit << shift;
6820 -       if (partitioned)
6821 +       if (partitioned) {
6822                 sprintf(disk->disk_name, "md_d%d", unit);
6823 -       else
6824 +               sprintf(disk->devfs_name, "md/d%d", unit);
6825 +       } else {
6826                 sprintf(disk->disk_name, "md%d", unit);
6827 +               sprintf(disk->devfs_name, "md/%d", unit);
6828 +       }
6829         disk->fops = &md_fops;
6830         disk->private_data = mddev;
6831         disk->queue = mddev->queue;
6832 @@ -5539,11 +5543,23 @@
6833                 unregister_blkdev(MAJOR_NR, "md");
6834                 return -1;
6835         }
6836 +       devfs_mk_dir("md");
6837         blk_register_region(MKDEV(MAJOR_NR, 0), 1UL<<MINORBITS, THIS_MODULE,
6838                             md_probe, NULL, NULL);
6839         blk_register_region(MKDEV(mdp_major, 0), 1UL<<MINORBITS, THIS_MODULE,
6840                             md_probe, NULL, NULL);
6841  
6842 +       for (minor=0; minor < MAX_MD_DEVS; ++minor)
6843 +               devfs_mk_bdev(MKDEV(MAJOR_NR, minor),
6844 +                               S_IFBLK|S_IRUSR|S_IWUSR,
6845 +                               "md/%d", minor);
6846 +
6847 +       for (minor=0; minor < MAX_MD_DEVS; ++minor)
6848 +               devfs_mk_bdev(MKDEV(mdp_major, minor<<MdpMinorShift),
6849 +                             S_IFBLK|S_IRUSR|S_IWUSR,
6850 +                             "md/mdp%d", minor);
6851 +
6852 +
6853         register_reboot_notifier(&md_notifier);
6854         raid_table_header = register_sysctl_table(raid_root_table, 1);
6855  
6856 @@ -5599,9 +5615,16 @@
6857  {
6858         mddev_t *mddev;
6859         struct list_head *tmp;
6860 +       int i;
6861  
6862         blk_unregister_region(MKDEV(MAJOR_NR,0), 1U << MINORBITS);
6863         blk_unregister_region(MKDEV(mdp_major,0), 1U << MINORBITS);
6864 +       for (i=0; i < MAX_MD_DEVS; i++)
6865 +               devfs_remove("md/%d", i);
6866 +       for (i=0; i < MAX_MD_DEVS; i++)
6867 +               devfs_remove("md/d%d", i);
6868 +
6869 +       devfs_remove("md");
6870  
6871         unregister_blkdev(MAJOR_NR,"md");
6872         unregister_blkdev(mdp_major, "mdp");
6873 diff -urN linux-2.6.19.old/drivers/media/dvb/dvb-core/dvbdev.c linux-2.6.19.dev/drivers/media/dvb/dvb-core/dvbdev.c
6874 --- linux-2.6.19.old/drivers/media/dvb/dvb-core/dvbdev.c        2006-11-29 22:57:37.000000000 +0100
6875 +++ linux-2.6.19.dev/drivers/media/dvb/dvb-core/dvbdev.c        2006-12-14 03:12:59.000000000 +0100
6876 @@ -231,6 +231,10 @@
6877  
6878         mutex_unlock(&dvbdev_register_lock);
6879  
6880 +       devfs_mk_cdev(MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
6881 +                       S_IFCHR | S_IRUSR | S_IWUSR,
6882 +                       "dvb/adapter%d/%s%d", adap->num, dnames[type], id);
6883 +
6884         class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
6885                             adap->device, "dvb%d.%s%d", adap->num, dnames[type], id);
6886  
6887 @@ -248,6 +252,9 @@
6888         if (!dvbdev)
6889                 return;
6890  
6891 +       devfs_remove("dvb/adapter%d/%s%d", dvbdev->adapter->num,
6892 +                       dnames[dvbdev->type], dvbdev->id);
6893 +
6894         class_device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num,
6895                                         dvbdev->type, dvbdev->id)));
6896  
6897 @@ -295,6 +302,7 @@
6898  
6899         printk ("DVB: registering new adapter (%s).\n", name);
6900  
6901 +       devfs_mk_dir("dvb/adapter%d", num);
6902         adap->num = num;
6903         adap->name = name;
6904         adap->module = module;
6905 @@ -311,6 +319,8 @@
6906  
6907  int dvb_unregister_adapter(struct dvb_adapter *adap)
6908  {
6909 +       devfs_remove("dvb/adapter%d", adap->num);
6910 +
6911         if (mutex_lock_interruptible(&dvbdev_register_lock))
6912                 return -ERESTARTSYS;
6913         list_del (&adap->list_head);
6914 @@ -400,6 +410,8 @@
6915                 goto error;
6916         }
6917  
6918 +       devfs_mk_dir("dvb");
6919 +
6920         dvb_class = class_create(THIS_MODULE, "dvb");
6921         if (IS_ERR(dvb_class)) {
6922                 retval = PTR_ERR(dvb_class);
6923 @@ -416,6 +428,7 @@
6924  
6925  static void __exit exit_dvbdev(void)
6926  {
6927 +       devfs_remove("dvb");
6928         class_destroy(dvb_class);
6929         cdev_del(&dvb_device_cdev);
6930         unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
6931 diff -urN linux-2.6.19.old/drivers/media/dvb/dvb-core/dvbdev.h linux-2.6.19.dev/drivers/media/dvb/dvb-core/dvbdev.h
6932 --- linux-2.6.19.old/drivers/media/dvb/dvb-core/dvbdev.h        2006-11-29 22:57:37.000000000 +0100
6933 +++ linux-2.6.19.dev/drivers/media/dvb/dvb-core/dvbdev.h        2006-12-14 03:12:59.000000000 +0100
6934 @@ -27,6 +27,7 @@
6935  #include <linux/poll.h>
6936  #include <linux/fs.h>
6937  #include <linux/list.h>
6938 +#include <linux/devfs_fs_kernel.h>
6939  #include <linux/smp_lock.h>
6940  
6941  #define DVB_MAJOR 212
6942 diff -urN linux-2.6.19.old/drivers/media/dvb/ttpci/av7110.h linux-2.6.19.dev/drivers/media/dvb/ttpci/av7110.h
6943 --- linux-2.6.19.old/drivers/media/dvb/ttpci/av7110.h   2006-11-29 22:57:37.000000000 +0100
6944 +++ linux-2.6.19.dev/drivers/media/dvb/ttpci/av7110.h   2006-12-14 03:12:59.000000000 +0100
6945 @@ -6,6 +6,10 @@
6946  #include <linux/netdevice.h>
6947  #include <linux/i2c.h>
6948  
6949 +#ifdef CONFIG_DEVFS_FS
6950 +#include <linux/devfs_fs_kernel.h>
6951 +#endif
6952 +
6953  #include <linux/dvb/video.h>
6954  #include <linux/dvb/audio.h>
6955  #include <linux/dvb/dmx.h>
6956 diff -urN linux-2.6.19.old/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c linux-2.6.19.dev/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
6957 --- linux-2.6.19.old/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c  2006-11-29 22:57:37.000000000 +0100
6958 +++ linux-2.6.19.dev/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c  2006-12-14 03:12:59.000000000 +0100
6959 @@ -126,6 +126,10 @@
6960  
6961         int revision;
6962  
6963 +#if 0
6964 +       devfs_handle_t stc_devfs_handle;
6965 +#endif
6966 +
6967         struct dvb_frontend* fe;
6968  };
6969  
6970 @@ -1741,6 +1745,13 @@
6971                 return -ENODEV;
6972         }
6973  
6974 +#if 0
6975 +       ttusb->stc_devfs_handle =
6976 +           devfs_register(ttusb->adapter->devfs_handle, TTUSB_BUDGET_NAME,
6977 +                          DEVFS_FL_DEFAULT, 0, 192,
6978 +                          S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
6979 +                          | S_IROTH | S_IWOTH, &stc_fops, ttusb);
6980 +#endif
6981         usb_set_intfdata(intf, (void *) ttusb);
6982  
6983         frontend_init(ttusb);
6984 diff -urN linux-2.6.19.old/drivers/media/radio/miropcm20-rds.c linux-2.6.19.dev/drivers/media/radio/miropcm20-rds.c
6985 --- linux-2.6.19.old/drivers/media/radio/miropcm20-rds.c        2006-11-29 22:57:37.000000000 +0100
6986 +++ linux-2.6.19.dev/drivers/media/radio/miropcm20-rds.c        2006-12-14 03:12:59.000000000 +0100
6987 @@ -115,6 +115,7 @@
6988  static struct miscdevice rds_miscdev = {
6989         .minor          = MISC_DYNAMIC_MINOR,
6990         .name           = "radiotext",
6991 +       .devfs_name     = "v4l/rds/radiotext",
6992         .fops           = &rds_fops,
6993  };
6994  
6995 diff -urN linux-2.6.19.old/drivers/media/video/arv.c linux-2.6.19.dev/drivers/media/video/arv.c
6996 --- linux-2.6.19.old/drivers/media/video/arv.c  2006-11-29 22:57:37.000000000 +0100
6997 +++ linux-2.6.19.dev/drivers/media/video/arv.c  2006-12-14 03:12:59.000000000 +0100
6998 @@ -19,6 +19,7 @@
6999   */
7000  
7001  #include <linux/init.h>
7002 +#include <linux/devfs_fs_kernel.h>
7003  #include <linux/module.h>
7004  #include <linux/delay.h>
7005  #include <linux/errno.h>
7006 diff -urN linux-2.6.19.old/drivers/media/video/videodev.c linux-2.6.19.dev/drivers/media/video/videodev.c
7007 --- linux-2.6.19.old/drivers/media/video/videodev.c     2006-11-29 22:57:37.000000000 +0100
7008 +++ linux-2.6.19.dev/drivers/media/video/videodev.c     2006-12-14 03:12:59.000000000 +0100
7009 @@ -38,6 +38,7 @@
7010  #include <linux/init.h>
7011  #include <linux/kmod.h>
7012  #include <linux/slab.h>
7013 +#include <linux/devfs_fs_kernel.h>
7014  #include <asm/uaccess.h>
7015  #include <asm/system.h>
7016  
7017 @@ -1593,6 +1594,10 @@
7018         video_device[i]=vfd;
7019         vfd->minor=i;
7020         mutex_unlock(&videodev_lock);
7021 +
7022 +       sprintf(vfd->devfs_name, "v4l/%s%d", name_base, i - base);
7023 +       devfs_mk_cdev(MKDEV(VIDEO_MAJOR, vfd->minor),
7024 +                       S_IFCHR | S_IRUSR | S_IWUSR, vfd->devfs_name);
7025         mutex_init(&vfd->lock);
7026  
7027         /* sysfs class */
7028 @@ -1602,6 +1607,7 @@
7029         vfd->class_dev.class       = &video_class;
7030         vfd->class_dev.devt        = MKDEV(VIDEO_MAJOR, vfd->minor);
7031         sprintf(vfd->class_dev.class_id, "%s%d", name_base, i - base);
7032 +       strlcpy(vfd->class_dev.class_id, vfd->devfs_name + 4, BUS_ID_SIZE);
7033         ret = class_device_register(&vfd->class_dev);
7034         if (ret < 0) {
7035                 printk(KERN_ERR "%s: class_device_register failed\n",
7036 @@ -1648,6 +1654,7 @@
7037         if(video_device[vfd->minor]!=vfd)
7038                 panic("videodev: bad unregister");
7039  
7040 +       devfs_remove(vfd->devfs_name);
7041         video_device[vfd->minor]=NULL;
7042         class_device_unregister(&vfd->class_dev);
7043         mutex_unlock(&videodev_lock);
7044 diff -urN linux-2.6.19.old/drivers/message/i2o/i2o_block.c linux-2.6.19.dev/drivers/message/i2o/i2o_block.c
7045 --- linux-2.6.19.old/drivers/message/i2o/i2o_block.c    2006-11-29 22:57:37.000000000 +0100
7046 +++ linux-2.6.19.dev/drivers/message/i2o/i2o_block.c    2006-12-14 03:12:59.000000000 +0100
7047 @@ -1090,6 +1090,7 @@
7048         gd = i2o_blk_dev->gd;
7049         gd->first_minor = unit << 4;
7050         sprintf(gd->disk_name, "i2o/hd%c", 'a' + unit);
7051 +       sprintf(gd->devfs_name, "i2o/hd%c", 'a' + unit);
7052         gd->driverfs_dev = &i2o_dev->device;
7053  
7054         /* setup request queue */
7055 diff -urN linux-2.6.19.old/drivers/mmc/mmc_block.c linux-2.6.19.dev/drivers/mmc/mmc_block.c
7056 --- linux-2.6.19.old/drivers/mmc/mmc_block.c    2006-11-29 22:57:37.000000000 +0100
7057 +++ linux-2.6.19.dev/drivers/mmc/mmc_block.c    2006-12-14 03:12:59.000000000 +0100
7058 @@ -27,6 +27,7 @@
7059  #include <linux/hdreg.h>
7060  #include <linux/kdev_t.h>
7061  #include <linux/blkdev.h>
7062 +#include <linux/devfs_fs_kernel.h>
7063  #include <linux/mutex.h>
7064  #include <linux/scatterlist.h>
7065  
7066 @@ -472,6 +473,7 @@
7067          */
7068  
7069         sprintf(md->disk->disk_name, "mmcblk%d", devidx);
7070 +       sprintf(md->disk->devfs_name, "mmc/blk%d", devidx);
7071  
7072         blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits);
7073  
7074 @@ -617,6 +619,7 @@
7075         if (major == 0)
7076                 major = res;
7077  
7078 +       devfs_mk_dir("mmc");
7079         return mmc_register_driver(&mmc_driver);
7080  
7081   out:
7082 @@ -626,6 +629,7 @@
7083  static void __exit mmc_blk_exit(void)
7084  {
7085         mmc_unregister_driver(&mmc_driver);
7086 +       devfs_remove("mmc");
7087         unregister_blkdev(major, "mmc");
7088  }
7089  
7090 diff -urN linux-2.6.19.old/drivers/mtd/mtd_blkdevs.c linux-2.6.19.dev/drivers/mtd/mtd_blkdevs.c
7091 --- linux-2.6.19.old/drivers/mtd/mtd_blkdevs.c  2006-11-29 22:57:37.000000000 +0100
7092 +++ linux-2.6.19.dev/drivers/mtd/mtd_blkdevs.c  2006-12-14 03:12:59.000000000 +0100
7093 @@ -21,6 +21,9 @@
7094  #include <linux/init.h>
7095  #include <linux/mutex.h>
7096  #include <asm/uaccess.h>
7097 +#ifdef CONFIG_DEVFS_FS
7098 +#include <linux/devfs_fs_kernel.h>
7099 +#endif
7100  
7101  static LIST_HEAD(blktrans_majors);
7102  
7103 @@ -295,6 +298,11 @@
7104                 snprintf(gd->disk_name, sizeof(gd->disk_name),
7105                          "%s%d", tr->name, new->devnum);
7106  
7107 +#ifdef CONFIG_DEVFS_FS
7108 +               snprintf(gd->devfs_name, sizeof(gd->devfs_name),
7109 +                        "%s/%c", tr->name, (tr->part_bits?'a':'0') + new->devnum);
7110 +#endif
7111 +
7112         /* 2.5 has capacity in units of 512 bytes while still
7113            having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */
7114         set_capacity(gd, (new->size * new->blksize) >> 9);
7115 @@ -411,6 +419,10 @@
7116                 return ret;
7117         }
7118  
7119 +#ifdef CONFIG_DEVFS_FS
7120 +       devfs_mk_dir(tr->name);
7121 +#endif
7122 +
7123         INIT_LIST_HEAD(&tr->devs);
7124         list_add(&tr->list, &blktrans_majors);
7125  
7126 @@ -443,6 +455,10 @@
7127                 tr->remove_dev(dev);
7128         }
7129  
7130 +#ifdef CONFIG_DEVFS_FS
7131 +       devfs_remove(tr->name);
7132 +#endif
7133 +
7134         blk_cleanup_queue(tr->blkcore_priv->rq);
7135         unregister_blkdev(tr->major, tr->name);
7136  
7137 diff -urN linux-2.6.19.old/drivers/mtd/mtdchar.c linux-2.6.19.dev/drivers/mtd/mtdchar.c
7138 --- linux-2.6.19.old/drivers/mtd/mtdchar.c      2006-11-29 22:57:37.000000000 +0100
7139 +++ linux-2.6.19.dev/drivers/mtd/mtdchar.c      2006-12-14 03:12:59.000000000 +0100
7140 @@ -18,19 +18,33 @@
7141  
7142  #include <asm/uaccess.h>
7143  
7144 +#ifdef CONFIG_DEVFS_FS
7145 +#include <linux/devfs_fs_kernel.h>
7146 +#else
7147 +#include <linux/device.h>
7148 +
7149  static struct class *mtd_class;
7150 +#endif
7151  
7152  static void mtd_notify_add(struct mtd_info* mtd)
7153  {
7154         if (!mtd)
7155                 return;
7156  
7157 +#ifdef CONFIG_DEVFS_FS
7158 +       devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
7159 +                       S_IFCHR | S_IRUGO | S_IWUGO, "mtd/%d", mtd->index);
7160 +
7161 +       devfs_mk_cdev(MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
7162 +                       S_IFCHR | S_IRUGO, "mtd/%dro", mtd->index);
7163 +#else
7164         class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
7165                             NULL, "mtd%d", mtd->index);
7166  
7167         class_device_create(mtd_class, NULL,
7168                             MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
7169                             NULL, "mtd%dro", mtd->index);
7170 +#endif
7171  }
7172  
7173  static void mtd_notify_remove(struct mtd_info* mtd)
7174 @@ -38,8 +52,13 @@
7175         if (!mtd)
7176                 return;
7177  
7178 +#ifdef CONFIG_DEVFS_FS
7179 +       devfs_remove("mtd/%d", mtd->index);
7180 +       devfs_remove("mtd/%dro", mtd->index);
7181 +#else
7182         class_device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2));
7183         class_device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1));
7184 +#endif
7185  }
7186  
7187  static struct mtd_notifier notifier = {
7188 @@ -47,6 +66,22 @@
7189         .remove = mtd_notify_remove,
7190  };
7191  
7192 +#ifdef CONFIG_DEVFS_FS
7193 +       static inline void mtdchar_devfs_init(void)
7194 +       {
7195 +               devfs_mk_dir("mtd");
7196 +               register_mtd_user(&notifier);
7197 +       }
7198 +       static inline void mtdchar_devfs_exit(void)
7199 +       {
7200 +               unregister_mtd_user(&notifier);
7201 +               devfs_remove("mtd");
7202 +       }
7203 +       #else /* !DEVFS */
7204 +       #define mtdchar_devfs_init() do { } while(0)
7205 +       #define mtdchar_devfs_exit() do { } while(0)
7206 +#endif
7207 +
7208  /*
7209   * Data structure to hold the pointer to the mtd device as well
7210   * as mode information ofr various use cases.
7211 @@ -778,6 +813,9 @@
7212                 return -EAGAIN;
7213         }
7214  
7215 +#ifdef CONFIG_DEVFS_FS
7216 +       mtdchar_devfs_init();
7217 +#else
7218         mtd_class = class_create(THIS_MODULE, "mtd");
7219  
7220         if (IS_ERR(mtd_class)) {
7221 @@ -787,13 +825,19 @@
7222         }
7223  
7224         register_mtd_user(&notifier);
7225 +#endif
7226         return 0;
7227  }
7228  
7229  static void __exit cleanup_mtdchar(void)
7230  {
7231 +
7232 +#ifdef CONFIG_DEVFS_FS
7233 +       mtdchar_devfs_exit();
7234 +#else
7235         unregister_mtd_user(&notifier);
7236         class_destroy(mtd_class);
7237 +#endif
7238         unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
7239  }
7240  
7241 diff -urN linux-2.6.19.old/drivers/net/ppp_generic.c linux-2.6.19.dev/drivers/net/ppp_generic.c
7242 --- linux-2.6.19.old/drivers/net/ppp_generic.c  2006-11-29 22:57:37.000000000 +0100
7243 +++ linux-2.6.19.dev/drivers/net/ppp_generic.c  2006-12-14 03:12:59.000000000 +0100
7244 @@ -27,6 +27,7 @@
7245  #include <linux/kmod.h>
7246  #include <linux/init.h>
7247  #include <linux/list.h>
7248 +#include <linux/devfs_fs_kernel.h>
7249  #include <linux/netdevice.h>
7250  #include <linux/poll.h>
7251  #include <linux/ppp_defs.h>
7252 @@ -861,6 +862,10 @@
7253                         goto out_chrdev;
7254                 }
7255                 class_device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
7256 +               err = devfs_mk_cdev(MKDEV(PPP_MAJOR, 0),
7257 +                               S_IFCHR|S_IRUSR|S_IWUSR, "ppp");
7258 +               if (err)
7259 +                       goto out_chrdev;
7260         }
7261  
7262  out:
7263 @@ -2675,6 +2680,7 @@
7264         cardmap_destroy(&all_ppp_units);
7265         if (unregister_chrdev(PPP_MAJOR, "ppp") != 0)
7266                 printk(KERN_ERR "PPP: failed to unregister PPP device\n");
7267 +       devfs_remove("ppp");
7268         class_device_destroy(ppp_class, MKDEV(PPP_MAJOR, 0));
7269         class_destroy(ppp_class);
7270  }
7271 diff -urN linux-2.6.19.old/drivers/net/tun.c linux-2.6.19.dev/drivers/net/tun.c
7272 --- linux-2.6.19.old/drivers/net/tun.c  2006-11-29 22:57:37.000000000 +0100
7273 +++ linux-2.6.19.dev/drivers/net/tun.c  2006-12-14 03:12:59.000000000 +0100
7274 @@ -762,6 +762,7 @@
7275         .minor = TUN_MINOR,
7276         .name = "tun",
7277         .fops = &tun_fops,
7278 +       .devfs_name = "net/tun",
7279  };
7280  
7281  /* ethtool interface */
7282 diff -urN linux-2.6.19.old/drivers/net/wan/cosa.c linux-2.6.19.dev/drivers/net/wan/cosa.c
7283 --- linux-2.6.19.old/drivers/net/wan/cosa.c     2006-11-29 22:57:37.000000000 +0100
7284 +++ linux-2.6.19.dev/drivers/net/wan/cosa.c     2006-12-14 03:12:59.000000000 +0100
7285 @@ -84,6 +84,7 @@
7286  #include <linux/slab.h>
7287  #include <linux/poll.h>
7288  #include <linux/fs.h>
7289 +#include <linux/devfs_fs_kernel.h>
7290  #include <linux/interrupt.h>
7291  #include <linux/delay.h>
7292  #include <linux/errno.h>
7293 @@ -391,6 +392,7 @@
7294                 err = -ENODEV;
7295                 goto out;
7296         }
7297 +       devfs_mk_dir("cosa");
7298         cosa_class = class_create(THIS_MODULE, "cosa");
7299         if (IS_ERR(cosa_class)) {
7300                 err = PTR_ERR(cosa_class);
7301 @@ -399,6 +401,13 @@
7302         for (i=0; i<nr_cards; i++) {
7303                 class_device_create(cosa_class, NULL, MKDEV(cosa_major, i),
7304                                 NULL, "cosa%d", i);
7305 +               err = devfs_mk_cdev(MKDEV(cosa_major, i),
7306 +                               S_IFCHR|S_IRUSR|S_IWUSR,
7307 +                               "cosa/%d", i);
7308 +               if (err) {
7309 +                       class_device_destroy(cosa_class, MKDEV(cosa_major, i));
7310 +                       goto out_chrdev;                
7311 +               }
7312         }
7313         err = 0;
7314         goto out;
7315 @@ -416,9 +425,12 @@
7316         int i;
7317         printk(KERN_INFO "Unloading the cosa module\n");
7318  
7319 -       for (i=0; i<nr_cards; i++)
7320 +       for (i=0; i<nr_cards; i++) {
7321                 class_device_destroy(cosa_class, MKDEV(cosa_major, i));
7322 +               devfs_remove("cosa/%d", i);
7323 +       }
7324         class_destroy(cosa_class);
7325 +       devfs_remove("cosa");
7326         for (cosa=cosa_cards; nr_cards--; cosa++) {
7327                 /* Clean up the per-channel data */
7328                 for (i=0; i<cosa->nchannels; i++) {
7329 diff -urN linux-2.6.19.old/drivers/s390/block/dasd.c linux-2.6.19.dev/drivers/s390/block/dasd.c
7330 --- linux-2.6.19.old/drivers/s390/block/dasd.c  2006-11-29 22:57:37.000000000 +0100
7331 +++ linux-2.6.19.dev/drivers/s390/block/dasd.c  2006-12-14 03:12:59.000000000 +0100
7332 @@ -1903,6 +1903,7 @@
7333         }
7334         dasd_gendisk_exit();
7335         dasd_devmap_exit();
7336 +       devfs_remove("dasd");
7337         if (dasd_debug_area != NULL) {
7338                 debug_unregister(dasd_debug_area);
7339                 dasd_debug_area = NULL;
7340 @@ -2176,6 +2177,9 @@
7341  
7342         dasd_diag_discipline_pointer = NULL;
7343  
7344 +       rc = devfs_mk_dir("dasd");
7345 +       if (rc)
7346 +               goto failed;
7347         rc = dasd_devmap_init();
7348         if (rc)
7349                 goto failed;
7350 diff -urN linux-2.6.19.old/drivers/s390/block/dasd_genhd.c linux-2.6.19.dev/drivers/s390/block/dasd_genhd.c
7351 --- linux-2.6.19.old/drivers/s390/block/dasd_genhd.c    2006-11-29 22:57:37.000000000 +0100
7352 +++ linux-2.6.19.dev/drivers/s390/block/dasd_genhd.c    2006-12-14 03:12:59.000000000 +0100
7353 @@ -67,6 +67,8 @@
7354         }
7355         len += sprintf(gdp->disk_name + len, "%c", 'a'+(device->devindex%26));
7356  
7357 +       sprintf(gdp->devfs_name, "dasd/%s", device->cdev->dev.bus_id);
7358 +
7359         if (device->features & DASD_FEATURE_READONLY)
7360                 set_disk_ro(gdp, 1);
7361         gdp->private_data = device;
7362 diff -urN linux-2.6.19.old/drivers/s390/block/dasd_int.h linux-2.6.19.dev/drivers/s390/block/dasd_int.h
7363 --- linux-2.6.19.old/drivers/s390/block/dasd_int.h      2006-11-29 22:57:37.000000000 +0100
7364 +++ linux-2.6.19.dev/drivers/s390/block/dasd_int.h      2006-12-14 03:12:59.000000000 +0100
7365 @@ -54,6 +54,7 @@
7366  #include <linux/module.h>
7367  #include <linux/wait.h>
7368  #include <linux/blkdev.h>
7369 +#include <linux/devfs_fs_kernel.h>
7370  #include <linux/genhd.h>
7371  #include <linux/hdreg.h>
7372  #include <linux/interrupt.h>
7373 diff -urN linux-2.6.19.old/drivers/s390/block/xpram.c linux-2.6.19.dev/drivers/s390/block/xpram.c
7374 --- linux-2.6.19.old/drivers/s390/block/xpram.c 2006-11-29 22:57:37.000000000 +0100
7375 +++ linux-2.6.19.dev/drivers/s390/block/xpram.c 2006-12-14 03:12:59.000000000 +0100
7376 @@ -36,6 +36,7 @@
7377  #include <linux/hdreg.h>  /* HDIO_GETGEO */
7378  #include <linux/sysdev.h>
7379  #include <linux/bio.h>
7380 +#include <linux/devfs_fs_kernel.h>
7381  #include <asm/uaccess.h>
7382  
7383  #define XPRAM_NAME     "xpram"
7384 @@ -363,6 +364,8 @@
7385         if (rc < 0)
7386                 goto out;
7387  
7388 +       devfs_mk_dir("slram");
7389 +
7390         /*
7391          * Assign the other needed values: make request function, sizes and
7392          * hardsect size. All the minor devices feature the same value.
7393 @@ -391,12 +394,14 @@
7394                 disk->private_data = &xpram_devices[i];
7395                 disk->queue = xpram_queue;
7396                 sprintf(disk->disk_name, "slram%d", i);
7397 +               sprintf(disk->devfs_name, "slram/%d", i);
7398                 set_capacity(disk, xpram_sizes[i] << 1);
7399                 add_disk(disk);
7400         }
7401  
7402         return 0;
7403  out_unreg:
7404 +       devfs_remove("slram");
7405         unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
7406  out:
7407         while (i--)
7408 @@ -415,7 +420,10 @@
7409                 put_disk(xpram_disks[i]);
7410         }
7411         unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
7412 +       devfs_remove("slram");
7413         blk_cleanup_queue(xpram_queue);
7414 +       sysdev_unregister(&xpram_sys_device);
7415 +       sysdev_class_unregister(&xpram_sysclass);
7416  }
7417  
7418  static int __init xpram_init(void)
7419 diff -urN linux-2.6.19.old/drivers/s390/char/monreader.c linux-2.6.19.dev/drivers/s390/char/monreader.c
7420 --- linux-2.6.19.old/drivers/s390/char/monreader.c      2006-11-29 22:57:37.000000000 +0100
7421 +++ linux-2.6.19.dev/drivers/s390/char/monreader.c      2006-12-14 03:12:59.000000000 +0100
7422 @@ -586,6 +586,7 @@
7423  
7424  static struct miscdevice mon_dev = {
7425         .name       = "monreader",
7426 +       .devfs_name = "monreader",
7427         .fops       = &mon_fops,
7428         .minor      = MISC_DYNAMIC_MINOR,
7429  };
7430 diff -urN linux-2.6.19.old/drivers/s390/char/tty3270.c linux-2.6.19.dev/drivers/s390/char/tty3270.c
7431 --- linux-2.6.19.old/drivers/s390/char/tty3270.c        2006-11-29 22:57:37.000000000 +0100
7432 +++ linux-2.6.19.dev/drivers/s390/char/tty3270.c        2006-12-14 03:12:59.000000000 +0100
7433 @@ -1783,6 +1783,7 @@
7434          * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc
7435          */
7436         driver->owner = THIS_MODULE;
7437 +       driver->devfs_name = "ttyTUB/";
7438         driver->driver_name = "ttyTUB";
7439         driver->name = "ttyTUB";
7440         driver->major = IBM_TTY3270_MAJOR;
7441 @@ -1790,7 +1791,7 @@
7442         driver->type = TTY_DRIVER_TYPE_SYSTEM;
7443         driver->subtype = SYSTEM_TYPE_TTY;
7444         driver->init_termios = tty_std_termios;
7445 -       driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_DYNAMIC_DEV;
7446 +       driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_NO_DEVFS;
7447         tty_set_operations(driver, &tty3270_ops);
7448         ret = tty_register_driver(driver);
7449         if (ret) {
7450 diff -urN linux-2.6.19.old/drivers/sbus/char/bpp.c linux-2.6.19.dev/drivers/sbus/char/bpp.c
7451 --- linux-2.6.19.old/drivers/sbus/char/bpp.c    2006-11-29 22:57:37.000000000 +0100
7452 +++ linux-2.6.19.dev/drivers/sbus/char/bpp.c    2006-12-14 03:12:59.000000000 +0100
7453 @@ -20,6 +20,7 @@
7454  #include <linux/timer.h>
7455  #include <linux/ioport.h>
7456  #include <linux/major.h>
7457 +#include <linux/devfs_fs_kernel.h>
7458  
7459  #include <asm/uaccess.h>
7460  #include <asm/io.h>
7461 @@ -1030,6 +1031,11 @@
7462                 instances[idx].opened = 0;
7463                 probeLptPort(idx);
7464         }
7465 +       devfs_mk_dir("bpp");
7466 +       for (idx = 0; idx < BPP_NO; idx++) {
7467 +               devfs_mk_cdev(MKDEV(BPP_MAJOR, idx),
7468 +                               S_IFCHR | S_IRUSR | S_IWUSR, "bpp/%d", idx);
7469 +       }
7470  
7471         return 0;
7472  }
7473 @@ -1038,6 +1044,9 @@
7474  {
7475         unsigned idx;
7476  
7477 +       for (idx = 0; idx < BPP_NO; idx++)
7478 +               devfs_remove("bpp/%d", idx);
7479 +       devfs_remove("bpp");
7480         unregister_chrdev(BPP_MAJOR, dev_name);
7481  
7482         for (idx = 0;  idx < BPP_NO; idx++) {
7483 diff -urN linux-2.6.19.old/drivers/sbus/char/vfc_dev.c linux-2.6.19.dev/drivers/sbus/char/vfc_dev.c
7484 --- linux-2.6.19.old/drivers/sbus/char/vfc_dev.c        2006-11-29 22:57:37.000000000 +0100
7485 +++ linux-2.6.19.dev/drivers/sbus/char/vfc_dev.c        2006-12-14 03:12:59.000000000 +0100
7486 @@ -164,6 +164,10 @@
7487                 return -EINVAL;
7488         if (init_vfc_hw(dev))
7489                 return -EIO;
7490 +
7491 +       devfs_mk_cdev(MKDEV(VFC_MAJOR, instance),
7492 +                       S_IFCHR | S_IRUSR | S_IWUSR,
7493 +                       "vfc/%d", instance);
7494         return 0;
7495  }
7496  
7497 @@ -673,6 +677,7 @@
7498                 kfree(vfc_dev_lst);
7499                 return -EIO;
7500         }
7501 +       devfs_mk_dir("vfc");
7502         instance = 0;
7503         for_all_sbusdev(sdev, sbus) {
7504                 if (strcmp(sdev->prom_name, "vfc") == 0) {
7505 @@ -712,6 +717,7 @@
7506  {
7507         if(dev == NULL)
7508                 return;
7509 +       devfs_remove("vfc/%d", dev->instance);
7510         sbus_iounmap(dev->regs, sizeof(struct vfc_regs));
7511         kfree(dev);
7512  }
7513 @@ -725,6 +731,7 @@
7514         for (devp = vfc_dev_lst; *devp; devp++)
7515                 deinit_vfc_device(*devp);
7516  
7517 +       devfs_remove("vfc");
7518         kfree(vfc_dev_lst);
7519         return;
7520  }
7521 diff -urN linux-2.6.19.old/drivers/sbus/char/vfc.h linux-2.6.19.dev/drivers/sbus/char/vfc.h
7522 --- linux-2.6.19.old/drivers/sbus/char/vfc.h    2006-11-29 22:57:37.000000000 +0100
7523 +++ linux-2.6.19.dev/drivers/sbus/char/vfc.h    2006-12-14 03:12:59.000000000 +0100
7524 @@ -1,6 +1,8 @@
7525  #ifndef _LINUX_VFC_H_
7526  #define _LINUX_VFC_H_
7527  
7528 +#include <linux/devfs_fs_kernel.h>
7529 +
7530  /*
7531   * The control register for the vfc is at offset 0x4000
7532   * The first field ram bank is located at offset 0x5000
7533 diff -urN linux-2.6.19.old/drivers/scsi/osst.c linux-2.6.19.dev/drivers/scsi/osst.c
7534 --- linux-2.6.19.old/drivers/scsi/osst.c        2006-11-29 22:57:37.000000000 +0100
7535 +++ linux-2.6.19.dev/drivers/scsi/osst.c        2006-12-14 03:12:59.000000000 +0100
7536 @@ -48,6 +48,7 @@
7537  #include <linux/vmalloc.h>
7538  #include <linux/blkdev.h>
7539  #include <linux/moduleparam.h>
7540 +#include <linux/devfs_fs_kernel.h>
7541  #include <linux/delay.h>
7542  #include <linux/jiffies.h>
7543  #include <asm/uaccess.h>
7544 @@ -5859,6 +5860,18 @@
7545                 STps->drv_block = (-1);
7546                 STps->drv_file = (-1);
7547         }
7548 +       for (mode = 0; mode < ST_NBR_MODES; ++mode) {
7549 +               /*  Rewind entry  */
7550 +               devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5)),
7551 +                               S_IFCHR | S_IRUGO | S_IWUGO,
7552 +                               "%s/ot%s", SDp->devfs_name, osst_formats[mode]);
7553 +
7554 +               /*  No-rewind entry  */
7555 +               devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5) + 128),
7556 +                               S_IFCHR | S_IRUGO | S_IWUGO,
7557 +                               "%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
7558 +       }
7559 +       drive->number = devfs_register_tape(SDp->devfs_name);
7560  
7561         tpnt->current_mode = 0;
7562         tpnt->modes[0].defined = 1;
7563 @@ -5914,6 +5927,11 @@
7564                         osst_sysfs_destroy(MKDEV(OSST_MAJOR, i));
7565                         osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128));
7566                         tpnt->device = NULL;
7567 +                       for (mode = 0; mode < ST_NBR_MODES; ++mode) {
7568 +                               devfs_remove("%s/ot%s", SDp->devfs_name, osst_formats[mode]);
7569 +                               devfs_remove("%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
7570 +                       }
7571 +                       devfs_unregister_tape(tpnt->drive->number);
7572                         put_disk(tpnt->drive);
7573                         os_scsi_tapes[i] = NULL;
7574                         osst_nr_dev--;
7575 diff -urN linux-2.6.19.old/drivers/scsi/scsi.c linux-2.6.19.dev/drivers/scsi/scsi.c
7576 --- linux-2.6.19.old/drivers/scsi/scsi.c        2006-11-29 22:57:37.000000000 +0100
7577 +++ linux-2.6.19.dev/drivers/scsi/scsi.c        2006-12-14 03:12:59.000000000 +0100
7578 @@ -48,6 +48,7 @@
7579  #include <linux/delay.h>
7580  #include <linux/init.h>
7581  #include <linux/completion.h>
7582 +#include <linux/devfs_fs_kernel.h>
7583  #include <linux/unistd.h>
7584  #include <linux/spinlock.h>
7585  #include <linux/kmod.h>
7586 @@ -1119,6 +1120,7 @@
7587  
7588         scsi_netlink_init();
7589  
7590 +       devfs_mk_dir("scsi");
7591         printk(KERN_NOTICE "SCSI subsystem initialized\n");
7592         return 0;
7593  
7594 @@ -1144,6 +1146,7 @@
7595         scsi_exit_sysctl();
7596         scsi_exit_hosts();
7597         scsi_exit_devinfo();
7598 +       devfs_remove("scsi");
7599         scsi_exit_procfs();
7600         scsi_exit_queue();
7601  }
7602 diff -urN linux-2.6.19.old/drivers/scsi/scsi_scan.c linux-2.6.19.dev/drivers/scsi/scsi_scan.c
7603 --- linux-2.6.19.old/drivers/scsi/scsi_scan.c   2006-11-29 22:57:37.000000000 +0100
7604 +++ linux-2.6.19.dev/drivers/scsi/scsi_scan.c   2006-12-14 03:12:59.000000000 +0100
7605 @@ -719,8 +719,12 @@
7606                         sdev->inq_periph_qual, inq_result[2] & 0x07,
7607                         (inq_result[3] & 0x0f) == 1 ? " CCS" : "");
7608  
7609 +       sprintf(sdev->devfs_name, "scsi/host%d/bus%d/target%d/lun%d",
7610 +                               sdev->host->host_no, sdev->channel,
7611 +                               sdev->id, sdev->lun);
7612 +
7613         /*
7614 -        * End sysfs code.
7615 +        * End driverfs/devfs code.
7616          */
7617  
7618         if ((sdev->scsi_level >= SCSI_2) && (inq_result[7] & 2) &&
7619 diff -urN linux-2.6.19.old/drivers/scsi/sd.c linux-2.6.19.dev/drivers/scsi/sd.c
7620 --- linux-2.6.19.old/drivers/scsi/sd.c  2006-11-29 22:57:37.000000000 +0100
7621 +++ linux-2.6.19.dev/drivers/scsi/sd.c  2006-12-14 03:12:59.000000000 +0100
7622 @@ -1687,6 +1687,8 @@
7623                         'a' + m1, 'a' + m2, 'a' + m3);
7624         }
7625  
7626 +       strcpy(gd->devfs_name, sdp->devfs_name);
7627 +
7628         gd->private_data = &sdkp->driver;
7629         gd->queue = sdkp->device->request_queue;
7630  
7631 diff -urN linux-2.6.19.old/drivers/scsi/sg.c linux-2.6.19.dev/drivers/scsi/sg.c
7632 --- linux-2.6.19.old/drivers/scsi/sg.c  2006-11-29 22:57:37.000000000 +0100
7633 +++ linux-2.6.19.dev/drivers/scsi/sg.c  2006-12-14 03:12:59.000000000 +0100
7634 @@ -43,6 +43,7 @@
7635  #include <linux/poll.h>
7636  #include <linux/smp_lock.h>
7637  #include <linux/moduleparam.h>
7638 +#include <linux/devfs_fs_kernel.h>
7639  #include <linux/cdev.h>
7640  #include <linux/seq_file.h>
7641  #include <linux/blkdev.h>
7642 @@ -1530,6 +1531,7 @@
7643                 class_device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, k));
7644                 cdev_del(sdp->cdev);
7645                 sdp->cdev = NULL;
7646 +               devfs_remove("%s/generic", scsidp->devfs_name);
7647                 put_disk(sdp->disk);
7648                 sdp->disk = NULL;
7649                 if (NULL == sdp->headfp)
7650 diff -urN linux-2.6.19.old/drivers/scsi/sr.c linux-2.6.19.dev/drivers/scsi/sr.c
7651 --- linux-2.6.19.old/drivers/scsi/sr.c  2006-11-29 22:57:37.000000000 +0100
7652 +++ linux-2.6.19.dev/drivers/scsi/sr.c  2006-12-14 03:12:59.000000000 +0100
7653 @@ -591,6 +591,8 @@
7654         get_capabilities(cd);
7655         sr_vendor_init(cd);
7656  
7657 +       snprintf(disk->devfs_name, sizeof(disk->devfs_name),
7658 +                       "%s/cd", sdev->devfs_name);
7659         disk->driverfs_dev = &sdev->sdev_gendev;
7660         set_capacity(disk, cd->capacity);
7661         disk->private_data = &cd->driver;
7662 diff -urN linux-2.6.19.old/drivers/scsi/st.c linux-2.6.19.dev/drivers/scsi/st.c
7663 --- linux-2.6.19.old/drivers/scsi/st.c  2006-11-29 22:57:37.000000000 +0100
7664 +++ linux-2.6.19.dev/drivers/scsi/st.c  2006-12-14 03:12:59.000000000 +0100
7665 @@ -35,6 +35,7 @@
7666  #include <linux/spinlock.h>
7667  #include <linux/blkdev.h>
7668  #include <linux/moduleparam.h>
7669 +#include <linux/devfs_fs_kernel.h>
7670  #include <linux/cdev.h>
7671  #include <linux/delay.h>
7672  #include <linux/mutex.h>
7673 @@ -4056,6 +4057,21 @@
7674                         goto out_free_tape;
7675         }
7676  
7677 +       for (mode = 0; mode < ST_NBR_MODES; ++mode) {
7678 +               /* Make sure that the minor numbers corresponding to the four
7679 +                  first modes always get the same names */
7680 +               i = mode << (4 - ST_NBR_MODE_BITS);
7681 +               /*  Rewind entry  */
7682 +               devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, 0)),
7683 +                             S_IFCHR | S_IRUGO | S_IWUGO,
7684 +                             "%s/mt%s", SDp->devfs_name, st_formats[i]);
7685 +               /*  No-rewind entry  */
7686 +               devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, 1)),
7687 +                             S_IFCHR | S_IRUGO | S_IWUGO,
7688 +                             "%s/mt%sn", SDp->devfs_name, st_formats[i]);
7689 +       }
7690 +       disk->number = devfs_register_tape(SDp->devfs_name);
7691 +
7692         sdev_printk(KERN_WARNING, SDp,
7693                     "Attached scsi tape %s\n", tape_name(tpnt));
7694         printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n",
7695 @@ -4109,9 +4125,13 @@
7696                         scsi_tapes[i] = NULL;
7697                         st_nr_dev--;
7698                         write_unlock(&st_dev_arr_lock);
7699 +                       devfs_unregister_tape(tpnt->disk->number);
7700                         sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
7701                                           "tape");
7702                         for (mode = 0; mode < ST_NBR_MODES; ++mode) {
7703 +                               j = mode << (4 - ST_NBR_MODE_BITS);
7704 +                               devfs_remove("%s/mt%s", SDp->devfs_name, st_formats[j]);
7705 +                               devfs_remove("%s/mt%sn", SDp->devfs_name, st_formats[j]);
7706                                 for (j=0; j < 2; j++) {
7707                                         class_device_destroy(st_sysfs_class,
7708                                                              MKDEV(SCSI_TAPE_MAJOR,
7709 diff -urN linux-2.6.19.old/drivers/serial/21285.c linux-2.6.19.dev/drivers/serial/21285.c
7710 --- linux-2.6.19.old/drivers/serial/21285.c     2006-11-29 22:57:37.000000000 +0100
7711 +++ linux-2.6.19.dev/drivers/serial/21285.c     2006-12-14 03:12:59.000000000 +0100
7712 @@ -478,6 +478,7 @@
7713         .owner                  = THIS_MODULE,
7714         .driver_name            = "ttyFB",
7715         .dev_name               = "ttyFB",
7716 +       .devfs_name             = "ttyFB",
7717         .major                  = SERIAL_21285_MAJOR,
7718         .minor                  = SERIAL_21285_MINOR,
7719         .nr                     = 1,
7720 diff -urN linux-2.6.19.old/drivers/serial/8250.c linux-2.6.19.dev/drivers/serial/8250.c
7721 --- linux-2.6.19.old/drivers/serial/8250.c      2006-11-29 22:57:37.000000000 +0100
7722 +++ linux-2.6.19.dev/drivers/serial/8250.c      2006-12-14 03:12:59.000000000 +0100
7723 @@ -2381,6 +2381,7 @@
7724  static struct uart_driver serial8250_reg = {
7725         .owner                  = THIS_MODULE,
7726         .driver_name            = "serial",
7727 +       .devfs_name             = "tts/",
7728         .dev_name               = "ttyS",
7729         .major                  = TTY_MAJOR,
7730         .minor                  = 64,
7731 diff -urN linux-2.6.19.old/drivers/serial/atmel_serial.c linux-2.6.19.dev/drivers/serial/atmel_serial.c
7732 --- linux-2.6.19.old/drivers/serial/atmel_serial.c      2006-11-29 22:57:37.000000000 +0100
7733 +++ linux-2.6.19.dev/drivers/serial/atmel_serial.c      2006-12-14 03:12:59.000000000 +0100
7734 @@ -875,6 +875,7 @@
7735         .owner                  = THIS_MODULE,
7736         .driver_name            = "atmel_serial",
7737         .dev_name               = ATMEL_DEVICENAME,
7738 +       .devfs_name             = ATMEL_DEVICENAME,
7739         .major                  = SERIAL_ATMEL_MAJOR,
7740         .minor                  = MINOR_START,
7741         .nr                     = ATMEL_MAX_UART,
7742 diff -urN linux-2.6.19.old/drivers/serial/crisv10.c linux-2.6.19.dev/drivers/serial/crisv10.c
7743 --- linux-2.6.19.old/drivers/serial/crisv10.c   2006-11-29 22:57:37.000000000 +0100
7744 +++ linux-2.6.19.dev/drivers/serial/crisv10.c   2006-12-14 03:12:59.000000000 +0100
7745 @@ -4877,7 +4877,7 @@
7746         driver->init_termios = tty_std_termios;
7747         driver->init_termios.c_cflag =
7748                 B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
7749 -       driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
7750 +       driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
7751         driver->termios = serial_termios;
7752         driver->termios_locked = serial_termios_locked;
7753  
7754 diff -urN linux-2.6.19.old/drivers/serial/dz.c linux-2.6.19.dev/drivers/serial/dz.c
7755 --- linux-2.6.19.old/drivers/serial/dz.c        2006-11-29 22:57:37.000000000 +0100
7756 +++ linux-2.6.19.dev/drivers/serial/dz.c        2006-12-14 03:12:59.000000000 +0100
7757 @@ -767,7 +767,11 @@
7758  static struct uart_driver dz_reg = {
7759         .owner                  = THIS_MODULE,
7760         .driver_name            = "serial",
7761 +#ifdef CONFIG_DEVFS
7762 +       .dev_name               = "tts/%d",
7763 +#else
7764         .dev_name               = "ttyS%d",
7765 +#endif
7766         .major                  = TTY_MAJOR,
7767         .minor                  = 64,
7768         .nr                     = DZ_NB_PORT,
7769 diff -urN linux-2.6.19.old/drivers/serial/imx.c linux-2.6.19.dev/drivers/serial/imx.c
7770 --- linux-2.6.19.old/drivers/serial/imx.c       2006-11-29 22:57:37.000000000 +0100
7771 +++ linux-2.6.19.dev/drivers/serial/imx.c       2006-12-14 03:12:59.000000000 +0100
7772 @@ -887,6 +887,7 @@
7773         .owner          = THIS_MODULE,
7774         .driver_name    = DRIVER_NAME,
7775         .dev_name       = "ttySMX",
7776 +       .devfs_name     = "ttsmx/",
7777         .major          = SERIAL_IMX_MAJOR,
7778         .minor          = MINOR_START,
7779         .nr             = ARRAY_SIZE(imx_ports),
7780 diff -urN linux-2.6.19.old/drivers/serial/ip22zilog.c linux-2.6.19.dev/drivers/serial/ip22zilog.c
7781 --- linux-2.6.19.old/drivers/serial/ip22zilog.c 2006-11-29 22:57:37.000000000 +0100
7782 +++ linux-2.6.19.dev/drivers/serial/ip22zilog.c 2006-12-14 03:12:59.000000000 +0100
7783 @@ -1082,6 +1082,7 @@
7784  static struct uart_driver ip22zilog_reg = {
7785         .owner          = THIS_MODULE,
7786         .driver_name    = "serial",
7787 +       .devfs_name     = "tts/",
7788         .dev_name       = "ttyS",
7789         .major          = TTY_MAJOR,
7790         .minor          = 64,
7791 diff -urN linux-2.6.19.old/drivers/serial/m32r_sio.c linux-2.6.19.dev/drivers/serial/m32r_sio.c
7792 --- linux-2.6.19.old/drivers/serial/m32r_sio.c  2006-11-29 22:57:37.000000000 +0100
7793 +++ linux-2.6.19.dev/drivers/serial/m32r_sio.c  2006-12-14 03:12:59.000000000 +0100
7794 @@ -1127,6 +1127,7 @@
7795  static struct uart_driver m32r_sio_reg = {
7796         .owner                  = THIS_MODULE,
7797         .driver_name            = "sio",
7798 +       .devfs_name             = "tts/",
7799         .dev_name               = "ttyS",
7800         .major                  = TTY_MAJOR,
7801         .minor                  = 64,
7802 diff -urN linux-2.6.19.old/drivers/serial/mcfserial.c linux-2.6.19.dev/drivers/serial/mcfserial.c
7803 --- linux-2.6.19.old/drivers/serial/mcfserial.c 2006-11-29 22:57:37.000000000 +0100
7804 +++ linux-2.6.19.dev/drivers/serial/mcfserial.c 2006-12-14 03:12:59.000000000 +0100
7805 @@ -1713,6 +1713,7 @@
7806         /* Initialize the tty_driver structure */
7807         mcfrs_serial_driver->owner = THIS_MODULE;
7808         mcfrs_serial_driver->name = "ttyS";
7809 +       mcfrs_serial_driver->devfs_name = "ttys/";
7810         mcfrs_serial_driver->driver_name = "serial";
7811         mcfrs_serial_driver->major = TTY_MAJOR;
7812         mcfrs_serial_driver->minor_start = 64;
7813 diff -urN linux-2.6.19.old/drivers/serial/mpc52xx_uart.c linux-2.6.19.dev/drivers/serial/mpc52xx_uart.c
7814 --- linux-2.6.19.old/drivers/serial/mpc52xx_uart.c      2006-11-29 22:57:37.000000000 +0100
7815 +++ linux-2.6.19.dev/drivers/serial/mpc52xx_uart.c      2006-12-14 03:12:59.000000000 +0100
7816 @@ -693,6 +693,7 @@
7817         .owner          = THIS_MODULE,
7818         .driver_name    = "mpc52xx_psc_uart",
7819         .dev_name       = "ttyPSC",
7820 +       .devfs_name     = "ttyPSC",
7821         .major          = SERIAL_PSC_MAJOR,
7822         .minor          = SERIAL_PSC_MINOR,
7823         .nr             = MPC52xx_PSC_MAXNUM,
7824 diff -urN linux-2.6.19.old/drivers/serial/mpsc.c linux-2.6.19.dev/drivers/serial/mpsc.c
7825 --- linux-2.6.19.old/drivers/serial/mpsc.c      2006-11-29 22:57:37.000000000 +0100
7826 +++ linux-2.6.19.dev/drivers/serial/mpsc.c      2006-12-14 03:12:59.000000000 +0100
7827 @@ -314,6 +314,7 @@
7828  #define MPSC_MAJOR             204
7829  #define MPSC_MINOR_START       44
7830  #define        MPSC_DRIVER_NAME        "MPSC"
7831 +#define        MPSC_DEVFS_NAME         "ttymm/"
7832  #define        MPSC_DEV_NAME           "ttyMM"
7833  #define        MPSC_VERSION            "1.00"
7834  
7835 @@ -1861,6 +1862,7 @@
7836  static struct uart_driver mpsc_reg = {
7837         .owner       = THIS_MODULE,
7838         .driver_name = MPSC_DRIVER_NAME,
7839 +       .devfs_name  = MPSC_DEVFS_NAME,
7840         .dev_name    = MPSC_DEV_NAME,
7841         .major       = MPSC_MAJOR,
7842         .minor       = MPSC_MINOR_START,
7843 diff -urN linux-2.6.19.old/drivers/serial/pmac_zilog.c linux-2.6.19.dev/drivers/serial/pmac_zilog.c
7844 --- linux-2.6.19.old/drivers/serial/pmac_zilog.c        2006-11-29 22:57:37.000000000 +0100
7845 +++ linux-2.6.19.dev/drivers/serial/pmac_zilog.c        2006-12-14 03:12:59.000000000 +0100
7846 @@ -100,6 +100,7 @@
7847  static struct uart_driver pmz_uart_reg = {
7848         .owner          =       THIS_MODULE,
7849         .driver_name    =       "ttyS",
7850 +       .devfs_name     =       "tts/",
7851         .dev_name       =       "ttyS",
7852         .major          =       TTY_MAJOR,
7853  };
7854 diff -urN linux-2.6.19.old/drivers/serial/pxa.c linux-2.6.19.dev/drivers/serial/pxa.c
7855 --- linux-2.6.19.old/drivers/serial/pxa.c       2006-11-29 22:57:37.000000000 +0100
7856 +++ linux-2.6.19.dev/drivers/serial/pxa.c       2006-12-14 03:12:59.000000000 +0100
7857 @@ -777,6 +777,7 @@
7858  static struct uart_driver serial_pxa_reg = {
7859         .owner          = THIS_MODULE,
7860         .driver_name    = "PXA serial",
7861 +       .devfs_name     = "tts/",
7862         .dev_name       = "ttyS",
7863         .major          = TTY_MAJOR,
7864         .minor          = 64,
7865 diff -urN linux-2.6.19.old/drivers/serial/s3c2410.c linux-2.6.19.dev/drivers/serial/s3c2410.c
7866 --- linux-2.6.19.old/drivers/serial/s3c2410.c   2006-11-29 22:57:37.000000000 +0100
7867 +++ linux-2.6.19.dev/drivers/serial/s3c2410.c   2006-12-14 03:12:59.000000000 +0100
7868 @@ -148,6 +148,7 @@
7869  /* UART name and device definitions */
7870  
7871  #define S3C24XX_SERIAL_NAME    "ttySAC"
7872 +#define S3C24XX_SERIAL_DEVFS    "tts/"
7873  #define S3C24XX_SERIAL_MAJOR   204
7874  #define S3C24XX_SERIAL_MINOR   64
7875  
7876 @@ -950,6 +951,7 @@
7877         .nr             = 3,
7878         .cons           = S3C24XX_SERIAL_CONSOLE,
7879         .driver_name    = S3C24XX_SERIAL_NAME,
7880 +       .devfs_name     = S3C24XX_SERIAL_DEVFS,
7881         .major          = S3C24XX_SERIAL_MAJOR,
7882         .minor          = S3C24XX_SERIAL_MINOR,
7883  };
7884 diff -urN linux-2.6.19.old/drivers/serial/sa1100.c linux-2.6.19.dev/drivers/serial/sa1100.c
7885 --- linux-2.6.19.old/drivers/serial/sa1100.c    2006-11-29 22:57:37.000000000 +0100
7886 +++ linux-2.6.19.dev/drivers/serial/sa1100.c    2006-12-14 03:12:59.000000000 +0100
7887 @@ -815,6 +815,7 @@
7888         .owner                  = THIS_MODULE,
7889         .driver_name            = "ttySA",
7890         .dev_name               = "ttySA",
7891 +       .devfs_name             = "ttySA",
7892         .major                  = SERIAL_SA1100_MAJOR,
7893         .minor                  = MINOR_START,
7894         .nr                     = NR_PORTS,
7895 diff -urN linux-2.6.19.old/drivers/serial/serial_core.c linux-2.6.19.dev/drivers/serial/serial_core.c
7896 --- linux-2.6.19.old/drivers/serial/serial_core.c       2006-11-29 22:57:37.000000000 +0100
7897 +++ linux-2.6.19.dev/drivers/serial/serial_core.c       2006-12-14 03:12:59.000000000 +0100
7898 @@ -2182,6 +2182,7 @@
7899  
7900         normal->owner           = drv->owner;
7901         normal->driver_name     = drv->driver_name;
7902 +       normal->devfs_name      = drv->devfs_name;
7903         normal->name            = drv->dev_name;
7904         normal->major           = drv->major;
7905         normal->minor_start     = drv->minor;
7906 @@ -2189,7 +2190,7 @@
7907         normal->subtype         = SERIAL_TYPE_NORMAL;
7908         normal->init_termios    = tty_std_termios;
7909         normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
7910 -       normal->flags           = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
7911 +       normal->flags           = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
7912         normal->driver_state    = drv;
7913         tty_set_operations(normal, &uart_ops);
7914  
7915 diff -urN linux-2.6.19.old/drivers/serial/serial_txx9.c linux-2.6.19.dev/drivers/serial/serial_txx9.c
7916 --- linux-2.6.19.old/drivers/serial/serial_txx9.c       2006-11-29 22:57:37.000000000 +0100
7917 +++ linux-2.6.19.dev/drivers/serial/serial_txx9.c       2006-12-14 03:12:59.000000000 +0100
7918 @@ -68,10 +68,12 @@
7919  #if !defined(CONFIG_SERIAL_TXX9_STDSERIAL)
7920  /* "ttyS" is used for standard serial driver */
7921  #define TXX9_TTY_NAME "ttyTX"
7922 +#define TXX9_TTY_DEVFS_NAME "tttx/"
7923  #define TXX9_TTY_MINOR_START   (64 + 64)       /* ttyTX0(128), ttyTX1(129) */
7924  #else
7925  /* acts like standard serial driver */
7926  #define TXX9_TTY_NAME "ttyS"
7927 +#define TXX9_TTY_DEVFS_NAME "tts/"
7928  #define TXX9_TTY_MINOR_START   64
7929  #endif
7930  #define TXX9_TTY_MAJOR TTY_MAJOR
7931 @@ -968,6 +970,7 @@
7932  static struct uart_driver serial_txx9_reg = {
7933         .owner                  = THIS_MODULE,
7934         .driver_name            = "serial_txx9",
7935 +       .devfs_name             = TXX9_TTY_DEVFS_NAME,
7936         .dev_name               = TXX9_TTY_NAME,
7937         .major                  = TXX9_TTY_MAJOR,
7938         .minor                  = TXX9_TTY_MINOR_START,
7939 diff -urN linux-2.6.19.old/drivers/serial/sh-sci.c linux-2.6.19.dev/drivers/serial/sh-sci.c
7940 --- linux-2.6.19.old/drivers/serial/sh-sci.c    2006-11-29 22:57:37.000000000 +0100
7941 +++ linux-2.6.19.dev/drivers/serial/sh-sci.c    2006-12-14 03:12:59.000000000 +0100
7942 @@ -1320,6 +1320,9 @@
7943  static struct uart_driver sci_uart_driver = {
7944         .owner          = THIS_MODULE,
7945         .driver_name    = "sci",
7946 +#ifdef CONFIG_DEVFS_FS
7947 +       .devfs_name     = "ttsc/",
7948 +#endif
7949         .dev_name       = "ttySC",
7950         .major          = SCI_MAJOR,
7951         .minor          = SCI_MINOR_START,
7952 diff -urN linux-2.6.19.old/drivers/serial/sunhv.c linux-2.6.19.dev/drivers/serial/sunhv.c
7953 --- linux-2.6.19.old/drivers/serial/sunhv.c     2006-11-29 22:57:37.000000000 +0100
7954 +++ linux-2.6.19.dev/drivers/serial/sunhv.c     2006-12-14 03:12:59.000000000 +0100
7955 @@ -353,6 +353,7 @@
7956  static struct uart_driver sunhv_reg = {
7957         .owner                  = THIS_MODULE,
7958         .driver_name            = "serial",
7959 +       .devfs_name             = "tts/",
7960         .dev_name               = "ttyS",
7961         .major                  = TTY_MAJOR,
7962  };
7963 diff -urN linux-2.6.19.old/drivers/serial/sunsab.c linux-2.6.19.dev/drivers/serial/sunsab.c
7964 --- linux-2.6.19.old/drivers/serial/sunsab.c    2006-11-29 22:57:37.000000000 +0100
7965 +++ linux-2.6.19.dev/drivers/serial/sunsab.c    2006-12-14 03:12:59.000000000 +0100
7966 @@ -849,6 +849,7 @@
7967  static struct uart_driver sunsab_reg = {
7968         .owner                  = THIS_MODULE,
7969         .driver_name            = "serial",
7970 +       .devfs_name             = "tts/",
7971         .dev_name               = "ttyS",
7972         .major                  = TTY_MAJOR,
7973  };
7974 diff -urN linux-2.6.19.old/drivers/serial/sunsu.c linux-2.6.19.dev/drivers/serial/sunsu.c
7975 --- linux-2.6.19.old/drivers/serial/sunsu.c     2006-11-29 22:57:37.000000000 +0100
7976 +++ linux-2.6.19.dev/drivers/serial/sunsu.c     2006-12-14 03:12:59.000000000 +0100
7977 @@ -1175,6 +1175,7 @@
7978  static struct uart_driver sunsu_reg = {
7979         .owner                  = THIS_MODULE,
7980         .driver_name            = "serial",
7981 +       .devfs_name             = "tts/",
7982         .dev_name               = "ttyS",
7983         .major                  = TTY_MAJOR,
7984  };
7985 diff -urN linux-2.6.19.old/drivers/serial/sunzilog.c linux-2.6.19.dev/drivers/serial/sunzilog.c
7986 --- linux-2.6.19.old/drivers/serial/sunzilog.c  2006-11-29 22:57:37.000000000 +0100
7987 +++ linux-2.6.19.dev/drivers/serial/sunzilog.c  2006-12-14 03:12:59.000000000 +0100
7988 @@ -1006,6 +1006,7 @@
7989  static struct uart_driver sunzilog_reg = {
7990         .owner          =       THIS_MODULE,
7991         .driver_name    =       "ttyS",
7992 +       .devfs_name     =       "tts/",
7993         .dev_name       =       "ttyS",
7994         .major          =       TTY_MAJOR,
7995  };
7996 diff -urN linux-2.6.19.old/drivers/serial/v850e_uart.c linux-2.6.19.dev/drivers/serial/v850e_uart.c
7997 --- linux-2.6.19.old/drivers/serial/v850e_uart.c        2006-11-29 22:57:37.000000000 +0100
7998 +++ linux-2.6.19.dev/drivers/serial/v850e_uart.c        2006-12-14 03:12:59.000000000 +0100
7999 @@ -468,6 +468,7 @@
8000  static struct uart_driver v850e_uart_driver = {
8001         .owner                  = THIS_MODULE,
8002         .driver_name            = "v850e_uart",
8003 +       .devfs_name             = "tts/",
8004         .dev_name               = "ttyS",
8005         .major                  = TTY_MAJOR,
8006         .minor                  = V850E_UART_MINOR_BASE,
8007 diff -urN linux-2.6.19.old/drivers/serial/vr41xx_siu.c linux-2.6.19.dev/drivers/serial/vr41xx_siu.c
8008 --- linux-2.6.19.old/drivers/serial/vr41xx_siu.c        2006-11-29 22:57:37.000000000 +0100
8009 +++ linux-2.6.19.dev/drivers/serial/vr41xx_siu.c        2006-12-14 03:12:59.000000000 +0100
8010 @@ -910,6 +910,7 @@
8011         .owner          = THIS_MODULE,
8012         .driver_name    = "SIU",
8013         .dev_name       = "ttyVR",
8014 +       .devfs_name     = "ttvr/",
8015         .major          = SIU_MAJOR,
8016         .minor          = SIU_MINOR_BASE,
8017         .cons           = SERIAL_VR41XX_CONSOLE,
8018 diff -urN linux-2.6.19.old/drivers/tc/zs.c linux-2.6.19.dev/drivers/tc/zs.c
8019 --- linux-2.6.19.old/drivers/tc/zs.c    2006-11-29 22:57:37.000000000 +0100
8020 +++ linux-2.6.19.dev/drivers/tc/zs.c    2006-12-14 03:12:59.000000000 +0100
8021 @@ -1744,6 +1744,7 @@
8022         /* Not all of this is exactly right for us. */
8023  
8024         serial_driver->owner = THIS_MODULE;
8025 +       serial_driver->devfs_name = "tts/";
8026         serial_driver->name = "ttyS";
8027         serial_driver->major = TTY_MAJOR;
8028         serial_driver->minor_start = 64;
8029 @@ -1752,7 +1753,7 @@
8030         serial_driver->init_termios = tty_std_termios;
8031         serial_driver->init_termios.c_cflag =
8032                 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
8033 -       serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
8034 +       serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
8035         tty_set_operations(serial_driver, &serial_ops);
8036  
8037         if (tty_register_driver(serial_driver))
8038 diff -urN linux-2.6.19.old/drivers/telephony/phonedev.c linux-2.6.19.dev/drivers/telephony/phonedev.c
8039 --- linux-2.6.19.old/drivers/telephony/phonedev.c       2006-11-29 22:57:37.000000000 +0100
8040 +++ linux-2.6.19.dev/drivers/telephony/phonedev.c       2006-12-14 03:12:59.000000000 +0100
8041 @@ -28,6 +28,7 @@
8042  
8043  #include <linux/kmod.h>
8044  #include <linux/sem.h>
8045 +#include <linux/devfs_fs_kernel.h>
8046  #include <linux/mutex.h>
8047  
8048  #define PHONE_NUM_DEVICES      256
8049 @@ -105,6 +106,8 @@
8050                 if (phone_device[i] == NULL) {
8051                         phone_device[i] = p;
8052                         p->minor = i;
8053 +                       devfs_mk_cdev(MKDEV(PHONE_MAJOR,i),
8054 +                               S_IFCHR|S_IRUSR|S_IWUSR, "phone/%d", i);
8055                         mutex_unlock(&phone_lock);
8056                         return 0;
8057                 }
8058 @@ -122,6 +125,7 @@
8059         mutex_lock(&phone_lock);
8060         if (phone_device[pfd->minor] != pfd)
8061                 panic("phone: bad unregister");
8062 +       devfs_remove("phone/%d", pfd->minor);
8063         phone_device[pfd->minor] = NULL;
8064         mutex_unlock(&phone_lock);
8065  }
8066 diff -urN linux-2.6.19.old/drivers/usb/class/cdc-acm.c linux-2.6.19.dev/drivers/usb/class/cdc-acm.c
8067 --- linux-2.6.19.old/drivers/usb/class/cdc-acm.c        2006-11-29 22:57:37.000000000 +0100
8068 +++ linux-2.6.19.dev/drivers/usb/class/cdc-acm.c        2006-12-14 03:12:59.000000000 +0100
8069 @@ -1151,11 +1151,12 @@
8070         acm_tty_driver->owner = THIS_MODULE,
8071         acm_tty_driver->driver_name = "acm",
8072         acm_tty_driver->name = "ttyACM",
8073 +       acm_tty_driver->devfs_name = "usb/acm/",
8074         acm_tty_driver->major = ACM_TTY_MAJOR,
8075         acm_tty_driver->minor_start = 0,
8076         acm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL,
8077         acm_tty_driver->subtype = SERIAL_TYPE_NORMAL,
8078 -       acm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
8079 +       acm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
8080         acm_tty_driver->init_termios = tty_std_termios;
8081         acm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
8082         tty_set_operations(acm_tty_driver, &acm_ops);
8083 diff -urN linux-2.6.19.old/drivers/usb/gadget/serial.c linux-2.6.19.dev/drivers/usb/gadget/serial.c
8084 --- linux-2.6.19.old/drivers/usb/gadget/serial.c        2006-11-29 22:57:37.000000000 +0100
8085 +++ linux-2.6.19.dev/drivers/usb/gadget/serial.c        2006-12-14 03:12:59.000000000 +0100
8086 @@ -587,11 +587,12 @@
8087         gs_tty_driver->owner = THIS_MODULE;
8088         gs_tty_driver->driver_name = GS_SHORT_NAME;
8089         gs_tty_driver->name = "ttygs";
8090 +       gs_tty_driver->devfs_name = "usb/ttygs/";
8091         gs_tty_driver->major = GS_MAJOR;
8092         gs_tty_driver->minor_start = GS_MINOR_START;
8093         gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
8094         gs_tty_driver->subtype = SERIAL_TYPE_NORMAL;
8095 -       gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
8096 +       gs_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
8097         gs_tty_driver->init_termios = tty_std_termios;
8098         gs_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
8099         tty_set_operations(gs_tty_driver, &gs_tty_ops);
8100 diff -urN linux-2.6.19.old/drivers/usb/serial/usb-serial.c linux-2.6.19.dev/drivers/usb/serial/usb-serial.c
8101 --- linux-2.6.19.old/drivers/usb/serial/usb-serial.c    2006-11-29 22:57:37.000000000 +0100
8102 +++ linux-2.6.19.dev/drivers/usb/serial/usb-serial.c    2006-12-14 03:12:59.000000000 +0100
8103 @@ -1055,12 +1055,13 @@
8104  
8105         usb_serial_tty_driver->owner = THIS_MODULE;
8106         usb_serial_tty_driver->driver_name = "usbserial";
8107 +       usb_serial_tty_driver->devfs_name = "usb/tts/";
8108         usb_serial_tty_driver->name =   "ttyUSB";
8109         usb_serial_tty_driver->major = SERIAL_TTY_MAJOR;
8110         usb_serial_tty_driver->minor_start = 0;
8111         usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
8112         usb_serial_tty_driver->subtype = SERIAL_TYPE_NORMAL;
8113 -       usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
8114 +       usb_serial_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
8115         usb_serial_tty_driver->init_termios = tty_std_termios;
8116         usb_serial_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
8117         tty_set_operations(usb_serial_tty_driver, &serial_ops);
8118 diff -urN linux-2.6.19.old/drivers/video/fbmem.c linux-2.6.19.dev/drivers/video/fbmem.c
8119 --- linux-2.6.19.old/drivers/video/fbmem.c      2006-11-29 22:57:37.000000000 +0100
8120 +++ linux-2.6.19.dev/drivers/video/fbmem.c      2006-12-14 03:12:59.000000000 +0100
8121 @@ -31,6 +31,7 @@
8122  #ifdef CONFIG_KMOD
8123  #include <linux/kmod.h>
8124  #endif
8125 +#include <linux/devfs_fs_kernel.h>
8126  #include <linux/err.h>
8127  #include <linux/device.h>
8128  #include <linux/efi.h>
8129 @@ -1324,6 +1325,8 @@
8130         fb_add_videomode(&mode, &fb_info->modelist);
8131         registered_fb[i] = fb_info;
8132  
8133 +       devfs_mk_cdev(MKDEV(FB_MAJOR, i),
8134 +                       S_IFCHR | S_IRUGO | S_IWUGO, "fb/%d", i);
8135         event.info = fb_info;
8136         fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
8137         return 0;
8138 @@ -1349,6 +1352,7 @@
8139         i = fb_info->node;
8140         if (!registered_fb[i])
8141                 return -EINVAL;
8142 +       devfs_remove("fb/%d", i);
8143  
8144         if (fb_info->pixmap.addr &&
8145             (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
8146 @@ -1400,6 +1404,7 @@
8147  {
8148         create_proc_read_entry("fb", 0, NULL, fbmem_read_proc, NULL);
8149  
8150 +       devfs_mk_dir("fb");
8151         if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
8152                 printk("unable to get major %d for fb devs\n", FB_MAJOR);
8153  
8154 diff -urN linux-2.6.19.old/fs/block_dev.c linux-2.6.19.dev/fs/block_dev.c
8155 --- linux-2.6.19.old/fs/block_dev.c     2006-11-29 22:57:37.000000000 +0100
8156 +++ linux-2.6.19.dev/fs/block_dev.c     2006-12-14 03:12:59.000000000 +0100
8157 @@ -11,6 +11,7 @@
8158  #include <linux/slab.h>
8159  #include <linux/kmod.h>
8160  #include <linux/major.h>
8161 +#include <linux/devfs_fs_kernel.h>
8162  #include <linux/smp_lock.h>
8163  #include <linux/highmem.h>
8164  #include <linux/blkdev.h>
8165 diff -urN linux-2.6.19.old/fs/char_dev.c linux-2.6.19.dev/fs/char_dev.c
8166 --- linux-2.6.19.old/fs/char_dev.c      2006-11-29 22:57:37.000000000 +0100
8167 +++ linux-2.6.19.dev/fs/char_dev.c      2006-12-14 03:12:59.000000000 +0100
8168 @@ -13,6 +13,7 @@
8169  #include <linux/errno.h>
8170  #include <linux/module.h>
8171  #include <linux/smp_lock.h>
8172 +#include <linux/devfs_fs_kernel.h>
8173  #include <linux/seq_file.h>
8174  
8175  #include <linux/kobject.h>
8176 diff -urN linux-2.6.19.old/fs/coda/psdev.c linux-2.6.19.dev/fs/coda/psdev.c
8177 --- linux-2.6.19.old/fs/coda/psdev.c    2006-11-29 22:57:37.000000000 +0100
8178 +++ linux-2.6.19.dev/fs/coda/psdev.c    2006-12-14 03:12:59.000000000 +0100
8179 @@ -28,6 +28,7 @@
8180  #include <linux/delay.h>
8181  #include <linux/skbuff.h>
8182  #include <linux/proc_fs.h>
8183 +#include <linux/devfs_fs_kernel.h>
8184  #include <linux/vmalloc.h>
8185  #include <linux/fs.h>
8186  #include <linux/file.h>
8187 @@ -364,12 +365,22 @@
8188                 err = PTR_ERR(coda_psdev_class);
8189                 goto out_chrdev;
8190         }               
8191 -       for (i = 0; i < MAX_CODADEVS; i++)
8192 +       devfs_mk_dir ("coda");
8193 +       for (i = 0; i < MAX_CODADEVS; i++) {
8194                 class_device_create(coda_psdev_class, NULL,
8195                                 MKDEV(CODA_PSDEV_MAJOR,i), NULL, "cfs%d", i);
8196 +               err = devfs_mk_cdev(MKDEV(CODA_PSDEV_MAJOR, i),
8197 +                               S_IFCHR|S_IRUSR|S_IWUSR, "coda/%d", i);
8198 +               if (err)
8199 +                       goto out_class;
8200 +       }
8201         coda_sysctl_init();
8202         goto out;
8203  
8204 +out_class:
8205 +       for (i = 0; i < MAX_CODADEVS; i++) 
8206 +               class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
8207 +       class_destroy(coda_psdev_class);
8208  out_chrdev:
8209         unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
8210  out:
8211 @@ -408,9 +419,12 @@
8212         }
8213         return 0;
8214  out:
8215 -       for (i = 0; i < MAX_CODADEVS; i++)
8216 +       for (i = 0; i < MAX_CODADEVS; i++) {
8217                 class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
8218 +               devfs_remove("coda/%d", i);
8219 +       }
8220         class_destroy(coda_psdev_class);
8221 +       devfs_remove("coda");
8222         unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
8223         coda_sysctl_clean();
8224  out1:
8225 @@ -427,9 +441,12 @@
8226          if ( err != 0 ) {
8227                  printk("coda: failed to unregister filesystem\n");
8228          }
8229 -       for (i = 0; i < MAX_CODADEVS; i++)
8230 +       for (i = 0; i < MAX_CODADEVS; i++) {
8231                 class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
8232 +               devfs_remove("coda/%d", i);
8233 +       }
8234         class_destroy(coda_psdev_class);
8235 +       devfs_remove("coda");
8236         unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
8237         coda_sysctl_clean();
8238         coda_destroy_inodecache();
8239 diff -urN linux-2.6.19.old/fs/compat_ioctl.c linux-2.6.19.dev/fs/compat_ioctl.c
8240 --- linux-2.6.19.old/fs/compat_ioctl.c  2006-11-29 22:57:37.000000000 +0100
8241 +++ linux-2.6.19.dev/fs/compat_ioctl.c  2006-12-14 03:12:59.000000000 +0100
8242 @@ -42,6 +42,7 @@
8243  #include <linux/cdrom.h>
8244  #include <linux/auto_fs.h>
8245  #include <linux/auto_fs4.h>
8246 +#include <linux/devfs_fs.h>
8247  #include <linux/tty.h>
8248  #include <linux/vt_kern.h>
8249  #include <linux/fb.h>
8250 diff -urN linux-2.6.19.old/fs/devfs/base.c linux-2.6.19.dev/fs/devfs/base.c
8251 --- linux-2.6.19.old/fs/devfs/base.c    1970-01-01 01:00:00.000000000 +0100
8252 +++ linux-2.6.19.dev/fs/devfs/base.c    2006-12-14 03:12:59.000000000 +0100
8253 @@ -0,0 +1,2835 @@
8254 +/*  devfs (Device FileSystem) driver.
8255 +
8256 +    Copyright (C) 1998-2002  Richard Gooch
8257 +
8258 +    This library is free software; you can redistribute it and/or
8259 +    modify it under the terms of the GNU Library General Public
8260 +    License as published by the Free Software Foundation; either
8261 +    version 2 of the License, or (at your option) any later version.
8262 +
8263 +    This library is distributed in the hope that it will be useful,
8264 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
8265 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8266 +    Library General Public License for more details.
8267 +
8268 +    You should have received a copy of the GNU Library General Public
8269 +    License along with this library; if not, write to the Free
8270 +    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
8271 +
8272 +    Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
8273 +    The postal address is:
8274 +      Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
8275 +
8276 +    ChangeLog
8277 +
8278 +    19980110   Richard Gooch <rgooch@atnf.csiro.au>
8279 +               Original version.
8280 +  v0.1
8281 +    19980111   Richard Gooch <rgooch@atnf.csiro.au>
8282 +               Created per-fs inode table rather than using inode->u.generic_ip
8283 +  v0.2
8284 +    19980111   Richard Gooch <rgooch@atnf.csiro.au>
8285 +               Created .epoch inode which has a ctime of 0.
8286 +              Fixed loss of named pipes when dentries lost.
8287 +              Fixed loss of inode data when devfs_register() follows mknod().
8288 +  v0.3
8289 +    19980111   Richard Gooch <rgooch@atnf.csiro.au>
8290 +               Fix for when compiling with CONFIG_KERNELD.
8291 +    19980112   Richard Gooch <rgooch@atnf.csiro.au>
8292 +               Fix for readdir() which sometimes didn't show entries.
8293 +              Added <<tolerant>> option to <devfs_register>.
8294 +  v0.4
8295 +    19980113   Richard Gooch <rgooch@atnf.csiro.au>
8296 +               Created <devfs_fill_file> function.
8297 +  v0.5
8298 +    19980115   Richard Gooch <rgooch@atnf.csiro.au>
8299 +               Added subdirectory support. Major restructuring.
8300 +    19980116   Richard Gooch <rgooch@atnf.csiro.au>
8301 +               Fixed <find_by_dev> to not search major=0,minor=0.
8302 +              Added symlink support.
8303 +  v0.6
8304 +    19980120   Richard Gooch <rgooch@atnf.csiro.au>
8305 +               Created <devfs_mk_dir> function and support directory unregister
8306 +    19980120   Richard Gooch <rgooch@atnf.csiro.au>
8307 +               Auto-ownership uses real uid/gid rather than effective uid/gid.
8308 +  v0.7
8309 +    19980121   Richard Gooch <rgooch@atnf.csiro.au>
8310 +               Supported creation of sockets.
8311 +  v0.8
8312 +    19980122   Richard Gooch <rgooch@atnf.csiro.au>
8313 +               Added DEVFS_FL_HIDE_UNREG flag.
8314 +              Interface change to <devfs_mk_symlink>.
8315 +               Created <devfs_symlink> to support symlink(2).
8316 +  v0.9
8317 +    19980123   Richard Gooch <rgooch@atnf.csiro.au>
8318 +               Added check to <devfs_fill_file> to check inode is in devfs.
8319 +              Added optional traversal of symlinks.
8320 +  v0.10
8321 +    19980124   Richard Gooch <rgooch@atnf.csiro.au>
8322 +               Created <devfs_get_flags> and <devfs_set_flags>.
8323 +  v0.11
8324 +    19980125   C. Scott Ananian <cananian@alumni.princeton.edu>
8325 +               Created <devfs_find_handle>.
8326 +    19980125   Richard Gooch <rgooch@atnf.csiro.au>
8327 +               Allow removal of symlinks.
8328 +  v0.12
8329 +    19980125   Richard Gooch <rgooch@atnf.csiro.au>
8330 +               Created <devfs_set_symlink_destination>.
8331 +    19980126   Richard Gooch <rgooch@atnf.csiro.au>
8332 +               Moved DEVFS_SUPER_MAGIC into header file.
8333 +              Added DEVFS_FL_HIDE flag.
8334 +              Created <devfs_get_maj_min>.
8335 +              Created <devfs_get_handle_from_inode>.
8336 +              Fixed minor bug in <find_by_dev>.
8337 +    19980127   Richard Gooch <rgooch@atnf.csiro.au>
8338 +              Changed interface to <find_by_dev>, <find_entry>,
8339 +              <devfs_unregister>, <devfs_fill_file> and <devfs_find_handle>.
8340 +              Fixed inode times when symlink created with symlink(2).
8341 +  v0.13
8342 +    19980129   C. Scott Ananian <cananian@alumni.princeton.edu>
8343 +               Exported <devfs_set_symlink_destination>, <devfs_get_maj_min>
8344 +              and <devfs_get_handle_from_inode>.
8345 +    19980129   Richard Gooch <rgooch@atnf.csiro.au>
8346 +              Created <devfs_unlink> to support unlink(2).
8347 +  v0.14
8348 +    19980129   Richard Gooch <rgooch@atnf.csiro.au>
8349 +              Fixed kerneld support for entries in devfs subdirectories.
8350 +    19980130   Richard Gooch <rgooch@atnf.csiro.au>
8351 +              Bugfixes in <call_kerneld>.
8352 +  v0.15
8353 +    19980207   Richard Gooch <rgooch@atnf.csiro.au>
8354 +              Call kerneld when looking up unregistered entries.
8355 +  v0.16
8356 +    19980326   Richard Gooch <rgooch@atnf.csiro.au>
8357 +              Modified interface to <devfs_find_handle> for symlink traversal.
8358 +  v0.17
8359 +    19980331   Richard Gooch <rgooch@atnf.csiro.au>
8360 +              Fixed persistence bug with device numbers for manually created
8361 +              device files.
8362 +              Fixed problem with recreating symlinks with different content.
8363 +  v0.18
8364 +    19980401   Richard Gooch <rgooch@atnf.csiro.au>
8365 +              Changed to CONFIG_KMOD.
8366 +              Hide entries which are manually unlinked.
8367 +              Always invalidate devfs dentry cache when registering entries.
8368 +              Created <devfs_rmdir> to support rmdir(2).
8369 +              Ensure directories created by <devfs_mk_dir> are visible.
8370 +  v0.19
8371 +    19980402   Richard Gooch <rgooch@atnf.csiro.au>
8372 +              Invalidate devfs dentry cache when making directories.
8373 +              Invalidate devfs dentry cache when removing entries.
8374 +              Fixed persistence bug with fifos.
8375 +  v0.20
8376 +    19980421   Richard Gooch <rgooch@atnf.csiro.au>
8377 +              Print process command when debugging kerneld/kmod.
8378 +              Added debugging for register/unregister/change operations.
8379 +    19980422   Richard Gooch <rgooch@atnf.csiro.au>
8380 +              Added "devfs=" boot options.
8381 +  v0.21
8382 +    19980426   Richard Gooch <rgooch@atnf.csiro.au>
8383 +              No longer lock/unlock superblock in <devfs_put_super>.
8384 +              Drop negative dentries when they are released.
8385 +              Manage dcache more efficiently.
8386 +  v0.22
8387 +    19980427   Richard Gooch <rgooch@atnf.csiro.au>
8388 +              Added DEVFS_FL_AUTO_DEVNUM flag.
8389 +  v0.23
8390 +    19980430   Richard Gooch <rgooch@atnf.csiro.au>
8391 +              No longer set unnecessary methods.
8392 +  v0.24
8393 +    19980504   Richard Gooch <rgooch@atnf.csiro.au>
8394 +              Added PID display to <call_kerneld> debugging message.
8395 +              Added "after" debugging message to <call_kerneld>.
8396 +    19980519   Richard Gooch <rgooch@atnf.csiro.au>
8397 +              Added "diread" and "diwrite" boot options.
8398 +    19980520   Richard Gooch <rgooch@atnf.csiro.au>
8399 +              Fixed persistence problem with permissions.
8400 +  v0.25
8401 +    19980602   Richard Gooch <rgooch@atnf.csiro.au>
8402 +              Support legacy device nodes.
8403 +              Fixed bug where recreated inodes were hidden.
8404 +  v0.26
8405 +    19980602   Richard Gooch <rgooch@atnf.csiro.au>
8406 +              Improved debugging in <get_vfs_inode>.
8407 +    19980607   Richard Gooch <rgooch@atnf.csiro.au>
8408 +              No longer free old dentries in <devfs_mk_dir>.
8409 +              Free all dentries for a given entry when deleting inodes.
8410 +  v0.27
8411 +    19980627   Richard Gooch <rgooch@atnf.csiro.au>
8412 +              Limit auto-device numbering to majors 128 to 239.
8413 +  v0.28
8414 +    19980629   Richard Gooch <rgooch@atnf.csiro.au>
8415 +              Fixed inode times persistence problem.
8416 +  v0.29
8417 +    19980704   Richard Gooch <rgooch@atnf.csiro.au>
8418 +              Fixed spelling in <devfs_readlink> debug.
8419 +              Fixed bug in <devfs_setup> parsing "dilookup".
8420 +  v0.30
8421 +    19980705   Richard Gooch <rgooch@atnf.csiro.au>
8422 +              Fixed devfs inode leak when manually recreating inodes.
8423 +              Fixed permission persistence problem when recreating inodes.
8424 +  v0.31
8425 +    19980727   Richard Gooch <rgooch@atnf.csiro.au>
8426 +              Removed harmless "unused variable" compiler warning.
8427 +              Fixed modes for manually recreated device nodes.
8428 +  v0.32
8429 +    19980728   Richard Gooch <rgooch@atnf.csiro.au>
8430 +              Added NULL devfs inode warning in <devfs_read_inode>.
8431 +              Force all inode nlink values to 1.
8432 +  v0.33
8433 +    19980730   Richard Gooch <rgooch@atnf.csiro.au>
8434 +              Added "dimknod" boot option.
8435 +              Set inode nlink to 0 when freeing dentries.
8436 +              Fixed modes for manually recreated symlinks.
8437 +  v0.34
8438 +    19980802   Richard Gooch <rgooch@atnf.csiro.au>
8439 +              Fixed bugs in recreated directories and symlinks.
8440 +  v0.35
8441 +    19980806   Richard Gooch <rgooch@atnf.csiro.au>
8442 +              Fixed bugs in recreated device nodes.
8443 +    19980807   Richard Gooch <rgooch@atnf.csiro.au>
8444 +              Fixed bug in currently unused <devfs_get_handle_from_inode>.
8445 +              Defined new <devfs_handle_t> type.
8446 +              Improved debugging when getting entries.
8447 +              Fixed bug where directories could be emptied.
8448 +  v0.36
8449 +    19980809   Richard Gooch <rgooch@atnf.csiro.au>
8450 +              Replaced dummy .epoch inode with .devfsd character device.
8451 +    19980810   Richard Gooch <rgooch@atnf.csiro.au>
8452 +              Implemented devfsd protocol revision 0.
8453 +  v0.37
8454 +    19980819   Richard Gooch <rgooch@atnf.csiro.au>
8455 +              Added soothing message to warning in <devfs_d_iput>.
8456 +  v0.38
8457 +    19980829   Richard Gooch <rgooch@atnf.csiro.au>
8458 +              Use GCC extensions for structure initialisations.
8459 +              Implemented async open notification.
8460 +              Incremented devfsd protocol revision to 1.
8461 +  v0.39
8462 +    19980908   Richard Gooch <rgooch@atnf.csiro.au>
8463 +              Moved async open notification to end of <devfs_open>.
8464 +  v0.40
8465 +    19980910   Richard Gooch <rgooch@atnf.csiro.au>
8466 +              Prepended "/dev/" to module load request.
8467 +              Renamed <call_kerneld> to <call_kmod>.
8468 +  v0.41
8469 +    19980910   Richard Gooch <rgooch@atnf.csiro.au>
8470 +              Fixed typo "AYSNC" -> "ASYNC".
8471 +  v0.42
8472 +    19980910   Richard Gooch <rgooch@atnf.csiro.au>
8473 +              Added open flag for files.
8474 +  v0.43
8475 +    19980927   Richard Gooch <rgooch@atnf.csiro.au>
8476 +              Set i_blocks=0 and i_blksize=1024 in <devfs_read_inode>.
8477 +  v0.44
8478 +    19981005   Richard Gooch <rgooch@atnf.csiro.au>
8479 +              Added test for empty <<name>> in <devfs_find_handle>.
8480 +              Renamed <generate_path> to <devfs_generate_path> and published.
8481 +  v0.45
8482 +    19981006   Richard Gooch <rgooch@atnf.csiro.au>
8483 +              Created <devfs_get_fops>.
8484 +  v0.46
8485 +    19981007   Richard Gooch <rgooch@atnf.csiro.au>
8486 +              Limit auto-device numbering to majors 144 to 239.
8487 +  v0.47
8488 +    19981010   Richard Gooch <rgooch@atnf.csiro.au>
8489 +              Updated <devfs_follow_link> for VFS change in 2.1.125.
8490 +  v0.48
8491 +    19981022   Richard Gooch <rgooch@atnf.csiro.au>
8492 +              Created DEVFS_ FL_COMPAT flag.
8493 +  v0.49
8494 +    19981023   Richard Gooch <rgooch@atnf.csiro.au>
8495 +              Created "nocompat" boot option.
8496 +  v0.50
8497 +    19981025   Richard Gooch <rgooch@atnf.csiro.au>
8498 +              Replaced "mount" boot option with "nomount".
8499 +  v0.51
8500 +    19981110   Richard Gooch <rgooch@atnf.csiro.au>
8501 +              Created "only" boot option.
8502 +  v0.52
8503 +    19981112   Richard Gooch <rgooch@atnf.csiro.au>
8504 +              Added DEVFS_FL_REMOVABLE flag.
8505 +  v0.53
8506 +    19981114   Richard Gooch <rgooch@atnf.csiro.au>
8507 +              Only call <scan_dir_for_removable> on first call to
8508 +              <devfs_readdir>.
8509 +  v0.54
8510 +    19981205   Richard Gooch <rgooch@atnf.csiro.au>
8511 +              Updated <devfs_rmdir> for VFS change in 2.1.131.
8512 +  v0.55
8513 +    19981218   Richard Gooch <rgooch@atnf.csiro.au>
8514 +              Created <devfs_mk_compat>.
8515 +    19981220   Richard Gooch <rgooch@atnf.csiro.au>
8516 +              Check for partitions on removable media in <devfs_lookup>.
8517 +  v0.56
8518 +    19990118   Richard Gooch <rgooch@atnf.csiro.au>
8519 +              Added support for registering regular files.
8520 +              Created <devfs_set_file_size>.
8521 +              Update devfs inodes from entries if not changed through FS.
8522 +  v0.57
8523 +    19990124   Richard Gooch <rgooch@atnf.csiro.au>
8524 +              Fixed <devfs_fill_file> to only initialise temporary inodes.
8525 +              Trap for NULL fops in <devfs_register>.
8526 +              Return -ENODEV in <devfs_fill_file> for non-driver inodes.
8527 +  v0.58
8528 +    19990126   Richard Gooch <rgooch@atnf.csiro.au>
8529 +              Switched from PATH_MAX to DEVFS_PATHLEN.
8530 +  v0.59
8531 +    19990127   Richard Gooch <rgooch@atnf.csiro.au>
8532 +              Created "nottycompat" boot option.
8533 +  v0.60
8534 +    19990318   Richard Gooch <rgooch@atnf.csiro.au>
8535 +              Fixed <devfsd_read> to not overrun event buffer.
8536 +  v0.61
8537 +    19990329   Richard Gooch <rgooch@atnf.csiro.au>
8538 +              Created <devfs_auto_unregister>.
8539 +  v0.62
8540 +    19990330   Richard Gooch <rgooch@atnf.csiro.au>
8541 +              Don't return unregistred entries in <devfs_find_handle>.
8542 +              Panic in <devfs_unregister> if entry unregistered.
8543 +    19990401   Richard Gooch <rgooch@atnf.csiro.au>
8544 +              Don't panic in <devfs_auto_unregister> for duplicates.
8545 +  v0.63
8546 +    19990402   Richard Gooch <rgooch@atnf.csiro.au>
8547 +              Don't unregister already unregistered entries in <unregister>.
8548 +  v0.64
8549 +    19990510   Richard Gooch <rgooch@atnf.csiro.au>
8550 +              Disable warning messages when unable to read partition table for
8551 +              removable media.
8552 +  v0.65
8553 +    19990512   Richard Gooch <rgooch@atnf.csiro.au>
8554 +              Updated <devfs_lookup> for VFS change in 2.3.1-pre1.
8555 +              Created "oops-on-panic" boot option.
8556 +              Improved debugging in <devfs_register> and <devfs_unregister>.
8557 +  v0.66
8558 +    19990519   Richard Gooch <rgooch@atnf.csiro.au>
8559 +              Added documentation for some functions.
8560 +    19990525   Richard Gooch <rgooch@atnf.csiro.au>
8561 +              Removed "oops-on-panic" boot option: now always Oops.
8562 +  v0.67
8563 +    19990531   Richard Gooch <rgooch@atnf.csiro.au>
8564 +              Improved debugging in <devfs_register>.
8565 +  v0.68
8566 +    19990604   Richard Gooch <rgooch@atnf.csiro.au>
8567 +              Added "diunlink" and "nokmod" boot options.
8568 +              Removed superfluous warning message in <devfs_d_iput>.
8569 +  v0.69
8570 +    19990611   Richard Gooch <rgooch@atnf.csiro.au>
8571 +              Took account of change to <d_alloc_root>.
8572 +  v0.70
8573 +    19990614   Richard Gooch <rgooch@atnf.csiro.au>
8574 +              Created separate event queue for each mounted devfs.
8575 +              Removed <devfs_invalidate_dcache>.
8576 +              Created new ioctl()s.
8577 +              Incremented devfsd protocol revision to 3.
8578 +              Fixed bug when re-creating directories: contents were lost.
8579 +              Block access to inodes until devfsd updates permissions.
8580 +    19990615   Richard Gooch <rgooch@atnf.csiro.au>
8581 +              Support 2.2.x kernels.
8582 +  v0.71
8583 +    19990623   Richard Gooch <rgooch@atnf.csiro.au>
8584 +              Switched to sending process uid/gid to devfsd.
8585 +              Renamed <call_kmod> to <try_modload>.
8586 +              Added DEVFSD_NOTIFY_LOOKUP event.
8587 +    19990624   Richard Gooch <rgooch@atnf.csiro.au>
8588 +              Added DEVFSD_NOTIFY_CHANGE event.
8589 +              Incremented devfsd protocol revision to 4.
8590 +  v0.72
8591 +    19990713   Richard Gooch <rgooch@atnf.csiro.au>
8592 +              Return EISDIR rather than EINVAL for read(2) on directories.
8593 +  v0.73
8594 +    19990809   Richard Gooch <rgooch@atnf.csiro.au>
8595 +              Changed <devfs_setup> to new __init scheme.
8596 +  v0.74
8597 +    19990901   Richard Gooch <rgooch@atnf.csiro.au>
8598 +              Changed remaining function declarations to new __init scheme.
8599 +  v0.75
8600 +    19991013   Richard Gooch <rgooch@atnf.csiro.au>
8601 +              Created <devfs_get_info>, <devfs_set_info>,
8602 +              <devfs_get_first_child> and <devfs_get_next_sibling>.
8603 +              Added <<dir>> parameter to <devfs_register>, <devfs_mk_compat>,
8604 +              <devfs_mk_dir> and <devfs_find_handle>.
8605 +              Work sponsored by SGI.
8606 +  v0.76
8607 +    19991017   Richard Gooch <rgooch@atnf.csiro.au>
8608 +              Allow multiple unregistrations.
8609 +              Work sponsored by SGI.
8610 +  v0.77
8611 +    19991026   Richard Gooch <rgooch@atnf.csiro.au>
8612 +              Added major and minor number to devfsd protocol.
8613 +              Incremented devfsd protocol revision to 5.
8614 +              Work sponsored by SGI.
8615 +  v0.78
8616 +    19991030   Richard Gooch <rgooch@atnf.csiro.au>
8617 +              Support info pointer for all devfs entry types.
8618 +              Added <<info>> parameter to <devfs_mk_dir> and
8619 +              <devfs_mk_symlink>.
8620 +              Work sponsored by SGI.
8621 +  v0.79
8622 +    19991031   Richard Gooch <rgooch@atnf.csiro.au>
8623 +              Support "../" when searching devfs namespace.
8624 +              Work sponsored by SGI.
8625 +  v0.80
8626 +    19991101   Richard Gooch <rgooch@atnf.csiro.au>
8627 +              Created <devfs_get_unregister_slave>.
8628 +              Work sponsored by SGI.
8629 +  v0.81
8630 +    19991103   Richard Gooch <rgooch@atnf.csiro.au>
8631 +              Exported <devfs_get_parent>.
8632 +              Work sponsored by SGI.
8633 +  v0.82
8634 +    19991104   Richard Gooch <rgooch@atnf.csiro.au>
8635 +               Removed unused <devfs_set_symlink_destination>.
8636 +    19991105   Richard Gooch <rgooch@atnf.csiro.au>
8637 +               Do not hide entries from devfsd or children.
8638 +              Removed DEVFS_ FL_TTY_COMPAT flag.
8639 +              Removed "nottycompat" boot option.
8640 +              Removed <devfs_mk_compat>.
8641 +              Work sponsored by SGI.
8642 +  v0.83
8643 +    19991107   Richard Gooch <rgooch@atnf.csiro.au>
8644 +              Added DEVFS_FL_WAIT flag.
8645 +              Work sponsored by SGI.
8646 +  v0.84
8647 +    19991107   Richard Gooch <rgooch@atnf.csiro.au>
8648 +              Support new "disc" naming scheme in <get_removable_partition>.
8649 +              Allow NULL fops in <devfs_register>.
8650 +              Work sponsored by SGI.
8651 +  v0.85
8652 +    19991110   Richard Gooch <rgooch@atnf.csiro.au>
8653 +              Fall back to major table if NULL fops given to <devfs_register>.
8654 +              Work sponsored by SGI.
8655 +  v0.86
8656 +    19991204   Richard Gooch <rgooch@atnf.csiro.au>
8657 +              Support fifos when unregistering.
8658 +              Work sponsored by SGI.
8659 +  v0.87
8660 +    19991209   Richard Gooch <rgooch@atnf.csiro.au>
8661 +              Removed obsolete DEVFS_ FL_COMPAT and DEVFS_ FL_TOLERANT flags.
8662 +              Work sponsored by SGI.
8663 +  v0.88
8664 +    19991214   Richard Gooch <rgooch@atnf.csiro.au>
8665 +              Removed kmod support.
8666 +              Work sponsored by SGI.
8667 +  v0.89
8668 +    19991216   Richard Gooch <rgooch@atnf.csiro.au>
8669 +              Improved debugging in <get_vfs_inode>.
8670 +              Ensure dentries created by devfsd will be cleaned up.
8671 +              Work sponsored by SGI.
8672 +  v0.90
8673 +    19991223   Richard Gooch <rgooch@atnf.csiro.au>
8674 +              Created <devfs_get_name>.
8675 +              Work sponsored by SGI.
8676 +  v0.91
8677 +    20000203   Richard Gooch <rgooch@atnf.csiro.au>
8678 +              Ported to kernel 2.3.42.
8679 +              Removed <devfs_fill_file>.
8680 +              Work sponsored by SGI.
8681 +  v0.92
8682 +    20000306   Richard Gooch <rgooch@atnf.csiro.au>
8683 +              Added DEVFS_ FL_NO_PERSISTENCE flag.
8684 +              Removed unnecessary call to <update_devfs_inode_from_entry> in
8685 +              <devfs_readdir>.
8686 +              Work sponsored by SGI.
8687 +  v0.93
8688 +    20000413   Richard Gooch <rgooch@atnf.csiro.au>
8689 +              Set inode->i_size to correct size for symlinks.
8690 +    20000414   Richard Gooch <rgooch@atnf.csiro.au>
8691 +              Only give lookup() method to directories to comply with new VFS
8692 +              assumptions.
8693 +              Work sponsored by SGI.
8694 +    20000415   Richard Gooch <rgooch@atnf.csiro.au>
8695 +              Remove unnecessary tests in symlink methods.
8696 +              Don't kill existing block ops in <devfs_read_inode>.
8697 +              Work sponsored by SGI.
8698 +  v0.94
8699 +    20000424   Richard Gooch <rgooch@atnf.csiro.au>
8700 +              Don't create missing directories in <devfs_find_handle>.
8701 +              Work sponsored by SGI.
8702 +  v0.95
8703 +    20000430   Richard Gooch <rgooch@atnf.csiro.au>
8704 +              Added CONFIG_DEVFS_MOUNT.
8705 +              Work sponsored by SGI.
8706 +  v0.96
8707 +    20000608   Richard Gooch <rgooch@atnf.csiro.au>
8708 +              Disabled multi-mount capability (use VFS bindings instead).
8709 +              Work sponsored by SGI.
8710 +  v0.97
8711 +    20000610   Richard Gooch <rgooch@atnf.csiro.au>
8712 +              Switched to FS_SINGLE to disable multi-mounts.
8713 +    20000612   Richard Gooch <rgooch@atnf.csiro.au>
8714 +              Removed module support.
8715 +              Removed multi-mount code.
8716 +              Removed compatibility macros: VFS has changed too much.
8717 +              Work sponsored by SGI.
8718 +  v0.98
8719 +    20000614   Richard Gooch <rgooch@atnf.csiro.au>
8720 +              Merged devfs inode into devfs entry.
8721 +              Work sponsored by SGI.
8722 +  v0.99
8723 +    20000619   Richard Gooch <rgooch@atnf.csiro.au>
8724 +              Removed dead code in <devfs_register> which used to call
8725 +              <free_dentries>.
8726 +              Work sponsored by SGI.
8727 +  v0.100
8728 +    20000621   Richard Gooch <rgooch@atnf.csiro.au>
8729 +              Changed interface to <devfs_register>.
8730 +              Work sponsored by SGI.
8731 +  v0.101
8732 +    20000622   Richard Gooch <rgooch@atnf.csiro.au>
8733 +              Simplified interface to <devfs_mk_symlink> and <devfs_mk_dir>.
8734 +              Simplified interface to <devfs_find_handle>.
8735 +              Work sponsored by SGI.
8736 +  v0.102
8737 +    20010519   Richard Gooch <rgooch@atnf.csiro.au>
8738 +              Ensure <devfs_generate_path> terminates string for root entry.
8739 +              Exported <devfs_get_name> to modules.
8740 +    20010520   Richard Gooch <rgooch@atnf.csiro.au>
8741 +              Make <devfs_mk_symlink> send events to devfsd.
8742 +              Cleaned up option processing in <devfs_setup>.
8743 +    20010521   Richard Gooch <rgooch@atnf.csiro.au>
8744 +              Fixed bugs in handling symlinks: could leak or cause Oops.
8745 +    20010522   Richard Gooch <rgooch@atnf.csiro.au>
8746 +              Cleaned up directory handling by separating fops.
8747 +  v0.103
8748 +    20010601   Richard Gooch <rgooch@atnf.csiro.au>
8749 +              Fixed handling of inverted options in <devfs_setup>.
8750 +  v0.104
8751 +    20010604   Richard Gooch <rgooch@atnf.csiro.au>
8752 +              Adjusted <try_modload> to account for <devfs_generate_path> fix.
8753 +  v0.105
8754 +    20010617   Richard Gooch <rgooch@atnf.csiro.au>
8755 +              Answered question posed by Al Viro and removed his comments.
8756 +              Moved setting of registered flag after other fields are changed.
8757 +              Fixed race between <devfsd_close> and <devfsd_notify_one>.
8758 +              Global VFS changes added bogus BKL to <devfsd_close>: removed.
8759 +              Widened locking in <devfs_readlink> and <devfs_follow_link>.
8760 +              Replaced <devfsd_read> stack usage with <devfsd_ioctl> kmalloc.
8761 +              Simplified locking in <devfsd_ioctl> and fixed memory leak.
8762 +  v0.106
8763 +    20010709   Richard Gooch <rgooch@atnf.csiro.au>
8764 +              Removed broken devnum allocation and use <devfs_alloc_devnum>.
8765 +              Fixed old devnum leak by calling new <devfs_dealloc_devnum>.
8766 +  v0.107
8767 +    20010712   Richard Gooch <rgooch@atnf.csiro.au>
8768 +              Fixed bug in <devfs_setup> which could hang boot process.
8769 +  v0.108
8770 +    20010730   Richard Gooch <rgooch@atnf.csiro.au>
8771 +              Added DEVFSD_NOTIFY_DELETE event.
8772 +    20010801   Richard Gooch <rgooch@atnf.csiro.au>
8773 +              Removed #include <asm/segment.h>.
8774 +  v0.109
8775 +    20010807   Richard Gooch <rgooch@atnf.csiro.au>
8776 +              Fixed inode table races by removing it and using
8777 +              inode->u.generic_ip instead.
8778 +              Moved <devfs_read_inode> into <get_vfs_inode>.
8779 +              Moved <devfs_write_inode> into <devfs_notify_change>.
8780 +  v0.110
8781 +    20010808   Richard Gooch <rgooch@atnf.csiro.au>
8782 +              Fixed race in <devfs_do_symlink> for uni-processor.
8783 +  v0.111
8784 +    20010818   Richard Gooch <rgooch@atnf.csiro.au>
8785 +              Removed remnant of multi-mount support in <devfs_mknod>.
8786 +               Removed unused DEVFS_FL_SHOW_UNREG flag.
8787 +  v0.112
8788 +    20010820   Richard Gooch <rgooch@atnf.csiro.au>
8789 +              Removed nlink field from struct devfs_inode.
8790 +  v0.113
8791 +    20010823   Richard Gooch <rgooch@atnf.csiro.au>
8792 +              Replaced BKL with global rwsem to protect symlink data (quick
8793 +              and dirty hack).
8794 +  v0.114
8795 +    20010827   Richard Gooch <rgooch@atnf.csiro.au>
8796 +              Replaced global rwsem for symlink with per-link refcount.
8797 +  v0.115
8798 +    20010919   Richard Gooch <rgooch@atnf.csiro.au>
8799 +              Set inode->i_mapping->a_ops for block nodes in <get_vfs_inode>.
8800 +  v0.116
8801 +    20011008   Richard Gooch <rgooch@atnf.csiro.au>
8802 +              Fixed overrun in <devfs_link> by removing function (not needed).
8803 +    20011009   Richard Gooch <rgooch@atnf.csiro.au>
8804 +              Fixed buffer underrun in <try_modload>.
8805 +    20011029   Richard Gooch <rgooch@atnf.csiro.au>
8806 +              Fixed race in <devfsd_ioctl> when setting event mask.
8807 +    20011114   Richard Gooch <rgooch@atnf.csiro.au>
8808 +              First release of new locking code.
8809 +  v1.0
8810 +    20011117   Richard Gooch <rgooch@atnf.csiro.au>
8811 +              Discard temporary buffer, now use "%s" for dentry names.
8812 +    20011118   Richard Gooch <rgooch@atnf.csiro.au>
8813 +              Don't generate path in <try_modload>: use fake entry instead.
8814 +              Use "existing" directory in <_devfs_make_parent_for_leaf>.
8815 +    20011122   Richard Gooch <rgooch@atnf.csiro.au>
8816 +              Use slab cache rather than fixed buffer for devfsd events.
8817 +  v1.1
8818 +    20011125   Richard Gooch <rgooch@atnf.csiro.au>
8819 +              Send DEVFSD_NOTIFY_REGISTERED events in <devfs_mk_dir>.
8820 +    20011127   Richard Gooch <rgooch@atnf.csiro.au>
8821 +              Fixed locking bug in <devfs_d_revalidate_wait> due to typo.
8822 +              Do not send CREATE, CHANGE, ASYNC_OPEN or DELETE events from
8823 +              devfsd or children.
8824 +  v1.2
8825 +    20011202   Richard Gooch <rgooch@atnf.csiro.au>
8826 +              Fixed bug in <devfsd_read>: was dereferencing freed pointer.
8827 +  v1.3
8828 +    20011203   Richard Gooch <rgooch@atnf.csiro.au>
8829 +              Fixed bug in <devfsd_close>: was dereferencing freed pointer.
8830 +              Added process group check for devfsd privileges.
8831 +  v1.4
8832 +    20011204   Richard Gooch <rgooch@atnf.csiro.au>
8833 +              Use SLAB_ATOMIC in <devfsd_notify_de> from <devfs_d_delete>.
8834 +  v1.5
8835 +    20011211   Richard Gooch <rgooch@atnf.csiro.au>
8836 +              Return old entry in <devfs_mk_dir> for 2.4.x kernels.
8837 +    20011212   Richard Gooch <rgooch@atnf.csiro.au>
8838 +              Increment refcount on module in <check_disc_changed>.
8839 +    20011215   Richard Gooch <rgooch@atnf.csiro.au>
8840 +              Created <devfs_get_handle> and exported <devfs_put>.
8841 +              Increment refcount on module in <devfs_get_ops>.
8842 +              Created <devfs_put_ops>.
8843 +  v1.6
8844 +    20011216   Richard Gooch <rgooch@atnf.csiro.au>
8845 +              Added poisoning to <devfs_put>.
8846 +              Improved debugging messages.
8847 +  v1.7
8848 +    20011221   Richard Gooch <rgooch@atnf.csiro.au>
8849 +              Corrected (made useful) debugging message in <unregister>.
8850 +              Moved <kmem_cache_create> in <mount_devfs_fs> to <init_devfs_fs>
8851 +    20011224   Richard Gooch <rgooch@atnf.csiro.au>
8852 +              Added magic number to guard against scribbling drivers.
8853 +    20011226   Richard Gooch <rgooch@atnf.csiro.au>
8854 +              Only return old entry in <devfs_mk_dir> if a directory.
8855 +              Defined macros for error and debug messages.
8856 +  v1.8
8857 +    20020113   Richard Gooch <rgooch@atnf.csiro.au>
8858 +              Fixed (rare, old) race in <devfs_lookup>.
8859 +  v1.9
8860 +    20020120   Richard Gooch <rgooch@atnf.csiro.au>
8861 +              Fixed deadlock bug in <devfs_d_revalidate_wait>.
8862 +              Tag VFS deletable in <devfs_mk_symlink> if handle ignored.
8863 +  v1.10
8864 +    20020129   Richard Gooch <rgooch@atnf.csiro.au>
8865 +              Added KERN_* to remaining messages.
8866 +              Cleaned up declaration of <stat_read>.
8867 +  v1.11
8868 +    20020219   Richard Gooch <rgooch@atnf.csiro.au>
8869 +              Changed <devfs_rmdir> to allow later additions if not yet empty.
8870 +  v1.12
8871 +    20020406   Richard Gooch <rgooch@atnf.csiro.au>
8872 +              Removed silently introduced calls to lock_kernel() and
8873 +              unlock_kernel() due to recent VFS locking changes. BKL isn't
8874 +              required in devfs.
8875 +  v1.13
8876 +    20020428   Richard Gooch <rgooch@atnf.csiro.au>
8877 +              Removed 2.4.x compatibility code.
8878 +  v1.14
8879 +    20020510   Richard Gooch <rgooch@atnf.csiro.au>
8880 +              Added BKL to <devfs_open> because drivers still need it.
8881 +  v1.15
8882 +    20020512   Richard Gooch <rgooch@atnf.csiro.au>
8883 +              Protected <scan_dir_for_removable> and <get_removable_partition>
8884 +              from changing directory contents.
8885 +  v1.16
8886 +    20020514   Richard Gooch <rgooch@atnf.csiro.au>
8887 +              Minor cleanup of <scan_dir_for_removable>.
8888 +  v1.17
8889 +    20020721   Richard Gooch <rgooch@atnf.csiro.au>
8890 +              Switched to ISO C structure field initialisers.
8891 +              Switch to set_current_state() and move before add_wait_queue().
8892 +    20020722   Richard Gooch <rgooch@atnf.csiro.au>
8893 +              Fixed devfs entry leak in <devfs_readdir> when *readdir fails.
8894 +  v1.18
8895 +    20020725   Richard Gooch <rgooch@atnf.csiro.au>
8896 +              Created <devfs_find_and_unregister>.
8897 +  v1.19
8898 +    20020728   Richard Gooch <rgooch@atnf.csiro.au>
8899 +              Removed deprecated <devfs_find_handle>.
8900 +  v1.20
8901 +    20020820   Richard Gooch <rgooch@atnf.csiro.au>
8902 +              Fixed module unload race in <devfs_open>.
8903 +  v1.21
8904 +    20021013   Richard Gooch <rgooch@atnf.csiro.au>
8905 +              Removed DEVFS_ FL_AUTO_OWNER.
8906 +              Switched lingering structure field initialiser to ISO C.
8907 +              Added locking when updating FCB flags.
8908 +  v1.22
8909 +*/
8910 +#include <linux/types.h>
8911 +#include <linux/errno.h>
8912 +#include <linux/time.h>
8913 +#include <linux/tty.h>
8914 +#include <linux/timer.h>
8915 +#include <linux/autoconf.h>
8916 +#include <linux/kernel.h>
8917 +#include <linux/wait.h>
8918 +#include <linux/string.h>
8919 +#include <linux/slab.h>
8920 +#include <linux/ioport.h>
8921 +#include <linux/delay.h>
8922 +#include <linux/ctype.h>
8923 +#include <linux/mm.h>
8924 +#include <linux/module.h>
8925 +#include <linux/init.h>
8926 +#include <linux/devfs_fs.h>
8927 +#include <linux/devfs_fs_kernel.h>
8928 +#include <linux/smp_lock.h>
8929 +#include <linux/smp.h>
8930 +#include <linux/rwsem.h>
8931 +#include <linux/sched.h>
8932 +#include <linux/namei.h>
8933 +#include <linux/bitops.h>
8934 +
8935 +#include <asm/uaccess.h>
8936 +#include <asm/io.h>
8937 +#include <asm/processor.h>
8938 +#include <asm/system.h>
8939 +#include <asm/pgtable.h>
8940 +#include <asm/atomic.h>
8941 +
8942 +#define DEVFS_VERSION            "2004-01-31"
8943 +
8944 +#define DEVFS_NAME "devfs"
8945 +
8946 +#define FIRST_INODE 1
8947 +
8948 +#define STRING_LENGTH 256
8949 +#define FAKE_BLOCK_SIZE 1024
8950 +#define POISON_PTR ( *(void **) poison_array )
8951 +#define MAGIC_VALUE 0x327db823
8952 +
8953 +#ifndef TRUE
8954 +#  define TRUE 1
8955 +#  define FALSE 0
8956 +#endif
8957 +
8958 +#define MODE_DIR (S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO)
8959 +
8960 +#define DEBUG_NONE         0x0000000
8961 +#define DEBUG_MODULE_LOAD  0x0000001
8962 +#define DEBUG_REGISTER     0x0000002
8963 +#define DEBUG_UNREGISTER   0x0000004
8964 +#define DEBUG_FREE         0x0000008
8965 +#define DEBUG_SET_FLAGS    0x0000010
8966 +#define DEBUG_S_READ       0x0000100   /*  Break  */
8967 +#define DEBUG_I_LOOKUP     0x0001000   /*  Break  */
8968 +#define DEBUG_I_CREATE     0x0002000
8969 +#define DEBUG_I_GET        0x0004000
8970 +#define DEBUG_I_CHANGE     0x0008000
8971 +#define DEBUG_I_UNLINK     0x0010000
8972 +#define DEBUG_I_RLINK      0x0020000
8973 +#define DEBUG_I_FLINK      0x0040000
8974 +#define DEBUG_I_MKNOD      0x0080000
8975 +#define DEBUG_F_READDIR    0x0100000   /*  Break  */
8976 +#define DEBUG_D_DELETE     0x1000000   /*  Break  */
8977 +#define DEBUG_D_RELEASE    0x2000000
8978 +#define DEBUG_D_IPUT       0x4000000
8979 +#define DEBUG_ALL          0xfffffff
8980 +#define DEBUG_DISABLED     DEBUG_NONE
8981 +
8982 +#define OPTION_NONE             0x00
8983 +#define OPTION_MOUNT            0x01
8984 +
8985 +#define PRINTK(format, args...) \
8986 +   {printk (KERN_ERR "%s" format, __FUNCTION__ , ## args);}
8987 +
8988 +#define OOPS(format, args...) \
8989 +   {printk (KERN_CRIT "%s" format, __FUNCTION__ , ## args); \
8990 +    printk ("Forcing Oops\n"); \
8991 +    BUG();}
8992 +
8993 +#ifdef CONFIG_DEVFS_DEBUG
8994 +#  define VERIFY_ENTRY(de) \
8995 +   {if ((de) && (de)->magic_number != MAGIC_VALUE) \
8996 +        OOPS ("(%p): bad magic value: %x\n", (de), (de)->magic_number);}
8997 +#  define WRITE_ENTRY_MAGIC(de,magic) (de)->magic_number = (magic)
8998 +#  define DPRINTK(flag, format, args...) \
8999 +   {if (devfs_debug & flag) \
9000 +       printk (KERN_INFO "%s" format, __FUNCTION__ , ## args);}
9001 +#else
9002 +#  define VERIFY_ENTRY(de)
9003 +#  define WRITE_ENTRY_MAGIC(de,magic)
9004 +#  define DPRINTK(flag, format, args...)
9005 +#endif
9006 +
9007 +typedef struct devfs_entry *devfs_handle_t;
9008 +
9009 +struct directory_type {
9010 +       rwlock_t lock;          /*  Lock for searching(R)/updating(W)   */
9011 +       struct devfs_entry *first;
9012 +       struct devfs_entry *last;
9013 +       unsigned char no_more_additions:1;
9014 +};
9015 +
9016 +struct symlink_type {
9017 +       unsigned int length;    /*  Not including the NULL-termimator       */
9018 +       char *linkname;         /*  This is NULL-terminated                 */
9019 +};
9020 +
9021 +struct devfs_inode {           /*  This structure is for "persistent" inode storage  */
9022 +       struct dentry *dentry;
9023 +       struct timespec atime;
9024 +       struct timespec mtime;
9025 +       struct timespec ctime;
9026 +       unsigned int ino;       /*  Inode number as seen in the VFS         */
9027 +       uid_t uid;
9028 +       gid_t gid;
9029 +};
9030 +
9031 +struct devfs_entry {
9032 +#ifdef CONFIG_DEVFS_DEBUG
9033 +       unsigned int magic_number;
9034 +#endif
9035 +       void *info;
9036 +       atomic_t refcount;      /*  When this drops to zero, it's unused    */
9037 +       union {
9038 +               struct directory_type dir;
9039 +               dev_t dev;
9040 +               struct symlink_type symlink;
9041 +               const char *name;       /*  Only used for (mode == 0)               */
9042 +       } u;
9043 +       struct devfs_entry *prev;       /*  Previous entry in the parent directory  */
9044 +       struct devfs_entry *next;       /*  Next entry in the parent directory      */
9045 +       struct devfs_entry *parent;     /*  The parent directory                    */
9046 +       struct devfs_inode inode;
9047 +       umode_t mode;
9048 +       unsigned short namelen; /*  I think 64k+ filenames are a way off... */
9049 +       unsigned char vfs:1;    /*  Whether the VFS may delete the entry   */
9050 +       char name[1];           /*  This is just a dummy: the allocated array
9051 +                                  is bigger. This is NULL-terminated      */
9052 +};
9053 +
9054 +/*  The root of the device tree  */
9055 +static struct devfs_entry *root_entry;
9056 +
9057 +struct devfsd_buf_entry {
9058 +       struct devfs_entry *de; /*  The name is generated with this         */
9059 +       unsigned short type;    /*  The type of event                       */
9060 +       umode_t mode;
9061 +       uid_t uid;
9062 +       gid_t gid;
9063 +       struct devfsd_buf_entry *next;
9064 +};
9065 +
9066 +struct fs_info {               /*  This structure is for the mounted devfs  */
9067 +       struct super_block *sb;
9068 +       spinlock_t devfsd_buffer_lock;  /*  Lock when inserting/deleting events  */
9069 +       struct devfsd_buf_entry *devfsd_first_event;
9070 +       struct devfsd_buf_entry *devfsd_last_event;
9071 +       volatile int devfsd_sleeping;
9072 +       volatile struct task_struct *devfsd_task;
9073 +       volatile pid_t devfsd_pgrp;
9074 +       volatile struct file *devfsd_file;
9075 +       struct devfsd_notify_struct *devfsd_info;
9076 +       volatile unsigned long devfsd_event_mask;
9077 +       atomic_t devfsd_overrun_count;
9078 +       wait_queue_head_t devfsd_wait_queue;    /*  Wake devfsd on input       */
9079 +       wait_queue_head_t revalidate_wait_queue;        /*  Wake when devfsd sleeps    */
9080 +};
9081 +
9082 +static struct fs_info fs_info = {.devfsd_buffer_lock = SPIN_LOCK_UNLOCKED };
9083 +static kmem_cache_t *devfsd_buf_cache;
9084 +#ifdef CONFIG_DEVFS_DEBUG
9085 +static unsigned int devfs_debug_init __initdata = DEBUG_NONE;
9086 +static unsigned int devfs_debug = DEBUG_NONE;
9087 +static DEFINE_SPINLOCK(stat_lock);
9088 +static unsigned int stat_num_entries;
9089 +static unsigned int stat_num_bytes;
9090 +#endif
9091 +static unsigned char poison_array[8] =
9092 +    { 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a };
9093 +
9094 +#ifdef CONFIG_DEVFS_MOUNT
9095 +static unsigned int boot_options = OPTION_MOUNT;
9096 +#else
9097 +static unsigned int boot_options = OPTION_NONE;
9098 +#endif
9099 +
9100 +/*  Forward function declarations  */
9101 +static devfs_handle_t _devfs_walk_path(struct devfs_entry *dir,
9102 +                                      const char *name, int namelen,
9103 +                                      int traverse_symlink);
9104 +static ssize_t devfsd_read(struct file *file, char __user *buf, size_t len,
9105 +                          loff_t * ppos);
9106 +static int devfsd_ioctl(struct inode *inode, struct file *file,
9107 +                       unsigned int cmd, unsigned long arg);
9108 +static int devfsd_close(struct inode *inode, struct file *file);
9109 +#ifdef CONFIG_DEVFS_DEBUG
9110 +static ssize_t stat_read(struct file *file, char __user *buf, size_t len,
9111 +                        loff_t * ppos);
9112 +static const struct file_operations stat_fops = {
9113 +       .open = nonseekable_open,
9114 +       .read = stat_read,
9115 +};
9116 +#endif
9117 +
9118 +/*  Devfs daemon file operations  */
9119 +static const struct file_operations devfsd_fops = {
9120 +       .open = nonseekable_open,
9121 +       .read = devfsd_read,
9122 +       .ioctl = devfsd_ioctl,
9123 +       .release = devfsd_close,
9124 +};
9125 +
9126 +/*  Support functions follow  */
9127 +
9128 +/**
9129 + *     devfs_get - Get a reference to a devfs entry.
9130 + *     @de:  The devfs entry.
9131 + */
9132 +
9133 +static struct devfs_entry *devfs_get(struct devfs_entry *de)
9134 +{
9135 +       VERIFY_ENTRY(de);
9136 +       if (de)
9137 +               atomic_inc(&de->refcount);
9138 +       return de;
9139 +}                              /*  End Function devfs_get  */
9140 +
9141 +/**
9142 + *     devfs_put - Put (release) a reference to a devfs entry.
9143 + *     @de:  The handle to the devfs entry.
9144 + */
9145 +
9146 +static void devfs_put(devfs_handle_t de)
9147 +{
9148 +       if (!de)
9149 +               return;
9150 +       VERIFY_ENTRY(de);
9151 +       if (de->info == POISON_PTR)
9152 +               OOPS("(%p): poisoned pointer\n", de);
9153 +       if (!atomic_dec_and_test(&de->refcount))
9154 +               return;
9155 +       if (de == root_entry)
9156 +               OOPS("(%p): root entry being freed\n", de);
9157 +       DPRINTK(DEBUG_FREE, "(%s): de: %p, parent: %p \"%s\"\n",
9158 +               de->name, de, de->parent,
9159 +               de->parent ? de->parent->name : "no parent");
9160 +       if (S_ISLNK(de->mode))
9161 +               kfree(de->u.symlink.linkname);
9162 +       WRITE_ENTRY_MAGIC(de, 0);
9163 +#ifdef CONFIG_DEVFS_DEBUG
9164 +       spin_lock(&stat_lock);
9165 +       --stat_num_entries;
9166 +       stat_num_bytes -= sizeof *de + de->namelen;
9167 +       if (S_ISLNK(de->mode))
9168 +               stat_num_bytes -= de->u.symlink.length + 1;
9169 +       spin_unlock(&stat_lock);
9170 +#endif
9171 +       de->info = POISON_PTR;
9172 +       kfree(de);
9173 +}                              /*  End Function devfs_put  */
9174 +
9175 +/**
9176 + *     _devfs_search_dir - Search for a devfs entry in a directory.
9177 + *     @dir:  The directory to search.
9178 + *     @name:  The name of the entry to search for.
9179 + *     @namelen:  The number of characters in @name.
9180 + *
9181 + *  Search for a devfs entry in a directory and returns a pointer to the entry
9182 + *   on success, else %NULL. The directory must be locked already.
9183 + *   An implicit devfs_get() is performed on the returned entry.
9184 + */
9185 +
9186 +static struct devfs_entry *_devfs_search_dir(struct devfs_entry *dir,
9187 +                                            const char *name,
9188 +                                            unsigned int namelen)
9189 +{
9190 +       struct devfs_entry *curr;
9191 +
9192 +       if (!S_ISDIR(dir->mode)) {
9193 +               PRINTK("(%s): not a directory\n", dir->name);
9194 +               return NULL;
9195 +       }
9196 +       for (curr = dir->u.dir.first; curr != NULL; curr = curr->next) {
9197 +               if (curr->namelen != namelen)
9198 +                       continue;
9199 +               if (memcmp(curr->name, name, namelen) == 0)
9200 +                       break;
9201 +               /*  Not found: try the next one  */
9202 +       }
9203 +       return devfs_get(curr);
9204 +}                              /*  End Function _devfs_search_dir  */
9205 +
9206 +/**
9207 + *     _devfs_alloc_entry - Allocate a devfs entry.
9208 + *     @name:     the name of the entry
9209 + *     @namelen:  the number of characters in @name
9210 + *      @mode:     the mode for the entry
9211 + *
9212 + *  Allocate a devfs entry and returns a pointer to the entry on success, else
9213 + *   %NULL.
9214 + */
9215 +
9216 +static struct devfs_entry *_devfs_alloc_entry(const char *name,
9217 +                                             unsigned int namelen,
9218 +                                             umode_t mode)
9219 +{
9220 +       struct devfs_entry *new;
9221 +       static unsigned long inode_counter = FIRST_INODE;
9222 +       static DEFINE_SPINLOCK(counter_lock);
9223 +
9224 +       if (name && (namelen < 1))
9225 +               namelen = strlen(name);
9226 +       if ((new = kmalloc(sizeof *new + namelen, GFP_KERNEL)) == NULL)
9227 +               return NULL;
9228 +       memset(new, 0, sizeof *new + namelen);  /*  Will set '\0' on name  */
9229 +       new->mode = mode;
9230 +       if (S_ISDIR(mode))
9231 +               rwlock_init(&new->u.dir.lock);
9232 +       atomic_set(&new->refcount, 1);
9233 +       spin_lock(&counter_lock);
9234 +       new->inode.ino = inode_counter++;
9235 +       spin_unlock(&counter_lock);
9236 +       if (name)
9237 +               memcpy(new->name, name, namelen);
9238 +       new->namelen = namelen;
9239 +       WRITE_ENTRY_MAGIC(new, MAGIC_VALUE);
9240 +#ifdef CONFIG_DEVFS_DEBUG
9241 +       spin_lock(&stat_lock);
9242 +       ++stat_num_entries;
9243 +       stat_num_bytes += sizeof *new + namelen;
9244 +       spin_unlock(&stat_lock);
9245 +#endif
9246 +       return new;
9247 +}                              /*  End Function _devfs_alloc_entry  */
9248 +
9249 +/**
9250 + *     _devfs_append_entry - Append a devfs entry to a directory's child list.
9251 + *     @dir:  The directory to add to.
9252 + *     @de:  The devfs entry to append.
9253 + *     @old_de: If an existing entry exists, it will be written here. This may
9254 + *              be %NULL. An implicit devfs_get() is performed on this entry.
9255 + *
9256 + *  Append a devfs entry to a directory's list of children, checking first to
9257 + *   see if an entry of the same name exists. The directory will be locked.
9258 + *   The value 0 is returned on success, else a negative error code.
9259 + *   On failure, an implicit devfs_put() is performed on %de.
9260 + */
9261 +
9262 +static int _devfs_append_entry(devfs_handle_t dir, devfs_handle_t de,
9263 +                              devfs_handle_t * old_de)
9264 +{
9265 +       int retval;
9266 +
9267 +       if (old_de)
9268 +               *old_de = NULL;
9269 +       if (!S_ISDIR(dir->mode)) {
9270 +               PRINTK("(%s): dir: \"%s\" is not a directory\n", de->name,
9271 +                      dir->name);
9272 +               devfs_put(de);
9273 +               return -ENOTDIR;
9274 +       }
9275 +       write_lock(&dir->u.dir.lock);
9276 +       if (dir->u.dir.no_more_additions)
9277 +               retval = -ENOENT;
9278 +       else {
9279 +               struct devfs_entry *old;
9280 +
9281 +               old = _devfs_search_dir(dir, de->name, de->namelen);
9282 +               if (old_de)
9283 +                       *old_de = old;
9284 +               else
9285 +                       devfs_put(old);
9286 +               if (old == NULL) {
9287 +                       de->parent = dir;
9288 +                       de->prev = dir->u.dir.last;
9289 +                       /*  Append to the directory's list of children  */
9290 +                       if (dir->u.dir.first == NULL)
9291 +                               dir->u.dir.first = de;
9292 +                       else
9293 +                               dir->u.dir.last->next = de;
9294 +                       dir->u.dir.last = de;
9295 +                       retval = 0;
9296 +               } else
9297 +                       retval = -EEXIST;
9298 +       }
9299 +       write_unlock(&dir->u.dir.lock);
9300 +       if (retval)
9301 +               devfs_put(de);
9302 +       return retval;
9303 +}                              /*  End Function _devfs_append_entry  */
9304 +
9305 +/**
9306 + *     _devfs_get_root_entry - Get the root devfs entry.
9307 + *
9308 + *     Returns the root devfs entry on success, else %NULL.
9309 + *
9310 + *     TODO it must be called asynchronously due to the fact
9311 + *     that devfs is initialized relatively late. Proper way
9312 + *     is to remove module_init from init_devfs_fs and manually
9313 + *     call it early enough during system init
9314 + */
9315 +
9316 +static struct devfs_entry *_devfs_get_root_entry(void)
9317 +{
9318 +       struct devfs_entry *new;
9319 +       static DEFINE_SPINLOCK(root_lock);
9320 +
9321 +       if (root_entry)
9322 +               return root_entry;
9323 +
9324 +       new = _devfs_alloc_entry(NULL, 0, MODE_DIR);
9325 +       if (new == NULL)
9326 +               return NULL;
9327 +
9328 +       spin_lock(&root_lock);
9329 +       if (root_entry) {
9330 +               spin_unlock(&root_lock);
9331 +               devfs_put(new);
9332 +               return root_entry;
9333 +       }
9334 +       root_entry = new;
9335 +       spin_unlock(&root_lock);
9336 +
9337 +       return root_entry;
9338 +}                              /*  End Function _devfs_get_root_entry  */
9339 +
9340 +/**
9341 + *     _devfs_descend - Descend down a tree using the next component name.
9342 + *     @dir:  The directory to search.
9343 + *     @name:  The component name to search for.
9344 + *     @namelen:  The length of %name.
9345 + *     @next_pos:  The position of the next '/' or '\0' is written here.
9346 + *
9347 + *  Descend into a directory, searching for a component. This function forms
9348 + *   the core of a tree-walking algorithm. The directory will be locked.
9349 + *   The devfs entry corresponding to the component is returned. If there is
9350 + *   no matching entry, %NULL is returned.
9351 + *   An implicit devfs_get() is performed on the returned entry.
9352 + */
9353 +
9354 +static struct devfs_entry *_devfs_descend(struct devfs_entry *dir,
9355 +                                         const char *name, int namelen,
9356 +                                         int *next_pos)
9357 +{
9358 +       const char *stop, *ptr;
9359 +       struct devfs_entry *entry;
9360 +
9361 +       if ((namelen >= 3) && (strncmp(name, "../", 3) == 0)) { /*  Special-case going to parent directory  */
9362 +               *next_pos = 3;
9363 +               return devfs_get(dir->parent);
9364 +       }
9365 +       stop = name + namelen;
9366 +       /*  Search for a possible '/'  */
9367 +       for (ptr = name; (ptr < stop) && (*ptr != '/'); ++ptr) ;
9368 +       *next_pos = ptr - name;
9369 +       read_lock(&dir->u.dir.lock);
9370 +       entry = _devfs_search_dir(dir, name, *next_pos);
9371 +       read_unlock(&dir->u.dir.lock);
9372 +       return entry;
9373 +}                              /*  End Function _devfs_descend  */
9374 +
9375 +static devfs_handle_t _devfs_make_parent_for_leaf(struct devfs_entry *dir,
9376 +                                                 const char *name,
9377 +                                                 int namelen, int *leaf_pos)
9378 +{
9379 +       int next_pos = 0;
9380 +
9381 +       if (dir == NULL)
9382 +               dir = _devfs_get_root_entry();
9383 +       if (dir == NULL)
9384 +               return NULL;
9385 +       devfs_get(dir);
9386 +       /*  Search for possible trailing component and ignore it  */
9387 +       for (--namelen; (namelen > 0) && (name[namelen] != '/'); --namelen) ;
9388 +       *leaf_pos = (name[namelen] == '/') ? (namelen + 1) : 0;
9389 +       for (; namelen > 0; name += next_pos, namelen -= next_pos) {
9390 +               struct devfs_entry *de, *old = NULL;
9391 +
9392 +               if ((de =
9393 +                    _devfs_descend(dir, name, namelen, &next_pos)) == NULL) {
9394 +                       de = _devfs_alloc_entry(name, next_pos, MODE_DIR);
9395 +                       devfs_get(de);
9396 +                       if (!de || _devfs_append_entry(dir, de, &old)) {
9397 +                               devfs_put(de);
9398 +                               if (!old || !S_ISDIR(old->mode)) {
9399 +                                       devfs_put(old);
9400 +                                       devfs_put(dir);
9401 +                                       return NULL;
9402 +                               }
9403 +                               de = old;       /*  Use the existing directory  */
9404 +                       }
9405 +               }
9406 +               if (de == dir->parent) {
9407 +                       devfs_put(dir);
9408 +                       devfs_put(de);
9409 +                       return NULL;
9410 +               }
9411 +               devfs_put(dir);
9412 +               dir = de;
9413 +               if (name[next_pos] == '/')
9414 +                       ++next_pos;
9415 +       }
9416 +       return dir;
9417 +}                              /*  End Function _devfs_make_parent_for_leaf  */
9418 +
9419 +static devfs_handle_t _devfs_prepare_leaf(devfs_handle_t * dir,
9420 +                                         const char *name, umode_t mode)
9421 +{
9422 +       int namelen, leaf_pos;
9423 +       struct devfs_entry *de;
9424 +
9425 +       namelen = strlen(name);
9426 +       if ((*dir = _devfs_make_parent_for_leaf(*dir, name, namelen,
9427 +                                               &leaf_pos)) == NULL) {
9428 +               PRINTK("(%s): could not create parent path\n", name);
9429 +               return NULL;
9430 +       }
9431 +       if ((de = _devfs_alloc_entry(name + leaf_pos, namelen - leaf_pos, mode))
9432 +           == NULL) {
9433 +               PRINTK("(%s): could not allocate entry\n", name);
9434 +               devfs_put(*dir);
9435 +               return NULL;
9436 +       }
9437 +       return de;
9438 +}                              /*  End Function _devfs_prepare_leaf  */
9439 +
9440 +static devfs_handle_t _devfs_walk_path(struct devfs_entry *dir,
9441 +                                      const char *name, int namelen,
9442 +                                      int traverse_symlink)
9443 +{
9444 +       int next_pos = 0;
9445 +
9446 +       if (dir == NULL)
9447 +               dir = _devfs_get_root_entry();
9448 +       if (dir == NULL)
9449 +               return NULL;
9450 +       devfs_get(dir);
9451 +       for (; namelen > 0; name += next_pos, namelen -= next_pos) {
9452 +               struct devfs_entry *de, *link;
9453 +
9454 +               if (!S_ISDIR(dir->mode)) {
9455 +                       devfs_put(dir);
9456 +                       return NULL;
9457 +               }
9458 +
9459 +               if ((de =
9460 +                    _devfs_descend(dir, name, namelen, &next_pos)) == NULL) {
9461 +                       devfs_put(dir);
9462 +                       return NULL;
9463 +               }
9464 +               if (S_ISLNK(de->mode) && traverse_symlink) {    /*  Need to follow the link: this is a stack chomper  */
9465 +                       /* FIXME what if it puts outside of mounted tree? */
9466 +                       link = _devfs_walk_path(dir, de->u.symlink.linkname,
9467 +                                               de->u.symlink.length, TRUE);
9468 +                       devfs_put(de);
9469 +                       if (!link) {
9470 +                               devfs_put(dir);
9471 +                               return NULL;
9472 +                       }
9473 +                       de = link;
9474 +               }
9475 +               devfs_put(dir);
9476 +               dir = de;
9477 +               if (name[next_pos] == '/')
9478 +                       ++next_pos;
9479 +       }
9480 +       return dir;
9481 +}                              /*  End Function _devfs_walk_path  */
9482 +
9483 +/**
9484 + *     _devfs_find_entry - Find a devfs entry.
9485 + *     @dir: The handle to the parent devfs directory entry. If this is %NULL the
9486 + *             name is relative to the root of the devfs.
9487 + *     @name: The name of the entry. This may be %NULL.
9488 + *     @traverse_symlink: If %TRUE then symbolic links are traversed.
9489 + *
9490 + *     Returns the devfs_entry pointer on success, else %NULL. An implicit
9491 + *     devfs_get() is performed.
9492 + */
9493 +
9494 +static struct devfs_entry *_devfs_find_entry(devfs_handle_t dir,
9495 +                                            const char *name,
9496 +                                            int traverse_symlink)
9497 +{
9498 +       unsigned int namelen = strlen(name);
9499 +
9500 +       if (name[0] == '/') {
9501 +               /*  Skip leading pathname component  */
9502 +               if (namelen < 2) {
9503 +                       PRINTK("(%s): too short\n", name);
9504 +                       return NULL;
9505 +               }
9506 +               for (++name, --namelen; (*name != '/') && (namelen > 0);
9507 +                    ++name, --namelen) ;
9508 +               if (namelen < 2) {
9509 +                       PRINTK("(%s): too short\n", name);
9510 +                       return NULL;
9511 +               }
9512 +               ++name;
9513 +               --namelen;
9514 +       }
9515 +       return _devfs_walk_path(dir, name, namelen, traverse_symlink);
9516 +}                              /*  End Function _devfs_find_entry  */
9517 +
9518 +static struct devfs_entry *get_devfs_entry_from_vfs_inode(struct inode *inode)
9519 +{
9520 +       if (inode == NULL)
9521 +               return NULL;
9522 +       VERIFY_ENTRY((struct devfs_entry *)inode->i_private);
9523 +       return inode->i_private;
9524 +}                              /*  End Function get_devfs_entry_from_vfs_inode  */
9525 +
9526 +/**
9527 + *     free_dentry - Free the dentry for a device entry and invalidate inode.
9528 + *     @de: The entry.
9529 + *
9530 + *     This must only be called after the entry has been unhooked from its
9531 + *      parent directory.
9532 + */
9533 +
9534 +static void free_dentry(struct devfs_entry *de)
9535 +{
9536 +       struct dentry *dentry = de->inode.dentry;
9537 +
9538 +       if (!dentry)
9539 +               return;
9540 +       spin_lock(&dcache_lock);
9541 +       dget_locked(dentry);
9542 +       spin_unlock(&dcache_lock);
9543 +       /*  Forcefully remove the inode  */
9544 +       if (dentry->d_inode != NULL)
9545 +               dentry->d_inode->i_nlink = 0;
9546 +       d_drop(dentry);
9547 +       dput(dentry);
9548 +}                              /*  End Function free_dentry  */
9549 +
9550 +/**
9551 + *     is_devfsd_or_child - Test if the current process is devfsd or one of its children.
9552 + *     @fs_info: The filesystem information.
9553 + *
9554 + *     Returns %TRUE if devfsd or child, else %FALSE.
9555 + */
9556 +
9557 +static int is_devfsd_or_child(struct fs_info *fs_info)
9558 +{
9559 +       struct task_struct *p = current;
9560 +
9561 +       if (p == fs_info->devfsd_task)
9562 +               return (TRUE);
9563 +       if (process_group(p) == fs_info->devfsd_pgrp)
9564 +               return (TRUE);
9565 +       read_lock(&tasklist_lock);
9566 +       for (; p != &init_task; p = p->real_parent) {
9567 +               if (p == fs_info->devfsd_task) {
9568 +                       read_unlock(&tasklist_lock);
9569 +                       return (TRUE);
9570 +               }
9571 +       }
9572 +       read_unlock(&tasklist_lock);
9573 +       return (FALSE);
9574 +}                              /*  End Function is_devfsd_or_child  */
9575 +
9576 +/**
9577 + *     devfsd_queue_empty - Test if devfsd has work pending in its event queue.
9578 + *     @fs_info: The filesystem information.
9579 + *
9580 + *     Returns %TRUE if the queue is empty, else %FALSE.
9581 + */
9582 +
9583 +static inline int devfsd_queue_empty(struct fs_info *fs_info)
9584 +{
9585 +       return (fs_info->devfsd_last_event) ? FALSE : TRUE;
9586 +}                              /*  End Function devfsd_queue_empty  */
9587 +
9588 +/**
9589 + *     wait_for_devfsd_finished - Wait for devfsd to finish processing its event queue.
9590 + *     @fs_info: The filesystem information.
9591 + *
9592 + *     Returns %TRUE if no more waiting will be required, else %FALSE.
9593 + */
9594 +
9595 +static int wait_for_devfsd_finished(struct fs_info *fs_info)
9596 +{
9597 +       DECLARE_WAITQUEUE(wait, current);
9598 +
9599 +       if (fs_info->devfsd_task == NULL)
9600 +               return (TRUE);
9601 +       if (devfsd_queue_empty(fs_info) && fs_info->devfsd_sleeping)
9602 +               return TRUE;
9603 +       if (is_devfsd_or_child(fs_info))
9604 +               return (FALSE);
9605 +       set_current_state(TASK_UNINTERRUPTIBLE);
9606 +       add_wait_queue(&fs_info->revalidate_wait_queue, &wait);
9607 +       if (!devfsd_queue_empty(fs_info) || !fs_info->devfsd_sleeping)
9608 +               if (fs_info->devfsd_task)
9609 +                       schedule();
9610 +       remove_wait_queue(&fs_info->revalidate_wait_queue, &wait);
9611 +       __set_current_state(TASK_RUNNING);
9612 +       return (TRUE);
9613 +}                              /*  End Function wait_for_devfsd_finished  */
9614 +
9615 +/**
9616 + *     devfsd_notify_de - Notify the devfsd daemon of a change.
9617 + *     @de: The devfs entry that has changed. This and all parent entries will
9618 + *            have their reference counts incremented if the event was queued.
9619 + *     @type: The type of change.
9620 + *     @mode: The mode of the entry.
9621 + *     @uid: The user ID.
9622 + *     @gid: The group ID.
9623 + *     @fs_info: The filesystem info.
9624 + *
9625 + *     Returns %TRUE if an event was queued and devfsd woken up, else %FALSE.
9626 + */
9627 +
9628 +static int devfsd_notify_de(struct devfs_entry *de,
9629 +                           unsigned short type, umode_t mode,
9630 +                           uid_t uid, gid_t gid, struct fs_info *fs_info)
9631 +{
9632 +       struct devfsd_buf_entry *entry;
9633 +       struct devfs_entry *curr;
9634 +
9635 +       if (!(fs_info->devfsd_event_mask & (1 << type)))
9636 +               return (FALSE);
9637 +       if ((entry = kmem_cache_alloc(devfsd_buf_cache, SLAB_KERNEL)) == NULL) {
9638 +               atomic_inc(&fs_info->devfsd_overrun_count);
9639 +               return (FALSE);
9640 +       }
9641 +       for (curr = de; curr != NULL; curr = curr->parent)
9642 +               devfs_get(curr);
9643 +       entry->de = de;
9644 +       entry->type = type;
9645 +       entry->mode = mode;
9646 +       entry->uid = uid;
9647 +       entry->gid = gid;
9648 +       entry->next = NULL;
9649 +       spin_lock(&fs_info->devfsd_buffer_lock);
9650 +       if (!fs_info->devfsd_first_event)
9651 +               fs_info->devfsd_first_event = entry;
9652 +       if (fs_info->devfsd_last_event)
9653 +               fs_info->devfsd_last_event->next = entry;
9654 +       fs_info->devfsd_last_event = entry;
9655 +       spin_unlock(&fs_info->devfsd_buffer_lock);
9656 +       wake_up_interruptible(&fs_info->devfsd_wait_queue);
9657 +       return (TRUE);
9658 +}                              /*  End Function devfsd_notify_de  */
9659 +
9660 +/**
9661 + *     devfsd_notify - Notify the devfsd daemon of a change.
9662 + *     @de: The devfs entry that has changed.
9663 + *     @type: The type of change event.
9664 + *     @wait: If TRUE, the function waits for the daemon to finish processing
9665 + *             the event.
9666 + */
9667 +
9668 +static void devfsd_notify(struct devfs_entry *de, unsigned short type)
9669 +{
9670 +       devfsd_notify_de(de, type, de->mode, current->euid,
9671 +                        current->egid, &fs_info);
9672 +}
9673 +
9674 +static int devfs_mk_dev(dev_t dev, umode_t mode, const char *fmt, va_list args)
9675 +{
9676 +       struct devfs_entry *dir = NULL, *de;
9677 +       char buf[64];
9678 +       int error, n;
9679 +
9680 +       n = vsnprintf(buf, sizeof(buf), fmt, args);
9681 +       if (n >= sizeof(buf) || !buf[0]) {
9682 +               printk(KERN_WARNING "%s: invalid format string %s\n",
9683 +                      __FUNCTION__, fmt);
9684 +               return -EINVAL;
9685 +       }
9686 +
9687 +       de = _devfs_prepare_leaf(&dir, buf, mode);
9688 +       if (!de) {
9689 +               printk(KERN_WARNING "%s: could not prepare leaf for %s\n",
9690 +                      __FUNCTION__, buf);
9691 +               return -ENOMEM; /* could be more accurate... */
9692 +       }
9693 +
9694 +       de->u.dev = dev;
9695 +
9696 +       error = _devfs_append_entry(dir, de, NULL);
9697 +       if (error) {
9698 +               printk(KERN_WARNING "%s: could not append to parent for %s\n",
9699 +                      __FUNCTION__, buf);
9700 +               goto out;
9701 +       }
9702 +
9703 +       devfsd_notify(de, DEVFSD_NOTIFY_REGISTERED);
9704 +      out:
9705 +       devfs_put(dir);
9706 +       return error;
9707 +}
9708 +
9709 +int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...)
9710 +{
9711 +       va_list args;
9712 +
9713 +       if (!S_ISBLK(mode)) {
9714 +               printk(KERN_WARNING "%s: invalide mode (%u) for %s\n",
9715 +                      __FUNCTION__, mode, fmt);
9716 +               return -EINVAL;
9717 +       }
9718 +
9719 +       va_start(args, fmt);
9720 +       return devfs_mk_dev(dev, mode, fmt, args);
9721 +}
9722 +
9723 +EXPORT_SYMBOL(devfs_mk_bdev);
9724 +
9725 +int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...)
9726 +{
9727 +       va_list args;
9728 +
9729 +       if (!S_ISCHR(mode)) {
9730 +               printk(KERN_WARNING "%s: invalide mode (%u) for %s\n",
9731 +                      __FUNCTION__, mode, fmt);
9732 +               return -EINVAL;
9733 +       }
9734 +
9735 +       va_start(args, fmt);
9736 +       return devfs_mk_dev(dev, mode, fmt, args);
9737 +}
9738 +
9739 +EXPORT_SYMBOL(devfs_mk_cdev);
9740 +
9741 +/**
9742 + *     _devfs_unhook - Unhook a device entry from its parents list
9743 + *     @de: The entry to unhook.
9744 + *
9745 + *     Returns %TRUE if the entry was unhooked, else %FALSE if it was
9746 + *             previously unhooked.
9747 + *     The caller must have a write lock on the parent directory.
9748 + */
9749 +
9750 +static int _devfs_unhook(struct devfs_entry *de)
9751 +{
9752 +       struct devfs_entry *parent;
9753 +
9754 +       if (!de || (de->prev == de))
9755 +               return FALSE;
9756 +       parent = de->parent;
9757 +       if (de->prev == NULL)
9758 +               parent->u.dir.first = de->next;
9759 +       else
9760 +               de->prev->next = de->next;
9761 +       if (de->next == NULL)
9762 +               parent->u.dir.last = de->prev;
9763 +       else
9764 +               de->next->prev = de->prev;
9765 +       de->prev = de;          /*  Indicate we're unhooked                      */
9766 +       de->next = NULL;        /*  Force early termination for <devfs_readdir>  */
9767 +       return TRUE;
9768 +}                              /*  End Function _devfs_unhook  */
9769 +
9770 +/**
9771 + *     _devfs_unregister - Unregister a device entry from its parent.
9772 + *     @dir: The parent directory.
9773 + *     @de: The entry to unregister.
9774 + *
9775 + *     The caller must have a write lock on the parent directory, which is
9776 + *     unlocked by this function.
9777 + */
9778 +
9779 +static void _devfs_unregister(struct devfs_entry *dir, struct devfs_entry *de)
9780 +{
9781 +       int unhooked = _devfs_unhook(de);
9782 +
9783 +       write_unlock(&dir->u.dir.lock);
9784 +       if (!unhooked)
9785 +               return;
9786 +       devfs_get(dir);
9787 +       devfsd_notify(de, DEVFSD_NOTIFY_UNREGISTERED);
9788 +       free_dentry(de);
9789 +       devfs_put(dir);
9790 +       if (!S_ISDIR(de->mode))
9791 +               return;
9792 +       while (TRUE) {          /*  Recursively unregister: this is a stack chomper  */
9793 +               struct devfs_entry *child;
9794 +
9795 +               write_lock(&de->u.dir.lock);
9796 +               de->u.dir.no_more_additions = TRUE;
9797 +               child = de->u.dir.first;
9798 +               VERIFY_ENTRY(child);
9799 +               _devfs_unregister(de, child);
9800 +               if (!child)
9801 +                       break;
9802 +               DPRINTK(DEBUG_UNREGISTER, "(%s): child: %p  refcount: %d\n",
9803 +                       child->name, child, atomic_read(&child->refcount));
9804 +               devfs_put(child);
9805 +       }
9806 +}                              /*  End Function _devfs_unregister  */
9807 +
9808 +static int devfs_do_symlink(devfs_handle_t dir, const char *name,
9809 +                           const char *link, devfs_handle_t * handle)
9810 +{
9811 +       int err;
9812 +       unsigned int linklength;
9813 +       char *newlink;
9814 +       struct devfs_entry *de;
9815 +
9816 +       if (handle != NULL)
9817 +               *handle = NULL;
9818 +       if (name == NULL) {
9819 +               PRINTK("(): NULL name pointer\n");
9820 +               return -EINVAL;
9821 +       }
9822 +       if (link == NULL) {
9823 +               PRINTK("(%s): NULL link pointer\n", name);
9824 +               return -EINVAL;
9825 +       }
9826 +       linklength = strlen(link);
9827 +       if ((newlink = kmalloc(linklength + 1, GFP_KERNEL)) == NULL)
9828 +               return -ENOMEM;
9829 +       memcpy(newlink, link, linklength);
9830 +       newlink[linklength] = '\0';
9831 +       if ((de = _devfs_prepare_leaf(&dir, name, S_IFLNK | S_IRUGO | S_IXUGO))
9832 +           == NULL) {
9833 +               PRINTK("(%s): could not prepare leaf\n", name);
9834 +               kfree(newlink);
9835 +               return -ENOTDIR;
9836 +       }
9837 +       de->info = NULL;
9838 +       de->u.symlink.linkname = newlink;
9839 +       de->u.symlink.length = linklength;
9840 +       if ((err = _devfs_append_entry(dir, de, NULL)) != 0) {
9841 +               PRINTK("(%s): could not append to parent, err: %d\n", name,
9842 +                      err);
9843 +               devfs_put(dir);
9844 +               return err;
9845 +       }
9846 +       devfs_put(dir);
9847 +#ifdef CONFIG_DEVFS_DEBUG
9848 +       spin_lock(&stat_lock);
9849 +       stat_num_bytes += linklength + 1;
9850 +       spin_unlock(&stat_lock);
9851 +#endif
9852 +       if (handle != NULL)
9853 +               *handle = de;
9854 +       return 0;
9855 +}                              /*  End Function devfs_do_symlink  */
9856 +
9857 +/**
9858 + *     devfs_mk_symlink Create a symbolic link in the devfs namespace.
9859 + *     @from: The name of the entry.
9860 + *     @to: Name of the destination
9861 + *
9862 + *     Returns 0 on success, else a negative error code is returned.
9863 + */
9864 +
9865 +int devfs_mk_symlink(const char *from, const char *to)
9866 +{
9867 +       devfs_handle_t de;
9868 +       int err;
9869 +
9870 +       err = devfs_do_symlink(NULL, from, to, &de);
9871 +       if (!err) {
9872 +               de->vfs = TRUE;
9873 +               devfsd_notify(de, DEVFSD_NOTIFY_REGISTERED);
9874 +       }
9875 +
9876 +       return err;
9877 +}
9878 +
9879 +/**
9880 + *     devfs_mk_dir - Create a directory in the devfs namespace.
9881 + *             new name is relative to the root of the devfs.
9882 + *     @fmt: The name of the entry.
9883 + *
9884 + *     Use of this function is optional. The devfs_register() function
9885 + *     will automatically create intermediate directories as needed. This function
9886 + *     is provided for efficiency reasons, as it provides a handle to a directory.
9887 + *     On failure %NULL is returned.
9888 + */
9889 +
9890 +int devfs_mk_dir(const char *fmt, ...)
9891 +{
9892 +       struct devfs_entry *dir = NULL, *de = NULL, *old;
9893 +       char buf[64];
9894 +       va_list args;
9895 +       int error, n;
9896 +
9897 +       va_start(args, fmt);
9898 +       n = vsnprintf(buf, 64, fmt, args);
9899 +       if (n >= 64 || !buf[0]) {
9900 +               printk(KERN_WARNING "%s: invalid argument.", __FUNCTION__);
9901 +               return -EINVAL;
9902 +       }
9903 +
9904 +       de = _devfs_prepare_leaf(&dir, buf, MODE_DIR);
9905 +       if (!de) {
9906 +               PRINTK("(%s): could not prepare leaf\n", buf);
9907 +               return -EINVAL;
9908 +       }
9909 +
9910 +       error = _devfs_append_entry(dir, de, &old);
9911 +       if (error == -EEXIST && S_ISDIR(old->mode)) {
9912 +               /*
9913 +                * devfs_mk_dir() of an already-existing directory will
9914 +                * return success.
9915 +                */
9916 +               error = 0;
9917 +               goto out_put;
9918 +       } else if (error) {
9919 +               PRINTK("(%s): could not append to dir: %p \"%s\"\n",
9920 +                      buf, dir, dir->name);
9921 +               devfs_put(old);
9922 +               goto out_put;
9923 +       }
9924 +
9925 +       devfsd_notify(de, DEVFSD_NOTIFY_REGISTERED);
9926 +
9927 +      out_put:
9928 +       devfs_put(dir);
9929 +       return error;
9930 +}
9931 +
9932 +void devfs_remove(const char *fmt, ...)
9933 +{
9934 +       char buf[64];
9935 +       va_list args;
9936 +       int n;
9937 +
9938 +       va_start(args, fmt);
9939 +       n = vsnprintf(buf, sizeof(buf), fmt, args);
9940 +       if (n < sizeof(buf) && buf[0]) {
9941 +               devfs_handle_t de = _devfs_find_entry(NULL, buf, 0);
9942 +
9943 +               if (!de) {
9944 +                       printk(KERN_ERR "%s: %s not found, cannot remove\n",
9945 +                              __FUNCTION__, buf);
9946 +                       dump_stack();
9947 +                       return;
9948 +               }
9949 +
9950 +               write_lock(&de->parent->u.dir.lock);
9951 +               _devfs_unregister(de->parent, de);
9952 +               devfs_put(de);
9953 +               devfs_put(de);
9954 +       }
9955 +}
9956 +
9957 +/**
9958 + *     devfs_generate_path - Generate a pathname for an entry, relative to the devfs root.
9959 + *     @de: The devfs entry.
9960 + *     @path: The buffer to write the pathname to. The pathname and '\0'
9961 + *             terminator will be written at the end of the buffer.
9962 + *     @buflen: The length of the buffer.
9963 + *
9964 + *     Returns the offset in the buffer where the pathname starts on success,
9965 + *     else a negative error code.
9966 + */
9967 +
9968 +static int devfs_generate_path(devfs_handle_t de, char *path, int buflen)
9969 +{
9970 +       int pos;
9971 +#define NAMEOF(de) ( (de)->mode ? (de)->name : (de)->u.name )
9972 +
9973 +       if (de == NULL)
9974 +               return -EINVAL;
9975 +       VERIFY_ENTRY(de);
9976 +       if (de->namelen >= buflen)
9977 +               return -ENAMETOOLONG;   /*  Must be first       */
9978 +       path[buflen - 1] = '\0';
9979 +       if (de->parent == NULL)
9980 +               return buflen - 1;      /*  Don't prepend root  */
9981 +       pos = buflen - de->namelen - 1;
9982 +       memcpy(path + pos, NAMEOF(de), de->namelen);
9983 +       for (de = de->parent; de->parent != NULL; de = de->parent) {
9984 +               if (pos - de->namelen - 1 < 0)
9985 +                       return -ENAMETOOLONG;
9986 +               path[--pos] = '/';
9987 +               pos -= de->namelen;
9988 +               memcpy(path + pos, NAMEOF(de), de->namelen);
9989 +       }
9990 +       return pos;
9991 +}                              /*  End Function devfs_generate_path  */
9992 +
9993 +/**
9994 + *     devfs_setup - Process kernel boot options.
9995 + *     @str: The boot options after the "devfs=".
9996 + */
9997 +
9998 +static int __init devfs_setup(char *str)
9999 +{
10000 +       static struct {
10001 +               char *name;
10002 +               unsigned int mask;
10003 +               unsigned int *opt;
10004 +       } devfs_options_tab[] __initdata = {
10005 +#ifdef CONFIG_DEVFS_DEBUG
10006 +               {
10007 +               "dall", DEBUG_ALL, &devfs_debug_init}, {
10008 +               "dmod", DEBUG_MODULE_LOAD, &devfs_debug_init}, {
10009 +               "dreg", DEBUG_REGISTER, &devfs_debug_init}, {
10010 +               "dunreg", DEBUG_UNREGISTER, &devfs_debug_init}, {
10011 +               "dfree", DEBUG_FREE, &devfs_debug_init}, {
10012 +               "diget", DEBUG_I_GET, &devfs_debug_init}, {
10013 +               "dchange", DEBUG_SET_FLAGS, &devfs_debug_init}, {
10014 +               "dsread", DEBUG_S_READ, &devfs_debug_init}, {
10015 +               "dichange", DEBUG_I_CHANGE, &devfs_debug_init}, {
10016 +               "dimknod", DEBUG_I_MKNOD, &devfs_debug_init}, {
10017 +               "dilookup", DEBUG_I_LOOKUP, &devfs_debug_init}, {
10018 +               "diunlink", DEBUG_I_UNLINK, &devfs_debug_init},
10019 +#endif                         /*  CONFIG_DEVFS_DEBUG  */
10020 +               {
10021 +               "mount", OPTION_MOUNT, &boot_options}, {
10022 +               NULL, 0, NULL}
10023 +       };
10024 +
10025 +       while ((*str != '\0') && !isspace(*str)) {
10026 +               int i, found = 0, invert = 0;
10027 +
10028 +               if (strncmp(str, "no", 2) == 0) {
10029 +                       invert = 1;
10030 +                       str += 2;
10031 +               }
10032 +               for (i = 0; devfs_options_tab[i].name != NULL; i++) {
10033 +                       int len = strlen(devfs_options_tab[i].name);
10034 +
10035 +                       if (strncmp(str, devfs_options_tab[i].name, len) == 0) {
10036 +                               if (invert)
10037 +                                       *devfs_options_tab[i].opt &=
10038 +                                           ~devfs_options_tab[i].mask;
10039 +                               else
10040 +                                       *devfs_options_tab[i].opt |=
10041 +                                           devfs_options_tab[i].mask;
10042 +                               str += len;
10043 +                               found = 1;
10044 +                               break;
10045 +                       }
10046 +               }
10047 +               if (!found)
10048 +                       return 0;       /*  No match         */
10049 +               if (*str != ',')
10050 +                       return 0;       /*  No more options  */
10051 +               ++str;
10052 +       }
10053 +       return 1;
10054 +}                              /*  End Function devfs_setup  */
10055 +
10056 +__setup("devfs=", devfs_setup);
10057 +
10058 +EXPORT_SYMBOL(devfs_mk_dir);
10059 +EXPORT_SYMBOL(devfs_remove);
10060 +
10061 +/**
10062 + *     try_modload - Notify devfsd of an inode lookup by a non-devfsd process.
10063 + *     @parent: The parent devfs entry.
10064 + *     @fs_info: The filesystem info.
10065 + *     @name: The device name.
10066 + *     @namelen: The number of characters in @name.
10067 + *     @buf: A working area that will be used. This must not go out of scope
10068 + *            until devfsd is idle again.
10069 + *
10070 + *     Returns 0 on success (event was queued), else a negative error code.
10071 + */
10072 +
10073 +static int try_modload(struct devfs_entry *parent, struct fs_info *fs_info,
10074 +                      const char *name, unsigned namelen,
10075 +                      struct devfs_entry *buf)
10076 +{
10077 +       if (!(fs_info->devfsd_event_mask & (1 << DEVFSD_NOTIFY_LOOKUP)))
10078 +               return -ENOENT;
10079 +       if (is_devfsd_or_child(fs_info))
10080 +               return -ENOENT;
10081 +       memset(buf, 0, sizeof *buf);
10082 +       atomic_set(&buf->refcount, 1);
10083 +       buf->parent = parent;
10084 +       buf->namelen = namelen;
10085 +       buf->u.name = name;
10086 +       WRITE_ENTRY_MAGIC(buf, MAGIC_VALUE);
10087 +       if (!devfsd_notify_de(buf, DEVFSD_NOTIFY_LOOKUP, 0,
10088 +                             current->euid, current->egid, fs_info))
10089 +               return -ENOENT;
10090 +       /*  Possible success: event has been queued  */
10091 +       return 0;
10092 +}                              /*  End Function try_modload  */
10093 +
10094 +/*  Superblock operations follow  */
10095 +
10096 +static struct inode_operations devfs_iops;
10097 +static struct inode_operations devfs_dir_iops;
10098 +static const struct file_operations devfs_fops;
10099 +static const struct file_operations devfs_dir_fops;
10100 +static struct inode_operations devfs_symlink_iops;
10101 +
10102 +static int devfs_notify_change(struct dentry *dentry, struct iattr *iattr)
10103 +{
10104 +       int retval;
10105 +       struct devfs_entry *de;
10106 +       struct inode *inode = dentry->d_inode;
10107 +       struct fs_info *fs_info = inode->i_sb->s_fs_info;
10108 +
10109 +       de = get_devfs_entry_from_vfs_inode(inode);
10110 +       if (de == NULL)
10111 +               return -ENODEV;
10112 +       retval = inode_change_ok(inode, iattr);
10113 +       if (retval != 0)
10114 +               return retval;
10115 +       retval = inode_setattr(inode, iattr);
10116 +       if (retval != 0)
10117 +               return retval;
10118 +       DPRINTK(DEBUG_I_CHANGE, "(%d): VFS inode: %p  devfs_entry: %p\n",
10119 +               (int)inode->i_ino, inode, de);
10120 +       DPRINTK(DEBUG_I_CHANGE, "():   mode: 0%o  uid: %d  gid: %d\n",
10121 +               (int)inode->i_mode, (int)inode->i_uid, (int)inode->i_gid);
10122 +       /*  Inode is not on hash chains, thus must save permissions here rather
10123 +          than in a write_inode() method  */
10124 +       de->mode = inode->i_mode;
10125 +       de->inode.uid = inode->i_uid;
10126 +       de->inode.gid = inode->i_gid;
10127 +       de->inode.atime = inode->i_atime;
10128 +       de->inode.mtime = inode->i_mtime;
10129 +       de->inode.ctime = inode->i_ctime;
10130 +       if ((iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)) &&
10131 +           !is_devfsd_or_child(fs_info))
10132 +               devfsd_notify_de(de, DEVFSD_NOTIFY_CHANGE, inode->i_mode,
10133 +                                inode->i_uid, inode->i_gid, fs_info);
10134 +       return 0;
10135 +}                              /*  End Function devfs_notify_change  */
10136 +
10137 +static struct super_operations devfs_sops = {
10138 +       .drop_inode = generic_delete_inode,
10139 +       .statfs = simple_statfs,
10140 +};
10141 +
10142 +/**
10143 + *     _devfs_get_vfs_inode - Get a VFS inode.
10144 + *     @sb: The super block.
10145 + *     @de: The devfs inode.
10146 + *     @dentry: The dentry to register with the devfs inode.
10147 + *
10148 + *     Returns the inode on success, else %NULL. An implicit devfs_get() is
10149 + *       performed if the inode is created.
10150 + */
10151 +
10152 +static struct inode *_devfs_get_vfs_inode(struct super_block *sb,
10153 +                                         struct devfs_entry *de,
10154 +                                         struct dentry *dentry)
10155 +{
10156 +       struct inode *inode;
10157 +
10158 +       if (de->prev == de)
10159 +               return NULL;    /*  Quick check to see if unhooked  */
10160 +       if ((inode = new_inode(sb)) == NULL) {
10161 +               PRINTK("(%s): new_inode() failed, de: %p\n", de->name, de);
10162 +               return NULL;
10163 +       }
10164 +       if (de->parent) {
10165 +               read_lock(&de->parent->u.dir.lock);
10166 +               if (de->prev != de)
10167 +                       de->inode.dentry = dentry;      /*      Not unhooked  */
10168 +               read_unlock(&de->parent->u.dir.lock);
10169 +       } else
10170 +               de->inode.dentry = dentry;      /*  Root: no locking needed  */
10171 +       if (de->inode.dentry != dentry) {       /*  Must have been unhooked  */
10172 +               iput(inode);
10173 +               return NULL;
10174 +       }
10175 +       /* FIXME where is devfs_put? */
10176 +       inode->i_private = devfs_get(de);
10177 +       inode->i_ino = de->inode.ino;
10178 +       DPRINTK(DEBUG_I_GET, "(%d): VFS inode: %p  devfs_entry: %p\n",
10179 +               (int)inode->i_ino, inode, de);
10180 +       inode->i_blocks = 0;
10181 +       inode->i_op = &devfs_iops;
10182 +       inode->i_mode = de->mode;
10183 +       if (S_ISDIR(de->mode)) {
10184 +               inode->i_op = &devfs_dir_iops;
10185 +               inode->i_fop = &devfs_dir_fops;
10186 +       } else if (S_ISLNK(de->mode)) {
10187 +               inode->i_op = &devfs_symlink_iops;
10188 +               inode->i_size = de->u.symlink.length;
10189 +       } else if (S_ISCHR(de->mode) || S_ISBLK(de->mode)) {
10190 +               init_special_inode(inode, de->mode, de->u.dev);
10191 +       } else if (S_ISFIFO(de->mode) || S_ISSOCK(de->mode)) {
10192 +               init_special_inode(inode, de->mode, 0);
10193 +       } else {
10194 +               PRINTK("(%s): unknown mode %o de: %p\n",
10195 +                      de->name, de->mode, de);
10196 +               iput(inode);
10197 +               devfs_put(de);
10198 +               return NULL;
10199 +       }
10200 +
10201 +       inode->i_uid = de->inode.uid;
10202 +       inode->i_gid = de->inode.gid;
10203 +       inode->i_atime = de->inode.atime;
10204 +       inode->i_mtime = de->inode.mtime;
10205 +       inode->i_ctime = de->inode.ctime;
10206 +       DPRINTK(DEBUG_I_GET, "():   mode: 0%o  uid: %d  gid: %d\n",
10207 +               (int)inode->i_mode, (int)inode->i_uid, (int)inode->i_gid);
10208 +       return inode;
10209 +}                              /*  End Function _devfs_get_vfs_inode  */
10210 +
10211 +/*  File operations for device entries follow  */
10212 +
10213 +static int devfs_readdir(struct file *file, void *dirent, filldir_t filldir)
10214 +{
10215 +       int err, count;
10216 +       int stored = 0;
10217 +       struct fs_info *fs_info;
10218 +       struct devfs_entry *parent, *de, *next = NULL;
10219 +       struct inode *inode = file->f_dentry->d_inode;
10220 +
10221 +       fs_info = inode->i_sb->s_fs_info;
10222 +       parent = get_devfs_entry_from_vfs_inode(file->f_dentry->d_inode);
10223 +       if ((long)file->f_pos < 0)
10224 +               return -EINVAL;
10225 +       DPRINTK(DEBUG_F_READDIR, "(%s): fs_info: %p  pos: %ld\n",
10226 +               parent->name, fs_info, (long)file->f_pos);
10227 +       switch ((long)file->f_pos) {
10228 +       case 0:
10229 +               err = (*filldir) (dirent, "..", 2, file->f_pos,
10230 +                                 parent_ino(file->f_dentry), DT_DIR);
10231 +               if (err == -EINVAL)
10232 +                       break;
10233 +               if (err < 0)
10234 +                       return err;
10235 +               file->f_pos++;
10236 +               ++stored;
10237 +               /*  Fall through  */
10238 +       case 1:
10239 +               err =
10240 +                   (*filldir) (dirent, ".", 1, file->f_pos, inode->i_ino,
10241 +                               DT_DIR);
10242 +               if (err == -EINVAL)
10243 +                       break;
10244 +               if (err < 0)
10245 +                       return err;
10246 +               file->f_pos++;
10247 +               ++stored;
10248 +               /*  Fall through  */
10249 +       default:
10250 +               /*  Skip entries  */
10251 +               count = file->f_pos - 2;
10252 +               read_lock(&parent->u.dir.lock);
10253 +               for (de = parent->u.dir.first; de && (count > 0); de = de->next)
10254 +                       --count;
10255 +               devfs_get(de);
10256 +               read_unlock(&parent->u.dir.lock);
10257 +               /*  Now add all remaining entries  */
10258 +               while (de) {
10259 +                       err = (*filldir) (dirent, de->name, de->namelen,
10260 +                                         file->f_pos, de->inode.ino,
10261 +                                         de->mode >> 12);
10262 +                       if (err < 0)
10263 +                               devfs_put(de);
10264 +                       else {
10265 +                               file->f_pos++;
10266 +                               ++stored;
10267 +                       }
10268 +                       if (err == -EINVAL)
10269 +                               break;
10270 +                       if (err < 0)
10271 +                               return err;
10272 +                       read_lock(&parent->u.dir.lock);
10273 +                       next = devfs_get(de->next);
10274 +                       read_unlock(&parent->u.dir.lock);
10275 +                       devfs_put(de);
10276 +                       de = next;
10277 +               }
10278 +               break;
10279 +       }
10280 +       return stored;
10281 +}                              /*  End Function devfs_readdir  */
10282 +
10283 +/* Open devfs specific special files */
10284 +static int devfs_open(struct inode *inode, struct file *file)
10285 +{
10286 +       int err;
10287 +       int minor = MINOR(inode->i_rdev);
10288 +       struct file_operations *old_fops, *new_fops;
10289 +
10290 +       switch (minor) {
10291 +       case 0:         /* /dev/.devfsd */
10292 +               new_fops = fops_get(&devfsd_fops);
10293 +               break;
10294 +#ifdef CONFIG_DEVFS_DEBUG
10295 +       case 1:         /* /dev/.stat */
10296 +               new_fops = fops_get(&stat_fops);
10297 +               break;
10298 +#endif
10299 +       default:
10300 +               return -ENODEV;
10301 +       }
10302 +
10303 +       if (new_fops == NULL)
10304 +               return -ENODEV;
10305 +       old_fops = file->f_op;
10306 +       file->f_op = new_fops;
10307 +       err = new_fops->open ? new_fops->open(inode, file) : 0;
10308 +       if (err) {
10309 +               file->f_op = old_fops;
10310 +               fops_put(new_fops);
10311 +       } else
10312 +               fops_put(old_fops);
10313 +       return err;
10314 +}                              /*  End Function devfs_open  */
10315 +
10316 +static const struct file_operations devfs_fops = {
10317 +       .open = devfs_open,
10318 +};
10319 +
10320 +static const struct file_operations devfs_dir_fops = {
10321 +       .read = generic_read_dir,
10322 +       .readdir = devfs_readdir,
10323 +};
10324 +
10325 +/*  Dentry operations for device entries follow  */
10326 +
10327 +/**
10328 + *     devfs_d_release - Callback for when a dentry is freed.
10329 + *     @dentry: The dentry.
10330 + */
10331 +
10332 +static void devfs_d_release(struct dentry *dentry)
10333 +{
10334 +       DPRINTK(DEBUG_D_RELEASE, "(%p): inode: %p\n", dentry, dentry->d_inode);
10335 +}                              /*  End Function devfs_d_release  */
10336 +
10337 +/**
10338 + *     devfs_d_iput - Callback for when a dentry loses its inode.
10339 + *     @dentry: The dentry.
10340 + *     @inode: The inode.
10341 + */
10342 +
10343 +static void devfs_d_iput(struct dentry *dentry, struct inode *inode)
10344 +{
10345 +       struct devfs_entry *de;
10346 +
10347 +       de = get_devfs_entry_from_vfs_inode(inode);
10348 +       DPRINTK(DEBUG_D_IPUT,
10349 +               "(%s): dentry: %p inode: %p de: %p de->dentry: %p\n", de->name,
10350 +               dentry, inode, de, de->inode.dentry);
10351 +       if (de->inode.dentry && (de->inode.dentry != dentry))
10352 +               OOPS("(%s): de: %p dentry: %p de->dentry: %p\n",
10353 +                    de->name, de, dentry, de->inode.dentry);
10354 +       de->inode.dentry = NULL;
10355 +       iput(inode);
10356 +       devfs_put(de);
10357 +}                              /*  End Function devfs_d_iput  */
10358 +
10359 +static int devfs_d_delete(struct dentry *dentry);
10360 +
10361 +static struct dentry_operations devfs_dops = {
10362 +       .d_delete = devfs_d_delete,
10363 +       .d_release = devfs_d_release,
10364 +       .d_iput = devfs_d_iput,
10365 +};
10366 +
10367 +static int devfs_d_revalidate_wait(struct dentry *dentry, struct nameidata *);
10368 +
10369 +static struct dentry_operations devfs_wait_dops = {
10370 +       .d_delete = devfs_d_delete,
10371 +       .d_release = devfs_d_release,
10372 +       .d_iput = devfs_d_iput,
10373 +       .d_revalidate = devfs_d_revalidate_wait,
10374 +};
10375 +
10376 +/**
10377 + *     devfs_d_delete - Callback for when all files for a dentry are closed.
10378 + *     @dentry: The dentry.
10379 + */
10380 +
10381 +static int devfs_d_delete(struct dentry *dentry)
10382 +{
10383 +       struct inode *inode = dentry->d_inode;
10384 +
10385 +       if (dentry->d_op == &devfs_wait_dops)
10386 +               dentry->d_op = &devfs_dops;
10387 +       /*  Unhash dentry if negative (has no inode)  */
10388 +       if (inode == NULL) {
10389 +               DPRINTK(DEBUG_D_DELETE, "(%p): dropping negative dentry\n",
10390 +                       dentry);
10391 +               return 1;
10392 +       }
10393 +       return 0;
10394 +}                              /*  End Function devfs_d_delete  */
10395 +
10396 +struct devfs_lookup_struct {
10397 +       devfs_handle_t de;
10398 +       wait_queue_head_t wait_queue;
10399 +};
10400 +
10401 +/* XXX: this doesn't handle the case where we got a negative dentry
10402 +        but a devfs entry has been registered in the meanwhile */
10403 +static int devfs_d_revalidate_wait(struct dentry *dentry, struct nameidata *nd)
10404 +{
10405 +       struct inode *dir = dentry->d_parent->d_inode;
10406 +       struct fs_info *fs_info = dir->i_sb->s_fs_info;
10407 +       devfs_handle_t parent = get_devfs_entry_from_vfs_inode(dir);
10408 +       struct devfs_lookup_struct *lookup_info = dentry->d_fsdata;
10409 +       DECLARE_WAITQUEUE(wait, current);
10410 +       int need_lock;
10411 +
10412 +       /*
10413 +        * FIXME HACK
10414 +        *
10415 +        * make sure that
10416 +        *   d_instantiate always runs under lock
10417 +        *   we release i_mutex lock before going to sleep
10418 +        *
10419 +        * unfortunately sometimes d_revalidate is called with
10420 +        * and sometimes without i_mutex lock held. The following checks
10421 +        * attempt to deduce when we need to add (and drop resp.) lock
10422 +        * here. This relies on current (2.6.2) calling coventions:
10423 +        *
10424 +        *   lookup_hash is always run under i_mutex and is passing NULL
10425 +        *   as nd
10426 +        *
10427 +        *   open(...,O_CREATE,...) calls _lookup_hash under i_mutex
10428 +        *   and sets flags to LOOKUP_OPEN|LOOKUP_CREATE
10429 +        *
10430 +        *   all other invocations of ->d_revalidate seem to happen
10431 +        *   outside of i_mutex
10432 +        */
10433 +       need_lock = nd &&
10434 +           (!(nd->flags & LOOKUP_CREATE) || (nd->flags & LOOKUP_PARENT));
10435 +
10436 +       if (need_lock)
10437 +               mutex_lock(&dir->i_mutex);
10438 +
10439 +       if (is_devfsd_or_child(fs_info)) {
10440 +               devfs_handle_t de = lookup_info->de;
10441 +               struct inode *inode;
10442 +
10443 +               DPRINTK(DEBUG_I_LOOKUP,
10444 +                       "(%s): dentry: %p inode: %p de: %p by: \"%s\"\n",
10445 +                       dentry->d_name.name, dentry, dentry->d_inode, de,
10446 +                       current->comm);
10447 +               if (dentry->d_inode)
10448 +                       goto out;
10449 +               if (de == NULL) {
10450 +                       read_lock(&parent->u.dir.lock);
10451 +                       de = _devfs_search_dir(parent, dentry->d_name.name,
10452 +                                              dentry->d_name.len);
10453 +                       read_unlock(&parent->u.dir.lock);
10454 +                       if (de == NULL)
10455 +                               goto out;
10456 +                       lookup_info->de = de;
10457 +               }
10458 +               /*  Create an inode, now that the driver information is available  */
10459 +               inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry);
10460 +               if (!inode)
10461 +                       goto out;
10462 +               DPRINTK(DEBUG_I_LOOKUP,
10463 +                       "(%s): new VFS inode(%u): %p de: %p by: \"%s\"\n",
10464 +                       de->name, de->inode.ino, inode, de, current->comm);
10465 +               d_instantiate(dentry, inode);
10466 +               goto out;
10467 +       }
10468 +       if (lookup_info == NULL)
10469 +               goto out;       /*  Early termination  */
10470 +       read_lock(&parent->u.dir.lock);
10471 +       if (dentry->d_fsdata) {
10472 +               set_current_state(TASK_UNINTERRUPTIBLE);
10473 +               add_wait_queue(&lookup_info->wait_queue, &wait);
10474 +               read_unlock(&parent->u.dir.lock);
10475 +               /* at this point it is always (hopefully) locked */
10476 +               mutex_unlock(&dir->i_mutex);
10477 +               schedule();
10478 +               mutex_lock(&dir->i_mutex);
10479 +               /*
10480 +                * This does not need nor should remove wait from wait_queue.
10481 +                * Wait queue head is never reused - nothing is ever added to it
10482 +                * after all waiters have been waked up and head itself disappears
10483 +                * very soon after it. Moreover it is local variable on stack that
10484 +                * is likely to have already disappeared so any reference to it
10485 +                * at this point is buggy.
10486 +                */
10487 +
10488 +       } else
10489 +               read_unlock(&parent->u.dir.lock);
10490 +
10491 +      out:
10492 +       if (need_lock)
10493 +               mutex_unlock(&dir->i_mutex);
10494 +       return 1;
10495 +}                              /*  End Function devfs_d_revalidate_wait  */
10496 +
10497 +/*  Inode operations for device entries follow  */
10498 +
10499 +static struct dentry *devfs_lookup(struct inode *dir, struct dentry *dentry,
10500 +                                  struct nameidata *nd)
10501 +{
10502 +       struct devfs_entry tmp; /*  Must stay in scope until devfsd idle again  */
10503 +       struct devfs_lookup_struct lookup_info;
10504 +       struct fs_info *fs_info = dir->i_sb->s_fs_info;
10505 +       struct devfs_entry *parent, *de;
10506 +       struct inode *inode;
10507 +       struct dentry *retval = NULL;
10508 +
10509 +       /*  Set up the dentry operations before anything else, to ensure cleaning
10510 +          up on any error  */
10511 +       dentry->d_op = &devfs_dops;
10512 +       /*  First try to get the devfs entry for this directory  */
10513 +       parent = get_devfs_entry_from_vfs_inode(dir);
10514 +       DPRINTK(DEBUG_I_LOOKUP, "(%s): dentry: %p parent: %p by: \"%s\"\n",
10515 +               dentry->d_name.name, dentry, parent, current->comm);
10516 +       if (parent == NULL)
10517 +               return ERR_PTR(-ENOENT);
10518 +       read_lock(&parent->u.dir.lock);
10519 +       de = _devfs_search_dir(parent, dentry->d_name.name, dentry->d_name.len);
10520 +       read_unlock(&parent->u.dir.lock);
10521 +       lookup_info.de = de;
10522 +       init_waitqueue_head(&lookup_info.wait_queue);
10523 +       dentry->d_fsdata = &lookup_info;
10524 +       if (de == NULL) {       /*  Try with devfsd. For any kind of failure, leave a negative dentry
10525 +                                  so someone else can deal with it (in the case where the sysadmin
10526 +                                  does a mknod()). It's important to do this before hashing the
10527 +                                  dentry, so that the devfsd queue is filled before revalidates
10528 +                                  can start  */
10529 +               if (try_modload(parent, fs_info, dentry->d_name.name, dentry->d_name.len, &tmp) < 0) {  /*  Lookup event was not queued to devfsd  */
10530 +                       d_add(dentry, NULL);
10531 +                       return NULL;
10532 +               }
10533 +       }
10534 +       dentry->d_op = &devfs_wait_dops;
10535 +       d_add(dentry, NULL);    /*  Open the floodgates  */
10536 +       /*  Unlock directory semaphore, which will release any waiters. They
10537 +          will get the hashed dentry, and may be forced to wait for
10538 +          revalidation  */
10539 +       mutex_unlock(&dir->i_mutex);
10540 +       wait_for_devfsd_finished(fs_info);      /*  If I'm not devfsd, must wait  */
10541 +       mutex_lock(&dir->i_mutex);      /*  Grab it again because them's the rules  */
10542 +       de = lookup_info.de;
10543 +       /*  If someone else has been so kind as to make the inode, we go home
10544 +          early  */
10545 +       if (dentry->d_inode)
10546 +               goto out;
10547 +       if (de == NULL) {
10548 +               read_lock(&parent->u.dir.lock);
10549 +               de = _devfs_search_dir(parent, dentry->d_name.name,
10550 +                                      dentry->d_name.len);
10551 +               read_unlock(&parent->u.dir.lock);
10552 +               if (de == NULL)
10553 +                       goto out;
10554 +               /*  OK, there's an entry now, but no VFS inode yet  */
10555 +       }
10556 +       /*  Create an inode, now that the driver information is available  */
10557 +       inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry);
10558 +       if (!inode) {
10559 +               retval = ERR_PTR(-ENOMEM);
10560 +               goto out;
10561 +       }
10562 +       DPRINTK(DEBUG_I_LOOKUP,
10563 +               "(%s): new VFS inode(%u): %p de: %p by: \"%s\"\n", de->name,
10564 +               de->inode.ino, inode, de, current->comm);
10565 +       d_instantiate(dentry, inode);
10566 +      out:
10567 +       write_lock(&parent->u.dir.lock);
10568 +       dentry->d_op = &devfs_dops;
10569 +       dentry->d_fsdata = NULL;
10570 +       wake_up(&lookup_info.wait_queue);
10571 +       write_unlock(&parent->u.dir.lock);
10572 +       devfs_put(de);
10573 +       return retval;
10574 +}                              /*  End Function devfs_lookup  */
10575 +
10576 +static int devfs_unlink(struct inode *dir, struct dentry *dentry)
10577 +{
10578 +       int unhooked;
10579 +       struct devfs_entry *de;
10580 +       struct inode *inode = dentry->d_inode;
10581 +       struct fs_info *fs_info = dir->i_sb->s_fs_info;
10582 +
10583 +       de = get_devfs_entry_from_vfs_inode(inode);
10584 +       DPRINTK(DEBUG_I_UNLINK, "(%s): de: %p\n", dentry->d_name.name, de);
10585 +       if (de == NULL)
10586 +               return -ENOENT;
10587 +       if (!de->vfs)
10588 +               return -EPERM;
10589 +       write_lock(&de->parent->u.dir.lock);
10590 +       unhooked = _devfs_unhook(de);
10591 +       write_unlock(&de->parent->u.dir.lock);
10592 +       if (!unhooked)
10593 +               return -ENOENT;
10594 +       if (!is_devfsd_or_child(fs_info))
10595 +               devfsd_notify_de(de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
10596 +                                inode->i_uid, inode->i_gid, fs_info);
10597 +       free_dentry(de);
10598 +       devfs_put(de);
10599 +       return 0;
10600 +}                              /*  End Function devfs_unlink  */
10601 +
10602 +static int devfs_symlink(struct inode *dir, struct dentry *dentry,
10603 +                        const char *symname)
10604 +{
10605 +       int err;
10606 +       struct fs_info *fs_info = dir->i_sb->s_fs_info;
10607 +       struct devfs_entry *parent, *de;
10608 +       struct inode *inode;
10609 +
10610 +       /*  First try to get the devfs entry for this directory  */
10611 +       parent = get_devfs_entry_from_vfs_inode(dir);
10612 +       if (parent == NULL)
10613 +               return -ENOENT;
10614 +       err = devfs_do_symlink(parent, dentry->d_name.name, symname, &de);
10615 +       DPRINTK(DEBUG_DISABLED, "(%s): errcode from <devfs_do_symlink>: %d\n",
10616 +               dentry->d_name.name, err);
10617 +       if (err < 0)
10618 +               return err;
10619 +       de->vfs = TRUE;
10620 +       de->inode.uid = current->euid;
10621 +       de->inode.gid = current->egid;
10622 +       de->inode.atime = CURRENT_TIME;
10623 +       de->inode.mtime = CURRENT_TIME;
10624 +       de->inode.ctime = CURRENT_TIME;
10625 +       if ((inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry)) == NULL)
10626 +               return -ENOMEM;
10627 +       DPRINTK(DEBUG_DISABLED, "(%s): new VFS inode(%u): %p  dentry: %p\n",
10628 +               dentry->d_name.name, de->inode.ino, inode, dentry);
10629 +       d_instantiate(dentry, inode);
10630 +       if (!is_devfsd_or_child(fs_info))
10631 +               devfsd_notify_de(de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
10632 +                                inode->i_uid, inode->i_gid, fs_info);
10633 +       return 0;
10634 +}                              /*  End Function devfs_symlink  */
10635 +
10636 +static int devfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
10637 +{
10638 +       int err;
10639 +       struct fs_info *fs_info = dir->i_sb->s_fs_info;
10640 +       struct devfs_entry *parent, *de;
10641 +       struct inode *inode;
10642 +
10643 +       mode = (mode & ~S_IFMT) | S_IFDIR;      /*  VFS doesn't pass S_IFMT part  */
10644 +       parent = get_devfs_entry_from_vfs_inode(dir);
10645 +       if (parent == NULL)
10646 +               return -ENOENT;
10647 +       de = _devfs_alloc_entry(dentry->d_name.name, dentry->d_name.len, mode);
10648 +       if (!de)
10649 +               return -ENOMEM;
10650 +       de->vfs = TRUE;
10651 +       if ((err = _devfs_append_entry(parent, de, NULL)) != 0)
10652 +               return err;
10653 +       de->inode.uid = current->euid;
10654 +       de->inode.gid = current->egid;
10655 +       de->inode.atime = CURRENT_TIME;
10656 +       de->inode.mtime = CURRENT_TIME;
10657 +       de->inode.ctime = CURRENT_TIME;
10658 +       if ((inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry)) == NULL)
10659 +               return -ENOMEM;
10660 +       DPRINTK(DEBUG_DISABLED, "(%s): new VFS inode(%u): %p  dentry: %p\n",
10661 +               dentry->d_name.name, de->inode.ino, inode, dentry);
10662 +       d_instantiate(dentry, inode);
10663 +       if (!is_devfsd_or_child(fs_info))
10664 +               devfsd_notify_de(de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
10665 +                                inode->i_uid, inode->i_gid, fs_info);
10666 +       return 0;
10667 +}                              /*  End Function devfs_mkdir  */
10668 +
10669 +static int devfs_rmdir(struct inode *dir, struct dentry *dentry)
10670 +{
10671 +       int err = 0;
10672 +       struct devfs_entry *de;
10673 +       struct fs_info *fs_info = dir->i_sb->s_fs_info;
10674 +       struct inode *inode = dentry->d_inode;
10675 +
10676 +       if (dir->i_sb->s_fs_info != inode->i_sb->s_fs_info)
10677 +               return -EINVAL;
10678 +       de = get_devfs_entry_from_vfs_inode(inode);
10679 +       if (de == NULL)
10680 +               return -ENOENT;
10681 +       if (!S_ISDIR(de->mode))
10682 +               return -ENOTDIR;
10683 +       if (!de->vfs)
10684 +               return -EPERM;
10685 +       /*  First ensure the directory is empty and will stay that way  */
10686 +       write_lock(&de->u.dir.lock);
10687 +       if (de->u.dir.first)
10688 +               err = -ENOTEMPTY;
10689 +       else
10690 +               de->u.dir.no_more_additions = TRUE;
10691 +       write_unlock(&de->u.dir.lock);
10692 +       if (err)
10693 +               return err;
10694 +       /*  Now unhook the directory from its parent  */
10695 +       write_lock(&de->parent->u.dir.lock);
10696 +       if (!_devfs_unhook(de))
10697 +               err = -ENOENT;
10698 +       write_unlock(&de->parent->u.dir.lock);
10699 +       if (err)
10700 +               return err;
10701 +       if (!is_devfsd_or_child(fs_info))
10702 +               devfsd_notify_de(de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
10703 +                                inode->i_uid, inode->i_gid, fs_info);
10704 +       free_dentry(de);
10705 +       devfs_put(de);
10706 +       return 0;
10707 +}                              /*  End Function devfs_rmdir  */
10708 +
10709 +static int devfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
10710 +                      dev_t rdev)
10711 +{
10712 +       int err;
10713 +       struct fs_info *fs_info = dir->i_sb->s_fs_info;
10714 +       struct devfs_entry *parent, *de;
10715 +       struct inode *inode;
10716 +
10717 +       DPRINTK(DEBUG_I_MKNOD, "(%s): mode: 0%o  dev: %u:%u\n",
10718 +               dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev));
10719 +       parent = get_devfs_entry_from_vfs_inode(dir);
10720 +       if (parent == NULL)
10721 +               return -ENOENT;
10722 +       de = _devfs_alloc_entry(dentry->d_name.name, dentry->d_name.len, mode);
10723 +       if (!de)
10724 +               return -ENOMEM;
10725 +       de->vfs = TRUE;
10726 +       if (S_ISCHR(mode) || S_ISBLK(mode))
10727 +               de->u.dev = rdev;
10728 +       if ((err = _devfs_append_entry(parent, de, NULL)) != 0)
10729 +               return err;
10730 +       de->inode.uid = current->euid;
10731 +       de->inode.gid = current->egid;
10732 +       de->inode.atime = CURRENT_TIME;
10733 +       de->inode.mtime = CURRENT_TIME;
10734 +       de->inode.ctime = CURRENT_TIME;
10735 +       if ((inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry)) == NULL)
10736 +               return -ENOMEM;
10737 +       DPRINTK(DEBUG_I_MKNOD, ":   new VFS inode(%u): %p  dentry: %p\n",
10738 +               de->inode.ino, inode, dentry);
10739 +       d_instantiate(dentry, inode);
10740 +       if (!is_devfsd_or_child(fs_info))
10741 +               devfsd_notify_de(de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
10742 +                                inode->i_uid, inode->i_gid, fs_info);
10743 +       return 0;
10744 +}                              /*  End Function devfs_mknod  */
10745 +
10746 +static void *devfs_follow_link(struct dentry *dentry, struct nameidata *nd)
10747 +{
10748 +       struct devfs_entry *p = get_devfs_entry_from_vfs_inode(dentry->d_inode);
10749 +       nd_set_link(nd, p ? p->u.symlink.linkname : ERR_PTR(-ENODEV));
10750 +       return NULL;
10751 +}                              /*  End Function devfs_follow_link  */
10752 +
10753 +static struct inode_operations devfs_iops = {
10754 +       .setattr = devfs_notify_change,
10755 +};
10756 +
10757 +static struct inode_operations devfs_dir_iops = {
10758 +       .lookup = devfs_lookup,
10759 +       .unlink = devfs_unlink,
10760 +       .symlink = devfs_symlink,
10761 +       .mkdir = devfs_mkdir,
10762 +       .rmdir = devfs_rmdir,
10763 +       .mknod = devfs_mknod,
10764 +       .setattr = devfs_notify_change,
10765 +};
10766 +
10767 +static struct inode_operations devfs_symlink_iops = {
10768 +       .readlink = generic_readlink,
10769 +       .follow_link = devfs_follow_link,
10770 +       .setattr = devfs_notify_change,
10771 +};
10772 +
10773 +static int devfs_fill_super(struct super_block *sb, void *data, int silent)
10774 +{
10775 +       struct inode *root_inode = NULL;
10776 +
10777 +       if (_devfs_get_root_entry() == NULL)
10778 +               goto out_no_root;
10779 +       atomic_set(&fs_info.devfsd_overrun_count, 0);
10780 +       init_waitqueue_head(&fs_info.devfsd_wait_queue);
10781 +       init_waitqueue_head(&fs_info.revalidate_wait_queue);
10782 +       fs_info.sb = sb;
10783 +       sb->s_fs_info = &fs_info;
10784 +       sb->s_blocksize = 1024;
10785 +       sb->s_blocksize_bits = 10;
10786 +       sb->s_magic = DEVFS_SUPER_MAGIC;
10787 +       sb->s_op = &devfs_sops;
10788 +       sb->s_time_gran = 1;
10789 +       if ((root_inode = _devfs_get_vfs_inode(sb, root_entry, NULL)) == NULL)
10790 +               goto out_no_root;
10791 +       sb->s_root = d_alloc_root(root_inode);
10792 +       if (!sb->s_root)
10793 +               goto out_no_root;
10794 +       DPRINTK(DEBUG_S_READ, "(): made devfs ptr: %p\n", sb->s_fs_info);
10795 +       return 0;
10796 +
10797 +      out_no_root:
10798 +       PRINTK("(): get root inode failed\n");
10799 +       if (root_inode)
10800 +               iput(root_inode);
10801 +       return -EINVAL;
10802 +}                              /*  End Function devfs_fill_super  */
10803 +
10804 +static int devfs_get_sb(struct file_system_type *fs_type,
10805 +                                       int flags, const char *dev_name,
10806 +                                       void *data, struct vfsmount *mnt)
10807 +{
10808 +       return get_sb_single(fs_type, flags, data, devfs_fill_super, mnt);
10809 +}
10810 +
10811 +static struct file_system_type devfs_fs_type = {
10812 +       .name = DEVFS_NAME,
10813 +       .get_sb = devfs_get_sb,
10814 +       .kill_sb = kill_anon_super,
10815 +};
10816 +
10817 +/*  File operations for devfsd follow  */
10818 +
10819 +static ssize_t devfsd_read(struct file *file, char __user *buf, size_t len,
10820 +                          loff_t * ppos)
10821 +{
10822 +       int done = FALSE;
10823 +       int ival;
10824 +       loff_t pos, devname_offset, tlen, rpos;
10825 +       devfs_handle_t de;
10826 +       struct devfsd_buf_entry *entry;
10827 +       struct fs_info *fs_info = file->f_dentry->d_inode->i_sb->s_fs_info;
10828 +       struct devfsd_notify_struct *info = fs_info->devfsd_info;
10829 +       DECLARE_WAITQUEUE(wait, current);
10830 +
10831 +       /*  Verify the task has grabbed the queue  */
10832 +       if (fs_info->devfsd_task != current)
10833 +               return -EPERM;
10834 +       info->major = 0;
10835 +       info->minor = 0;
10836 +       /*  Block for a new entry  */
10837 +       set_current_state(TASK_INTERRUPTIBLE);
10838 +       add_wait_queue(&fs_info->devfsd_wait_queue, &wait);
10839 +       while (devfsd_queue_empty(fs_info)) {
10840 +               fs_info->devfsd_sleeping = TRUE;
10841 +               wake_up(&fs_info->revalidate_wait_queue);
10842 +               schedule();
10843 +               fs_info->devfsd_sleeping = FALSE;
10844 +               if (signal_pending(current)) {
10845 +                       remove_wait_queue(&fs_info->devfsd_wait_queue, &wait);
10846 +                       __set_current_state(TASK_RUNNING);
10847 +                       return -EINTR;
10848 +               }
10849 +               set_current_state(TASK_INTERRUPTIBLE);
10850 +       }
10851 +       remove_wait_queue(&fs_info->devfsd_wait_queue, &wait);
10852 +       __set_current_state(TASK_RUNNING);
10853 +       /*  Now play with the data  */
10854 +       ival = atomic_read(&fs_info->devfsd_overrun_count);
10855 +       info->overrun_count = ival;
10856 +       entry = fs_info->devfsd_first_event;
10857 +       info->type = entry->type;
10858 +       info->mode = entry->mode;
10859 +       info->uid = entry->uid;
10860 +       info->gid = entry->gid;
10861 +       de = entry->de;
10862 +       if (S_ISCHR(de->mode) || S_ISBLK(de->mode)) {
10863 +               info->major = MAJOR(de->u.dev);
10864 +               info->minor = MINOR(de->u.dev);
10865 +       }
10866 +       pos = devfs_generate_path(de, info->devname, DEVFS_PATHLEN);
10867 +       if (pos < 0)
10868 +               return pos;
10869 +       info->namelen = DEVFS_PATHLEN - pos - 1;
10870 +       if (info->mode == 0)
10871 +               info->mode = de->mode;
10872 +       devname_offset = info->devname - (char *)info;
10873 +       rpos = *ppos;
10874 +       if (rpos < devname_offset) {
10875 +               /*  Copy parts of the header  */
10876 +               tlen = devname_offset - rpos;
10877 +               if (tlen > len)
10878 +                       tlen = len;
10879 +               if (copy_to_user(buf, (char *)info + rpos, tlen)) {
10880 +                       return -EFAULT;
10881 +               }
10882 +               rpos += tlen;
10883 +               buf += tlen;
10884 +               len -= tlen;
10885 +       }
10886 +       if ((rpos >= devname_offset) && (len > 0)) {
10887 +               /*  Copy the name  */
10888 +               tlen = info->namelen + 1;
10889 +               if (tlen > len)
10890 +                       tlen = len;
10891 +               else
10892 +                       done = TRUE;
10893 +               if (copy_to_user
10894 +                   (buf, info->devname + pos + rpos - devname_offset, tlen)) {
10895 +                       return -EFAULT;
10896 +               }
10897 +               rpos += tlen;
10898 +       }
10899 +       tlen = rpos - *ppos;
10900 +       if (done) {
10901 +               devfs_handle_t parent;
10902 +
10903 +               spin_lock(&fs_info->devfsd_buffer_lock);
10904 +               fs_info->devfsd_first_event = entry->next;
10905 +               if (entry->next == NULL)
10906 +                       fs_info->devfsd_last_event = NULL;
10907 +               spin_unlock(&fs_info->devfsd_buffer_lock);
10908 +               for (; de != NULL; de = parent) {
10909 +                       parent = de->parent;
10910 +                       devfs_put(de);
10911 +               }
10912 +               kmem_cache_free(devfsd_buf_cache, entry);
10913 +               if (ival > 0)
10914 +                       atomic_sub(ival, &fs_info->devfsd_overrun_count);
10915 +               *ppos = 0;
10916 +       } else
10917 +               *ppos = rpos;
10918 +       return tlen;
10919 +}                              /*  End Function devfsd_read  */
10920 +
10921 +static int devfsd_ioctl(struct inode *inode, struct file *file,
10922 +                       unsigned int cmd, unsigned long arg)
10923 +{
10924 +       int ival;
10925 +       struct fs_info *fs_info = inode->i_sb->s_fs_info;
10926 +
10927 +       switch (cmd) {
10928 +       case DEVFSDIOC_GET_PROTO_REV:
10929 +               ival = DEVFSD_PROTOCOL_REVISION_KERNEL;
10930 +               if (copy_to_user((void __user *)arg, &ival, sizeof ival))
10931 +                       return -EFAULT;
10932 +               break;
10933 +       case DEVFSDIOC_SET_EVENT_MASK:
10934 +               /*  Ensure only one reader has access to the queue. This scheme will
10935 +                  work even if the global kernel lock were to be removed, because it
10936 +                  doesn't matter who gets in first, as long as only one gets it  */
10937 +               if (fs_info->devfsd_task == NULL) {
10938 +                       static DEFINE_SPINLOCK(lock);
10939 +
10940 +                       if (!spin_trylock(&lock))
10941 +                               return -EBUSY;
10942 +                       if (fs_info->devfsd_task != NULL) {     /*  We lost the race...  */
10943 +                               spin_unlock(&lock);
10944 +                               return -EBUSY;
10945 +                       }
10946 +                       fs_info->devfsd_task = current;
10947 +                       spin_unlock(&lock);
10948 +                       fs_info->devfsd_pgrp =
10949 +                           (process_group(current) ==
10950 +                            current->pid) ? process_group(current) : 0;
10951 +                       fs_info->devfsd_file = file;
10952 +                       fs_info->devfsd_info =
10953 +                           kmalloc(sizeof *fs_info->devfsd_info, GFP_KERNEL);
10954 +                       if (!fs_info->devfsd_info) {
10955 +                               devfsd_close(inode, file);
10956 +                               return -ENOMEM;
10957 +                       }
10958 +               } else if (fs_info->devfsd_task != current)
10959 +                       return -EBUSY;
10960 +               fs_info->devfsd_event_mask = arg;       /*  Let the masses come forth  */
10961 +               break;
10962 +       case DEVFSDIOC_RELEASE_EVENT_QUEUE:
10963 +               if (fs_info->devfsd_file != file)
10964 +                       return -EPERM;
10965 +               return devfsd_close(inode, file);
10966 +               /*break; */
10967 +#ifdef CONFIG_DEVFS_DEBUG
10968 +       case DEVFSDIOC_SET_DEBUG_MASK:
10969 +               if (copy_from_user(&ival, (void __user *)arg, sizeof ival))
10970 +                       return -EFAULT;
10971 +               devfs_debug = ival;
10972 +               break;
10973 +#endif
10974 +       default:
10975 +               return -ENOIOCTLCMD;
10976 +       }
10977 +       return 0;
10978 +}                              /*  End Function devfsd_ioctl  */
10979 +
10980 +static int devfsd_close(struct inode *inode, struct file *file)
10981 +{
10982 +       struct devfsd_buf_entry *entry, *next;
10983 +       struct fs_info *fs_info = inode->i_sb->s_fs_info;
10984 +
10985 +       if (fs_info->devfsd_file != file)
10986 +               return 0;
10987 +       fs_info->devfsd_event_mask = 0;
10988 +       fs_info->devfsd_file = NULL;
10989 +       spin_lock(&fs_info->devfsd_buffer_lock);
10990 +       entry = fs_info->devfsd_first_event;
10991 +       fs_info->devfsd_first_event = NULL;
10992 +       fs_info->devfsd_last_event = NULL;
10993 +       kfree(fs_info->devfsd_info);
10994 +       fs_info->devfsd_info = NULL;
10995 +       spin_unlock(&fs_info->devfsd_buffer_lock);
10996 +       fs_info->devfsd_pgrp = 0;
10997 +       fs_info->devfsd_task = NULL;
10998 +       wake_up(&fs_info->revalidate_wait_queue);
10999 +       for (; entry; entry = next) {
11000 +               next = entry->next;
11001 +               kmem_cache_free(devfsd_buf_cache, entry);
11002 +       }
11003 +       return 0;
11004 +}                              /*  End Function devfsd_close  */
11005 +
11006 +#ifdef CONFIG_DEVFS_DEBUG
11007 +static ssize_t stat_read(struct file *file, char __user *buf, size_t len,
11008 +                        loff_t * ppos)
11009 +{
11010 +       ssize_t num;
11011 +       char txt[80];
11012 +
11013 +       num = sprintf(txt, "Number of entries: %u  number of bytes: %u\n",
11014 +                     stat_num_entries, stat_num_bytes) + 1;
11015 +       if (*ppos >= num)
11016 +               return 0;
11017 +       if (*ppos + len > num)
11018 +               len = num - *ppos;
11019 +       if (copy_to_user(buf, txt + *ppos, len))
11020 +               return -EFAULT;
11021 +       *ppos += len;
11022 +       return len;
11023 +}                              /*  End Function stat_read  */
11024 +#endif
11025 +
11026 +static int __init init_devfs_fs(void)
11027 +{
11028 +       int err;
11029 +       int major;
11030 +       struct devfs_entry *devfsd;
11031 +#ifdef CONFIG_DEVFS_DEBUG
11032 +       struct devfs_entry *stat;
11033 +#endif
11034 +
11035 +       if (_devfs_get_root_entry() == NULL)
11036 +               return -ENOMEM;
11037 +
11038 +       printk(KERN_INFO "%s: %s Richard Gooch (rgooch@atnf.csiro.au)\n",
11039 +              DEVFS_NAME, DEVFS_VERSION);
11040 +       devfsd_buf_cache = kmem_cache_create("devfsd_event",
11041 +                                            sizeof(struct devfsd_buf_entry),
11042 +                                            0, 0, NULL, NULL);
11043 +       if (!devfsd_buf_cache)
11044 +               OOPS("(): unable to allocate event slab\n");
11045 +#ifdef CONFIG_DEVFS_DEBUG
11046 +       devfs_debug = devfs_debug_init;
11047 +       printk(KERN_INFO "%s: devfs_debug: 0x%0x\n", DEVFS_NAME, devfs_debug);
11048 +#endif
11049 +       printk(KERN_INFO "%s: boot_options: 0x%0x\n", DEVFS_NAME, boot_options);
11050 +
11051 +       /* register special device for devfsd communication */
11052 +       major = register_chrdev(0, "devfs", &devfs_fops);
11053 +       if (major < 0)
11054 +               return major;
11055 +
11056 +       /*  And create the entry for ".devfsd"  */
11057 +       devfsd = _devfs_alloc_entry(".devfsd", 0, S_IFCHR | S_IRUSR | S_IWUSR);
11058 +       if (devfsd == NULL)
11059 +               return -ENOMEM;
11060 +       devfsd->u.dev = MKDEV(major, 0);
11061 +       _devfs_append_entry(root_entry, devfsd, NULL);
11062 +
11063 +#ifdef CONFIG_DEVFS_DEBUG
11064 +       stat = _devfs_alloc_entry(".stat", 0, S_IFCHR | S_IRUGO);
11065 +       if (stat == NULL)
11066 +               return -ENOMEM;
11067 +       stat->u.dev = MKDEV(major, 1);
11068 +       _devfs_append_entry(root_entry, stat, NULL);
11069 +#endif
11070 +
11071 +       err = register_filesystem(&devfs_fs_type);
11072 +       return err;
11073 +}                              /*  End Function init_devfs_fs  */
11074 +
11075 +void __init mount_devfs_fs(void)
11076 +{
11077 +       int err;
11078 +
11079 +       if (!(boot_options & OPTION_MOUNT))
11080 +               return;
11081 +       err = do_mount("none", "/dev", "devfs", 0, NULL);
11082 +       if (err == 0)
11083 +               printk(KERN_INFO "Mounted devfs on /dev\n");
11084 +       else
11085 +               PRINTK("(): unable to mount devfs, err: %d\n", err);
11086 +}                              /*  End Function mount_devfs_fs  */
11087 +
11088 +module_init(init_devfs_fs)
11089 diff -urN linux-2.6.19.old/fs/devfs/Makefile linux-2.6.19.dev/fs/devfs/Makefile
11090 --- linux-2.6.19.old/fs/devfs/Makefile  1970-01-01 01:00:00.000000000 +0100
11091 +++ linux-2.6.19.dev/fs/devfs/Makefile  2006-12-14 03:12:59.000000000 +0100
11092 @@ -0,0 +1,8 @@
11093 +#
11094 +# Makefile for the linux devfs-filesystem routines.
11095 +#
11096 +
11097 +obj-$(CONFIG_DEVFS_FS) += devfs.o
11098 +
11099 +devfs-objs := base.o util.o
11100 +
11101 diff -urN linux-2.6.19.old/fs/devfs/util.c linux-2.6.19.dev/fs/devfs/util.c
11102 --- linux-2.6.19.old/fs/devfs/util.c    1970-01-01 01:00:00.000000000 +0100
11103 +++ linux-2.6.19.dev/fs/devfs/util.c    2006-12-14 03:12:59.000000000 +0100
11104 @@ -0,0 +1,97 @@
11105 +/*  devfs (Device FileSystem) utilities.
11106 +
11107 +    Copyright (C) 1999-2002  Richard Gooch
11108 +
11109 +    This library is free software; you can redistribute it and/or
11110 +    modify it under the terms of the GNU Library General Public
11111 +    License as published by the Free Software Foundation; either
11112 +    version 2 of the License, or (at your option) any later version.
11113 +
11114 +    This library is distributed in the hope that it will be useful,
11115 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
11116 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11117 +    Library General Public License for more details.
11118 +
11119 +    You should have received a copy of the GNU Library General Public
11120 +    License along with this library; if not, write to the Free
11121 +    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
11122 +
11123 +    Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
11124 +    The postal address is:
11125 +      Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
11126 +
11127 +    ChangeLog
11128 +
11129 +    19991031   Richard Gooch <rgooch@atnf.csiro.au>
11130 +               Created.
11131 +    19991103   Richard Gooch <rgooch@atnf.csiro.au>
11132 +               Created <_devfs_convert_name> and supported SCSI and IDE CD-ROMs
11133 +    20000203   Richard Gooch <rgooch@atnf.csiro.au>
11134 +               Changed operations pointer type to void *.
11135 +    20000621   Richard Gooch <rgooch@atnf.csiro.au>
11136 +               Changed interface to <devfs_register_series>.
11137 +    20000622   Richard Gooch <rgooch@atnf.csiro.au>
11138 +               Took account of interface change to <devfs_mk_symlink>.
11139 +               Took account of interface change to <devfs_mk_dir>.
11140 +    20010519   Richard Gooch <rgooch@atnf.csiro.au>
11141 +               Documentation cleanup.
11142 +    20010709   Richard Gooch <rgooch@atnf.csiro.au>
11143 +               Created <devfs_*alloc_major> and <devfs_*alloc_devnum>.
11144 +    20010710   Richard Gooch <rgooch@atnf.csiro.au>
11145 +               Created <devfs_*alloc_unique_number>.
11146 +    20010730   Richard Gooch <rgooch@atnf.csiro.au>
11147 +               Documentation typo fix.
11148 +    20010806   Richard Gooch <rgooch@atnf.csiro.au>
11149 +               Made <block_semaphore> and <char_semaphore> private.
11150 +    20010813   Richard Gooch <rgooch@atnf.csiro.au>
11151 +               Fixed bug in <devfs_alloc_unique_number>: limited to 128 numbers
11152 +    20010818   Richard Gooch <rgooch@atnf.csiro.au>
11153 +               Updated major masks up to Linus' "no new majors" proclamation.
11154 +              Block: were 126 now 122 free, char: were 26 now 19 free.
11155 +    20020324   Richard Gooch <rgooch@atnf.csiro.au>
11156 +               Fixed bug in <devfs_alloc_unique_number>: was clearing beyond
11157 +              bitfield.
11158 +    20020326   Richard Gooch <rgooch@atnf.csiro.au>
11159 +               Fixed bitfield data type for <devfs_*alloc_devnum>.
11160 +               Made major bitfield type and initialiser 64 bit safe.
11161 +    20020413   Richard Gooch <rgooch@atnf.csiro.au>
11162 +               Fixed shift warning on 64 bit machines.
11163 +    20020428   Richard Gooch <rgooch@atnf.csiro.au>
11164 +               Copied and used macro for error messages from fs/devfs/base.c 
11165 +    20021013   Richard Gooch <rgooch@atnf.csiro.au>
11166 +               Documentation fix.
11167 +    20030101   Adam J. Richter <adam@yggdrasil.com>
11168 +               Eliminate DEVFS_SPECIAL_{CHR,BLK}.  Use mode_t instead.
11169 +    20030106   Christoph Hellwig <hch@infradead.org>
11170 +               Rewrite devfs_{,de}alloc_devnum to look like C code.
11171 +*/
11172 +#include <linux/module.h>
11173 +#include <linux/init.h>
11174 +#include <linux/devfs_fs_kernel.h>
11175 +#include <linux/slab.h>
11176 +#include <linux/vmalloc.h>
11177 +#include <linux/genhd.h>
11178 +#include <linux/bitops.h>
11179 +
11180 +int devfs_register_tape(const char *name)
11181 +{
11182 +       char tname[32], dest[64];
11183 +       static unsigned int tape_counter;
11184 +       unsigned int n = tape_counter++;
11185 +
11186 +       sprintf(dest, "../%s", name);
11187 +       sprintf(tname, "tapes/tape%u", n);
11188 +       devfs_mk_symlink(tname, dest);
11189 +
11190 +       return n;
11191 +}
11192 +
11193 +EXPORT_SYMBOL(devfs_register_tape);
11194 +
11195 +void devfs_unregister_tape(int num)
11196 +{
11197 +       if (num >= 0)
11198 +               devfs_remove("tapes/tape%u", num);
11199 +}
11200 +
11201 +EXPORT_SYMBOL(devfs_unregister_tape);
11202 diff -urN linux-2.6.19.old/fs/Kconfig linux-2.6.19.dev/fs/Kconfig
11203 --- linux-2.6.19.old/fs/Kconfig 2006-11-29 22:57:37.000000000 +0100
11204 +++ linux-2.6.19.dev/fs/Kconfig 2006-12-14 03:12:59.000000000 +0100
11205 @@ -957,6 +957,56 @@
11206           building a kernel for install/rescue disks or your system is very
11207           limited in memory.
11208  
11209 +config DEVFS_FS
11210 +       bool "/dev file system support (OBSOLETE)"
11211 +       depends on EXPERIMENTAL
11212 +       help
11213 +         This is support for devfs, a virtual file system (like /proc) which
11214 +         provides the file system interface to device drivers, normally found
11215 +         in /dev. Devfs does not depend on major and minor number
11216 +         allocations. Device drivers register entries in /dev which then
11217 +         appear automatically, which means that the system administrator does
11218 +         not have to create character and block special device files in the
11219 +         /dev directory using the mknod command (or MAKEDEV script) anymore.
11220 +
11221 +         This is work in progress. If you want to use this, you *must* read
11222 +         the material in <file:Documentation/filesystems/devfs/>, especially
11223 +         the file README there.
11224 +
11225 +         Note that devfs no longer manages /dev/pts!  If you are using UNIX98
11226 +         ptys, you will also need to mount the /dev/pts filesystem (devpts).
11227 +
11228 +         Note that devfs has been obsoleted by udev,
11229 +         <http://www.kernel.org/pub/linux/utils/kernel/hotplug/>.
11230 +         It has been stripped down to a bare minimum and is only provided for
11231 +         legacy installations that use its naming scheme which is
11232 +         unfortunately different from the names normal Linux installations
11233 +         use.
11234 +
11235 +         If unsure, say N.
11236 +
11237 +config DEVFS_MOUNT
11238 +       bool "Automatically mount at boot"
11239 +       depends on DEVFS_FS
11240 +       help
11241 +         This option appears if you have CONFIG_DEVFS_FS enabled. Setting
11242 +         this to 'Y' will make the kernel automatically mount devfs onto /dev
11243 +         when the system is booted, before the init thread is started.
11244 +         You can override this with the "devfs=nomount" boot option.
11245 +
11246 +         If unsure, say N.
11247 +
11248 +config DEVFS_DEBUG
11249 +       bool "Debug devfs"
11250 +       depends on DEVFS_FS
11251 +       help
11252 +         If you say Y here, then the /dev file system code will generate
11253 +         debugging messages. See the file
11254 +         <file:Documentation/filesystems/devfs/boot-options> for more
11255 +         details.
11256 +
11257 +         If unsure, say N.
11258 +
11259  config SYSFS
11260         bool "sysfs file system support" if EMBEDDED
11261         default y
11262 diff -urN linux-2.6.19.old/fs/Makefile linux-2.6.19.dev/fs/Makefile
11263 --- linux-2.6.19.old/fs/Makefile        2006-11-29 22:57:37.000000000 +0100
11264 +++ linux-2.6.19.dev/fs/Makefile        2006-12-14 03:12:59.000000000 +0100
11265 @@ -76,6 +76,7 @@
11266  obj-$(CONFIG_VFAT_FS)          += vfat/
11267  obj-$(CONFIG_BFS_FS)           += bfs/
11268  obj-$(CONFIG_ISO9660_FS)       += isofs/
11269 +obj-$(CONFIG_DEVFS_FS)         += devfs/
11270  obj-$(CONFIG_HFSPLUS_FS)       += hfsplus/ # Before hfs to find wrapped HFS+
11271  obj-$(CONFIG_HFS_FS)           += hfs/
11272  obj-$(CONFIG_ECRYPT_FS)                += ecryptfs/
11273 diff -urN linux-2.6.19.old/fs/partitions/check.c linux-2.6.19.dev/fs/partitions/check.c
11274 --- linux-2.6.19.old/fs/partitions/check.c      2006-11-29 22:57:37.000000000 +0100
11275 +++ linux-2.6.19.dev/fs/partitions/check.c      2006-12-14 03:12:59.000000000 +0100
11276 @@ -18,8 +18,10 @@
11277  #include <linux/fs.h>
11278  #include <linux/kmod.h>
11279  #include <linux/ctype.h>
11280 +#include <linux/devfs_fs_kernel.h>
11281  
11282  #include "check.h"
11283 +#include "devfs.h"
11284  
11285  #include "acorn.h"
11286  #include "amiga.h"
11287 @@ -159,11 +161,18 @@
11288         if (!state)
11289                 return NULL;
11290  
11291 -       disk_name(hd, 0, state->name);
11292 -       printk(KERN_INFO " %s:", state->name);
11293 -       if (isdigit(state->name[strlen(state->name)-1]))
11294 +#ifdef CONFIG_DEVFS_FS
11295 +       if (hd->devfs_name[0] != '\0') {
11296 +               printk(KERN_INFO " /dev/%s:", hd->devfs_name);
11297                 sprintf(state->name, "p");
11298 -
11299 +       }
11300 +#endif
11301 +       else {
11302 +               disk_name(hd, 0, state->name);
11303 +               printk(KERN_INFO " %s:", state->name);
11304 +               if (isdigit(state->name[strlen(state->name)-1]))
11305 +                       sprintf(state->name, "p");
11306 +       }
11307         state->limit = hd->minors;
11308         i = res = 0;
11309         while (!res && check_part[i]) {
11310 @@ -319,7 +328,7 @@
11311         p->nr_sects = 0;
11312         p->ios[0] = p->ios[1] = 0;
11313         p->sectors[0] = p->sectors[1] = 0;
11314 -       sysfs_remove_link(&p->kobj, "subsystem");
11315 +       devfs_remove("%s/part%d", disk->devfs_name, part);
11316         if (p->holder_dir)
11317                 kobject_unregister(p->holder_dir);
11318         kobject_uevent(&p->kobj, KOBJ_REMOVE);
11319 @@ -339,7 +348,10 @@
11320         p->start_sect = start;
11321         p->nr_sects = len;
11322         p->partno = part;
11323 -       p->policy = disk->policy;
11324 +
11325 +       devfs_mk_bdev(MKDEV(disk->major, disk->first_minor + part),
11326 +                       S_IFBLK|S_IRUSR|S_IWUSR,
11327 +                       "%s/part%d", disk->devfs_name, part);
11328  
11329         if (isdigit(disk->kobj.name[strlen(disk->kobj.name)-1]))
11330                 snprintf(p->kobj.name,KOBJ_NAME_LEN,"%sp%d",disk->kobj.name,part);
11331 @@ -444,8 +456,14 @@
11332         disk_sysfs_add_subdirs(disk);
11333  
11334         /* No minors to use for partitions */
11335 -       if (disk->minors == 1)
11336 +       if (disk->minors == 1) {
11337 +               if (disk->devfs_name[0] != '\0')
11338 +                       devfs_add_disk(disk);
11339                 goto exit;
11340 +       }
11341 +
11342 +       /* always add handle for the whole disk */
11343 +       devfs_add_partitioned(disk);
11344  
11345         /* No such device (e.g., media were just removed) */
11346         if (!get_capacity(disk))
11347 @@ -553,6 +571,8 @@
11348         disk_stat_set_all(disk, 0);
11349         disk->stamp = 0;
11350  
11351 +       devfs_remove_disk(disk);
11352 +
11353         kobject_uevent(&disk->kobj, KOBJ_REMOVE);
11354         if (disk->holder_dir)
11355                 kobject_unregister(disk->holder_dir);
11356 diff -urN linux-2.6.19.old/fs/partitions/devfs.c linux-2.6.19.dev/fs/partitions/devfs.c
11357 --- linux-2.6.19.old/fs/partitions/devfs.c      1970-01-01 01:00:00.000000000 +0100
11358 +++ linux-2.6.19.dev/fs/partitions/devfs.c      2006-12-14 03:12:59.000000000 +0100
11359 @@ -0,0 +1,130 @@
11360 +/*
11361 + * This tries to keep block devices away from devfs as much as possible.
11362 + */
11363 +#include <linux/fs.h>
11364 +#include <linux/devfs_fs_kernel.h>
11365 +#include <linux/vmalloc.h>
11366 +#include <linux/genhd.h>
11367 +#include <linux/bitops.h>
11368 +#include <linux/mutex.h>
11369 +
11370 +
11371 +struct unique_numspace {
11372 +       u32               num_free;          /*  Num free in bits       */
11373 +       u32               length;            /*  Array length in bytes  */
11374 +       unsigned long     *bits;
11375 +       struct semaphore  mutex;
11376 +};
11377 +
11378 +static DEFINE_MUTEX(numspace_mutex);
11379 +
11380 +static int expand_numspace(struct unique_numspace *s)
11381 +{
11382 +       u32 length;
11383 +       void *bits;
11384 +
11385 +       if (s->length < 16)
11386 +               length = 16;
11387 +       else
11388 +               length = s->length << 1;
11389 +
11390 +       bits = vmalloc(length);
11391 +       if (!bits)
11392 +               return -ENOMEM;
11393 +       if (s->bits) {
11394 +               memcpy(bits, s->bits, s->length);
11395 +               vfree(s->bits);
11396 +       }
11397 +               
11398 +       s->num_free = (length - s->length) << 3;
11399 +       s->bits = bits;
11400 +       memset(bits + s->length, 0, length - s->length);
11401 +       s->length = length;
11402 +
11403 +       return 0;
11404 +}
11405 +
11406 +static int alloc_unique_number(struct unique_numspace *s)
11407 +{
11408 +       int rval = 0;
11409 +
11410 +       mutex_lock(&numspace_mutex);
11411 +       if (s->num_free < 1)
11412 +               rval = expand_numspace(s);
11413 +       if (!rval) {
11414 +               rval = find_first_zero_bit(s->bits, s->length << 3);
11415 +               --s->num_free;
11416 +               __set_bit(rval, s->bits);
11417 +       }
11418 +       mutex_unlock(&numspace_mutex);
11419 +
11420 +       return rval;
11421 +}
11422 +
11423 +static void dealloc_unique_number(struct unique_numspace *s, int number)
11424 +{
11425 +       int old_val;
11426 +
11427 +       if (number >= 0) {
11428 +               mutex_lock(&numspace_mutex);
11429 +               old_val = __test_and_clear_bit(number, s->bits);
11430 +               if (old_val)
11431 +                       ++s->num_free;
11432 +               mutex_unlock(&numspace_mutex);
11433 +       }
11434 +}
11435 +
11436 +static struct unique_numspace disc_numspace;
11437 +static struct unique_numspace cdrom_numspace;
11438 +
11439 +void devfs_add_partitioned(struct gendisk *disk)
11440 +{
11441 +       char dirname[64], symlink[16];
11442 +
11443 +       devfs_mk_dir(disk->devfs_name);
11444 +       devfs_mk_bdev(MKDEV(disk->major, disk->first_minor),
11445 +                       S_IFBLK|S_IRUSR|S_IWUSR,
11446 +                       "%s/disc", disk->devfs_name);
11447 +
11448 +       disk->number = alloc_unique_number(&disc_numspace);
11449 +
11450 +       sprintf(symlink, "discs/disc%d", disk->number);
11451 +       sprintf(dirname, "../%s", disk->devfs_name);
11452 +       devfs_mk_symlink(symlink, dirname);
11453 +
11454 +}
11455 +
11456 +void devfs_add_disk(struct gendisk *disk)
11457 +{
11458 +       devfs_mk_bdev(MKDEV(disk->major, disk->first_minor),
11459 +                       (disk->flags & GENHD_FL_CD) ?
11460 +                               S_IFBLK|S_IRUGO|S_IWUGO :
11461 +                               S_IFBLK|S_IRUSR|S_IWUSR,
11462 +                       "%s", disk->devfs_name);
11463 +
11464 +       if (disk->flags & GENHD_FL_CD) {
11465 +               char dirname[64], symlink[16];
11466 +
11467 +               disk->number = alloc_unique_number(&cdrom_numspace);
11468 +
11469 +               sprintf(symlink, "cdroms/cdrom%d", disk->number);
11470 +               sprintf(dirname, "../%s", disk->devfs_name);
11471 +               devfs_mk_symlink(symlink, dirname);
11472 +       }
11473 +}
11474 +
11475 +void devfs_remove_disk(struct gendisk *disk)
11476 +{
11477 +       if (disk->minors != 1) {
11478 +               devfs_remove("discs/disc%d", disk->number);
11479 +               dealloc_unique_number(&disc_numspace, disk->number);
11480 +               devfs_remove("%s/disc", disk->devfs_name);
11481 +       }
11482 +       if (disk->flags & GENHD_FL_CD) {
11483 +               devfs_remove("cdroms/cdrom%d", disk->number);
11484 +               dealloc_unique_number(&cdrom_numspace, disk->number);
11485 +       }
11486 +       devfs_remove(disk->devfs_name);
11487 +}
11488 +
11489 +
11490 diff -urN linux-2.6.19.old/fs/partitions/devfs.h linux-2.6.19.dev/fs/partitions/devfs.h
11491 --- linux-2.6.19.old/fs/partitions/devfs.h      1970-01-01 01:00:00.000000000 +0100
11492 +++ linux-2.6.19.dev/fs/partitions/devfs.h      2006-12-14 03:12:59.000000000 +0100
11493 @@ -0,0 +1,10 @@
11494 +
11495 +#ifdef CONFIG_DEVFS_FS
11496 +void devfs_add_disk(struct gendisk *dev);
11497 +void devfs_add_partitioned(struct gendisk *dev);
11498 +void devfs_remove_disk(struct gendisk *dev);
11499 +#else
11500 +# define devfs_add_disk(disk)                  do { } while (0)
11501 +# define devfs_add_partitioned(disk)           do { } while (0)
11502 +# define devfs_remove_disk(disk)               do { } while (0)
11503 +#endif
11504 diff -urN linux-2.6.19.old/fs/partitions/Makefile linux-2.6.19.dev/fs/partitions/Makefile
11505 --- linux-2.6.19.old/fs/partitions/Makefile     2006-11-29 22:57:37.000000000 +0100
11506 +++ linux-2.6.19.dev/fs/partitions/Makefile     2006-12-14 03:12:59.000000000 +0100
11507 @@ -4,6 +4,7 @@
11508  
11509  obj-$(CONFIG_BLOCK) := check.o
11510  
11511 +obj-$(CONFIG_DEVFS_FS) += devfs.o
11512  obj-$(CONFIG_ACORN_PARTITION) += acorn.o
11513  obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
11514  obj-$(CONFIG_ATARI_PARTITION) += atari.o
11515 diff -urN linux-2.6.19.old/include/asm-ppc/ocp.h linux-2.6.19.dev/include/asm-ppc/ocp.h
11516 --- linux-2.6.19.old/include/asm-ppc/ocp.h      2006-11-29 22:57:37.000000000 +0100
11517 +++ linux-2.6.19.dev/include/asm-ppc/ocp.h      2006-12-14 03:12:59.000000000 +0100
11518 @@ -26,6 +26,7 @@
11519  
11520  #include <linux/init.h>
11521  #include <linux/list.h>
11522 +#include <linux/devfs_fs_kernel.h>
11523  #include <linux/device.h>
11524  
11525  #include <asm/mmu.h>
11526 diff -urN linux-2.6.19.old/include/linux/compat_ioctl.h linux-2.6.19.dev/include/linux/compat_ioctl.h
11527 --- linux-2.6.19.old/include/linux/compat_ioctl.h       2006-11-29 22:57:37.000000000 +0100
11528 +++ linux-2.6.19.dev/include/linux/compat_ioctl.h       2006-12-14 03:12:59.000000000 +0100
11529 @@ -571,6 +571,11 @@
11530  COMPATIBLE_IOCTL(AUTOFS_IOC_ASKREGHOST)
11531  COMPATIBLE_IOCTL(AUTOFS_IOC_TOGGLEREGHOST)
11532  COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT)
11533 +/* DEVFS */
11534 +COMPATIBLE_IOCTL(DEVFSDIOC_GET_PROTO_REV)
11535 +COMPATIBLE_IOCTL(DEVFSDIOC_SET_EVENT_MASK)
11536 +COMPATIBLE_IOCTL(DEVFSDIOC_RELEASE_EVENT_QUEUE)
11537 +COMPATIBLE_IOCTL(DEVFSDIOC_SET_DEBUG_MASK)
11538  /* Raw devices */
11539  COMPATIBLE_IOCTL(RAW_SETBIND)
11540  COMPATIBLE_IOCTL(RAW_GETBIND)
11541 diff -urN linux-2.6.19.old/include/linux/devfs_fs.h linux-2.6.19.dev/include/linux/devfs_fs.h
11542 --- linux-2.6.19.old/include/linux/devfs_fs.h   1970-01-01 01:00:00.000000000 +0100
11543 +++ linux-2.6.19.dev/include/linux/devfs_fs.h   2006-12-14 03:12:59.000000000 +0100
11544 @@ -0,0 +1,41 @@
11545 +#ifndef _LINUX_DEVFS_FS_H
11546 +#define _LINUX_DEVFS_FS_H
11547 +
11548 +#include <linux/ioctl.h>
11549 +
11550 +#define DEVFSD_PROTOCOL_REVISION_KERNEL  5
11551 +
11552 +#define        DEVFSD_IOCTL_BASE       'd'
11553 +
11554 +/*  These are the various ioctls  */
11555 +#define DEVFSDIOC_GET_PROTO_REV         _IOR(DEVFSD_IOCTL_BASE, 0, int)
11556 +#define DEVFSDIOC_SET_EVENT_MASK        _IOW(DEVFSD_IOCTL_BASE, 2, int)
11557 +#define DEVFSDIOC_RELEASE_EVENT_QUEUE   _IOW(DEVFSD_IOCTL_BASE, 3, int)
11558 +#define DEVFSDIOC_SET_DEBUG_MASK        _IOW(DEVFSD_IOCTL_BASE, 4, int)
11559 +
11560 +#define DEVFSD_NOTIFY_REGISTERED    0
11561 +#define DEVFSD_NOTIFY_UNREGISTERED  1
11562 +#define DEVFSD_NOTIFY_ASYNC_OPEN    2
11563 +#define DEVFSD_NOTIFY_CLOSE         3
11564 +#define DEVFSD_NOTIFY_LOOKUP        4
11565 +#define DEVFSD_NOTIFY_CHANGE        5
11566 +#define DEVFSD_NOTIFY_CREATE        6
11567 +#define DEVFSD_NOTIFY_DELETE        7
11568 +
11569 +#define DEVFS_PATHLEN               1024       /*  Never change this otherwise the
11570 +                                                  binary interface will change   */
11571 +
11572 +struct devfsd_notify_struct {  /*  Use native C types to ensure same types in kernel and user space     */
11573 +       unsigned int type;      /*  DEVFSD_NOTIFY_* value                   */
11574 +       unsigned int mode;      /*  Mode of the inode or device entry       */
11575 +       unsigned int major;     /*  Major number of device entry            */
11576 +       unsigned int minor;     /*  Minor number of device entry            */
11577 +       unsigned int uid;       /*  Uid of process, inode or device entry   */
11578 +       unsigned int gid;       /*  Gid of process, inode or device entry   */
11579 +       unsigned int overrun_count;     /*  Number of lost events                   */
11580 +       unsigned int namelen;   /*  Number of characters not including '\0' */
11581 +       /*  The device name MUST come last                                       */
11582 +       char devname[DEVFS_PATHLEN];    /*  This will be '\0' terminated            */
11583 +};
11584 +
11585 +#endif                         /*  _LINUX_DEVFS_FS_H  */
11586 diff -urN linux-2.6.19.old/include/linux/devfs_fs_kernel.h linux-2.6.19.dev/include/linux/devfs_fs_kernel.h
11587 --- linux-2.6.19.old/include/linux/devfs_fs_kernel.h    1970-01-01 01:00:00.000000000 +0100
11588 +++ linux-2.6.19.dev/include/linux/devfs_fs_kernel.h    2006-12-14 03:12:59.000000000 +0100
11589 @@ -0,0 +1,58 @@
11590 +#ifndef _LINUX_DEVFS_FS_KERNEL_H
11591 +#define _LINUX_DEVFS_FS_KERNEL_H
11592 +
11593 +#include <linux/fs.h>
11594 +#include <linux/autoconf.h>
11595 +#include <linux/spinlock.h>
11596 +#include <linux/types.h>
11597 +
11598 +#include <asm/semaphore.h>
11599 +
11600 +#define DEVFS_SUPER_MAGIC                0x1373
11601 +
11602 +#ifdef CONFIG_DEVFS_FS
11603 +extern int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...)
11604 +    __attribute__ ((format(printf, 3, 4)));
11605 +extern int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...)
11606 +    __attribute__ ((format(printf, 3, 4)));
11607 +extern int devfs_mk_symlink(const char *name, const char *link);
11608 +extern int devfs_mk_dir(const char *fmt, ...)
11609 +    __attribute__ ((format(printf, 1, 2)));
11610 +extern void devfs_remove(const char *fmt, ...)
11611 +    __attribute__ ((format(printf, 1, 2)));
11612 +extern int devfs_register_tape(const char *name);
11613 +extern void devfs_unregister_tape(int num);
11614 +extern void mount_devfs_fs(void);
11615 +#else                          /*  CONFIG_DEVFS_FS  */
11616 +static inline int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...)
11617 +{
11618 +       return 0;
11619 +}
11620 +static inline int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...)
11621 +{
11622 +       return 0;
11623 +}
11624 +static inline int devfs_mk_symlink(const char *name, const char *link)
11625 +{
11626 +       return 0;
11627 +}
11628 +static inline int devfs_mk_dir(const char *fmt, ...)
11629 +{
11630 +       return 0;
11631 +}
11632 +static inline void devfs_remove(const char *fmt, ...)
11633 +{
11634 +}
11635 +static inline int devfs_register_tape(const char *name)
11636 +{
11637 +       return -1;
11638 +}
11639 +static inline void devfs_unregister_tape(int num)
11640 +{
11641 +}
11642 +static inline void mount_devfs_fs(void)
11643 +{
11644 +       return;
11645 +}
11646 +#endif                         /*  CONFIG_DEVFS_FS  */
11647 +#endif                         /*  _LINUX_DEVFS_FS_KERNEL_H  */
11648 diff -urN linux-2.6.19.old/include/linux/fb.h linux-2.6.19.dev/include/linux/fb.h
11649 --- linux-2.6.19.old/include/linux/fb.h 2006-11-29 22:57:37.000000000 +0100
11650 +++ linux-2.6.19.dev/include/linux/fb.h 2006-12-14 03:12:59.000000000 +0100
11651 @@ -379,6 +379,7 @@
11652  #include <linux/init.h>
11653  #include <linux/device.h>
11654  #include <linux/workqueue.h>
11655 +#include <linux/devfs_fs_kernel.h>
11656  #include <linux/notifier.h>
11657  #include <linux/list.h>
11658  #include <linux/backlight.h>
11659 diff -urN linux-2.6.19.old/include/linux/genhd.h linux-2.6.19.dev/include/linux/genhd.h
11660 --- linux-2.6.19.old/include/linux/genhd.h      2006-11-29 22:57:37.000000000 +0100
11661 +++ linux-2.6.19.dev/include/linux/genhd.h      2006-12-14 03:12:59.000000000 +0100
11662 @@ -114,6 +114,8 @@
11663         sector_t capacity;
11664  
11665         int flags;
11666 +       char devfs_name[64];            /* devfs crap */
11667 +       int number;                     /* more of the same */
11668         struct device *driverfs_dev;
11669         struct kobject kobj;
11670         struct kobject *holder_dir;
11671 diff -urN linux-2.6.19.old/include/linux/ide.h linux-2.6.19.dev/include/linux/ide.h
11672 --- linux-2.6.19.old/include/linux/ide.h        2006-11-29 22:57:37.000000000 +0100
11673 +++ linux-2.6.19.dev/include/linux/ide.h        2006-12-14 03:12:59.000000000 +0100
11674 @@ -553,6 +553,7 @@
11675         struct hd_driveid       *id;    /* drive model identification info */
11676         struct proc_dir_entry *proc;    /* /proc/ide/ directory entry */
11677         struct ide_settings_s *settings;/* /proc/ide/ drive settings */
11678 +       char            devfs_name[64]; /* devfs crap */
11679  
11680         struct hwif_s           *hwif;  /* actually (ide_hwif_t *) */
11681  
11682 diff -urN linux-2.6.19.old/include/linux/miscdevice.h linux-2.6.19.dev/include/linux/miscdevice.h
11683 --- linux-2.6.19.old/include/linux/miscdevice.h 2006-11-29 22:57:37.000000000 +0100
11684 +++ linux-2.6.19.dev/include/linux/miscdevice.h 2006-12-14 03:12:59.000000000 +0100
11685 @@ -40,6 +40,7 @@
11686         struct list_head list;
11687         struct device *dev;
11688         struct class_device *class;
11689 +       char devfs_name[64];
11690  };
11691  
11692  extern int misc_register(struct miscdevice * misc);
11693 diff -urN linux-2.6.19.old/include/linux/serial_core.h linux-2.6.19.dev/include/linux/serial_core.h
11694 --- linux-2.6.19.old/include/linux/serial_core.h        2006-11-29 22:57:37.000000000 +0100
11695 +++ linux-2.6.19.dev/include/linux/serial_core.h        2006-12-14 03:12:59.000000000 +0100
11696 @@ -339,6 +339,7 @@
11697         struct module           *owner;
11698         const char              *driver_name;
11699         const char              *dev_name;
11700 +       const char              *devfs_name;
11701         int                      major;
11702         int                      minor;
11703         int                      nr;
11704 diff -urN linux-2.6.19.old/include/linux/tty_driver.h linux-2.6.19.dev/include/linux/tty_driver.h
11705 --- linux-2.6.19.old/include/linux/tty_driver.h 2006-11-29 22:57:37.000000000 +0100
11706 +++ linux-2.6.19.dev/include/linux/tty_driver.h 2006-12-14 03:12:59.000000000 +0100
11707 @@ -157,6 +157,7 @@
11708         struct cdev cdev;
11709         struct module   *owner;
11710         const char      *driver_name;
11711 +       const char      *devfs_name;
11712         const char      *name;
11713         int     name_base;      /* offset of printed name */
11714         int     major;          /* major device number */
11715 @@ -251,6 +252,8 @@
11716   *     called.  This is to be used by drivers that have tty devices
11717   *     that can appear and disappear while the main tty driver is
11718   *     registered with the tty core.
11719 + * TTY_DRIVER_NO_DEVFS --- if set, do not create devfs entries. This
11720 + *     is only used by tty_register_driver().
11721   *
11722   * TTY_DRIVER_DEVPTS_MEM -- don't use the standard arrays, instead
11723   *     use dynamic memory keyed through the devpts filesystem.  This
11724 @@ -260,6 +263,7 @@
11725  #define TTY_DRIVER_RESET_TERMIOS       0x0002
11726  #define TTY_DRIVER_REAL_RAW            0x0004
11727  #define TTY_DRIVER_DYNAMIC_DEV         0x0008
11728 +#define TTY_DRIVER_NO_DEVFS            0x0008
11729  #define TTY_DRIVER_DEVPTS_MEM          0x0010
11730  
11731  /* tty driver types */
11732 diff -urN linux-2.6.19.old/include/media/v4l2-dev.h linux-2.6.19.dev/include/media/v4l2-dev.h
11733 --- linux-2.6.19.old/include/media/v4l2-dev.h   2006-11-29 22:57:37.000000000 +0100
11734 +++ linux-2.6.19.dev/include/media/v4l2-dev.h   2006-12-14 03:12:59.000000000 +0100
11735 @@ -315,6 +315,7 @@
11736         /* for videodev.c intenal usage -- please don't touch */
11737         int users;                     /* video_exclusive_{open|close} ... */
11738         struct mutex lock;             /* ... helper function uses these   */
11739 +       char devfs_name[64];           /* devfs */
11740         struct class_device class_dev; /* sysfs */
11741  };
11742  
11743 diff -urN linux-2.6.19.old/include/scsi/scsi_device.h linux-2.6.19.dev/include/scsi/scsi_device.h
11744 --- linux-2.6.19.old/include/scsi/scsi_device.h 2006-11-29 22:57:37.000000000 +0100
11745 +++ linux-2.6.19.dev/include/scsi/scsi_device.h 2006-12-14 03:12:59.000000000 +0100
11746 @@ -74,6 +74,7 @@
11747         unsigned sector_size;   /* size in bytes */
11748  
11749         void *hostdata;         /* available to low-level driver */
11750 +       char devfs_name[256];   /* devfs junk */
11751         char type;
11752         char scsi_level;
11753         char inq_periph_qual;   /* PQ from INQUIRY data */      
11754 diff -urN linux-2.6.19.old/include/sound/core.h linux-2.6.19.dev/include/sound/core.h
11755 --- linux-2.6.19.old/include/sound/core.h       2006-11-29 22:57:37.000000000 +0100
11756 +++ linux-2.6.19.dev/include/sound/core.h       2006-12-14 03:12:59.000000000 +0100
11757 @@ -188,6 +188,8 @@
11758         const struct file_operations *f_ops;    /* file operations */
11759         void *private_data;             /* private data for f_ops->open */
11760         struct class_device *class_dev; /* class device for sysfs */
11761 +       char name[0];                   /* device name for devfs (keep
11762 +                                          at the end of structure) */
11763  };
11764  
11765  /* sound.c */
11766 diff -urN linux-2.6.19.old/init/do_mounts.c linux-2.6.19.dev/init/do_mounts.c
11767 --- linux-2.6.19.old/init/do_mounts.c   2006-11-29 22:57:37.000000000 +0100
11768 +++ linux-2.6.19.dev/init/do_mounts.c   2006-12-14 03:12:59.000000000 +0100
11769 @@ -335,7 +335,7 @@
11770  {
11771         void *data = nfs_root_data();
11772  
11773 -       create_dev("/dev/root", ROOT_DEV);
11774 +       create_dev("/dev/root", ROOT_DEV, root_device_name);
11775         if (data &&
11776             do_mount_root("/dev/root", "nfs", root_mountflags, data) == 0)
11777                 return 1;
11778 @@ -397,7 +397,7 @@
11779         }
11780  #endif
11781  #ifdef CONFIG_BLOCK
11782 -       create_dev("/dev/root", ROOT_DEV);
11783 +       create_dev("/dev/root", ROOT_DEV, root_device_name);
11784         mount_block_root("/dev/root", root_mountflags);
11785  #endif
11786  }
11787 @@ -409,6 +409,8 @@
11788  {
11789         int is_floppy;
11790  
11791 +       mount_devfs();
11792 +
11793         if (root_delay) {
11794                 printk(KERN_INFO "Waiting %dsec before mounting root device...\n",
11795                        root_delay);
11796 @@ -442,8 +444,10 @@
11797  
11798         mount_root();
11799  out:
11800 +       umount_devfs("/dev");
11801         sys_mount(".", "/", NULL, MS_MOVE, NULL);
11802         sys_chroot(".");
11803         security_sb_post_mountroot();
11804 +       mount_devfs_fs ();
11805  }
11806  
11807 diff -urN linux-2.6.19.old/init/do_mounts_devfs.c linux-2.6.19.dev/init/do_mounts_devfs.c
11808 --- linux-2.6.19.old/init/do_mounts_devfs.c     1970-01-01 01:00:00.000000000 +0100
11809 +++ linux-2.6.19.dev/init/do_mounts_devfs.c     2006-12-14 03:12:59.000000000 +0100
11810 @@ -0,0 +1,137 @@
11811 +
11812 +#include <linux/kernel.h>
11813 +#include <linux/dirent.h>
11814 +#include <linux/string.h>
11815 +
11816 +#include "do_mounts.h"
11817 +
11818 +void __init mount_devfs(void)
11819 +{
11820 +       sys_mount("devfs", "/dev", "devfs", 0, NULL);
11821 +}
11822 +
11823 +void __init umount_devfs(char *path)
11824 +{
11825 +       sys_umount(path, 0);
11826 +}
11827 +
11828 +/*
11829 + * If the dir will fit in *buf, return its length.  If it won't fit, return
11830 + * zero.  Return -ve on error.
11831 + */
11832 +static int __init do_read_dir(int fd, void *buf, int len)
11833 +{
11834 +       long bytes, n;
11835 +       char *p = buf;
11836 +       sys_lseek(fd, 0, 0);
11837 +
11838 +       for (bytes = 0; bytes < len; bytes += n) {
11839 +               n = sys_getdents64(fd, (struct linux_dirent64 *)(p + bytes),
11840 +                                       len - bytes);
11841 +               if (n < 0)
11842 +                       return n;
11843 +               if (n == 0)
11844 +                       return bytes;
11845 +       }
11846 +       return 0;
11847 +}
11848 +
11849 +/*
11850 + * Try to read all of a directory.  Returns the contents at *p, which
11851 + * is kmalloced memory.  Returns the number of bytes read at *len.  Returns
11852 + * NULL on error.
11853 + */
11854 +static void * __init read_dir(char *path, int *len)
11855 +{
11856 +       int size;
11857 +       int fd = sys_open(path, 0, 0);
11858 +
11859 +       *len = 0;
11860 +       if (fd < 0)
11861 +               return NULL;
11862 +
11863 +       for (size = 1 << 9; size <= (PAGE_SIZE << MAX_ORDER); size <<= 1) {
11864 +               void *p = kmalloc(size, GFP_KERNEL);
11865 +               int n;
11866 +               if (!p)
11867 +                       break;
11868 +               n = do_read_dir(fd, p, size);
11869 +               if (n > 0) {
11870 +                       sys_close(fd);
11871 +                       *len = n;
11872 +                       return p;
11873 +               }
11874 +               kfree(p);
11875 +               if (n == -EINVAL)
11876 +                       continue;       /* Try a larger buffer */
11877 +               if (n < 0)
11878 +                       break;
11879 +       }
11880 +       sys_close(fd);
11881 +       return NULL;
11882 +}
11883 +
11884 +/*
11885 + * recursively scan <path>, looking for a device node of type <dev>
11886 + */
11887 +static int __init find_in_devfs(char *path, unsigned dev)
11888 +{
11889 +       char *end = path + strlen(path);
11890 +       int rest = path + 64 - end;
11891 +       int size;
11892 +       char *p = read_dir(path, &size);
11893 +       char *s;
11894 +
11895 +       if (!p)
11896 +               return -1;
11897 +       for (s = p; s < p + size; s += ((struct linux_dirent64 *)s)->d_reclen) {
11898 +               struct linux_dirent64 *d = (struct linux_dirent64 *)s;
11899 +               if (strlen(d->d_name) + 2 > rest)
11900 +                       continue;
11901 +               switch (d->d_type) {
11902 +                       case DT_BLK:
11903 +                               sprintf(end, "/%s", d->d_name);
11904 +                               if (bstat(path) != dev)
11905 +                                       break;
11906 +                               kfree(p);
11907 +                               return 0;
11908 +                       case DT_DIR:
11909 +                               if (strcmp(d->d_name, ".") == 0)
11910 +                                       break;
11911 +                               if (strcmp(d->d_name, "..") == 0)
11912 +                                       break;
11913 +                               sprintf(end, "/%s", d->d_name);
11914 +                               if (find_in_devfs(path, dev) < 0)
11915 +                                       break;
11916 +                               kfree(p);
11917 +                               return 0;
11918 +               }
11919 +       }
11920 +       kfree(p);
11921 +       return -1;
11922 +}
11923 +
11924 +/*
11925 + * create a device node called <name> which points to
11926 + * <devfs_name> if possible, otherwise find a device node
11927 + * which matches <dev> and make <name> a symlink pointing to it.
11928 + */
11929 +int __init create_dev(char *name, dev_t dev, char *devfs_name)
11930 +{
11931 +       char path[64];
11932 +
11933 +       sys_unlink(name);
11934 +       if (devfs_name && devfs_name[0]) {
11935 +               if (strncmp(devfs_name, "/dev/", 5) == 0)
11936 +                       devfs_name += 5;
11937 +               sprintf(path, "/dev/%s", devfs_name);
11938 +               if (sys_access(path, 0) == 0)
11939 +                       return sys_symlink(devfs_name, name);
11940 +       }
11941 +       if (!dev)
11942 +               return -1;
11943 +       strcpy(path, "/dev");
11944 +       if (find_in_devfs(path, new_encode_dev(dev)) < 0)
11945 +               return -1;
11946 +       return sys_symlink(path + 5, name);
11947 +}
11948 diff -urN linux-2.6.19.old/init/do_mounts.h linux-2.6.19.dev/init/do_mounts.h
11949 --- linux-2.6.19.old/init/do_mounts.h   2006-11-29 22:57:37.000000000 +0100
11950 +++ linux-2.6.19.dev/init/do_mounts.h   2006-12-14 03:12:59.000000000 +0100
11951 @@ -6,6 +6,7 @@
11952  #include <linux/mount.h>
11953  #include <linux/major.h>
11954  #include <linux/root_dev.h>
11955 +#include <linux/devfs_fs_kernel.h>
11956  
11957  void  change_floppy(char *fmt, ...);
11958  void  mount_block_root(char *name, int flags);
11959 @@ -13,12 +14,25 @@
11960  extern int root_mountflags;
11961  extern char *root_device_name;
11962  
11963 -static inline int create_dev(char *name, dev_t dev)
11964 +#ifdef CONFIG_DEVFS_FS
11965 +
11966 +void mount_devfs(void);
11967 +void umount_devfs(char *path);
11968 +int  create_dev(char *name, dev_t dev, char *devfs_name);
11969 +
11970 +#else
11971 +
11972 +static inline void mount_devfs(void) {}
11973 +static inline void umount_devfs(const char *path) {}
11974 +
11975 +static inline int create_dev(char *name, dev_t dev, char *devfs_name)
11976  {
11977         sys_unlink(name);
11978         return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
11979  }
11980  
11981 +#endif
11982 +
11983  #if BITS_PER_LONG == 32
11984  static inline u32 bstat(char *name)
11985  {
11986 diff -urN linux-2.6.19.old/init/do_mounts_initrd.c linux-2.6.19.dev/init/do_mounts_initrd.c
11987 --- linux-2.6.19.old/init/do_mounts_initrd.c    2006-11-29 22:57:37.000000000 +0100
11988 +++ linux-2.6.19.dev/init/do_mounts_initrd.c    2006-12-14 03:12:59.000000000 +0100
11989 @@ -43,7 +43,7 @@
11990         int pid;
11991  
11992         real_root_dev = new_encode_dev(ROOT_DEV);
11993 -       create_dev("/dev/root.old", Root_RAM0);
11994 +       create_dev("/dev/root.old", Root_RAM0, NULL);
11995         /* mount initrd on rootfs' /root */
11996         mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
11997         sys_mkdir("/old", 0700);
11998 @@ -53,6 +53,7 @@
11999         sys_chdir("/root");
12000         sys_mount(".", "/", NULL, MS_MOVE, NULL);
12001         sys_chroot(".");
12002 +       mount_devfs_fs ();
12003  
12004         current->flags |= PF_NOFREEZE;
12005         pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
12006 @@ -69,6 +70,7 @@
12007         sys_chroot(".");
12008         sys_close(old_fd);
12009         sys_close(root_fd);
12010 +       umount_devfs("/old/dev");
12011  
12012         if (new_decode_dev(real_root_dev) == Root_RAM0) {
12013                 sys_chdir("/old");
12014 @@ -104,7 +106,7 @@
12015  int __init initrd_load(void)
12016  {
12017         if (mount_initrd) {
12018 -               create_dev("/dev/ram", Root_RAM0);
12019 +               create_dev("/dev/ram", Root_RAM0, NULL);
12020                 /*
12021                  * Load the initrd data into /dev/ram0. Execute it as initrd
12022                  * unless /dev/ram0 is supposed to be our actual root device,
12023 diff -urN linux-2.6.19.old/init/do_mounts_md.c linux-2.6.19.dev/init/do_mounts_md.c
12024 --- linux-2.6.19.old/init/do_mounts_md.c        2006-11-29 22:57:37.000000000 +0100
12025 +++ linux-2.6.19.dev/init/do_mounts_md.c        2006-12-14 03:12:59.000000000 +0100
12026 @@ -121,18 +121,19 @@
12027                 int err = 0;
12028                 char *devname;
12029                 mdu_disk_info_t dinfo;
12030 -               char name[16];
12031 +               char name[16], devfs_name[16];
12032  
12033                 minor = md_setup_args[ent].minor;
12034                 partitioned = md_setup_args[ent].partitioned;
12035                 devname = md_setup_args[ent].device_names;
12036  
12037                 sprintf(name, "/dev/md%s%d", partitioned?"_d":"", minor);
12038 +               sprintf(devfs_name, "/dev/md/%s%d", partitioned?"d":"", minor);
12039                 if (partitioned)
12040                         dev = MKDEV(mdp_major, minor << MdpMinorShift);
12041                 else
12042                         dev = MKDEV(MD_MAJOR, minor);
12043 -               create_dev(name, dev);
12044 +               create_dev(name, dev, devfs_name);
12045                 for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
12046                         char *p;
12047                         char comp_name[64];
12048 @@ -267,7 +268,7 @@
12049  
12050  void __init md_run_setup(void)
12051  {
12052 -       create_dev("/dev/md0", MKDEV(MD_MAJOR, 0));
12053 +       create_dev("/dev/md0", MKDEV(MD_MAJOR, 0), "md/0");
12054         if (raid_noautodetect)
12055                 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
12056         else {
12057 diff -urN linux-2.6.19.old/init/main.c linux-2.6.19.dev/init/main.c
12058 --- linux-2.6.19.old/init/main.c        2006-11-29 22:57:37.000000000 +0100
12059 +++ linux-2.6.19.dev/init/main.c        2006-12-14 03:12:59.000000000 +0100
12060 @@ -12,6 +12,7 @@
12061  #include <linux/types.h>
12062  #include <linux/module.h>
12063  #include <linux/proc_fs.h>
12064 +#include <linux/devfs_fs_kernel.h>
12065  #include <linux/kernel.h>
12066  #include <linux/syscalls.h>
12067  #include <linux/string.h>
12068 diff -urN linux-2.6.19.old/init/Makefile linux-2.6.19.dev/init/Makefile
12069 --- linux-2.6.19.old/init/Makefile      2006-11-29 22:57:37.000000000 +0100
12070 +++ linux-2.6.19.dev/init/Makefile      2006-12-14 03:12:59.000000000 +0100
12071 @@ -6,6 +6,7 @@
12072  obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o
12073  
12074  mounts-y                       := do_mounts.o
12075 +mounts-$(CONFIG_DEVFS_FS)      += do_mounts_devfs.o
12076  mounts-$(CONFIG_BLK_DEV_RAM)   += do_mounts_rd.o
12077  mounts-$(CONFIG_BLK_DEV_INITRD)        += do_mounts_initrd.o
12078  mounts-$(CONFIG_BLK_DEV_MD)    += do_mounts_md.o
12079 diff -urN linux-2.6.19.old/mm/shmem.c linux-2.6.19.dev/mm/shmem.c
12080 --- linux-2.6.19.old/mm/shmem.c 2006-11-29 22:57:37.000000000 +0100
12081 +++ linux-2.6.19.dev/mm/shmem.c 2006-12-14 03:12:59.000000000 +0100
12082 @@ -25,6 +25,7 @@
12083  
12084  #include <linux/module.h>
12085  #include <linux/init.h>
12086 +#include <linux/devfs_fs_kernel.h>
12087  #include <linux/fs.h>
12088  #include <linux/xattr.h>
12089  #include <linux/generic_acl.h>
12090 @@ -2427,6 +2428,9 @@
12091                 goto out2;
12092         }
12093  
12094 +#ifdef CONFIG_TMPFS
12095 +       devfs_mk_dir("shm");
12096 +#endif
12097         shm_mnt = vfs_kern_mount(&tmpfs_fs_type, MS_NOUSER,
12098                                 tmpfs_fs_type.name, NULL);
12099         if (IS_ERR(shm_mnt)) {
12100 diff -urN linux-2.6.19.old/mm/tiny-shmem.c linux-2.6.19.dev/mm/tiny-shmem.c
12101 --- linux-2.6.19.old/mm/tiny-shmem.c    2006-11-29 22:57:37.000000000 +0100
12102 +++ linux-2.6.19.dev/mm/tiny-shmem.c    2006-12-14 03:12:59.000000000 +0100
12103 @@ -12,6 +12,7 @@
12104  
12105  #include <linux/fs.h>
12106  #include <linux/init.h>
12107 +#include <linux/devfs_fs_kernel.h>
12108  #include <linux/vfs.h>
12109  #include <linux/mount.h>
12110  #include <linux/file.h>
12111 @@ -32,6 +33,9 @@
12112  {
12113         BUG_ON(register_filesystem(&tmpfs_fs_type) != 0);
12114  
12115 +#ifdef CONFIG_TMPFS
12116 +       devfs_mk_dir("shm");
12117 +#endif
12118         shm_mnt = kern_mount(&tmpfs_fs_type);
12119         BUG_ON(IS_ERR(shm_mnt));
12120  
12121 diff -urN linux-2.6.19.old/net/bluetooth/rfcomm/tty.c linux-2.6.19.dev/net/bluetooth/rfcomm/tty.c
12122 --- linux-2.6.19.old/net/bluetooth/rfcomm/tty.c 2006-11-29 22:57:37.000000000 +0100
12123 +++ linux-2.6.19.dev/net/bluetooth/rfcomm/tty.c 2006-12-14 03:12:59.000000000 +0100
12124 @@ -1039,12 +1039,13 @@
12125  
12126         rfcomm_tty_driver->owner        = THIS_MODULE;
12127         rfcomm_tty_driver->driver_name  = "rfcomm";
12128 +       rfcomm_tty_driver->devfs_name   = "bluetooth/rfcomm/";
12129         rfcomm_tty_driver->name         = "rfcomm";
12130         rfcomm_tty_driver->major        = RFCOMM_TTY_MAJOR;
12131         rfcomm_tty_driver->minor_start  = RFCOMM_TTY_MINOR;
12132         rfcomm_tty_driver->type         = TTY_DRIVER_TYPE_SERIAL;
12133         rfcomm_tty_driver->subtype      = SERIAL_TYPE_NORMAL;
12134 -       rfcomm_tty_driver->flags        = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
12135 +       rfcomm_tty_driver->flags        = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
12136         rfcomm_tty_driver->init_termios = tty_std_termios;
12137         rfcomm_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
12138         tty_set_operations(rfcomm_tty_driver, &rfcomm_ops);
12139 diff -urN linux-2.6.19.old/net/irda/ircomm/ircomm_tty.c linux-2.6.19.dev/net/irda/ircomm/ircomm_tty.c
12140 --- linux-2.6.19.old/net/irda/ircomm/ircomm_tty.c       2006-11-29 22:57:37.000000000 +0100
12141 +++ linux-2.6.19.dev/net/irda/ircomm/ircomm_tty.c       2006-12-14 03:12:59.000000000 +0100
12142 @@ -123,6 +123,7 @@
12143         driver->owner           = THIS_MODULE;
12144         driver->driver_name     = "ircomm";
12145         driver->name            = "ircomm";
12146 +       driver->devfs_name      = "ircomm";
12147         driver->major           = IRCOMM_TTY_MAJOR;
12148         driver->minor_start     = IRCOMM_TTY_MINOR;
12149         driver->type            = TTY_DRIVER_TYPE_SERIAL;
12150 diff -urN linux-2.6.19.old/net/irda/irnet/irnet.h linux-2.6.19.dev/net/irda/irnet/irnet.h
12151 --- linux-2.6.19.old/net/irda/irnet/irnet.h     2006-11-29 22:57:37.000000000 +0100
12152 +++ linux-2.6.19.dev/net/irda/irnet/irnet.h     2006-12-14 03:12:59.000000000 +0100
12153 @@ -244,6 +244,7 @@
12154  #include <linux/skbuff.h>
12155  #include <linux/tty.h>
12156  #include <linux/proc_fs.h>
12157 +#include <linux/devfs_fs_kernel.h>
12158  #include <linux/netdevice.h>
12159  #include <linux/miscdevice.h>
12160  #include <linux/poll.h>
12161 diff -urN linux-2.6.19.old/sound/core/info.c linux-2.6.19.dev/sound/core/info.c
12162 --- linux-2.6.19.old/sound/core/info.c  2006-11-29 22:57:37.000000000 +0100
12163 +++ linux-2.6.19.dev/sound/core/info.c  2006-12-14 03:12:59.000000000 +0100
12164 @@ -29,6 +29,7 @@
12165  #include <sound/info.h>
12166  #include <sound/version.h>
12167  #include <linux/proc_fs.h>
12168 +#include <linux/devfs_fs_kernel.h>
12169  #include <linux/mutex.h>
12170  #include <stdarg.h>
12171  
12172 diff -urN linux-2.6.19.old/sound/core/sound.c linux-2.6.19.dev/sound/core/sound.c
12173 --- linux-2.6.19.old/sound/core/sound.c 2006-11-29 22:57:37.000000000 +0100
12174 +++ linux-2.6.19.dev/sound/core/sound.c 2006-12-14 03:12:59.000000000 +0100
12175 @@ -32,6 +32,7 @@
12176  #include <sound/control.h>
12177  #include <sound/initval.h>
12178  #include <linux/kmod.h>
12179 +#include <linux/devfs_fs_kernel.h>
12180  #include <linux/mutex.h>
12181  
12182  #define SNDRV_OS_MINORS 256
12183 @@ -41,6 +42,7 @@
12184  EXPORT_SYMBOL(snd_major);
12185  
12186  static int cards_limit = 1;
12187 +static int device_mode = S_IFCHR | S_IRUGO | S_IWUGO;
12188  
12189  MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
12190  MODULE_DESCRIPTION("Advanced Linux Sound Architecture driver for soundcards.");
12191 @@ -49,6 +51,10 @@
12192  MODULE_PARM_DESC(major, "Major # for sound driver.");
12193  module_param(cards_limit, int, 0444);
12194  MODULE_PARM_DESC(cards_limit, "Count of auto-loadable soundcards.");
12195 +#ifdef CONFIG_DEVFS_FS
12196 +module_param(device_mode, int, 0444);
12197 +MODULE_PARM_DESC(device_mode, "Device file permission mask for devfs.");
12198 +#endif
12199  MODULE_ALIAS_CHARDEV_MAJOR(CONFIG_SND_MAJOR);
12200  
12201  /* this one holds the actual max. card number currently available.
12202 @@ -244,7 +250,7 @@
12203         struct device *device = NULL;
12204  
12205         snd_assert(name, return -EINVAL);
12206 -       preg = kmalloc(sizeof *preg, GFP_KERNEL);
12207 +       preg = kmalloc((sizeof *preg) + strlen(name) + 1, GFP_KERNEL);
12208         if (preg == NULL)
12209                 return -ENOMEM;
12210         preg->type = type;
12211 @@ -252,6 +258,7 @@
12212         preg->device = dev;
12213         preg->f_ops = f_ops;
12214         preg->private_data = private_data;
12215 +       strcpy(preg->name, name); /* for devfs */
12216         mutex_lock(&sound_mutex);
12217  #ifdef CONFIG_SND_DYNAMIC_MINORS
12218         minor = snd_find_free_minor();
12219 @@ -266,6 +273,8 @@
12220                 return minor;
12221         }
12222         snd_minors[minor] = preg;
12223 +       if (type != SNDRV_DEVICE_TYPE_CONTROL || preg->card >= cards_limit)
12224 +               devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name);
12225         if (card)
12226                 device = card->dev;
12227         preg->class_dev = class_device_create(sound_class, NULL,
12228 @@ -320,6 +329,9 @@
12229                 return -EINVAL;
12230         }
12231  
12232 +       if (snd_minors[minor]->type != SNDRV_DEVICE_TYPE_CONTROL ||
12233 +           snd_minors[minor]->card >= cards_limit)     /* created in sound.c */
12234 +               devfs_remove("snd/%s", snd_minors[minor]->name);
12235         class_device_destroy(sound_class, MKDEV(major, minor));
12236  
12237         kfree(snd_minors[minor]);
12238 @@ -430,17 +442,24 @@
12239  
12240  static int __init alsa_sound_init(void)
12241  {
12242 +       short controlnum;
12243 +
12244         snd_major = major;
12245         snd_ecards_limit = cards_limit;
12246 +       devfs_mk_dir("snd");
12247         if (register_chrdev(major, "alsa", &snd_fops)) {
12248                 snd_printk(KERN_ERR "unable to register native major device number %d\n", major);
12249 +               devfs_remove("snd");
12250                 return -EIO;
12251         }
12252         if (snd_info_init() < 0) {
12253                 unregister_chrdev(major, "alsa");
12254 +               devfs_remove("snd");
12255                 return -ENOMEM;
12256         }
12257         snd_info_minor_register();
12258 +       for (controlnum = 0; controlnum < cards_limit; controlnum++)
12259 +               devfs_mk_cdev(MKDEV(major, controlnum<<5), S_IFCHR | device_mode, "snd/controlC%d", controlnum);
12260  #ifndef MODULE
12261         printk(KERN_INFO "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n");
12262  #endif
12263 @@ -449,10 +468,16 @@
12264  
12265  static void __exit alsa_sound_exit(void)
12266  {
12267 +       short controlnum;
12268 +
12269 +       for (controlnum = 0; controlnum < cards_limit; controlnum++)
12270 +               devfs_remove("snd/controlC%d", controlnum);
12271 +
12272         snd_info_minor_unregister();
12273         snd_info_done();
12274         if (unregister_chrdev(major, "alsa") != 0)
12275                 snd_printk(KERN_ERR "unable to unregister major device number %d\n", major);
12276 +       devfs_remove("snd");
12277  }
12278  
12279  module_init(alsa_sound_init)
12280 diff -urN linux-2.6.19.old/sound/oss/soundcard.c linux-2.6.19.dev/sound/oss/soundcard.c
12281 --- linux-2.6.19.old/sound/oss/soundcard.c      2006-11-29 22:57:37.000000000 +0100
12282 +++ linux-2.6.19.dev/sound/oss/soundcard.c      2006-12-14 03:12:59.000000000 +0100
12283 @@ -37,6 +37,7 @@
12284  #include <linux/wait.h>
12285  #include <linux/slab.h>
12286  #include <linux/ioport.h>
12287 +#include <linux/devfs_fs_kernel.h>
12288  #include <linux/major.h>
12289  #include <linux/delay.h>
12290  #include <linux/proc_fs.h>
12291 @@ -557,6 +558,9 @@
12292         sound_dmap_flag = (dmabuf > 0 ? 1 : 0);
12293  
12294         for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) {
12295 +               devfs_mk_cdev(MKDEV(SOUND_MAJOR, dev_list[i].minor),
12296 +                               S_IFCHR | dev_list[i].mode,
12297 +                               "sound/%s", dev_list[i].name);
12298                 class_device_create(sound_class, NULL,
12299                                     MKDEV(SOUND_MAJOR, dev_list[i].minor),
12300                                     NULL, "%s", dev_list[i].name);
12301 @@ -564,10 +568,15 @@
12302                 if (!dev_list[i].num)
12303                         continue;
12304  
12305 -               for (j = 1; j < *dev_list[i].num; j++)
12306 +               for (j = 1; j < *dev_list[i].num; j++) {
12307 +                       devfs_mk_cdev(MKDEV(SOUND_MAJOR,
12308 +                                               dev_list[i].minor + (j*0x10)),
12309 +                                       S_IFCHR | dev_list[i].mode,
12310 +                                       "sound/%s%d", dev_list[i].name, j);
12311                         class_device_create(sound_class, NULL,
12312                                             MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)),
12313                                             NULL, "%s%d", dev_list[i].name, j);
12314 +               }
12315         }
12316  
12317         if (sound_nblocks >= 1024)
12318 @@ -581,11 +590,14 @@
12319         int i, j;
12320  
12321         for (i = 0; i < sizeof (dev_list) / sizeof *dev_list; i++) {
12322 +               devfs_remove("sound/%s", dev_list[i].name);
12323                 class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor));
12324                 if (!dev_list[i].num)
12325                         continue;
12326 -               for (j = 1; j < *dev_list[i].num; j++)
12327 +               for (j = 1; j < *dev_list[i].num; j++) {
12328 +                       devfs_remove("sound/%s%d", dev_list[i].name, j);
12329                         class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)));
12330 +               }
12331         }
12332         
12333         unregister_sound_special(1);
12334 diff -urN linux-2.6.19.old/sound/sound_core.c linux-2.6.19.dev/sound/sound_core.c
12335 --- linux-2.6.19.old/sound/sound_core.c 2006-11-29 22:57:37.000000000 +0100
12336 +++ linux-2.6.19.dev/sound/sound_core.c 2006-12-14 03:12:59.000000000 +0100
12337 @@ -43,6 +43,7 @@
12338  #include <linux/sound.h>
12339  #include <linux/major.h>
12340  #include <linux/kmod.h>
12341 +#include <linux/devfs_fs_kernel.h>
12342  #include <linux/device.h>
12343  
12344  #define SOUND_STEP 16
12345 @@ -170,6 +171,8 @@
12346         else
12347                 sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP);
12348  
12349 +       devfs_mk_cdev(MKDEV(SOUND_MAJOR, s->unit_minor),
12350 +                       S_IFCHR | mode, s->name);
12351         class_device_create(sound_class, NULL, MKDEV(SOUND_MAJOR, s->unit_minor),
12352                             dev, s->name+6);
12353         return r;
12354 @@ -193,6 +196,7 @@
12355         p = __sound_remove_unit(list, unit);
12356         spin_unlock(&sound_loader_lock);
12357         if (p) {
12358 +               devfs_remove(p->name);
12359                 class_device_destroy(sound_class, MKDEV(SOUND_MAJOR, p->unit_minor));
12360                 kfree(p);
12361         }
12362 @@ -527,6 +531,7 @@
12363         /* We have nothing to really do here - we know the lists must be
12364            empty */
12365         unregister_chrdev(SOUND_MAJOR, "sound");
12366 +       devfs_remove("sound");
12367         class_destroy(sound_class);
12368  }
12369  
12370 @@ -536,6 +541,7 @@
12371                 printk(KERN_ERR "soundcore: sound device already in use.\n");
12372                 return -EBUSY;
12373         }
12374 +       devfs_mk_dir ("sound");
12375         sound_class = class_create(THIS_MODULE, "sound");
12376         if (IS_ERR(sound_class))
12377                 return PTR_ERR(sound_class);