\chapter{Device drivers}

\section{Introduction}

The purpose of a device driver is to act as an intermediate layer
between an operating-specific API that is common for a group of
similar devices and vendor-specific interfaces for individual types of
devices. 

An important part of writing device drivers for a Lisp operating
system is therefore to specify the different groups of devices and the
corresponding operating-specific API for each group.%
\footnote{As everything else in this document, this chapter is open to
  discussion.  More so here, because I have no prior experience in
  defining device-driver APIs. -- RS}

\section{Tickets}

Some I/O operations, when called, return an object of type
\emph{ticket}.  A ticket is either \emph{pending} or it has
\emph{expired}.  A pending ticket corresponds to an I/O operation that
is not yet complete.  

\Defprotoclass{ticket}

The base class for all tickets.

\Defclass{standard-ticket}

Instantiable subclass of the class \texttt{ticket}

\Defgeneric {expired-p} {ticket}

Return true if and only if \textit{ticket} has expired.

\Defun {wait-some} {\rest tickets}

Suspend the current process until one of the tickets has expired. 

\Defun {wait-all} {\rest tickets}

Suspend the current process until all of the tickets have expired.

\section{Disk drivers}

\Defprotoclass{disk}

This is the root class of all disk device classes.  A disk is a device
that stores data in \emph{blocks}.  The size of a block varies between
different types of disks.  Blocks are numbered from $0$ to $N-1$ where
$N$ is the total number of blocks on this device.  Because of the
existence of bad blocks, $N$ may be smaller than the nominal size of
the device.  Nevertheless, the driver and the disk controller conspire
to present the disk as contiguous sequence of blocks. 

\Defclass{standard-disk}

This class is an instantiable subclass of the class \texttt{disk}. 

\Defgeneric {size} {disk}

Return the number of blocks that \textit{disk} may store, so excluding
bad blocks.

\Defgeneric {block-size} {disk}

Return the size of a native block for \textit{disk}.  This size is the
preferred size to use in transfers to and from this type of disk.

\Defgeneric {write-block} {disk block address}

Issue a \emph{write} operation transferring the data in \textit{block}
to \textit{disk}.  The parameter \textit{disk} is an
instance of the class \textit{disk}, and \textit{block} is a a vector
of type \texttt{(simple-array (unsigned-byte 8) (*))}.  The size of
\textit{block} must be a power of 2, and the address must be aligned
to the size of \textit{block}.  If the size of \textit{block} is
\emph{smaller} than the native block size of \textit{disk} then a
request to read an entire native block will be issued and the result
will be stored in a temporary location.  Part of the native block in
the temporary location will then be overwritten by the contents of
\textit{block}.  Finally, the contents of the temporary location will
be written to the device.  If the size of \textit{block} is
\emph{greater} than the native block size of \textit{disk}, then
several native blocks will be written from \textit{block}.

A call to this generic function returns an instance of the class
\texttt{ticket}.  The functions \texttt{wait-some} and
\texttt{wait-all} can be used to wait for the I/O operation to finish.

\Defgeneric {read-block} {disk block address}

Read a block of data from the disk.  The parameter \textit{disk} is an
instance of the class \textit{disk}, and \textit{block} is a a vector
of type \texttt{(simple-array (unsigned-byte 8) (*))}.  The size of
\textit{block} must be a power of 2, and the address must be aligned
to the size of \textit{block}.  If the size of \textit{block} is
\emph{smaller} than the native block size of \textit{disk} then a
request to read an entire native block will be issued and the result
will be stored in a temporary location.  Then a part of that native
block will be copied to \textit{block}.  If the size of \textit{block}
is \emph{greater} than the native block size of \textit{disk}, then
several native blocks will be read into \textit{block}.

A call to this generic function returns an instance of the class
\texttt{ticket}.  The functions \texttt{wait-some} and
\texttt{wait-all} can be used to wait for the I/O operation to finish.

%%  LocalWords:  instantiable
