diff options
| author | Benedikt Spranger <b.spranger@linutronix.de> | 2009-11-24 08:58:33 +0100 |
|---|---|---|
| committer | Benedikt Spranger <b.spranger@linutronix.de> | 2009-11-24 08:58:33 +0100 |
| commit | 8467e6f35df9e7f39c727e51d50c00f96a1081c9 (patch) | |
| tree | 7602c7e1376915b6ea1d7902af0efa858aff7e1f /kernel-devel | |
| parent | 7ec20455300298bb170ba50c1b22c1d9236cef00 (diff) | |
PCI example added
Diffstat (limited to 'kernel-devel')
| -rw-r--r-- | kernel-devel/module-basics/images/PCI_driver.dia | bin | 0 -> 2492 bytes | |||
| -rw-r--r-- | kernel-devel/module-basics/images/PCI_driver.png | bin | 0 -> 22853 bytes | |||
| -rw-r--r-- | kernel-devel/module-basics/pres_module-basics_de.tex | 244 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain/vain.c | 1 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_pci/Makefile | 13 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_pci/vain_pci.c | 6 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_pci/vain_pci_1.c | 19 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_pci/vain_pci_2.c | 22 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_pci/vain_pci_3.c | 17 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_pci/vain_pci_4.c | 21 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_pci/vain_pci_5.c | 23 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_pci/vain_pci_6.c | 7 | ||||
| -rw-r--r-- | kernel-devel/module-basics/vain_pci/vain_pci_orig.c | 114 |
13 files changed, 483 insertions, 4 deletions
diff --git a/kernel-devel/module-basics/images/PCI_driver.dia b/kernel-devel/module-basics/images/PCI_driver.dia Binary files differnew file mode 100644 index 0000000..cc9a630 --- /dev/null +++ b/kernel-devel/module-basics/images/PCI_driver.dia diff --git a/kernel-devel/module-basics/images/PCI_driver.png b/kernel-devel/module-basics/images/PCI_driver.png Binary files differnew file mode 100644 index 0000000..02fe4cb --- /dev/null +++ b/kernel-devel/module-basics/images/PCI_driver.png diff --git a/kernel-devel/module-basics/pres_module-basics_de.tex b/kernel-devel/module-basics/pres_module-basics_de.tex index 3e62220..a62397c 100644 --- a/kernel-devel/module-basics/pres_module-basics_de.tex +++ b/kernel-devel/module-basics/pres_module-basics_de.tex @@ -11,8 +11,7 @@ \institute{Linutronix GmbH} \begin{document} -\lstset{language=[ANSI]C} - +\lstset{language=[ANSI]C, moredelim=[is][\color{blue}]{|}{|}} \maketitle % ----- Slide Aufbau ------------------ @@ -69,6 +68,7 @@ module_exit(vain_exit); MODULE_AUTHOR("Benedikt Spranger <b.spranger@linutronix.de>"); MODULE_DESCRIPTION("a more or less useless module"); MODULE_LICENSE("GPL v2"); +MODULE_VERSION("0815"); \end{lstlisting} \end{tiny} \end{itemize} @@ -104,8 +104,8 @@ make[1]: Entering directory `/usr/src/linux-2.6.30' CC [M] /path/to/vain/vain.o Building modules, stage 2. MODPOST 1 modules - CC /path/to//vain/vain.mod.o - LD [M] /path/to//vain/vain.ko + CC /path/to/vain/vain.mod.o + LD [M] /path/to/vain/vain.ko make[1]: Leaving directory `/usr/src/linux-2.6.30' $ \end{verbatim} @@ -132,4 +132,240 @@ vain_exit: done \end{itemize} \end{frame} +% ----- Slide Komplexere Module ------------------ +\begin{frame} +\frametitle{Komplexere Modul} +\pause +\begin{itemize} +\item Teil eines Bussystems +\pause +\begin{itemize} +\item USB +\pause +\item PCI +\pause +\item Platform +\pause +\item \dots +\pause +\end{itemize} +\item Teil eines Subsystems +\pause +\begin{itemize} +\item Character-Devices +\pause +\item Block-Devices +\pause +\item Network-Devices +\pause +\item \dots +\end{itemize} +\end{itemize} +\end{frame} + +% ----- Slide PCI Treiber ------------------ +\begin{frame}[fragile] +\frametitle{Aufbau eines PCI Treiber Moduls} +\pause +\begin{itemize} +\item Header +\pause +\begin{tiny} +\begin{lstlisting}[frame=trBL] +#include <linux/init.h> +#include <linux/module.h> +|#include <linux/pci.h>| +\end{lstlisting} +\end{tiny} +\pause +\item Init +\pause +\begin{tiny} +\begin{lstlisting}[frame=trBL] +static int vain_pci_init(void) +{ + int err; + + |err = pci_register_driver(&vain_pci_driver);| + + if (!err) + printk(KERN_INFO "vain_pci_init: done\n"); + return err; +} + +module_init(vain_pci_init); +\end{lstlisting} +\end{tiny} +\end{itemize} +\end{frame} + +% ----- Slide PCI Treiber (fort.) ------------------ +\begin{frame}[fragile] +\frametitle{Aufbau eines PCI Treiber Moduls (fort.)} +\begin{itemize} +\item Exit +\pause +\begin{tiny} +\begin{lstlisting}[frame=trBL] +static void vain_pci_exit(void) +{ + |pci_unregister_driver(&vain_pci_driver);| + printk(KERN_INFO ``vain_pci_exit: done\n''); +} + +module_exit(vain_pci_exit); +\end{lstlisting} +\end{tiny} +\end{itemize} +\end{frame} + +% ----- Slide PCI Treiber (fort.) ------------------ +\begin{frame}[fragile] +\frametitle{Aufbau eines PCI Treiber Moduls (fort.)} +\begin{itemize} +\item struct pci\_driver +\pause +\begin{tiny} +\begin{lstlisting}[frame=trBL] +|static struct pci_driver vain_pci_driver = { + .name = "vain_pci", + .id_table = vain_pci_ids, + .probe = vain_pci_probe, + .remove = __devexit_p(vain_pci_remove), +};| +\end{lstlisting} +\end{tiny} +\end{itemize} +\end{frame} + +% ----- Slide PCI Treiber (fort.) ------------------ +\begin{frame}[fragile] +\frametitle{Aufbau eines PCI Treiber Moduls (fort.)} +\begin{itemize} +\item struct struct pci\_device\_id +\pause +\begin{tiny} +\begin{lstlisting}[frame=trBL] +|static struct pci_device_id vain_pci_ids[] __devinitdata = { + {PCI_VENDOR_ID_ILLEGAL_VENDOR, PCI_DEVICE_ID_ILLEGAL_VENDOR_DEVICE, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + {0, } +};| +\end{lstlisting} +\end{tiny} +\end{itemize} +\end{frame} + +% ----- Slide PCI Treiber (fort.) ------------------ +\begin{frame}[fragile] +\frametitle{Aufbau eines PCI Treiber Moduls (fort.)} +\begin{itemize} +\item probe +\pause +\begin{tiny} +\begin{lstlisting}[frame=trBL] +|static int __devinit vain_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int ret; + + ret = pci_enable_device(pdev); + if (ret) + goto err_free; + + ret = pci_request_regions(pdev, "vain_pci"); + if (ret) + goto err_disable_device; + + info->base = pci_ioremap_bar(pdev, 0); + if (!info->base) { + ret = -ENODEV; + goto err_rel_regs; + } + + return 0;| +\end{lstlisting} +\dots +\end{tiny} +\end{itemize} +\end{frame} + +% ----- Slide PCI Treiber (fort.) ------------------ +\begin{frame}[fragile] +\frametitle{Aufbau eines PCI Treiber Moduls (fort.)} +\begin{itemize} +\item remove +\pause +\begin{tiny} +\begin{lstlisting}[frame=trBL] +|static void __devexit vain_pci_remove(struct pci_dev *pdev) +{ + struct vain_pci_info *info = pci_get_drvdata(pdev); + + iounmap(info->base); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + + kfree (info); +}| +\end{lstlisting} +\end{tiny} +\end{itemize} +\end{frame} + +% ----- Slide PCI Treiber Hintergrund ------------------ +\begin{frame} +\frametitle{PCI Treiber Hintergrund} +\includegraphics[width=7cm]{images/PCI_driver.png} +\end{frame} + +% ----- Slide PCI Rumpf Treiber ------------------ +\begin{frame}[fragile] +\frametitle{PCI Rumpf Treiber} +\begin{tiny} +\lstinputlisting{vain_pci/vain_pci_1.c} +\end{tiny} +\end{frame} + +% ----- Slide PCI Rumpf Treiber (fort.) ------------------ +\begin{frame}[fragile] +\frametitle{PCI Rumpf Treiber (fort.)} +\begin{tiny} +\lstinputlisting{vain_pci/vain_pci_2.c} +\end{tiny} +\end{frame} + +% ----- Slide PCI Rumpf Treiber (fort.) ------------------ +\begin{frame}[fragile] +\frametitle{PCI Rumpf Treiber (fort.)} +\begin{tiny} +\lstinputlisting{vain_pci/vain_pci_3.c} +\end{tiny} +\end{frame} + +% ----- Slide PCI Rumpf Treiber (fort.) ------------------ +\begin{frame}[fragile] +\frametitle{PCI Rumpf Treiber (fort.)} +\begin{tiny} +\lstinputlisting{vain_pci/vain_pci_4.c} +\end{tiny} +\end{frame} + +% ----- Slide PCI Rumpf Treiber (fort.) ------------------ +\begin{frame}[fragile] +\frametitle{PCI Rumpf Treiber (fort.)} +\begin{tiny} +\lstinputlisting{vain_pci/vain_pci_5.c} +\end{tiny} +\end{frame} + +% ----- Slide PCI Rumpf Treiber (fort.) ------------------ +\begin{frame}[fragile] +\frametitle{PCI Rumpf Treiber (fort.)} +\begin{tiny} +\lstinputlisting{vain_pci/vain_pci_6.c} +\end{tiny} +\end{frame} + \end{document} diff --git a/kernel-devel/module-basics/vain/vain.c b/kernel-devel/module-basics/vain/vain.c index 6b27033..a4564a9 100644 --- a/kernel-devel/module-basics/vain/vain.c +++ b/kernel-devel/module-basics/vain/vain.c @@ -18,3 +18,4 @@ module_exit(vain_exit); MODULE_AUTHOR("Benedikt Spranger <b.spranger@linutronix.de>"); MODULE_DESCRIPTION("a more or less useless module"); MODULE_LICENSE("GPL v2"); +MODULE_VERSION("0815") diff --git a/kernel-devel/module-basics/vain_pci/Makefile b/kernel-devel/module-basics/vain_pci/Makefile new file mode 100644 index 0000000..3c10921 --- /dev/null +++ b/kernel-devel/module-basics/vain_pci/Makefile @@ -0,0 +1,13 @@ +# If KERNELRELEASE is defined, we've been invoked from the +# kernel build system and can use its language. +ifneq ($(KERNELRELEASE),) + obj-m := vain_pci.o + +# Otherwise we were called directly from the command +# line; invoke the kernel build system. +else + KERNELDIR ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules +endif
\ No newline at end of file diff --git a/kernel-devel/module-basics/vain_pci/vain_pci.c b/kernel-devel/module-basics/vain_pci/vain_pci.c new file mode 100644 index 0000000..ff95d0d --- /dev/null +++ b/kernel-devel/module-basics/vain_pci/vain_pci.c @@ -0,0 +1,6 @@ +#include "vain_pci_1.c" +#include "vain_pci_2.c" +#include "vain_pci_3.c" +#include "vain_pci_4.c" +#include "vain_pci_5.c" +#include "vain_pci_6.c" diff --git a/kernel-devel/module-basics/vain_pci/vain_pci_1.c b/kernel-devel/module-basics/vain_pci/vain_pci_1.c new file mode 100644 index 0000000..d60b230 --- /dev/null +++ b/kernel-devel/module-basics/vain_pci/vain_pci_1.c @@ -0,0 +1,19 @@ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/pci.h> + +#define PCI_VENDOR_ID_ILLEGAL_VENDOR 0xffff +#define PCI_DEVICE_ID_ILLEGAL_VENDOR_DEVICE 0x2342 + +struct vain_pci_info { + void __iomem *base; + struct pci_dev *pdev; + spinlock_t lock; +}; + +static struct pci_device_id vain_pci_ids[] __devinitdata = { + {PCI_VENDOR_ID_ILLEGAL_VENDOR, PCI_DEVICE_ID_ILLEGAL_VENDOR_DEVICE, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + {0, } +}; +MODULE_DEVICE_TABLE(pci, vain_pci_ids); diff --git a/kernel-devel/module-basics/vain_pci/vain_pci_2.c b/kernel-devel/module-basics/vain_pci/vain_pci_2.c new file mode 100644 index 0000000..cc4118d --- /dev/null +++ b/kernel-devel/module-basics/vain_pci/vain_pci_2.c @@ -0,0 +1,22 @@ +static int __devinit vain_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct vain_pci_info *info; + int ret; + + dev_dbg(&pdev->dev, "Init, new card found\n"); + + info = kzalloc(sizeof(struct vain_pci_info), GFP_KERNEL); + if (unlikely(!info)) { + dev_err(&pdev->dev, "Could not allocate memory\n"); + ret = -ENOMEM; + goto err_free; + } + + info->pdev = pdev; + + ret = pci_enable_device(pdev); + if (ret) { + dev_err(&pdev->dev, "Failed to enable PCI Device\n"); + goto err_free; + } diff --git a/kernel-devel/module-basics/vain_pci/vain_pci_3.c b/kernel-devel/module-basics/vain_pci/vain_pci_3.c new file mode 100644 index 0000000..77bee68 --- /dev/null +++ b/kernel-devel/module-basics/vain_pci/vain_pci_3.c @@ -0,0 +1,17 @@ + ret = pci_request_regions(pdev, "vain_pci"); + if (ret) { + dev_err(&pdev->dev, "I/O address 0x%04x already in use\n", + (int) /* nozomi_private.io_addr */ 0); + goto err_disable_device; + } + + info->base = pci_ioremap_bar(pdev, 0); + if (!info->base) { + dev_err(&pdev->dev, "Unable to map card MMIO\n"); + ret = -ENODEV; + goto err_rel_regs; + } + + pci_set_drvdata(pdev, info); + + return 0; diff --git a/kernel-devel/module-basics/vain_pci/vain_pci_4.c b/kernel-devel/module-basics/vain_pci/vain_pci_4.c new file mode 100644 index 0000000..f238f22 --- /dev/null +++ b/kernel-devel/module-basics/vain_pci/vain_pci_4.c @@ -0,0 +1,21 @@ +err_rel_regs: + pci_release_regions(pdev); +err_disable_device: + pci_disable_device(pdev); +err_free: + kfree(info); + + return ret; +} + +static void __devexit vain_pci_remove(struct pci_dev *pdev) +{ + struct vain_pci_info *info = pci_get_drvdata(pdev); + + iounmap(info->base); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + + kfree (info); +} diff --git a/kernel-devel/module-basics/vain_pci/vain_pci_5.c b/kernel-devel/module-basics/vain_pci/vain_pci_5.c new file mode 100644 index 0000000..6bdc314 --- /dev/null +++ b/kernel-devel/module-basics/vain_pci/vain_pci_5.c @@ -0,0 +1,23 @@ +static struct pci_driver vain_pci_driver = { + .name = "vain_pci", + .id_table = vain_pci_ids, + .probe = vain_pci_probe, + .remove = __devexit_p(vain_pci_remove), +}; + +static int vain_pci_init(void) +{ + int err; + + err = pci_register_driver(&vain_pci_driver); + + if (!err) + printk(KERN_INFO "vain_pci_init: done\n"); + return err; +} + +static void vain_pci_exit(void) +{ + pci_unregister_driver(&vain_pci_driver); + printk(KERN_INFO "vain_pci_exit: done\n"); +} diff --git a/kernel-devel/module-basics/vain_pci/vain_pci_6.c b/kernel-devel/module-basics/vain_pci/vain_pci_6.c new file mode 100644 index 0000000..d672a25 --- /dev/null +++ b/kernel-devel/module-basics/vain_pci/vain_pci_6.c @@ -0,0 +1,7 @@ +module_init(vain_pci_init); +module_exit(vain_pci_exit); + +MODULE_AUTHOR("Benedikt Spranger <b.spranger@linutronix.de>"); +MODULE_DESCRIPTION("a more or less useless PCI module"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("0815"); diff --git a/kernel-devel/module-basics/vain_pci/vain_pci_orig.c b/kernel-devel/module-basics/vain_pci/vain_pci_orig.c new file mode 100644 index 0000000..d84a54e --- /dev/null +++ b/kernel-devel/module-basics/vain_pci/vain_pci_orig.c @@ -0,0 +1,114 @@ +#include <linux/init.h> +#include <linux/module.h> +#include <linux/pci.h> + +#define PCI_VENDOR_ID_ILLEGAL_VENDOR 0xffff +#define PCI_DEVICE_ID_ILLEGAL_VENDOR_DEVICE 0x2342 + +struct vain_pci_info { + void __iomem *base; + struct pci_dev *pdev; + spinlock_t lock; +}; + +static struct pci_device_id vain_pci_ids[] __devinitdata = { + {PCI_VENDOR_ID_ILLEGAL_VENDOR, PCI_DEVICE_ID_ILLEGAL_VENDOR_DEVICE, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + {0, } +}; +MODULE_DEVICE_TABLE(pci, vain_pci_ids); + +static int __devinit vain_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct vain_pci_info *info; + int ret; + + dev_dbg(&pdev->dev, "Init, new card found\n"); + + info = kzalloc(sizeof(struct vain_pci_info), GFP_KERNEL); + if (unlikely(!info)) { + dev_err(&pdev->dev, "Could not allocate memory\n"); + ret = -ENOMEM; + goto err_free; + } + + info->pdev = pdev; + + ret = pci_enable_device(pdev); + if (ret) { + dev_err(&pdev->dev, "Failed to enable PCI Device\n"); + goto err_free; + } + + ret = pci_request_regions(pdev, "vain_pci"); + if (ret) { + dev_err(&pdev->dev, "I/O address 0x%04x already in use\n", + (int) /* nozomi_private.io_addr */ 0); + goto err_disable_device; + } + + info->base = pci_ioremap_bar(pdev, 0); + if (!info->base) { + dev_err(&pdev->dev, "Unable to map card MMIO\n"); + ret = -ENODEV; + goto err_rel_regs; + } + + pci_set_drvdata(pdev, info); + + return 0; + +err_rel_regs: + pci_release_regions(pdev); +err_disable_device: + pci_disable_device(pdev); +err_free: + kfree(info); + + return ret; +} + +static void __devexit vain_pci_remove(struct pci_dev *pdev) +{ + struct vain_pci_info *info = pci_get_drvdata(pdev); + + iounmap(info->base); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + + kfree (info); +} + +static struct pci_driver vain_pci_driver = { + .name = "vain_pci", + .id_table = vain_pci_ids, + .probe = vain_pci_probe, + .remove = __devexit_p(vain_pci_remove), +}; + +static int vain_pci_init(void) +{ + int err; + + err = pci_register_driver(&vain_pci_driver); + + if (!err) + printk(KERN_INFO "vain_pci_init: done\n"); + return err; +} + +static void vain_pci_exit(void) +{ + pci_unregister_driver(&vain_pci_driver); + printk(KERN_INFO "vain_pci_exit: done\n"); +} + +module_init(vain_pci_init); +module_exit(vain_pci_exit); + +MODULE_AUTHOR("Benedikt Spranger <b.spranger@linutronix.de>"); +MODULE_DESCRIPTION("a more or less useless PCI module"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION("0815"); |
