Main Page   Modules   Related Pages  

AtheOS Device Driver API


Functions

status_t rename_process (int nProcessID, const char *pzName)
 Rename a process. More...

int alloc_tld (void)
 Allocate a TLD slot. More...

int free_tld (int nHandle)
 Release a TLD slot. More...

status_t delete_semaphore (sem_id hSema)
 Delete a kernel semaphore. More...

status_t lock_semaphore_ex (sem_id hSema, int nCount, uint32 nFlags, bigtime_t nTimeOut)
 Aquire a semaphore. More...

status_t lock_semaphore (sem_id hSema, uint32 nFlags, bigtime_t nTimeOut)
 Lock a semaphore. More...

status_t unlock_semaphore_ex (sem_id hSema, int nCount)
 Release a semaphore. More...

status_t unlock_semaphore (sem_id hSema)
 Release a semaphore. More...

status_t unlock_and_suspend (sem_id hWaitQueue, sem_id hSema)
 Unlock a reqular semaphore and block on a wait-queue. More...

status_t spinunlock_and_suspend (sem_id hWaitQueue, SpinLock_s *psLock, uint32 nCPUFlags, bigtime_t nTimeout)
 Release a sinlock and block on a wait-queue in one atomic operation. More...

status_t sleep_on_sem (sem_id hSema, bigtime_t nTimeOut)
 Non conditionally block on a semaphore (wait-queue). More...

status_t wakeup_sem (sem_id hSema, bool bAll)
 Wake up threads blocked on a wait-queue. More...

int create_device_node (int nDeviceID, const char *pzPath, const DeviceOperations_s *psOps, void *pCookie)
 Publish a device-node inside the /dev/ directory. More...

int delete_device_node (int nHandle)
 Remove a device node from the /dev/ directory. More...

int rename_device_node (int nHandle, const char *pzNewPath)
 Rename and/or move a device node. More...

int decode_disk_partitions (device_geometry *psDiskGeom, Partition_s *pasPartitions, int nMaxPartitions, void *pCookie, disk_read_op *pfReadCallback)
 Decode a hard-disk partition table. More...

int based_open (int nRootFD, const char *pzPath, int nFlags,...)
 Open a file relative to a given directory. More...

int freadlink (int nFile, char *pzBuffer, size_t nBufSize)
 Read the content of an previously opened symlink. More...


Function Documentation

int alloc_tld ( void )
 

Allocate a TLD slot.

Description:
Allocate a TLD. A TLD (thread local storage) is a integer that is allocated on the process level but accessed by threads. A thread can assign an arbritary value to a TLD and then retrieve the value later. The TLD handle can be distributed among the threads but each thread will have their own privat storage for the TLD. This means that both thread A and thread B can store different values to the same TLD without overwriting each other's TLD. This is for example used to give each thread a privat "errno" global variable.

Returns:
On success a positive handle is returned. On error a negative error code is returned.
Error codes:
ENOMEM All TLD slots are in use.
See also:
free_tld(), set_tld(), get_tld()
Author(s):
Kurt Skauen (kurt@atheos.cx)

int based_open ( int nRootFD,
const char * pzPath,
int nFlags,
... )
 

Open a file relative to a given directory.

Description:
based_open() have the same semantics as open() except that you can specify the "current working directory" as a parameter.

The first parameter should be a file descriptor for a open directory and the path can be eighter absolute (starting with a "/") in which case the semantics is exactly the same as for open() or it can be relative to nRootFD.

The "real" current working directory is not affected.

This provide a thread-safe way to do do the following:

                int nOldDir = open( ".", O_RDONLY );
                fchdir( nRootFD );
                nFile = open( pzPath, ... );
                fchdir( nOldDir );
                close( nOldDir );

The problem with the above example in a multithreaded environment is that other threads will be affected by the change of current working directory and might get into trouble while we temporarily change it. Using based_open() is also more efficient since only one kernel-call is done (based_open() is just as efficient as open()).

Parameters:
nRootFD   The directory to use as starting point when searching for pzPath
pzPath   Path to the file to open. This can eighter be absolute or relative to nRootFD.
nFlags   Flags controlling how to open the file. Look at open() for a full description of the flags.
nMode   The access rights to set on the newly created file if O_CREAT is specified in nFlags

Returns:
based_open() return the new file descriptor on success or a negatice error code if an error occurs.
Error codes:
  • EMFILE nRootFD is not a valid file descriptor
  • ENOTDIR nRootFD is not a directory
  • In addition all error-codes returned by open() can be returned.
See also:
open(), close()
Author(s):
Kurt Skauen (kurt@atheos.cx)

int create_device_node ( int nDeviceID,
const char * pzPath,
const DeviceOperations_s * psOps,
void * pCookie )
 

Publish a device-node inside the /dev/ directory.

Description:
Device drivers can call this function to publish their device nodes inside the /dev/ directory. AtheOS have a very flexible and dynamic system for managing device nodes. A device driver can create, rename and delete nodes inside the /dev/ directory at any time. Normally a device driver will call create_device_node() during initialization and delete_device_node() when being deinitialized, but it can also create and delete nodes at other points if it for example controll some form of removable device that might be added or removed after the device driver has been loaded.
Note:
Parameters:
nDeviceID   This is the unique device ID passed to the driver in the "device_init()" funcion.
pzPath   The path is relative to /dev/ and can specify directories in addition to the node-name. For example "disk/scsi/hda/raw" will create a device node name "raw" inside /dev/disk/scsi/hda/". The path should not have any leading or trailing slashes.
psOps   Pointer to a DeviceOperations_s structure containing a list of function pointers that will be called by the kernel on behalf of the user of the device. Functions like read(), write(), ioctl(), etc etc, will be mapped more or less directly into calls into the device driver through these function pointers.
pCookie   This is just a void pointer that the kernel will be associating with the device-node and that will be passed back to the driver when calling functions in psOps. This can be used by the driver to associate some private data with the device node.

Returns:
create_device_node() returns a handle that can later be used to rename the node with rename_device_node() or to delete the node with delete_device_node(). If the node is not deleted before the driver is unloaded it will be deleted automatically by the kernel.

See also:
delete_device_node(), rename_device_node()
Author(s):
Kurt Skauen (kurt@atheos.cx)

int decode_disk_partitions ( device_geometry * psDiskGeom,
Partition_s * pasPartitions,
int nMaxPartitions,
void * pCookie,
disk_read_op * pfReadCallback )
 

Decode a hard-disk partition table.

Description:
decode_disk_partitions() can be called by block-device drivers to decode a disk's partition table. It will return both primary partitions and logical partitions within the extended partition if one exists. The extended partition itself will not be returned.

The caller must provide the device-geometry and a callback that will be called to read the primary partition table and any existing nested extended partition tabless.

The partition table is validated and the function will fail if it is found invalid. Checks performed includes overlaping partitions, partitions ending outside the disk and the primary table containing more than one extended partition.

Note:
Primary partitions are numbered 0-3 based on their position inside the primary table. Logical partition are numbered from 4 and up. This might leave "holes" in the returned array of partitions. The returned count only indicate the highest used partition number and the caller must check each returned partition and filter out partitions where the type-field is '0'.
Parameters:
psDevice   Pointer to a device_geometry structure describing the disk's geometry.
pasPartitions   Pointer to an array of partition descriptors that will be filled in.
nMaxPartitions   Number of entries allocated for pasPartitions. Maximum nMaxPartitions number of partitions will be returned. If the function return exactly nMaxPartitions it might have overflowed and the call should be repeated with a larger buffer.
pCookie   Pointer private to the caller that will be passed back to the pfReadCallback call-back function.
pfReadCallback   Pointer to a function that will be called to read in partition tables.

Returns:
A positive maximum partition-count on success or a negative error code on failure.
See also:
create_device_node(), delete_device_node()
Author(s):
Kurt Skauen (kurt@atheos.cx)

int delete_device_node ( int nHandle )
 

Remove a device node from the /dev/ directory.

Description:
Delete a node previously created with create_device_node(). The device node will be removed from /dev/ directory and the DeviceOperations_s structure and the cookie passed to create_device_node() can now be destroyed by the driver.
Parameters:
nHandle   A device-node handle returned by a previous call to create_device_node()
Returns:
0 on success, a negative error code on failure
See also:
create_device_node(), rename_device_node()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t delete_semaphore ( sem_id hSema )
 

Delete a kernel semaphore.

Description:
Delete a semaphore previously created with create_semaphore(). Resources consumed by the semaphore will be released and all threads currently blocked on the semaphore will be waked up and the blocking function will return an error code.
Parameters:
hSema   Semaphore handle returned by a previous call to create_semaphore()
Returns:
On success 0 is returned. On error a negative error code is returned.
See also:
create_semaphore(), lock_semaphore(), lock_semaphore_ex(), unlock_semaphore(), unlock_semaphore_ex(), sleep_on_sem(), wakeup_sem(), unlock_and_suspend() ,spinunlock_and_suspend()
Author(s):
Kurt Skauen (kurt@atheos.cx)

int freadlink ( int nFile,
char * pzBuffer,
size_t nBufSize )
 

Read the content of an previously opened symlink.

Description:
Read the content of a symlink previously opened with open( path, O_NOTRAVERSE ).

The semantics is the same as for readlink() except that it take and already opened symlink rather than a path-name.

Normally when passing a symlink path to open() it will automatically open the file/dir that the link points to and not the link itself. To stop open() from traversing the links you can add the O_NOTRAVERSE flag to the open-mode. open() will then return a file-handle representing the link itself rather than the file the link points at.

Parameters:
nFile   File descriptor representing the symlink to read.
pzBuffer   Pointer to a buffer of at least nBufSize bytes that will receive the content of the symlink. The buffer will not be NUL terminated but the number of bytes added to the buffer will be returned by freadlink().
nBufSize   Size of pzBuffer.
Returns:
The call returns the number of bytes placed in the buffers on success, or a negatice error code if an error occurs.
Error codes:
  • EBADF nFile is not a valid file descriptor or is not open for reading
  • EINVAL nFile is not a symlink
  • ENOSYS The filesystem hosting nFile does not support symbolic links.
See also:
readlink()
Author(s):
Kurt Skauen (kurt@atheos.cx)

int free_tld ( int nHandle )
 

Release a TLD slot.

Description:
Release a TLD slot previously allocated with alloc_tld().
Parameters:
nHandle   The TLD slot to release.
Returns:
On success 0 is returned. On error a negative error code is returned.
Error codes:
  • EINVAL Invalid TLD handle.
See also:
alloc_tld(), set_tld(), get_tld()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t lock_semaphore ( sem_id hSema,
uint32 nFlags,
bigtime_t nTimeOut )
 

Lock a semaphore.

Description:
Locks a semaphore. Equivalent of calling lock_semaphore_ex() with a count of 1.
Parameters:
hSema   Semaphore handle to lock.
nFlags  
  • SEM_NOSIG Ignore signals while blocking on the semaphore. Only set this flag on semaphores that are known to be released realtively soon. Otherwhise the caller should handle the EINTR error and exit from the kernel as soon as possible if a signal is caught.
nTimeOut   Maximum number of micro seconds to wait for the semaphore to be released. If the timeout is 0 lock_semaphore_ex() will never return, and if it is INFINITE_TIMEOUT it will block until the semaphore can be aquired or a signel is caught.
Returns:
On success 0 is returned. On error a negative error code is returned.
Error codes:
  • ETIME the semaphore could not be aquired before the timeout expiered.
  • EINTR a signal was caught before the semaphore could be aquired.
  • EINVAL hSema was not a valid semaphore handle, or the semaphore was deleted while we blocked.
See also:
lock_semaphore_ex()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t lock_semaphore_ex ( sem_id hSema,
int nCount,
uint32 nFlags,
bigtime_t nTimeOut )
 

Aquire a semaphore.

Description:
Aquire a semaphore. lock_semaphore_ex() will decrease the semaphore's nesting counter with "nCount".

If the timeout is larger than 0 and the nesting counter becomes negative the calling thread will be blocked. The thread will then stay blocked until one of the following conditions are met:

  • Another thread release the semaphore and cause the nesting counter to become positive again and the function returns successfully.
  • The timeout runs out and the function returns with an ETIME error.
  • The calling threads catch a signal and the function return the EINTR error code.
If the timeout is 0 lock_semaphore_ex() will never block, but instead returns immediatly with ETIME if the semaphore can not be aquired. If the timeout is INFINITE_TIMEOUT the thread will be blocked until it can be successfully aquired or a signal is caught.

Warning:
Since lock_semaphore_ex() called with a non-0 timeout might block it must never be called from a interrupt handler. Non-atomic resources accessed from interrupt handlers must be protected with spinlocks.
Parameters:
hSema   Semaphore handle to lock.
nCount   Positive value that should be subtracted from the current nesting counter.
nFlags  
  • SEM_NOSIG Ignore signals while blocking on the semaphore. Only set this flag on semaphores that are known to be released realtively soon. Otherwhise the caller should handle the EINTR error and exit from the kernel as soon as possible if a signal is caught.
nTimeOut   Maximum number of micro seconds to wait for the semaphore to be released. If the timeout is 0 lock_semaphore_ex() will never return, and if it is INFINITE_TIMEOUT it will block until the semaphore can be aquired or a signel is caught.
Returns:
On success 0 is returned. On error a negative error code is returned.
Error codes:
  • ETIME the semaphore could not be aquired before the timeout expiered.
  • EINTR a signal was caught before the semaphore could be aquired.
  • EINVAL hSema was not a valid semaphore handle, or the semaphore was deleted while we blocked.
See also:
unlock_semaphore_ex(), lock_semaphore(), unlock_semaphore_ex(), create_semaphore(), delete_semaphore(), unlock_semaphore(), unlock_semaphore_ex(), sleep_on_sem(), wakeup_sem(), unlock_and_suspend() spinunlock_and_suspend()
Author(s):
Kurt Skauen (kurt@atheos.cx)

int rename_device_node ( int nHandle,
const char * pzNewPath )
 

Rename and/or move a device node.

Description:
A device driver can rename and/or move a device node inside the /dev/ hierarchy. The new path should be relative to /dev/ and have the same format as the path passed to create_device_node().
Parameters:
nHandle   A device-node handle returned by a previous call to create_device_node()
pzNewPath   The new device-node path.
Returns:
See also:
create_device_node(), delete_device_node()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t rename_process ( int nProcessID,
const char * pzName )
 

Rename a process.

Description:
All processes have a name to aid debugging and to some degree make it possible to search for a process by name. The name is normally inherited from the parent during fork and later set to the executable name if the process exec's but it can also be set explicitly with rename_process().
Note:
The name will be replaced with the name of the executable if the process ever call execve().
Parameters:
nProcessID   Identity of the process to rename. You can also pass in -1 to rename the calling process.
pzName   The new process name. Maximum OS_NAME_LENGTH characters long including the 0 termination. On success 0 is returned. On error a negative error code is returned.
Error codes:
  • ESRCH nProcessID is not -1 and there is not process with that ID.
See also:
rename_thread(), get_process_id()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t sleep_on_sem ( sem_id hSema,
bigtime_t nTimeOut )
 

Non conditionally block on a semaphore (wait-queue).

Description:
Non conditionaly block on an semaphore until someone does a wakeup_sem(), we reach the timeout, or we catch a signal.

A semaphore (as created with create_semaphore()) can be used as a wait-queue rather than a semaphore/mutex by using sleep_on_sem() and wakeup_sem() instead of lock_semaphore() and unlock_semaphore().
Warning:
You should not mix calls to lock_semaphore()/unlock_semaphore() with sleep_on_sem()/wakeup_sem().
Parameters:
hSema   The wait-queue to sleep on (created with create_semaphore()).
nTimeout   Maximum number of microseconds to wait for someone to wake us up before ETIME is returned.

Returns:
On success 0 is returned. On error a negative error code is returned.
Error codes:
  • EINVAL hSema is not a valid semaphore handle.
  • ETIME Nobody woke us up before the timeout.
See also:
create_semaphore(), wakeup_sem()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t spinunlock_and_suspend ( sem_id hWaitQueue,
SpinLock_s * psLock,
uint32 nCPUFlags,
bigtime_t nTimeout )
 

Release a sinlock and block on a wait-queue in one atomic operation.

Description:
Same as unlock_and_suspend() except that it releases a spinlock instead of a regular semaphore. This is usefull for device-drivers that receive or transmitt data through interrupt handlers, and then need to syncronize this with threads that deliver or use the data.
Note:
Interrupts *MUST* be disabled prior to calling this function. The CPU flags will be restored to the value of nCPUFlags before returning unless an error (other than receiving a signal) occured.

This function can only be called from the kernel, or from device drivers. From user-space you should use unlock_and_suspend()
Warning:
Parameters:
return  
See also:
unlock_and_suspend()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t unlock_and_suspend ( sem_id hWaitQueue,
sem_id hSema )
 

Unlock a reqular semaphore and block on a wait-queue.

Description:
Unlocks an regular semaphore, and sleep on a wait-queue in one atomic operation. No other thread's will be able to lock the semaphore until we are safely added to the wait-queue. This is useful for example when waiting for data to arrive to an object, since it can guaranty that nobody can lock the object, and attempt to wake up sleeper's while you are in the gap between unlocking the object and blocking on the wait-queue.
Parameters:
hWaitQueue   Handle to the wait-queue to block on (created earlier with create_semaphore())
hSema   Semaphore to release.

Returns:
0 on success or a negative error code on failure.
See also:
unlock_semaphore(), sleep_on_sem(), spinunlock_and_suspend()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t unlock_semaphore ( sem_id hSema )
 

Release a semaphore.

Description:
Same as unlock_semaphore_x() with a count of 1.
See also:
unlock_semaphore_x()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t unlock_semaphore_ex ( sem_id hSema,
int nCount )
 

Release a semaphore.

Description:
Release a semaphore "nCount" number of times. The value of "nCount" will be added to the semaphores nesting counter and if the counter become positive (>=0) the first thread blocking on the semaphore will be unblocked.
Note:
If "nCount" is larger than 1 all blocked threads will be unblocked and they will then compeat for the semaphore based on their scheduler priority. If "nCount" is 1 only the first blocked thread will be unblocked.
Parameters:
hSema   The semaphore to release.
nCount   Number of times to release the semaphore.
Returns:
On success 0 is returned. On error a negative error code is returned.
Error codes:
  • EINVAL hSema is not a valid semaphore handle.
See also:
unlock_semaphore(), lock_semaphore_ex()
Author(s):
Kurt Skauen (kurt@atheos.cx)

status_t wakeup_sem ( sem_id hSema,
bool bAll )
 

Wake up threads blocked on a wait-queue.

Description:
Wake up eighter the first thread (the one that first blocked) or all threads blocked on a wait-queue.

If "bAll" is true all semaphores blocked on the queue will be released otherwhice only the first thread will be unblocked.
Warning:
You should not mix calls to lock_semaphore()/unlock_semaphore() with sleep_on_sem()/wakeup_sem().
Parameters:
hSema   Wait-queue to release (created with create_semaphore()).
bAll   true to wake up all threads, false to only wake up the first thread in the queue.
Returns:
On success 0 is returned. On error a negative error code is returned.
Error codes:
  • EINVAL hSema is not a valid semaphore handle.
See also:
sleep_on_sem(), create_semaphore()
Author(s):
Kurt Skauen (kurt@atheos.cx)


Generated at Sat Apr 7 16:12:35 2001 for AtheOS device driver API by doxygen1.2.5 written by Dimitri van Heesch, © 1997-2001