\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