1 /* devfs (Device FileSystem) utilities.
3 Copyright (C) 1999-2000 Richard Gooch
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 Richard Gooch may be reached by email at rgooch@atnf.csiro.au
20 The postal address is:
21 Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
25 19991031 Richard Gooch <rgooch@atnf.csiro.au>
27 19991103 Richard Gooch <rgooch@atnf.csiro.au>
28 Created <_devfs_convert_name> and supported SCSI and IDE CD-ROMs
29 20000203 Richard Gooch <rgooch@atnf.csiro.au>
30 Changed operations pointer type to void *.
31 20000621 Richard Gooch <rgooch@atnf.csiro.au>
32 Changed interface to <devfs_register_series>.
33 20000622 Richard Gooch <rgooch@atnf.csiro.au>
34 Took account of interface change to <devfs_mk_symlink>.
35 Took account of interface change to <devfs_mk_dir>.
37 #include <linux/module.h>
38 #include <linux/init.h>
39 #include <linux/locks.h>
40 #include <linux/kdev_t.h>
41 #include <linux/devfs_fs_kernel.h>
44 /* Private functions follow */
47 * _devfs_convert_name - Convert from an old style location-based name to new style.
48 * @new: The new name will be written here.
50 * @disc: If true, disc partitioning information should be processed.
53 static void __init
_devfs_convert_name (char *new, const char *old
, int disc
)
55 int host
, bus
, target
, lun
;
59 /* Decode "c#b#t#u#" */
60 if (old
[0] != 'c') return;
61 host
= simple_strtol (old
+ 1, &ptr
, 10);
62 if (ptr
[0] != 'b') return;
63 bus
= simple_strtol (ptr
+ 1, &ptr
, 10);
64 if (ptr
[0] != 't') return;
65 target
= simple_strtol (ptr
+ 1, &ptr
, 10);
66 if (ptr
[0] != 'u') return;
67 lun
= simple_strtol (ptr
+ 1, &ptr
, 10);
71 if (ptr
[0] == 'p') sprintf (part
, "part%s", ptr
+ 1);
72 else strcpy (part
, "disc");
75 sprintf (new, "/host%d/bus%d/target%d/lun%d/%s",
76 host
, bus
, target
, lun
, part
);
77 } /* End Function _devfs_convert_name */
80 /* Public functions follow */
83 * devfs_make_root - Create the root FS device entry if required.
84 * @name: The name of the root FS device, as passed by "root=".
87 void __init
devfs_make_root (const char *name
)
91 if ( (strncmp (name
, "sd/", 3) == 0) || (strncmp (name
, "sr/", 3) == 0) )
93 strcpy (dest
, "../scsi");
94 _devfs_convert_name (dest
+ 7, name
+ 3, (name
[1] == 'd') ? 1 : 0);
96 else if ( (strncmp (name
, "ide/hd/", 7) == 0) ||
97 (strncmp (name
, "ide/cd/", 7) == 0) )
100 _devfs_convert_name (dest
+ 2, name
+ 7, (name
[4] == 'h') ? 1 : 0);
103 devfs_mk_symlink (NULL
, name
, DEVFS_FL_DEFAULT
, dest
, NULL
, NULL
);
104 } /* End Function devfs_make_root */
108 * devfs_register_tape - Register a tape device in the "/dev/tapes" hierarchy.
109 * @de: Any tape device entry in the device directory.
112 void devfs_register_tape (devfs_handle_t de
)
115 devfs_handle_t parent
, slave
;
116 char name
[16], dest
[64];
117 static unsigned int tape_counter
= 0;
118 static devfs_handle_t tape_dir
= NULL
;
120 if (tape_dir
== NULL
) tape_dir
= devfs_mk_dir (NULL
, "tapes", NULL
);
121 parent
= devfs_get_parent (de
);
122 pos
= devfs_generate_path (parent
, dest
+ 3, sizeof dest
- 3);
124 strncpy (dest
+ pos
, "../", 3);
125 sprintf (name
, "tape%u", tape_counter
++);
126 devfs_mk_symlink (tape_dir
, name
, DEVFS_FL_DEFAULT
, dest
+ pos
,
128 devfs_auto_unregister (de
, slave
);
129 } /* End Function devfs_register_tape */
130 EXPORT_SYMBOL(devfs_register_tape
);
134 * devfs_register_series - Register a sequence of device entries.
135 * @dir: The handle to the parent devfs directory entry. If this is %NULL the
136 * new names are relative to the root of the devfs.
137 * @format: The printf-style format string. A single "\%u" is allowed.
138 * @flags: A set of bitwise-ORed flags (DEVFS_FL_*).
139 * @major: The major number. Not needed for regular files.
140 * @minor_start: The starting minor number. Not needed for regular files.
141 * @mode: The default file mode.
142 * @ops: The &file_operations or &block_device_operations structure.
143 * This must not be externally deallocated.
144 * @info: An arbitrary pointer which will be written to the private_data
145 * field of the &file structure passed to the device driver. You can set
146 * this to whatever you like, and change it once the file is opened (the next
147 * file opened will not see this change).
150 void devfs_register_series (devfs_handle_t dir
, const char *format
,
151 unsigned int num_entries
, unsigned int flags
,
152 unsigned int major
, unsigned int minor_start
,
153 umode_t mode
, void *ops
, void *info
)
158 for (count
= 0; count
< num_entries
; ++count
)
160 sprintf (devname
, format
, count
);
161 devfs_register (dir
, devname
, flags
, major
, minor_start
+ count
,
164 } /* End Function devfs_register_series */
165 EXPORT_SYMBOL(devfs_register_series
);