Coherent4.2.10/coh.386/lib/ddi_devno.c
/* $Header: $ */
#define _DDI_DKI 1
#define _SYSV4 1
/*
* Routines for manipulating device numbers.
*
* System V defines "dev_t" as 32-bit, which makes some things problematic
* when attempting to run SVR4 drivers in an iBCS2 environment. The concept
* of external and internal numbers, introduced at the same time as the 32-
* bit "dev_t", provides an effective solution.
*
* This is of primary importance to clone devices which may want to support
* more than 256 connections, but any driver which wants or needs to encode
* more that 8 bits of information in the minor number may also benefit from
* use of the external/internal mapping regime.
*
* $Log: $
*/
/*
*-IMPORTS:
* <sys/types.h>
* dev_t
* <limits.h>
* CHAR_BIT
*/
#include <sys/types.h>
#include <limits.h>
/*
* Define this symbol to make the code in this module ignore the _max_minor,
* _major [], and _minor [] configuration tables, and simply map internal and
* external major and minor numbers one-to-one.
*/
/* #define ONE_TO_ONE */
/*
* If we are dealing with a situation where we are trying to run DDI/DKI code
* side-by-side with code that uses a different "dev_t", we rely on a layer
* that can may the pre-SVR4 or alien calling sequence for the DDI/DKI entry
* points. This code must deal with converting the old-style "dev_t" to a
* new-style "dev_t" and vice-versa.
*
* In particular, if a device generates a minor number outside the range of
* precision of the old-style system, the mapping layer must use these
* functions to select an appropriate major number to overflow to.
*/
#define DSHIFT (sizeof (dev_t) * CHAR_BIT / 2)
#define GETEMAJOR(dev) ((major_t) ((dev) >> DSHIFT))
#define GETEMINOR(dev) ((minor_t) ((dev) & ~ (1L << DSHIFT)))
#define MAKEDEVICE(maj,min) (((dev_t) (maj) << DSHIFT) + (min))
/*
* The following external reference is to a table generated by the kernel
* configuration process for all the devices configured in the system. It
* defines a many-to-one mapping between external and internal major device
* numbers.
*
* This mapping can also affect internal device numbers; for instance,
* external major device 10, minor 5 might map to internal 2, minor 30.
*/
#ifndef ONE_TO_ONE
extern major_t _maxmajor;
extern major_t _major []; /* internal major number for external major */
extern minor_t _minor []; /* value added to external minor number */
#endif
/*
*-STATUS:
* DDI/DKI
*
*-NAME:
* etoimajor Convert external to internal major device number.
*
*-SYNOPSIS:
* #include <sys/types.h>
* #include <sys/ddi.h>
*
* major_t etoimajor (major_t emaj);
*
*-ARGUMENTS:
* emaj External major number.
*
*-DESCRIPTION:
* etoimajor () converts the external major number (emaj) to an internal
* major number. See getemajor () for a description of external and
* internal major numbers.
*
*-RETURN VALUE:
* etoimajor () returns the internal major number or NODEV if the
* external major number is not valid.
*
*-LEVEL:
* Base or interrupt.
*
*-NOTES:
* Does not sleep.
*
* Driver-defined basic locks, read/write locks, and sleep locks may be
* held across calls to this function.
*
*-SEE ALSO:
* getemajor (), geteminor (), getmajor (), getminor (), itoemajor (),
* makedevice ().
*/
#if __USE_PROTO__
major_t (etoimajor) (major_t emaj)
#else
major_t
etoimajor __ARGS ((emaj))
major_t emaj;
#endif
{
#ifdef ONE_TO_ONE
return emaj;
#else
return (emaj >= _maxmajor ? NODEV : _major [emaj]);
#endif
}
/*
*-STATUS:
* DDI/DKI
*
*-NAME:
* getemajor Get external major device number.
*
*-SYNOPSIS:
* #include <sys/types.h>
* #include <sys/ddi.h>
*
* major_t getemajor (dev_t dev);
*
*-ARGUMENTS:
* dev External device number.
*
*-DESCRIPTION:
* getemajor () returns the external major number given a device number,
* "dev". External major numbers are visible to the user. Internal major
* numbers are only visible in the kernel. Since the range of major
* numbers may be large and sparsely populated, the kernel keeps a
* mapping between external and internal major numbers to save space.
*
* All driver entry points are passed device numbers using external
* major numbers.
*
* Usually, a driver with more than one external major number will have
* only one internal major number. However, some system implementations
* map one-to-one between internal and external major numbers. Here, the
* internal major number is the same as the external major number and the
* driver may have more than one internal major number.
*
*-RETURN VALUE:
* The external major number.
*
*-LEVEL:
* Base or interrupt.
*
*-NOTES:
* Does not sleep.
*
* Driver-defined basic locks, read/write locks, and sleep locks may be
* held across calls to this function.
*
*-SEE ALSO:
* etoimajor (), geteminor (), getmajor (), getminor (), makedevice ().
*/
#if __USE_PROTO__
major_t (getemajor) (n_dev_t dev)
#else
major_t
getemajor __ARGS ((dev))
n_dev_t dev;
#endif
{
return GETEMAJOR (dev);
}
/*
*-STATUS:
* DDI/DKI
*
*-NAME:
* geteminor Get external minor device number.
*
*-SYNOPSIS:
* #include <sys/types.h>
* #include <sys/ddi.h>
*
* minor_t geteminor (dev_t dev);
*
*-ARGUMENTS:
* dev External device number.
*
*-DESCRIPTION:
* geteminor () returns the external minor number given a device number,
* "dev". External minor numbers are visible to the user. Internal minor
* numbers are only visible in the kernel. Since a driver can support
* more than one external major device that maps to the same internal
* major device, the kernel keeps a mapping between external minor
* numbers and internal minor numbers to allow drivers to index arrays
* more easily. For example, a driver may support two devices, each with
* five minor numbers. The user may see each set of minor numbers
* numbered from zero to four, but the driver sees them as one set of
* minor numbers numbered zero to nine.
*
* All driver entry points are passed device numbers using external minor
* numbers.
*
* Systems that map external major numbers one-to-one with internal major
* numbers also map external minor numbers one-to-one with internal minor
* numbers.
*
*-RETURN VALUE:
* The external minor number.
*
*-LEVEL:
* Base or interrupt.
*
*-NOTES:
* Does not sleep.
*
* Driver-defined basic locks, read/write locks, and sleep locks may be
* held across calls to this function.
*
*-SEE ALSO:
* etoimajor (), getemajor (), getmajor (), getminor (), makedevice ()
*/
#if __USE_PROTO__
minor_t (geteminor) (n_dev_t dev)
#else
minor_t
geteminor __ARGS ((dev))
n_dev_t dev;
#endif
{
return GETEMINOR (dev);
}
/*
*-STATUS:
* DDI/DKI
*
*-NAME:
* getmajor Get internal major device number.
*
*-SYNOPSIS:
* #include <sys/types.h>
* #include <sys/ddi.h>
*
* major_t getemajor (dev_t dev);
*
*-ARGUMENTS:
* dev Device number.
*
*-DESCRIPTION:
* The getmajor () function extracts the internal major number from a
* device number. See getemajor () for an explanation of external and
* internal major numbers.
*
*-RETURN VALUE:
* The internal major number.
*
*-LEVEL:
* Base or interrupt.
*
*-NOTES:
* No validity checking is performed. If "dev" is invalid, an invalid
* number is returned.
*
* Does not sleep.
*
* Driver-defined basic locks, read/write locks, and sleep locks may be
* held across calls to this function.
*
*-SEE ALSO:
* etoimajor (), getemajor (), geteminor (), getminor (), makedevice ()
*/
#if __USE_PROTO__
major_t (getmajor) (n_dev_t dev)
#else
major_t
getmajor __ARGS ((dev))
n_dev_t dev;
#endif
{
#ifdef ONE_TO_ONE
return GETEMAJOR (dev);
#else
return _major [GETEMAJOR (dev)];
#endif
}
/*
*-STATUS:
* DDI/DKI
*
*-NAME:
* getminor Get internal minor device number.
*
*-SYNOPSIS:
* #include <sys/types.h>
* #include <sys/ddi.h>
*
* minor_t getminor (dev_t dev);
*
*-ARGUMENTS:
* dev Device number.
*
*-DESCRIPTION:
* The getminor () function extracts the internal minor number from a
* device number. See getemajor () for an explanation of external and
* internal major numbers.
*
*-RETURN VALUE:
* The internal minor number.
*
*-LEVEL:
* Base or interrupt.
*
*-NOTES:
* No validity checking is performed. If "dev" is invalid, an invalid
* number is returned.
*
* Does not sleep.
*
* Driver-defined basic locks, read/write locks, and sleep locks may be
* held across calls to this function.
*
*-SEE ALSO:
* etoimajor (), getemajor (), geteminor (), getmajor (), makedevice ()
*/
#if __USE_PROTO__
minor_t (getminor) (n_dev_t dev)
#else
minor_t
getminor __ARGS ((dev))
n_dev_t dev;
#endif
{
#ifdef ONE_TO_ONE
return GETEMINOR (dev);
#else
return GETEMINOR (dev) + _minor [GETEMAJOR (dev)];
#endif
}
/*
*-STATUS:
* DDI/DKI
*
*-NAME:
* itoemajor Convert internal to external major number.
*
*-SYNOPSIS:
* #include <sys/types.h>
* #include <sys/ddi.h>
*
* major_t itoemajor (major_t imaj, major_t prevemaj);
*
*-ARGUMENTS:
* imaj Internal major number.
*
* prevemaj Most recently obtained external major number (or
* NODEV, if this is the first time the function has been
* called).
*
*-DESCRIPTION:
* itoemajor () converts the internal major number to the external major
* number. The external-to-internal major number mapping can be many-to-
* one, and so any internal major number may correspond to more than one
* external major number. By repeatedly invoking this function, the
* driver can obtain all possible external major number values. See
* getemajor () for an explanation of external and internal major
* numbers.
*
*-RETURN VALUE:
* External major number, or NODEV if all have been searched.
*
*-LEVEL:
* Base or interrupt.
*
*-NOTES:
* Does not sleep.
*
* Driver-defined basic locks, read/write locks, and sleep locks may be
* held across calls to this function.
*
*-SEE ALSO:
* etoimajor (), getemajor (), geteminor (), getmajor (), getminor (),
* makedevice ()
*/
#if __USE_PROTO__
major_t (itoemajor) (major_t imaj, major_t prevemaj)
#else
major_t
itoemajor __ARGS ((imaj, prevemaj))
major_t imaj;
major_t prevemaj;
#endif
{
#ifdef ONE_TO_ONE
return prevemaj == NODEV ? imaj : NODEV;
#else
if (prevemaj == NODEV)
prevemaj = 0;
else
prevemaj ++;
while (prevemaj ++ < _maxmajor)
if (_major [prevemaj] == imaj)
return prevemaj;
return NODEV;
#endif
}
/*
*-STATUS:
* DDI/DKI
*
*-NAME:
* makedevice Make device number from major and minor numbers.
*
*-SYNOPSIS:
* #include <sys/types.h>
* #include <sys/ddi.h>
*
* dev_t makedevice (major_t majnum, minor_t minnum);
*
*-ARGUMENTS:
* majnum Major number.
*
* minnum Minor number.
*
*-DESCRIPTION:
* The makedevice () function creates a device number from a major and
* minor device number. makedevice () should be used to create device
* numbers so that the driver will port easily to releases that treat
* device numbers differently.
*
*-RETURN VALUE:
* The device number, containing both the major number and the minor
* number, is returned. No validation of the major or number numbers is
* performed.
*
*-LEVEL:
* Base or interrupt.
*
*-NOTES:
* Does not sleep.
*
* Driver-defined basic locks, read/write locks, and sleep locks may be
* held across calls to this function.
*
*-SEE ALSO:
* getemajor (), geteminor (), getmajor (), getminor ()
*/
#if __USE_PROTO__
n_dev_t (makedevice) (major_t majnum, minor_t minnum)
#else
n_dev_t
makedevice __ARGS ((majnum, minnum))
major_t majnum;
minor_t minnum;
#endif
{
return MAKEDEVICE (majnum, minnum);
}