Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/gehenna-devsw]: src/sys/kern Add devsw APIs:
details: https://anonhg.NetBSD.org/src/rev/81cba2c50646
branches: gehenna-devsw
changeset: 527028:81cba2c50646
user: gehenna <gehenna%NetBSD.org@localhost>
date: Thu May 16 03:39:13 2002 +0000
description:
Add devsw APIs:
int devsw_attach(const char *devname, const struct bdevsw *bdev, int *bmajor,
const struct cdevsw *cdev, int *cmajor);
void devsw_detach(const struct bdevsw *bdev, const struct cdevsw *cdev);
const struct bdevsw *bdevsw_lookup(dev_t dev);
const struct cdevsw *cdevsw_lookup(dev_t dev);
int bdevsw_lookup_major(const struct bdevsw *bdev);
int cdevsw_lookup_major(const struct cdevsw *cdev);
const char *devsw_blk2name(int bmajor);
int devsw_name2blk(const char *name, char *devname, size_t devnamelen);
dev_t devsw_chr2blk(dev_t cdev);
dev_t devsw_blk2chr(dev_t bdev);
diffstat:
sys/kern/subr_devsw.c | 369 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 369 insertions(+), 0 deletions(-)
diffs (truncated from 373 to 300 lines):
diff -r f491d58aab64 -r 81cba2c50646 sys/kern/subr_devsw.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/kern/subr_devsw.c Thu May 16 03:39:13 2002 +0000
@@ -0,0 +1,369 @@
+/* $NetBSD: subr_devsw.c,v 1.1.2.1 2002/05/16 03:39:13 gehenna Exp $ */
+/*-
+ * Copyright (c) 2001,2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by MAEKAWA Masahide <gehenna%NetBSD.org@localhost>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * New device switch framework is developing.
+ * So debug options are always turned on.
+ */
+#ifndef DEVSW_DEBUG
+#define DEVSW_DEBUG
+#endif /* DEVSW_DEBUG */
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+
+#ifdef DEVSW_DEBUG
+#define DPRINTF(x) printf x
+#else /* DEVSW_DEBUG */
+#define DPRINTF(x)
+#endif /* DEVSW_DEBUG */
+
+#define MAXDEVSW 4096 /* the maximum of major device number */
+#define BDEVSW_SIZE (sizeof(struct bdevsw *))
+#define CDEVSW_SIZE (sizeof(struct cdevsw *))
+#define DEVSWCONV_SIZE (sizeof(struct devsw_conv))
+
+extern const struct bdevsw **bdevsw, *bdevsw0[];
+extern const struct cdevsw **cdevsw, *cdevsw0[];
+extern struct devsw_conv *devsw_conv, devsw_conv0[];
+extern int nbdevsw, ncdevsw, devsw_nconvs;
+
+int
+devsw_attach(const char *devname, const struct bdevsw *bdev, int *bmajor,
+ const struct cdevsw *cdev, int *cmajor)
+{
+ int i;
+
+ if (bdev == NULL && cdev == NULL)
+ return (EINVAL);
+ if (devname == NULL && bdev != NULL)
+ return (EINVAL);
+
+ if (bdevsw_lookup_major(bdev) != -1 ||
+ cdevsw_lookup_major(cdev) != -1)
+ return (EEXIST);
+
+ if (bdev != NULL) {
+ /* XXX */
+ if (*bmajor < 0) {
+ for (i = nbdevsw ; i < MAXDEVSW ; i++) {
+ if (bdevsw[i] != NULL)
+ continue;
+ *bmajor = i;
+ break;
+ }
+ if (*bmajor < 0 || *bmajor >= MAXDEVSW)
+ return (EINVAL);
+ }
+
+ if (*bmajor >= nbdevsw) {
+ int old = nbdevsw, new = *bmajor;
+ void **newptr;
+
+ newptr = malloc(new * BDEVSW_SIZE, M_DEVBUF, M_NOWAIT);
+ if (newptr == NULL)
+ return (ENOMEM);
+ memset(newptr + old, 0, (new - old) * BDEVSW_SIZE);
+ if (old != 0) {
+ memcpy(newptr, bdevsw, old * BDEVSW_SIZE);
+ if (bdevsw != bdevsw0)
+ free(bdevsw, M_DEVBUF);
+ }
+ bdevsw = (const struct bdevsw **)newptr;
+ nbdevsw = new;
+ }
+
+ if (bdevsw[*bmajor] != NULL)
+ return (EEXIST);
+ }
+
+ if (cdev != NULL) {
+ /* XXX */
+ if (*cmajor < 0) {
+ for (i = ncdevsw ; i < MAXDEVSW ; i++) {
+ if (cdevsw[i] != NULL)
+ continue;
+ *cmajor = i;
+ break;
+ }
+ if (*cmajor < 0 || *cmajor >= MAXDEVSW)
+ return (EINVAL);
+ }
+
+ if (*cmajor >= ncdevsw) {
+ int old = ncdevsw, new = *cmajor;
+ void **newptr;
+
+ newptr = malloc(new * CDEVSW_SIZE, M_DEVBUF, M_NOWAIT);
+ if (newptr == NULL)
+ return (ENOMEM);
+ memset(newptr + old, 0, (new - old) * CDEVSW_SIZE);
+ if (old != 0) {
+ memcpy(newptr, cdevsw, old * CDEVSW_SIZE);
+ if (cdevsw != cdevsw0)
+ free(cdevsw, M_DEVBUF);
+ }
+ cdevsw = (const struct cdevsw **)newptr;
+ ncdevsw = new;
+ }
+
+ if (cdevsw[*cmajor] != NULL)
+ return (EEXIST);
+ }
+
+ if (devname != NULL) {
+ for (i = 0 ; i < devsw_nconvs ; i++) {
+ if (devsw_conv[i].d_name == NULL)
+ break;
+ }
+ if (i == devsw_nconvs) {
+ int old = devsw_nconvs, new = old + 1;
+ void *newptr;
+
+ newptr = malloc(new * DEVSWCONV_SIZE,
+ M_DEVBUF, M_NOWAIT);
+ if (newptr == NULL)
+ return (ENOMEM);
+ if (old != 0) {
+ memcpy(newptr, devsw_conv,
+ old * DEVSWCONV_SIZE);
+ if (devsw_conv != devsw_conv0)
+ free(devsw_conv, M_DEVBUF);
+ }
+ devsw_conv = (struct devsw_conv *)newptr;
+ devsw_nconvs = new;
+ }
+ }
+
+ if (bdev != NULL)
+ bdevsw[*bmajor] = bdev;
+ if (cdev != NULL)
+ cdevsw[*cmajor] = cdev;
+ if (devname != NULL) {
+ devsw_conv[i].d_name = devname;
+ devsw_conv[i].d_bmajor = *bmajor;
+ devsw_conv[i].d_cmajor = *cmajor;
+ }
+
+ return (0);
+}
+
+void
+devsw_detach(const struct bdevsw *bdev, const struct cdevsw *cdev)
+{
+ int bmajor, i;
+
+ bmajor = -1;
+ if (bdev != NULL) {
+ for (i = 0 ; i < nbdevsw ; i++) {
+ if (bdevsw[i] != bdev)
+ continue;
+ bdevsw[i] = NULL;
+ bmajor = i;
+ break;
+ }
+ }
+ if (cdev != NULL) {
+ for (i = 0 ; i < ncdevsw ; i++) {
+ if (cdevsw[i] != cdev)
+ continue;
+ cdevsw[i] = NULL;
+ break;
+ }
+ }
+
+ if (bmajor != -1) {
+ for (i = 0 ; i < devsw_nconvs ; i++) {
+ if (devsw_conv[i].d_bmajor != bmajor)
+ continue;
+
+ devsw_conv[i].d_name = NULL;
+ devsw_conv[i].d_bmajor = -1;
+ devsw_conv[i].d_cmajor = -1;
+ break;
+ }
+ }
+}
+
+const struct bdevsw *
+bdevsw_lookup(dev_t dev)
+{
+ int bmajor;
+
+ if (dev == NODEV)
+ return (NULL);
+ bmajor = major(dev);
+ if (bmajor < 0 || bmajor >= nbdevsw)
+ return (NULL);
+
+ return (bdevsw[bmajor]);
+}
+
+const struct cdevsw *
+cdevsw_lookup(dev_t dev)
+{
+ int cmajor;
+
+ if (dev == NODEV)
+ return (NULL);
+ cmajor = major(dev);
+ if (cmajor < 0 || cmajor >= ncdevsw)
+ return (NULL);
+
+ return (cdevsw[cmajor]);
+}
+
+int
+bdevsw_lookup_major(const struct bdevsw *bdev)
+{
+ int bmajor;
+
+ for (bmajor = 0 ; bmajor < nbdevsw ; bmajor++) {
+ if (bdevsw[bmajor] == bdev)
+ return (bmajor);
+ }
+
+ return (-1);
+}
+
+int
+cdevsw_lookup_major(const struct cdevsw *cdev)
+{
+ int cmajor;
+
+ for (cmajor = 0 ; cmajor < ncdevsw ; cmajor++) {
+ if (cdevsw[cmajor] == cdev)
+ return (cmajor);
+ }
+
+ return (-1);
+}
+
+/*
+ * Convert from block major number to name.
+ */
+const char *
+devsw_blk2name(int bmajor)
+{
+ int i;
+
+ if (bmajor < 0 || bmajor >= nbdevsw)
+ return (NULL);
+
+ for (i = 0 ; i < devsw_nconvs ; i++) {
+ if (devsw_conv[i].d_name == NULL ||
+ devsw_conv[i].d_bmajor != bmajor)
+ continue;
+ return (devsw_conv[i].d_name);
+ }
+
+ return (NULL);
Home |
Main Index |
Thread Index |
Old Index