From 48367c0c4996f48217e3768bf0fd8dd599434ec4 Mon Sep 17 00:00:00 2001 From: Manuel Traut Date: Thu, 12 Apr 2012 17:34:47 +0200 Subject: add new chapter about the struct device - what is it - how is it used - should be extended to sth. like linux driver model overview Signed-off-by: Manuel Traut --- kernel-devel/linux-device/Makefile | 9 + .../linux-device/hints_linux-device_en.tex | 15 ++ kernel-devel/linux-device/pres_linux-device_en.tex | 237 +++++++++++++++++++++ 3 files changed, 261 insertions(+) create mode 100644 kernel-devel/linux-device/Makefile create mode 100644 kernel-devel/linux-device/hints_linux-device_en.tex create mode 100644 kernel-devel/linux-device/pres_linux-device_en.tex diff --git a/kernel-devel/linux-device/Makefile b/kernel-devel/linux-device/Makefile new file mode 100644 index 0000000..be2c24b --- /dev/null +++ b/kernel-devel/linux-device/Makefile @@ -0,0 +1,9 @@ +all: + for pdf in `ls -1 *.tex` ; do \ + TEXINPUTS=`pwd`:`pwd`/../..:.:..:$(TEXINPUTS) pdflatex $$pdf; \ + TEXINPUTS=`pwd`:`pwd`/../..:.:..:$(TEXINPUTS) pdflatex $$pdf; \ + done + +clean: + rm -f *.aux *.log *.pdf *.log *.snm *.toc *.vrb *.nav *.out + diff --git a/kernel-devel/linux-device/hints_linux-device_en.tex b/kernel-devel/linux-device/hints_linux-device_en.tex new file mode 100644 index 0000000..20174ab --- /dev/null +++ b/kernel-devel/linux-device/hints_linux-device_en.tex @@ -0,0 +1,15 @@ +\documentclass{article} +\usepackage{german} +\usepackage[utf8]{inputenc} + +\begin{document} + +\section*{Linux Device Structure\rq} + +\subsection*{Lernziele} +\begin{itemize} +\item Sinn und Zweck von 'struct device' +\item wichtige Funktionen in Verbindung mit 'struct device' +\end{itemize} + +\end{document} diff --git a/kernel-devel/linux-device/pres_linux-device_en.tex b/kernel-devel/linux-device/pres_linux-device_en.tex new file mode 100644 index 0000000..1d49773 --- /dev/null +++ b/kernel-devel/linux-device/pres_linux-device_en.tex @@ -0,0 +1,237 @@ +\input{configpres} + +\title{struct device} +%\maketitle + +\begin{frame} +\maketitle{aim} +\begin{itemize} +\item lowest level representation of every device in a Linux system +\item hosts information that the device model core needs to model the system +\item most subsystems track additional information about the devices they host +\item it is rare for devices to be represented by bare device structures +\item this struct is usually embedded within higher-level representation of + the device +\end{itemize} +\end{frame} + +\subtitle{components of the struct} + +\begin{frame} +\frametitle{name and type} +for example a mouse device +\begin{tiny} +\begin{lstlisting}[frame=trBL] +include/linux/device.h: +... +struct device { + ... + const char *init_name; + const struct device_type *type; + ... +\end{lstlisting} +\end{tiny} +\end{frame} + +\begin{frame} +\frametitle{connection of multiple devices} +for example usb-hostcontroller1/usb-device3/usb-endpoint4/mouse +\begin{tiny} +\begin{lstlisting}[frame=trBL] +include/linux/device.h: +... +struct device { + ... + struct device *parent; + ... +\end{lstlisting} +\end{tiny} +\begin{itemize} +\item 'parent' is a ptr to the device to which this device is attached +\item normaly a parent device is some sort of bus or host controller +\item If parent is NULL, the device, is a top-level device, which is not + usually what you want +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{private data} +\begin{tiny} +\begin{lstlisting}[frame=trBL] +drivers/base/base.h +... +struct device_private { + struct klist klist_children; //containing all children of this device + struct klist_node knode_parent; //node in sibling list + struct klist_node knode_driver; //node in driver list + struct klist_node knode_bus; //node in bus list + struct list_head deferred_probe;//entry in deferred_probe_list + void *driver_data; //private pointer for driver specific info + struct device *device; //pointer back to the device +}; +... +include/linux/device.h: +... +struct device { + ... + struct device_private *p; + ... +\end{lstlisting} +\end{tiny} +\end{frame} + +\begin{frame} +\frametitle{bus} +\begin{tiny} +\begin{lstlisting}[frame=trBL] +include/linux/device.h: +... +struct device { + ... + struct bus_type *bus; + ... +\end{lstlisting} +\end{tiny} +\begin{itemize} +\item used by driver core to link between bus - device +\item hosts pointer for: probe, remove, suspend, \dots +\item these functions are called by the driver core on bus state changes +\item bus drivers need to implement these calls and normaly redirect them to + the associated devices +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{driver} +\begin{tiny} +\begin{lstlisting}[frame=trBL] +include/linux/device.h: +... +struct device { + ... + struct device_driver *driver; + ... +\end{lstlisting} +\end{tiny} +\begin{itemize} +\item used by driver core to link between driver - device +\item hosts a table of device id, the driver is responsible for +\item hosts pointer for: probe, remove, suspend, \dots +\item these functions are called by the bus driver on bus state changes +\item device drivers need to implement these calls +\item e.g. after a succesful probe call a driver is responsible for a device +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{platform data} +\begin{tiny} +\begin{lstlisting}[frame=trBL] +include/linux/device.h: +... +struct device { + ... + void *platform_data; + ... +\end{lstlisting} +\end{tiny} +\begin{itemize} +\item structure is declared by the platform device driver +\item structure is normally initialized by 'board support package' +\item hosts for example how a specific device is connected (mem\_base, irq) +\item can host informations about chip variants +\item shrinks 'board support packages' +\item reduces board specific #ifdefs in driver code +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{misc} +\begin{itemize} +\item structs for device power management +\item ptr to NUMA node this device is close to +\item structs for DMA handling (if device is DMA capable) +\item information about associated device node(s) (/dev/huhu) +\item unique device id +\item lock to protect device resources +\item pointer to release() function of the device +\end{itemize} +\end{frame} + +\subtitle{how is it used} + +\begin{frame} +\frametitle{initialization} +The bus driver that discovers the device uses this to register the device with +the core: +\begin{tiny} +\begin{lstlisting}[frame=trBL] +int device_register(struct device * dev); +\end{lstlisting} +\end{tiny} +these fields should be initialized before calling the register function: +\begin{itemize} +\item parent +\item name +\item bus\_id +\item bus +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{use by a driver} +A device is removed from the core when its reference count goes to 0. +The reference count can be adjusted using: +\begin{tiny} +\begin{lstlisting}[frame=trBL] +struct device * get_device(struct device * dev); +void put_device(struct device * dev); +\end{lstlisting} +\end{tiny} +The device lock can be accessed by: +\begin{tiny} +\begin{lstlisting}[frame=trBL] +void lock_device(struct device * dev); +void unlock_device(struct device * dev); +\end{lstlisting} +\end{tiny} +\end{frame} + +\begin{frame} +\frametitle{device attributes} +Attributes can be exported to sysfs by the device driver. +\begin{tiny} +\begin{lstlisting}[frame=trBL] +my.c: +... +static DEVICE_ATTR(ro, 0444, my_show_ro, NULL); +static DEVICE_ATTR(rw, 0644, my_show_rw, my_store_rw); + +static struct attribute *my_dev_attrs[] = { + &dev_attr_ro.attr, + &dev_attr_rw.attr, + NULL, +}; + +static struct attribute_group my_dev_attr_group = { + .attrs = my_dev_attrs, +}; + +static const struct attribute_group *my_dev_attr_groups[] = { + &my_dev_attr_group, + NULL, +}; + +static int __init my_driver_init(struct device *my_dev) +{ + ... + my_dev->groups = my_dev_attr_groups; + device_register(my_dev); + ... +} + +\end{lstlisting} +\end{tiny} +\end{frame} + +\input{tailpres} -- cgit v1.2.3