From owner-freebsd-doc@FreeBSD.ORG Sun Aug 29 15:12:26 2004 Return-Path: Delivered-To: freebsd-doc@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 07EAA16A4CE for ; Sun, 29 Aug 2004 15:12:26 +0000 (GMT) Received: from hotmail.com (bay17-f28.bay17.hotmail.com [64.4.43.78]) by mx1.FreeBSD.org (Postfix) with ESMTP id E2D3B43D39 for ; Sun, 29 Aug 2004 15:12:25 +0000 (GMT) (envelope-from snoyt@hotmail.com) Received: from mail pickup service by hotmail.com with Microsoft SMTPSVC; Sun, 29 Aug 2004 08:01:00 -0700 Received: from 131.155.243.230 by by17fd.bay17.hotmail.msn.com with HTTP; Sun, 29 Aug 2004 15:00:59 GMT X-Originating-IP: [131.155.243.230] X-Originating-Email: [snoyt@hotmail.com] X-Sender: snoyt@hotmail.com From: "Gert van der Plas" To: doc@FreeBSD.org Date: Sun, 29 Aug 2004 17:00:59 +0200 Mime-Version: 1.0 Content-Type: text/plain; format=flowed Message-ID: X-OriginalArrivalTime: 29 Aug 2004 15:01:00.0409 (UTC) FILETIME=[FF038690:01C48DD8] Subject: update for FreeBSD Architecture Handbook: 13.4 Character Devices X-BeenThere: freebsd-doc@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Documentation project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 29 Aug 2004 15:12:26 -0000 Hi doc@FreeBSD.org, I wanted to write a kernel module and accessed your example 13-2: 'Example of a Sample Echo Pseudo-Device Driver for FreeBSD 5.X'. The source seems slightly outdated and did not work for FreeBSD 5.2-CURRENT of 30th of june. I fixed it and submit to you the updated version. Regards, Gert van der Plas /* * Simple Echo pseudo-device KLD * * Murray Stokely * * Converted to 5.X by Søren (Xride) Straarup * Updated 29 August 2004 by Gert van der Plas */ #include #include #include /* uprintf */ #include #include /* defines used in kernel.h */ #include /* types used in module initialization */ #include /* cdevsw struct */ #include /* uio struct */ #include #define BUFFERSIZE 256 #define CDEV_MAJOR 33 /* Function prototypes */ static d_open_t echo_open; static d_close_t echo_close; static d_read_t echo_read; static d_write_t echo_write; /* Character device entry points */ static struct cdevsw echo_cdevsw = { .d_open = echo_open, .d_close = echo_close, .d_maj = CDEV_MAJOR, .d_name = "echo", .d_read = echo_read, .d_write = echo_write, .d_version = D_VERSION }; typedef struct s_echo { char msg[BUFFERSIZE]; int len; } t_echo; /* vars */ static struct cdev *echo_dev; static int count; static t_echo *echomsg; MALLOC_DECLARE(M_ECHOBUF); MALLOC_DEFINE(M_ECHOBUF, "echobuffer", "buffer for echo module"); /* * This function is called by the kld[un]load(2) system calls to * determine what actions to take when a module is loaded or unloaded. */ static int echo_loader(struct module *m, int what, void *arg) { int err = 0; switch (what) { case MOD_LOAD: /* kldload */ echo_dev = make_dev(&echo_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "echo"); /* kmalloc memory for use by this driver */ MALLOC(echomsg, t_echo *, sizeof(t_echo), M_ECHOBUF, M_WAITOK); printf("Echo device loaded.\n"); break; case MOD_UNLOAD: destroy_dev(echo_dev); FREE(echomsg,M_ECHOBUF); printf("Echo device unloaded.\n"); break; default: err = EINVAL; break; } return(err); } static int echo_open(struct cdev *dev, int oflags, int devtype, struct thread *p) { int err = 0; uprintf("Opened device \"echo\" successfully.\n"); return(err); } static int echo_close(struct cdev *dev, int fflag, int devtype, struct thread *p) { uprintf("Closing device \"echo.\"\n"); return(0); } /* * The read function just takes the buf that was saved via * echo_write() and returns it to userland for accessing. * uio(9) */ static int echo_read(struct cdev *dev, struct uio *uio, int ioflag) { int err = 0; int amt; /* * How big is this read operation? Either as big as the user wants, * or as big as the remaining data */ amt = MIN(uio->uio_resid, (echomsg->len - uio->uio_offset > 0) ? echomsg->len - uio->uio_offset : 0); if ((err = uiomove(echomsg->msg + uio->uio_offset,amt,uio)) != 0) { uprintf("uiomove failed!\n"); } return(err); } /* * echo_write takes in a character string and saves it * to buf for later accessing. */ static int echo_write(struct cdev *dev, struct uio *uio, int ioflag) { int err = 0; /* Copy the string in from user memory to kernel memory */ err = copyin(uio->uio_iov->iov_base, echomsg->msg, MIN(uio->uio_iov->iov_len,BUFFERSIZE)); /* Now we need to null terminate, then record the length */ *(echomsg->msg + MIN(uio->uio_iov->iov_len,BUFFERSIZE)) = 0; echomsg->len = MIN(uio->uio_iov->iov_len,BUFFERSIZE); if (err != 0) { uprintf("Write failed: bad address!\n"); } count++; return(err); } DEV_MODULE(echo,echo_loader,NULL); _________________________________________________________________ Talk with your online friends with MSN Messenger http://messenger.msn.nl/