1 /* devfs (Device FileSystem) utilities.
3 Copyright (C) 1999-2002 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>.
36 20010519 Richard Gooch <rgooch@atnf.csiro.au>
37 Documentation cleanup.
38 20010709 Richard Gooch <rgooch@atnf.csiro.au>
39 Created <devfs_*alloc_major> and <devfs_*alloc_devnum>.
40 20010710 Richard Gooch <rgooch@atnf.csiro.au>
41 Created <devfs_*alloc_unique_number>.
42 20010730 Richard Gooch <rgooch@atnf.csiro.au>
43 Documentation typo fix.
44 20010806 Richard Gooch <rgooch@atnf.csiro.au>
45 Made <block_semaphore> and <char_semaphore> private.
46 20010813 Richard Gooch <rgooch@atnf.csiro.au>
47 Fixed bug in <devfs_alloc_unique_number>: limited to 128 numbers
48 20010818 Richard Gooch <rgooch@atnf.csiro.au>
49 Updated major masks up to Linus' "no new majors" proclamation.
50 Block: were 126 now 122 free, char: were 26 now 19 free.
51 20020324 Richard Gooch <rgooch@atnf.csiro.au>
52 Fixed bug in <devfs_alloc_unique_number>: was clearing beyond
54 20020326 Richard Gooch <rgooch@atnf.csiro.au>
55 Fixed bitfield data type for <devfs_*alloc_devnum>.
56 Made major bitfield type and initialiser 64 bit safe.
57 20020413 Richard Gooch <rgooch@atnf.csiro.au>
58 Fixed shift warning on 64 bit machines.
59 20020428 Richard Gooch <rgooch@atnf.csiro.au>
60 Copied and used macro for error messages from fs/devfs/base.c
62 #include <linux/module.h>
63 #include <linux/init.h>
64 #include <linux/devfs_fs_kernel.h>
65 #include <linux/slab.h>
66 #include <linux/vmalloc.h>
68 #include <asm/bitops.h>
70 #define PRINTK(format, args...) \
71 {printk (KERN_ERR "%s" format, __FUNCTION__ , ## args);}
74 /* Private functions follow */
77 * devfs_register_tape - Register a tape device in the "/dev/tapes" hierarchy.
78 * @de: Any tape device entry in the device directory.
81 void devfs_register_tape (devfs_handle_t de)
84 devfs_handle_t parent, slave;
85 char name[16], dest[64];
86 static unsigned int tape_counter;
87 static devfs_handle_t tape_dir;
89 if (tape_dir == NULL) tape_dir = devfs_mk_dir (NULL, "tapes", NULL);
90 parent = devfs_get_parent (de);
91 pos = devfs_generate_path (parent, dest + 3, sizeof dest - 3);
93 strncpy (dest + pos, "../", 3);
94 sprintf (name, "tape%u", tape_counter++);
95 devfs_mk_symlink (tape_dir, name, DEVFS_FL_DEFAULT, dest + pos,
97 devfs_auto_unregister (de, slave);
98 } /* End Function devfs_register_tape */
99 EXPORT_SYMBOL(devfs_register_tape);
103 * devfs_register_series - Register a sequence of device entries.
104 * @dir: The handle to the parent devfs directory entry. If this is %NULL
105 * the new names are relative to the root of the devfs.
106 * @format: The printf-style format string. A single "\%u" is allowed.
107 * @num_entries: The number of entries to register.
108 * @flags: A set of bitwise-ORed flags (DEVFS_FL_*).
109 * @major: The major number. Not needed for regular files.
110 * @minor_start: The starting minor number. Not needed for regular files.
111 * @mode: The default file mode.
112 * @ops: The &file_operations or &block_device_operations structure.
113 * This must not be externally deallocated.
114 * @info: An arbitrary pointer which will be written to the private_data
115 * field of the &file structure passed to the device driver. You
116 * can set this to whatever you like, and change it once the file
117 * is opened (the next file opened will not see this change).
120 void devfs_register_series (devfs_handle_t dir, const char *format,
121 unsigned int num_entries, unsigned int flags,
122 unsigned int major, unsigned int minor_start,
123 umode_t mode, void *ops, void *info)
128 for (count = 0; count < num_entries; ++count)
130 sprintf (devname, format, count);
131 devfs_register (dir, devname, flags, major, minor_start + count,
134 } /* End Function devfs_register_series */
135 EXPORT_SYMBOL(devfs_register_series);
141 unsigned long bits[256 / BITS_PER_LONG];
143 #if BITS_PER_LONG == 32
144 # define INITIALISER64(low,high) (low), (high)
146 # define INITIALISER64(low,high) ( (unsigned long) (high) << 32 | (low) )
149 /* Block majors already assigned:
150 0-3, 7-9, 11-63, 65-99, 101-113, 120-127, 199, 201, 240-255
153 static struct major_list block_major_list =
155 {INITIALISER64 (0xfffffb8f, 0xffffffff), /* Majors 0-31, 32-63 */
156 INITIALISER64 (0xfffffffe, 0xff03ffef), /* Majors 64-95, 96-127 */
157 INITIALISER64 (0x00000000, 0x00000000), /* Majors 128-159, 160-191 */
158 INITIALISER64 (0x00000280, 0xffff0000), /* Majors 192-223, 224-255 */
162 /* Char majors already assigned:
163 0-7, 9-151, 154-158, 160-211, 216-221, 224-230, 240-255
166 static struct major_list char_major_list =
168 {INITIALISER64 (0xfffffeff, 0xffffffff), /* Majors 0-31, 32-63 */
169 INITIALISER64 (0xffffffff, 0xffffffff), /* Majors 64-95, 96-127 */
170 INITIALISER64 (0x7cffffff, 0xffffffff), /* Majors 128-159, 160-191 */
171 INITIALISER64 (0x3f0fffff, 0xffff007f), /* Majors 192-223, 224-255 */
177 * devfs_alloc_major - Allocate a major number.
178 * @type: The type of the major (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK)
180 * Returns the allocated major, else -1 if none are available.
181 * This routine is thread safe and does not block.
184 int devfs_alloc_major (char type)
187 struct major_list *list;
189 list = (type == DEVFS_SPECIAL_CHR) ? &char_major_list : &block_major_list;
190 spin_lock (&list->lock);
191 major = find_first_zero_bit (list->bits, 256);
192 if (major < 256) __set_bit (major, list->bits);
194 spin_unlock (&list->lock);
196 } /* End Function devfs_alloc_major */
197 EXPORT_SYMBOL(devfs_alloc_major);
201 * devfs_dealloc_major - Deallocate a major number.
202 * @type: The type of the major (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK)
203 * @major: The major number.
204 * This routine is thread safe and does not block.
207 void devfs_dealloc_major (char type, int major)
210 struct major_list *list;
212 if (major < 0) return;
213 list = (type == DEVFS_SPECIAL_CHR) ? &char_major_list : &block_major_list;
214 spin_lock (&list->lock);
215 was_set = __test_and_clear_bit (major, list->bits);
216 spin_unlock (&list->lock);
217 if (!was_set) PRINTK ("(): major %d was already free\n", major);
218 } /* End Function devfs_dealloc_major */
219 EXPORT_SYMBOL(devfs_dealloc_major);
225 unsigned long bits[256 / BITS_PER_LONG];
226 struct minor_list *next;
231 struct minor_list *first, *last;
235 static DECLARE_MUTEX (block_semaphore);
236 static struct device_list block_list;
238 static DECLARE_MUTEX (char_semaphore);
239 static struct device_list char_list;
243 * devfs_alloc_devnum - Allocate a device number.
244 * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK).
246 * Returns the allocated device number, else NODEV if none are available.
247 * This routine is thread safe and may block.
250 kdev_t devfs_alloc_devnum (char type)
253 struct semaphore *semaphore;
254 struct device_list *list;
255 struct minor_list *entry;
257 if (type == DEVFS_SPECIAL_CHR)
259 semaphore = &char_semaphore;
264 semaphore = &block_semaphore;
267 if (list->none_free) return NODEV; /* Fast test */
274 for (entry = list->first; entry != NULL; entry = entry->next)
276 minor = find_first_zero_bit (entry->bits, 256);
277 if (minor >= 256) continue;
278 __set_bit (minor, entry->bits);
280 return mk_kdev (entry->major, minor);
282 /* Need to allocate a new major */
283 if ( ( entry = kmalloc (sizeof *entry, GFP_KERNEL) ) == NULL )
289 memset (entry, 0, sizeof *entry);
290 if ( ( entry->major = devfs_alloc_major (type) ) < 0 )
297 __set_bit (0, entry->bits);
298 if (list->first == NULL) list->first = entry;
299 else list->last->next = entry;
302 return mk_kdev (entry->major, 0);
303 } /* End Function devfs_alloc_devnum */
304 EXPORT_SYMBOL(devfs_alloc_devnum);
308 * devfs_dealloc_devnum - Dellocate a device number.
309 * @type: The type (DEVFS_SPECIAL_CHR or DEVFS_SPECIAL_BLK).
310 * @devnum: The device number.
312 * This routine is thread safe and does not block.
315 void devfs_dealloc_devnum (char type, kdev_t devnum)
318 struct semaphore *semaphore;
319 struct device_list *list;
320 struct minor_list *entry;
322 if ( kdev_none (devnum) ) return;
323 if (type == DEVFS_SPECIAL_CHR)
325 semaphore = &char_semaphore;
330 semaphore = &block_semaphore;
333 major = major (devnum);
334 minor = minor (devnum);
336 for (entry = list->first; entry != NULL; entry = entry->next)
340 if (entry->major != major) continue;
341 was_set = __test_and_clear_bit (minor, entry->bits);
342 if (was_set) list->none_free = 0;
345 PRINTK ( "(): device %s was already free\n", kdevname (devnum) );
349 PRINTK ( "(): major for %s not previously allocated\n",
351 } /* End Function devfs_dealloc_devnum */
352 EXPORT_SYMBOL(devfs_dealloc_devnum);
356 * devfs_alloc_unique_number - Allocate a unique (positive) number.
357 * @space: The number space to allocate from.
359 * Returns the allocated unique number, else a negative error code.
360 * This routine is thread safe and may block.
363 int devfs_alloc_unique_number (struct unique_numspace *space)
368 /* Get around stupid lack of semaphore initialiser */
369 spin_lock (&space->init_lock);
370 if (!space->sem_initialised)
372 sema_init (&space->semaphore, 1);
373 space->sem_initialised = 1;
375 spin_unlock (&space->init_lock);
376 down (&space->semaphore);
377 if (space->num_free < 1)
381 if (space->length < 16) length = 16;
382 else length = space->length << 1;
383 if ( ( bits = vmalloc (length) ) == NULL )
385 up (&space->semaphore);
388 if (space->bits != NULL)
390 memcpy (bits, space->bits, space->length);
393 space->num_free = (length - space->length) << 3;
395 memset (bits + space->length, 0, length - space->length);
396 space->length = length;
398 number = find_first_zero_bit (space->bits, space->length << 3);
400 __set_bit (number, space->bits);
401 up (&space->semaphore);
403 } /* End Function devfs_alloc_unique_number */
404 EXPORT_SYMBOL(devfs_alloc_unique_number);
408 * devfs_dealloc_unique_number - Deallocate a unique (positive) number.
409 * @space: The number space to deallocate from.
410 * @number: The number to deallocate.
412 * This routine is thread safe and may block.
415 void devfs_dealloc_unique_number (struct unique_numspace *space, int number)
419 if (number < 0) return;
420 down (&space->semaphore);
421 was_set = __test_and_clear_bit (number, space->bits);
422 if (was_set) ++space->num_free;
423 up (&space->semaphore);
424 if (!was_set) PRINTK ("(): number %d was already free\n", number);
425 } /* End Function devfs_dealloc_unique_number */
426 EXPORT_SYMBOL(devfs_dealloc_unique_number);