Fix reported Samba bug.
[linux-2.6/linux-mips.git] / fs / devfs / util.c
blob9f71763b1fd679c8385fc4bcf2c7f92cb3085d8d
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.
23 ChangeLog
25 19991031 Richard Gooch <rgooch@atnf.csiro.au>
26 Created.
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 */
46 /**
47 * _devfs_convert_name - Convert from an old style location-based name to new style.
48 * @new: The new name will be written here.
49 * @old: The old name.
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;
56 char *ptr;
57 char part[8];
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);
68 if (disc)
70 /* Decode "p#" */
71 if (ptr[0] == 'p') sprintf (part, "part%s", ptr + 1);
72 else strcpy (part, "disc");
74 else part[0] = '\0';
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 */
82 /**
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)
89 char dest[64];
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) )
99 strcpy (dest, "..");
100 _devfs_convert_name (dest + 2, name + 7, (name[4] == 'h') ? 1 : 0);
102 else return;
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)
114 int pos;
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);
123 if (pos < 0) return;
124 strncpy (dest + pos, "../", 3);
125 sprintf (name, "tape%u", tape_counter++);
126 devfs_mk_symlink (tape_dir, name, DEVFS_FL_DEFAULT, dest + pos,
127 &slave, NULL);
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)
155 unsigned int count;
156 char devname[128];
158 for (count = 0; count < num_entries; ++count)
160 sprintf (devname, format, count);
161 devfs_register (dir, devname, flags, major, minor_start + count,
162 mode, ops, info);
164 } /* End Function devfs_register_series */
165 EXPORT_SYMBOL(devfs_register_series);