summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorn_hibma <n_hibma@FreeBSD.org>2000-03-16 09:32:59 +0000
committern_hibma <n_hibma@FreeBSD.org>2000-03-16 09:32:59 +0000
commit7cb4860e818f92c566840532cf9cb975148d7cca (patch)
tree928f45242121f0567968ed8d79f8ef610ffbaded /sys
parent5c1a46084c3e3ce12aa997a78029d705ae6b3c9e (diff)
downloadFreeBSD-src-7cb4860e818f92c566840532cf9cb975148d7cca.zip
FreeBSD-src-7cb4860e818f92c566840532cf9cb975148d7cca.tar.gz
Instead of using the next unit available, use the first unit available.
This avoids the unit number from going up indefinitely when diconnecting and connecting 2 devices alternately. Noticed by: nsayer (quite a while ago) And stop calling DEVICE_NOMATCH at probe repeatedly. This stops the message on the PCI VGA board from being printed when loading a PCI driver.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/subr_bus.c33
-rw-r--r--sys/sys/bus_private.h2
2 files changed, 21 insertions, 14 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index aafbdad..b8131fe 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -267,7 +267,6 @@ devclass_find_internal(const char *classname, int create)
strcpy(dc->name, classname);
dc->devices = NULL;
dc->maxunit = 0;
- dc->nextunit = 0;
TAILQ_INIT(&dc->drivers);
TAILQ_INSERT_TAIL(&devclasses, dc, link);
}
@@ -487,21 +486,28 @@ devclass_alloc_unit(devclass_t dc, int *unitp)
* device.
*/
if (unit != -1) {
- device_t dev;
- dev = devclass_get_device(dc, unit);
- if (dev) {
+ if (unit >= 0 && unit < dc->maxunit && dc->devices[unit] != NULL) {
if (bootverbose)
- printf("devclass_alloc_unit: %s%d already exists, using next available unit number\n", dc->name, unit);
+ printf("%s-: %s%d exists, using next available unit number\n",
+ dc->name, dc->name, unit);
unit = -1;
}
}
+ /*
+ * We ended up with an unwired device, so let's find the next available
+ * slot for it.
+ */
if (unit == -1) {
- unit = dc->nextunit;
- dc->nextunit++;
- } else if (dc->nextunit <= unit)
- dc->nextunit = unit + 1;
+ unit = 0;
+ while (unit < dc->maxunit && dc->devices[unit] != NULL)
+ unit++;
+ }
+ /*
+ * We've selected a unit beyond the length of the table, so let's extend
+ * the table to make room for all units up to and including this one.
+ */
if (unit >= dc->maxunit) {
device_t *newlist;
int newsize;
@@ -571,8 +577,6 @@ devclass_delete_device(devclass_t dc, device_t dev)
dev->devclass = NULL;
free(dev->nameunit, M_BUS);
dev->nameunit = NULL;
- while (dc->nextunit > 0 && dc->devices[dc->nextunit - 1] == NULL)
- dc->nextunit--;
#ifdef DEVICE_SYSCTLS
device_unregister_oids(dev);
@@ -1147,7 +1151,10 @@ device_probe_and_attach(device_t dev)
dev->state = DS_NOTPRESENT;
}
} else {
+ if (!(dev->flags & DF_DONENOMATCH)) {
BUS_PROBE_NOMATCH(bus, dev);
+ dev->flags |= DF_DONENOMATCH;
+ }
}
} else {
if (bootverbose) {
@@ -2430,8 +2437,8 @@ print_devclass_short(devclass_t dc, int indent)
if ( !dc )
return;
- indentprintf(("devclass %s: max units = %d, next unit = %d\n",
- dc->name, dc->maxunit, dc->nextunit));
+ indentprintf(("devclass %s: max units = %d\n",
+ dc->name, dc->maxunit));
}
static void
diff --git a/sys/sys/bus_private.h b/sys/sys/bus_private.h
index 265a761..485e921 100644
--- a/sys/sys/bus_private.h
+++ b/sys/sys/bus_private.h
@@ -53,7 +53,6 @@ struct devclass {
char *name;
device_t *devices; /* array of devices indexed by unit */
int maxunit; /* size of devices array */
- int nextunit; /* next unused unit number */
};
/*
@@ -134,6 +133,7 @@ struct device {
#define DF_WILDCARD 4 /* unit was originally wildcard */
#define DF_DESCMALLOCED 8 /* description was malloced */
#define DF_QUIET 16 /* don't print verbose attach message */
+#define DF_DONENOMATCH 32 /* don't execute DEVICE_NOMATCH again */
u_char order; /* order from device_add_child_ordered() */
u_char pad;
#ifdef DEVICE_SYSCTLS
OpenPOWER on IntegriCloud