Page MenuHomeFreeBSD

D34357.diff
No OneTemporary

D34357.diff

Index: sys/kern/subr_bus.c
===================================================================
--- sys/kern/subr_bus.c
+++ sys/kern/subr_bus.c
@@ -210,6 +210,70 @@
#define print_devclass_list() /* nop */
#endif
+/*
+ * Preferred device list. If there's a tie, and the driver is on this list,
+ * it will be the one that wins the tie.
+ */
+static int sysctl_preferred(SYSCTL_HANDLER_ARGS);
+static const char **preferred_drivers;
+static int npref;
+SYSCTL_PROC(_hw_bus, OID_AUTO, preferred, CTLTYPE_STRING | CTLFLAG_RWTUN |
+ CTLFLAG_MPSAFE, NULL, 0, sysctl_preferred, "A", "list of preferrred drivers");
+
+static int
+sysctl_preferred(SYSCTL_HANDLER_ARGS)
+{
+ int error, len, newlen;
+ struct sbuf *sbuf;
+ char *buffer, *walk1, *walk2;
+
+ error = sysctl_wire_old_buffer(req, 0);
+ if (error != 0)
+ return (error);
+
+ sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
+ for (int i = 0; i < npref; i++) {
+ if (i > 0)
+ sbuf_putc(sbuf, ',');
+ sbuf_printf(sbuf, "%s", preferred_drivers[i]);
+ }
+
+ error = sbuf_finish(sbuf);
+ sbuf_delete(sbuf);
+
+ if (error || req->newptr == NULL)
+ return (error);
+
+ len = req->newlen - req->newidx;
+ if (len == 0)
+ return (0);
+
+ walk1 = buffer = malloc(len, M_BUS, M_ZERO | M_WAITOK);
+ error = SYSCTL_IN(req, buffer, len);
+
+ newlen = len;
+ npref = 1;
+ for (int i = 0; i < strlen(buffer); i++)
+ if (buffer[i] == ',')
+ npref++;
+ free(preferred_drivers, M_BUS);
+ preferred_drivers = malloc(newlen + npref * sizeof(const char *),
+ M_BUS, M_ZERO | M_WAITOK);
+ walk2 = (char *)(uintptr_t)preferred_drivers + npref * sizeof(const char *);
+ for (int i = 0; i < npref; i++) {
+ preferred_drivers[i] = walk2;
+ len = strcspn(walk1, ",");
+ memcpy(walk2, walk1, len);
+ walk2[len] = '\0';
+ walk1 += len + 1;
+ walk2 += len + 1;
+ }
+
+ free(buffer, M_BUS);
+ return (error);
+}
+
+
/*
* dev sysctl tree
*/
@@ -377,7 +441,6 @@
static int devctl_queue_length = DEVCTL_DEFAULT_QUEUE_LEN;
SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_queue, CTLTYPE_INT | CTLFLAG_RWTUN |
CTLFLAG_MPSAFE, NULL, 0, sysctl_devctl_queue, "I", "devctl queue length");
-
static d_open_t devopen;
static d_close_t devclose;
static d_read_t devread;
@@ -2096,6 +2159,19 @@
return (TAILQ_NEXT(last, link));
}
+/**
+ * @internal
+ */
+static bool
+driver_is_preferred(const char *name)
+{
+ for (int i = 0; i < npref; i++)
+ if (strcmp(name, preferred_drivers[i]) == 0)
+ return (true);
+ return (false);
+}
+
+
/**
* @internal
*/
@@ -2203,7 +2279,8 @@
* best matching driver. Initialise the value
* of pri for the first match.
*/
- if (best == NULL || result > pri) {
+ if (best == NULL || result > pri ||
+ (result == pri && driver_is_preferred(child->driver->name))) {
best = dl;
pri = result;
continue;

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 11, 8:10 PM (4 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29549437
Default Alt Text
D34357.diff (2 KB)

Event Timeline