\section{Device Interfaces}

A device class represents the functional type of a device, but it is
characterized by the interfaces to communicate with that type of
device. A device class interface defines a set of semantics to
communicate with a device of a certain type. These are most
often in the form of device nodes visible to user space, though they could
also be regular files in a filesystem exported by the kernel. 

There may be multiple interfaces per device type, and not all devices
or drivers of a class may support all the interfaces of that
class. For example, the input device class describes devices that are
capable of generating input for the kernel. A device and driver may
support multiple ways of communicating with it. For example, a touch
screen may be accessed as a mouse device, as well as a touch screen
device. However, a mouse device may be accessed using only the mouse
interface, and not the touchscreen interface.

The driver model defines struct device\_interface to describe device
interfaces. They are simple structures that may be dynamically
registered and unregistered with device classes. A class's interfaces
are referenced when a device is added to or removed from the class. When
a device is added, the driver model attempts to add the device to
every interface registered with the class. 

A device may not support all of the interfaces registered with the
device, so the driver model defines a separate object type to express
a device's membership with an interface. An instance of this object is
added to a device's list. When a device is removed from a class, it is
removed from the interfaces to which it had been added by iterating
over this list, rather than the list of the class's interfaces.


\subsection*{Driver Model Representation}

struct device\_interface is similar to struct device\_class, though
simpler. Its member fields and methods are described below.


\begin{table}
\begin{footnotesize}
\begin{tabularx}{\linewidth}{|X|X|X|} \hline
\textit{Name}	& \textit{Return Type} & \textit{Description} \\ \hline \hline

name	& char *	& Name of interface (must be unique only for class).
\\\hline

devclass	& struct device\_class *	& Class interface belongs to.
\\\hline

subsys	& struct subsystem	& Collection of subordinate objects.
\\\hline

devnum	& u32	& Enumerator for registered devices.
\\\hline

\end{tabularx} \\
\end{footnotesize}
\caption{\footnotesize{struct device\_interface Data Fields.}}
\end{table}


An interface's 'subsys' member contains generic object meta data and
is registered as subordinate of the subsystem of the interface's
device class. It is also used to contain the device-specific objects
allocated by the interface.

The 'devnum' member is used to enumerate devices when they are
registered with the interface. When an interface attaches the
device-specific data to the interface, it is assigned the value of
'devnum', which is then incremented.



\begin{table}
\begin{footnotesize}
\begin{tabularx}{\linewidth}{|X|X|X|} \hline
\textit{Name}	& \textit{Return Type} & \textit{Description} \\ \hline \hline

add\_device(
  struct device *
)
& int
& Called to register device with interface, after device has been
	registered with class. 
\\\hline

remove\_device(
  struct intf\_data *
)
& int
& Called to unregister device from interface, before device has been
	unregistered from class.
\\\hline

\end{tabularx} \\
\end{footnotesize}
\caption{\footnotesize{struct device\_interface Methods.}}
\end{table}



\subsection*{Programming Interface}

Interface objects should be statically allocated and registered on
startup. They should initialize the 'name' and 'devclass' field, as
well as the methods they support. Interfaces support only a
registration interface. There is no explicit mechanism to perform
reference counting on them, though one could do so directly on the
embedded struct subsystem.


\begin{table}
\begin{footnotesize}
\begin{tabularx}{\linewidth}{|X|X|X|} \hline
\textit{Name}	& \textit{Return Type} & \textit{Description} \\ \hline \hline

interface\_register(
  struct device\_interface *
)
& int
& Register interface with class.
\\\hline

interface\_unregister(
  struct device\_interface *
)
& void
& Unregister interface from class.
\\\hline

\end{tabularx} \\
\end{footnotesize}
\caption{\footnotesize{struct device\_interface Programming Interface.}}
\end{table}


\subsection*{Interface Data}

The driver model defines an object, struct intf\_data, to describe a
device-specific object for an interface. This object can be registered
as an object of the interface's embedded subsystem and added to the
'intf\_list' member of struct device. This allows interfaces to
maintain an accurate list of registered devices, and for
devices to maintain an accurate list of interface membership.

This is necessary since devices may not belong to all of
the interfaces of a device class, and an interface may not be valid
for all devices registered with a device class. When a device
is removed from a device class, the driver model core can iterate over
the device's list of intf\_data objects to reference its containing
interfaces. And, when an interface is removed from a class, the driver
model core can iterate over the interface's subordinate kobjects -
since they are embedded in struct intf\_data - to reference the attached
devices.


\begin{table}
\begin{footnotesize}
\begin{tabularx}{\linewidth}{|X|X|X|} \hline
\textit{Name}	& \textit{Return Type} & \textit{Description} \\ \hline \hline

intf
& struct device\_interface
& Interface data belongs to.
\\\hline

dev
& struct device *
& Device being registered with interface.
\\\hline

intf\_num
& u32
& Interface-enumerated value of this object.
\\\hline

dev\_entry
& struct list\_head
& List entry in device's list of interface objects.
\\\hline

kobj
& struct kobject
& Generic object data.
\\\hline

\end{tabularx} \\
\end{footnotesize}
\caption{\footnotesize{struct intf\_data Data Members.}}
\end{table}



\begin{table}
\begin{footnotesize}
\begin{tabularx}{\linewidth}{|X|X|X|} \hline
\textit{Name}	& \textit{Return Type} & \textit{Description} \\ \hline \hline

interface\_add\_data(
  struct intf\_data *
)
& int
& Attach data object to interface and device. This should usually be
	called during the interface's add\_device() method once it's
	determined the device can support it.
\\\hline


\end{tabularx} \\
\end{footnotesize}
\caption{\footnotesize{struct intf\_data Programming Interface.}}
\end{table}


struct intf\_data may be embedded in a more complex device-specific
data structure for the interface, or may be allocated separately. It
should be allocated during the core's call to the interface's
add\_device method. This method should then call
interface\_add\_data() to attach the data to the deivce and the
interface. The interface should initialize the 'intf' and 'dev'
members of the intf\_data object before calling
interface\_add\_data().


When a device is removed from an interface, the internal function
interface\_remove\_data() is called immediately before the interface's
remove\_device() method. This detaches it from the device and the
interface, so that the interface may free the structure in their
remove\_device() method. 

