From 9b9f6392dcd580043ff81cfcb36c0b624d9e07e9 Mon Sep 17 00:00:00 2001 From: Serge Vakulenko Date: Thu, 5 Feb 2015 19:05:59 -0800 Subject: [PATCH] Added a skeleton for character driver. --- sys/include/skel.h | 45 +++++++++++++ sys/pic32/cfg/skel.dev | 4 ++ sys/pic32/devsw.c | 55 ++++++++-------- sys/pic32/skel.c | 142 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 221 insertions(+), 25 deletions(-) create mode 100644 sys/include/skel.h create mode 100644 sys/pic32/cfg/skel.dev create mode 100644 sys/pic32/skel.c diff --git a/sys/include/skel.h b/sys/include/skel.h new file mode 100644 index 0000000..08b8a7e --- /dev/null +++ b/sys/include/skel.h @@ -0,0 +1,45 @@ +/* + * Ioctl definitions for skeleton driver. + * + * Copyright (C) 2015 Serge Vakulenko + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that the copyright notice and this + * permission notice and warranty disclaimer appear in supporting + * documentation, and that the name of the author not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * The author disclaim all warranties with regard to this + * software, including all implied warranties of merchantability + * and fitness. In no event shall the author be liable for any + * special, indirect or consequential damages or any damages + * whatsoever resulting from loss of use, data or profits, whether + * in an action of contract, negligence or other tortious action, + * arising out of or in connection with the use or performance of + * this software. + */ +#ifndef _SKEL_H +#define _SKEL_H + +#include + +#define SKELCTL_SETMODE _IO ('?', 0) /* set driver mode mode */ + +#define SKELCTL_IO(n) _ION('?', 3, n) /* transfer n bytes */ + +#ifdef KERNEL +#include "conf.h" + +extern const struct devspec skeldevs[]; + +int skeldev_open (dev_t dev, int flag, int mode); +int skeldev_close (dev_t dev, int flag, int mode); +int skeldev_read (dev_t dev, struct uio *uio, int flag); +int skeldev_write (dev_t dev, struct uio *uio, int flag); +int skeldev_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag); +#endif + +#endif diff --git a/sys/pic32/cfg/skel.dev b/sys/pic32/cfg/skel.dev new file mode 100644 index 0000000..1d6f0d9 --- /dev/null +++ b/sys/pic32/cfg/skel.dev @@ -0,0 +1,4 @@ +always + file skel.o + define SKEL_ENABLED YES +end always diff --git a/sys/pic32/devsw.c b/sys/pic32/devsw.c index 7537282..74bb080 100644 --- a/sys/pic32/devsw.c +++ b/sys/pic32/devsw.c @@ -23,39 +23,39 @@ extern int strcmp(char *s1, char *s2); #ifdef UARTUSB_ENABLED -#include "usb_uart.h" +# include "usb_uart.h" #endif #ifdef GPIO_ENABLED -#include "gpio.h" +# include "gpio.h" #endif #ifdef ADC_ENABLED -#include "adc.h" +# include "adc.h" #endif #ifdef SPI_ENABLED -#include "spi.h" +# include "spi.h" #endif #ifdef GLCD_ENABLED -#include "glcd.h" +# include "glcd.h" #endif #ifdef OC_ENABLED -#include "oc.h" +# include "oc.h" #endif #ifdef PICGA_ENABLED -#include "picga.h" +# include "picga.h" #endif #ifdef PTY_ENABLED -#include "pty.h" +# include "pty.h" #endif #ifdef HX8357_ENABLED -#include "hx8357.h" +# include "hx8357.h" #endif /* @@ -117,13 +117,16 @@ const struct bdevsw bdevsw[] = { const int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]) - 1; -// The RetroDisks require the same master number as the disk entry in the -// rdisk.c file. A bit of a bind, but it means that the RetroDisk -// devices must be numbered from master 0 upwards. +/* + * The RetroDisks require the same master number as the disk entry in the + * rdisk.c file. A bit of a bind, but it means that the RetroDisk + * devices must be numbered from master 0 upwards. + */ +const struct cdevsw cdevsw[] = { -const struct cdevsw cdevsw[] = { - -// Static drivers - every system has these: +/* + * Static drivers - every system has these: + */ { /* cn = 0 */ cnopen, cnclose, cnread, cnwrite, @@ -155,18 +158,21 @@ const struct cdevsw cdevsw[] = { nostrategy, 0, 0, swapcdevs }, - -// Optional drivers from here on: +/* + * Optional drivers from here on: + */ #ifdef LOG_ENABLED -{ /* log = 3 */ +{ logopen, logclose, logread, norw, logioctl, nulldev, 0, logselect, nostrategy, 0, 0, logdevs }, #endif -#if defined(UART1_ENABLED) || defined(UART2_ENABLED) || defined(UART3_ENABLED) || defined(UART4_ENABLED) || defined(UART5_ENABLED) || defined(UART6_ENABLED) +#if defined(UART1_ENABLED) || defined(UART2_ENABLED) || \ + defined(UART3_ENABLED) || defined(UART4_ENABLED) || \ + defined(UART5_ENABLED) || defined(UART6_ENABLED) { uartopen, uartclose, uartread, uartwrite, uartioctl, nulldev, uartttys, uartselect, @@ -251,13 +257,12 @@ const struct cdevsw cdevsw[] = { }, #endif -// End the list with a blank entry -{ - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0 -}, +/* + * End the list with a blank entry + */ +{ 0 }, }; + const int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]) - 1; /* diff --git a/sys/pic32/skel.c b/sys/pic32/skel.c new file mode 100644 index 0000000..5dc8f3e --- /dev/null +++ b/sys/pic32/skel.c @@ -0,0 +1,142 @@ +/* + * Skeleton for a character device driver. + * + * Copyright (C) 2015 Serge Vakulenko + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that the copyright notice and this + * permission notice and warranty disclaimer appear in supporting + * documentation, and that the name of the author not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * The author disclaim all warranties with regard to this + * software, including all implied warranties of merchantability + * and fitness. In no event shall the author be liable for any + * special, indirect or consequential damages or any damages + * whatsoever resulting from loss of use, data or profits, whether + * in an action of contract, negligence or other tortious action, + * arising out of or in connection with the use or performance of + * this software. + */ +#include "param.h" +#include "conf.h" +#include "user.h" +#include "ioctl.h" +#include "systm.h" +#include "uio.h" +#include "skel.h" + +/* + * List of device names and minor numbers. + * Assume we have five ports. + */ +const struct devspec skeldevs[] = { + { 0, "skel1" }, + { 1, "skel2" }, + { 2, "skel3" }, + { 3, "skel4" }, + { 4, "skel5" }, + { 0, 0 } +}; + +#define NSKEL 5 /* Ports 1...5 */ + +/* + * To enable debug output, uncomment the first line. + */ +#define PRINTDBG printf +#ifndef PRINTDBG +# define PRINTDBG(...) /*empty*/ +#endif + +/* + * Open /dev/skel# device. + */ +int skeldev_open(dev_t dev, int flag, int mode) +{ + int unit = minor(dev); + + if (unit >= NSKEL) + return ENXIO; + + if (u.u_uid != 0) + return EPERM; + + // TODO: initialize the port. + PRINTDBG("--- %s() unit=%u, flag=%d, mode=%d\n", __func__, unit, flag, mode); + return 0; +} + +/* + * Close device. + */ +int skeldev_close(dev_t dev, int flag, int mode) +{ + int unit = minor(dev); + + if (u.u_uid != 0) + return EPERM; + + // TODO: disable the port. + PRINTDBG("--- %s() unit=%u, flag=%d, mode=%d\n", __func__, unit, flag, mode); + return 0; +} + +/* + * Read data from device. + */ +int skeldev_read(dev_t dev, struct uio *uio, int flag) +{ + int unit = minor(dev); + + // TODO: read data from port to user program. + PRINTDBG("--- %s() unit=%u, flag=%d\n", __func__, unit, flag); + return 0; +} + +/* + * Write data to device. + */ +int skeldev_write(dev_t dev, struct uio *uio, int flag) +{ + int unit = minor(dev); + + // TODO: write data from user program to port. + PRINTDBG("--- %s() unit=%u, flag=%d\n", __func__, unit, flag); + return 0; +} + +/* + * Control operations: + * SKELCTL_SETMODE - set device mode + * SKELCTL_IO(n) - perform R/W transaction of n bytes + */ +int skeldev_ioctl(dev_t dev, u_int cmd, caddr_t addr, int flag) +{ + int unit = minor(dev); + int nbytes; + + PRINTDBG("--- %s() unit=%u, cmd=0x%08x, addr=0x%08x, flag=%d\n", __func__, unit, cmd, addr, flag); + switch (cmd & ~(IOCPARM_MASK << 16)) { + default: + return ENODEV; + + case SKELCTL_SETMODE: + // TODO: set device mode. + PRINTDBG("--- SETMODE 0x%x\n", (unsigned) addr); + return 0; + + case SKELCTL_IO(0): /* transfer n bytes */ + nbytes = (cmd >> 16) & IOCPARM_MASK; + if (baduaddr(addr) || baduaddr(addr + nbytes - 1)) + return EFAULT; + + // TODO: transfer nbytes from device to addr. + PRINTDBG("--- Transfer nbytes=%u to addr=0x%08x\n", addr); + break; + } + return 0; +}