summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_conf.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2003-02-20 15:35:54 +0000
committerphk <phk@FreeBSD.org>2003-02-20 15:35:54 +0000
commitfb70d313d77648ce45097f4209c46870d99cd197 (patch)
tree81376bfe1355105919b0598263dcfa0cc29f26c4 /sys/kern/kern_conf.c
parente4c356edebfc9ee6b6e394ad2dd41ef53e7efc83 (diff)
downloadFreeBSD-src-fb70d313d77648ce45097f4209c46870d99cd197.zip
FreeBSD-src-fb70d313d77648ce45097f4209c46870d99cd197.tar.gz
Add a dead_cdevsw which does its best to return ENXIO if at all possible.
In devsw() return dead_cdevsw instead of NULL in case the dev_t does not have a si_devsw. This may improve our survival chances with devices which go away unexpectedly.
Diffstat (limited to 'sys/kern/kern_conf.c')
-rw-r--r--sys/kern/kern_conf.c56
1 files changed, 53 insertions, 3 deletions
diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c
index 9e4e92a..d471cd4 100644
--- a/sys/kern/kern_conf.c
+++ b/sys/kern/kern_conf.c
@@ -29,6 +29,7 @@
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
+#include <sys/bio.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
@@ -66,15 +67,64 @@ static int ready_for_devs;
static int free_devt;
SYSCTL_INT(_debug, OID_AUTO, free_devt, CTLFLAG_RW, &free_devt, 0, "");
+/* Define a dead_cdevsw for use when devices leave unexpectedly. */
+
+static int
+enxio(void)
+{
+ return (ENXIO);
+}
+
+#define dead_open (d_open_t *)enxio
+#define dead_close (d_close_t *)enxio
+#define dead_read (d_read_t *)enxio
+#define dead_write (d_write_t *)enxio
+#define dead_ioctl (d_ioctl_t *)enxio
+#define dead_poll nopoll
+#define dead_mmap nommap
+
+static void
+dead_strategy(struct bio *bp)
+{
+
+ biofinish(bp, NULL, ENXIO);
+}
+
+#define dead_dump (d_dump_t *)enxio
+
+static int
+dead_psize(dev_t dev)
+{
+
+ return (-1);
+}
+
+#define dead_kqfilter (d_kqfilter_t *)enxio
+
+static struct cdevsw dead_cdevsw = {
+ /* open */ dead_open,
+ /* close */ dead_close,
+ /* read */ dead_read,
+ /* write */ dead_write,
+ /* ioctl */ dead_ioctl,
+ /* poll */ dead_poll,
+ /* mmap */ dead_mmap,
+ /* strategy */ dead_strategy,
+ /* name */ "dead",
+ /* maj */ 255,
+ /* dump */ dead_dump,
+ /* psize */ dead_psize,
+ /* flags */ 0,
+ /* kqfilter */ dead_kqfilter
+};
+
struct cdevsw *
devsw(dev_t dev)
{
if (dev->si_devsw)
return (dev->si_devsw);
- if (dev->si_devsw)
- return (dev->si_devsw);
- return (NULL);
+ return (&dead_cdevsw);
}
/*
OpenPOWER on IntegriCloud